@astryxdesign/cli 0.6.4 → 0.6.5-canary.031021b
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 +56 -0
- package/README.md +97 -90
- package/api/build/build.doc.mjs +6 -1
- package/api/build/build.test.mjs +22 -0
- package/api/build/kit/kit.mjs +44 -5
- package/api/component/_adapter.d.mts +25 -0
- package/api/component/_adapter.mjs +59 -5
- package/api/component/component.d.mts +6 -3
- package/api/component/component.doc.mjs +37 -17
- package/api/component/component.mjs +249 -9
- package/api/component/component.type.d.mts +25 -0
- package/api/component/component.type.mjs +44 -0
- package/api/discover/_adapter.d.mts +114 -6
- package/api/discover/_adapter.mjs +372 -17
- package/api/discover/_adapter.test.mjs +215 -0
- package/api/discover/_catalog-view.d.mts +115 -0
- package/api/discover/_catalog-view.mjs +203 -0
- package/api/discover/_catalog-view.test.mjs +128 -0
- package/api/discover/detail/detail.d.mts +18 -6
- package/api/discover/detail/detail.mjs +67 -13
- package/api/discover/detail/detail.test.mjs +85 -0
- package/api/discover/detail/item/item.d.mts +26 -0
- package/api/discover/detail/item/item.mjs +78 -0
- package/api/discover/detail/item/item.test.mjs +73 -0
- package/api/discover/discover.d.mts +3 -9
- package/api/discover/discover.doc.mjs +61 -18
- package/api/discover/discover.mjs +220 -36
- package/api/discover/discover.test.mjs +11 -2
- package/api/discover/discover.type.d.mts +147 -8
- package/api/discover/discover.type.mjs +102 -12
- package/api/discover/list/list.d.mts +20 -6
- package/api/discover/list/list.mjs +45 -12
- package/api/discover/list/list.test.mjs +46 -0
- package/api/discover/search/search.d.mts +18 -16
- package/api/discover/search/search.mjs +102 -56
- package/api/discover/search/search.test.mjs +144 -10
- package/api/docs/_adapter.d.mts +8 -3
- package/api/docs/_adapter.mjs +14 -6
- package/api/docs/docOverlays.test.mjs +27 -1
- package/api/docs/docs.doc.mjs +2 -2
- package/api/doctor/doctor.d.mts +8 -3
- package/api/doctor/doctor.doc.mjs +17 -8
- package/api/doctor/doctor.mjs +90 -9
- package/api/doctor/doctor.test.mjs +122 -10
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/gap-report/gap-report.doc.mjs +19 -10
- package/api/hook/hook.doc.mjs +6 -3
- package/api/index.d.mts +1 -0
- package/api/index.mjs +5 -3
- package/api/init/init.doc.mjs +17 -12
- package/api/integration/add-helpers.d.mts +5 -2
- package/api/integration/add-helpers.mjs +36 -9
- package/api/integration/add-theme.mjs +22 -1
- package/api/integration/add-theme.test.mjs +34 -0
- package/api/integration/authoring-checks.mjs +2 -2
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
- package/api/integration/pack-check.mjs +82 -9
- package/api/integration/pack-check.test.mjs +90 -0
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/isError.doc.mjs +1 -1
- package/api/search/search.d.mts +27 -1
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +228 -16
- package/api/swizzle/swizzle.doc.mjs +7 -5
- package/api/template/copy/copy.mjs +1 -1
- package/api/template/copy/copy.test.mjs +9 -0
- package/api/template/template.doc.mjs +2 -1
- package/api/theme/add/add.mjs +17 -25
- package/api/theme/add/add.rollback.test.mjs +158 -0
- package/api/theme/add/add.staging.test.mjs +40 -23
- package/api/theme/build/build.family.test.mjs +7 -12
- package/api/theme/build/build.mjs +8 -18
- package/api/theme/build/build.rollback.test.mjs +148 -0
- package/api/theme/generateTonalPalette.doc.mjs +1 -2
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +9 -10
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +2 -1
- package/api/theme/themePaletteGenerate.doc.mjs +15 -8
- package/api/theme/themeTargets.doc.mjs +3 -2
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/run/files-changed.test.mjs +111 -0
- package/api/upgrade/run/run.mjs +5 -3
- package/api/upgrade/upgrade.doc.mjs +24 -22
- package/api/upgrade/upgrade.type.mjs +2 -2
- package/assets/codemods/__tests__/runner.test.mjs +3 -1
- package/assets/codemods/file-count.test.mjs +163 -0
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +5 -4
- package/assets/docs/README.md +4 -2
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +8 -2
- package/assets/docs/elevation.doc.mjs +6 -4
- package/assets/docs/getting-started.doc.mjs +5 -16
- package/assets/docs/icons.doc.mjs +2 -21
- package/assets/docs/illustrations.doc.mjs +7 -15
- package/assets/docs/internationalization.doc.mjs +7 -5
- package/assets/docs/layout.doc.dense.mjs +130 -82
- package/assets/docs/layout.doc.mjs +133 -77
- package/assets/docs/migration.doc.mjs +19 -21
- package/assets/docs/motion.doc.mjs +16 -3
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +8 -0
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +8 -3
- package/assets/docs/spacing.doc.mjs +7 -2
- package/assets/docs/styling-libraries.doc.mjs +6 -2
- package/assets/docs/styling.doc.mjs +19 -23
- package/assets/docs/theme.doc.dense.mjs +58 -18
- package/assets/docs/theme.doc.mjs +57 -47
- package/assets/docs/theme.doc.zh.mjs +9 -8
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +389 -8
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/add-a-component.doc.mjs +75 -0
- package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
- package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
- package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
- package/assets/docs/tree/block-template.doc.mjs +130 -0
- package/assets/docs/tree/build-the-template.doc.mjs +28 -0
- package/assets/docs/tree/building-blocks.doc.mjs +46 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
- package/assets/docs/tree/checks.doc.mjs +119 -0
- package/assets/docs/tree/codemods.doc.mjs +147 -0
- package/assets/docs/tree/component-family.doc.mjs +113 -0
- package/assets/docs/tree/component-imports.doc.mjs +69 -0
- package/assets/docs/tree/component-lookups.doc.mjs +149 -0
- package/assets/docs/tree/components.doc.mjs +23 -0
- package/assets/docs/tree/configuration.doc.mjs +23 -0
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
- package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
- package/assets/docs/tree/docs.doc.mjs +21 -0
- package/assets/docs/tree/document-the-template.doc.mjs +28 -0
- package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
- package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
- package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
- package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
- package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
- package/assets/docs/tree/help.doc.mjs +16 -0
- package/assets/docs/tree/integrations.doc.mjs +25 -451
- package/assets/docs/tree/links.doc.mjs +98 -0
- package/assets/docs/tree/package-and-test.doc.mjs +32 -0
- package/assets/docs/tree/page-template.doc.mjs +71 -0
- package/assets/docs/tree/publishing.doc.mjs +111 -0
- package/assets/docs/tree/quick-start.doc.mjs +272 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
- package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
- package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
- package/assets/docs/tree/ship.doc.mjs +16 -0
- package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
- package/assets/docs/tree/single-component.doc.mjs +165 -0
- package/assets/docs/tree/start-a-template.doc.mjs +143 -0
- package/assets/docs/tree/subcomponent.doc.mjs +115 -0
- package/assets/docs/tree/template-assets.doc.mjs +64 -0
- package/assets/docs/tree/template-doc-overview.doc.mjs +109 -0
- package/assets/docs/tree/template-fonts.doc.mjs +102 -0
- package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
- package/assets/docs/tree/template-icons.doc.mjs +97 -0
- package/assets/docs/tree/template-images-media.doc.mjs +127 -0
- package/assets/docs/tree/template-styles.doc.mjs +93 -0
- package/assets/docs/tree/templates.doc.mjs +34 -0
- package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
- package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
- package/assets/docs/tree/themes.doc.mjs +39 -0
- package/assets/docs/tree/troubleshooting.doc.mjs +149 -0
- package/assets/docs/tree/upgrading.doc.mjs +103 -0
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
- package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
- package/assets/docs/tree/versioning.doc.mjs +161 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
- package/assets/docs/typography.doc.mjs +24 -4
- package/assets/docs/working-with-ai.doc.mjs +30 -22
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/authoring/config/config.doc.mjs +9 -1
- package/authoring/config/parse.d.mts +2 -0
- package/authoring/config/parse.mjs +19 -0
- package/authoring/config/parse.test.mjs +8 -0
- package/authoring/config/type.ts +11 -0
- package/authoring/discover/discover.doc.d.mts +13 -0
- package/authoring/discover/discover.doc.mjs +138 -0
- package/authoring/discover/parse.d.mts +24 -0
- package/authoring/discover/parse.mjs +128 -0
- package/authoring/discover/parse.test.mjs +124 -0
- package/authoring/discover/type.ts +87 -0
- package/authoring/doctypes/_schema.d.mts +3 -2
- package/authoring/doctypes/_schema.mjs +6 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +4 -2
- package/authoring/doctypes/component/component.doc.mjs +6 -0
- package/authoring/doctypes/component/type.ts +8 -0
- package/authoring/doctypes/reference/reference.doc.mjs +7 -0
- package/authoring/doctypes/reference/type.ts +5 -0
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +2 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +10 -0
- package/authoring/index.mjs +1 -0
- package/authoring/integration/integration.doc.mjs +12 -10
- package/clients/cli/commands/component/index.mjs +152 -55
- package/clients/cli/commands/component-batch.test.mjs +341 -0
- package/clients/cli/commands/component-ownership.test.mjs +89 -0
- package/clients/cli/commands/component.doc.mjs +27 -9
- package/clients/cli/commands/discover.doc.mjs +53 -9
- package/clients/cli/commands/discover.mjs +393 -118
- package/clients/cli/commands/discover.sources.test.mjs +267 -0
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +60 -17
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -2
- package/clients/cli/commands/doctor-integration.test.mjs +53 -0
- package/clients/cli/commands/doctor.doc.mjs +3 -1
- package/clients/cli/commands/doctor.mjs +49 -5
- package/clients/cli/commands/gap-report.doc.mjs +10 -9
- package/clients/cli/commands/init.doc.mjs +9 -6
- package/clients/cli/commands/integration-add.doc.mjs +9 -9
- package/clients/cli/commands/integration-authoring.test.mjs +61 -10
- package/clients/cli/commands/integration-pack.doc.mjs +5 -9
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration-verify.doc.mjs +22 -0
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +74 -43
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +10 -3
- package/clients/cli/commands/search.mjs +21 -2
- package/clients/cli/commands/search.test.mjs +21 -4
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/text-json-parity.test.mjs +7 -1
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -2
- package/clients/cli/commands/theme-palette.doc.mjs +1 -2
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +62 -3
- package/clients/cli/index.mjs +28 -6
- package/clients/cli/lib/define-command.mjs +28 -4
- package/clients/cli/lib/define-command.test.mjs +54 -0
- package/clients/cli/lib/exit-codes.test.mjs +17 -1
- package/clients/cli/lib/json-shim.mjs +24 -14
- package/clients/cli/lib/manifest.mjs +18 -5
- package/clients/cli/lib/manifest.test.mjs +5 -2
- package/clients/cli/lib/parse-error-format.test.mjs +81 -0
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/discovery/authoring-self-docs.mjs +1 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +6 -2
- package/foundation/discovery/cli-self-docs.mjs +16 -2
- package/foundation/discovery/cli-self-docs.test.mjs +20 -0
- package/foundation/discovery/docs-discovery.mjs +5 -1
- package/foundation/discovery/docs-discovery.test.mjs +21 -0
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +3 -2
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/tree.d.mts +4 -0
- package/foundation/doc-compiler/tree.mjs +6 -1
- package/foundation/integrations/cli-requirement.d.mts +26 -6
- package/foundation/integrations/cli-requirement.mjs +46 -11
- package/foundation/integrations/cli-requirement.test.mjs +7 -2
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +14 -1
- package/foundation/integrations/integrations.mjs +41 -1
- package/foundation/integrations/integrations.test.mjs +31 -0
- package/foundation/response/batch.type.d.mts +33 -0
- package/foundation/response/batch.type.mjs +34 -0
- package/foundation/response/error-codes.doc.mjs +6 -8
- package/foundation/response/error-codes.test.mjs +30 -5
- package/foundation/response/response-types.doc.d.mts +4 -3
- package/foundation/response/response-types.doc.mjs +40 -10
- package/foundation/response/response-types.doc.test.mjs +23 -0
- package/foundation/response/response.doc.mjs +11 -10
- package/package.json +9 -9
- package/api/docs/docs.test.mjs +0 -243
- package/api/docs/integration-tree.test.mjs +0 -555
- package/api/docs/integrationDocs.test.mjs +0 -314
- package/api/search/search.test.mjs +0 -512
- package/assets/docs/tree/integrations.test.mjs +0 -62
- package/assets/docs/tree/writing-docs.doc.mjs +0 -286
- package/clients/cli/commands/docs.test.mjs +0 -294
- package/foundation/agent-docs/agent-docs.test.mjs +0 -1159
- package/foundation/doc-compiler/tree.test.mjs +0 -598
|
@@ -63,7 +63,9 @@ describe('authoring self-docs', () => {
|
|
|
63
63
|
describe('what the authoring docs say about the docs tree', () => {
|
|
64
64
|
it('marks exactly the fields the docs tree does not read yet', () => {
|
|
65
65
|
const notReadYet = graphFieldsDoc.fields
|
|
66
|
-
.filter(field =>
|
|
66
|
+
.filter(field =>
|
|
67
|
+
/^Reserved: .*Nothing reads it today/.test(field.description),
|
|
68
|
+
)
|
|
67
69
|
.map(field => field.name);
|
|
68
70
|
// The tree reads `placement` for every guide (spec:AST-046); the other
|
|
69
71
|
// graph fields are still refused by every topic reader.
|
|
@@ -79,7 +81,9 @@ describe('what the authoring docs say about the docs tree', () => {
|
|
|
79
81
|
expect(placement.description).toMatch(
|
|
80
82
|
/Read for every guide, the CLI's and each integration's/,
|
|
81
83
|
);
|
|
82
|
-
expect(graphFieldsDoc.description).toMatch(
|
|
84
|
+
expect(graphFieldsDoc.description).toMatch(
|
|
85
|
+
/Nothing reads `aliases` or `audience` today/,
|
|
86
|
+
);
|
|
83
87
|
});
|
|
84
88
|
|
|
85
89
|
it('keeps graph blocks behind the separate GraphContentBlock type, and a section takes a reference block', () => {
|
|
@@ -315,12 +315,20 @@ function functionSection(fn, index) {
|
|
|
315
315
|
}
|
|
316
316
|
const params = fn.params ?? [];
|
|
317
317
|
if (params.length > 0) {
|
|
318
|
+
// A Default column only when some parameter declares a default, so a
|
|
319
|
+
// function with none keeps a three-column table.
|
|
320
|
+
const defaults = params.some(
|
|
321
|
+
(/** @type {any} */ p) => typeof p.default === 'string' && p.default !== '',
|
|
322
|
+
);
|
|
318
323
|
content.push({
|
|
319
324
|
type: 'table',
|
|
320
|
-
headers:
|
|
325
|
+
headers: defaults
|
|
326
|
+
? ['Parameter', 'Type', 'Default', 'Description']
|
|
327
|
+
: ['Parameter', 'Type', 'Description'],
|
|
321
328
|
rows: params.map((/** @type {any} */ p) => [
|
|
322
|
-
`\`${p.name}
|
|
329
|
+
`\`${p.name}\`${p.required ? ' (required)' : ''}`,
|
|
323
330
|
`\`${p.type ?? ''}\``,
|
|
331
|
+
...(defaults ? [p.default ?? ''] : []),
|
|
324
332
|
p.description ?? '',
|
|
325
333
|
]),
|
|
326
334
|
});
|
|
@@ -405,6 +413,12 @@ export function cliDocSection(doc, index) {
|
|
|
405
413
|
if (doc.type === 'command') return commandSection(doc, index);
|
|
406
414
|
if (doc.type === 'function') return functionSection(doc, index);
|
|
407
415
|
if (doc.type === 'enum') return enumSection(doc);
|
|
416
|
+
if (doc.type === 'namespace')
|
|
417
|
+
return {
|
|
418
|
+
id: routeSegment(doc.name),
|
|
419
|
+
title: doc.title,
|
|
420
|
+
content: doc.blocks ?? [],
|
|
421
|
+
};
|
|
408
422
|
return {...selfDocSection(doc), id: routeSegment(doc.name)};
|
|
409
423
|
}
|
|
410
424
|
|
|
@@ -315,6 +315,26 @@ describe('cliDocSection', () => {
|
|
|
315
315
|
]);
|
|
316
316
|
});
|
|
317
317
|
|
|
318
|
+
it('marks required parameters and adds a Default column when a parameter has a default', () => {
|
|
319
|
+
const beta = fn('beta', {
|
|
320
|
+
params: [
|
|
321
|
+
{name: 'slug', type: 'string', description: 'The slug.', required: true},
|
|
322
|
+
{name: 'options.limit', type: 'number', description: 'How many.', default: '20'},
|
|
323
|
+
],
|
|
324
|
+
});
|
|
325
|
+
const table = cliDocSection(beta, indexOf([beta])).content.find(
|
|
326
|
+
(/** @type {any} */ block) => block.type === 'table',
|
|
327
|
+
);
|
|
328
|
+
expect(table).toEqual({
|
|
329
|
+
type: 'table',
|
|
330
|
+
headers: ['Parameter', 'Type', 'Default', 'Description'],
|
|
331
|
+
rows: [
|
|
332
|
+
['`slug` (required)', '`string`', '', 'The slug.'],
|
|
333
|
+
['`options.limit`', '`number`', '20', 'How many.'],
|
|
334
|
+
],
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
318
338
|
it('renders an API function, an enum, and a schema', () => {
|
|
319
339
|
const alpha = fn('alpha', {
|
|
320
340
|
description: 'Longer.',
|
|
@@ -626,7 +626,11 @@ function findMergeTarget(sections, section) {
|
|
|
626
626
|
const sameTitle = sections.findIndex(
|
|
627
627
|
candidate => sourceTitle(candidate) === title,
|
|
628
628
|
);
|
|
629
|
-
return sameTitle;
|
|
629
|
+
if (sameTitle !== -1) return sameTitle;
|
|
630
|
+
// A base section retitled later keeps its old key as its `id`, so an
|
|
631
|
+
// extension that still names it by the old title finds it by that id. A
|
|
632
|
+
// title variant of a section with no id stays a separate section.
|
|
633
|
+
return sections.findIndex(candidate => candidate.id === key);
|
|
630
634
|
}
|
|
631
635
|
|
|
632
636
|
/**
|
|
@@ -509,6 +509,27 @@ describe('mergeTopic', () => {
|
|
|
509
509
|
expect(base.sections[0].content[0].text).toBe('npm i');
|
|
510
510
|
});
|
|
511
511
|
|
|
512
|
+
it('finds a retitled base section by the key its old title derives', () => {
|
|
513
|
+
// A base section retitled later keeps its old key as its `id`; an
|
|
514
|
+
// extension that still names it by the old title replaces it.
|
|
515
|
+
const merged = mergeTopic(
|
|
516
|
+
{
|
|
517
|
+
...base,
|
|
518
|
+
sections: [
|
|
519
|
+
{id: 'quick-start', title: 'Wrap your app in a theme', content: []},
|
|
520
|
+
{id: 'tokens', title: 'Tokens', content: []},
|
|
521
|
+
],
|
|
522
|
+
},
|
|
523
|
+
{sections: [{title: 'Quick Start', content: []}]},
|
|
524
|
+
);
|
|
525
|
+
expect(merged.sections.map(section => [section.id, section.title])).toEqual(
|
|
526
|
+
[
|
|
527
|
+
['quick-start', 'Quick Start'],
|
|
528
|
+
['tokens', 'Tokens'],
|
|
529
|
+
],
|
|
530
|
+
);
|
|
531
|
+
});
|
|
532
|
+
|
|
512
533
|
it('replaces a section by stable ID even when its title changes', () => {
|
|
513
534
|
const merged = mergeTopic(
|
|
514
535
|
{
|
|
@@ -32,7 +32,7 @@ export function sectionTitleKey(title: unknown): string;
|
|
|
32
32
|
export function sectionKey(section: any): string;
|
|
33
33
|
/**
|
|
34
34
|
* A name as a docs-tree route segment: lowercase words joined by hyphens, so
|
|
35
|
-
* `integrationPackCheck` and `integration
|
|
35
|
+
* `integrationPackCheck` and `integration verify` both read naturally.
|
|
36
36
|
* @param {string} name
|
|
37
37
|
* @returns {string}
|
|
38
38
|
*/
|
|
@@ -95,7 +95,7 @@ function legacyTitleMatchIndex(sections, query) {
|
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* A name as a docs-tree route segment: lowercase words joined by hyphens, so
|
|
98
|
-
* `integrationPackCheck` and `integration
|
|
98
|
+
* `integrationPackCheck` and `integration verify` both read naturally.
|
|
99
99
|
* @param {string} name
|
|
100
100
|
* @returns {string}
|
|
101
101
|
*/
|
|
@@ -53,8 +53,8 @@ const RUNNERS = {
|
|
|
53
53
|
sites: ['import(node:child_process)', 'worker_threads.Worker'],
|
|
54
54
|
},
|
|
55
55
|
'api/integration/pack-check.mjs': {
|
|
56
|
-
runs: '`npm pack`, `tar`, and a Node script that resolves the packed specifiers, to check a package as published',
|
|
57
|
-
sites: ['child_process.spawnSync ×3'],
|
|
56
|
+
runs: '`npm pack`, `tar`, and a Node script that resolves the packed specifiers, to check a package as published, and the package\'s doc modules, to see which need a newer CLI',
|
|
57
|
+
sites: ['child_process.spawnSync ×3', 'loadTopicModule'],
|
|
58
58
|
},
|
|
59
59
|
'api/swizzle/_github.mjs': {
|
|
60
60
|
runs: '`gh auth status`, to check the GitHub CLI is signed in',
|
|
@@ -188,6 +188,7 @@ const RUNNERS = {
|
|
|
188
188
|
'import ../../../api/integration/integrationPackCheck.doc.mjs',
|
|
189
189
|
'import ./integration-add.doc.mjs',
|
|
190
190
|
'import ./integration-pack.doc.mjs',
|
|
191
|
+
'import ./integration-verify.doc.mjs',
|
|
191
192
|
'import ./integration.doc.mjs',
|
|
192
193
|
],
|
|
193
194
|
},
|
|
@@ -58,7 +58,7 @@ export const KIND_GROUPS = Object.freeze({
|
|
|
58
58
|
schema: {
|
|
59
59
|
segment: 'schemas',
|
|
60
60
|
title: 'Schemas',
|
|
61
|
-
summary: '
|
|
61
|
+
summary: 'Data shapes, field by field.',
|
|
62
62
|
},
|
|
63
63
|
enum: {
|
|
64
64
|
segment: 'enums',
|
|
@@ -140,6 +140,7 @@ export const UNORGANIZED = 'unorganized';
|
|
|
140
140
|
* @property {string} name
|
|
141
141
|
* @property {string} title
|
|
142
142
|
* @property {string} summary
|
|
143
|
+
* @property {string[]} [keywords] an authored namespace's search keywords
|
|
143
144
|
* @property {string | null} parent the parent's route; null at the top
|
|
144
145
|
* @property {string | null} slot the parent slot this node sits in
|
|
145
146
|
* @property {number | null} order
|
|
@@ -420,10 +421,14 @@ export function buildDocsTree({namespaces, docs, topics = []}) {
|
|
|
420
421
|
name: input.doc.name,
|
|
421
422
|
title: input.doc.title,
|
|
422
423
|
summary: input.doc.summary,
|
|
424
|
+
...(Array.isArray(input.doc.keywords)
|
|
425
|
+
? {keywords: input.doc.keywords}
|
|
426
|
+
: {}),
|
|
423
427
|
parent: parentRoute,
|
|
424
428
|
slot: home?.slot ?? null,
|
|
425
429
|
order: home?.order ?? null,
|
|
426
430
|
generated: false,
|
|
431
|
+
ref: {selfDoc: input.doc},
|
|
427
432
|
slots: Object.entries(input.doc.slots).map(([name, slot]) => ({
|
|
428
433
|
name,
|
|
429
434
|
title: slot.title,
|
|
@@ -20,13 +20,31 @@ export function lowestAdmitted(range: unknown): string | null;
|
|
|
20
20
|
*/
|
|
21
21
|
export function docsTreeCliProblem(pkg: any): string | null;
|
|
22
22
|
/**
|
|
23
|
-
* Why a package with a template that sets `replaces` would lose
|
|
24
|
-
*
|
|
23
|
+
* Why a package with a template that sets `replaces` would lose templates and
|
|
24
|
+
* doc topics on an older CLI (spec:AST-035), or null when its declared CLI
|
|
25
25
|
* range admits only CLIs that read the field.
|
|
26
26
|
* @param {any} pkg package.json
|
|
27
27
|
* @returns {string | null}
|
|
28
28
|
*/
|
|
29
29
|
export function replacesCliProblem(pkg: any): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Why a package with a doc section that sets `id` would lose its doc topics on
|
|
32
|
+
* an older CLI, or null when its declared CLI range admits only CLIs that read
|
|
33
|
+
* the field. Published 0.6.3 rejects a section `id` and hides every doc topic
|
|
34
|
+
* the package ships.
|
|
35
|
+
* @param {any} pkg package.json
|
|
36
|
+
* @returns {string | null}
|
|
37
|
+
*/
|
|
38
|
+
export function sectionIdsCliProblem(pkg: any): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Why a package that ships a theme would lose its themes and doc topics on an
|
|
41
|
+
* older CLI, or null when its declared CLI range admits only CLIs that read
|
|
42
|
+
* typed theme descriptors. Published 0.6.3 rejects a themes root with no
|
|
43
|
+
* `manifest.json` catalog, which `integration add theme` no longer writes.
|
|
44
|
+
* @param {any} pkg package.json
|
|
45
|
+
* @returns {string | null}
|
|
46
|
+
*/
|
|
47
|
+
export function themesCliProblem(pkg: any): string | null;
|
|
30
48
|
/**
|
|
31
49
|
* The package.json with a CLI peer that reads namespace docs: optional, unless
|
|
32
50
|
* the package already says otherwise.
|
|
@@ -37,9 +55,11 @@ export function withDocsTreeCli(pkg: any): any;
|
|
|
37
55
|
export const CLI_PACKAGE: "@astryxdesign/cli";
|
|
38
56
|
/**
|
|
39
57
|
* The first CLI release that reads an integration's docs tree (namespace docs
|
|
40
|
-
* and placed guides)
|
|
41
|
-
* hide every doc topic a package with a
|
|
42
|
-
* ships, with no warning
|
|
43
|
-
* package's
|
|
58
|
+
* and placed guides), its templates' `replaces`, and its typed theme
|
|
59
|
+
* descriptors. A release before it can hide every doc topic a package with a
|
|
60
|
+
* namespace doc or a placed guide ships, with no warning; it rejects
|
|
61
|
+
* `replaces`, drops that template, and hides the package's doc topics; and it
|
|
62
|
+
* rejects a themes root without the `manifest.json` catalog the CLI no longer
|
|
63
|
+
* writes, withholding the package's themes and doc topics.
|
|
44
64
|
*/
|
|
45
65
|
export const DOCS_TREE_CLI: "0.7.0";
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* @input A package.json object.
|
|
7
7
|
* @output Whether its `peerDependencies` range for `@astryxdesign/cli` admits
|
|
8
8
|
* only CLIs that read namespace docs, and the package.json that declares it.
|
|
9
|
-
* @position foundation/integrations; read by `integration add doc --parent
|
|
10
|
-
*
|
|
9
|
+
* @position foundation/integrations; read by `integration add doc --parent`
|
|
10
|
+
* and `integration add theme`, which declare the peer, and
|
|
11
|
+
* `integration verify`, which requires it.
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
14
|
import {semverCompare} from '../env/semver.mjs';
|
|
@@ -16,10 +17,12 @@ export const CLI_PACKAGE = '@astryxdesign/cli';
|
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* The first CLI release that reads an integration's docs tree (namespace docs
|
|
19
|
-
* and placed guides)
|
|
20
|
-
* hide every doc topic a package with a
|
|
21
|
-
* ships, with no warning
|
|
22
|
-
* package's
|
|
20
|
+
* and placed guides), its templates' `replaces`, and its typed theme
|
|
21
|
+
* descriptors. A release before it can hide every doc topic a package with a
|
|
22
|
+
* namespace doc or a placed guide ships, with no warning; it rejects
|
|
23
|
+
* `replaces`, drops that template, and hides the package's doc topics; and it
|
|
24
|
+
* rejects a themes root without the `manifest.json` catalog the CLI no longer
|
|
25
|
+
* writes, withholding the package's themes and doc topics.
|
|
23
26
|
*/
|
|
24
27
|
export const DOCS_TREE_CLI = '0.7.0';
|
|
25
28
|
|
|
@@ -92,11 +95,11 @@ function cliRangeProblem(pkg, feature, loss) {
|
|
|
92
95
|
const range = pkg?.peerDependencies?.[CLI_PACKAGE];
|
|
93
96
|
const fix = `"${CLI_PACKAGE}": ">=${DOCS_TREE_CLI}" in peerDependencies (optional in peerDependenciesMeta, if the CLI is not required)`;
|
|
94
97
|
if (typeof range !== 'string') {
|
|
95
|
-
return `The package ${feature} but declares no ${CLI_PACKAGE} peer. A CLI
|
|
98
|
+
return `The package ${feature} but declares no ${CLI_PACKAGE} peer. A stable CLI before ${DOCS_TREE_CLI} ${loss}. Declare ${fix}.`;
|
|
96
99
|
}
|
|
97
100
|
const lowest = lowestAdmitted(range);
|
|
98
101
|
if (lowest == null || semverCompare(lowest, DOCS_TREE_CLI) < 0) {
|
|
99
|
-
return `The package ${feature}, but its ${CLI_PACKAGE} peer range "${range}" admits a CLI
|
|
102
|
+
return `The package ${feature}, but its ${CLI_PACKAGE} peer range "${range}" admits a stable CLI before ${DOCS_TREE_CLI}, which ${loss}. Declare ${fix}.`;
|
|
100
103
|
}
|
|
101
104
|
return null;
|
|
102
105
|
}
|
|
@@ -119,8 +122,8 @@ export function docsTreeCliProblem(pkg) {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
/**
|
|
122
|
-
* Why a package with a template that sets `replaces` would lose
|
|
123
|
-
*
|
|
125
|
+
* Why a package with a template that sets `replaces` would lose templates and
|
|
126
|
+
* doc topics on an older CLI (spec:AST-035), or null when its declared CLI
|
|
124
127
|
* range admits only CLIs that read the field.
|
|
125
128
|
* @param {any} pkg package.json
|
|
126
129
|
* @returns {string | null}
|
|
@@ -129,7 +132,39 @@ export function replacesCliProblem(pkg) {
|
|
|
129
132
|
return cliRangeProblem(
|
|
130
133
|
pkg,
|
|
131
134
|
'has a template that sets `replaces`',
|
|
132
|
-
"rejects the field, and
|
|
135
|
+
"rejects the field, drops that template, and hides the package's doc topics",
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Why a package with a doc section that sets `id` would lose its doc topics on
|
|
141
|
+
* an older CLI, or null when its declared CLI range admits only CLIs that read
|
|
142
|
+
* the field. Published 0.6.3 rejects a section `id` and hides every doc topic
|
|
143
|
+
* the package ships.
|
|
144
|
+
* @param {any} pkg package.json
|
|
145
|
+
* @returns {string | null}
|
|
146
|
+
*/
|
|
147
|
+
export function sectionIdsCliProblem(pkg) {
|
|
148
|
+
return cliRangeProblem(
|
|
149
|
+
pkg,
|
|
150
|
+
'has a doc section that sets `id`',
|
|
151
|
+
'rejects the field, and can hide every doc topic the package ships',
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Why a package that ships a theme would lose its themes and doc topics on an
|
|
157
|
+
* older CLI, or null when its declared CLI range admits only CLIs that read
|
|
158
|
+
* typed theme descriptors. Published 0.6.3 rejects a themes root with no
|
|
159
|
+
* `manifest.json` catalog, which `integration add theme` no longer writes.
|
|
160
|
+
* @param {any} pkg package.json
|
|
161
|
+
* @returns {string | null}
|
|
162
|
+
*/
|
|
163
|
+
export function themesCliProblem(pkg) {
|
|
164
|
+
return cliRangeProblem(
|
|
165
|
+
pkg,
|
|
166
|
+
'ships a theme',
|
|
167
|
+
"cannot read typed theme descriptors, and can drop the package's themes and hide its doc topics",
|
|
133
168
|
);
|
|
134
169
|
}
|
|
135
170
|
|
|
@@ -32,6 +32,11 @@ describe('docsTreeCliProblem', () => {
|
|
|
32
32
|
expect(docsTreeCliProblem({name: '@acme/kit'})).toContain(
|
|
33
33
|
'declares no @astryxdesign/cli peer',
|
|
34
34
|
);
|
|
35
|
+
// Stable releases: a canary built from main before its release reports
|
|
36
|
+
// the older version and reads every feature.
|
|
37
|
+
expect(docsTreeCliProblem({name: '@acme/kit'})).toContain(
|
|
38
|
+
'A stable CLI before 0.7.0 does not read the docs tree',
|
|
39
|
+
);
|
|
35
40
|
});
|
|
36
41
|
|
|
37
42
|
it.each(['^0.6.0', '^0.6.0 || >=0.7.0', '*', '>=0.6.3'])(
|
|
@@ -39,7 +44,7 @@ describe('docsTreeCliProblem', () => {
|
|
|
39
44
|
range => {
|
|
40
45
|
expect(
|
|
41
46
|
docsTreeCliProblem({peerDependencies: {'@astryxdesign/cli': range}}),
|
|
42
|
-
).toContain('admits a CLI
|
|
47
|
+
).toContain('admits a stable CLI before');
|
|
43
48
|
},
|
|
44
49
|
);
|
|
45
50
|
|
|
@@ -76,7 +81,7 @@ describe('replacesCliProblem', () => {
|
|
|
76
81
|
);
|
|
77
82
|
expect(
|
|
78
83
|
replacesCliProblem({peerDependencies: {'@astryxdesign/cli': '^0.6.0'}}),
|
|
79
|
-
).toContain('admits a CLI
|
|
84
|
+
).toContain('admits a stable CLI before');
|
|
80
85
|
expect(
|
|
81
86
|
replacesCliProblem({peerDependencies: {'@astryxdesign/cli': '>=0.7.0'}}),
|
|
82
87
|
).toBeNull();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file Contribution inventory for integration
|
|
4
|
+
* @file Contribution inventory for `astryx integration verify`.
|
|
5
5
|
*
|
|
6
6
|
* Enumerates the files and contribution identities an integration package
|
|
7
7
|
* declares, for cross-referencing against the npm tarball. The file inventory
|
|
@@ -45,7 +45,7 @@ export function findManifestPaths(dir: string): string[];
|
|
|
45
45
|
* @param {string} file absolute manifest path
|
|
46
46
|
* @param {string} [label] used in error messages
|
|
47
47
|
* @param {{fresh?: boolean}} [options]
|
|
48
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, agentDocsError?: string}>}
|
|
48
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string}>}
|
|
49
49
|
*/
|
|
50
50
|
export function loadManifest(file: string, label?: string, { fresh }?: {
|
|
51
51
|
fresh?: boolean;
|
|
@@ -55,6 +55,8 @@ export function loadManifest(file: string, label?: string, { fresh }?: {
|
|
|
55
55
|
debug?: import("../../authoring/debug/type").DebugEventHandler;
|
|
56
56
|
gapReport?: import("../../authoring/gap-report/type").GapReportHandler;
|
|
57
57
|
gapReportError?: string;
|
|
58
|
+
discover?: import("../../authoring/discover/type").DiscoverSource;
|
|
59
|
+
discoverError?: string;
|
|
58
60
|
agentDocsError?: string;
|
|
59
61
|
}>;
|
|
60
62
|
/**
|
|
@@ -154,6 +156,9 @@ export function loadIntegrations(specs?: string[], { cwd, fresh, resolveProvider
|
|
|
154
156
|
* validated package-owned handler from the `gapReport` NAMED export.
|
|
155
157
|
* @property {string} [__gapReportError] isolated named-handler validation error.
|
|
156
158
|
* Named exports are not manifest keys — see {@link loadManifest}.
|
|
159
|
+
* @property {import('../../authoring/discover/type').DiscoverSource} [__discover]
|
|
160
|
+
* validated catalog source from the `discover` NAMED export.
|
|
161
|
+
* @property {string} [__discoverError] isolated discover-source validation error.
|
|
157
162
|
*/
|
|
158
163
|
/** Conventional manifest basenames, in load-precedence order. */
|
|
159
164
|
export const MANIFEST_BASENAMES: string[];
|
|
@@ -245,4 +250,12 @@ export type LoadedIntegration = {
|
|
|
245
250
|
* Named exports are not manifest keys — see {@link loadManifest}.
|
|
246
251
|
*/
|
|
247
252
|
__gapReportError?: string | undefined;
|
|
253
|
+
/**
|
|
254
|
+
* validated catalog source from the `discover` NAMED export.
|
|
255
|
+
*/
|
|
256
|
+
__discover?: import("../../authoring/discover/type").DiscoverSource | undefined;
|
|
257
|
+
/**
|
|
258
|
+
* isolated discover-source validation error.
|
|
259
|
+
*/
|
|
260
|
+
__discoverError?: string | undefined;
|
|
248
261
|
};
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
} from '../../authoring/integration/schema.mjs';
|
|
30
30
|
import {importUserModule, findPresentFiles} from '../fs/module-loader.mjs';
|
|
31
31
|
import {parseGapReportHandler} from '../../authoring/gap-report/parse.mjs';
|
|
32
|
+
import {parseDiscoverSource} from '../../authoring/discover/parse.mjs';
|
|
32
33
|
import {resolveProviders} from './provider-resolution.mjs';
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -80,6 +81,9 @@ import {resolveProviders} from './provider-resolution.mjs';
|
|
|
80
81
|
* validated package-owned handler from the `gapReport` NAMED export.
|
|
81
82
|
* @property {string} [__gapReportError] isolated named-handler validation error.
|
|
82
83
|
* Named exports are not manifest keys — see {@link loadManifest}.
|
|
84
|
+
* @property {import('../../authoring/discover/type').DiscoverSource} [__discover]
|
|
85
|
+
* validated catalog source from the `discover` NAMED export.
|
|
86
|
+
* @property {string} [__discoverError] isolated discover-source validation error.
|
|
83
87
|
*/
|
|
84
88
|
|
|
85
89
|
/** Conventional manifest basenames, in load-precedence order. */
|
|
@@ -167,6 +171,23 @@ function parseGapReportHandlerExport(value, label) {
|
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Parse the optional named discover source the same way: a malformed one is
|
|
176
|
+
* isolated from every other contribution and reported by `astryx discover`.
|
|
177
|
+
*
|
|
178
|
+
* @param {unknown} value
|
|
179
|
+
* @param {string} label
|
|
180
|
+
* @returns {{source?: import('../../authoring/discover/type').DiscoverSource, error?: string}}
|
|
181
|
+
*/
|
|
182
|
+
function parseDiscoverSourceExport(value, label) {
|
|
183
|
+
if (value === undefined) return {};
|
|
184
|
+
try {
|
|
185
|
+
return {source: parseDiscoverSource(value, `${label} named export "discover"`)};
|
|
186
|
+
} catch (error) {
|
|
187
|
+
return {error: error instanceof Error ? error.message : String(error)};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
170
191
|
/**
|
|
171
192
|
* Load and validate a manifest module's default export, while isolating the
|
|
172
193
|
* optional `agentDocs` contribution from the manifest's other fields.
|
|
@@ -183,7 +204,7 @@ function parseGapReportHandlerExport(value, label) {
|
|
|
183
204
|
* @param {string} file absolute manifest path
|
|
184
205
|
* @param {string} [label] used in error messages
|
|
185
206
|
* @param {{fresh?: boolean}} [options]
|
|
186
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, agentDocsError?: string}>}
|
|
207
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string}>}
|
|
187
208
|
*/
|
|
188
209
|
export async function loadManifest(
|
|
189
210
|
file,
|
|
@@ -194,6 +215,7 @@ export async function loadManifest(
|
|
|
194
215
|
const raw = mod?.default;
|
|
195
216
|
const baseManifest = parseIntegrationBase(raw, label);
|
|
196
217
|
const gapReport = parseGapReportHandlerExport(mod?.gapReport, label);
|
|
218
|
+
const discover = parseDiscoverSourceExport(mod?.discover, label);
|
|
197
219
|
const hasAgentDocs =
|
|
198
220
|
raw != null &&
|
|
199
221
|
typeof raw === 'object' &&
|
|
@@ -228,6 +250,8 @@ export async function loadManifest(
|
|
|
228
250
|
: undefined,
|
|
229
251
|
gapReport: gapReport.handler,
|
|
230
252
|
gapReportError: gapReport.error,
|
|
253
|
+
discover: discover.source,
|
|
254
|
+
discoverError: discover.error,
|
|
231
255
|
agentDocsError,
|
|
232
256
|
};
|
|
233
257
|
}
|
|
@@ -345,6 +369,10 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
345
369
|
let gapReportHandler;
|
|
346
370
|
/** @type {string | undefined} */
|
|
347
371
|
let gapReportError;
|
|
372
|
+
/** @type {import('../../authoring/discover/type').DiscoverSource | undefined} */
|
|
373
|
+
let discoverSource;
|
|
374
|
+
/** @type {string | undefined} */
|
|
375
|
+
let discoverError;
|
|
348
376
|
/** @type {string | undefined} */
|
|
349
377
|
let agentDocsError;
|
|
350
378
|
try {
|
|
@@ -354,6 +382,8 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
354
382
|
debug: debugHandler,
|
|
355
383
|
gapReport: gapReportHandler,
|
|
356
384
|
gapReportError,
|
|
385
|
+
discover: discoverSource,
|
|
386
|
+
discoverError,
|
|
357
387
|
agentDocsError,
|
|
358
388
|
} = await loadManifest(manifestFile, `Integration ${spec}`, {fresh}));
|
|
359
389
|
} catch (err) {
|
|
@@ -397,6 +427,8 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
397
427
|
__debug: debugHandler,
|
|
398
428
|
__gapReport: gapReportHandler,
|
|
399
429
|
__gapReportError: gapReportError,
|
|
430
|
+
__discover: discoverSource,
|
|
431
|
+
__discoverError: discoverError,
|
|
400
432
|
__spec: spec,
|
|
401
433
|
__packageDir: packageDir,
|
|
402
434
|
__packageExports: pkg.exports ?? null,
|
|
@@ -448,6 +480,10 @@ export async function loadIntegrations(
|
|
|
448
480
|
let gapReportHandler;
|
|
449
481
|
/** @type {string | undefined} */
|
|
450
482
|
let gapReportError;
|
|
483
|
+
/** @type {import('../../authoring/discover/type').DiscoverSource | undefined} */
|
|
484
|
+
let discoverSource;
|
|
485
|
+
/** @type {string | undefined} */
|
|
486
|
+
let discoverError;
|
|
451
487
|
/** @type {string | undefined} */
|
|
452
488
|
let agentDocsError;
|
|
453
489
|
try {
|
|
@@ -457,6 +493,8 @@ export async function loadIntegrations(
|
|
|
457
493
|
debug: debugHandler,
|
|
458
494
|
gapReport: gapReportHandler,
|
|
459
495
|
gapReportError,
|
|
496
|
+
discover: discoverSource,
|
|
497
|
+
discoverError,
|
|
460
498
|
agentDocsError,
|
|
461
499
|
} = await loadManifest(manifestFile, `Integration ${spec}`, {fresh}));
|
|
462
500
|
} catch (err) {
|
|
@@ -507,6 +545,8 @@ export async function loadIntegrations(
|
|
|
507
545
|
__debug: debugHandler,
|
|
508
546
|
__gapReport: gapReportHandler,
|
|
509
547
|
__gapReportError: gapReportError,
|
|
548
|
+
__discover: discoverSource,
|
|
549
|
+
__discoverError: discoverError,
|
|
510
550
|
__spec: spec,
|
|
511
551
|
__packageDir: packageDir,
|
|
512
552
|
__packageExports: pkg.exports ?? null,
|
|
@@ -785,3 +785,34 @@ describe('the `gapReport` named export', () => {
|
|
|
785
785
|
expect(loaded.__unknownKeys).toEqual(['gapReport']);
|
|
786
786
|
});
|
|
787
787
|
});
|
|
788
|
+
|
|
789
|
+
describe('the `discover` named export', () => {
|
|
790
|
+
it('is carried out of the manifest module as __discover', async () => {
|
|
791
|
+
writeManifestPackage(tmpDir, {
|
|
792
|
+
body:
|
|
793
|
+
`export async function discover() { return {schemaVersion: 1}; }\n` +
|
|
794
|
+
`export default {issuesUrl: 'https://example.com/i'};\n`,
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
const [loaded] = await loadIntegrations(['@acme/widgets'], {cwd: tmpDir});
|
|
798
|
+
|
|
799
|
+
expect(typeof loaded.__discover).toBe('function');
|
|
800
|
+
expect(loaded.__discoverError).toBeUndefined();
|
|
801
|
+
expect(loaded.__unknownKeys).toEqual([]);
|
|
802
|
+
expect(loaded.issuesUrl).toBe('https://example.com/i');
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it('keeps the manifest and records why when the export is not a function', async () => {
|
|
806
|
+
writeManifestPackage(tmpDir, {
|
|
807
|
+
body:
|
|
808
|
+
`export const discover = {url: 'https://example.com/catalog.json'};\n` +
|
|
809
|
+
`export default {issuesUrl: 'https://example.com/i'};\n`,
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
const [loaded] = await loadIntegrations(['@acme/widgets'], {cwd: tmpDir});
|
|
813
|
+
|
|
814
|
+
expect(loaded.__discover).toBeUndefined();
|
|
815
|
+
expect(loaded.__discoverError).toContain('must be a function');
|
|
816
|
+
expect(loaded.issuesUrl).toBe('https://example.com/i');
|
|
817
|
+
});
|
|
818
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
* One complete row for an accepted selector.
|
|
6
|
+
*/
|
|
7
|
+
export type BatchRow<TResult, TCandidate> = ({
|
|
8
|
+
selector: string;
|
|
9
|
+
status: "found";
|
|
10
|
+
result: TResult;
|
|
11
|
+
} | {
|
|
12
|
+
selector: string;
|
|
13
|
+
status: "ambiguous";
|
|
14
|
+
code: string;
|
|
15
|
+
error: string;
|
|
16
|
+
candidates: TCandidate[];
|
|
17
|
+
} | {
|
|
18
|
+
selector: string;
|
|
19
|
+
status: "not_found" | "error";
|
|
20
|
+
code: string;
|
|
21
|
+
error: string;
|
|
22
|
+
suggestions?: import("./base").Suggestion[];
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* One ordered batch receipt inside the shared `{type, data}` success envelope.
|
|
26
|
+
*/
|
|
27
|
+
export type BatchResponse<TType extends string, TResult, TCandidate> = {
|
|
28
|
+
type: TType;
|
|
29
|
+
data: {
|
|
30
|
+
count: number;
|
|
31
|
+
results: BatchRow<TResult, TCandidate>[];
|
|
32
|
+
};
|
|
33
|
+
};
|