@astryxdesign/cli 0.6.3-canary.98a2e4e → 0.6.3-canary.9e4c545

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 (88) hide show
  1. package/api/docs/_adapter.d.mts +30 -27
  2. package/api/docs/_adapter.mjs +154 -124
  3. package/api/docs/compiled-topics.test.mjs +78 -0
  4. package/api/docs/detail/detail.d.mts +0 -15
  5. package/api/docs/detail/detail.mjs +14 -78
  6. package/api/docs/detail/section/section.mjs +22 -18
  7. package/api/docs/detail/section/section.test.mjs +4 -3
  8. package/api/docs/index/index.mjs +6 -5
  9. package/api/doctor/doctor.mjs +3 -7
  10. package/api/search/search.mjs +5 -5
  11. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  12. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  13. package/authoring/_shared/contract.ts +22 -0
  14. package/authoring/codemod/codemod.doc.mjs +6 -1
  15. package/authoring/codemod/parse.d.mts +8 -8
  16. package/authoring/codemod/parse.mjs +8 -6
  17. package/authoring/config/parse.d.mts +13 -13
  18. package/authoring/config/parse.mjs +8 -8
  19. package/authoring/config/type.ts +3 -3
  20. package/authoring/debug/parse.d.mts +4 -4
  21. package/authoring/debug/parse.mjs +3 -3
  22. package/authoring/doctypes/_schema.d.mts +121 -11
  23. package/authoring/doctypes/_schema.mjs +144 -13
  24. package/authoring/doctypes/base/graph-fields.doc.mjs +11 -4
  25. package/authoring/doctypes/base/type.ts +8 -4
  26. package/authoring/doctypes/command/command.doc.mjs +3 -2
  27. package/authoring/doctypes/command/parse.d.mts +2 -2
  28. package/authoring/doctypes/command/parse.mjs +1 -1
  29. package/authoring/doctypes/command/type.ts +2 -2
  30. package/authoring/doctypes/component/component.doc.mjs +5 -2
  31. package/authoring/doctypes/component/parse.d.mts +2 -2
  32. package/authoring/doctypes/component/parse.mjs +1 -1
  33. package/authoring/doctypes/component/type.ts +1 -1
  34. package/authoring/doctypes/enum/parse.d.mts +2 -2
  35. package/authoring/doctypes/enum/parse.mjs +1 -1
  36. package/authoring/doctypes/enum/type.ts +1 -1
  37. package/authoring/doctypes/function/function.doc.mjs +4 -0
  38. package/authoring/doctypes/function/parse.d.mts +2 -2
  39. package/authoring/doctypes/function/parse.mjs +1 -1
  40. package/authoring/doctypes/function/type.ts +1 -1
  41. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  42. package/authoring/doctypes/hook/parse.d.mts +2 -2
  43. package/authoring/doctypes/hook/parse.mjs +1 -1
  44. package/authoring/doctypes/hook/type.ts +1 -1
  45. package/authoring/doctypes/legacy.d.mts +6 -6
  46. package/authoring/doctypes/legacy.mjs +3 -3
  47. package/authoring/doctypes/load-contract.test.mjs +207 -0
  48. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -3
  49. package/authoring/doctypes/namespace/parse.d.mts +2 -2
  50. package/authoring/doctypes/namespace/parse.mjs +1 -1
  51. package/authoring/doctypes/namespace/type.ts +2 -2
  52. package/authoring/doctypes/parse.d.mts +18 -18
  53. package/authoring/doctypes/parse.mjs +9 -9
  54. package/authoring/doctypes/reference/parse.d.mts +2 -2
  55. package/authoring/doctypes/reference/parse.mjs +1 -1
  56. package/authoring/doctypes/reference/reference.doc.mjs +6 -2
  57. package/authoring/doctypes/reference/type.ts +1 -1
  58. package/authoring/doctypes/schema/parse.d.mts +2 -2
  59. package/authoring/doctypes/schema/parse.mjs +1 -1
  60. package/authoring/doctypes/schema/type.ts +2 -2
  61. package/authoring/doctypes/template/parse.d.mts +92 -1
  62. package/authoring/doctypes/template/parse.mjs +33 -1
  63. package/authoring/doctypes/template/template.doc.mjs +4 -0
  64. package/authoring/doctypes/template/type.ts +4 -1
  65. package/authoring/doctypes/types.ts +10 -10
  66. package/authoring/gap-report/parse.d.mts +9 -9
  67. package/authoring/gap-report/parse.mjs +6 -6
  68. package/authoring/gap-report/type.ts +1 -1
  69. package/authoring/identity/identity.doc.mjs +3 -2
  70. package/authoring/identity/type.ts +10 -10
  71. package/authoring/index.d.ts +19 -19
  72. package/authoring/integration/parse.d.mts +2 -2
  73. package/authoring/integration/parse.mjs +1 -1
  74. package/authoring/integration/schema.d.mts +4 -4
  75. package/authoring/integration/schema.mjs +3 -3
  76. package/authoring/integration/type.ts +1 -1
  77. package/foundation/discovery/authoring-self-docs.test.mjs +71 -12
  78. package/foundation/discovery/docs-discovery.d.mts +4 -0
  79. package/foundation/discovery/docs-discovery.mjs +16 -2
  80. package/foundation/discovery/docs-discovery.test.mjs +47 -11
  81. package/foundation/doc-compiler/compile.d.mts +162 -0
  82. package/foundation/doc-compiler/compile.mjs +262 -0
  83. package/foundation/doc-compiler/doc-compiler.test.mjs +687 -0
  84. package/foundation/doc-compiler/ir.d.mts +9 -0
  85. package/foundation/doc-compiler/ir.mjs +287 -0
  86. package/foundation/doc-compiler/lenses.d.mts +33 -0
  87. package/foundation/doc-compiler/lenses.mjs +127 -0
  88. package/package.json +9 -9
@@ -91,7 +91,12 @@ export const ReferenceContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
91
91
  full: "full";
92
92
  }>>;
93
93
  }, z.core.$strict>], "type">;
94
- /** New-format stamped component doc (`type: 'component'`). */
94
+ /**
95
+ * New-format stamped component doc (`type: 'component'`): one component's
96
+ * `props`, or the `components` a group doc documents together. These are the
97
+ * shapes the published ComponentDoc type allows, and the ones an unstamped doc
98
+ * may already take.
99
+ */
95
100
  export const ComponentDocKindSchema: z.ZodObject<{
96
101
  type: z.ZodLiteral<"component">;
97
102
  theming: z.ZodOptional<z.ZodUnknown>;
@@ -119,13 +124,16 @@ export const ComponentDocKindSchema: z.ZodObject<{
119
124
  public: "public";
120
125
  internal: "internal";
121
126
  }>>;
122
- props: z.ZodArray<z.ZodObject<{
127
+ props: z.ZodOptional<z.ZodArray<z.ZodObject<{
123
128
  name: z.ZodString;
124
129
  type: z.ZodString;
125
130
  description: z.ZodString;
126
131
  default: z.ZodOptional<z.ZodString>;
127
132
  required: z.ZodOptional<z.ZodBoolean>;
128
- }, z.core.$loose>>;
133
+ }, z.core.$loose>>>;
134
+ components: z.ZodOptional<z.ZodArray<z.ZodObject<{
135
+ name: z.ZodString;
136
+ }, z.core.$loose>>>;
129
137
  }, z.core.$loose>;
130
138
  /** New-format stamped function doc (`type: 'function'`). */
131
139
  export const FunctionDocKindSchema: z.ZodObject<{
@@ -165,6 +173,26 @@ export const FunctionDocKindSchema: z.ZodObject<{
165
173
  internal: "internal";
166
174
  }>>;
167
175
  }, z.core.$loose>;
176
+ /**
177
+ * A stamped function doc as it loads: as with components, `displayName` may be
178
+ * missing and `usage` passes through unchecked.
179
+ *
180
+ * @typedef {Omit<FunctionDoc, 'type' | 'displayName' | 'usage'>
181
+ * & {type: 'function', displayName?: string, usage?: unknown}} LoadedFunctionDoc
182
+ */
183
+ /**
184
+ * @typedef {import('../_shared/contract.js').Expect<
185
+ * import('../_shared/contract.js').MutuallyAssignable<
186
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof FunctionDocKindSchema>>,
187
+ * import('../_shared/contract.js').NamedFields<LoadedFunctionDoc>
188
+ * >
189
+ * >} _FunctionDocDriftLock
190
+ */
191
+ /**
192
+ * Every HookDoc is a FunctionDoc, so the one function schema covers both.
193
+ *
194
+ * @typedef {import('../_shared/contract.js').Expect<[HookDoc] extends [FunctionDoc] ? true : false>} _HookDocIsFunctionDocLock
195
+ */
168
196
  /**
169
197
  * Stamped generic reference/topic doc (`type: 'generic'`). `title` and
170
198
  * `sections` stay optional at this parser boundary for docs produced by the
@@ -289,7 +317,7 @@ export const SchemaDocKindSchema: z.ZodObject<{
289
317
  description: z.ZodString;
290
318
  namespace: z.ZodOptional<z.ZodString>;
291
319
  appliesTo: z.ZodOptional<z.ZodString>;
292
- fields: z.ZodArray<z.ZodType<import("./schema/type").SchemaFieldDoc, any, z.core.$ZodTypeInternals<import("./schema/type").SchemaFieldDoc, any>>>;
320
+ fields: z.ZodArray<z.ZodType<import("./schema/type.js").SchemaFieldDoc, any, z.core.$ZodTypeInternals<import("./schema/type.js").SchemaFieldDoc, any>>>;
293
321
  examples: z.ZodOptional<z.ZodArray<z.ZodObject<{
294
322
  label: z.ZodOptional<z.ZodString>;
295
323
  code: z.ZodString;
@@ -370,6 +398,14 @@ export const SchemaDocKindSchema: z.ZodObject<{
370
398
  internal: "internal";
371
399
  }>>;
372
400
  }, z.core.$loose>;
401
+ /**
402
+ * @typedef {import('../_shared/contract.js').Expect<
403
+ * import('../_shared/contract.js').MutuallyAssignable<
404
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof SchemaDocKindSchema>>,
405
+ * import('../_shared/contract.js').NamedFields<SchemaDoc & {type: 'schema'}>
406
+ * >
407
+ * >} _SchemaDocDriftLock
408
+ */
373
409
  /** New stamped command doc (`type: 'command'`). */
374
410
  export const CommandDocKindSchema: z.ZodObject<{
375
411
  type: z.ZodLiteral<"command">;
@@ -481,6 +517,14 @@ export const CommandDocKindSchema: z.ZodObject<{
481
517
  internal: "internal";
482
518
  }>>;
483
519
  }, z.core.$loose>;
520
+ /**
521
+ * @typedef {import('../_shared/contract.js').Expect<
522
+ * import('../_shared/contract.js').MutuallyAssignable<
523
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof CommandDocKindSchema>>,
524
+ * import('../_shared/contract.js').NamedFields<CommandDoc & {type: 'command'}>
525
+ * >
526
+ * >} _CommandDocDriftLock
527
+ */
484
528
  /** New stamped enum doc (`type: 'enum'`). */
485
529
  export const EnumDocKindSchema: z.ZodObject<{
486
530
  type: z.ZodLiteral<"enum">;
@@ -885,13 +929,79 @@ export const LegacyDocSchema: z.ZodUnion<readonly [z.ZodObject<{
885
929
  extends: z.ZodOptional<z.ZodString>;
886
930
  tokenCategory: z.ZodOptional<z.ZodString>;
887
931
  }, z.core.$loose>]>;
888
- export type AuthoredDocGraphFieldsType = import("./base/type").AuthoredDocGraphFields;
889
- export type AuthoredDocKind = import("./base/type").AuthoredDocKind;
890
- export type NamespaceDoc = import("./namespace/type").NamespaceDoc;
891
- export type ReferenceContentBlock = import("./reference/type").ReferenceContentBlock;
892
- export type _AuthoredDocGraphDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").MutuallyAssignable<z.infer<typeof _AuthoredDocGraphSchema>, AuthoredDocGraphFieldsType>>;
893
- export type _ReferenceContentBlockDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").Equal<z.infer<typeof ReferenceContentBlockSchema>, ReferenceContentBlock>>;
894
- export type _NamespaceDocDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").Equal<z.infer<typeof NamespaceDocKindSchema>, NamespaceDoc>>;
932
+ export type AuthoredDocGraphFieldsType = import("./base/type.js").AuthoredDocGraphFields;
933
+ export type AuthoredDocKind = import("./base/type.js").AuthoredDocKind;
934
+ export type NamespaceDoc = import("./namespace/type.js").NamespaceDoc;
935
+ export type ReferenceContentBlock = import("./reference/type.js").ReferenceContentBlock;
936
+ export type ReferenceDoc = import("./reference/type.js").ReferenceDoc;
937
+ export type SingleComponentDoc = import("./component/type.js").SingleComponentDoc;
938
+ export type ComponentPropDoc = import("./base/type.js").ComponentPropDoc;
939
+ export type HookDoc = import("./hook/type.js").HookDoc;
940
+ export type FunctionDoc = import("./function/type.js").FunctionDoc;
941
+ export type SchemaDoc = import("./schema/type.js").SchemaDoc;
942
+ export type CommandDoc = import("./command/type.js").CommandDoc;
943
+ export type EnumDoc = import("./enum/type.js").EnumDoc;
944
+ export type _AuthoredDocKindDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof AuthoredDocKindSchema>, AuthoredDocKind>>;
945
+ export type _AuthoredDocGraphDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<z.infer<typeof _AuthoredDocGraphSchema>, AuthoredDocGraphFieldsType>>;
946
+ export type _ReferenceContentBlockDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof ReferenceContentBlockSchema>, ReferenceContentBlock>>;
947
+ /**
948
+ * A stamped component doc as it loads. The loader accepts what the unstamped
949
+ * format always accepted, so stamping an existing doc never breaks it:
950
+ * `displayName` may be missing, `category` is any string, `usage`, `theming`,
951
+ * `playground` and `examples` pass through unchecked, and a doc has `props`,
952
+ * `components`, or both; each `components` entry needs only a `name`. Every
953
+ * other field matches the published type.
954
+ */
955
+ export type LoadedComponentDoc = Omit<SingleComponentDoc, "type" | "displayName" | "category" | "usage" | "theming" | "examples" | "playground" | "props"> & {
956
+ type: "component";
957
+ displayName?: string;
958
+ category?: string;
959
+ usage?: unknown;
960
+ theming?: unknown;
961
+ examples?: unknown[];
962
+ playground?: unknown;
963
+ props?: ComponentPropDoc[];
964
+ components?: Array<{
965
+ name: string;
966
+ }>;
967
+ };
968
+ export type _ComponentDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof ComponentDocKindSchema>>, import("../_shared/contract.js").NamedFields<LoadedComponentDoc>>>;
969
+ /**
970
+ * A stamped function doc as it loads: as with components, `displayName` may be
971
+ * missing and `usage` passes through unchecked.
972
+ */
973
+ export type LoadedFunctionDoc = Omit<FunctionDoc, "type" | "displayName" | "usage"> & {
974
+ type: "function";
975
+ displayName?: string;
976
+ usage?: unknown;
977
+ };
978
+ export type _FunctionDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof FunctionDocKindSchema>>, import("../_shared/contract.js").NamedFields<LoadedFunctionDoc>>>;
979
+ /**
980
+ * Every HookDoc is a FunctionDoc, so the one function schema covers both.
981
+ */
982
+ export type _HookDocIsFunctionDocLock = import("../_shared/contract.js").Expect<[HookDoc] extends [FunctionDoc] ? true : false>;
983
+ /**
984
+ * A stamped generic doc as the load check accepts it. `title`, `description`
985
+ * and `sections` may be missing, as in docs the v0.3.0 factory-removal codemod
986
+ * produced; `parseReference` then fills them (title from `displayName` or
987
+ * `name`, an empty description, no sections), so its result is a full
988
+ * ReferenceDoc. Only a doc with a description and sections is a usable topic
989
+ * (see `problemsInTopic`).
990
+ */
991
+ export type LoadedReferenceDoc = Omit<ReferenceDoc, "type" | "title" | "description" | "sections"> & {
992
+ type: "generic";
993
+ } & Partial<Pick<ReferenceDoc, "title" | "description" | "sections">>;
994
+ export type _ReferenceDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof GenericDocKindSchema>>, import("../_shared/contract.js").NamedFields<LoadedReferenceDoc>>>;
995
+ export type _SchemaDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof SchemaDocKindSchema>>, import("../_shared/contract.js").NamedFields<SchemaDoc & {
996
+ type: "schema";
997
+ }>>>;
998
+ export type _CommandDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof CommandDocKindSchema>>, import("../_shared/contract.js").NamedFields<CommandDoc & {
999
+ type: "command";
1000
+ }>>>;
1001
+ export type _EnumDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<import("../_shared/contract.js").NamedFields<z.infer<typeof EnumDocKindSchema>>, import("../_shared/contract.js").NamedFields<EnumDoc & {
1002
+ type: "enum";
1003
+ }>>>;
1004
+ export type _NamespaceDocDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof NamespaceDocKindSchema>, NamespaceDoc>>;
895
1005
  import { z } from 'zod';
896
1006
  declare const _AuthoredDocGraphSchema: z.ZodObject<{
897
1007
  placement: z.ZodOptional<z.ZodObject<{
@@ -11,10 +11,18 @@
11
11
 
12
12
  import {z} from 'zod';
13
13
 
14
- /** @typedef {import('./base/type').AuthoredDocGraphFields} AuthoredDocGraphFieldsType */
15
- /** @typedef {import('./base/type').AuthoredDocKind} AuthoredDocKind */
16
- /** @typedef {import('./namespace/type').NamespaceDoc} NamespaceDoc */
17
- /** @typedef {import('./reference/type').ReferenceContentBlock} ReferenceContentBlock */
14
+ /** @typedef {import('./base/type.js').AuthoredDocGraphFields} AuthoredDocGraphFieldsType */
15
+ /** @typedef {import('./base/type.js').AuthoredDocKind} AuthoredDocKind */
16
+ /** @typedef {import('./namespace/type.js').NamespaceDoc} NamespaceDoc */
17
+ /** @typedef {import('./reference/type.js').ReferenceContentBlock} ReferenceContentBlock */
18
+ /** @typedef {import('./reference/type.js').ReferenceDoc} ReferenceDoc */
19
+ /** @typedef {import('./component/type.js').SingleComponentDoc} SingleComponentDoc */
20
+ /** @typedef {import('./base/type.js').ComponentPropDoc} ComponentPropDoc */
21
+ /** @typedef {import('./hook/type.js').HookDoc} HookDoc */
22
+ /** @typedef {import('./function/type.js').FunctionDoc} FunctionDoc */
23
+ /** @typedef {import('./schema/type.js').SchemaDoc} SchemaDoc */
24
+ /** @typedef {import('./command/type.js').CommandDoc} CommandDoc */
25
+ /** @typedef {import('./enum/type.js').EnumDoc} EnumDoc */
18
26
 
19
27
  const nonEmptyString = z.string().min(1);
20
28
 
@@ -31,6 +39,12 @@ export const AuthoredDocKindSchema = z.enum([
31
39
  'namespace',
32
40
  ]);
33
41
 
42
+ /**
43
+ * @typedef {import('../_shared/contract.js').Expect<
44
+ * import('../_shared/contract.js').Equal<z.infer<typeof AuthoredDocKindSchema>, AuthoredDocKind>
45
+ * >} _AuthoredDocKindDriftLock
46
+ */
47
+
34
48
  /** Shared optional graph fields for every authored doc kind. */
35
49
  export const AuthoredDocGraphFields = {
36
50
  placement: z
@@ -48,8 +62,8 @@ export const AuthoredDocGraphFields = {
48
62
  const _AuthoredDocGraphSchema = z.object(AuthoredDocGraphFields).strict();
49
63
 
50
64
  /**
51
- * @typedef {import('../_shared/contract').Expect<
52
- * import('../_shared/contract').MutuallyAssignable<
65
+ * @typedef {import('../_shared/contract.js').Expect<
66
+ * import('../_shared/contract.js').MutuallyAssignable<
53
67
  * z.infer<typeof _AuthoredDocGraphSchema>,
54
68
  * AuthoredDocGraphFieldsType
55
69
  * >
@@ -161,8 +175,8 @@ export const ReferenceContentBlockSchema = z.discriminatedUnion('type', [
161
175
  ]);
162
176
 
163
177
  /**
164
- * @typedef {import('../_shared/contract').Expect<
165
- * import('../_shared/contract').Equal<
178
+ * @typedef {import('../_shared/contract.js').Expect<
179
+ * import('../_shared/contract.js').Equal<
166
180
  * z.infer<typeof ReferenceContentBlockSchema>,
167
181
  * ReferenceContentBlock
168
182
  * >
@@ -245,11 +259,58 @@ const ComponentBaseSchema = z
245
259
  })
246
260
  .passthrough();
247
261
 
248
- /** New-format stamped component doc (`type: 'component'`). */
262
+ /**
263
+ * One entry in a group doc's `components`: a full ComponentEntry or a
264
+ * name-only ComponentRef. Readers look every entry up by `name`, so that much
265
+ * is checked here; the rest passes through, as on an unstamped doc.
266
+ */
267
+ const ComponentGroupEntrySchema = z
268
+ .object({name: z.string().min(1, 'component name is required')})
269
+ .passthrough();
270
+
271
+ /**
272
+ * New-format stamped component doc (`type: 'component'`): one component's
273
+ * `props`, or the `components` a group doc documents together. These are the
274
+ * shapes the published ComponentDoc type allows, and the ones an unstamped doc
275
+ * may already take.
276
+ */
249
277
  export const ComponentDocKindSchema = ComponentBaseSchema.extend({
250
- props: z.array(PropSchema),
278
+ props: z.array(PropSchema).optional(),
279
+ components: z.array(ComponentGroupEntrySchema).optional(),
280
+ }).superRefine((doc, context) => {
281
+ if (doc.props == null && doc.components == null) {
282
+ context.addIssue({
283
+ code: 'custom',
284
+ path: ['props'],
285
+ message:
286
+ 'expected the props array, or `components` for a doc that groups several components',
287
+ });
288
+ }
251
289
  });
252
290
 
291
+ /**
292
+ * A stamped component doc as it loads. The loader accepts what the unstamped
293
+ * format always accepted, so stamping an existing doc never breaks it:
294
+ * `displayName` may be missing, `category` is any string, `usage`, `theming`,
295
+ * `playground` and `examples` pass through unchecked, and a doc has `props`,
296
+ * `components`, or both; each `components` entry needs only a `name`. Every
297
+ * other field matches the published type.
298
+ *
299
+ * @typedef {Omit<SingleComponentDoc,
300
+ * 'type' | 'displayName' | 'category' | 'usage' | 'theming' | 'examples' | 'playground' | 'props'>
301
+ * & {type: 'component', displayName?: string, category?: string, usage?: unknown,
302
+ * theming?: unknown, examples?: unknown[], playground?: unknown,
303
+ * props?: ComponentPropDoc[], components?: Array<{name: string}>}} LoadedComponentDoc
304
+ */
305
+ /**
306
+ * @typedef {import('../_shared/contract.js').Expect<
307
+ * import('../_shared/contract.js').MutuallyAssignable<
308
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof ComponentDocKindSchema>>,
309
+ * import('../_shared/contract.js').NamedFields<LoadedComponentDoc>
310
+ * >
311
+ * >} _ComponentDocDriftLock
312
+ */
313
+
253
314
  /** Return entry for generalized function docs. */
254
315
  const FunctionReturnSchema = z
255
316
  .object({
@@ -269,6 +330,28 @@ export const FunctionDocKindSchema = z
269
330
  })
270
331
  .passthrough();
271
332
 
333
+ /**
334
+ * A stamped function doc as it loads: as with components, `displayName` may be
335
+ * missing and `usage` passes through unchecked.
336
+ *
337
+ * @typedef {Omit<FunctionDoc, 'type' | 'displayName' | 'usage'>
338
+ * & {type: 'function', displayName?: string, usage?: unknown}} LoadedFunctionDoc
339
+ */
340
+ /**
341
+ * @typedef {import('../_shared/contract.js').Expect<
342
+ * import('../_shared/contract.js').MutuallyAssignable<
343
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof FunctionDocKindSchema>>,
344
+ * import('../_shared/contract.js').NamedFields<LoadedFunctionDoc>
345
+ * >
346
+ * >} _FunctionDocDriftLock
347
+ */
348
+
349
+ /**
350
+ * Every HookDoc is a FunctionDoc, so the one function schema covers both.
351
+ *
352
+ * @typedef {import('../_shared/contract.js').Expect<[HookDoc] extends [FunctionDoc] ? true : false>} _HookDocIsFunctionDocLock
353
+ */
354
+
272
355
  /**
273
356
  * Stamped generic reference/topic doc (`type: 'generic'`). `title` and
274
357
  * `sections` stay optional at this parser boundary for docs produced by the
@@ -308,9 +391,30 @@ export const GenericDocKindSchema = z
308
391
  });
309
392
  });
310
393
 
394
+ /**
395
+ * A stamped generic doc as the load check accepts it. `title`, `description`
396
+ * and `sections` may be missing, as in docs the v0.3.0 factory-removal codemod
397
+ * produced; `parseReference` then fills them (title from `displayName` or
398
+ * `name`, an empty description, no sections), so its result is a full
399
+ * ReferenceDoc. Only a doc with a description and sections is a usable topic
400
+ * (see `problemsInTopic`).
401
+ *
402
+ * @typedef {Omit<ReferenceDoc, 'type' | 'title' | 'description' | 'sections'>
403
+ * & {type: 'generic'}
404
+ * & Partial<Pick<ReferenceDoc, 'title' | 'description' | 'sections'>>} LoadedReferenceDoc
405
+ */
406
+ /**
407
+ * @typedef {import('../_shared/contract.js').Expect<
408
+ * import('../_shared/contract.js').MutuallyAssignable<
409
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof GenericDocKindSchema>>,
410
+ * import('../_shared/contract.js').NamedFields<LoadedReferenceDoc>
411
+ * >
412
+ * >} _ReferenceDocDriftLock
413
+ */
414
+
311
415
  /** Recursive field descriptor for a SchemaDoc. */
312
416
  const SchemaFieldSchema =
313
- /** @type {import('zod').ZodType<import('./schema/type').SchemaFieldDoc>} */ (
417
+ /** @type {import('zod').ZodType<import('./schema/type.js').SchemaFieldDoc>} */ (
314
418
  z.lazy(() =>
315
419
  z
316
420
  .object({
@@ -351,6 +455,15 @@ export const SchemaDocKindSchema = z
351
455
  })
352
456
  .passthrough();
353
457
 
458
+ /**
459
+ * @typedef {import('../_shared/contract.js').Expect<
460
+ * import('../_shared/contract.js').MutuallyAssignable<
461
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof SchemaDocKindSchema>>,
462
+ * import('../_shared/contract.js').NamedFields<SchemaDoc & {type: 'schema'}>
463
+ * >
464
+ * >} _SchemaDocDriftLock
465
+ */
466
+
354
467
  /** New stamped command doc (`type: 'command'`). */
355
468
  export const CommandDocKindSchema = z
356
469
  .object({
@@ -411,6 +524,15 @@ export const CommandDocKindSchema = z
411
524
  })
412
525
  .passthrough();
413
526
 
527
+ /**
528
+ * @typedef {import('../_shared/contract.js').Expect<
529
+ * import('../_shared/contract.js').MutuallyAssignable<
530
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof CommandDocKindSchema>>,
531
+ * import('../_shared/contract.js').NamedFields<CommandDoc & {type: 'command'}>
532
+ * >
533
+ * >} _CommandDocDriftLock
534
+ */
535
+
414
536
  /** New stamped enum doc (`type: 'enum'`). */
415
537
  export const EnumDocKindSchema = z
416
538
  .object({
@@ -432,6 +554,15 @@ export const EnumDocKindSchema = z
432
554
  })
433
555
  .passthrough();
434
556
 
557
+ /**
558
+ * @typedef {import('../_shared/contract.js').Expect<
559
+ * import('../_shared/contract.js').MutuallyAssignable<
560
+ * import('../_shared/contract.js').NamedFields<z.infer<typeof EnumDocKindSchema>>,
561
+ * import('../_shared/contract.js').NamedFields<EnumDoc & {type: 'enum'}>
562
+ * >
563
+ * >} _EnumDocDriftLock
564
+ */
565
+
435
566
  const NamespaceSlotSchema = z
436
567
  .object({
437
568
  title: nonEmptyString,
@@ -514,8 +645,8 @@ export const NamespaceDocKindSchema = z
514
645
  });
515
646
 
516
647
  /**
517
- * @typedef {import('../_shared/contract').Expect<
518
- * import('../_shared/contract').Equal<
648
+ * @typedef {import('../_shared/contract.js').Expect<
649
+ * import('../_shared/contract.js').Equal<
519
650
  * z.infer<typeof NamespaceDocKindSchema>,
520
651
  * NamespaceDoc
521
652
  * >
@@ -12,14 +12,14 @@ export const doc = {
12
12
  displayName: 'Authored doc graph fields',
13
13
  namespace: 'authoring',
14
14
  description:
15
- 'Optional placement, compatibility aliases, and audience fields shared by every authored documentation kind.',
15
+ 'Placement, compatibility aliases, and audience: fields every authored doc kind declares for the docs graph. The docs graph is not built yet, so nothing reads them: a reference topic that sets one fails to load, and other doc kinds accept them and ignore them.',
16
16
  appliesTo: 'Every supported .doc.mjs object',
17
17
  fields: [
18
18
  {
19
19
  name: 'placement',
20
20
  type: 'DocPlacement',
21
21
  description:
22
- 'Requests one canonical parent. The compiler fails invalid explicit placement instead of silently using Unorganized.',
22
+ 'Requests one canonical parent in the docs graph. Not read yet: a topic that sets it fails to load.',
23
23
  fields: [
24
24
  {
25
25
  name: 'placement.parent',
@@ -43,13 +43,20 @@ export const doc = {
43
43
  name: 'aliases',
44
44
  type: 'string[]',
45
45
  description:
46
- 'Prior names or routes retained for compatibility. Aliases do not create another identity.',
46
+ 'Prior names or routes the docs graph will keep resolving to this doc, without creating another identity. Not read yet: a topic that sets it fails to load.',
47
47
  },
48
48
  {
49
49
  name: 'audience',
50
50
  type: "'public' | 'internal'",
51
- description: 'Bundle audience. Omit for public documentation.',
51
+ description:
52
+ "Which docs bundle includes this doc ('public' when omitted). Not read yet: a topic that sets it fails to load.",
52
53
  default: "'public'",
53
54
  },
54
55
  ],
56
+ notes: [
57
+ {
58
+ type: 'prose',
59
+ text: 'Unknown fields: `component`, `function`, `generic`, `schema`, `command` and `enum` docs accept a field they do not know, and nothing reads it, so a doc written for a newer CLI still loads here. `page`, `block` and `namespace` docs refuse one. Sections and content blocks refuse one in every doc.',
60
+ },
61
+ ],
55
62
  };
@@ -30,13 +30,17 @@ export interface DocPlacement {
30
30
  order?: number;
31
31
  }
32
32
 
33
- /** Graph metadata shared by every authored doc kind. */
33
+ /**
34
+ * Graph metadata shared by every authored doc kind. Reserved for the docs
35
+ * graph, which is not built yet: nothing reads these fields, and a reference
36
+ * topic that sets one fails to load.
37
+ */
34
38
  export interface AuthoredDocGraphFields {
35
- /** Requested canonical parent. Omit to use source adoption or Unorganized. */
39
+ /** Requested canonical parent in the docs graph. Not read yet. */
36
40
  placement?: DocPlacement;
37
- /** Prior routes or names that must continue to resolve to this stable doc. */
41
+ /** Prior routes or names the docs graph will keep resolving. Not read yet. */
38
42
  aliases?: string[];
39
- /** Bundle audience. Omit for public docs. */
43
+ /** Docs bundle audience; omit for public docs. Not read yet. */
40
44
  audience?: DocAudience;
41
45
  }
42
46
 
@@ -135,8 +135,9 @@ export const doc = {
135
135
  },
136
136
  {
137
137
  name: 'options[].default',
138
- type: 'string',
139
- description: 'Default value as a string.',
138
+ type: 'string | boolean | string[]',
139
+ description:
140
+ 'Default value: a string, a boolean, or a list of strings.',
140
141
  },
141
142
  {
142
143
  name: 'options[].cliOnly',
@@ -1,7 +1,7 @@
1
1
  // @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
- /** @typedef {import('../types').CommandDoc} CommandDoc */
4
+ /** @typedef {import('../types.js').CommandDoc} CommandDoc */
5
5
  /**
6
6
  * Validate an unknown value as a stamped command doc, or throw.
7
7
  *
@@ -10,4 +10,4 @@
10
10
  * @returns {CommandDoc}
11
11
  */
12
12
  export function parseCommand(input: unknown, label?: string): CommandDoc;
13
- export type CommandDoc = import("../types").CommandDoc;
13
+ export type CommandDoc = import("../types.js").CommandDoc;
@@ -8,7 +8,7 @@
8
8
  import {CommandDocKindSchema} from '../_schema.mjs';
9
9
  import {formatZodError} from '../../_shared/errors.mjs';
10
10
 
11
- /** @typedef {import('../types').CommandDoc} CommandDoc */
11
+ /** @typedef {import('../types.js').CommandDoc} CommandDoc */
12
12
 
13
13
  /**
14
14
  * Validate an unknown value as a stamped command doc, or throw.
@@ -9,8 +9,8 @@
9
9
  * `--help`. Colocated at `clients/cli/commands/<name>.doc.mjs`.
10
10
  */
11
11
 
12
- import type {AuthoredDocGraphFields} from '../base/type';
13
- import type {ReferenceContentBlock} from '../reference/type';
12
+ import type {AuthoredDocGraphFields} from '../base/type.js';
13
+ import type {ReferenceContentBlock} from '../reference/type.js';
14
14
 
15
15
  /** A positional argument. `param` links it to a FunctionDoc param for its description. */
16
16
  export interface CommandArgDoc {
@@ -124,8 +124,7 @@ export const doc = {
124
124
  name: 'usage',
125
125
  type: 'UsageDoc',
126
126
  description:
127
- 'Component usage documentation: concise summary, best practices, component-specific accessibility requirements, and optional visual anatomy. (Optional on SubComponentDoc, where the sub-component description is used instead.)',
128
- required: true,
127
+ 'Component usage documentation: concise summary, best practices, component-specific accessibility requirements, and optional visual anatomy. Required on a component doc; optional on a sub-component doc (`subComponentOf`), which uses its description instead.',
129
128
  fields: [
130
129
  {
131
130
  name: 'usage.description',
@@ -242,6 +241,10 @@ export const docs = {
242
241
  },
243
242
  ],
244
243
  notes: [
244
+ {
245
+ type: 'prose',
246
+ text: "When it loads, a stamped component doc is checked as loosely as an unstamped one, so adding `type: 'component'` to an existing doc never breaks it: `displayName` may be missing, `category` may be any string, and `usage`, `theming`, `playground` and `examples` are not checked. Each entry in a group doc's `components` must have a `name`. Write to the type anyway; it is the contract.",
247
+ },
245
248
  {
246
249
  type: 'prose',
247
250
  text: 'ComponentDoc is a discriminated union of three shapes that all extend ComponentBaseDoc. Pick the variant by which key you set: `props` (single), `components` (multi), or `subComponentOf` (sub).',
@@ -1,7 +1,7 @@
1
1
  // @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
- /** @typedef {import('../types').ComponentDoc} ComponentDoc */
4
+ /** @typedef {import('../types.js').ComponentDoc} ComponentDoc */
5
5
  /**
6
6
  * Validate an unknown value as a stamped component doc, or throw.
7
7
  *
@@ -10,4 +10,4 @@
10
10
  * @returns {ComponentDoc}
11
11
  */
12
12
  export function parseComponent(input: unknown, label?: string): ComponentDoc;
13
- export type ComponentDoc = import("../types").ComponentDoc;
13
+ export type ComponentDoc = import("../types.js").ComponentDoc;
@@ -8,7 +8,7 @@
8
8
  import {ComponentDocKindSchema} from '../_schema.mjs';
9
9
  import {formatZodError} from '../../_shared/errors.mjs';
10
10
 
11
- /** @typedef {import('../types').ComponentDoc} ComponentDoc */
11
+ /** @typedef {import('../types.js').ComponentDoc} ComponentDoc */
12
12
 
13
13
  /**
14
14
  * Validate an unknown value as a stamped component doc, or throw.
@@ -19,7 +19,7 @@ import type {
19
19
  HookReturnDoc,
20
20
  RegistryDocIdentity,
21
21
  UsageDoc,
22
- } from '../base/type';
22
+ } from '../base/type.js';
23
23
 
24
24
  /**
25
25
  * Shared fields between single-component and multi-component docs.
@@ -1,7 +1,7 @@
1
1
  // @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
- /** @typedef {import('../types').EnumDoc} EnumDoc */
4
+ /** @typedef {import('../types.js').EnumDoc} EnumDoc */
5
5
  /**
6
6
  * Validate an unknown value as a stamped enum doc, or throw.
7
7
  *
@@ -10,4 +10,4 @@
10
10
  * @returns {EnumDoc}
11
11
  */
12
12
  export function parseEnum(input: unknown, label?: string): EnumDoc;
13
- export type EnumDoc = import("../types").EnumDoc;
13
+ export type EnumDoc = import("../types.js").EnumDoc;
@@ -8,7 +8,7 @@
8
8
  import {EnumDocKindSchema} from '../_schema.mjs';
9
9
  import {formatZodError} from '../../_shared/errors.mjs';
10
10
 
11
- /** @typedef {import('../types').EnumDoc} EnumDoc */
11
+ /** @typedef {import('../types.js').EnumDoc} EnumDoc */
12
12
 
13
13
  /**
14
14
  * Validate an unknown value as a stamped enum doc, or throw.
@@ -5,7 +5,7 @@
5
5
  * discriminants). Colocated next to the source of truth it documents.
6
6
  */
7
7
 
8
- import type {AuthoredDocGraphFields} from '../base/type';
8
+ import type {AuthoredDocGraphFields} from '../base/type.js';
9
9
 
10
10
  /** One member of an enumerated vocabulary. */
11
11
  export interface EnumMemberDoc {
@@ -250,6 +250,10 @@ export const doc = {
250
250
  },
251
251
  ],
252
252
  notes: [
253
+ {
254
+ type: 'prose',
255
+ text: 'When it loads, a stamped function doc may leave out `displayName`, and its `usage` is not checked. Write to the type anyway; it is the contract.',
256
+ },
253
257
  {
254
258
  type: 'prose',
255
259
  text: "The `type` discriminant is 'function' for both flavors. Set `kind: 'hook'` or `kind: 'api'` to drive docsite sectioning; it is inferred from `importPath` when omitted.",