@astryxdesign/cli 0.4.5 → 0.4.6-canary.cea9ecd
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/CHANGELOG.md +26 -0
- package/api/component/_adapter.d.mts +22 -5
- package/api/component/_adapter.mjs +51 -3
- package/api/docs/_adapter.d.mts +37 -8
- package/api/docs/_adapter.mjs +70 -41
- package/api/docs/detail/detail.d.mts +2 -0
- package/api/docs/detail/detail.mjs +12 -10
- package/api/docs/detail/section/section.d.mts +2 -0
- package/api/docs/detail/section/section.mjs +1 -0
- package/api/docs/docs.d.mts +2 -0
- package/api/docs/docs.doc.mjs +11 -2
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.type.d.mts +15 -0
- package/api/docs/docs.type.mjs +6 -0
- package/api/docs/integrationDocs.test.mjs +208 -0
- package/api/docs/list/list.d.mts +5 -1
- package/api/docs/list/list.mjs +30 -14
- package/api/init/run/run.mjs +9 -4
- package/api/integration/validate-integration.mjs +2 -1
- package/api/integration/validate-integration.type.d.mts +1 -0
- package/api/integration/validate-integration.type.mjs +1 -0
- package/api/search/search.mjs +26 -15
- package/api/upgrade/_adapter.d.mts +2 -2
- package/api/upgrade/_adapter.mjs +7 -3
- package/api/upgrade/run/run.mjs +1 -1
- package/assets/codemods/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +245 -0
- package/assets/codemods/transforms/v0.1.0/drop-xds-prefix-imports.mjs +139 -13
- package/assets/docs/cli-integrations.doc.mjs +41 -3
- package/assets/docs/layout.doc.dense.mjs +275 -30
- package/assets/docs/layout.doc.mjs +412 -78
- package/assets/docs/theme.doc.mjs +3 -3
- package/assets/templates/blocks/components/AvatarGroup/AvatarGroupInteractive.doc.mjs +15 -0
- package/assets/templates/blocks/components/AvatarGroup/AvatarGroupInteractive.tsx +47 -0
- package/assets/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.doc.mjs +1 -1
- package/assets/templates/blocks/components/Breadcrumbs/BreadcrumbsCustomSeparator.tsx +18 -5
- package/assets/templates/blocks/components/Selector/SelectorOptionDescriptions.doc.mjs +14 -0
- package/assets/templates/blocks/components/Selector/SelectorOptionDescriptions.tsx +76 -0
- package/assets/templates/pages/dashboard-cohort-funnel/page.tsx +914 -0
- package/assets/templates/pages/dashboard-cohort-funnel/template.doc.mjs +12 -0
- package/assets/templates/pages/dashboard-data/page.tsx +894 -0
- package/assets/templates/pages/dashboard-data/template.doc.mjs +13 -0
- package/assets/templates/pages/dashboard-executive-summary/page.tsx +874 -0
- package/assets/templates/pages/dashboard-executive-summary/template.doc.mjs +13 -0
- package/assets/templates/pages/dashboard-project-status/page.tsx +1139 -0
- package/assets/templates/pages/dashboard-project-status/template.doc.mjs +13 -0
- package/assets/templates/pages/dashboard-service-monitoring/page.tsx +1590 -0
- package/assets/templates/pages/dashboard-service-monitoring/template.doc.mjs +12 -0
- package/authoring/doctypes/_schema.d.mts +2 -0
- package/authoring/doctypes/_schema.mjs +5 -0
- package/authoring/doctypes/reference/reference.doc.mjs +14 -0
- package/authoring/doctypes/reference/type.ts +12 -0
- package/authoring/doctypes/template/type.ts +2 -0
- package/authoring/integration/integration.doc.mjs +10 -1
- package/authoring/integration/parse.d.mts +1 -0
- package/authoring/integration/parse.mjs +1 -0
- package/authoring/integration/parse.test.mjs +1 -0
- package/authoring/integration/type.ts +5 -0
- package/clients/cli/commands/component-ownership.test.mjs +63 -3
- package/clients/cli/commands/theme-build.doc.mjs +1 -1
- package/foundation/agent-docs/agent-docs.d.mts +19 -3
- package/foundation/agent-docs/agent-docs.mjs +30 -11
- package/foundation/agent-docs/agent-docs.test.mjs +38 -0
- package/foundation/config/project.d.mts +16 -0
- package/foundation/config/project.mjs +65 -4
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/discovery/docs-discovery.d.mts +185 -0
- package/foundation/discovery/docs-discovery.mjs +544 -0
- package/foundation/discovery/docs-discovery.test.mjs +341 -0
- package/foundation/integrations/integrations.d.mts +8 -6
- package/foundation/integrations/integrations.mjs +6 -4
- package/foundation/integrations/validate-contributions.mjs +30 -2
- package/package.json +9 -9
|
@@ -24,6 +24,7 @@ function scaffold({
|
|
|
24
24
|
withCodemods = true,
|
|
25
25
|
brokenComponent = false,
|
|
26
26
|
brokenCodemod = false,
|
|
27
|
+
docs = null,
|
|
27
28
|
integrationIssuesUrl = 'https://example.com/widgets/issues',
|
|
28
29
|
} = {}) {
|
|
29
30
|
fs.writeFileSync(
|
|
@@ -48,6 +49,7 @@ function scaffold({
|
|
|
48
49
|
if (withComponents) manifest.components = './components';
|
|
49
50
|
if (withTemplates) manifest.templates = './templates';
|
|
50
51
|
if (withCodemods) manifest.codemods = './codemods';
|
|
52
|
+
if (docs) manifest.docs = './docs';
|
|
51
53
|
if (integrationIssuesUrl) manifest.issuesUrl = integrationIssuesUrl;
|
|
52
54
|
fs.writeFileSync(
|
|
53
55
|
path.join(pkgDir, 'astryx.integration.mjs'),
|
|
@@ -99,9 +101,34 @@ function scaffold({
|
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
if (docs) {
|
|
105
|
+
const docsDir = path.join(pkgDir, 'docs');
|
|
106
|
+
fs.mkdirSync(docsDir, {recursive: true});
|
|
107
|
+
for (const [file, doc] of Object.entries(docs)) {
|
|
108
|
+
fs.writeFileSync(
|
|
109
|
+
path.join(docsDir, file),
|
|
110
|
+
typeof doc === 'string'
|
|
111
|
+
? doc
|
|
112
|
+
: `export const docs = ${JSON.stringify(doc, null, 2)};\n`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
102
117
|
return pkgDir;
|
|
103
118
|
}
|
|
104
119
|
|
|
120
|
+
/** A minimal, valid topic for the docs-root fixtures. */
|
|
121
|
+
function topicDoc(fields) {
|
|
122
|
+
return {
|
|
123
|
+
type: 'generic',
|
|
124
|
+
name: 'deploying',
|
|
125
|
+
title: 'Deploying',
|
|
126
|
+
description: 'How to ship it.',
|
|
127
|
+
sections: [{title: 'Overview', content: [{type: 'prose', text: 'Ship it.'}]}],
|
|
128
|
+
...fields,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
105
132
|
beforeEach(() => {
|
|
106
133
|
originalCwd = process.cwd();
|
|
107
134
|
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-project-test-'));
|
|
@@ -198,6 +225,45 @@ describe('Project discovery', () => {
|
|
|
198
225
|
expect(integration[0].codemods[0].id).toBe('drop-foo');
|
|
199
226
|
});
|
|
200
227
|
|
|
228
|
+
it('docs() adds an integration topic beside the built-in ones', async () => {
|
|
229
|
+
scaffold({docs: {'deploying.doc.mjs': topicDoc()}});
|
|
230
|
+
const project = await Project.load(tmpDir);
|
|
231
|
+
const catalog = await project.docs();
|
|
232
|
+
expect(catalog.resolve('deploying')).toMatchObject({
|
|
233
|
+
name: 'deploying',
|
|
234
|
+
package: '@acme/widgets',
|
|
235
|
+
});
|
|
236
|
+
// The CLI's own topics are still there.
|
|
237
|
+
expect(catalog.resolve('tokens').package).toBe('@astryxdesign/cli');
|
|
238
|
+
expect(await project.issues()).toEqual([]);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('docs() lets an integration replace a built-in topic, aliasing the old name', async () => {
|
|
242
|
+
scaffold({
|
|
243
|
+
docs: {
|
|
244
|
+
'setup.doc.mjs': topicDoc({name: 'setup', replaces: 'getting-started'}),
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
const project = await Project.load(tmpDir);
|
|
248
|
+
const catalog = await project.docs();
|
|
249
|
+
expect(catalog.resolve('setup').package).toBe('@acme/widgets');
|
|
250
|
+
expect(catalog.resolve('getting-started').name).toBe('setup');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('docs() records an unusable topic as an issue and contributes none', async () => {
|
|
254
|
+
scaffold({
|
|
255
|
+
docs: {
|
|
256
|
+
'ok.doc.mjs': topicDoc(),
|
|
257
|
+
'broken.doc.mjs': topicDoc({name: 'broken', sections: []}),
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
const project = await Project.load(tmpDir);
|
|
261
|
+
const catalog = await project.docs();
|
|
262
|
+
expect(catalog.resolve('deploying')).toBeUndefined();
|
|
263
|
+
const issues = await project.issues();
|
|
264
|
+
expect(issues.some(i => i.code === 'invalid_doc' && i.severity === 'error')).toBe(true);
|
|
265
|
+
});
|
|
266
|
+
|
|
201
267
|
it('memoizes components() — the second call does not re-walk', async () => {
|
|
202
268
|
scaffold();
|
|
203
269
|
const project = await Project.load(tmpDir);
|
|
@@ -0,0 +1,185 @@
|
|
|
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
|
+
* @typedef {object} DocsTopicRecord A doc file discovered under a docs root.
|
|
6
|
+
* @property {string} name
|
|
7
|
+
* @property {string} package owner package
|
|
8
|
+
* @property {string} path absolute path to the doc file
|
|
9
|
+
* @property {string} [title]
|
|
10
|
+
* @property {string} [description]
|
|
11
|
+
* @property {string|null} [category]
|
|
12
|
+
* @property {string} [replaces] topic this doc takes the place of
|
|
13
|
+
* @property {string} [extendsTopic] topic this doc merges onto (`extends`)
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} DocsTopicEntry A resolved topic in the catalog.
|
|
17
|
+
* @property {string} name
|
|
18
|
+
* @property {string} package owner package
|
|
19
|
+
* @property {string} path absolute path to the doc file
|
|
20
|
+
* @property {string} [title]
|
|
21
|
+
* @property {string} [description]
|
|
22
|
+
* @property {string|null} [category]
|
|
23
|
+
* @property {string} [replaces] the topic this one took the place of
|
|
24
|
+
* @property {Array<{package: string, path: string}>} extensions overlays to
|
|
25
|
+
* merge onto the base doc, in the order their integrations were configured
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Discover the CLI's own topics.
|
|
29
|
+
* @returns {Record<string, string>} topic name → absolute doc path
|
|
30
|
+
*/
|
|
31
|
+
export function discoverBuiltinTopics(): Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Load a topic doc from disk. A `.ts` doc is loaded through jiti, the rest
|
|
34
|
+
* natively; both the historical `export const docs` and the stamped
|
|
35
|
+
* `export default` forms are accepted, because core authors the first and the
|
|
36
|
+
* integration guide documents the second.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} file absolute path to a doc file
|
|
39
|
+
* @returns {Promise<unknown>} the authored doc value
|
|
40
|
+
*/
|
|
41
|
+
export function loadTopicModule(file: string): Promise<unknown>;
|
|
42
|
+
/**
|
|
43
|
+
* Check the fields the docs surfaces actually read. `parseDoc` is the outer
|
|
44
|
+
* gate, but the reference-doc schema is a passthrough over `{name, type}` —
|
|
45
|
+
* a doc with no `sections`, or a prose block whose `text` is misspelled,
|
|
46
|
+
* passes it and reaches a reader as a missing section or a blank gap. Those
|
|
47
|
+
* are hard to trace back from the rendered output, so they are caught here,
|
|
48
|
+
* where the file that needs fixing can be named.
|
|
49
|
+
*
|
|
50
|
+
* @param {any} doc a parsed doc
|
|
51
|
+
* @returns {string[]} problems, each already pointed at a place in the doc
|
|
52
|
+
*/
|
|
53
|
+
export function problemsInTopic(doc: any): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Discover the topics contributed by a single loaded integration. Mirrors
|
|
56
|
+
* `discoverIntegrationComponents`: walk the resolved root, take every
|
|
57
|
+
* conventional doc file, and record what it declares. Unlike component
|
|
58
|
+
* discovery this loads each doc, because a topic's name and its relationship
|
|
59
|
+
* to an existing topic are fields inside the file.
|
|
60
|
+
*
|
|
61
|
+
* Errors are returned, not thrown: one unusable doc is reported as an issue
|
|
62
|
+
* against its package while the rest of the CLI keeps working.
|
|
63
|
+
*
|
|
64
|
+
* @param {{name: string, docs?: string}} integration a loaded integration
|
|
65
|
+
* @returns {Promise<{records: DocsTopicRecord[], errors: Error[]}>}
|
|
66
|
+
*/
|
|
67
|
+
export function discoverIntegrationDocs(integration: {
|
|
68
|
+
name: string;
|
|
69
|
+
docs?: string;
|
|
70
|
+
}): Promise<{
|
|
71
|
+
records: DocsTopicRecord[];
|
|
72
|
+
errors: Error[];
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Merge an extension onto a base topic: a section whose title matches one in
|
|
76
|
+
* the base replaces it, a section the base does not have is appended, and the
|
|
77
|
+
* title/description are taken from the extension when it states them.
|
|
78
|
+
*
|
|
79
|
+
* Keyed by section TITLE rather than by position, the way the localization
|
|
80
|
+
* overlays are — position keying grafts an overlay onto whichever section
|
|
81
|
+
* happens to share its index, so a partial or reordered overlay corrupts
|
|
82
|
+
* everything after it (#2182).
|
|
83
|
+
*
|
|
84
|
+
* @param {any} base
|
|
85
|
+
* @param {any} overlay
|
|
86
|
+
* @returns {any} a new doc; neither input is mutated
|
|
87
|
+
*/
|
|
88
|
+
export function mergeTopic(base: any, overlay: any): any;
|
|
89
|
+
/**
|
|
90
|
+
* Owner package recorded for the built-in topics. They ship inside the CLI
|
|
91
|
+
* (assets/docs), not in @astryxdesign/core, so this is the CLI's own name —
|
|
92
|
+
* unlike component discovery, whose built-ins belong to core.
|
|
93
|
+
*/
|
|
94
|
+
export const BUILTIN_DOCS_PACKAGE: "@astryxdesign/cli";
|
|
95
|
+
/**
|
|
96
|
+
* Every topic a project can read, and the relationships between them.
|
|
97
|
+
*
|
|
98
|
+
* Insertion order is the read order: the built-in topics in discovery order,
|
|
99
|
+
* then whatever the configured integrations add, in the order they are
|
|
100
|
+
* configured. A replacement keeps the position of the topic it replaced, so
|
|
101
|
+
* "the first topic" stays stable for a reader that opens it by default.
|
|
102
|
+
*/
|
|
103
|
+
export class DocsCatalog {
|
|
104
|
+
/**
|
|
105
|
+
* Seed a catalog with the CLI's own topics.
|
|
106
|
+
* @param {Record<string, string>} [builtins] topic name → absolute path
|
|
107
|
+
* @returns {DocsCatalog}
|
|
108
|
+
*/
|
|
109
|
+
static fromBuiltins(builtins?: Record<string, string>): DocsCatalog;
|
|
110
|
+
/**
|
|
111
|
+
* Add one integration-contributed doc, honoring what it declares. Returns
|
|
112
|
+
* the issue it caused, or null when it applied cleanly — the caller owns
|
|
113
|
+
* routing (an `error` skips the contribution, a `warning` keeps it).
|
|
114
|
+
*
|
|
115
|
+
* @param {DocsTopicRecord} record
|
|
116
|
+
* @returns {import('../integrations/issue').AstryxIntegrationIssue | null}
|
|
117
|
+
*/
|
|
118
|
+
add(record: DocsTopicRecord): import("../integrations/issue").AstryxIntegrationIssue | null;
|
|
119
|
+
/**
|
|
120
|
+
* Look a topic up by name, case-insensitively, following the alias a renamed
|
|
121
|
+
* replacement left behind.
|
|
122
|
+
* @param {unknown} name
|
|
123
|
+
* @returns {DocsTopicEntry | undefined}
|
|
124
|
+
*/
|
|
125
|
+
resolve(name: unknown): DocsTopicEntry | undefined;
|
|
126
|
+
/** @returns {string[]} every topic name, in read order */
|
|
127
|
+
names(): string[];
|
|
128
|
+
/** @returns {DocsTopicEntry[]} every topic, in read order */
|
|
129
|
+
entries(): DocsTopicEntry[];
|
|
130
|
+
#private;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A doc file discovered under a docs root.
|
|
134
|
+
*/
|
|
135
|
+
export type DocsTopicRecord = {
|
|
136
|
+
name: string;
|
|
137
|
+
/**
|
|
138
|
+
* owner package
|
|
139
|
+
*/
|
|
140
|
+
package: string;
|
|
141
|
+
/**
|
|
142
|
+
* absolute path to the doc file
|
|
143
|
+
*/
|
|
144
|
+
path: string;
|
|
145
|
+
title?: string | undefined;
|
|
146
|
+
description?: string | undefined;
|
|
147
|
+
category?: string | null | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* topic this doc takes the place of
|
|
150
|
+
*/
|
|
151
|
+
replaces?: string | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* topic this doc merges onto (`extends`)
|
|
154
|
+
*/
|
|
155
|
+
extendsTopic?: string | undefined;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* A resolved topic in the catalog.
|
|
159
|
+
*/
|
|
160
|
+
export type DocsTopicEntry = {
|
|
161
|
+
name: string;
|
|
162
|
+
/**
|
|
163
|
+
* owner package
|
|
164
|
+
*/
|
|
165
|
+
package: string;
|
|
166
|
+
/**
|
|
167
|
+
* absolute path to the doc file
|
|
168
|
+
*/
|
|
169
|
+
path: string;
|
|
170
|
+
title?: string | undefined;
|
|
171
|
+
description?: string | undefined;
|
|
172
|
+
category?: string | null | undefined;
|
|
173
|
+
/**
|
|
174
|
+
* the topic this one took the place of
|
|
175
|
+
*/
|
|
176
|
+
replaces?: string | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* overlays to
|
|
179
|
+
* merge onto the base doc, in the order their integrations were configured
|
|
180
|
+
*/
|
|
181
|
+
extensions: Array<{
|
|
182
|
+
package: string;
|
|
183
|
+
path: string;
|
|
184
|
+
}>;
|
|
185
|
+
};
|