@astryxdesign/cli 0.6.3-canary.c82ebb8 → 0.6.3-canary.ca632c6
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 -0
- package/api/docs/detail/section/section.mjs +9 -15
- package/api/docs/detail/section/section.test.mjs +15 -6
- package/api/doctor/doctor.mjs +1 -1
- package/api/doctor/doctor.test.mjs +6 -6
- package/api/upgrade/_adapter.d.mts +22 -4
- package/api/upgrade/_adapter.mjs +19 -6
- package/api/upgrade/run/run.mjs +355 -59
- package/api/upgrade/upgrade.doc.mjs +5 -1
- package/api/upgrade/upgrade.type.d.mts +34 -0
- package/api/upgrade/upgrade.type.mjs +15 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +248 -110
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +4 -0
- package/assets/codemods/transforms/next/index.mjs +8 -0
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/docs/cli-integrations.doc.mjs +13 -0
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/authoring/codemod/type.ts +12 -0
- package/authoring/doctypes/_schema.d.mts +71 -141
- package/authoring/doctypes/_schema.mjs +29 -2
- package/authoring/doctypes/load-contract.test.mjs +1 -1
- package/authoring/doctypes/namespace/namespace.doc.mjs +2 -2
- package/authoring/doctypes/namespace/parse.test.mjs +23 -25
- package/authoring/doctypes/namespace/type.ts +5 -2
- package/authoring/doctypes/parse.mjs +3 -2
- package/authoring/doctypes/reference/reference.doc.mjs +5 -3
- package/authoring/doctypes/reference/type.ts +7 -8
- package/authoring/index.d.ts +1 -0
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.mjs +10 -44
- package/clients/cli/commands/docs.mjs +15 -58
- package/clients/cli/commands/docs.test.mjs +11 -14
- package/clients/cli/commands/text-json-parity.test.mjs +718 -0
- package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
- package/clients/cli/commands/upgrade.doc.mjs +2 -1
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +2 -0
- package/clients/cli/formatters/index.test.mjs +6 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +3 -2
- package/foundation/discovery/docs-discovery.mjs +6 -5
- package/foundation/discovery/docs-discovery.test.mjs +7 -10
- package/foundation/discovery/docs-section-key.d.mts +19 -8
- package/foundation/discovery/docs-section-key.mjs +119 -32
- package/foundation/discovery/docs-section-key.test.mjs +41 -19
- package/foundation/doc-compiler/compile.mjs +5 -4
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +10 -0
- package/foundation/response/error-codes.mjs +6 -0
- package/foundation/response/error-codes.test.mjs +55 -11
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -189,6 +189,8 @@ if (isError(result)) {
|
|
|
189
189
|
| `ERR_UNKNOWN_FEATURE` | An unrecognized `--features` value was passed to init. |
|
|
190
190
|
| `ERR_UNKNOWN_CODEMOD` | A `--codemod` value did not match any registered codemod (upgrade). |
|
|
191
191
|
| `ERR_CODEMOD_FAILED` | One or more codemods failed during an upgrade run. |
|
|
192
|
+
| `ERR_CODEMOD_PROTECTED` | A required codemod change remains blocked by a protected consumer file. |
|
|
193
|
+
| `ERR_CODEMOD_PROTECTION_SOURCE` | A working-tree protection declaration could not be read or parsed. |
|
|
192
194
|
| `ERR_NOT_FOUND` | A generic discover/lookup query matched nothing in any package. |
|
|
193
195
|
| `ERR_NO_DOC` | A component exists but has no typed `.doc.mjs` file. |
|
|
194
196
|
| `ERR_NO_SHOWCASE` | No showcase exists for the requested component. |
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @file docs.detail.section leaf — load a single section of a topic.
|
|
5
5
|
*
|
|
6
6
|
* @input A topic name, a section query, and optional {lang, zh, dense}. Resolves
|
|
7
|
-
* the topic via the shared adapter,
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* the topic via the shared adapter, keeps the 0.6.x first title-substring
|
|
8
|
+
* match, then falls back to a stable key or normalized title key, and links
|
|
9
|
+
* only that section.
|
|
10
10
|
* @output { type: 'docs.detail.section', data: ReferenceSection } with any
|
|
11
11
|
* token-ref blocks inlined — matching `astryx --json docs <topic> <section>`.
|
|
12
12
|
* Throws ERR_UNKNOWN_SECTION when nothing matches, or when the query matches
|
|
@@ -17,10 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import {AstryxError} from '../../../error.mjs';
|
|
19
19
|
import {ERROR_CODES} from '../../../../foundation/response/error-codes.mjs';
|
|
20
|
-
import {
|
|
21
|
-
findDocSection,
|
|
22
|
-
sectionKey,
|
|
23
|
-
} from '../../../../foundation/discovery/docs-section-key.mjs';
|
|
20
|
+
import {findDocSection} from '../../../../foundation/discovery/docs-section-key.mjs';
|
|
24
21
|
import {linkReferenceSection} from '../../../../foundation/doc-compiler/compile.mjs';
|
|
25
22
|
import {
|
|
26
23
|
readerSections,
|
|
@@ -52,16 +49,13 @@ export async function section(topic, sectionName, options = {}) {
|
|
|
52
49
|
|
|
53
50
|
const {catalog, node, lang} = await resolveTopicDocs(topic, options);
|
|
54
51
|
const sections = readerSections(node);
|
|
55
|
-
const {section: match
|
|
52
|
+
const {section: match} = findDocSection(sections, sectionName);
|
|
56
53
|
if (!match) {
|
|
57
|
-
const ambiguous = candidates.length > 1;
|
|
58
54
|
throw new AstryxError(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
:
|
|
62
|
-
|
|
63
|
-
name: sectionKey(s),
|
|
64
|
-
reason: s.title,
|
|
55
|
+
`Section "${sectionName}" not found in "${topic}"`,
|
|
56
|
+
sections.map(s => ({
|
|
57
|
+
name: s.title,
|
|
58
|
+
reason: 'available section',
|
|
65
59
|
})),
|
|
66
60
|
ERROR_CODES.ERR_UNKNOWN_SECTION,
|
|
67
61
|
);
|
|
@@ -30,6 +30,17 @@ describe('docs.detail.section leaf', () => {
|
|
|
30
30
|
}
|
|
31
31
|
expect(err).toBeInstanceOf(AstryxError);
|
|
32
32
|
expect(err.code).toBe('ERR_UNKNOWN_SECTION');
|
|
33
|
+
expect(err.suggestions).toEqual(
|
|
34
|
+
expect.arrayContaining([
|
|
35
|
+
expect.objectContaining({
|
|
36
|
+
name: expect.any(String),
|
|
37
|
+
reason: 'available section',
|
|
38
|
+
}),
|
|
39
|
+
]),
|
|
40
|
+
);
|
|
41
|
+
expect(err.suggestions.some(suggestion => /\s/u.test(suggestion.name))).toBe(
|
|
42
|
+
true,
|
|
43
|
+
);
|
|
33
44
|
}, SLOW);
|
|
34
45
|
|
|
35
46
|
it('does not return the first section for an empty section name', async () => {
|
|
@@ -50,12 +61,10 @@ describe('docs.detail.section leaf', () => {
|
|
|
50
61
|
expect(res.data.id).toBe(target.id);
|
|
51
62
|
}, SLOW);
|
|
52
63
|
|
|
53
|
-
it('
|
|
54
|
-
const
|
|
55
|
-
expect(
|
|
56
|
-
expect(
|
|
57
|
-
expect(err.message).toMatch(/matches \d+ sections/);
|
|
58
|
-
expect(err.suggestions.length).toBeGreaterThan(1);
|
|
64
|
+
it('keeps a previously accepted ambiguous query on its first match', async () => {
|
|
65
|
+
const res = await section('theme', 'e');
|
|
66
|
+
expect(res.type).toBe('docs.detail.section');
|
|
67
|
+
expect(res.data).toBeDefined();
|
|
59
68
|
}, SLOW);
|
|
60
69
|
|
|
61
70
|
it.each([null, 'zh', 'dense'])(
|
package/api/doctor/doctor.mjs
CHANGED
|
@@ -994,7 +994,7 @@ export async function checkDocsProgressiveDisclosure(ctx) {
|
|
|
994
994
|
return {
|
|
995
995
|
id,
|
|
996
996
|
label,
|
|
997
|
-
status: '
|
|
997
|
+
status: 'warn',
|
|
998
998
|
message: joinProblems(problems),
|
|
999
999
|
fix: 'Fix the doc each problem names; split a section that is too large into smaller ones, each with its own key.',
|
|
1000
1000
|
};
|
|
@@ -391,7 +391,7 @@ describe('checkDocsProgressiveDisclosure', () => {
|
|
|
391
391
|
expect(c.message).toMatch(/^\d+ topics: /);
|
|
392
392
|
}, SLOW);
|
|
393
393
|
|
|
394
|
-
it('
|
|
394
|
+
it('warns on an invalid doc an integration contributed', async () => {
|
|
395
395
|
const c = await checkDocsProgressiveDisclosure({
|
|
396
396
|
docsCatalogIssues: [
|
|
397
397
|
{
|
|
@@ -402,13 +402,13 @@ describe('checkDocsProgressiveDisclosure', () => {
|
|
|
402
402
|
},
|
|
403
403
|
],
|
|
404
404
|
});
|
|
405
|
-
expect(c.status).toBe('
|
|
405
|
+
expect(c.status).toBe('warn');
|
|
406
406
|
expect(c.message).toBe('@acme/widgets: bad.doc.mjs exports no doc');
|
|
407
407
|
});
|
|
408
408
|
|
|
409
|
-
it('
|
|
409
|
+
it('warns when the docs catalog cannot be built', async () => {
|
|
410
410
|
const c = await checkDocsProgressiveDisclosure({docsCatalogError: 'boom'});
|
|
411
|
-
expect(c.status).toBe('
|
|
411
|
+
expect(c.status).toBe('warn');
|
|
412
412
|
expect(c.message).toContain('boom');
|
|
413
413
|
});
|
|
414
414
|
|
|
@@ -436,7 +436,7 @@ describe('checkDocsProgressiveDisclosure', () => {
|
|
|
436
436
|
}),
|
|
437
437
|
docsCatalogIssues: [],
|
|
438
438
|
});
|
|
439
|
-
expect(c.status).toBe('
|
|
439
|
+
expect(c.status).toBe('warn');
|
|
440
440
|
expect(c.message).toMatch(/^2 problems: /);
|
|
441
441
|
expect(c.message).toContain('huge everything: 41 KB, over the 32 KB one read may return');
|
|
442
442
|
expect(c.message).toContain('broken: ');
|
|
@@ -812,7 +812,7 @@ describe('checkDocsProgressiveDisclosure languages', () => {
|
|
|
812
812
|
docsCatalog: DocsCatalog.fromBuiltins({deploying: path.join(dir, 'deploying.doc.mjs')}),
|
|
813
813
|
docsCatalogIssues: [],
|
|
814
814
|
});
|
|
815
|
-
expect(c.status).toBe('
|
|
815
|
+
expect(c.status).toBe('warn');
|
|
816
816
|
expect(c.message).toContain('deploying [zh]: zh overlay broken');
|
|
817
817
|
expect(c.message).toContain('deploying [dense] overview: 41 KB');
|
|
818
818
|
expect(c.message).not.toMatch(/deploying overview:/);
|
|
@@ -104,19 +104,27 @@ export function ensureCodemodDeps({ installDeps }?: {
|
|
|
104
104
|
* Run the CORE registry codemods. Runs BEFORE the config is loaded so a core
|
|
105
105
|
* CONFIG codemod can repair a config the strict loader would otherwise reject.
|
|
106
106
|
* @param {CoreVersionManifest[]} versionManifests
|
|
107
|
-
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string}} options
|
|
107
|
+
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean}} options
|
|
108
108
|
*/
|
|
109
|
-
export function runCoreCodemods(versionManifests: CoreVersionManifest[], { apply, path: srcPath, codemod, skipCodemods, root }: {
|
|
109
|
+
export function runCoreCodemods(versionManifests: CoreVersionManifest[], { apply, path: srcPath, codemod, skipCodemods, root, protection, silent }: {
|
|
110
110
|
apply: boolean;
|
|
111
111
|
path: string;
|
|
112
112
|
codemod?: string;
|
|
113
113
|
skipCodemods: Set<string>;
|
|
114
114
|
root?: string;
|
|
115
|
+
protection?: {
|
|
116
|
+
root: string;
|
|
117
|
+
classify: (file: string) => import("../../foundation/fs/file-protection.mjs").FileProtection[];
|
|
118
|
+
};
|
|
119
|
+
silent?: boolean;
|
|
115
120
|
}): Promise<{
|
|
116
121
|
totalFilesChanged: number;
|
|
117
122
|
totalTransformsApplied: number;
|
|
118
123
|
totalValidationBlocked: number;
|
|
124
|
+
changedFiles: string[];
|
|
119
125
|
writtenFiles: string[];
|
|
126
|
+
stagedContents: Map<string, string>;
|
|
127
|
+
protectedFiles: import("../../authoring/codemod/type").CodemodRunResult["protectedFiles"];
|
|
120
128
|
errors: Array<{
|
|
121
129
|
file: string;
|
|
122
130
|
codemod: string;
|
|
@@ -180,20 +188,30 @@ export function selectIntegrationCodemodsFor(integrations: Array<import("../../f
|
|
|
180
188
|
/**
|
|
181
189
|
* Run the file-based INTEGRATION codemods (config codemods first, then code).
|
|
182
190
|
* @param {Array<{version: string, codemods: import('../../authoring/codemod/type').CodemodEntry[]}>} versionGroups
|
|
183
|
-
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string
|
|
191
|
+
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, contents?: Map<string, string>, silent?: boolean}} options
|
|
184
192
|
*/
|
|
185
193
|
export function runIntegrationCodemodsStep(versionGroups: Array<{
|
|
186
194
|
version: string;
|
|
187
195
|
codemods: import("../../authoring/codemod/type").CodemodEntry[];
|
|
188
|
-
}>, { apply, path: srcPath, codemod, skipCodemods }: {
|
|
196
|
+
}>, { apply, path: srcPath, codemod, skipCodemods, root, protection, contents, silent, }: {
|
|
189
197
|
apply: boolean;
|
|
190
198
|
path: string;
|
|
191
199
|
codemod?: string;
|
|
192
200
|
skipCodemods: Set<string>;
|
|
201
|
+
root?: string;
|
|
202
|
+
protection?: {
|
|
203
|
+
root: string;
|
|
204
|
+
classify: (file: string) => import("../../foundation/fs/file-protection.mjs").FileProtection[];
|
|
205
|
+
};
|
|
206
|
+
contents?: Map<string, string>;
|
|
207
|
+
silent?: boolean;
|
|
193
208
|
}): Promise<{
|
|
194
209
|
totalFilesChanged: number;
|
|
195
210
|
totalTransformsApplied: number;
|
|
211
|
+
changedFiles: string[];
|
|
196
212
|
writtenFiles: string[];
|
|
213
|
+
stagedContents: Map<string, string>;
|
|
214
|
+
protectedFiles: import("../../authoring/codemod/type").CodemodRunResult["protectedFiles"];
|
|
197
215
|
errors: Array<{
|
|
198
216
|
file: string;
|
|
199
217
|
codemod: string;
|
package/api/upgrade/_adapter.mjs
CHANGED
|
@@ -329,19 +329,20 @@ export async function ensureCodemodDeps({installDeps} = {}) {
|
|
|
329
329
|
* Run the CORE registry codemods. Runs BEFORE the config is loaded so a core
|
|
330
330
|
* CONFIG codemod can repair a config the strict loader would otherwise reject.
|
|
331
331
|
* @param {CoreVersionManifest[]} versionManifests
|
|
332
|
-
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string}} options
|
|
332
|
+
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean}} options
|
|
333
333
|
*/
|
|
334
334
|
export async function runCoreCodemods(
|
|
335
335
|
versionManifests,
|
|
336
|
-
{apply, path: srcPath, codemod, skipCodemods, root},
|
|
336
|
+
{apply, path: srcPath, codemod, skipCodemods, root, protection, silent},
|
|
337
337
|
) {
|
|
338
338
|
return runCodemods(versionManifests, {
|
|
339
339
|
apply,
|
|
340
340
|
path: srcPath,
|
|
341
341
|
codemod,
|
|
342
342
|
skipCodemods,
|
|
343
|
-
silent: logger.silent,
|
|
343
|
+
silent: silent ?? logger.silent,
|
|
344
344
|
root,
|
|
345
|
+
protection,
|
|
345
346
|
});
|
|
346
347
|
}
|
|
347
348
|
|
|
@@ -479,11 +480,20 @@ export async function selectIntegrationCodemodsFor(integrations, from, to) {
|
|
|
479
480
|
/**
|
|
480
481
|
* Run the file-based INTEGRATION codemods (config codemods first, then code).
|
|
481
482
|
* @param {Array<{version: string, codemods: import('../../authoring/codemod/type').CodemodEntry[]}>} versionGroups
|
|
482
|
-
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string
|
|
483
|
+
* @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, contents?: Map<string, string>, silent?: boolean}} options
|
|
483
484
|
*/
|
|
484
485
|
export async function runIntegrationCodemodsStep(
|
|
485
486
|
versionGroups,
|
|
486
|
-
{
|
|
487
|
+
{
|
|
488
|
+
apply,
|
|
489
|
+
path: srcPath,
|
|
490
|
+
codemod,
|
|
491
|
+
skipCodemods,
|
|
492
|
+
root,
|
|
493
|
+
protection,
|
|
494
|
+
contents,
|
|
495
|
+
silent,
|
|
496
|
+
},
|
|
487
497
|
) {
|
|
488
498
|
const jscodeshift = (await import('jscodeshift')).default;
|
|
489
499
|
return runIntegrationCodemods(versionGroups, {
|
|
@@ -492,6 +502,9 @@ export async function runIntegrationCodemodsStep(
|
|
|
492
502
|
codemod,
|
|
493
503
|
skipCodemods,
|
|
494
504
|
jscodeshift,
|
|
495
|
-
silent: logger.silent,
|
|
505
|
+
silent: silent ?? logger.silent,
|
|
506
|
+
root,
|
|
507
|
+
protection,
|
|
508
|
+
contents,
|
|
496
509
|
});
|
|
497
510
|
}
|