@astryxdesign/cli 0.6.3-canary.e59d786 → 0.6.3-canary.e78c3ce

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/api/docs/detail/section/section.mjs +9 -15
  2. package/api/docs/detail/section/section.test.mjs +15 -6
  3. package/api/doctor/doctor.mjs +1 -1
  4. package/api/doctor/doctor.test.mjs +6 -6
  5. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  6. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +4 -0
  7. package/assets/codemods/transforms/next/index.mjs +8 -0
  8. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  9. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  10. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  11. package/authoring/doctypes/_schema.d.mts +71 -141
  12. package/authoring/doctypes/_schema.mjs +29 -2
  13. package/authoring/doctypes/load-contract.test.mjs +1 -1
  14. package/authoring/doctypes/namespace/namespace.doc.mjs +2 -2
  15. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  16. package/authoring/doctypes/namespace/type.ts +5 -2
  17. package/authoring/doctypes/parse.mjs +3 -2
  18. package/authoring/doctypes/reference/reference.doc.mjs +5 -3
  19. package/authoring/doctypes/reference/type.ts +7 -8
  20. package/authoring/index.d.ts +1 -0
  21. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  22. package/clients/cli/commands/build-theme.mjs +10 -44
  23. package/clients/cli/commands/docs.mjs +15 -58
  24. package/clients/cli/commands/docs.test.mjs +11 -14
  25. package/clients/cli/commands/text-json-parity.test.mjs +718 -0
  26. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  27. package/clients/cli/commands/upgrade.mjs +26 -7
  28. package/clients/cli/formatters/index.mjs +2 -0
  29. package/clients/cli/formatters/index.test.mjs +6 -0
  30. package/foundation/discovery/authoring-self-docs.test.mjs +3 -2
  31. package/foundation/discovery/docs-discovery.mjs +6 -5
  32. package/foundation/discovery/docs-discovery.test.mjs +7 -10
  33. package/foundation/discovery/docs-section-key.d.mts +19 -8
  34. package/foundation/discovery/docs-section-key.mjs +119 -32
  35. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  36. package/foundation/doc-compiler/compile.mjs +5 -4
  37. package/package.json +9 -9
@@ -4,9 +4,9 @@
4
4
  * @file docs.detail.section leaf — load a single section of a topic.
5
5
  *
6
6
  * @input A topic name, a section query, and optional {lang, zh, dense}. Resolves
7
- * the topic via the shared adapter, finds the section in its lowered compiled
8
- * node by its stable key, then by exact title, then by a title that contains
9
- * the query, and links only that section.
7
+ * the topic via the shared adapter, keeps the 0.6.x first title-substring
8
+ * match, then falls back to a stable key or normalized title key, and links
9
+ * only that section.
10
10
  * @output { type: 'docs.detail.section', data: ReferenceSection } with any
11
11
  * token-ref blocks inlined — matching `astryx --json docs <topic> <section>`.
12
12
  * Throws ERR_UNKNOWN_SECTION when nothing matches, or when the query matches
@@ -17,10 +17,7 @@
17
17
 
18
18
  import {AstryxError} from '../../../error.mjs';
19
19
  import {ERROR_CODES} from '../../../../foundation/response/error-codes.mjs';
20
- import {
21
- findDocSection,
22
- sectionKey,
23
- } from '../../../../foundation/discovery/docs-section-key.mjs';
20
+ import {findDocSection} from '../../../../foundation/discovery/docs-section-key.mjs';
24
21
  import {linkReferenceSection} from '../../../../foundation/doc-compiler/compile.mjs';
25
22
  import {
26
23
  readerSections,
@@ -52,16 +49,13 @@ export async function section(topic, sectionName, options = {}) {
52
49
 
53
50
  const {catalog, node, lang} = await resolveTopicDocs(topic, options);
54
51
  const sections = readerSections(node);
55
- const {section: match, candidates} = findDocSection(sections, sectionName);
52
+ const {section: match} = findDocSection(sections, sectionName);
56
53
  if (!match) {
57
- const ambiguous = candidates.length > 1;
58
54
  throw new AstryxError(
59
- ambiguous
60
- ? `Section "${sectionName}" matches ${candidates.length} sections in "${topic}". Read one by its key.`
61
- : `Section "${sectionName}" not found in "${topic}"`,
62
- (ambiguous ? candidates : sections).map(s => ({
63
- name: sectionKey(s),
64
- reason: s.title,
55
+ `Section "${sectionName}" not found in "${topic}"`,
56
+ sections.map(s => ({
57
+ name: s.title,
58
+ reason: 'available section',
65
59
  })),
66
60
  ERROR_CODES.ERR_UNKNOWN_SECTION,
67
61
  );
@@ -30,6 +30,17 @@ describe('docs.detail.section leaf', () => {
30
30
  }
31
31
  expect(err).toBeInstanceOf(AstryxError);
32
32
  expect(err.code).toBe('ERR_UNKNOWN_SECTION');
33
+ expect(err.suggestions).toEqual(
34
+ expect.arrayContaining([
35
+ expect.objectContaining({
36
+ name: expect.any(String),
37
+ reason: 'available section',
38
+ }),
39
+ ]),
40
+ );
41
+ expect(err.suggestions.some(suggestion => /\s/u.test(suggestion.name))).toBe(
42
+ true,
43
+ );
33
44
  }, SLOW);
34
45
 
35
46
  it('does not return the first section for an empty section name', async () => {
@@ -50,12 +61,10 @@ describe('docs.detail.section leaf', () => {
50
61
  expect(res.data.id).toBe(target.id);
51
62
  }, SLOW);
52
63
 
53
- it('refuses a query that matches more than one section', async () => {
54
- const err = await section('theme', 'e').catch(e => e);
55
- expect(err).toBeInstanceOf(AstryxError);
56
- expect(err.code).toBe('ERR_UNKNOWN_SECTION');
57
- expect(err.message).toMatch(/matches \d+ sections/);
58
- expect(err.suggestions.length).toBeGreaterThan(1);
64
+ it('keeps a previously accepted ambiguous query on its first match', async () => {
65
+ const res = await section('theme', 'e');
66
+ expect(res.type).toBe('docs.detail.section');
67
+ expect(res.data).toBeDefined();
59
68
  }, SLOW);
60
69
 
61
70
  it.each([null, 'zh', 'dense'])(
@@ -994,7 +994,7 @@ export async function checkDocsProgressiveDisclosure(ctx) {
994
994
  return {
995
995
  id,
996
996
  label,
997
- status: 'fail',
997
+ status: 'warn',
998
998
  message: joinProblems(problems),
999
999
  fix: 'Fix the doc each problem names; split a section that is too large into smaller ones, each with its own key.',
1000
1000
  };
@@ -391,7 +391,7 @@ describe('checkDocsProgressiveDisclosure', () => {
391
391
  expect(c.message).toMatch(/^\d+ topics: /);
392
392
  }, SLOW);
393
393
 
394
- it('fails on an invalid doc an integration contributed', async () => {
394
+ it('warns on an invalid doc an integration contributed', async () => {
395
395
  const c = await checkDocsProgressiveDisclosure({
396
396
  docsCatalogIssues: [
397
397
  {
@@ -402,13 +402,13 @@ describe('checkDocsProgressiveDisclosure', () => {
402
402
  },
403
403
  ],
404
404
  });
405
- expect(c.status).toBe('fail');
405
+ expect(c.status).toBe('warn');
406
406
  expect(c.message).toBe('@acme/widgets: bad.doc.mjs exports no doc');
407
407
  });
408
408
 
409
- it('fails when the docs catalog cannot be built', async () => {
409
+ it('warns when the docs catalog cannot be built', async () => {
410
410
  const c = await checkDocsProgressiveDisclosure({docsCatalogError: 'boom'});
411
- expect(c.status).toBe('fail');
411
+ expect(c.status).toBe('warn');
412
412
  expect(c.message).toContain('boom');
413
413
  });
414
414
 
@@ -436,7 +436,7 @@ describe('checkDocsProgressiveDisclosure', () => {
436
436
  }),
437
437
  docsCatalogIssues: [],
438
438
  });
439
- expect(c.status).toBe('fail');
439
+ expect(c.status).toBe('warn');
440
440
  expect(c.message).toMatch(/^2 problems: /);
441
441
  expect(c.message).toContain('huge everything: 41 KB, over the 32 KB one read may return');
442
442
  expect(c.message).toContain('broken: ');
@@ -812,7 +812,7 @@ describe('checkDocsProgressiveDisclosure languages', () => {
812
812
  docsCatalog: DocsCatalog.fromBuiltins({deploying: path.join(dir, 'deploying.doc.mjs')}),
813
813
  docsCatalogIssues: [],
814
814
  });
815
- expect(c.status).toBe('fail');
815
+ expect(c.status).toBe('warn');
816
816
  expect(c.message).toContain('deploying [zh]: zh overlay broken');
817
817
  expect(c.message).toContain('deploying [dense] overview: 41 KB');
818
818
  expect(c.message).not.toMatch(/deploying overview:/);
@@ -0,0 +1,63 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import transform from '../migrate-native-picker-to-presentation.mjs';
5
+
6
+ async function applyTransform(source) {
7
+ const jscodeshift = (await import('jscodeshift')).default;
8
+ const j = jscodeshift.withParser('tsx');
9
+ const api = {jscodeshift: j, stats: () => {}, report: () => {}};
10
+ return transform({source, path: 'test.tsx'}, api) ?? source;
11
+ }
12
+
13
+ describe('migrate-native-picker-to-presentation', () => {
14
+ it('maps DateInput and DateTimeInput values (FR3)', async () => {
15
+ const output =
16
+ await applyTransform(`import {DateInput, DateTimeInput} from '@astryxdesign/core';
17
+ const a = <DateInput label="d" nativePicker="touch" />;
18
+ const b = <DateInput label="d" nativePicker="always" />;
19
+ const c = <DateTimeInput label="dt" nativePicker="never" />;`);
20
+
21
+ expect(output).toContain("presentation='adaptive-native'");
22
+ expect(output).toContain("presentation='native'");
23
+ expect(output).toContain("presentation='adaptive-bottom-sheet'");
24
+ expect(output).not.toContain('nativePicker');
25
+ });
26
+
27
+ it('maps TimeInput never to text-input (FR3)', async () => {
28
+ const output =
29
+ await applyTransform(`import {TimeInput} from '@astryxdesign/core';
30
+ const a = <TimeInput label="t" nativePicker="never" />;
31
+ const b = <TimeInput label="t" nativePicker={'touch'} />;`);
32
+
33
+ expect(output).toContain("presentation='text-input'");
34
+ expect(output).toContain("presentation={'adaptive-native'}");
35
+ });
36
+
37
+ it('drops nativePicker when presentation is already set (FR4)', async () => {
38
+ const output =
39
+ await applyTransform(`import {DateInput} from '@astryxdesign/core';
40
+ const a = <DateInput label="d" presentation="popover" nativePicker="always" />;`);
41
+
42
+ expect(output).toContain('presentation="popover"');
43
+ expect(output).not.toContain('nativePicker');
44
+ });
45
+
46
+ it('leaves dynamic values and unrelated components unchanged', async () => {
47
+ const source = `import {DateInput, Selector} from '@astryxdesign/core';
48
+ const a = <DateInput label="d" nativePicker={mode} />;
49
+ const b = <Selector nativePicker="never" />;`;
50
+ expect(await applyTransform(source)).toBe(source);
51
+ });
52
+
53
+ it('leaves a mixed static/dynamic conditional byte-identical when a sibling migrates', async () => {
54
+ const output =
55
+ await applyTransform(`import {TimeInput} from '@astryxdesign/core';
56
+ const a = <TimeInput label="t" nativePicker="touch" />;
57
+ const b = <TimeInput label="t" nativePicker={flag ? 'always' : mode} />;`);
58
+
59
+ expect(output).toContain("presentation='adaptive-native'");
60
+ expect(output).toContain("nativePicker={flag ? 'always' : mode}");
61
+ expect(output).not.toContain("'native'");
62
+ });
63
+ });
@@ -81,6 +81,7 @@ describe('migrate-theme-catalog-to-descriptors', () => {
81
81
  it('is staged for the next release as a project codemod', () => {
82
82
  expect(manifest.map(t => [t.name, t.meta.codemodType])).toEqual([
83
83
  ['migrate-theme-catalog-to-descriptors', 'project'],
84
+ ['migrate-native-picker-to-presentation', undefined],
84
85
  ]);
85
86
  });
86
87
 
@@ -135,6 +136,9 @@ describe('migrate-theme-catalog-to-descriptors', () => {
135
136
 
136
137
  it('previews without writing, even with no source folder', async () => {
137
138
  writeKit([entry('ocean')]);
139
+ // A staged code codemod (migrate-native-picker-to-presentation) requires
140
+ // the source folder to exist; an empty one exercises the same preview.
141
+ fs.mkdirSync(path.join(root, 'src'), {recursive: true});
138
142
 
139
143
  const result = await run(false, path.join(root, 'src'));
140
144
 
@@ -10,6 +10,9 @@
10
10
  import migrateThemeCatalogToDescriptors, {
11
11
  meta as migrateThemeCatalogToDescriptorsMeta,
12
12
  } from './migrate-theme-catalog-to-descriptors.mjs';
13
+ import migrateNativePickerToPresentation, {
14
+ meta as migrateNativePickerToPresentationMeta,
15
+ } from './migrate-native-picker-to-presentation.mjs';
13
16
 
14
17
  export default [
15
18
  {
@@ -17,4 +20,9 @@ export default [
17
20
  transform: migrateThemeCatalogToDescriptors,
18
21
  meta: migrateThemeCatalogToDescriptorsMeta,
19
22
  },
23
+ {
24
+ name: 'migrate-native-picker-to-presentation',
25
+ transform: migrateNativePickerToPresentation,
26
+ meta: migrateNativePickerToPresentationMeta,
27
+ },
20
28
  ];
@@ -0,0 +1,148 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Codemod: migrate nativePicker to presentation on date/time inputs
5
+ *
6
+ * `spec:AST-043` FR3 mapping, applied only to static literals written
7
+ * directly on imported `DateInput`, `DateTimeInput`, and `TimeInput`
8
+ * elements: the prop is renamed to `presentation` and its value mapped.
9
+ * When the element already sets `presentation`, the deprecated prop is
10
+ * removed (presentation wins, FR4). Dynamic values are left unchanged —
11
+ * the deprecated prop keeps working, so an unmigrated callsite is still
12
+ * correct, and guessing at an expression's values would not be.
13
+ */
14
+
15
+ import {transformProp} from '../../transform-prop.mjs';
16
+
17
+ export const meta = {
18
+ title: 'Migrate nativePicker to presentation',
19
+ description:
20
+ 'Renames `nativePicker` to `presentation` on DateInput, DateTimeInput, ' +
21
+ 'and TimeInput, mapping touch→adaptive-native, always→native, and ' +
22
+ 'never→adaptive-bottom-sheet (text-input for TimeInput). Dynamic ' +
23
+ 'values are left for manual migration; the deprecated prop still works.',
24
+ };
25
+
26
+ const CORE_IMPORT_RE = /^@(astryxdesign|xds)\/core(?:\/|$)/;
27
+
28
+ const COMPONENT_PROPS = new Map([
29
+ ['DateInput', new Set(['nativePicker'])],
30
+ ['DateTimeInput', new Set(['nativePicker'])],
31
+ ['TimeInput', new Set(['nativePicker'])],
32
+ ]);
33
+
34
+ /** @param {string} component @param {string} value */
35
+ function mapValue(component, value) {
36
+ switch (value) {
37
+ case 'touch':
38
+ return 'adaptive-native';
39
+ case 'always':
40
+ return 'native';
41
+ case 'never':
42
+ return component === 'TimeInput' ? 'text-input' : 'adaptive-bottom-sheet';
43
+ default:
44
+ return undefined;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Collect the string-literal leaves of a value expression without mutating
50
+ * anything. Returns false for any dynamic or non-string node.
51
+ * @param {any} node
52
+ * @param {any[]} leaves
53
+ * @returns {boolean}
54
+ */
55
+ function collectStaticLeaves(node, leaves) {
56
+ if (!node) return false;
57
+ if (
58
+ node.type === 'TSAsExpression' ||
59
+ node.type === 'TSSatisfiesExpression' ||
60
+ node.type === 'TypeCastExpression' ||
61
+ node.type === 'ParenthesizedExpression'
62
+ ) {
63
+ return collectStaticLeaves(node.expression, leaves);
64
+ }
65
+ if (node.type === 'ConditionalExpression') {
66
+ return (
67
+ collectStaticLeaves(node.consequent, leaves) &&
68
+ collectStaticLeaves(node.alternate, leaves)
69
+ );
70
+ }
71
+ if (
72
+ (node.type !== 'StringLiteral' && node.type !== 'Literal') ||
73
+ typeof node.value !== 'string'
74
+ ) {
75
+ return false;
76
+ }
77
+ leaves.push(node);
78
+ return true;
79
+ }
80
+
81
+ /**
82
+ * Map every leaf, or none of them: a mixed static/dynamic conditional must
83
+ * stay byte-identical, never half-migrated.
84
+ * @param {any} node
85
+ * @param {string} component
86
+ */
87
+ function mapStaticValue(node, component) {
88
+ /** @type {any[]} */
89
+ const leaves = [];
90
+ if (!collectStaticLeaves(node, leaves)) return false;
91
+ if (leaves.some(leaf => mapValue(component, leaf.value) === undefined)) {
92
+ return false;
93
+ }
94
+ for (const leaf of leaves) {
95
+ leaf.value = mapValue(component, leaf.value);
96
+ if (leaf.raw) leaf.raw = undefined;
97
+ }
98
+ return true;
99
+ }
100
+
101
+ /**
102
+ * @param {import('../../../../authoring/codemod/type').AstryxCodemodFile} file
103
+ * @param {import('../../../../authoring/codemod/type').CodemodTransformApi} api
104
+ * @returns {string | null | undefined}
105
+ */
106
+ export default function transformer(file, api) {
107
+ if (!file.source.includes('nativePicker')) return undefined;
108
+ const j = api.jscodeshift;
109
+ const root = j(file.source);
110
+ let hasChanges = false;
111
+
112
+ transformProp(
113
+ root,
114
+ j,
115
+ {
116
+ matchesImport: source => CORE_IMPORT_RE.test(source),
117
+ components: COMPONENT_PROPS,
118
+ },
119
+ (propPath, {component}) => {
120
+ const opening = propPath.parent?.node;
121
+ const attributes = opening?.attributes ?? [];
122
+ const hasPresentation = attributes.some(
123
+ (/** @type {any} */ attribute) =>
124
+ attribute.type === 'JSXAttribute' &&
125
+ attribute.name?.name === 'presentation',
126
+ );
127
+ const prop = propPath.node;
128
+ if (hasPresentation) {
129
+ // FR4: presentation wins; drop the deprecated prop.
130
+ opening.attributes = attributes.filter(
131
+ (/** @type {any} */ attribute) => attribute !== prop,
132
+ );
133
+ hasChanges = true;
134
+ return;
135
+ }
136
+ const value =
137
+ prop.value?.type === 'JSXExpressionContainer'
138
+ ? prop.value.expression
139
+ : prop.value;
140
+ if (!mapStaticValue(value, component)) return;
141
+ prop.name.name = 'presentation';
142
+ hasChanges = true;
143
+ },
144
+ );
145
+
146
+ if (!hasChanges) return undefined;
147
+ return root.toSource({quote: 'single'});
148
+ }
@@ -41,7 +41,7 @@ export default function DateInputDateRange() {
41
41
  max={max}
42
42
  description={description}
43
43
  placeholder="Select a booking date"
44
- nativePicker="never"
44
+ presentation="adaptive-bottom-sheet"
45
45
  value={value}
46
46
  onChange={setValue}
47
47
  />
@@ -17,6 +17,7 @@ export default function TimeInputConstrained() {
17
17
  max={'22:00' as never}
18
18
  description="Evening seating: 5 PM – 10 PM"
19
19
  placeholder="Select reservation time"
20
+ presentation="adaptive-bottom-sheet"
20
21
  value={evening as never}
21
22
  onChange={setEvening as never}
22
23
  hasClear
@@ -25,7 +25,7 @@ export namespace AuthoredDocGraphFields {
25
25
  internal: "internal";
26
26
  }>>;
27
27
  }
28
- /** Runtime schema for every existing and V1 semantic content block. */
28
+ /** Runtime schema for the stable content-block union published in 0.6.x. */
29
29
  export const ReferenceContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
30
30
  type: z.ZodLiteral<"prose">;
31
31
  text: z.ZodString;
@@ -55,6 +55,74 @@ export const ReferenceContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
55
55
  type: z.ZodLiteral<"token-ref">;
56
56
  topic: z.ZodString;
57
57
  section: z.ZodString;
58
+ }, z.core.$strict>], "type">;
59
+ /** Runtime schema for graph-only blocks used by NamespaceDoc. */
60
+ export const GraphContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
61
+ type: z.ZodLiteral<"workflow">;
62
+ title: z.ZodOptional<z.ZodString>;
63
+ steps: z.ZodArray<z.ZodObject<{
64
+ title: z.ZodString;
65
+ description: z.ZodOptional<z.ZodString>;
66
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
67
+ }, z.core.$strict>>;
68
+ }, z.core.$strict>, z.ZodObject<{
69
+ type: z.ZodLiteral<"collection">;
70
+ title: z.ZodOptional<z.ZodString>;
71
+ source: z.ZodObject<{
72
+ slot: z.ZodString;
73
+ }, z.core.$strict>;
74
+ presentation: z.ZodOptional<z.ZodEnum<{
75
+ list: "list";
76
+ cards: "cards";
77
+ compact: "compact";
78
+ }>>;
79
+ whenEmpty: z.ZodOptional<z.ZodEnum<{
80
+ show: "show";
81
+ omit: "omit";
82
+ }>>;
83
+ }, z.core.$strict>, z.ZodObject<{
84
+ type: z.ZodLiteral<"reference">;
85
+ target: z.ZodString;
86
+ projection: z.ZodOptional<z.ZodObject<{
87
+ fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
88
+ sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
89
+ }, z.core.$strict>>;
90
+ presentation: z.ZodOptional<z.ZodEnum<{
91
+ compact: "compact";
92
+ summary: "summary";
93
+ full: "full";
94
+ }>>;
95
+ }, z.core.$strict>], "type">;
96
+ /** Namespace content accepts both stable reference blocks and graph-only blocks. */
97
+ export const NamespaceContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
98
+ type: z.ZodLiteral<"prose">;
99
+ text: z.ZodString;
100
+ }, z.core.$strict>, z.ZodObject<{
101
+ type: z.ZodLiteral<"heading">;
102
+ level: z.ZodUnion<readonly [z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>, z.ZodLiteral<6>]>;
103
+ text: z.ZodString;
104
+ }, z.core.$strict>, z.ZodObject<{
105
+ type: z.ZodLiteral<"code">;
106
+ lang: z.ZodString;
107
+ code: z.ZodString;
108
+ label: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strict>, z.ZodObject<{
110
+ type: z.ZodLiteral<"table">;
111
+ headers: z.ZodArray<z.ZodString>;
112
+ rows: z.ZodArray<z.ZodArray<z.ZodString>>;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ type: z.ZodLiteral<"list">;
115
+ style: z.ZodEnum<{
116
+ ordered: "ordered";
117
+ unordered: "unordered";
118
+ do: "do";
119
+ dont: "dont";
120
+ }>;
121
+ items: z.ZodArray<z.ZodString>;
122
+ }, z.core.$strict>, z.ZodObject<{
123
+ type: z.ZodLiteral<"token-ref">;
124
+ topic: z.ZodString;
125
+ section: z.ZodString;
58
126
  }, z.core.$strict>, z.ZodObject<{
59
127
  type: z.ZodLiteral<"workflow">;
60
128
  title: z.ZodOptional<z.ZodString>;
@@ -235,41 +303,6 @@ export const GenericDocKindSchema: z.ZodObject<{
235
303
  type: z.ZodLiteral<"token-ref">;
236
304
  topic: z.ZodString;
237
305
  section: z.ZodString;
238
- }, z.core.$strict>, z.ZodObject<{
239
- type: z.ZodLiteral<"workflow">;
240
- title: z.ZodOptional<z.ZodString>;
241
- steps: z.ZodArray<z.ZodObject<{
242
- title: z.ZodString;
243
- description: z.ZodOptional<z.ZodString>;
244
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
245
- }, z.core.$strict>>;
246
- }, z.core.$strict>, z.ZodObject<{
247
- type: z.ZodLiteral<"collection">;
248
- title: z.ZodOptional<z.ZodString>;
249
- source: z.ZodObject<{
250
- slot: z.ZodString;
251
- }, z.core.$strict>;
252
- presentation: z.ZodOptional<z.ZodEnum<{
253
- list: "list";
254
- cards: "cards";
255
- compact: "compact";
256
- }>>;
257
- whenEmpty: z.ZodOptional<z.ZodEnum<{
258
- show: "show";
259
- omit: "omit";
260
- }>>;
261
- }, z.core.$strict>, z.ZodObject<{
262
- type: z.ZodLiteral<"reference">;
263
- target: z.ZodString;
264
- projection: z.ZodOptional<z.ZodObject<{
265
- fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
266
- sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
267
- }, z.core.$strict>>;
268
- presentation: z.ZodOptional<z.ZodEnum<{
269
- compact: "compact";
270
- summary: "summary";
271
- full: "full";
272
- }>>;
273
306
  }, z.core.$strict>], "type">>;
274
307
  previewType: z.ZodOptional<z.ZodEnum<{
275
308
  swatch: "swatch";
@@ -351,41 +384,6 @@ export const SchemaDocKindSchema: z.ZodObject<{
351
384
  type: z.ZodLiteral<"token-ref">;
352
385
  topic: z.ZodString;
353
386
  section: z.ZodString;
354
- }, z.core.$strict>, z.ZodObject<{
355
- type: z.ZodLiteral<"workflow">;
356
- title: z.ZodOptional<z.ZodString>;
357
- steps: z.ZodArray<z.ZodObject<{
358
- title: z.ZodString;
359
- description: z.ZodOptional<z.ZodString>;
360
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
361
- }, z.core.$strict>>;
362
- }, z.core.$strict>, z.ZodObject<{
363
- type: z.ZodLiteral<"collection">;
364
- title: z.ZodOptional<z.ZodString>;
365
- source: z.ZodObject<{
366
- slot: z.ZodString;
367
- }, z.core.$strict>;
368
- presentation: z.ZodOptional<z.ZodEnum<{
369
- list: "list";
370
- cards: "cards";
371
- compact: "compact";
372
- }>>;
373
- whenEmpty: z.ZodOptional<z.ZodEnum<{
374
- show: "show";
375
- omit: "omit";
376
- }>>;
377
- }, z.core.$strict>, z.ZodObject<{
378
- type: z.ZodLiteral<"reference">;
379
- target: z.ZodString;
380
- projection: z.ZodOptional<z.ZodObject<{
381
- fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
382
- sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
383
- }, z.core.$strict>>;
384
- presentation: z.ZodOptional<z.ZodEnum<{
385
- compact: "compact";
386
- summary: "summary";
387
- full: "full";
388
- }>>;
389
387
  }, z.core.$strict>], "type">>>;
390
388
  placement: z.ZodOptional<z.ZodObject<{
391
389
  parent: z.ZodString;
@@ -470,41 +468,6 @@ export const CommandDocKindSchema: z.ZodObject<{
470
468
  type: z.ZodLiteral<"token-ref">;
471
469
  topic: z.ZodString;
472
470
  section: z.ZodString;
473
- }, z.core.$strict>, z.ZodObject<{
474
- type: z.ZodLiteral<"workflow">;
475
- title: z.ZodOptional<z.ZodString>;
476
- steps: z.ZodArray<z.ZodObject<{
477
- title: z.ZodString;
478
- description: z.ZodOptional<z.ZodString>;
479
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
480
- }, z.core.$strict>>;
481
- }, z.core.$strict>, z.ZodObject<{
482
- type: z.ZodLiteral<"collection">;
483
- title: z.ZodOptional<z.ZodString>;
484
- source: z.ZodObject<{
485
- slot: z.ZodString;
486
- }, z.core.$strict>;
487
- presentation: z.ZodOptional<z.ZodEnum<{
488
- list: "list";
489
- cards: "cards";
490
- compact: "compact";
491
- }>>;
492
- whenEmpty: z.ZodOptional<z.ZodEnum<{
493
- show: "show";
494
- omit: "omit";
495
- }>>;
496
- }, z.core.$strict>, z.ZodObject<{
497
- type: z.ZodLiteral<"reference">;
498
- target: z.ZodString;
499
- projection: z.ZodOptional<z.ZodObject<{
500
- fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
501
- sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
502
- }, z.core.$strict>>;
503
- presentation: z.ZodOptional<z.ZodEnum<{
504
- compact: "compact";
505
- summary: "summary";
506
- full: "full";
507
- }>>;
508
471
  }, z.core.$strict>], "type">>>;
509
472
  placement: z.ZodOptional<z.ZodObject<{
510
473
  parent: z.ZodString;
@@ -877,41 +840,6 @@ export const LegacyDocSchema: z.ZodUnion<readonly [z.ZodObject<{
877
840
  type: z.ZodLiteral<"token-ref">;
878
841
  topic: z.ZodString;
879
842
  section: z.ZodString;
880
- }, z.core.$strict>, z.ZodObject<{
881
- type: z.ZodLiteral<"workflow">;
882
- title: z.ZodOptional<z.ZodString>;
883
- steps: z.ZodArray<z.ZodObject<{
884
- title: z.ZodString;
885
- description: z.ZodOptional<z.ZodString>;
886
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
887
- }, z.core.$strict>>;
888
- }, z.core.$strict>, z.ZodObject<{
889
- type: z.ZodLiteral<"collection">;
890
- title: z.ZodOptional<z.ZodString>;
891
- source: z.ZodObject<{
892
- slot: z.ZodString;
893
- }, z.core.$strict>;
894
- presentation: z.ZodOptional<z.ZodEnum<{
895
- list: "list";
896
- cards: "cards";
897
- compact: "compact";
898
- }>>;
899
- whenEmpty: z.ZodOptional<z.ZodEnum<{
900
- show: "show";
901
- omit: "omit";
902
- }>>;
903
- }, z.core.$strict>, z.ZodObject<{
904
- type: z.ZodLiteral<"reference">;
905
- target: z.ZodString;
906
- projection: z.ZodOptional<z.ZodObject<{
907
- fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
908
- sections: z.ZodOptional<z.ZodArray<z.ZodString>>;
909
- }, z.core.$strict>>;
910
- presentation: z.ZodOptional<z.ZodEnum<{
911
- compact: "compact";
912
- summary: "summary";
913
- full: "full";
914
- }>>;
915
843
  }, z.core.$strict>], "type">>;
916
844
  previewType: z.ZodOptional<z.ZodEnum<{
917
845
  swatch: "swatch";
@@ -933,6 +861,7 @@ export type AuthoredDocGraphFieldsType = import("./base/type.js").AuthoredDocGra
933
861
  export type AuthoredDocKind = import("./base/type.js").AuthoredDocKind;
934
862
  export type NamespaceDoc = import("./namespace/type.js").NamespaceDoc;
935
863
  export type ReferenceContentBlock = import("./reference/type.js").ReferenceContentBlock;
864
+ export type GraphContentBlock = import("./reference/type.js").GraphContentBlock;
936
865
  export type ReferenceDoc = import("./reference/type.js").ReferenceDoc;
937
866
  export type SingleComponentDoc = import("./component/type.js").SingleComponentDoc;
938
867
  export type ComponentPropDoc = import("./base/type.js").ComponentPropDoc;
@@ -944,6 +873,7 @@ export type EnumDoc = import("./enum/type.js").EnumDoc;
944
873
  export type _AuthoredDocKindDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof AuthoredDocKindSchema>, AuthoredDocKind>>;
945
874
  export type _AuthoredDocGraphDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<z.infer<typeof _AuthoredDocGraphSchema>, AuthoredDocGraphFieldsType>>;
946
875
  export type _ReferenceContentBlockDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof ReferenceContentBlockSchema>, ReferenceContentBlock>>;
876
+ export type _GraphContentBlockDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof GraphContentBlockSchema>, GraphContentBlock>>;
947
877
  /**
948
878
  * A stamped component doc as it loads. The loader accepts what the unstamped
949
879
  * format always accepted, so stamping an existing doc never breaks it: