@astryxdesign/cli 0.6.3-canary.98a2e4e → 0.6.3-canary.9dbb6c1
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 +106 -73
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/build.doc.mjs +4 -3
- package/api/build/build.test.mjs +14 -3
- package/api/build/build.type.d.mts +36 -2
- package/api/build/build.type.mjs +25 -4
- package/api/build/help/help.d.mts +8 -5
- package/api/build/help/help.mjs +56 -6
- package/api/component/component.doc.mjs +13 -3
- package/api/component/component.mjs +31 -2
- package/api/component/component.test.mjs +38 -0
- package/api/component/component.type.d.mts +22 -11
- package/api/component/component.type.mjs +32 -24
- package/api/component/detail/blocks/blocks.d.mts +2 -1
- package/api/component/detail/blocks/blocks.mjs +4 -3
- package/api/component/list/list.d.mts +0 -5
- package/api/component/list/list.mjs +37 -9
- package/api/discover/discover.doc.mjs +2 -1
- package/api/discover/discover.type.d.mts +4 -4
- package/api/discover/discover.type.mjs +10 -10
- package/api/docs/_adapter.d.mts +28 -30
- package/api/docs/_adapter.mjs +73 -135
- package/api/docs/compiled-topics.test.mjs +78 -0
- package/api/docs/detail/detail.d.mts +0 -15
- package/api/docs/detail/detail.mjs +14 -78
- package/api/docs/detail/section/section.mjs +22 -18
- package/api/docs/detail/section/section.test.mjs +4 -3
- package/api/docs/docs.doc.mjs +1 -0
- package/api/docs/docs.type.d.mts +4 -4
- package/api/docs/docs.type.mjs +10 -10
- package/api/docs/index/index.mjs +6 -5
- package/api/docs/list/list.mjs +3 -7
- package/api/doctor/doctor.d.mts +25 -3
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +186 -18
- package/api/doctor/doctor.test.mjs +326 -1
- package/api/gap-report/gap-report.doc.mjs +8 -4
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- 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/hook/list/list.mjs +69 -17
- package/api/init/init.doc.mjs +5 -0
- package/api/init/init.test.mjs +41 -1
- package/api/init/remove/remove.mjs +1 -1
- package/api/init/run/run.mjs +20 -10
- package/api/integration/add-contribution.component-names.test.mjs +120 -0
- package/api/integration/add-contribution.mjs +23 -10
- package/api/integration/add-contribution.test.mjs +121 -7
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.test.mjs +8 -4
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +8 -4
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +2 -1
- package/api/integration/integrationAddDoc.doc.mjs +1 -0
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +1 -0
- package/api/integration/integrationPackCheck.doc.mjs +1 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +1 -0
- package/api/integration/pack-check.mjs +49 -7
- package/api/integration/pack-check.test.mjs +266 -47
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +52 -102
- package/api/integration/validate-integration.test.mjs +176 -23
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +2 -1
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/envelope-types.test.mjs +76 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +3 -2
- package/api/layout/expand/expand.mjs +7 -5
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.mjs +2 -1
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +2 -1
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search-return-type.test.mjs +54 -0
- package/api/search/search.d.mts +2 -9
- package/api/search/search.doc.mjs +6 -1
- package/api/search/search.mjs +31 -14
- package/api/search/search.test.mjs +34 -0
- package/api/search/search.type.d.mts +1 -1
- package/api/search/search.type.mjs +1 -1
- package/api/swizzle/copy/copy.mjs +28 -11
- package/api/swizzle/swizzle.doc.mjs +2 -1
- package/api/swizzle/swizzle.type.d.mts +2 -2
- package/api/swizzle/swizzle.type.mjs +2 -2
- package/api/template/copy/copy.mjs +17 -23
- package/api/template/copy/copy.test.mjs +17 -0
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.doc.mjs +3 -1
- package/api/template/template.type.d.mts +5 -5
- package/api/template/template.type.mjs +12 -12
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +84 -0
- package/api/theme/add/add.mjs +20 -3
- package/api/theme/add/add.staging.test.mjs +66 -0
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/build/build.mjs +133 -42
- package/api/theme/build/build.public-component-vars.test.mjs +1 -1
- package/api/theme/build/build.receipt-doc.test.mjs +111 -0
- package/api/theme/build/build.test.mjs +127 -0
- package/api/theme/build/font-warning.mjs +3 -3
- package/api/theme/build/font-warning.test.mjs +5 -2
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/palette/generate/generate.mjs +8 -3
- package/api/theme/palette/generate/generate.test.mjs +96 -0
- package/api/theme/palette/generate/generator.d.mts +10 -13
- package/api/theme/palette/generate/generator.mjs +15 -4
- package/api/theme/palette/generate/generator.test.mjs +10 -0
- package/api/theme/template/template.mjs +11 -2
- package/api/theme/template/template.test.mjs +15 -0
- package/api/theme/theme.type.d.mts +170 -11
- package/api/theme/theme.type.mjs +94 -27
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +8 -4
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +5 -1
- package/api/upgrade/_adapter.d.mts +12 -3
- package/api/upgrade/_adapter.mjs +108 -70
- package/api/upgrade/list/list.mjs +2 -1
- package/api/upgrade/list/list.test.mjs +73 -0
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +1 -0
- package/api/upgrade/status/status.mjs +2 -2
- package/api/upgrade/upgrade.doc.mjs +3 -1
- package/api/upgrade/upgrade.type.d.mts +8 -4
- package/api/upgrade/upgrade.type.mjs +11 -10
- package/assets/codemods/integration-discovery.mjs +48 -4
- package/assets/codemods/integration-discovery.test.mjs +73 -0
- package/assets/codemods/runner.mjs +115 -5
- package/assets/codemods/term-log.mjs +32 -8
- package/assets/codemods/term-log.test.mjs +19 -1
- package/assets/codemods/transform-prop.mjs +109 -0
- package/assets/codemods/transform-prop.test.mjs +95 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +216 -0
- package/assets/codemods/transforms/next/index.mjs +11 -1
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
- package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
- package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
- package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
- package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
- package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
- package/assets/docs/cli-integrations.doc.mjs +26 -30
- package/assets/docs/cli.doc.mjs +15 -0
- package/assets/docs/styling-libraries.doc.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/working-with-ai.doc.mjs +1 -1
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
- package/assets/templates/pages/table-tree/page.tsx +1704 -0
- package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/_shared/contract.ts +22 -0
- package/authoring/codemod/codemod.doc.mjs +7 -2
- package/authoring/codemod/parse.d.mts +8 -8
- package/authoring/codemod/parse.mjs +8 -6
- package/authoring/config/config.doc.mjs +2 -2
- package/authoring/config/debug-composition.test.mjs +92 -0
- package/authoring/config/parse.d.mts +13 -13
- package/authoring/config/parse.mjs +8 -8
- package/authoring/config/type.ts +18 -6
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +4 -4
- package/authoring/debug/parse.mjs +3 -3
- package/authoring/doctypes/_schema.d.mts +121 -11
- package/authoring/doctypes/_schema.mjs +144 -13
- package/authoring/doctypes/base/graph-fields.doc.mjs +11 -4
- package/authoring/doctypes/base/type.ts +8 -4
- package/authoring/doctypes/command/command.doc.mjs +4 -3
- package/authoring/doctypes/command/parse.d.mts +2 -2
- package/authoring/doctypes/command/parse.mjs +1 -1
- package/authoring/doctypes/command/type.ts +3 -3
- package/authoring/doctypes/component/component.doc.mjs +5 -2
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +3 -3
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/parse.d.mts +2 -2
- package/authoring/doctypes/enum/parse.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +2 -2
- package/authoring/doctypes/function/function.doc.mjs +5 -1
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +2 -2
- package/authoring/doctypes/hook/hook.doc.mjs +4 -0
- package/authoring/doctypes/hook/parse.d.mts +2 -2
- package/authoring/doctypes/hook/parse.mjs +1 -1
- package/authoring/doctypes/hook/type.ts +3 -3
- package/authoring/doctypes/legacy.d.mts +6 -6
- package/authoring/doctypes/legacy.mjs +3 -3
- package/authoring/doctypes/load-contract.test.mjs +208 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -3
- package/authoring/doctypes/namespace/parse.d.mts +2 -2
- package/authoring/doctypes/namespace/parse.mjs +1 -1
- package/authoring/doctypes/namespace/type.ts +2 -2
- package/authoring/doctypes/parse.d.mts +22 -20
- package/authoring/doctypes/parse.mjs +16 -12
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +1 -1
- package/authoring/doctypes/reference/reference.doc.mjs +7 -3
- package/authoring/doctypes/reference/type.ts +3 -3
- package/authoring/doctypes/schema/parse.d.mts +2 -2
- package/authoring/doctypes/schema/parse.mjs +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +3 -4
- package/authoring/doctypes/template/parse.d.mts +92 -1
- package/authoring/doctypes/template/parse.mjs +33 -1
- package/authoring/doctypes/template/template.doc.mjs +7 -3
- package/authoring/doctypes/template/type.ts +4 -1
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +12 -11
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/gap-report/parse.d.mts +9 -9
- package/authoring/gap-report/parse.mjs +6 -6
- package/authoring/gap-report/type.ts +1 -1
- package/authoring/identity/identity.doc.mjs +3 -2
- package/authoring/identity/type.ts +10 -10
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +21 -19
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/schema.d.mts +4 -4
- package/authoring/integration/schema.mjs +3 -3
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/command-load-failure.test.mjs +83 -0
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/blog.mjs +23 -8
- package/clients/cli/commands/blog.test.mjs +42 -1
- package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
- package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
- package/clients/cli/commands/build-theme.mjs +5 -5
- package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
- package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
- package/clients/cli/commands/build.doc.mjs +5 -2
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
- package/clients/cli/commands/build.mjs +32 -47
- package/clients/cli/commands/build.playbook.test.mjs +75 -0
- package/clients/cli/commands/build.text-fields.test.mjs +40 -0
- package/clients/cli/commands/component/index.mjs +2 -7
- package/clients/cli/commands/component-package.test.mjs +46 -0
- package/clients/cli/commands/component-resolution.test.mjs +21 -0
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/component.test.mjs +19 -0
- package/clients/cli/commands/detail-levels.test.mjs +2 -2
- package/clients/cli/commands/discover.broken-integration.test.mjs +48 -0
- package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
- package/clients/cli/commands/discover.doc.mjs +5 -3
- package/clients/cli/commands/discover.mjs +3 -3
- package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
- package/clients/cli/commands/doctor-integration.test.mjs +15 -7
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +6 -16
- package/clients/cli/commands/doctor.test.mjs +42 -0
- package/clients/cli/commands/gap-report.doc.mjs +17 -6
- package/clients/cli/commands/gap-report.test.mjs +72 -0
- package/clients/cli/commands/hook/index.mjs +7 -17
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
- package/clients/cli/commands/init.doc.mjs +20 -9
- package/clients/cli/commands/init.flag-help.test.mjs +153 -0
- package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
- package/clients/cli/commands/integration-add.doc.mjs +22 -6
- package/clients/cli/commands/integration-authoring.test.mjs +13 -9
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/interactive-guard.test.mjs +101 -24
- package/clients/cli/commands/json-contract.test.mjs +33 -0
- package/clients/cli/commands/layout-check.doc.mjs +15 -4
- package/clients/cli/commands/layout-expand.doc.mjs +22 -5
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +3 -3
- package/clients/cli/commands/layout.mjs +21 -9
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
- package/clients/cli/commands/search.doc.mjs +7 -4
- package/clients/cli/commands/search.mjs +17 -7
- package/clients/cli/commands/search.test.mjs +75 -0
- package/clients/cli/commands/swizzle.doc.mjs +3 -2
- package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
- package/clients/cli/commands/template.doc.mjs +29 -7
- package/clients/cli/commands/template.flag-help.test.mjs +117 -0
- package/clients/cli/commands/template.path-help.test.mjs +40 -0
- package/clients/cli/commands/theme-add.doc.mjs +4 -3
- package/clients/cli/commands/theme-build.doc.mjs +8 -7
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
- package/clients/cli/commands/theme-template.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
- package/clients/cli/commands/upgrade.doc.mjs +18 -7
- package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
- package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
- package/clients/cli/index.mjs +13 -30
- package/clients/cli/latest-version-env.test.mjs +50 -0
- package/clients/cli/lib/cli-error.test.mjs +7 -0
- package/clients/cli/lib/component-format.mjs +9 -9
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +32 -6
- package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
- package/clients/cli/lib/exit-codes.test.mjs +97 -0
- package/clients/cli/lib/hook-format.mjs +19 -10
- package/clients/cli/lib/json-shim.mjs +38 -2
- package/clients/cli/lib/json-shim.test.mjs +83 -0
- package/clients/cli/lib/manifest.d.ts +2 -0
- package/clients/cli/lib/manifest.mjs +22 -0
- package/clients/cli/lib/manifest.test.mjs +17 -0
- package/foundation/agent-docs/agent-docs.d.mts +4 -0
- package/foundation/agent-docs/agent-docs.mjs +69 -3
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
- package/foundation/config/integration-debug.test.mjs +28 -3
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +8 -0
- package/foundation/config/project.mjs +173 -30
- package/foundation/config/project.test.mjs +129 -16
- package/foundation/discovery/authoring-self-docs.d.mts +6 -0
- package/foundation/discovery/authoring-self-docs.mjs +17 -7
- package/foundation/discovery/authoring-self-docs.test.mjs +71 -12
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +113 -0
- package/foundation/discovery/cli-self-docs.mjs +514 -0
- package/foundation/discovery/cli-self-docs.test.mjs +437 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +7 -2
- package/foundation/discovery/docs-discovery.mjs +24 -14
- package/foundation/discovery/docs-discovery.test.mjs +55 -16
- package/foundation/discovery/template-adapter.d.mts +21 -5
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
- package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
- package/foundation/discovery/template-adapter.mjs +319 -65
- package/foundation/discovery/template-adapter.test.mjs +15 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/discovery/theming-targets.test.mjs +4 -0
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +218 -0
- package/foundation/doc-compiler/bundle.test.mjs +255 -0
- package/foundation/doc-compiler/compile.d.mts +362 -0
- package/foundation/doc-compiler/compile.mjs +511 -0
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +277 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +286 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +22 -0
- package/foundation/doc-compiler/ir.mjs +464 -0
- package/foundation/doc-compiler/lenses.d.mts +33 -0
- package/foundation/doc-compiler/lenses.mjs +127 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +492 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +126 -0
- package/foundation/doc-compiler/read.mjs +320 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/fs/module-loader.d.mts +1 -0
- package/foundation/fs/module-loader.mjs +50 -1
- package/foundation/fs/module-loader.stdout.test.mjs +332 -0
- package/foundation/fs/path-safety.d.mts +3 -2
- package/foundation/fs/path-safety.mjs +49 -19
- package/foundation/fs/path-safety.test.mjs +50 -0
- package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -52
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +1 -1
- package/foundation/integrations/contribution-inventory.mjs +17 -20
- package/foundation/integrations/contribution-inventory.test.mjs +67 -27
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.mjs +104 -10
- package/foundation/response/base.d.ts +8 -4
- package/foundation/response/error-codes.doc.mjs +3 -4
- package/foundation/response/error-codes.mjs +2 -2
- package/foundation/response/error-codes.test.mjs +83 -0
- package/foundation/response/json-contract.test.mjs +11 -0
- package/foundation/response/json.d.mts +4 -2
- package/foundation/response/json.mjs +8 -10
- package/foundation/response/response-types.doc.mjs +11 -11
- package/foundation/response/response-types.doc.test.mjs +158 -0
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.mjs +22 -10
- package/foundation/xle/expand.d.mts +2 -0
- package/foundation/xle/expand.mjs +3 -2
- package/foundation/xle/expand.test.mjs +54 -0
- package/package.json +9 -11
- package/assets/templates/themes/manifest.json +0 -95
- package/clients/cli/lib/update-check.mjs +0 -83
- package/clients/cli/lib/update-check.test.mjs +0 -137
- package/clients/cli/update-hint-commands.test.mjs +0 -54
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
* async). It does what loadConfig did — find the config sibling-of
|
|
16
16
|
* package.json, import + validate it, load the configured integrations —
|
|
17
17
|
* plus autolink the installed ones no config names, and self-resolve the
|
|
18
|
-
* package being authored when it carries a manifest.
|
|
18
|
+
* package being authored when it carries a manifest. Provider identity is
|
|
19
|
+
* resolved once over all three (see integrations/provider-resolution), and
|
|
20
|
+
* the ledger is kept for {@link providerLedgerOf}. Discovery is LAZY.
|
|
19
21
|
* - Discovery methods (components/templates/codemods/docs/themes) are MEMOIZED per
|
|
20
22
|
* instance (via the pluggable cache) and orchestrate the EXISTING discovery
|
|
21
23
|
* functions — Project never reimplements discovery.
|
|
@@ -38,9 +40,10 @@ import {parseConfig} from '../../authoring/config/parse.mjs';
|
|
|
38
40
|
import {
|
|
39
41
|
loadIntegrations,
|
|
40
42
|
loadLocalIntegration,
|
|
41
|
-
|
|
43
|
+
resolvePackageDir,
|
|
42
44
|
} from '../integrations/integrations.mjs';
|
|
43
|
-
import {
|
|
45
|
+
import {loadAutolinkCandidates} from '../integrations/autolink.mjs';
|
|
46
|
+
import {resolveProviders} from '../integrations/provider-resolution.mjs';
|
|
44
47
|
import {
|
|
45
48
|
setProject as setDebugProject,
|
|
46
49
|
setEventHandler as setDebugEventHandler,
|
|
@@ -95,6 +98,118 @@ function errorMessage(err) {
|
|
|
95
98
|
return message == null ? String(err) : String(message);
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Load the configured integrations one at a time, so a package that cannot
|
|
103
|
+
* load at all (not installed, no manifest, more than one manifest, not a bare
|
|
104
|
+
* name) becomes that entry's load-error marker instead of failing the project.
|
|
105
|
+
* @param {string[]} specs
|
|
106
|
+
* @param {{cwd: string, fresh: boolean}} options
|
|
107
|
+
* @returns {Promise<import('../integrations/integrations.mjs').LoadedIntegration[]>}
|
|
108
|
+
*/
|
|
109
|
+
async function loadConfiguredIntegrations(specs, {cwd, fresh}) {
|
|
110
|
+
/** @type {import('../integrations/integrations.mjs').LoadedIntegration[]} */
|
|
111
|
+
const loaded = [];
|
|
112
|
+
const seen = new Set();
|
|
113
|
+
for (const spec of specs) {
|
|
114
|
+
if (!spec || seen.has(spec)) continue;
|
|
115
|
+
seen.add(spec);
|
|
116
|
+
try {
|
|
117
|
+
loaded.push(
|
|
118
|
+
...(await loadIntegrations([spec], {
|
|
119
|
+
cwd,
|
|
120
|
+
fresh,
|
|
121
|
+
resolveProviders: false,
|
|
122
|
+
})),
|
|
123
|
+
);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
/** @type {string|undefined} */
|
|
126
|
+
let packageDir;
|
|
127
|
+
try {
|
|
128
|
+
packageDir = resolvePackageDir(spec, cwd);
|
|
129
|
+
} catch {
|
|
130
|
+
// Not a bare package name: there is no install location to record.
|
|
131
|
+
}
|
|
132
|
+
const pkg = packageDir ? readPackageJson(packageDir) : null;
|
|
133
|
+
loaded.push(
|
|
134
|
+
loadErrorMarker({
|
|
135
|
+
name: packageName(pkg) ?? spec,
|
|
136
|
+
version: pkg?.version,
|
|
137
|
+
spec,
|
|
138
|
+
packageDir,
|
|
139
|
+
err,
|
|
140
|
+
}),
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return loaded;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Resolve the package being authored. Every failure, including an unreadable
|
|
149
|
+
* package.json or more than one manifest, becomes its load-error marker.
|
|
150
|
+
* @param {string} projectDir
|
|
151
|
+
* @param {boolean} fresh
|
|
152
|
+
* @returns {Promise<import('../integrations/integrations.mjs').LoadedIntegration|null>}
|
|
153
|
+
*/
|
|
154
|
+
async function loadLocalIntegrationSafely(projectDir, fresh) {
|
|
155
|
+
try {
|
|
156
|
+
return await loadLocalIntegration(projectDir, {fresh});
|
|
157
|
+
} catch (err) {
|
|
158
|
+
const pkg = readPackageJson(projectDir);
|
|
159
|
+
const name = packageName(pkg) ?? '(local integration)';
|
|
160
|
+
return {
|
|
161
|
+
...loadErrorMarker({
|
|
162
|
+
name,
|
|
163
|
+
version: pkg?.version,
|
|
164
|
+
spec: name,
|
|
165
|
+
packageDir: projectDir,
|
|
166
|
+
err,
|
|
167
|
+
}),
|
|
168
|
+
__local: true,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* An inert entry for an integration that could not be loaded. It contributes
|
|
175
|
+
* nothing; Project reports its `__loadError` as the package's issue.
|
|
176
|
+
* @param {{name: string, version?: unknown, spec: string, packageDir?: string, err: unknown}} input
|
|
177
|
+
* @returns {import('../integrations/integrations.mjs').LoadedIntegration}
|
|
178
|
+
*/
|
|
179
|
+
function loadErrorMarker({name, version, spec, packageDir, err}) {
|
|
180
|
+
return /** @type {import('../integrations/integrations.mjs').LoadedIntegration} */ ({
|
|
181
|
+
name,
|
|
182
|
+
...(typeof version === 'string' ? {version} : {}),
|
|
183
|
+
__spec: spec,
|
|
184
|
+
...(packageDir ? {__packageDir: packageDir} : {}),
|
|
185
|
+
__loadError: errorMessage(err),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @param {Record<string, unknown>|null} pkg
|
|
191
|
+
* @returns {string|undefined}
|
|
192
|
+
*/
|
|
193
|
+
function packageName(pkg) {
|
|
194
|
+
const name = pkg?.name;
|
|
195
|
+
return typeof name === 'string' && name.length > 0 ? name : undefined;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @param {string} dir
|
|
200
|
+
* @returns {Record<string, unknown>|null}
|
|
201
|
+
*/
|
|
202
|
+
function readPackageJson(dir) {
|
|
203
|
+
try {
|
|
204
|
+
const pkg = JSON.parse(
|
|
205
|
+
fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'),
|
|
206
|
+
);
|
|
207
|
+
return pkg && typeof pkg === 'object' ? pkg : null;
|
|
208
|
+
} catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
98
213
|
/**
|
|
99
214
|
* An integration issue tagged with the owner package. The base
|
|
100
215
|
* {@link import('../integrations/issue').AstryxIntegrationIssue} fields plus the
|
|
@@ -147,13 +262,15 @@ function findPackageRoot(startDir) {
|
|
|
147
262
|
*
|
|
148
263
|
* This governs INHERITED handlers only. A project's own `debug` always runs.
|
|
149
264
|
*
|
|
150
|
-
*
|
|
265
|
+
* Read from the project root whether or not an astryx.config exists: an
|
|
266
|
+
* autolinked integration contributes a handler with no config at all.
|
|
267
|
+
*
|
|
268
|
+
* @param {string} projectDir directory holding the project's package.json
|
|
151
269
|
* @returns {boolean}
|
|
152
270
|
*/
|
|
153
|
-
function inheritsIntegrationDebug(
|
|
154
|
-
if (!configPath) return true;
|
|
271
|
+
function inheritsIntegrationDebug(projectDir) {
|
|
155
272
|
try {
|
|
156
|
-
const pkgPath = path.join(
|
|
273
|
+
const pkgPath = path.join(projectDir, 'package.json');
|
|
157
274
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
158
275
|
return pkg?.astryx?.inheritDebug !== false;
|
|
159
276
|
} catch {
|
|
@@ -182,6 +299,24 @@ export function findConfigPath(startDir = process.cwd()) {
|
|
|
182
299
|
return present.length === 1 ? present[0] : null;
|
|
183
300
|
}
|
|
184
301
|
|
|
302
|
+
/**
|
|
303
|
+
* The provider ledger each loaded Project resolved, kept off the class so it
|
|
304
|
+
* is not part of the Project API.
|
|
305
|
+
* @type {WeakMap<Project, import('../integrations/provider-resolution.mjs').ProviderLedger>}
|
|
306
|
+
*/
|
|
307
|
+
const PROVIDER_LEDGERS = new WeakMap();
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* The provider ledger a Project resolved at load: one outcome for every
|
|
311
|
+
* package directory configured, autolinked, or authored. Internal: upgrade
|
|
312
|
+
* resolves on top of it, and tests account for every candidate with it.
|
|
313
|
+
* @param {Project} project
|
|
314
|
+
* @returns {import('../integrations/provider-resolution.mjs').ProviderLedger}
|
|
315
|
+
*/
|
|
316
|
+
export function providerLedgerOf(project) {
|
|
317
|
+
return PROVIDER_LEDGERS.get(project) ?? new Map();
|
|
318
|
+
}
|
|
319
|
+
|
|
185
320
|
/**
|
|
186
321
|
* The single API for reading resolved project configuration. Construct via the
|
|
187
322
|
* async {@link Project.load} factory.
|
|
@@ -276,11 +411,10 @@ export class Project {
|
|
|
276
411
|
fresh,
|
|
277
412
|
});
|
|
278
413
|
integrations = config.integrations ?? [];
|
|
279
|
-
|
|
414
|
+
// Provider identity is resolved once, below, over the final set.
|
|
415
|
+
loadedIntegrations = await loadConfiguredIntegrations(integrations, {
|
|
280
416
|
cwd: projectDir,
|
|
281
417
|
fresh,
|
|
282
|
-
// Provider identity is resolved once, below, over the final set.
|
|
283
|
-
resolveProviders: false,
|
|
284
418
|
});
|
|
285
419
|
}
|
|
286
420
|
|
|
@@ -288,35 +422,42 @@ export class Project {
|
|
|
288
422
|
// This runs whether or not a config exists, because the projects it reaches
|
|
289
423
|
// are overwhelmingly the ones with no astryx.config at all: a scaffold adds
|
|
290
424
|
// the dependency and writes no config, and the integration then contributes
|
|
291
|
-
// nothing for want of a line nobody knew to write.
|
|
425
|
+
// nothing for want of a line nobody knew to write. Resolved AFTER the
|
|
292
426
|
// configured ones so an explicit entry keeps its position and its
|
|
293
427
|
// precedence in every discovery order.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
fresh,
|
|
300
|
-
})),
|
|
301
|
-
];
|
|
428
|
+
const autolinked = await loadAutolinkCandidates({
|
|
429
|
+
projectDir,
|
|
430
|
+
loaded: loadedIntegrations,
|
|
431
|
+
fresh,
|
|
432
|
+
});
|
|
302
433
|
|
|
303
434
|
// The package being authored is the one package that cannot install itself.
|
|
304
435
|
// When it carries a manifest, resolve its working bytes directly so every
|
|
305
436
|
// existing consumer command doubles as the author's preview. A local copy
|
|
306
437
|
// replaces the same installed package in place, preserving configured
|
|
307
438
|
// precedence while making the source being edited authoritative.
|
|
308
|
-
const localIntegration = await
|
|
309
|
-
if (localIntegration) {
|
|
310
|
-
const existing = loadedIntegrations.findIndex(
|
|
311
|
-
integration => integration.name === localIntegration.name,
|
|
312
|
-
);
|
|
313
|
-
if (existing === -1) loadedIntegrations.push(localIntegration);
|
|
314
|
-
else loadedIntegrations[existing] = localIntegration;
|
|
315
|
-
}
|
|
439
|
+
const localIntegration = await loadLocalIntegrationSafely(projectDir, fresh);
|
|
316
440
|
|
|
317
441
|
// Autolinked and local packages can claim a provider ID that a configured
|
|
318
442
|
// package already holds, so identity is resolved once over the final set.
|
|
319
|
-
|
|
443
|
+
const resolution = resolveProviders([
|
|
444
|
+
...loadedIntegrations.map(integration => ({
|
|
445
|
+
source: /** @type {const} */ ('configured'),
|
|
446
|
+
integration,
|
|
447
|
+
spec: integration.__spec,
|
|
448
|
+
})),
|
|
449
|
+
...autolinked,
|
|
450
|
+
...(localIntegration
|
|
451
|
+
? [
|
|
452
|
+
{
|
|
453
|
+
source: /** @type {const} */ ('local'),
|
|
454
|
+
integration: localIntegration,
|
|
455
|
+
spec: localIntegration.__spec,
|
|
456
|
+
},
|
|
457
|
+
]
|
|
458
|
+
: []),
|
|
459
|
+
]);
|
|
460
|
+
loadedIntegrations = resolution.integrations;
|
|
320
461
|
|
|
321
462
|
// The debug recorder resolves its settings synchronously, long before any
|
|
322
463
|
// command gets here, so this is where a project's `debug` block gets a
|
|
@@ -335,7 +476,7 @@ export class Project {
|
|
|
335
476
|
// because Project.load can run more than once in a process and appending
|
|
336
477
|
// would deliver twice.
|
|
337
478
|
setDebugIntegrationEventHandlers(
|
|
338
|
-
inheritsIntegrationDebug(
|
|
479
|
+
inheritsIntegrationDebug(projectDir)
|
|
339
480
|
? loadedIntegrations.map(integration => integration.__debug)
|
|
340
481
|
: [],
|
|
341
482
|
);
|
|
@@ -347,7 +488,7 @@ export class Project {
|
|
|
347
488
|
// Never let recording break config loading.
|
|
348
489
|
}
|
|
349
490
|
|
|
350
|
-
|
|
491
|
+
const project = new Project({
|
|
351
492
|
cwd,
|
|
352
493
|
configPath,
|
|
353
494
|
config,
|
|
@@ -356,6 +497,8 @@ export class Project {
|
|
|
356
497
|
cache: resolvedCache,
|
|
357
498
|
hash,
|
|
358
499
|
});
|
|
500
|
+
PROVIDER_LEDGERS.set(project, resolution.ledger);
|
|
501
|
+
return project;
|
|
359
502
|
}
|
|
360
503
|
|
|
361
504
|
/**
|
|
@@ -163,7 +163,7 @@ function scaffoldLocalPackage({name = '@acme/local'} = {}) {
|
|
|
163
163
|
|
|
164
164
|
fs.mkdirSync(path.join(tmpDir, 'templates'));
|
|
165
165
|
fs.writeFileSync(
|
|
166
|
-
path.join(tmpDir, 'templates', 'local-page.
|
|
166
|
+
path.join(tmpDir, 'templates', 'local-page.doc.mjs'),
|
|
167
167
|
`export default {type: 'page', name: 'Local page', description: 'Local page.'};\n`,
|
|
168
168
|
);
|
|
169
169
|
fs.writeFileSync(
|
|
@@ -181,21 +181,8 @@ function scaffoldLocalPackage({name = '@acme/local'} = {}) {
|
|
|
181
181
|
|
|
182
182
|
fs.mkdirSync(path.join(tmpDir, 'themes', 'ocean'), {recursive: true});
|
|
183
183
|
fs.writeFileSync(
|
|
184
|
-
path.join(tmpDir, 'themes', '
|
|
185
|
-
|
|
186
|
-
version: 1,
|
|
187
|
-
themes: [
|
|
188
|
-
{
|
|
189
|
-
slug: 'ocean',
|
|
190
|
-
displayName: 'Ocean',
|
|
191
|
-
description: 'Ocean theme.',
|
|
192
|
-
maintained: true,
|
|
193
|
-
entry: 'oceanTheme.ts',
|
|
194
|
-
exportName: 'oceanTheme',
|
|
195
|
-
files: ['oceanTheme.ts'],
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
}),
|
|
184
|
+
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.doc.mjs'),
|
|
185
|
+
`/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */\nexport default {type: 'theme', name: 'ocean', displayName: 'Ocean', description: 'Ocean theme.', maintained: true};\n`,
|
|
199
186
|
);
|
|
200
187
|
fs.writeFileSync(
|
|
201
188
|
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'),
|
|
@@ -515,6 +502,132 @@ describe('Project issues (skip + warn)', () => {
|
|
|
515
502
|
});
|
|
516
503
|
});
|
|
517
504
|
|
|
505
|
+
describe('Project loads each integration in isolation', () => {
|
|
506
|
+
/**
|
|
507
|
+
* Install a package under node_modules with the given root files.
|
|
508
|
+
* @param {string} name
|
|
509
|
+
* @param {string[]} manifests manifest basenames to write
|
|
510
|
+
*/
|
|
511
|
+
function installPackage(name, manifests) {
|
|
512
|
+
const dir = path.join(tmpDir, 'node_modules', ...name.split('/'));
|
|
513
|
+
fs.mkdirSync(dir, {recursive: true});
|
|
514
|
+
fs.writeFileSync(
|
|
515
|
+
path.join(dir, 'package.json'),
|
|
516
|
+
JSON.stringify({name, version: '1.0.0'}),
|
|
517
|
+
);
|
|
518
|
+
for (const file of manifests) {
|
|
519
|
+
fs.writeFileSync(path.join(dir, file), 'export default {};\n');
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/** @param {string[]} integrations */
|
|
524
|
+
function writeConfig(integrations) {
|
|
525
|
+
fs.writeFileSync(
|
|
526
|
+
path.join(tmpDir, 'astryx.config.mjs'),
|
|
527
|
+
`export default ${JSON.stringify({integrations})};\n`,
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** @param {Project} project */
|
|
532
|
+
async function widgetComponents(project) {
|
|
533
|
+
return (await project.components())
|
|
534
|
+
.filter(component => component.package === '@acme/widgets')
|
|
535
|
+
.map(component => component.name);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
it.each([
|
|
539
|
+
['is not installed', '@acme/broken', () => {}, /Install it first/],
|
|
540
|
+
[
|
|
541
|
+
'has no root manifest',
|
|
542
|
+
'@acme/broken',
|
|
543
|
+
() => installPackage('@acme/broken', []),
|
|
544
|
+
/no conventional root manifest/,
|
|
545
|
+
],
|
|
546
|
+
[
|
|
547
|
+
'has two root manifests',
|
|
548
|
+
'@acme/broken',
|
|
549
|
+
() =>
|
|
550
|
+
installPackage('@acme/broken', [
|
|
551
|
+
'astryx.integration.mjs',
|
|
552
|
+
'astryx.integration.js',
|
|
553
|
+
]),
|
|
554
|
+
/multiple root manifests/,
|
|
555
|
+
],
|
|
556
|
+
[
|
|
557
|
+
'is not a bare package name',
|
|
558
|
+
'../escape',
|
|
559
|
+
() => {},
|
|
560
|
+
/Invalid integration package name/,
|
|
561
|
+
],
|
|
562
|
+
])(
|
|
563
|
+
'keeps the others when a configured package %s',
|
|
564
|
+
async (_label, spec, install, message) => {
|
|
565
|
+
scaffold();
|
|
566
|
+
install();
|
|
567
|
+
writeConfig([spec, '@acme/widgets']);
|
|
568
|
+
|
|
569
|
+
const project = await Project.load(tmpDir);
|
|
570
|
+
|
|
571
|
+
expect(await widgetComponents(project)).toEqual(['Widget']);
|
|
572
|
+
expect(await project.issues()).toContainEqual(
|
|
573
|
+
expect.objectContaining({
|
|
574
|
+
package: spec,
|
|
575
|
+
code: 'integration_error',
|
|
576
|
+
message: expect.stringMatching(message),
|
|
577
|
+
}),
|
|
578
|
+
);
|
|
579
|
+
},
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
it('keeps configured integrations when the package being authored has two root manifests', async () => {
|
|
583
|
+
scaffold();
|
|
584
|
+
fs.writeFileSync(
|
|
585
|
+
path.join(tmpDir, 'package.json'),
|
|
586
|
+
JSON.stringify({name: '@acme/local', version: '1.0.0'}),
|
|
587
|
+
);
|
|
588
|
+
fs.writeFileSync(
|
|
589
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
590
|
+
'export default {};\n',
|
|
591
|
+
);
|
|
592
|
+
fs.writeFileSync(
|
|
593
|
+
path.join(tmpDir, 'astryx.integration.js'),
|
|
594
|
+
'export default {};\n',
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
const project = await Project.load(tmpDir);
|
|
598
|
+
|
|
599
|
+
expect(await widgetComponents(project)).toEqual(['Widget']);
|
|
600
|
+
expect(await project.issues()).toContainEqual(
|
|
601
|
+
expect.objectContaining({
|
|
602
|
+
package: '@acme/local',
|
|
603
|
+
code: 'integration_error',
|
|
604
|
+
message: expect.stringMatching(/multiple root manifests/),
|
|
605
|
+
}),
|
|
606
|
+
);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it('puts the package being authored at its configured position when the config names it', async () => {
|
|
610
|
+
scaffold();
|
|
611
|
+
scaffoldLocalPackage({name: '@acme/local'});
|
|
612
|
+
writeConfig(['@acme/local', '@acme/widgets']);
|
|
613
|
+
|
|
614
|
+
const project = await Project.load(tmpDir);
|
|
615
|
+
|
|
616
|
+
expect(
|
|
617
|
+
project.loadedIntegrations.map(integration => [
|
|
618
|
+
integration.name,
|
|
619
|
+
Boolean(integration.__local),
|
|
620
|
+
]),
|
|
621
|
+
).toEqual([
|
|
622
|
+
['@acme/local', true],
|
|
623
|
+
['@acme/widgets', false],
|
|
624
|
+
]);
|
|
625
|
+
expect(await project.issues()).not.toContainEqual(
|
|
626
|
+
expect.objectContaining({package: '@acme/local', code: 'integration_error'}),
|
|
627
|
+
);
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
|
|
518
631
|
describe('Project.issuesUrl routing', () => {
|
|
519
632
|
it('routes core to config.issuesUrl, falling back to the default', async () => {
|
|
520
633
|
scaffold({issuesUrl: 'https://example.com/core'});
|
|
@@ -24,6 +24,12 @@ export function loadAuthoringSelfDocs(sources?: string[], root?: string): Promis
|
|
|
24
24
|
error: string;
|
|
25
25
|
}[];
|
|
26
26
|
}>;
|
|
27
|
+
/**
|
|
28
|
+
* One self-doc as a topic section, keyed by the doc's own name.
|
|
29
|
+
* @param {any} doc
|
|
30
|
+
* @returns {import('../../authoring/doctypes/reference/type').ReferenceSection}
|
|
31
|
+
*/
|
|
32
|
+
export function selfDocSection(doc: any): import("../../authoring/doctypes/reference/type").ReferenceSection;
|
|
27
33
|
/**
|
|
28
34
|
* The `authoring` topic: one section per self-doc, in the order given.
|
|
29
35
|
* @param {any[]} docs
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
import * as fs from 'node:fs';
|
|
19
19
|
import * as path from 'node:path';
|
|
20
|
-
import {pathToFileURL} from 'node:url';
|
|
21
20
|
import {CLI_ROOT} from '../fs/paths.mjs';
|
|
21
|
+
import {readDocView} from '../doc-compiler/read.mjs';
|
|
22
22
|
import {
|
|
23
23
|
DOC_OUTPUT_BUDGET_BYTES,
|
|
24
24
|
oversizedDocSections,
|
|
@@ -31,6 +31,8 @@ export const AUTHORING_ROOT = path.join(CLI_ROOT, 'authoring');
|
|
|
31
31
|
export const AUTHORING_SELF_DOCS = [
|
|
32
32
|
'integration/integration.doc.mjs',
|
|
33
33
|
'config/config.doc.mjs',
|
|
34
|
+
'debug/debug.doc.mjs',
|
|
35
|
+
'gap-report/gap-report.doc.mjs',
|
|
34
36
|
'codemod/codemod.doc.mjs',
|
|
35
37
|
'identity/identity.doc.mjs',
|
|
36
38
|
'doctypes/base/graph-fields.doc.mjs',
|
|
@@ -43,6 +45,7 @@ export const AUTHORING_SELF_DOCS = [
|
|
|
43
45
|
'doctypes/reference/reference.doc.mjs',
|
|
44
46
|
'doctypes/schema/schema.doc.mjs',
|
|
45
47
|
'doctypes/template/template.doc.mjs',
|
|
48
|
+
'doctypes/theme/theme.doc.mjs',
|
|
46
49
|
];
|
|
47
50
|
|
|
48
51
|
/** Blocks a self-doc note may carry that a topic section can render. */
|
|
@@ -59,7 +62,8 @@ export function discoverAuthoringSelfDocSources(root = AUTHORING_ROOT) {
|
|
|
59
62
|
/** @param {string} dir */
|
|
60
63
|
const walk = dir => {
|
|
61
64
|
for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {
|
|
62
|
-
if (entry.name === 'node_modules' || entry.name.startsWith('__'))
|
|
65
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('__'))
|
|
66
|
+
continue;
|
|
63
67
|
const full = path.join(dir, entry.name);
|
|
64
68
|
if (entry.isDirectory()) walk(full);
|
|
65
69
|
else if (entry.name.endsWith('.doc.mjs')) {
|
|
@@ -86,9 +90,14 @@ export async function loadAuthoringSelfDocs(
|
|
|
86
90
|
const failed = [];
|
|
87
91
|
for (const source of sources) {
|
|
88
92
|
try {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
const doc = await readDocView(path.join(root, source), {
|
|
94
|
+
root: 'self-docs',
|
|
95
|
+
loader: 'native',
|
|
96
|
+
});
|
|
97
|
+
if (
|
|
98
|
+
typeof doc?.name !== 'string' ||
|
|
99
|
+
typeof doc?.description !== 'string'
|
|
100
|
+
) {
|
|
92
101
|
throw new Error('exports no doc with a name and a description');
|
|
93
102
|
}
|
|
94
103
|
loaded.push({source, doc});
|
|
@@ -129,7 +138,7 @@ function fieldRows(fields) {
|
|
|
129
138
|
* @param {any} doc
|
|
130
139
|
* @returns {import('../../authoring/doctypes/reference/type').ReferenceSection}
|
|
131
140
|
*/
|
|
132
|
-
function selfDocSection(doc) {
|
|
141
|
+
export function selfDocSection(doc) {
|
|
133
142
|
/** @type {any[]} */
|
|
134
143
|
const content = [{type: 'prose', text: doc.description}];
|
|
135
144
|
if (doc.appliesTo) {
|
|
@@ -144,7 +153,8 @@ function selfDocSection(doc) {
|
|
|
144
153
|
});
|
|
145
154
|
}
|
|
146
155
|
for (const example of doc.examples ?? []) {
|
|
147
|
-
if (typeof example?.code !== 'string' || example.code.trim() === '')
|
|
156
|
+
if (typeof example?.code !== 'string' || example.code.trim() === '')
|
|
157
|
+
continue;
|
|
148
158
|
content.push({
|
|
149
159
|
type: 'code',
|
|
150
160
|
lang: example.lang ?? 'js',
|
|
@@ -9,7 +9,14 @@ import {
|
|
|
9
9
|
buildAuthoringTopic,
|
|
10
10
|
discoverAuthoringSelfDocSources,
|
|
11
11
|
} from './authoring-self-docs.mjs';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
GRAPH_BLOCK_TYPES,
|
|
14
|
+
GRAPH_ONLY_FIELDS,
|
|
15
|
+
problemsInTopic,
|
|
16
|
+
} from './docs-discovery.mjs';
|
|
17
|
+
import {doc as graphFieldsDoc} from '../../authoring/doctypes/base/graph-fields.doc.mjs';
|
|
18
|
+
import {doc as namespaceDoc} from '../../authoring/doctypes/namespace/namespace.doc.mjs';
|
|
19
|
+
import {doc as referenceDoc} from '../../authoring/doctypes/reference/reference.doc.mjs';
|
|
13
20
|
import {docs} from '../../api/docs/docs.mjs';
|
|
14
21
|
|
|
15
22
|
const SLOW = 60_000;
|
|
@@ -37,14 +44,58 @@ describe('authoring self-docs', () => {
|
|
|
37
44
|
expect(topic.sections).toHaveLength(AUTHORING_SELF_DOCS.length);
|
|
38
45
|
});
|
|
39
46
|
|
|
40
|
-
it(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
it(
|
|
48
|
+
'is readable progressively through the docs API',
|
|
49
|
+
async () => {
|
|
50
|
+
const index = await docs('authoring', undefined, {index: true});
|
|
51
|
+
expect(index.type).toBe('docs.index');
|
|
52
|
+
expect(index.data.sections.map(s => s.id)).toContain('integration');
|
|
53
|
+
const section = await docs('authoring', 'integration');
|
|
54
|
+
expect(section.data.title).toBe('Astryx Integration');
|
|
55
|
+
expect(section.data.content.some(block => block.type === 'table')).toBe(
|
|
56
|
+
true,
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
SLOW,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('what the authoring docs say about the unbuilt docs graph', () => {
|
|
64
|
+
it('marks exactly the fields topic loading rejects as not read yet', () => {
|
|
65
|
+
const notReadYet = graphFieldsDoc.fields
|
|
66
|
+
.filter(field => /Not read yet/.test(field.description))
|
|
67
|
+
.map(field => field.name);
|
|
68
|
+
expect(notReadYet.sort()).toEqual([...GRAPH_ONLY_FIELDS].sort());
|
|
69
|
+
for (const field of graphFieldsDoc.fields) {
|
|
70
|
+
if (notReadYet.includes(field.name)) {
|
|
71
|
+
expect(field.description).toMatch(/fails to load/);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
expect(graphFieldsDoc.description).toMatch(/not built yet/);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('says a topic using a graph block fails to load', () => {
|
|
78
|
+
const content = referenceDoc.fields
|
|
79
|
+
.flatMap(field => [field, ...(field.fields ?? [])])
|
|
80
|
+
.find(field => field.name === 'sections[].content');
|
|
81
|
+
for (const type of GRAPH_BLOCK_TYPES) {
|
|
82
|
+
expect(content.description).toContain(type);
|
|
83
|
+
}
|
|
84
|
+
expect(content.description).toMatch(/fails to load/);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('says namespace docs are not loaded yet', () => {
|
|
88
|
+
expect(namespaceDoc.description).toMatch(/Not loaded yet/);
|
|
89
|
+
expect(
|
|
90
|
+
problemsInTopic({
|
|
91
|
+
...namespaceDoc.examples?.[0],
|
|
92
|
+
type: 'namespace',
|
|
93
|
+
name: 'x',
|
|
94
|
+
}),
|
|
95
|
+
).toEqual([
|
|
96
|
+
'"x" is a namespace doc. Only the docs graph reads namespace docs, and it is not built yet; remove this file from the docs directory.',
|
|
97
|
+
]);
|
|
98
|
+
});
|
|
48
99
|
});
|
|
49
100
|
|
|
50
101
|
describe('auditAuthoringSelfDocs', () => {
|
|
@@ -68,17 +119,25 @@ describe('auditAuthoringSelfDocs', () => {
|
|
|
68
119
|
path.join(root, 'kept', 'forgotten.doc.mjs'),
|
|
69
120
|
"export const doc = {name: 'forgotten', description: 'Not listed.'};\n",
|
|
70
121
|
);
|
|
71
|
-
const audit = await auditAuthoringSelfDocs({
|
|
122
|
+
const audit = await auditAuthoringSelfDocs({
|
|
123
|
+
root,
|
|
124
|
+
sources: ['kept/kept.doc.mjs'],
|
|
125
|
+
});
|
|
72
126
|
expect(audit.unreachable).toEqual(['kept/forgotten.doc.mjs']);
|
|
73
127
|
});
|
|
74
128
|
|
|
75
129
|
it('reports a self-doc that fails to load instead of throwing', async () => {
|
|
76
|
-
fs.writeFileSync(
|
|
130
|
+
fs.writeFileSync(
|
|
131
|
+
path.join(root, 'kept', 'broken.doc.mjs'),
|
|
132
|
+
'export const doc = {;\n',
|
|
133
|
+
);
|
|
77
134
|
const audit = await auditAuthoringSelfDocs({
|
|
78
135
|
root,
|
|
79
136
|
sources: ['kept/kept.doc.mjs', 'kept/broken.doc.mjs'],
|
|
80
137
|
});
|
|
81
|
-
expect(audit.failed.map(entry => entry.source)).toEqual([
|
|
138
|
+
expect(audit.failed.map(entry => entry.source)).toEqual([
|
|
139
|
+
'kept/broken.doc.mjs',
|
|
140
|
+
]);
|
|
82
141
|
expect(audit.sections).toBe(1);
|
|
83
142
|
});
|
|
84
143
|
|