@astryxdesign/cli 0.6.3-canary.f22695a → 0.6.3
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 +1 -2
- 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 +24 -37
- package/api/docs/_adapter.mjs +83 -169
- package/api/docs/detail/detail.mjs +63 -14
- package/api/docs/detail/section/section.d.mts +1 -1
- package/api/docs/detail/section/section.mjs +20 -44
- package/api/docs/detail/section/section.test.mjs +0 -41
- package/api/docs/docs.d.mts +2 -7
- package/api/docs/docs.doc.mjs +10 -27
- package/api/docs/docs.mjs +9 -16
- package/api/docs/docs.test.mjs +0 -6
- package/api/docs/docs.type.d.mts +3 -40
- package/api/docs/docs.type.mjs +8 -36
- package/api/docs/integrationDocs.test.mjs +0 -106
- package/api/doctor/doctor.d.mts +0 -48
- package/api/doctor/doctor.mjs +0 -232
- package/api/doctor/doctor.test.mjs +0 -196
- 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 +3 -5
- 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 +7 -49
- package/api/integration/pack-check.test.mjs +0 -249
- 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 +6 -20
- package/api/theme/build/build.test.mjs +0 -127
- package/api/theme/palette/generate/generate.mjs +1 -1
- package/api/theme/palette/generate/generator.d.mts +13 -10
- package/api/theme/palette/generate/generator.mjs +3 -7
- package/api/theme/theme.type.d.mts +11 -170
- package/api/theme/theme.type.mjs +27 -94
- package/api/upgrade/_adapter.mjs +5 -71
- package/api/upgrade/upgrade.doc.mjs +3 -4
- package/api/upgrade/upgrade.type.d.mts +5 -5
- package/api/upgrade/upgrade.type.mjs +11 -11
- package/assets/codemods/integration-discovery.mjs +2 -40
- package/assets/codemods/integration-discovery.test.mjs +0 -58
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +5 -27
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +5 -20
- package/assets/docs/README.md +0 -9
- package/assets/docs/cli-integrations.doc.mjs +15 -86
- package/assets/docs/styling-libraries.doc.mjs +1 -1
- package/assets/docs/working-with-ai.doc.mjs +1 -1
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +3 -19
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +65 -383
- package/authoring/_shared/contract.ts +0 -22
- package/authoring/codemod/codemod.doc.mjs +1 -6
- package/authoring/codemod/parse.d.mts +8 -8
- package/authoring/codemod/parse.mjs +6 -8
- 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 +23 -788
- package/authoring/doctypes/_schema.mjs +39 -492
- package/authoring/doctypes/base/type.ts +0 -40
- package/authoring/doctypes/command/command.doc.mjs +2 -3
- package/authoring/doctypes/command/parse.d.mts +2 -2
- package/authoring/doctypes/command/parse.mjs +1 -1
- package/authoring/doctypes/command/type.ts +2 -3
- package/authoring/doctypes/component/component.doc.mjs +3 -6
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +3 -4
- package/authoring/doctypes/enum/parse.d.mts +2 -2
- package/authoring/doctypes/enum/parse.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +1 -3
- package/authoring/doctypes/function/function.doc.mjs +0 -4
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +2 -6
- package/authoring/doctypes/hook/hook.doc.mjs +0 -4
- package/authoring/doctypes/hook/parse.d.mts +2 -2
- package/authoring/doctypes/hook/parse.mjs +1 -1
- package/authoring/doctypes/hook/type.ts +2 -3
- package/authoring/doctypes/legacy.d.mts +6 -8
- package/authoring/doctypes/legacy.mjs +4 -5
- package/authoring/doctypes/parse.d.mts +18 -20
- package/authoring/doctypes/parse.mjs +10 -16
- package/authoring/doctypes/parse.test.mjs +3 -77
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +5 -8
- package/authoring/doctypes/reference/reference.doc.mjs +4 -17
- package/authoring/doctypes/reference/type.ts +5 -51
- package/authoring/doctypes/schema/parse.d.mts +2 -2
- package/authoring/doctypes/schema/parse.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +2 -3
- package/authoring/doctypes/template/parse.d.mts +1 -92
- package/authoring/doctypes/template/parse.mjs +2 -36
- package/authoring/doctypes/template/parse.test.mjs +2 -8
- package/authoring/doctypes/template/template.doc.mjs +0 -4
- package/authoring/doctypes/template/type.ts +2 -5
- package/authoring/doctypes/types.ts +9 -10
- 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/index.d.mts +0 -1
- package/authoring/index.d.ts +17 -49
- package/authoring/index.mjs +0 -1
- package/authoring/integration/integration.doc.mjs +6 -13
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/parse.test.mjs +1 -10
- package/authoring/integration/schema.d.mts +4 -6
- package/authoring/integration/schema.mjs +3 -9
- package/authoring/integration/type.ts +6 -23
- package/authoring/shadcn/receipt.d.mts +6 -6
- package/clients/cli/commands/docs.doc.mjs +3 -13
- package/clients/cli/commands/docs.mjs +21 -121
- package/clients/cli/commands/docs.test.mjs +0 -88
- package/clients/cli/commands/integration-authoring.test.mjs +9 -13
- package/clients/cli/commands/theme-palette-generate.doc.mjs +4 -8
- package/clients/cli/commands/upgrade.doc.mjs +2 -2
- package/clients/cli/formatters/index.mjs +1 -162
- package/clients/cli/formatters/index.test.mjs +0 -91
- package/clients/cli/lib/manifest.mjs +2 -7
- package/foundation/config/project.mjs +6 -21
- package/foundation/discovery/component-discovery.d.mts +1 -1
- package/foundation/discovery/component-discovery.mjs +1 -2
- package/foundation/discovery/docs-discovery.d.mts +4 -11
- package/foundation/discovery/docs-discovery.mjs +88 -208
- package/foundation/discovery/docs-discovery.test.mjs +13 -279
- package/foundation/discovery/template-adapter.mjs +1 -2
- package/foundation/integrations/autolink.mjs +5 -12
- package/foundation/integrations/integration-warnings.mjs +0 -6
- package/foundation/integrations/integrations.d.mts +2 -46
- package/foundation/integrations/integrations.mjs +8 -167
- package/foundation/integrations/integrations.test.mjs +1 -384
- package/foundation/integrations/validate-contributions.d.mts +0 -2
- package/foundation/integrations/validate-contributions.mjs +0 -10
- package/foundation/response/json-contract.test.mjs +17 -46
- package/foundation/response/response-types.doc.mjs +1 -6
- package/package.json +11 -9
- package/api/docs/compiled-topics.test.mjs +0 -78
- package/api/docs/index/index.d.mts +0 -18
- package/api/docs/index/index.mjs +0 -32
- package/api/docs/index/index.test.mjs +0 -62
- package/api/upgrade/project-context.test.mjs +0 -272
- package/assets/docs/authoring.doc.mjs +0 -14
- package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +0 -14
- package/assets/templates/blocks/components/Timer/TimerFormats.tsx +0 -34
- package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +0 -14
- package/assets/templates/blocks/components/Timer/TimerInline.tsx +0 -14
- package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +0 -13
- package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +0 -47
- package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +0 -14
- package/assets/templates/blocks/components/Timer/TimerTypography.tsx +0 -31
- package/authoring/doctypes/base/graph-fields.doc.d.mts +0 -9
- package/authoring/doctypes/base/graph-fields.doc.mjs +0 -62
- package/authoring/doctypes/load-contract.test.mjs +0 -207
- package/authoring/doctypes/namespace/namespace.doc.d.mts +0 -9
- package/authoring/doctypes/namespace/namespace.doc.mjs +0 -132
- package/authoring/doctypes/namespace/parse.d.mts +0 -12
- package/authoring/doctypes/namespace/parse.mjs +0 -25
- package/authoring/doctypes/namespace/parse.test.mjs +0 -165
- package/authoring/doctypes/namespace/type.ts +0 -71
- package/authoring/identity/identity.doc.d.mts +0 -9
- package/authoring/identity/identity.doc.mjs +0 -61
- package/authoring/identity/type.ts +0 -132
- package/foundation/discovery/authoring-self-docs.d.mts +0 -69
- package/foundation/discovery/authoring-self-docs.mjs +0 -214
- package/foundation/discovery/authoring-self-docs.test.mjs +0 -154
- package/foundation/discovery/docs-output-budget.d.mts +0 -28
- package/foundation/discovery/docs-output-budget.mjs +0 -50
- package/foundation/discovery/docs-section-key.d.mts +0 -98
- package/foundation/discovery/docs-section-key.mjs +0 -221
- package/foundation/discovery/docs-section-key.test.mjs +0 -224
- package/foundation/doc-compiler/compile.d.mts +0 -162
- package/foundation/doc-compiler/compile.mjs +0 -262
- package/foundation/doc-compiler/doc-compiler.test.mjs +0 -687
- package/foundation/doc-compiler/ir.d.mts +0 -9
- package/foundation/doc-compiler/ir.mjs +0 -287
- package/foundation/doc-compiler/lenses.d.mts +0 -33
- package/foundation/doc-compiler/lenses.mjs +0 -127
- package/foundation/identity/provider-identity.d.mts +0 -90
- package/foundation/identity/provider-identity.mjs +0 -320
- package/foundation/identity/provider-identity.test.mjs +0 -254
- package/foundation/identity/providers.d.mts +0 -7
- package/foundation/identity/providers.mjs +0 -16
- package/foundation/integrations/provider-conflicts.test.mjs +0 -125
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file The authoring self-docs, and the `authoring` topic built from them.
|
|
5
|
-
*
|
|
6
|
-
* @input The SchemaDoc each authoring module colocates as `*.doc.mjs` under
|
|
7
|
-
* packages/cli/authoring.
|
|
8
|
-
* @output {@link AUTHORING_SELF_DOCS} (every self-doc, in reading order), the
|
|
9
|
-
* `authoring` reference topic with one section per self-doc, and an audit
|
|
10
|
-
* naming any self-doc the topic cannot reach, any that fails to load, and any
|
|
11
|
-
* section over the docs output budget.
|
|
12
|
-
* @position Read by assets/docs/authoring.doc.mjs (the topic) and by Doctor
|
|
13
|
-
* (the audit). Lives in foundation because authoring/ holds only contracts.
|
|
14
|
-
* A new `*.doc.mjs` under authoring/ must be added to the list, or Doctor and
|
|
15
|
-
* the self-doc tests fail.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import * as fs from 'node:fs';
|
|
19
|
-
import * as path from 'node:path';
|
|
20
|
-
import {pathToFileURL} from 'node:url';
|
|
21
|
-
import {CLI_ROOT} from '../fs/paths.mjs';
|
|
22
|
-
import {
|
|
23
|
-
DOC_OUTPUT_BUDGET_BYTES,
|
|
24
|
-
oversizedDocSections,
|
|
25
|
-
} from './docs-output-budget.mjs';
|
|
26
|
-
|
|
27
|
-
/** The directory the self-docs live under. */
|
|
28
|
-
export const AUTHORING_ROOT = path.join(CLI_ROOT, 'authoring');
|
|
29
|
-
|
|
30
|
-
/** Every authoring self-doc, relative to {@link AUTHORING_ROOT}, in reading order. */
|
|
31
|
-
export const AUTHORING_SELF_DOCS = [
|
|
32
|
-
'integration/integration.doc.mjs',
|
|
33
|
-
'config/config.doc.mjs',
|
|
34
|
-
'codemod/codemod.doc.mjs',
|
|
35
|
-
'identity/identity.doc.mjs',
|
|
36
|
-
'doctypes/base/graph-fields.doc.mjs',
|
|
37
|
-
'doctypes/component/component.doc.mjs',
|
|
38
|
-
'doctypes/hook/hook.doc.mjs',
|
|
39
|
-
'doctypes/function/function.doc.mjs',
|
|
40
|
-
'doctypes/command/command.doc.mjs',
|
|
41
|
-
'doctypes/enum/enum.doc.mjs',
|
|
42
|
-
'doctypes/namespace/namespace.doc.mjs',
|
|
43
|
-
'doctypes/reference/reference.doc.mjs',
|
|
44
|
-
'doctypes/schema/schema.doc.mjs',
|
|
45
|
-
'doctypes/template/template.doc.mjs',
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
/** Blocks a self-doc note may carry that a topic section can render. */
|
|
49
|
-
const TOPIC_BLOCKS = new Set(['prose', 'list', 'code', 'heading', 'table']);
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Every `*.doc.mjs` under `root`, relative and sorted.
|
|
53
|
-
* @param {string} [root]
|
|
54
|
-
* @returns {string[]}
|
|
55
|
-
*/
|
|
56
|
-
export function discoverAuthoringSelfDocSources(root = AUTHORING_ROOT) {
|
|
57
|
-
/** @type {string[]} */
|
|
58
|
-
const found = [];
|
|
59
|
-
/** @param {string} dir */
|
|
60
|
-
const walk = dir => {
|
|
61
|
-
for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {
|
|
62
|
-
if (entry.name === 'node_modules' || entry.name.startsWith('__')) continue;
|
|
63
|
-
const full = path.join(dir, entry.name);
|
|
64
|
-
if (entry.isDirectory()) walk(full);
|
|
65
|
-
else if (entry.name.endsWith('.doc.mjs')) {
|
|
66
|
-
found.push(path.relative(root, full).split(path.sep).join('/'));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
walk(root);
|
|
71
|
-
return found.sort();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Import each self-doc. One that fails is reported, never thrown, so one bad
|
|
76
|
-
* file cannot take the rest of the topic down with it.
|
|
77
|
-
* @param {string[]} [sources]
|
|
78
|
-
* @param {string} [root]
|
|
79
|
-
* @returns {Promise<{loaded: {source: string, doc: any}[], failed: {source: string, error: string}[]}>}
|
|
80
|
-
*/
|
|
81
|
-
export async function loadAuthoringSelfDocs(
|
|
82
|
-
sources = AUTHORING_SELF_DOCS,
|
|
83
|
-
root = AUTHORING_ROOT,
|
|
84
|
-
) {
|
|
85
|
-
const loaded = [];
|
|
86
|
-
const failed = [];
|
|
87
|
-
for (const source of sources) {
|
|
88
|
-
try {
|
|
89
|
-
const mod = await import(pathToFileURL(path.join(root, source)).href);
|
|
90
|
-
const doc = mod.doc ?? mod.docs ?? mod.default;
|
|
91
|
-
if (typeof doc?.name !== 'string' || typeof doc?.description !== 'string') {
|
|
92
|
-
throw new Error('exports no doc with a name and a description');
|
|
93
|
-
}
|
|
94
|
-
loaded.push({source, doc});
|
|
95
|
-
} catch (error) {
|
|
96
|
-
failed.push({
|
|
97
|
-
source,
|
|
98
|
-
error: error instanceof Error ? error.message : String(error),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return {loaded, failed};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param {any[]} fields
|
|
107
|
-
* @returns {string[][]}
|
|
108
|
-
*/
|
|
109
|
-
function fieldRows(fields) {
|
|
110
|
-
return fields.flatMap(field => [
|
|
111
|
-
[
|
|
112
|
-
String(field.name),
|
|
113
|
-
String(field.type ?? ''),
|
|
114
|
-
field.required ? 'yes' : 'no',
|
|
115
|
-
[
|
|
116
|
-
field.description,
|
|
117
|
-
field.default != null ? `Default: ${field.default}.` : null,
|
|
118
|
-
field.example != null ? `Example: ${field.example}.` : null,
|
|
119
|
-
]
|
|
120
|
-
.filter(Boolean)
|
|
121
|
-
.join(' '),
|
|
122
|
-
],
|
|
123
|
-
...fieldRows(field.fields ?? []),
|
|
124
|
-
]);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* One self-doc as a topic section, keyed by the doc's own name.
|
|
129
|
-
* @param {any} doc
|
|
130
|
-
* @returns {import('../../authoring/doctypes/reference/type').ReferenceSection}
|
|
131
|
-
*/
|
|
132
|
-
function selfDocSection(doc) {
|
|
133
|
-
/** @type {any[]} */
|
|
134
|
-
const content = [{type: 'prose', text: doc.description}];
|
|
135
|
-
if (doc.appliesTo) {
|
|
136
|
-
content.push({type: 'prose', text: `Applies to: ${doc.appliesTo}`});
|
|
137
|
-
}
|
|
138
|
-
const rows = fieldRows(doc.fields ?? []);
|
|
139
|
-
if (rows.length > 0) {
|
|
140
|
-
content.push({
|
|
141
|
-
type: 'table',
|
|
142
|
-
headers: ['Field', 'Type', 'Required', 'Description'],
|
|
143
|
-
rows,
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
for (const example of doc.examples ?? []) {
|
|
147
|
-
if (typeof example?.code !== 'string' || example.code.trim() === '') continue;
|
|
148
|
-
content.push({
|
|
149
|
-
type: 'code',
|
|
150
|
-
lang: example.lang ?? 'js',
|
|
151
|
-
...(example.label ? {label: example.label} : {}),
|
|
152
|
-
code: example.code,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
for (const note of doc.notes ?? []) {
|
|
156
|
-
if (TOPIC_BLOCKS.has(note?.type)) content.push(note);
|
|
157
|
-
}
|
|
158
|
-
return {id: doc.name, title: doc.displayName ?? doc.name, content};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* The `authoring` topic: one section per self-doc, in the order given.
|
|
163
|
-
* @param {any[]} docs
|
|
164
|
-
* @returns {import('../../authoring/doctypes/reference/type').ReferenceDoc}
|
|
165
|
-
*/
|
|
166
|
-
export function buildAuthoringReferenceDoc(docs) {
|
|
167
|
-
return /** @type {any} */ ({
|
|
168
|
-
name: 'authoring',
|
|
169
|
-
title: 'Authoring Reference',
|
|
170
|
-
category: 'guide',
|
|
171
|
-
description:
|
|
172
|
-
'Every file an integration author writes, field by field: the integration manifest, astryx.config, codemods, identity, and each doc type.',
|
|
173
|
-
sections: docs.map(selfDocSection),
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* The `authoring` topic from every self-doc that loads. One that fails is left
|
|
179
|
-
* out here and reported by {@link auditAuthoringSelfDocs}.
|
|
180
|
-
* @returns {Promise<import('../../authoring/doctypes/reference/type').ReferenceDoc>}
|
|
181
|
-
*/
|
|
182
|
-
export async function buildAuthoringTopic() {
|
|
183
|
-
const {loaded} = await loadAuthoringSelfDocs();
|
|
184
|
-
return buildAuthoringReferenceDoc(loaded.map(entry => entry.doc));
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* What stands between a self-doc and a reader of `astryx docs authoring`.
|
|
189
|
-
* @param {{root?: string, sources?: string[], budget?: number}} [options]
|
|
190
|
-
* @returns {Promise<{
|
|
191
|
-
* sections: number,
|
|
192
|
-
* unreachable: string[],
|
|
193
|
-
* failed: {source: string, error: string}[],
|
|
194
|
-
* oversized: {key: string, title: string, bytes: number}[],
|
|
195
|
-
* }>}
|
|
196
|
-
*/
|
|
197
|
-
export async function auditAuthoringSelfDocs({
|
|
198
|
-
root = AUTHORING_ROOT,
|
|
199
|
-
sources = AUTHORING_SELF_DOCS,
|
|
200
|
-
budget = DOC_OUTPUT_BUDGET_BYTES,
|
|
201
|
-
} = {}) {
|
|
202
|
-
const listed = new Set(sources);
|
|
203
|
-
const unreachable = discoverAuthoringSelfDocSources(root).filter(
|
|
204
|
-
source => !listed.has(source),
|
|
205
|
-
);
|
|
206
|
-
const {loaded, failed} = await loadAuthoringSelfDocs(sources, root);
|
|
207
|
-
const topic = buildAuthoringReferenceDoc(loaded.map(entry => entry.doc));
|
|
208
|
-
return {
|
|
209
|
-
sections: topic.sections.length,
|
|
210
|
-
unreachable,
|
|
211
|
-
failed,
|
|
212
|
-
oversized: oversizedDocSections(topic.sections, budget),
|
|
213
|
-
};
|
|
214
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
4
|
-
import * as fs from 'node:fs';
|
|
5
|
-
import * as path from 'node:path';
|
|
6
|
-
import {
|
|
7
|
-
AUTHORING_SELF_DOCS,
|
|
8
|
-
auditAuthoringSelfDocs,
|
|
9
|
-
buildAuthoringTopic,
|
|
10
|
-
discoverAuthoringSelfDocSources,
|
|
11
|
-
} from './authoring-self-docs.mjs';
|
|
12
|
-
import {
|
|
13
|
-
GRAPH_BLOCK_TYPES,
|
|
14
|
-
GRAPH_ONLY_FIELDS,
|
|
15
|
-
problemsInTopic,
|
|
16
|
-
} from './docs-discovery.mjs';
|
|
17
|
-
import {doc as graphFieldsDoc} from '../../authoring/doctypes/base/graph-fields.doc.mjs';
|
|
18
|
-
import {doc as namespaceDoc} from '../../authoring/doctypes/namespace/namespace.doc.mjs';
|
|
19
|
-
import {doc as referenceDoc} from '../../authoring/doctypes/reference/reference.doc.mjs';
|
|
20
|
-
import {docs} from '../../api/docs/docs.mjs';
|
|
21
|
-
|
|
22
|
-
const SLOW = 60_000;
|
|
23
|
-
|
|
24
|
-
describe('authoring self-docs', () => {
|
|
25
|
-
it('lists every self-doc on disk exactly once', () => {
|
|
26
|
-
expect([...AUTHORING_SELF_DOCS].sort()).toEqual(
|
|
27
|
-
discoverAuthoringSelfDocSources(),
|
|
28
|
-
);
|
|
29
|
-
expect(new Set(AUTHORING_SELF_DOCS).size).toBe(AUTHORING_SELF_DOCS.length);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('audits clean: every self-doc loads, is reachable, and fits one read', async () => {
|
|
33
|
-
expect(await auditAuthoringSelfDocs()).toEqual({
|
|
34
|
-
sections: AUTHORING_SELF_DOCS.length,
|
|
35
|
-
unreachable: [],
|
|
36
|
-
failed: [],
|
|
37
|
-
oversized: [],
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('builds a valid topic with one section per self-doc', async () => {
|
|
42
|
-
const topic = await buildAuthoringTopic();
|
|
43
|
-
expect(problemsInTopic(topic)).toEqual([]);
|
|
44
|
-
expect(topic.sections).toHaveLength(AUTHORING_SELF_DOCS.length);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it(
|
|
48
|
-
'is readable progressively through the docs API',
|
|
49
|
-
async () => {
|
|
50
|
-
const index = await docs('authoring', undefined, {index: true});
|
|
51
|
-
expect(index.type).toBe('docs.index');
|
|
52
|
-
expect(index.data.sections.map(s => s.id)).toContain('integration');
|
|
53
|
-
const section = await docs('authoring', 'integration');
|
|
54
|
-
expect(section.data.title).toBe('Astryx Integration');
|
|
55
|
-
expect(section.data.content.some(block => block.type === 'table')).toBe(
|
|
56
|
-
true,
|
|
57
|
-
);
|
|
58
|
-
},
|
|
59
|
-
SLOW,
|
|
60
|
-
);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('what the authoring docs say about the unbuilt docs graph', () => {
|
|
64
|
-
it('marks exactly the fields topic loading rejects as not read yet', () => {
|
|
65
|
-
const notReadYet = graphFieldsDoc.fields
|
|
66
|
-
.filter(field => /Not read yet/.test(field.description))
|
|
67
|
-
.map(field => field.name);
|
|
68
|
-
expect(notReadYet.sort()).toEqual([...GRAPH_ONLY_FIELDS].sort());
|
|
69
|
-
for (const field of graphFieldsDoc.fields) {
|
|
70
|
-
if (notReadYet.includes(field.name)) {
|
|
71
|
-
expect(field.description).toMatch(/fails to load/);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
expect(graphFieldsDoc.description).toMatch(/not built yet/);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('says a topic using a graph block fails to load', () => {
|
|
78
|
-
const content = referenceDoc.fields
|
|
79
|
-
.flatMap(field => [field, ...(field.fields ?? [])])
|
|
80
|
-
.find(field => field.name === 'sections[].content');
|
|
81
|
-
for (const type of GRAPH_BLOCK_TYPES) {
|
|
82
|
-
expect(content.description).toContain(type);
|
|
83
|
-
}
|
|
84
|
-
expect(content.description).toMatch(/fails to load/);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('says namespace docs are not loaded yet', () => {
|
|
88
|
-
expect(namespaceDoc.description).toMatch(/Not loaded yet/);
|
|
89
|
-
expect(
|
|
90
|
-
problemsInTopic({
|
|
91
|
-
...namespaceDoc.examples?.[0],
|
|
92
|
-
type: 'namespace',
|
|
93
|
-
name: 'x',
|
|
94
|
-
}),
|
|
95
|
-
).toEqual([
|
|
96
|
-
'"x" is a namespace doc. Only the docs graph reads namespace docs, and it is not built yet; remove this file from the docs directory.',
|
|
97
|
-
]);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('auditAuthoringSelfDocs', () => {
|
|
102
|
-
let root;
|
|
103
|
-
|
|
104
|
-
beforeEach(() => {
|
|
105
|
-
root = fs.mkdtempSync(path.join(process.cwd(), '.astryx-self-docs-'));
|
|
106
|
-
fs.mkdirSync(path.join(root, 'kept'));
|
|
107
|
-
fs.writeFileSync(
|
|
108
|
-
path.join(root, 'kept', 'kept.doc.mjs'),
|
|
109
|
-
"export const doc = {type: 'schema', name: 'kept', displayName: 'Kept', description: 'Listed.', fields: []};\n",
|
|
110
|
-
);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
afterEach(() => {
|
|
114
|
-
fs.rmSync(root, {recursive: true, force: true});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('names a self-doc on disk that the list leaves out', async () => {
|
|
118
|
-
fs.writeFileSync(
|
|
119
|
-
path.join(root, 'kept', 'forgotten.doc.mjs'),
|
|
120
|
-
"export const doc = {name: 'forgotten', description: 'Not listed.'};\n",
|
|
121
|
-
);
|
|
122
|
-
const audit = await auditAuthoringSelfDocs({
|
|
123
|
-
root,
|
|
124
|
-
sources: ['kept/kept.doc.mjs'],
|
|
125
|
-
});
|
|
126
|
-
expect(audit.unreachable).toEqual(['kept/forgotten.doc.mjs']);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('reports a self-doc that fails to load instead of throwing', async () => {
|
|
130
|
-
fs.writeFileSync(
|
|
131
|
-
path.join(root, 'kept', 'broken.doc.mjs'),
|
|
132
|
-
'export const doc = {;\n',
|
|
133
|
-
);
|
|
134
|
-
const audit = await auditAuthoringSelfDocs({
|
|
135
|
-
root,
|
|
136
|
-
sources: ['kept/kept.doc.mjs', 'kept/broken.doc.mjs'],
|
|
137
|
-
});
|
|
138
|
-
expect(audit.failed.map(entry => entry.source)).toEqual([
|
|
139
|
-
'kept/broken.doc.mjs',
|
|
140
|
-
]);
|
|
141
|
-
expect(audit.sections).toBe(1);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('names a section over the budget', async () => {
|
|
145
|
-
const audit = await auditAuthoringSelfDocs({
|
|
146
|
-
root,
|
|
147
|
-
sources: ['kept/kept.doc.mjs'],
|
|
148
|
-
budget: 10,
|
|
149
|
-
});
|
|
150
|
-
expect(audit.oversized).toEqual([
|
|
151
|
-
expect.objectContaining({key: 'kept', title: 'Kept'}),
|
|
152
|
-
]);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
-
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A payload's size as `--json` prints it: the envelope data, two-space
|
|
6
|
-
* indented, in UTF-8 bytes.
|
|
7
|
-
* @param {unknown} payload
|
|
8
|
-
* @returns {number}
|
|
9
|
-
*/
|
|
10
|
-
export function docPayloadBytes(payload: unknown): number;
|
|
11
|
-
/**
|
|
12
|
-
* @param {import('../../api/docs/docs.type.mjs').DocsIndex} index
|
|
13
|
-
* @returns {number}
|
|
14
|
-
*/
|
|
15
|
-
export function docsIndexBytes(index: import("../../api/docs/docs.type.mjs").DocsIndex): number;
|
|
16
|
-
/**
|
|
17
|
-
* The sections a single read would return more than `budget` bytes for.
|
|
18
|
-
* @param {any[]} sections
|
|
19
|
-
* @param {number} [budget]
|
|
20
|
-
* @returns {{key: string, title: string, bytes: number}[]}
|
|
21
|
-
*/
|
|
22
|
-
export function oversizedDocSections(sections: any[], budget?: number): {
|
|
23
|
-
key: string;
|
|
24
|
-
title: string;
|
|
25
|
-
bytes: number;
|
|
26
|
-
}[];
|
|
27
|
-
/** The most one index or one section read may return, in bytes. */
|
|
28
|
-
export const DOC_OUTPUT_BUDGET_BYTES: number;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file The most one progressive docs read may return.
|
|
5
|
-
*
|
|
6
|
-
* @input Docs payloads: one topic's section index, or one section.
|
|
7
|
-
* @output Their size in bytes as `--json` prints them, and the sections over
|
|
8
|
-
* the budget.
|
|
9
|
-
* @position Shared by Doctor's docs checks and the authoring self-doc audit, so
|
|
10
|
-
* both hold every read to the same limit.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {sectionKey} from './docs-section-key.mjs';
|
|
14
|
-
|
|
15
|
-
/** The most one index or one section read may return, in bytes. */
|
|
16
|
-
export const DOC_OUTPUT_BUDGET_BYTES = 32 * 1024;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* A payload's size as `--json` prints it: the envelope data, two-space
|
|
20
|
-
* indented, in UTF-8 bytes.
|
|
21
|
-
* @param {unknown} payload
|
|
22
|
-
* @returns {number}
|
|
23
|
-
*/
|
|
24
|
-
export function docPayloadBytes(payload) {
|
|
25
|
-
return Buffer.byteLength(JSON.stringify(payload, null, 2), 'utf8');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {import('../../api/docs/docs.type.mjs').DocsIndex} index
|
|
30
|
-
* @returns {number}
|
|
31
|
-
*/
|
|
32
|
-
export function docsIndexBytes(index) {
|
|
33
|
-
return docPayloadBytes({type: 'docs.index', data: index});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The sections a single read would return more than `budget` bytes for.
|
|
38
|
-
* @param {any[]} sections
|
|
39
|
-
* @param {number} [budget]
|
|
40
|
-
* @returns {{key: string, title: string, bytes: number}[]}
|
|
41
|
-
*/
|
|
42
|
-
export function oversizedDocSections(sections, budget = DOC_OUTPUT_BUDGET_BYTES) {
|
|
43
|
-
return sections
|
|
44
|
-
.map(section => ({
|
|
45
|
-
key: sectionKey(section),
|
|
46
|
-
title: section.title,
|
|
47
|
-
bytes: docPayloadBytes({type: 'docs.detail.section', data: section}),
|
|
48
|
-
}))
|
|
49
|
-
.filter(entry => entry.bytes > budget);
|
|
50
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
-
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Record the authored title of a section whose visible title a translation
|
|
6
|
-
* overlay replaces.
|
|
7
|
-
* @template {object} T
|
|
8
|
-
* @param {T} section
|
|
9
|
-
* @param {string} title
|
|
10
|
-
* @returns {T}
|
|
11
|
-
*/
|
|
12
|
-
export function withSourceTitle<T extends object>(section: T, title: string): T;
|
|
13
|
-
/**
|
|
14
|
-
* @param {any} section
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
export function sourceTitle(section: any): string;
|
|
18
|
-
/**
|
|
19
|
-
* The key a title derives: accents folded, `&` spelled out, and every other
|
|
20
|
-
* run of non-alphanumerics collapsed to one hyphen. Empty when the title has
|
|
21
|
-
* no Latin letters or digits to derive from.
|
|
22
|
-
* @param {unknown} title
|
|
23
|
-
* @returns {string}
|
|
24
|
-
*/
|
|
25
|
-
export function sectionTitleKey(title: unknown): string;
|
|
26
|
-
/**
|
|
27
|
-
* The key a section is addressed by: its authored `id`, else the key its
|
|
28
|
-
* authored title derives.
|
|
29
|
-
* @param {any} section
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
export function sectionKey(section: any): string;
|
|
33
|
-
/**
|
|
34
|
-
* Problems with the keys of a topic's sections: an authored id that is not a
|
|
35
|
-
* stable key, a title no key derives from, and two sections sharing a key.
|
|
36
|
-
* Keys are never suffixed to make them unique, because readers link to them.
|
|
37
|
-
* @param {any[]} sections
|
|
38
|
-
* @returns {string[]}
|
|
39
|
-
*/
|
|
40
|
-
export function sectionKeyProblems(sections: any[]): string[];
|
|
41
|
-
/**
|
|
42
|
-
* Stamp every section with the key it is addressed by. Runs only after
|
|
43
|
-
* extensions merge: a derived key must never take part in merge matching.
|
|
44
|
-
* @template {{sections: any[]}} T
|
|
45
|
-
* @param {T} doc
|
|
46
|
-
* @returns {T}
|
|
47
|
-
*/
|
|
48
|
-
export function withSectionKeys<T extends {
|
|
49
|
-
sections: any[];
|
|
50
|
-
}>(doc: T): T;
|
|
51
|
-
/**
|
|
52
|
-
* Find the section a reader asked for: by key, then by exact title (or the
|
|
53
|
-
* key the query derives), then by a title that contains the query. More than
|
|
54
|
-
* one match is refused rather than guessed.
|
|
55
|
-
* @param {any[]} sections
|
|
56
|
-
* @param {string} query
|
|
57
|
-
* @returns {{section: any | null, candidates: any[]}} `candidates` lists the
|
|
58
|
-
* matches when the query is ambiguous, and is empty when nothing matches
|
|
59
|
-
*/
|
|
60
|
-
export function findDocSection(sections: any[], query: string): {
|
|
61
|
-
section: any | null;
|
|
62
|
-
candidates: any[];
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* One line that says what a section holds: its first prose or list text,
|
|
66
|
-
* whitespace collapsed, cut at a word boundary.
|
|
67
|
-
* @param {any} section
|
|
68
|
-
* @param {number} [max]
|
|
69
|
-
* @returns {string}
|
|
70
|
-
*/
|
|
71
|
-
export function sectionSummary(section: any, max?: number): string;
|
|
72
|
-
/**
|
|
73
|
-
* The index a topic-only read returns: what the topic is, and one entry per
|
|
74
|
-
* section with the key to read it by.
|
|
75
|
-
* @param {{name: string, title: string, description: string, sections: any[]}} doc
|
|
76
|
-
* @returns {import('../../api/docs/docs.type.mjs').DocsIndex}
|
|
77
|
-
*/
|
|
78
|
-
export function buildDocsIndexData(doc: {
|
|
79
|
-
name: string;
|
|
80
|
-
title: string;
|
|
81
|
-
description: string;
|
|
82
|
-
sections: any[];
|
|
83
|
-
}): import("../../api/docs/docs.type.mjs").DocsIndex;
|
|
84
|
-
/**
|
|
85
|
-
* @file Stable section keys, section lookup, and the topic index.
|
|
86
|
-
*
|
|
87
|
-
* @input Reference-doc sections, each with an optional authored `id`.
|
|
88
|
-
* @output The key a section is addressed by (its `id`, else a kebab-case key
|
|
89
|
-
* derived from its authored title), lookup by key or title, and the compact
|
|
90
|
-
* index a topic-only docs read returns.
|
|
91
|
-
* @position Shared by docs discovery (which rejects colliding keys before a
|
|
92
|
-
* reader sees them), the docs leaves (index, section, detail), and Doctor
|
|
93
|
-
* (output budgets). Imports nothing from discovery, so both can use it.
|
|
94
|
-
*/
|
|
95
|
-
/** A stable key: lowercase letters and digits, joined by single hyphens. */
|
|
96
|
-
export const SECTION_KEY_RE: RegExp;
|
|
97
|
-
/** The longest summary an index entry carries, in characters. */
|
|
98
|
-
export const SECTION_SUMMARY_MAX: 240;
|