@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
|
@@ -388,14 +388,6 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
388
388
|
components.map(component => component.specifier),
|
|
389
389
|
scratchBase,
|
|
390
390
|
);
|
|
391
|
-
issues.push(
|
|
392
|
-
...validateSpecifierExtensions(
|
|
393
|
-
components.map(({name, specifier}) => ({
|
|
394
|
-
label: `Component "${name}"`,
|
|
395
|
-
specifier,
|
|
396
|
-
})),
|
|
397
|
-
),
|
|
398
|
-
);
|
|
399
391
|
for (const {name, specifier} of components) {
|
|
400
392
|
const result = resolved.get(specifier);
|
|
401
393
|
if (!result?.url || result.error) {
|
|
@@ -435,27 +427,19 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
435
427
|
*/
|
|
436
428
|
async function validatePackedTemplateExports(integration, scratchBase) {
|
|
437
429
|
const {templates} = await discoverIntegrationTemplatesForOne(integration);
|
|
438
|
-
const entries = templates.map(template => {
|
|
439
|
-
|
|
430
|
+
const entries = templates.map(template => ({
|
|
431
|
+
id: template.dirName,
|
|
432
|
+
specifier: `${integration.name}/${path
|
|
440
433
|
.relative(integration.__packageDir, template.filePath)
|
|
441
434
|
.split(path.sep)
|
|
442
|
-
.join('/')
|
|
443
|
-
|
|
444
|
-
return {
|
|
445
|
-
id: template.dirName,
|
|
446
|
-
specifier: `${integration.name}/${extensionless}`,
|
|
447
|
-
};
|
|
448
|
-
});
|
|
435
|
+
.join('/')}`,
|
|
436
|
+
}));
|
|
449
437
|
const resolved = resolveConsumerSpecifiers(
|
|
450
438
|
entries.map(entry => entry.specifier),
|
|
451
439
|
scratchBase,
|
|
452
440
|
);
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
label: `Template "${id}"`,
|
|
456
|
-
specifier,
|
|
457
|
-
})),
|
|
458
|
-
);
|
|
441
|
+
/** @type {Issue[]} */
|
|
442
|
+
const issues = [];
|
|
459
443
|
for (const {id, specifier} of entries) {
|
|
460
444
|
const result = resolved.get(specifier);
|
|
461
445
|
if (!result?.url || result.error) {
|
|
@@ -485,32 +469,6 @@ async function validatePackedTemplateExports(integration, scratchBase) {
|
|
|
485
469
|
return issues;
|
|
486
470
|
}
|
|
487
471
|
|
|
488
|
-
const TS_EXTENSION_RE = /\.tsx?$/u;
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Reject specifiers that end in a TypeScript extension — they fail under
|
|
492
|
-
* default `moduleResolution` with TS5097/TS2307 unless the consumer enables
|
|
493
|
-
* `allowImportingTsExtensions`.
|
|
494
|
-
*
|
|
495
|
-
* @param {Array<{label: string, specifier: string}>} entries
|
|
496
|
-
* @returns {Issue[]}
|
|
497
|
-
*/
|
|
498
|
-
function validateSpecifierExtensions(entries) {
|
|
499
|
-
/** @type {Issue[]} */
|
|
500
|
-
const issues = [];
|
|
501
|
-
for (const {label, specifier} of entries) {
|
|
502
|
-
if (TS_EXTENSION_RE.test(specifier)) {
|
|
503
|
-
issues.push(
|
|
504
|
-
error(
|
|
505
|
-
'typescript_extension_in_specifier',
|
|
506
|
-
`${label} advertises import "${specifier}", which ends in a TypeScript extension. A consumer with default moduleResolution will reject it (TS5097). Use an extensionless specifier mapped through the package exports.`,
|
|
507
|
-
),
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
return issues;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
472
|
/**
|
|
515
473
|
* Verify an integration package is ready to publish.
|
|
516
474
|
*
|
|
@@ -567,252 +567,3 @@ describe('pack-check mutation tests', () => {
|
|
|
567
567
|
}
|
|
568
568
|
});
|
|
569
569
|
});
|
|
570
|
-
|
|
571
|
-
describe('extensionless subpath resolution', () => {
|
|
572
|
-
it('rejects .tsx public specifiers before publishing', async () => {
|
|
573
|
-
// Manually construct a package with OLD-style .tsx exports keys
|
|
574
|
-
writePackage({
|
|
575
|
-
manifest: "export default {components: './components'};\n",
|
|
576
|
-
files: ['astryx.integration.mjs', 'components', 'index.mjs'],
|
|
577
|
-
themes: false,
|
|
578
|
-
});
|
|
579
|
-
const pkgFile = path.join(tmpDir, 'package.json');
|
|
580
|
-
const pkg = JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
|
|
581
|
-
pkg.exports = {
|
|
582
|
-
'.': './index.mjs',
|
|
583
|
-
'./components/AcmeWidget.tsx': './components/AcmeWidget.tsx',
|
|
584
|
-
};
|
|
585
|
-
fs.writeFileSync(pkgFile, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
586
|
-
fs.writeFileSync(
|
|
587
|
-
path.join(tmpDir, 'index.mjs'),
|
|
588
|
-
'export const existing = 1;\n',
|
|
589
|
-
);
|
|
590
|
-
fs.mkdirSync(path.join(tmpDir, 'components'));
|
|
591
|
-
fs.writeFileSync(
|
|
592
|
-
path.join(tmpDir, 'components', 'AcmeWidget.doc.mjs'),
|
|
593
|
-
`export default {type: 'component', name: 'AcmeWidget', import: '@acme/widgets/components/AcmeWidget.tsx', description: 'Widget.', props: []};\n`,
|
|
594
|
-
);
|
|
595
|
-
fs.writeFileSync(
|
|
596
|
-
path.join(tmpDir, 'components', 'AcmeWidget.tsx'),
|
|
597
|
-
'export function AcmeWidget() { return null; }\n',
|
|
598
|
-
);
|
|
599
|
-
|
|
600
|
-
const result = await integrationPackCheck({cwd: tmpDir});
|
|
601
|
-
|
|
602
|
-
// The .tsx extension in the specifier must be caught
|
|
603
|
-
expect(result.data.packable).toBe(false);
|
|
604
|
-
expect(result.data.issues).toContainEqual(
|
|
605
|
-
expect.objectContaining({
|
|
606
|
-
code: 'typescript_extension_in_specifier',
|
|
607
|
-
message: expect.stringContaining('.tsx'),
|
|
608
|
-
}),
|
|
609
|
-
);
|
|
610
|
-
});
|
|
611
|
-
|
|
612
|
-
it('generated extensionless component specifier resolves through exports map', async () => {
|
|
613
|
-
fs.writeFileSync(
|
|
614
|
-
path.join(tmpDir, 'package.json'),
|
|
615
|
-
`${JSON.stringify({
|
|
616
|
-
name: '@acme/widgets',
|
|
617
|
-
version: '1.0.0',
|
|
618
|
-
files: ['index.mjs'],
|
|
619
|
-
exports: {'.': './index.mjs'},
|
|
620
|
-
})}\n`,
|
|
621
|
-
);
|
|
622
|
-
fs.writeFileSync(
|
|
623
|
-
path.join(tmpDir, 'index.mjs'),
|
|
624
|
-
'export const existing = 1;\n',
|
|
625
|
-
);
|
|
626
|
-
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
627
|
-
|
|
628
|
-
// Verify the exports map has extensionless key → .tsx target
|
|
629
|
-
const pkg = JSON.parse(
|
|
630
|
-
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
631
|
-
);
|
|
632
|
-
expect(pkg.exports['./components/AcmeWidget']).toBe(
|
|
633
|
-
'./components/AcmeWidget.tsx',
|
|
634
|
-
);
|
|
635
|
-
expect(pkg.exports['./components/AcmeWidget.tsx']).toBeUndefined();
|
|
636
|
-
|
|
637
|
-
const result = await integrationPackCheck({cwd: tmpDir});
|
|
638
|
-
|
|
639
|
-
expect(result.data.packable).toBe(true);
|
|
640
|
-
expect(result.data.issues).not.toContainEqual(
|
|
641
|
-
expect.objectContaining({code: 'typescript_extension_in_specifier'}),
|
|
642
|
-
);
|
|
643
|
-
expect(result.data.issues).not.toContainEqual(
|
|
644
|
-
expect.objectContaining({code: 'component_import_unresolvable'}),
|
|
645
|
-
);
|
|
646
|
-
});
|
|
647
|
-
|
|
648
|
-
it('validates generated imports without project-local TypeScript', async () => {
|
|
649
|
-
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
650
|
-
tmpDir = fs.mkdtempSync(
|
|
651
|
-
path.join(os.tmpdir(), 'astryx-pack-check-no-typescript-'),
|
|
652
|
-
);
|
|
653
|
-
fs.writeFileSync(
|
|
654
|
-
path.join(tmpDir, 'package.json'),
|
|
655
|
-
`${JSON.stringify({
|
|
656
|
-
name: '@acme/widgets',
|
|
657
|
-
version: '1.0.0',
|
|
658
|
-
files: ['index.mjs'],
|
|
659
|
-
exports: {'.': './index.mjs'},
|
|
660
|
-
})}\n`,
|
|
661
|
-
);
|
|
662
|
-
fs.writeFileSync(
|
|
663
|
-
path.join(tmpDir, 'index.mjs'),
|
|
664
|
-
'export const existing = 1;\n',
|
|
665
|
-
);
|
|
666
|
-
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
667
|
-
|
|
668
|
-
const result = await integrationPackCheck({cwd: tmpDir});
|
|
669
|
-
|
|
670
|
-
expect(result.data.packable).toBe(true);
|
|
671
|
-
expect(result.data.issues).not.toContainEqual(
|
|
672
|
-
expect.objectContaining({code: 'component_import_unresolvable'}),
|
|
673
|
-
);
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
it('generated extensionless template specifiers resolve for page and block types', async () => {
|
|
677
|
-
fs.writeFileSync(
|
|
678
|
-
path.join(tmpDir, 'package.json'),
|
|
679
|
-
`${JSON.stringify({
|
|
680
|
-
name: '@acme/widgets',
|
|
681
|
-
version: '1.0.0',
|
|
682
|
-
files: ['index.mjs'],
|
|
683
|
-
exports: {'.': './index.mjs'},
|
|
684
|
-
})}\n`,
|
|
685
|
-
);
|
|
686
|
-
fs.writeFileSync(
|
|
687
|
-
path.join(tmpDir, 'index.mjs'),
|
|
688
|
-
'export const existing = 1;\n',
|
|
689
|
-
);
|
|
690
|
-
await integrationAddTemplate('account-page', {cwd: tmpDir, type: 'page'});
|
|
691
|
-
await integrationAddTemplate('info-card', {cwd: tmpDir, type: 'block'});
|
|
692
|
-
|
|
693
|
-
const pkg = JSON.parse(
|
|
694
|
-
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
695
|
-
);
|
|
696
|
-
expect(pkg.exports['./templates/account-page']).toBe(
|
|
697
|
-
'./templates/account-page.tsx',
|
|
698
|
-
);
|
|
699
|
-
expect(pkg.exports['./templates/info-card']).toBe(
|
|
700
|
-
'./templates/info-card.tsx',
|
|
701
|
-
);
|
|
702
|
-
|
|
703
|
-
const result = await integrationPackCheck({cwd: tmpDir});
|
|
704
|
-
|
|
705
|
-
expect(result.data.packable).toBe(true);
|
|
706
|
-
expect(result.data.issues).not.toContainEqual(
|
|
707
|
-
expect.objectContaining({code: 'template_import_unresolvable'}),
|
|
708
|
-
);
|
|
709
|
-
expect(result.data.issues).not.toContainEqual(
|
|
710
|
-
expect.objectContaining({code: 'typescript_extension_in_specifier'}),
|
|
711
|
-
);
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
it('preserves condition-style exports sugar without creating a map', async () => {
|
|
715
|
-
// Package with condition-only exports (sugar, no subpaths)
|
|
716
|
-
fs.writeFileSync(
|
|
717
|
-
path.join(tmpDir, 'package.json'),
|
|
718
|
-
`${JSON.stringify({
|
|
719
|
-
name: '@acme/widgets',
|
|
720
|
-
version: '1.0.0',
|
|
721
|
-
files: ['index.mjs'],
|
|
722
|
-
exports: {import: './index.mjs', require: './index.cjs'},
|
|
723
|
-
})}\n`,
|
|
724
|
-
);
|
|
725
|
-
fs.writeFileSync(
|
|
726
|
-
path.join(tmpDir, 'index.mjs'),
|
|
727
|
-
'export const existing = 1;\n',
|
|
728
|
-
);
|
|
729
|
-
fs.writeFileSync(path.join(tmpDir, 'index.cjs'), 'exports.existing = 1;\n');
|
|
730
|
-
fs.writeFileSync(
|
|
731
|
-
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
732
|
-
'export default {};\n',
|
|
733
|
-
);
|
|
734
|
-
|
|
735
|
-
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
736
|
-
|
|
737
|
-
const pkg = JSON.parse(
|
|
738
|
-
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
739
|
-
);
|
|
740
|
-
// Condition sugar wrapped into subpath map with the component added
|
|
741
|
-
expect(pkg.exports['.']).toEqual({
|
|
742
|
-
import: './index.mjs',
|
|
743
|
-
require: './index.cjs',
|
|
744
|
-
});
|
|
745
|
-
expect(pkg.exports['./components/AcmeWidget']).toBe(
|
|
746
|
-
'./components/AcmeWidget.tsx',
|
|
747
|
-
);
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
it('no-map: pack-check fails when generated component has no exports map', async () => {
|
|
751
|
-
fs.writeFileSync(
|
|
752
|
-
path.join(tmpDir, 'package.json'),
|
|
753
|
-
`${JSON.stringify({
|
|
754
|
-
name: '@acme/widgets',
|
|
755
|
-
version: '1.0.0',
|
|
756
|
-
files: ['dist'],
|
|
757
|
-
})}\n`,
|
|
758
|
-
);
|
|
759
|
-
fs.writeFileSync(
|
|
760
|
-
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
761
|
-
'export default {};\n',
|
|
762
|
-
);
|
|
763
|
-
|
|
764
|
-
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
765
|
-
await integrationAddTemplate('hero-page', {cwd: tmpDir, type: 'page'});
|
|
766
|
-
|
|
767
|
-
const pkg = JSON.parse(
|
|
768
|
-
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
769
|
-
);
|
|
770
|
-
// No exports map created
|
|
771
|
-
expect(pkg.exports).toBeUndefined();
|
|
772
|
-
|
|
773
|
-
const result = await integrationPackCheck({cwd: tmpDir});
|
|
774
|
-
|
|
775
|
-
// The extensionless import cannot resolve without an exports map —
|
|
776
|
-
// pack-check must fail closed, not false-green.
|
|
777
|
-
expect(result.data.packable).toBe(false);
|
|
778
|
-
expect(result.data.issues).toContainEqual(
|
|
779
|
-
expect.objectContaining({
|
|
780
|
-
severity: 'error',
|
|
781
|
-
message: expect.stringContaining('AcmeWidget'),
|
|
782
|
-
}),
|
|
783
|
-
);
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
it('idempotent when extensionless export already exists', async () => {
|
|
787
|
-
fs.writeFileSync(
|
|
788
|
-
path.join(tmpDir, 'package.json'),
|
|
789
|
-
`${JSON.stringify({
|
|
790
|
-
name: '@acme/widgets',
|
|
791
|
-
version: '1.0.0',
|
|
792
|
-
files: ['index.mjs'],
|
|
793
|
-
exports: {
|
|
794
|
-
'.': './index.mjs',
|
|
795
|
-
'./components/AcmeWidget': './components/AcmeWidget.tsx',
|
|
796
|
-
},
|
|
797
|
-
})}\n`,
|
|
798
|
-
);
|
|
799
|
-
fs.writeFileSync(
|
|
800
|
-
path.join(tmpDir, 'index.mjs'),
|
|
801
|
-
'export const existing = 1;\n',
|
|
802
|
-
);
|
|
803
|
-
fs.writeFileSync(
|
|
804
|
-
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
805
|
-
'export default {};\n',
|
|
806
|
-
);
|
|
807
|
-
|
|
808
|
-
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
809
|
-
|
|
810
|
-
const pkg = JSON.parse(
|
|
811
|
-
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
812
|
-
);
|
|
813
|
-
// Export preserved, no duplicate
|
|
814
|
-
expect(
|
|
815
|
-
Object.keys(pkg.exports).filter(k => k.includes('AcmeWidget')),
|
|
816
|
-
).toEqual(['./components/AcmeWidget']);
|
|
817
|
-
});
|
|
818
|
-
});
|
package/api/search/search.d.mts
CHANGED
package/api/search/search.mjs
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
import {loadIntegrationsSafely} from '../component/_adapter.mjs';
|
|
67
67
|
import {levenshteinDistance} from '../../foundation/text/string-utils.mjs';
|
|
68
68
|
import {discoverTemplates, extractComponents} from '../template/template.mjs';
|
|
69
|
-
import {loadDocsCatalog,
|
|
69
|
+
import {loadDocsCatalog, loadTopicDoc} from '../docs/_adapter.mjs';
|
|
70
70
|
import {AstryxError} from '../error.mjs';
|
|
71
71
|
import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
|
|
72
72
|
import {setResultCoverage} from './coverage.mjs';
|
|
@@ -732,16 +732,16 @@ async function gatherHooks(coreDir) {
|
|
|
732
732
|
async function gatherDocs(cwd) {
|
|
733
733
|
/** @type {Candidate[]} */
|
|
734
734
|
const candidates = [];
|
|
735
|
-
let
|
|
735
|
+
let entries;
|
|
736
736
|
try {
|
|
737
|
-
|
|
737
|
+
entries = (await loadDocsCatalog(cwd)).entries();
|
|
738
738
|
} catch {
|
|
739
739
|
return candidates;
|
|
740
740
|
}
|
|
741
|
-
for (const entry of
|
|
741
|
+
for (const entry of entries) {
|
|
742
742
|
let doc = null;
|
|
743
743
|
try {
|
|
744
|
-
doc =
|
|
744
|
+
doc = await loadTopicDoc(entry);
|
|
745
745
|
} catch {
|
|
746
746
|
// A topic that cannot be loaded is reported by the commands that own
|
|
747
747
|
// integration issues; search just cannot index it.
|
|
@@ -48,10 +48,10 @@ export type SearchResultEntry = {
|
|
|
48
48
|
/**
|
|
49
49
|
* - Template kind (`page` | `block`) — present for template results.
|
|
50
50
|
*/
|
|
51
|
-
kind?: "
|
|
51
|
+
kind?: "block" | "page" | undefined;
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
54
|
+
* xds --json search <query>
|
|
55
55
|
*/
|
|
56
56
|
export type SearchResponse = {
|
|
57
57
|
type: "search";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* xds --json swizzle [--list]
|
|
6
6
|
*/
|
|
7
7
|
export type SwizzleListResponse = {
|
|
8
8
|
type: "swizzle.list";
|
|
@@ -22,7 +22,7 @@ export type SwizzleFeedback = {
|
|
|
22
22
|
ghCommand?: string | undefined;
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* xds --json swizzle <component>
|
|
26
26
|
*/
|
|
27
27
|
export type SwizzleCopyResponse = {
|
|
28
28
|
type: "swizzle.copy";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* xds --json swizzle [--list]
|
|
11
11
|
*
|
|
12
12
|
* @typedef {object} SwizzleListResponse
|
|
13
13
|
* @property {'swizzle.list'} type
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* xds --json swizzle <component>
|
|
27
27
|
*
|
|
28
28
|
* @typedef {object} SwizzleCopyResponse
|
|
29
29
|
* @property {'swizzle.copy'} type
|
|
@@ -31,7 +31,7 @@ export function template(name?: string, options?: {
|
|
|
31
31
|
skeleton?: boolean | undefined;
|
|
32
32
|
cdn?: string | boolean | undefined;
|
|
33
33
|
show?: boolean | undefined;
|
|
34
|
-
type?: "
|
|
34
|
+
type?: "block" | "page" | undefined;
|
|
35
35
|
package?: string | undefined;
|
|
36
36
|
cwd?: string | undefined;
|
|
37
37
|
}): Promise<{
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* xds --json template [--list]
|
|
6
6
|
*/
|
|
7
7
|
export type TemplateListResponse = {
|
|
8
8
|
type: "template.list";
|
|
@@ -53,7 +53,7 @@ export type TemplateListEntry = {
|
|
|
53
53
|
scaffold?: boolean | undefined;
|
|
54
54
|
};
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* xds --json template <name>
|
|
57
57
|
*/
|
|
58
58
|
export type TemplateShowResponse = {
|
|
59
59
|
type: "template.show";
|
|
@@ -66,7 +66,7 @@ export type TemplateShowResponse = {
|
|
|
66
66
|
};
|
|
67
67
|
};
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* xds --json template <name> --skeleton
|
|
70
70
|
*/
|
|
71
71
|
export type TemplateSkeletonResponse = {
|
|
72
72
|
type: "template.skeleton";
|
|
@@ -78,7 +78,7 @@ export type TemplateSkeletonResponse = {
|
|
|
78
78
|
};
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* xds --json template <name> [path]
|
|
82
82
|
*/
|
|
83
83
|
export type TemplateCopyResponse = {
|
|
84
84
|
type: "template.copy";
|
|
@@ -90,7 +90,7 @@ export type TemplateCopyResponse = {
|
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
/**
|
|
93
|
-
*
|
|
93
|
+
* xds --json template --cdn [path]
|
|
94
94
|
* `written: false` with `reason: 'exists'` is a success: the command is safe to
|
|
95
95
|
* re-run, and an edited page is the consumer's file to keep. `version` is the
|
|
96
96
|
* Astryx version every CDN URL in the file was pinned to.
|
|
@@ -118,7 +118,7 @@ export type TemplateOptions = {
|
|
|
118
118
|
/**
|
|
119
119
|
* Filter templates by kind: 'page' or 'block'. Only applies to list views.
|
|
120
120
|
*/
|
|
121
|
-
type?: "
|
|
121
|
+
type?: "block" | "page" | undefined;
|
|
122
122
|
/**
|
|
123
123
|
* Narrow to templates from a specific package (id-only lookups across packages are ambiguous).
|
|
124
124
|
*/
|
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Each template is exactly two files: page.tsx (code) + template.doc.mjs (metadata).
|
|
8
8
|
*
|
|
9
|
-
* Invocation
|
|
9
|
+
* Invocation -> type discriminator
|
|
10
10
|
* ------------------------------------------------------------------
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* (unknown template)
|
|
11
|
+
* xds --json template [--list] -> template.list
|
|
12
|
+
* xds --json template <name> -> template.show
|
|
13
|
+
* xds --json template <name> --skeleton -> template.skeleton
|
|
14
|
+
* xds --json template <name> [path] -> template.copy
|
|
15
|
+
* xds --json template --cdn [path] -> template.cdn
|
|
16
|
+
* (unknown template) -> CLIError
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* xds --json template [--list]
|
|
21
21
|
* @typedef {object} TemplateListResponse
|
|
22
22
|
* @property {'template.list'} type
|
|
23
23
|
* @property {TemplateListEntry[]} data
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* xds --json template <name>
|
|
47
47
|
* @typedef {object} TemplateShowResponse
|
|
48
48
|
* @property {'template.show'} type
|
|
49
49
|
* @property {object} data
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
*/
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* xds --json template <name> --skeleton
|
|
59
59
|
* @typedef {object} TemplateSkeletonResponse
|
|
60
60
|
* @property {'template.skeleton'} type
|
|
61
61
|
* @property {object} data
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
*/
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* xds --json template <name> [path]
|
|
70
70
|
* @typedef {object} TemplateCopyResponse
|
|
71
71
|
* @property {'template.copy'} type
|
|
72
72
|
* @property {object} data
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
*/
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
*
|
|
80
|
+
* xds --json template --cdn [path]
|
|
81
81
|
* `written: false` with `reason: 'exists'` is a success: the command is safe to
|
|
82
82
|
* re-run, and an edited page is the consumer's file to keep. `version` is the
|
|
83
83
|
* Astryx version every CDN URL in the file was pinned to.
|
|
@@ -12,10 +12,9 @@
|
|
|
12
12
|
* - A .d.ts (plus an optional .variants.d.ts for custom prop values)
|
|
13
13
|
*
|
|
14
14
|
* It performs the writes and returns a `theme.build` receipt — its `warnings`
|
|
15
|
-
* carry override problems
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* CSS (nothing to build). Errors throw AstryxError (with
|
|
15
|
+
* carry override problems and any fonts the theme names but does not load
|
|
16
|
+
* (font-warning.mjs) — or `null` when the theme produced no CSS (nothing to
|
|
17
|
+
* build). Errors throw AstryxError (with
|
|
19
18
|
* a stable code). Human progress is emitted through the shared `logger`
|
|
20
19
|
* (silent by default), so the CLI keeps its exact output while a programmatic
|
|
21
20
|
* caller stays quiet.
|
|
@@ -2304,15 +2303,7 @@ async function themeBuildInternal(
|
|
|
2304
2303
|
const scopeSelector = themeScopeStart(themeDef.name);
|
|
2305
2304
|
const scopeTo = THEME_SCOPE_TO;
|
|
2306
2305
|
|
|
2307
|
-
|
|
2308
|
-
// warning text here that runtime callers receive on the console.
|
|
2309
|
-
/** @type {string[]} */
|
|
2310
|
-
const droppedDeclarations = [];
|
|
2311
|
-
|
|
2312
|
-
const {component, prose} = _generateThemeRulesSplit(
|
|
2313
|
-
resolvedTheme,
|
|
2314
|
-
droppedDeclarations,
|
|
2315
|
-
);
|
|
2306
|
+
const {component, prose} = _generateThemeRulesSplit(resolvedTheme);
|
|
2316
2307
|
const cssParts = [];
|
|
2317
2308
|
// Prose element defaults always ship — the `<Theme>` runtime
|
|
2318
2309
|
// (generateThemeCSS) always emits them, so the build must too, or the
|
|
@@ -2331,7 +2322,7 @@ async function themeBuildInternal(
|
|
|
2331
2322
|
let adaptationCss;
|
|
2332
2323
|
try {
|
|
2333
2324
|
adaptationCss = _generateAdaptationCSS
|
|
2334
|
-
? _generateAdaptationCSS(resolvedTheme
|
|
2325
|
+
? _generateAdaptationCSS(resolvedTheme)
|
|
2335
2326
|
: {component: '', prose: ''};
|
|
2336
2327
|
} catch (error) {
|
|
2337
2328
|
const message =
|
|
@@ -2377,16 +2368,11 @@ async function themeBuildInternal(
|
|
|
2377
2368
|
// adaptations on the same resolved leaf.
|
|
2378
2369
|
let onMediaCss = '';
|
|
2379
2370
|
if (_generateOnMediaCSS) {
|
|
2380
|
-
onMediaCss = _generateOnMediaCSS(resolvedTheme
|
|
2371
|
+
onMediaCss = _generateOnMediaCSS(resolvedTheme);
|
|
2381
2372
|
if (onMediaCss) {
|
|
2382
2373
|
cssParts.push(`@layer astryx-theme {\n${onMediaCss}\n}`);
|
|
2383
2374
|
}
|
|
2384
2375
|
}
|
|
2385
|
-
for (const message of droppedDeclarations) {
|
|
2386
|
-
const w = `Declaration ${message}. The generated CSS omits it; fix the value in the theme source.`;
|
|
2387
|
-
warningMessages.push(w);
|
|
2388
|
-
logger.warn(` ⚠ ${w}`);
|
|
2389
|
-
}
|
|
2390
2376
|
if (cssParts.length === 0) {
|
|
2391
2377
|
logger.log('No overrides found — nothing to build.');
|
|
2392
2378
|
return null;
|