@astryxdesign/cli 0.6.3-canary.ea2f048 → 0.6.3-canary.ebaebc4
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.
- package/README.md +2 -1
- package/api/build/build.type.d.mts +2 -2
- package/api/build/build.type.mjs +2 -2
- package/api/component/component.type.d.mts +6 -6
- package/api/component/component.type.mjs +19 -19
- package/api/discover/discover.type.d.mts +4 -4
- package/api/discover/discover.type.mjs +10 -10
- package/api/docs/_adapter.d.mts +37 -24
- package/api/docs/_adapter.mjs +169 -83
- package/api/docs/compiled-topics.test.mjs +78 -0
- package/api/docs/detail/detail.mjs +14 -63
- package/api/docs/detail/section/section.d.mts +1 -1
- package/api/docs/detail/section/section.mjs +44 -20
- package/api/docs/detail/section/section.test.mjs +41 -0
- package/api/docs/docs.d.mts +7 -2
- package/api/docs/docs.doc.mjs +27 -10
- package/api/docs/docs.mjs +16 -9
- package/api/docs/docs.test.mjs +6 -0
- package/api/docs/docs.type.d.mts +40 -3
- package/api/docs/docs.type.mjs +36 -8
- package/api/docs/index/index.d.mts +18 -0
- package/api/docs/index/index.mjs +32 -0
- package/api/docs/index/index.test.mjs +62 -0
- package/api/docs/integrationDocs.test.mjs +106 -0
- package/api/doctor/doctor.d.mts +48 -0
- package/api/doctor/doctor.mjs +232 -0
- package/api/doctor/doctor.test.mjs +196 -0
- package/api/hook/hook.type.d.mts +3 -3
- package/api/hook/hook.type.mjs +11 -11
- package/api/hook/list/list.d.mts +1 -1
- package/api/integration/add-contribution.mjs +5 -3
- package/api/integration/add-contribution.test.mjs +4 -4
- package/api/integration/integration-authoring.type.d.mts +1 -1
- package/api/integration/pack-check.mjs +49 -7
- package/api/integration/pack-check.test.mjs +249 -0
- package/api/search/search.d.mts +1 -1
- package/api/search/search.mjs +5 -5
- package/api/search/search.type.d.mts +2 -2
- package/api/search/search.type.mjs +1 -1
- package/api/swizzle/swizzle.type.d.mts +2 -2
- package/api/swizzle/swizzle.type.mjs +2 -2
- package/api/template/template.d.mts +1 -1
- package/api/template/template.type.d.mts +6 -6
- package/api/template/template.type.mjs +12 -12
- package/api/theme/build/build.mjs +20 -6
- package/api/theme/build/build.test.mjs +127 -0
- package/api/theme/palette/generate/generate.mjs +1 -1
- package/api/theme/palette/generate/generator.d.mts +10 -13
- package/api/theme/palette/generate/generator.mjs +7 -3
- package/api/theme/theme.type.d.mts +170 -11
- package/api/theme/theme.type.mjs +94 -27
- package/api/upgrade/_adapter.mjs +71 -5
- package/api/upgrade/project-context.test.mjs +272 -0
- package/api/upgrade/upgrade.doc.mjs +4 -3
- package/api/upgrade/upgrade.type.d.mts +5 -5
- package/api/upgrade/upgrade.type.mjs +11 -11
- package/assets/codemods/integration-discovery.mjs +40 -2
- package/assets/codemods/integration-discovery.test.mjs +58 -0
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
- package/assets/docs/README.md +9 -0
- package/assets/docs/authoring.doc.mjs +14 -0
- package/assets/docs/cli-integrations.doc.mjs +86 -15
- package/assets/docs/styling-libraries.doc.mjs +1 -1
- package/assets/docs/working-with-ai.doc.mjs +1 -1
- package/authoring/_shared/contract.ts +22 -0
- package/authoring/codemod/codemod.doc.mjs +6 -1
- package/authoring/codemod/parse.d.mts +8 -8
- package/authoring/codemod/parse.mjs +8 -6
- package/authoring/config/parse.d.mts +13 -13
- package/authoring/config/parse.mjs +8 -8
- package/authoring/config/type.ts +3 -3
- package/authoring/debug/parse.d.mts +5 -5
- package/authoring/debug/parse.mjs +3 -3
- package/authoring/doctypes/_schema.d.mts +788 -23
- package/authoring/doctypes/_schema.mjs +492 -39
- package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +62 -0
- package/authoring/doctypes/base/type.ts +40 -0
- package/authoring/doctypes/command/command.doc.mjs +3 -2
- package/authoring/doctypes/command/parse.d.mts +2 -2
- package/authoring/doctypes/command/parse.mjs +1 -1
- package/authoring/doctypes/command/type.ts +3 -2
- package/authoring/doctypes/component/component.doc.mjs +6 -3
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +4 -3
- package/authoring/doctypes/enum/parse.d.mts +2 -2
- package/authoring/doctypes/enum/parse.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +3 -1
- package/authoring/doctypes/function/function.doc.mjs +4 -0
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +6 -2
- package/authoring/doctypes/hook/hook.doc.mjs +4 -0
- package/authoring/doctypes/hook/parse.d.mts +2 -2
- package/authoring/doctypes/hook/parse.mjs +1 -1
- package/authoring/doctypes/hook/type.ts +3 -2
- package/authoring/doctypes/legacy.d.mts +8 -6
- package/authoring/doctypes/legacy.mjs +5 -4
- package/authoring/doctypes/load-contract.test.mjs +207 -0
- package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +132 -0
- package/authoring/doctypes/namespace/parse.d.mts +12 -0
- package/authoring/doctypes/namespace/parse.mjs +25 -0
- package/authoring/doctypes/namespace/parse.test.mjs +165 -0
- package/authoring/doctypes/namespace/type.ts +71 -0
- package/authoring/doctypes/parse.d.mts +20 -18
- package/authoring/doctypes/parse.mjs +16 -10
- package/authoring/doctypes/parse.test.mjs +77 -3
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +8 -5
- package/authoring/doctypes/reference/reference.doc.mjs +17 -4
- package/authoring/doctypes/reference/type.ts +51 -5
- package/authoring/doctypes/schema/parse.d.mts +2 -2
- package/authoring/doctypes/schema/parse.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +3 -2
- package/authoring/doctypes/template/parse.d.mts +92 -1
- package/authoring/doctypes/template/parse.mjs +36 -2
- package/authoring/doctypes/template/parse.test.mjs +8 -2
- package/authoring/doctypes/template/template.doc.mjs +4 -0
- package/authoring/doctypes/template/type.ts +5 -2
- package/authoring/doctypes/types.ts +10 -9
- package/authoring/gap-report/parse.d.mts +10 -10
- package/authoring/gap-report/parse.mjs +6 -6
- package/authoring/gap-report/type.ts +1 -1
- package/authoring/identity/identity.doc.d.mts +9 -0
- package/authoring/identity/identity.doc.mjs +61 -0
- package/authoring/identity/type.ts +132 -0
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +49 -17
- package/authoring/index.mjs +1 -0
- package/authoring/integration/integration.doc.mjs +13 -6
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/parse.test.mjs +10 -1
- package/authoring/integration/schema.d.mts +6 -4
- package/authoring/integration/schema.mjs +9 -3
- package/authoring/integration/type.ts +23 -6
- package/authoring/shadcn/receipt.d.mts +6 -6
- package/clients/cli/commands/docs.doc.mjs +13 -3
- package/clients/cli/commands/docs.mjs +121 -21
- package/clients/cli/commands/docs.test.mjs +88 -0
- package/clients/cli/commands/integration-authoring.test.mjs +13 -9
- package/clients/cli/commands/theme-palette-generate.doc.mjs +8 -4
- package/clients/cli/commands/upgrade.doc.mjs +2 -2
- package/clients/cli/formatters/index.mjs +162 -1
- package/clients/cli/formatters/index.test.mjs +91 -0
- package/clients/cli/lib/manifest.mjs +7 -2
- package/foundation/config/project.mjs +21 -6
- package/foundation/discovery/authoring-self-docs.d.mts +69 -0
- package/foundation/discovery/authoring-self-docs.mjs +214 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +154 -0
- package/foundation/discovery/component-discovery.d.mts +1 -1
- package/foundation/discovery/component-discovery.mjs +2 -1
- package/foundation/discovery/docs-discovery.d.mts +11 -4
- package/foundation/discovery/docs-discovery.mjs +208 -88
- package/foundation/discovery/docs-discovery.test.mjs +279 -13
- package/foundation/discovery/docs-output-budget.d.mts +28 -0
- package/foundation/discovery/docs-output-budget.mjs +50 -0
- package/foundation/discovery/docs-section-key.d.mts +98 -0
- package/foundation/discovery/docs-section-key.mjs +221 -0
- package/foundation/discovery/docs-section-key.test.mjs +224 -0
- package/foundation/discovery/template-adapter.mjs +2 -1
- package/foundation/discovery/theming-targets.test.mjs +4 -0
- package/foundation/doc-compiler/compile.d.mts +162 -0
- package/foundation/doc-compiler/compile.mjs +262 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +687 -0
- package/foundation/doc-compiler/ir.d.mts +9 -0
- package/foundation/doc-compiler/ir.mjs +287 -0
- package/foundation/doc-compiler/lenses.d.mts +33 -0
- package/foundation/doc-compiler/lenses.mjs +127 -0
- package/foundation/identity/provider-identity.d.mts +90 -0
- package/foundation/identity/provider-identity.mjs +320 -0
- package/foundation/identity/provider-identity.test.mjs +254 -0
- package/foundation/identity/providers.d.mts +7 -0
- package/foundation/identity/providers.mjs +16 -0
- package/foundation/integrations/autolink.mjs +12 -5
- package/foundation/integrations/integration-warnings.mjs +6 -0
- package/foundation/integrations/integrations.d.mts +46 -2
- package/foundation/integrations/integrations.mjs +167 -8
- package/foundation/integrations/integrations.test.mjs +384 -1
- package/foundation/integrations/provider-conflicts.test.mjs +125 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +10 -0
- package/foundation/response/json-contract.test.mjs +46 -17
- package/foundation/response/response-types.doc.mjs +6 -1
- package/package.json +9 -11
|
@@ -3,16 +3,208 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Sealed doc load-boundary schemas (doctypes-internal).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 'generic'`) and the legacy loose `export const docs = {...}` shape, so the
|
|
11
|
-
* ~600+ existing docs keep validating unchanged.
|
|
6
|
+
* Existing doctypes keep their historical top-level passthrough policy so
|
|
7
|
+
* already-published docs continue to load. NamespaceDoc and every semantic
|
|
8
|
+
* content block are strict: a misspelled field cannot reach a renderer as
|
|
9
|
+
* missing data.
|
|
12
10
|
*/
|
|
13
11
|
|
|
14
12
|
import {z} from 'zod';
|
|
15
13
|
|
|
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 */
|
|
26
|
+
|
|
27
|
+
const nonEmptyString = z.string().min(1);
|
|
28
|
+
|
|
29
|
+
/** Every authored doc-kind discriminant accepted by parseDoc. */
|
|
30
|
+
export const AuthoredDocKindSchema = z.enum([
|
|
31
|
+
'component',
|
|
32
|
+
'function',
|
|
33
|
+
'generic',
|
|
34
|
+
'page',
|
|
35
|
+
'block',
|
|
36
|
+
'schema',
|
|
37
|
+
'command',
|
|
38
|
+
'enum',
|
|
39
|
+
'namespace',
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {import('../_shared/contract.js').Expect<
|
|
44
|
+
* import('../_shared/contract.js').Equal<z.infer<typeof AuthoredDocKindSchema>, AuthoredDocKind>
|
|
45
|
+
* >} _AuthoredDocKindDriftLock
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/** Shared optional graph fields for every authored doc kind. */
|
|
49
|
+
export const AuthoredDocGraphFields = {
|
|
50
|
+
placement: z
|
|
51
|
+
.object({
|
|
52
|
+
parent: nonEmptyString,
|
|
53
|
+
slot: nonEmptyString.optional(),
|
|
54
|
+
order: z.number().int().safe().optional(),
|
|
55
|
+
})
|
|
56
|
+
.strict()
|
|
57
|
+
.optional(),
|
|
58
|
+
aliases: z.array(nonEmptyString).optional(),
|
|
59
|
+
audience: z.enum(['public', 'internal']).optional(),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const _AuthoredDocGraphSchema = z.object(AuthoredDocGraphFields).strict();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @typedef {import('../_shared/contract.js').Expect<
|
|
66
|
+
* import('../_shared/contract.js').MutuallyAssignable<
|
|
67
|
+
* z.infer<typeof _AuthoredDocGraphSchema>,
|
|
68
|
+
* AuthoredDocGraphFieldsType
|
|
69
|
+
* >
|
|
70
|
+
* >} _AuthoredDocGraphDriftLock
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
const ProseBlockSchema = z
|
|
74
|
+
.object({type: z.literal('prose'), text: nonEmptyString})
|
|
75
|
+
.strict();
|
|
76
|
+
const HeadingBlockSchema = z
|
|
77
|
+
.object({
|
|
78
|
+
type: z.literal('heading'),
|
|
79
|
+
level: z.union([z.literal(3), z.literal(4), z.literal(5), z.literal(6)]),
|
|
80
|
+
text: nonEmptyString,
|
|
81
|
+
})
|
|
82
|
+
.strict();
|
|
83
|
+
const CodeBlockSchema = z
|
|
84
|
+
.object({
|
|
85
|
+
type: z.literal('code'),
|
|
86
|
+
lang: nonEmptyString,
|
|
87
|
+
code: z.string(),
|
|
88
|
+
label: nonEmptyString.optional(),
|
|
89
|
+
})
|
|
90
|
+
.strict();
|
|
91
|
+
const TableBlockSchema = z
|
|
92
|
+
.object({
|
|
93
|
+
type: z.literal('table'),
|
|
94
|
+
headers: z.array(z.string()).min(1),
|
|
95
|
+
rows: z.array(z.array(z.string())),
|
|
96
|
+
})
|
|
97
|
+
.strict()
|
|
98
|
+
.superRefine((table, context) => {
|
|
99
|
+
table.rows.forEach((row, index) => {
|
|
100
|
+
if (row.length !== table.headers.length) {
|
|
101
|
+
context.addIssue({
|
|
102
|
+
code: 'custom',
|
|
103
|
+
path: ['rows', index],
|
|
104
|
+
message: `expected ${table.headers.length} cells`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
const ListBlockSchema = z
|
|
110
|
+
.object({
|
|
111
|
+
type: z.literal('list'),
|
|
112
|
+
style: z.enum(['ordered', 'unordered', 'do', 'dont']),
|
|
113
|
+
items: z.array(nonEmptyString).min(1),
|
|
114
|
+
})
|
|
115
|
+
.strict();
|
|
116
|
+
const TokenReferenceBlockSchema = z
|
|
117
|
+
.object({
|
|
118
|
+
type: z.literal('token-ref'),
|
|
119
|
+
topic: nonEmptyString,
|
|
120
|
+
section: nonEmptyString,
|
|
121
|
+
})
|
|
122
|
+
.strict();
|
|
123
|
+
const WorkflowBlockSchema = z
|
|
124
|
+
.object({
|
|
125
|
+
type: z.literal('workflow'),
|
|
126
|
+
title: nonEmptyString.optional(),
|
|
127
|
+
steps: z
|
|
128
|
+
.array(
|
|
129
|
+
z
|
|
130
|
+
.object({
|
|
131
|
+
title: nonEmptyString,
|
|
132
|
+
description: nonEmptyString.optional(),
|
|
133
|
+
references: z.array(nonEmptyString).min(1).optional(),
|
|
134
|
+
})
|
|
135
|
+
.strict(),
|
|
136
|
+
)
|
|
137
|
+
.min(1),
|
|
138
|
+
})
|
|
139
|
+
.strict();
|
|
140
|
+
const CollectionBlockSchema = z
|
|
141
|
+
.object({
|
|
142
|
+
type: z.literal('collection'),
|
|
143
|
+
title: nonEmptyString.optional(),
|
|
144
|
+
source: z.object({slot: nonEmptyString}).strict(),
|
|
145
|
+
presentation: z.enum(['list', 'cards', 'compact']).optional(),
|
|
146
|
+
whenEmpty: z.enum(['show', 'omit']).optional(),
|
|
147
|
+
})
|
|
148
|
+
.strict();
|
|
149
|
+
const ReferenceBlockSchema = z
|
|
150
|
+
.object({
|
|
151
|
+
type: z.literal('reference'),
|
|
152
|
+
target: nonEmptyString,
|
|
153
|
+
projection: z
|
|
154
|
+
.object({
|
|
155
|
+
fields: z.array(nonEmptyString).min(1).optional(),
|
|
156
|
+
sections: z.array(nonEmptyString).min(1).optional(),
|
|
157
|
+
})
|
|
158
|
+
.strict()
|
|
159
|
+
.optional(),
|
|
160
|
+
presentation: z.enum(['summary', 'compact', 'full']).optional(),
|
|
161
|
+
})
|
|
162
|
+
.strict();
|
|
163
|
+
|
|
164
|
+
/** Runtime schema for every existing and V1 semantic content block. */
|
|
165
|
+
export const ReferenceContentBlockSchema = z.discriminatedUnion('type', [
|
|
166
|
+
ProseBlockSchema,
|
|
167
|
+
HeadingBlockSchema,
|
|
168
|
+
CodeBlockSchema,
|
|
169
|
+
TableBlockSchema,
|
|
170
|
+
ListBlockSchema,
|
|
171
|
+
TokenReferenceBlockSchema,
|
|
172
|
+
WorkflowBlockSchema,
|
|
173
|
+
CollectionBlockSchema,
|
|
174
|
+
ReferenceBlockSchema,
|
|
175
|
+
]);
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @typedef {import('../_shared/contract.js').Expect<
|
|
179
|
+
* import('../_shared/contract.js').Equal<
|
|
180
|
+
* z.infer<typeof ReferenceContentBlockSchema>,
|
|
181
|
+
* ReferenceContentBlock
|
|
182
|
+
* >
|
|
183
|
+
* >} _ReferenceContentBlockDriftLock
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
const ReferenceSectionSchema = z
|
|
187
|
+
.object({
|
|
188
|
+
id: nonEmptyString.optional(),
|
|
189
|
+
title: nonEmptyString,
|
|
190
|
+
category: z.string().optional(),
|
|
191
|
+
content: z.array(ReferenceContentBlockSchema),
|
|
192
|
+
previewType: z
|
|
193
|
+
.enum([
|
|
194
|
+
'swatch',
|
|
195
|
+
'shadow-box',
|
|
196
|
+
'radius-box',
|
|
197
|
+
'spacing-bar',
|
|
198
|
+
'size-bar',
|
|
199
|
+
'border-line',
|
|
200
|
+
'duration-bar',
|
|
201
|
+
'easing-curve',
|
|
202
|
+
'font-sample',
|
|
203
|
+
])
|
|
204
|
+
.optional(),
|
|
205
|
+
})
|
|
206
|
+
.strict();
|
|
207
|
+
|
|
16
208
|
const PropSchema = z
|
|
17
209
|
.object({
|
|
18
210
|
name: z.string().min(1, 'prop name is required'),
|
|
@@ -42,6 +234,7 @@ const ReturnSchema = z
|
|
|
42
234
|
.passthrough();
|
|
43
235
|
|
|
44
236
|
const BaseDocFields = {
|
|
237
|
+
...AuthoredDocGraphFields,
|
|
45
238
|
name: z.string().min(1, 'name is required'),
|
|
46
239
|
displayName: z.string().optional(),
|
|
47
240
|
description: z.string().optional(),
|
|
@@ -56,21 +249,69 @@ const BaseDocFields = {
|
|
|
56
249
|
isHiddenFromOverview: z.boolean().optional(),
|
|
57
250
|
};
|
|
58
251
|
|
|
59
|
-
|
|
60
|
-
export const ComponentDocKindSchema = z
|
|
252
|
+
const ComponentBaseSchema = z
|
|
61
253
|
.object({
|
|
62
254
|
...BaseDocFields,
|
|
63
255
|
type: z.literal('component'),
|
|
64
|
-
props: z.array(PropSchema),
|
|
65
256
|
theming: z.unknown().optional(),
|
|
66
257
|
playground: z.unknown().optional(),
|
|
67
258
|
examples: z.array(z.unknown()).optional(),
|
|
68
259
|
})
|
|
69
260
|
.passthrough();
|
|
70
261
|
|
|
71
|
-
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
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
|
+
*/
|
|
277
|
+
export const ComponentDocKindSchema = ComponentBaseSchema.extend({
|
|
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
|
+
}
|
|
289
|
+
});
|
|
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
|
+
|
|
314
|
+
/** Return entry for generalized function docs. */
|
|
74
315
|
const FunctionReturnSchema = z
|
|
75
316
|
.object({
|
|
76
317
|
name: z.string().min(1).optional(),
|
|
@@ -79,8 +320,7 @@ const FunctionReturnSchema = z
|
|
|
79
320
|
})
|
|
80
321
|
.passthrough();
|
|
81
322
|
|
|
82
|
-
/** New-format stamped function doc (`type: 'function'`)
|
|
83
|
-
* functions alike (the discriminant and schema are shared). */
|
|
323
|
+
/** New-format stamped function doc (`type: 'function'`). */
|
|
84
324
|
export const FunctionDocKindSchema = z
|
|
85
325
|
.object({
|
|
86
326
|
...BaseDocFields,
|
|
@@ -90,30 +330,95 @@ export const FunctionDocKindSchema = z
|
|
|
90
330
|
})
|
|
91
331
|
.passthrough();
|
|
92
332
|
|
|
93
|
-
/**
|
|
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
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Stamped generic reference/topic doc (`type: 'generic'`). `title` and
|
|
357
|
+
* `sections` stay optional at this parser boundary for docs produced by the
|
|
358
|
+
* shipped v0.3.0 factory-removal codemod. When present, all rich fields and
|
|
359
|
+
* semantic blocks are validated.
|
|
360
|
+
*/
|
|
94
361
|
export const GenericDocKindSchema = z
|
|
95
362
|
.object({
|
|
96
363
|
...BaseDocFields,
|
|
97
364
|
type: z.literal('generic'),
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
365
|
+
title: nonEmptyString.optional(),
|
|
366
|
+
sections: z.array(ReferenceSectionSchema).min(1).optional(),
|
|
367
|
+
replaces: nonEmptyString.optional(),
|
|
368
|
+
extends: nonEmptyString.optional(),
|
|
369
|
+
tokenCategory: z.string().optional(),
|
|
103
370
|
})
|
|
104
|
-
.passthrough()
|
|
371
|
+
.passthrough()
|
|
372
|
+
.superRefine((doc, context) => {
|
|
373
|
+
if (doc.replaces != null && doc.extends != null) {
|
|
374
|
+
context.addIssue({
|
|
375
|
+
code: 'custom',
|
|
376
|
+
path: ['extends'],
|
|
377
|
+
message: 'declares both `replaces` and `extends`; choose one',
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
const sectionIds = new Set();
|
|
381
|
+
doc.sections?.forEach((section, index) => {
|
|
382
|
+
if (section.id == null) return;
|
|
383
|
+
if (sectionIds.has(section.id)) {
|
|
384
|
+
context.addIssue({
|
|
385
|
+
code: 'custom',
|
|
386
|
+
path: ['sections', index, 'id'],
|
|
387
|
+
message: `duplicate section id "${section.id}"`,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
sectionIds.add(section.id);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
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
|
+
*/
|
|
105
414
|
|
|
106
|
-
/** Recursive field descriptor for a SchemaDoc
|
|
107
|
-
* explicit cast breaks the self-referential type inference (TS7022) that the
|
|
108
|
-
* authoring-contract `checkJs` pass would otherwise flag. */
|
|
415
|
+
/** Recursive field descriptor for a SchemaDoc. */
|
|
109
416
|
const SchemaFieldSchema =
|
|
110
|
-
/** @type {import('zod').ZodType<import('./schema/type').SchemaFieldDoc>} */ (
|
|
417
|
+
/** @type {import('zod').ZodType<import('./schema/type.js').SchemaFieldDoc>} */ (
|
|
111
418
|
z.lazy(() =>
|
|
112
419
|
z
|
|
113
420
|
.object({
|
|
114
421
|
name: z.string().min(1, 'field name is required'),
|
|
115
|
-
// `{error}` covers a missing (undefined) type; `.min(1)` covers an
|
|
116
|
-
// empty string — both give the same author-friendly message.
|
|
117
422
|
type: z
|
|
118
423
|
.string({error: 'field type is required'})
|
|
119
424
|
.min(1, 'field type is required'),
|
|
@@ -128,15 +433,15 @@ const SchemaFieldSchema =
|
|
|
128
433
|
)
|
|
129
434
|
);
|
|
130
435
|
|
|
131
|
-
/** New stamped schema doc (`type: 'schema'`)
|
|
436
|
+
/** New stamped schema doc (`type: 'schema'`). */
|
|
132
437
|
export const SchemaDocKindSchema = z
|
|
133
438
|
.object({
|
|
439
|
+
...AuthoredDocGraphFields,
|
|
134
440
|
type: z.literal('schema'),
|
|
135
441
|
name: z.string().min(1, 'name is required'),
|
|
136
442
|
displayName: z.string().min(1, 'displayName is required'),
|
|
137
443
|
description: z.string(),
|
|
138
444
|
namespace: z.string().optional(),
|
|
139
|
-
aliases: z.array(z.string()).optional(),
|
|
140
445
|
appliesTo: z.string().optional(),
|
|
141
446
|
fields: z.array(SchemaFieldSchema),
|
|
142
447
|
examples: z
|
|
@@ -146,21 +451,29 @@ export const SchemaDocKindSchema = z
|
|
|
146
451
|
.passthrough(),
|
|
147
452
|
)
|
|
148
453
|
.optional(),
|
|
149
|
-
notes: z.array(
|
|
454
|
+
notes: z.array(ReferenceContentBlockSchema).optional(),
|
|
150
455
|
})
|
|
151
456
|
.passthrough();
|
|
152
457
|
|
|
153
|
-
/**
|
|
154
|
-
*
|
|
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
|
+
|
|
467
|
+
/** New stamped command doc (`type: 'command'`). */
|
|
155
468
|
export const CommandDocKindSchema = z
|
|
156
469
|
.object({
|
|
470
|
+
...AuthoredDocGraphFields,
|
|
157
471
|
type: z.literal('command'),
|
|
158
472
|
name: z.string().min(1, 'name is required'),
|
|
159
473
|
displayName: z.string().min(1, 'displayName is required'),
|
|
160
474
|
summary: z.string(),
|
|
161
475
|
description: z.string().optional(),
|
|
162
476
|
namespace: z.string().optional(),
|
|
163
|
-
aliases: z.array(z.string()).optional(),
|
|
164
477
|
fn: z.string().optional(),
|
|
165
478
|
args: z
|
|
166
479
|
.array(
|
|
@@ -207,20 +520,28 @@ export const CommandDocKindSchema = z
|
|
|
207
520
|
.array(z.object({code: z.number(), when: z.string()}).passthrough())
|
|
208
521
|
.optional(),
|
|
209
522
|
related: z.array(z.string()).optional(),
|
|
210
|
-
notes: z.array(
|
|
523
|
+
notes: z.array(ReferenceContentBlockSchema).optional(),
|
|
211
524
|
})
|
|
212
525
|
.passthrough();
|
|
213
526
|
|
|
214
|
-
/**
|
|
215
|
-
*
|
|
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
|
+
|
|
536
|
+
/** New stamped enum doc (`type: 'enum'`). */
|
|
216
537
|
export const EnumDocKindSchema = z
|
|
217
538
|
.object({
|
|
539
|
+
...AuthoredDocGraphFields,
|
|
218
540
|
type: z.literal('enum'),
|
|
219
541
|
name: z.string().min(1, 'name is required'),
|
|
220
542
|
displayName: z.string().min(1, 'displayName is required'),
|
|
221
543
|
description: z.string(),
|
|
222
544
|
namespace: z.string().optional(),
|
|
223
|
-
aliases: z.array(z.string()).optional(),
|
|
224
545
|
members: z.array(
|
|
225
546
|
z
|
|
226
547
|
.object({
|
|
@@ -233,8 +554,108 @@ export const EnumDocKindSchema = z
|
|
|
233
554
|
})
|
|
234
555
|
.passthrough();
|
|
235
556
|
|
|
236
|
-
|
|
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
|
+
|
|
566
|
+
const NamespaceSlotSchema = z
|
|
567
|
+
.object({
|
|
568
|
+
title: nonEmptyString,
|
|
569
|
+
accepts: z
|
|
570
|
+
.object({
|
|
571
|
+
kinds: z.array(AuthoredDocKindSchema).min(1),
|
|
572
|
+
providers: z.enum(['same', 'configured']).optional(),
|
|
573
|
+
})
|
|
574
|
+
.strict(),
|
|
575
|
+
})
|
|
576
|
+
.strict();
|
|
577
|
+
|
|
578
|
+
/** The one new authored doctype: a hierarchy and layout owner. */
|
|
579
|
+
export const NamespaceDocKindSchema = z
|
|
580
|
+
.object({
|
|
581
|
+
...AuthoredDocGraphFields,
|
|
582
|
+
type: z.literal('namespace'),
|
|
583
|
+
name: nonEmptyString,
|
|
584
|
+
title: nonEmptyString,
|
|
585
|
+
summary: nonEmptyString,
|
|
586
|
+
keywords: z.array(nonEmptyString).optional(),
|
|
587
|
+
slots: z
|
|
588
|
+
.record(nonEmptyString, NamespaceSlotSchema)
|
|
589
|
+
.refine(slots => Object.keys(slots).length > 0, {
|
|
590
|
+
message: 'at least one slot is required',
|
|
591
|
+
}),
|
|
592
|
+
adopts: z
|
|
593
|
+
.array(
|
|
594
|
+
z
|
|
595
|
+
.object({
|
|
596
|
+
source: z
|
|
597
|
+
.object({
|
|
598
|
+
group: nonEmptyString,
|
|
599
|
+
kinds: z.array(AuthoredDocKindSchema).min(1).optional(),
|
|
600
|
+
})
|
|
601
|
+
.strict(),
|
|
602
|
+
into: nonEmptyString,
|
|
603
|
+
groupBy: z.literal('kind').optional(),
|
|
604
|
+
})
|
|
605
|
+
.strict(),
|
|
606
|
+
)
|
|
607
|
+
.optional(),
|
|
608
|
+
blocks: z.array(ReferenceContentBlockSchema).optional(),
|
|
609
|
+
})
|
|
610
|
+
.strict()
|
|
611
|
+
.superRefine((doc, context) => {
|
|
612
|
+
const slots = new Set(Object.keys(doc.slots));
|
|
613
|
+
doc.adopts?.forEach((rule, index) => {
|
|
614
|
+
const slot = doc.slots[rule.into];
|
|
615
|
+
if (slot == null) {
|
|
616
|
+
context.addIssue({
|
|
617
|
+
code: 'custom',
|
|
618
|
+
path: ['adopts', index, 'into'],
|
|
619
|
+
message: `must name a declared slot; received "${rule.into}"`,
|
|
620
|
+
});
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
/** @type {AuthoredDocKind[]} */
|
|
624
|
+
const adoptedKinds =
|
|
625
|
+
rule.groupBy === 'kind' ? ['namespace'] : (rule.source.kinds ?? []);
|
|
626
|
+
adoptedKinds.forEach(kind => {
|
|
627
|
+
if (!slot.accepts.kinds.includes(kind)) {
|
|
628
|
+
context.addIssue({
|
|
629
|
+
code: 'custom',
|
|
630
|
+
path: ['adopts', index, 'into'],
|
|
631
|
+
message: `slot "${rule.into}" does not accept adopted kind "${kind}"`,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
doc.blocks?.forEach((block, index) => {
|
|
637
|
+
if (block.type === 'collection' && !slots.has(block.source.slot)) {
|
|
638
|
+
context.addIssue({
|
|
639
|
+
code: 'custom',
|
|
640
|
+
path: ['blocks', index, 'source', 'slot'],
|
|
641
|
+
message: `must name a declared slot; received "${block.source.slot}"`,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* @typedef {import('../_shared/contract.js').Expect<
|
|
649
|
+
* import('../_shared/contract.js').Equal<
|
|
650
|
+
* z.infer<typeof NamespaceDocKindSchema>,
|
|
651
|
+
* NamespaceDoc
|
|
652
|
+
* >
|
|
653
|
+
* >} _NamespaceDocDriftLock
|
|
654
|
+
*/
|
|
655
|
+
|
|
656
|
+
// Legacy loose format stays permissive for backward compatibility.
|
|
237
657
|
const LegacyBaseDocSchema = z.object({
|
|
658
|
+
...AuthoredDocGraphFields,
|
|
238
659
|
name: z.string().min(1, 'name is required'),
|
|
239
660
|
displayName: z.string().optional(),
|
|
240
661
|
description: z.string().optional(),
|
|
@@ -255,6 +676,37 @@ const LegacyBaseDocSchema = z.object({
|
|
|
255
676
|
relatedHooks: z.array(z.string()).optional(),
|
|
256
677
|
});
|
|
257
678
|
|
|
679
|
+
const LegacyReferenceDocSchema = LegacyBaseDocSchema.extend({
|
|
680
|
+
title: nonEmptyString,
|
|
681
|
+
description: z.string(),
|
|
682
|
+
sections: z.array(ReferenceSectionSchema).min(1),
|
|
683
|
+
replaces: nonEmptyString.optional(),
|
|
684
|
+
extends: nonEmptyString.optional(),
|
|
685
|
+
tokenCategory: z.string().optional(),
|
|
686
|
+
})
|
|
687
|
+
.passthrough()
|
|
688
|
+
.superRefine((doc, context) => {
|
|
689
|
+
if (doc.replaces != null && doc.extends != null) {
|
|
690
|
+
context.addIssue({
|
|
691
|
+
code: 'custom',
|
|
692
|
+
path: ['extends'],
|
|
693
|
+
message: 'declares both `replaces` and `extends`; choose one',
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
const sectionIds = new Set();
|
|
697
|
+
doc.sections.forEach((section, index) => {
|
|
698
|
+
if (section.id == null) return;
|
|
699
|
+
if (sectionIds.has(section.id)) {
|
|
700
|
+
context.addIssue({
|
|
701
|
+
code: 'custom',
|
|
702
|
+
path: ['sections', index, 'id'],
|
|
703
|
+
message: `duplicate section id "${section.id}"`,
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
sectionIds.add(section.id);
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
|
|
258
710
|
const LegacySingleComponentDocSchema = LegacyBaseDocSchema.extend({
|
|
259
711
|
props: z.array(PropSchema),
|
|
260
712
|
}).passthrough();
|
|
@@ -274,10 +726,11 @@ const LegacySubComponentDocSchema = LegacyBaseDocSchema.extend({
|
|
|
274
726
|
props: z.array(PropSchema),
|
|
275
727
|
}).passthrough();
|
|
276
728
|
|
|
277
|
-
/** The permissive legacy union (sub-component
|
|
729
|
+
/** The permissive legacy union (sub-component, hook, multi, single, then reference). */
|
|
278
730
|
export const LegacyDocSchema = z.union([
|
|
279
731
|
LegacySubComponentDocSchema,
|
|
280
732
|
LegacyHookDocSchema,
|
|
281
733
|
LegacyMultiComponentDocSchema,
|
|
282
734
|
LegacySingleComponentDocSchema,
|
|
735
|
+
LegacyReferenceDocSchema,
|
|
283
736
|
]);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file SchemaDoc for graph metadata shared by every authored doc kind.
|
|
6
|
+
* @position packages/cli/authoring/doctypes/base — doc-type documentation
|
|
7
|
+
*/
|
|
8
|
+
/** @type {import('@astryxdesign/cli/authoring').SchemaDoc} */
|
|
9
|
+
export const doc: import("@astryxdesign/cli/authoring").SchemaDoc;
|