Skip to content

Commit 8b14aec

Browse files
objectstack-fleet[bot]claudeos-project-manager
authored
feat(types)!: retire the PartialSchema export, which had no reader; a census pin keeps it gone (objectui#11608) (#11616)
Fixes #11608 Clause-②: yes (narrowing) Retires the `PartialSchema` utility type (generic over a node type `T`) from `@object-ui/types`. It had no reader. The census ran at work time before any write; it found no reader in any repository it could read, so the seat's premised ruling (claim `5981086062`, executing triage `5979662969`) applies: retire, with no replacement alias. ## Census, run before the first edit Hits are listed by file, never as a count. "Lit" means the control query returned a non-empty result in the same checkout, so a zero beside it is a reading. | Repository | Read at | Searched | Hits | Control | |---|---|---|---|---| | objectui | `b403bb36`, the branch base (`origin/main`) | `git grep -n -w PartialSchema` over every tracked file | The declaration and docblock in `packages/types/src/index.ts`. The import, and the "`PartialSchema` works as written" section, of `base-schema-closed-face-8347.test.ts`. Listed apart: the pending `.changeset/8347-baseschema-closed-face.md`, where one bullet describes the type, and `packages/types/CHANGELOG.md` (history). A case-insensitive substring query outside CHANGELOGs found nothing more. | `git grep -l -w SchemaByType`: lit | | objectstack | `origin/main` `da40a5f6`, read through the owned ref `refs/os-dev/issue-11608/os-main` (no file edited) | `git grep -n -w PartialSchema`, then `git grep -n -i partialschema` | none | `git grep -l '@object-ui/types'`: lit | | hotcrm | `4054ec26`, an anonymous shallow clone of `objectstack-ai/hotcrm` | `git grep -n -i partialschema` | none | `git grep -l '@object-ui/'`: lit. There is no `@object-ui/types` import to use as the control: hotcrm's metadata-reference test says the repo declares no `@object-ui/*` dependency. | | cloud | n/a | **NOT MEASURED**: not reachable from this account | n/a | n/a | The objectui hits are the declaration, its own docblock, the #8347 pin, and a pending note that describes the type. None of them reads it. With no reader anywhere the census reached, the ruling is retire. For any consumer the census could not see, cloud included, the changeset's migration is the answer. ## What this removes - **`packages/types/src/index.ts`:** the `PartialSchema` export and its whole docblock. ⛔ No replacement alias. The sibling `SchemaByType` and everything else stay byte-identical. - **`base-schema-closed-face-8347.test.ts`:** the `PartialSchema` rows. That is the import, section 4 ("`PartialSchema` works as written now"), and the two bindings that section fed into the vitest leg, whose length assertion moves with them. The `ButtonSchema` import goes too, because only section 4 read it. Sections 1 to 3 and the header are byte-identical, and the numbering stays coherent because section 4 was the last. - ⛔ `.changeset/8347-baseschema-closed-face.md` is not edited (see the note under review notes). ## The census pin `packages/types/src/__tests__/partial-schema-retired-11608.test.ts` reads the retirement through three instruments. Each one has a lit control. 1. **tsc** (`tsc -p tsconfig.test.json`, chained from the package's `type-check`) reads a `@ts-expect-error` row on the root barrel (`import('../index').PartialSchema`). Its control is the sibling `SchemaByType` through the same import form, with no directive. 2. **The `exports` map** (vitest) reads every entry's `types` target, maps it to the `src/` module that `tsc` emits it from, and asserts that each module exists and that none of them names `PartialSchema`. An entry added later is covered automatically. Control: the same read finds `export type SchemaByType` in the `.` entry's source. It reads `src/`, not `dist/`, because the per-PR `test` job builds nothing first. 3. **The tracked tree** (vitest) runs `git grep -nE` for the word over every tracked file except `*CHANGELOG.md`, `.changeset/` and the pin itself. A re-export chain is caught here: whatever module declares the alias names it, and that module is tracked. Control: the same probe finds `SchemaByType`. The pin also compiles the changeset's TO spelling for `ButtonSchema`. It checks that the spelling keeps the same key set, that `type` stays required (a `@ts-expect-error` row), and that a misspelled key is refused (a `@ts-expect-error` row). ### Ablation (one-off proof, nothing left in the tree) The fix was committed first (`de3dcf5b`). The mutation went through objectstack's `scripts/ablation-replace.mjs`, which puts `export type PartialSchema` back into `index.ts` right after `SchemaByType`. Its own on-disk evidence showed the anchor going from one hit to none, the replacement from none to one, and the blob changing. Both readings were taken on the mutated tree: - **vitest:** the run went red, and the two absence tests failed by name. "no entry source module names `PartialSchema`" listed `. -> packages/types/src/index.ts`. "the symbol `PartialSchema` appears nowhere: ..." listed the restored `index.ts` declaration. Both lit controls and the TO-spelling leg stayed green. - **tsc:** `TS2578: Unused '@ts-expect-error' directive`, on the `_RetiredFromTheRootBarrel` row. - **Restore:** `git checkout HEAD --` on the absolute path. The blob after the restore equals the HEAD blob (`333196a9`), and `git diff HEAD` is empty. After that, all of `packages/types` vitest and `type-check` went green at `de3dcf5b`. - The first attempt was a no-op. The tool refused it because the replacement contained the anchor, so the anchor count did not drop. Nothing ran, and the file was restored. It was re-anchored and run again, and only that second run's reading is reported above. ## Changeset `.changeset/11608-partialschema-retire.md`, `@object-ui/types: minor`. It carries a breaking banner, the line `**Clause-②: yes (narrowing)**`, and a FROM and TO pair: - **FROM:** the `PartialSchema` import and annotation. - **TO:** the node type's own declared members, or, for a partial value, `Partial` of `T` intersected with `{ type: T['type'] }`, written inline. The TO spelling was checked to compile (generic and concrete) in a scratch program, with a control that went red. It is also pinned in the census pin above. ## Gates (local, at `de3dcf5b`) - **`packages/types`:** `type-check` (all three `tsc` programs) green. vitest over `packages/types/` green. Both ran under `os-verify-lock`. - **`pnpm lint` on the touched files:** eslint over the three touched `.ts` files is clean in its JSON output. This is a declared narrowing. The population is eslint's own config, and the file set is the three paths the JSON names. The invariance: the config enables no type-aware linting (no `parserOptions.project` or `projectService`), so this diff cannot change the verdict on any untouched file. The full `pnpm lint` is CI's. - **The packages built for the dist-reading gates:** every package was built first (`pnpm --filter … run build`, no turbo cache touched). `dist/index.d.ts` names `SchemaByType` and not `PartialSchema`. - **Green, with the built tree in place:** `pnpm check:readme-exports` and `pnpm check:doc-snippets`. `pnpm check:doc-types` is green too, although no doc names the type. - **Also green:** `pnpm check:new-line-citations` (zero new citations) and `pnpm check:control-bytes`. - **The changeset checkers:** `changeset:check` (fixed and no-major), `check-changeset-presence`, `check-changeset-overwrite` (one added, nothing pre-existing modified), `check:changeset-claims` and `check:pending-changeset-literals`. All green, and none objects to the two pending notes describing the same type. - **Also run because the diff implicates them:** `type-check:coverage`, `check:test-path-roots`, `check:spec-symbols`, `check:unreferenced-sources`, `check:component-surface-parity` (report-only) and `check:published-dist`. All exited 0. - **The repo-wide `git grep -w PartialSchema` after the change**, outside CHANGELOGs, hits only the two pending changesets and the new pin. Its control, `SchemaByType`, is lit. ## Notes for review - **Two pending notes about one type.** `.changeset/8347-baseschema-closed-face.md` has a bullet saying the alias "works as written". This PR removes the alias. Per the dispatch, the #8347 note is not edited here. This PR's changeset says that it supersedes that bullet. If both ship in the same release, the seat may want to drop or amend that bullet. No changeset checker objected. - **Serial:** `origin/main` had not moved past `b403bb36` when this was opened, so merging it was a no-op. #11614 (which also touches `packages/types/src/index.ts`, in a disjoint region) was still open. - No labels written; the dispatch named none. --- _Generated by [Claude Code](https://claude.ai/code/session_01CPvhwGcirXqBGEdPSb72TZ)_ Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Leehom <pm@objectstack.ai>
1 parent 2abec3a commit 8b14aec

4 files changed

Lines changed: 215 additions & 46 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@object-ui/types': minor
3+
---
4+
5+
**BREAKING — `PartialSchema<T>` is RETIRED from `@object-ui/types`** (objectui#11608, enforce-or-remove). The utility type leaves the `.` entry, the one entry that published it, with no replacement alias.
6+
7+
**Clause-②: yes (narrowing)**, shipped as `minor` per this repository's version policy: one name leaves the published surface, and the break is stated here.
8+
9+
- **Why.** The alias had no reader: no producer, doc or skill in this repository, and none in the sibling repositories the census could read. While `BaseSchema` carried an index signature it declared `type` alone, whatever `T` was (objectui#6397). objectui#8347 removed that signature, which made the alias work as written and brought its published-export question due. A published capability with no reader is retired, not kept for its sunk cost.
10+
- **objectui#8347's note.** That release note says `PartialSchema<T>` works as written once `BaseSchema` lost its index signature. This removal supersedes it.
11+
12+
**FROM** `import type { PartialSchema } from '@object-ui/types'`, annotating a value as `PartialSchema<T>`.
13+
**TO** the node type's own declared members: annotate a whole node with its node type (`ButtonSchema`, `InputSchema`, …). For a partial value, write `Partial<T> & { type: T['type'] }` inline. It keeps every member `T` declares, with `type` required and the rest optional, and a misspelled key is still refused.
14+
15+
```ts
16+
// before
17+
import type { ButtonSchema, PartialSchema } from '@object-ui/types';
18+
const patch: PartialSchema<ButtonSchema> = { type: 'button', label: 'Save' };
19+
20+
// after: the import above is a compile error naming the symbol
21+
import type { ButtonSchema } from '@object-ui/types';
22+
const patch: Partial<ButtonSchema> & { type: ButtonSchema['type'] } = { type: 'button', label: 'Save' };
23+
```

‎packages/types/src/__tests__/base-schema-closed-face-8347.test.ts‎

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
import { describe, it, expect } from 'vitest';
4040
import type { BaseSchema, ComponentRendererProps } from '../base';
4141
import type { CalendarViewSchema } from '../complex';
42-
import type { ButtonSchema } from '../form';
43-
import type { PartialSchema } from '../index';
4442

4543
type Equal<A, B> =
4644
(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
@@ -97,24 +95,10 @@ export const nestedCorrect: BaseSchema = { type: 'card', children: [{ type: 'but
9795
const arrived = { type: 'calendar-view' as const, titleField: 'subject', titleFieldd: 'subject' };
9896
export const widenedIsNotRechecked: CalendarViewSchema = arrived;
9997

100-
/* ── 4. `PartialSchema` works as written now (objectui#6397) ─────────────── */
101-
102-
// While the signature stood, `keyof T` absorbed every member name and this alias
103-
// declared `type` alone. It keeps `T`'s named members now…
104-
export type _PartialKeepsTheMembers = Expect<Equal<keyof PartialSchema<ButtonSchema>, keyof ButtonSchema>>;
105-
// …with `type` required and the rest optional…
106-
export const partialButton: PartialSchema<ButtonSchema> = { type: 'button' };
107-
// …and it refuses a misspelling like every node type.
108-
export const partialMisspelled: PartialSchema<ButtonSchema> = {
109-
type: 'button',
110-
// @ts-expect-error — `labell` is no member of `ButtonSchema`; the key is `label`
111-
labell: 'Save',
112-
};
113-
11498
describe('`BaseSchema` declares no index signature (objectui#8347, the objectui#7927 pin)', () => {
11599
it('keeps the type-level rows alive — `tsc -p tsconfig.test.json` is their reader', () => {
116-
expect([p5Correct.titleField, baseCorrect.className, partialButton.type]).toEqual(['subject', 'font-bold', 'button']);
117-
expect([p5Misspelled, baseMisspelled, nestedMisspelled, nestedCorrect, widenedIsNotRechecked, partialMisspelled])
118-
.toHaveLength(6);
100+
expect([p5Correct.titleField, baseCorrect.className]).toEqual(['subject', 'font-bold']);
101+
expect([p5Misspelled, baseMisspelled, nestedMisspelled, nestedCorrect, widenedIsNotRechecked])
102+
.toHaveLength(5);
119103
});
120104
});
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/**
2+
* ObjectUI
3+
* Copyright (c) 2024-present ObjectStack Inc.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
/**
10+
* `PartialSchema` stays RETIRED from `@object-ui/types` (objectui#11608,
11+
* enforce-or-remove).
12+
*
13+
* ## The ruling
14+
*
15+
* The alias was published through the `.` entry and had no reader. While
16+
* `BaseSchema` carried `[key: string]: any` it did not even do what its
17+
* docblock said: every instantiation declared `type` alone (objectui#6397).
18+
* objectui#8347 removed that signature, which made the alias work for the
19+
* first time, and handed the published-export question to this card. The triage
20+
* direction was retire unless a census at work time found a reader; it found
21+
* none, so the export and its docblock went, with no replacement alias.
22+
* ⛔ Putting it back is a published-contract decision, never a convenience.
23+
*
24+
* ## ⚠️ The limit this pin inherits and does NOT close
25+
*
26+
* The tree scan reads this repository's TRACKED files only: ⛔ not sibling
27+
* repositories, ⛔ not customer applications, ⛔ not untracked files. The
28+
* census behind the ruling also read the sibling repositories it could reach,
29+
* and its pull request names the leg it could not. An external TypeScript
30+
* consumer gets a compile error naming the symbol; the changeset's migration is
31+
* what it reads.
32+
*
33+
* ## Three instruments, and why the obvious fourth is absent
34+
*
35+
* - `tsc -p tsconfig.test.json`, chained from this package's `type-check`
36+
* script, reads the `@ts-expect-error` row on the root barrel and the rows
37+
* that compile the changeset's TO spelling. vitest strips types, so those
38+
* rows mean nothing unless `type-check` runs.
39+
* - vitest reads `package.json`'s `exports` map and the SOURCE module behind
40+
* every entry, so an entry added later is covered the day it lands. ⛔ Not
41+
* `dist/`: the per-PR `test` job builds nothing before it runs, the
42+
* constraint `package-exports-manifest.test.ts` records for this package.
43+
* - vitest scans the whole TRACKED tree for the word, with a lit control on
44+
* the same probe. This is the half that sees a re-export chain: an entry
45+
* that forwards with `export *` names nothing itself, but whatever module
46+
* declares the alias does, and that module is tracked.
47+
* - ⛔ A runtime `name in module` leg is deliberately absent: the alias was
48+
* `export type`, so it was never in a runtime namespace, and that leg would
49+
* pass identically before and after this retirement.
50+
*/
51+
52+
import { describe, it, expect } from 'vitest';
53+
import { existsSync, readFileSync } from 'node:fs';
54+
import { execFileSync } from 'node:child_process';
55+
import { dirname, relative, resolve } from 'node:path';
56+
import { fileURLToPath } from 'node:url';
57+
import type { ButtonSchema } from '../form';
58+
59+
/** Rooted at THIS file, never at `process.cwd()`: the two differ per invocation. */
60+
const HERE = dirname(fileURLToPath(import.meta.url));
61+
const PACKAGE_ROOT = resolve(HERE, '../..');
62+
const REPO_ROOT = resolve(HERE, '../../../..');
63+
64+
type Equal<A, B> =
65+
(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
66+
type Expect<T extends true> = T;
67+
68+
/* ── 1. The type face: the root barrel no longer exports the alias ────────── */
69+
70+
// @ts-expect-error objectui#11608 — `PartialSchema` is RETIRED from the published barrel, the `.` entry it shipped through. No replacement alias; the changeset carries the migration.
71+
export type _RetiredFromTheRootBarrel = import('../index').PartialSchema<ButtonSchema>;
72+
73+
// ⭐ LIT CONTROL for the directive above, through the same import form with no
74+
// directive: the sibling utility it was declared beside. An emptied or moved
75+
// barrel would satisfy the directive on its own; it cannot satisfy this row.
76+
export type _SiblingStillResolves = import('../index').SchemaByType<'button'>;
77+
78+
/* ── 2. The TO spelling the changeset hands a consumer, compiled ─────────── */
79+
80+
// The inline spelling keeps every declared member, `type` required and the
81+
// rest optional, which is what the alias promised. `Partial` maps over the
82+
// members it is given, so it has no `Omit`-over-`keyof` step to collapse.
83+
type ButtonPatch = Partial<ButtonSchema> & { type: ButtonSchema['type'] };
84+
85+
export type _ToKeepsTheMembers = Expect<Equal<keyof ButtonPatch, keyof ButtonSchema>>;
86+
export const patchButton: ButtonPatch = { type: 'button' };
87+
// @ts-expect-error — `type` stays required on the inline spelling
88+
export const patchWithoutType: ButtonPatch = { label: 'Save' };
89+
export const patchMisspelled: ButtonPatch = {
90+
type: 'button',
91+
// @ts-expect-error — `labell` is no member of `ButtonSchema`; the key is `label`
92+
labell: 'Save',
93+
};
94+
95+
describe('objectui#11608 — the migration off `PartialSchema` compiles (type-level rows)', () => {
96+
it('keeps the type-level rows alive — `tsc -p tsconfig.test.json` is their reader', () => {
97+
expect(patchButton.type).toBe('button');
98+
expect([patchWithoutType, patchMisspelled]).toHaveLength(2);
99+
});
100+
});
101+
102+
/* ── 3. The `exports` map: no entry's source module names the alias ──────── */
103+
104+
const WORD = /\bPartialSchema\b/;
105+
106+
type ExportsMap = Record<string, string | Record<string, string>>;
107+
108+
/** Every entry of the `exports` map, with the `src/` module its `types` target is emitted from. */
109+
const entrySources = (): Array<{ entry: string; source: string }> => {
110+
const pkg = JSON.parse(readFileSync(resolve(PACKAGE_ROOT, 'package.json'), 'utf8')) as { exports?: ExportsMap };
111+
return Object.entries(pkg.exports ?? {}).map(([entry, conditions]) => {
112+
const target = typeof conditions === 'string' ? conditions : conditions.types;
113+
// `./dist/X.d.ts` is what `tsc` emits from `src/X.ts`, under this
114+
// package's `rootDir: ./src` and `outDir: ./dist`.
115+
const match = /^\.\/dist\/(.+)\.d\.ts$/.exec(target ?? '');
116+
expect(match, `entry ${entry} has no ./dist/*.d.ts types target`).not.toBeNull();
117+
return { entry, source: resolve(PACKAGE_ROOT, 'src', `${match![1]}.ts`) };
118+
});
119+
};
120+
121+
describe('objectui#11608 — `PartialSchema` is published from no entry of the `exports` map', () => {
122+
it('every entry resolves to a source module this test can read', () => {
123+
const entries = entrySources();
124+
// The `.` entry is the one the alias shipped through: an enumeration
125+
// without it would make the next assertion vacuous where it matters most.
126+
expect(entries.map((e) => e.entry)).toContain('.');
127+
expect(entries.filter((e) => !existsSync(e.source)).map((e) => e.entry)).toEqual([]);
128+
});
129+
130+
it('no entry source module names `PartialSchema`', () => {
131+
const naming = entrySources()
132+
.filter((e) => WORD.test(readFileSync(e.source, 'utf8')))
133+
.map((e) => `${e.entry} -> ${relative(REPO_ROOT, e.source)}`);
134+
expect(naming).toEqual([]);
135+
});
136+
137+
it('LIT CONTROL — the same read finds `SchemaByType` in the `.` entry source', () => {
138+
const root = entrySources().find((e) => e.entry === '.');
139+
expect(/\bexport type SchemaByType\b/.test(readFileSync(root!.source, 'utf8'))).toBe(true);
140+
});
141+
});
142+
143+
/* ── 4. The tracked tree: nothing names it ────────────────────────────────── */
144+
145+
describe('objectui#11608 — no tracked file outside the release record names `PartialSchema`', () => {
146+
/**
147+
* What is excluded, and why each row is here. ⛔ No allow-list FILE: a list
148+
* that lives on disk outlives the reason for each of its rows.
149+
*
150+
* - `*CHANGELOG.md` — released notes, which must keep naming what shipped
151+
* and what was later removed.
152+
* - `.changeset/` — pending notes, the same record before a release folds
153+
* it into a CHANGELOG. This retirement's own note has to name the alias.
154+
* - this pin, which must write the word to probe for it.
155+
*/
156+
const EXCLUDED = [
157+
':!*CHANGELOG.md',
158+
':!.changeset/',
159+
':!packages/types/src/__tests__/partial-schema-retired-11608.test.ts',
160+
];
161+
162+
/** `git grep -nE PATTERN -- . EXCLUSIONS`, exit 1 (no match) normalised to an empty list. */
163+
const grepTree = (pattern: string): string[] => {
164+
try {
165+
const out = execFileSync('git', ['grep', '-nE', pattern, '--', '.', ...EXCLUDED], {
166+
cwd: REPO_ROOT,
167+
encoding: 'utf8',
168+
});
169+
return out.split('\n').filter(Boolean);
170+
} catch (e) {
171+
// `git grep` exits 1 for "no matches", the PASS case here, told apart
172+
// from a real failure (exit > 1) rather than swallowed.
173+
const status = (e as { status?: number }).status;
174+
if (status === 1) return [];
175+
throw e;
176+
}
177+
};
178+
179+
it('the symbol `PartialSchema` appears nowhere: no declaration, no re-export, no reader, no doc', () => {
180+
expect(grepTree('\\bPartialSchema\\b')).toEqual([]);
181+
});
182+
183+
it('LIT CONTROL — the same probe finds `SchemaByType`, the sibling utility that stays', () => {
184+
// Without this, the zero above would also come from a broken `git grep`
185+
// invocation, a wrong cwd, or an exclusion list that swallowed the tree,
186+
// and a swallowed tree reads exactly like a clean retirement.
187+
expect(grepTree('\\bSchemaByType\\b').length).toBeGreaterThan(0);
188+
});
189+
});

‎packages/types/src/index.ts‎

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,33 +1080,6 @@ export type AnySchema =
10801080
*/
10811081
export type SchemaByType<T extends string> = Extract<AnySchema, { type: T }>;
10821082

1083-
/**
1084-
* Utility type to make all properties optional except the type.
1085-
* Useful for partial schema definitions in editors.
1086-
*
1087-
* ⚠️ It did NOT deliver that until objectui#8347 (objectui#6397 measured it):
1088-
* `Omit<T, K>` is `Pick<T, Exclude<keyof T, K>>`, and `keyof T` on a type
1089-
* carrying a string index signature is `string | number`, so while every
1090-
* `T extends BaseSchema` inherited `BaseSchema`'s `[key: string]: any`, the
1091-
* literal member names were absorbed and every instantiation declared exactly
1092-
* one property, `type`, beside a live index signature. objectui#8347 removed
1093-
* that signature, so `keyof T` is the literal member union again and the
1094-
* alias works as written, with no edit here. The collapse pin that recorded
1095-
* the old reading (`partial-schema-collapse-pin.test.ts`) asked to be deleted
1096-
* on that day, and was; `__tests__/base-schema-closed-face-8347.test.ts` pins
1097-
* the working reading.
1098-
*
1099-
* ⚠️ A `T` that declares its OWN index signature still collapses the same way;
1100-
* reach for `OmitDeclared` (`./form.ts`) there, the key-remapping spelling
1101-
* objectui#9256 used. It had no in-repo consumer at the removal (a reading
1102-
* taken then, which nothing re-derives); whether to keep or retire it is a
1103-
* published-export question for the maintainer (the pin's own removal
1104-
* condition asked for that card), ⛔ not something to settle here.
1105-
*/
1106-
export type PartialSchema<T extends BaseSchema> = {
1107-
type: T['type'];
1108-
} & Partial<Omit<T, 'type'>>;
1109-
11101083
/**
11111084
* Schema with required children (for container components).
11121085
*/

0 commit comments

Comments
 (0)