@astryxdesign/cli 0.6.3 → 0.6.4-canary.10dd683
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 +194 -0
- package/README.md +117 -78
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/_adapter.d.mts +50 -0
- package/api/build/_adapter.mjs +60 -0
- package/api/build/build.doc.mjs +16 -9
- package/api/build/build.test.mjs +197 -8
- package/api/build/build.type.d.mts +91 -2
- package/api/build/build.type.mjs +52 -8
- package/api/build/help/help.d.mts +12 -5
- package/api/build/help/help.mjs +69 -6
- package/api/build/kit/kit.d.mts +4 -1
- package/api/build/kit/kit.mjs +165 -49
- package/api/build/kit/rank.d.mts +44 -0
- package/api/build/kit/rank.mjs +432 -0
- package/api/build/kit/rank.test.mjs +196 -0
- package/api/component/_adapter.d.mts +6 -12
- package/api/component/_adapter.mjs +20 -10
- package/api/component/component.doc.mjs +13 -3
- package/api/component/component.mjs +91 -14
- 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 +40 -11
- 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 +62 -18
- package/api/discover/discover.mjs +220 -36
- package/api/discover/discover.test.mjs +11 -2
- package/api/discover/discover.type.d.mts +150 -11
- package/api/discover/discover.type.mjs +107 -17
- 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 +272 -41
- package/api/docs/_adapter.mjs +985 -108
- package/api/docs/compiled-topics.test.mjs +78 -0
- package/api/docs/detail/detail.mjs +22 -63
- package/api/docs/detail/section/section.d.mts +1 -1
- package/api/docs/detail/section/section.mjs +54 -19
- package/api/docs/detail/section/section.test.mjs +50 -0
- package/api/docs/docs.d.mts +10 -3
- package/api/docs/docs.doc.mjs +55 -16
- package/api/docs/docs.mjs +53 -10
- package/api/docs/docs.test.mjs +164 -4
- package/api/docs/docs.type.d.mts +221 -5
- package/api/docs/docs.type.mjs +153 -11
- package/api/docs/index/index.d.mts +18 -0
- package/api/docs/index/index.mjs +40 -0
- package/api/docs/index/index.test.mjs +62 -0
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +114 -8
- package/api/docs/list/list.mjs +28 -12
- package/api/docs/node/node.d.mts +43 -0
- package/api/docs/node/node.mjs +192 -0
- package/api/docs/reference-blocks.test.mjs +406 -0
- package/api/doctor/doctor.d.mts +99 -1
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +548 -1
- package/api/doctor/doctor.test.mjs +610 -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 +2 -2
- package/api/hook/list/list.mjs +69 -17
- package/api/index.d.mts +1 -1
- package/api/index.mjs +1 -0
- package/api/init/init.doc.mjs +6 -1
- 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.d.mts +2 -1
- package/api/integration/add-contribution.mjs +130 -15
- package/api/integration/add-contribution.test.mjs +258 -7
- package/api/integration/add-helpers.d.mts +5 -2
- package/api/integration/add-helpers.mjs +36 -9
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.mjs +138 -28
- package/api/integration/authoring-checks.test.mjs +179 -7
- package/api/integration/authoring-checks.type.mjs +6 -1
- package/api/integration/integration-authoring.type.d.mts +3 -1
- package/api/integration/integration-authoring.type.mjs +2 -0
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +14 -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 +8 -1
- 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 +2 -1
- package/api/integration/integrationPackCheck.doc.mjs +2 -1
- package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
- package/api/integration/pack-check.mjs +83 -7
- package/api/integration/pack-check.test.mjs +387 -47
- package/api/integration/pack-check.type.d.mts +26 -2
- package/api/integration/pack-check.type.mjs +14 -1
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/template-conflict-compatibility.test.mjs +73 -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 +179 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +3 -2
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/envelope-types.test.mjs +76 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +3 -2
- package/api/layout/_adapter.mjs +20 -5
- 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 +62 -11
- package/api/search/search.doc.mjs +8 -2
- package/api/search/search.mjs +471 -83
- package/api/search/search.test.mjs +124 -1
- package/api/search/search.type.d.mts +15 -3
- package/api/search/search.type.mjs +5 -2
- 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/list/list.mjs +1 -0
- package/api/template/table-floating-bulk-actions.test.mjs +66 -0
- package/api/template/template-integration.test.mjs +1072 -3
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.d.mts +1 -1
- package/api/template/template.doc.mjs +30 -8
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +12 -14
- package/api/template/template.type.mjs +15 -14
- 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 +31 -22
- package/api/theme/add/add.rollback.test.mjs +158 -0
- package/api/theme/add/add.staging.test.mjs +83 -0
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/build/build.family.test.mjs +7 -12
- package/api/theme/build/build.mjs +140 -59
- 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.rollback.test.mjs +148 -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 +20 -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 +6 -2
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +139 -22
- package/api/upgrade/list/list.mjs +2 -1
- package/api/upgrade/list/list.test.mjs +73 -0
- package/api/upgrade/project-context.test.mjs +272 -0
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/status/status.mjs +2 -2
- package/api/upgrade/upgrade.doc.mjs +12 -5
- package/api/upgrade/upgrade.type.d.mts +43 -5
- package/api/upgrade/upgrade.type.mjs +27 -11
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +48 -4
- package/assets/codemods/integration-discovery.test.mjs +73 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- 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/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/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
- package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/docs/README.md +9 -0
- package/assets/docs/authoring.doc.mjs +14 -0
- package/assets/docs/getting-started.doc.mjs +2 -2
- package/assets/docs/internationalization.doc.mjs +7 -5
- package/assets/docs/layout.doc.dense.mjs +2 -2
- package/assets/docs/layout.doc.mjs +1 -1
- package/assets/docs/principles.doc.mjs +6 -6
- package/assets/docs/styling-libraries.doc.mjs +4 -4
- package/assets/docs/styling.doc.mjs +4 -4
- package/assets/docs/theme.doc.mjs +5 -5
- package/assets/docs/tokens.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +30 -0
- package/assets/docs/tree/cli.doc.mjs +23 -0
- package/assets/docs/tree/commands.doc.mjs +25 -0
- package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +144 -26
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/working-with-ai.doc.mjs +4 -4
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/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/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
- package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
- package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
- package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
- package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
- 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/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +10 -2
- package/authoring/config/debug-composition.test.mjs +92 -0
- package/authoring/config/parse.d.mts +15 -13
- package/authoring/config/parse.mjs +27 -8
- package/authoring/config/parse.test.mjs +8 -0
- package/authoring/config/type.ts +29 -6
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +8 -8
- package/authoring/debug/parse.mjs +3 -3
- 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 +790 -23
- package/authoring/doctypes/_schema.mjs +543 -39
- package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
- package/authoring/doctypes/base/type.ts +41 -0
- 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 +5 -4
- package/authoring/doctypes/component/component.doc.mjs +6 -3
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +6 -5
- 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 +4 -2
- package/authoring/doctypes/function/function.doc.mjs +7 -2
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +9 -4
- 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 +5 -4
- package/authoring/doctypes/legacy.d.mts +8 -6
- package/authoring/doctypes/legacy.mjs +5 -4
- package/authoring/doctypes/load-contract.test.mjs +233 -0
- package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
- package/authoring/doctypes/namespace/parse.d.mts +12 -0
- package/authoring/doctypes/namespace/parse.mjs +25 -0
- package/authoring/doctypes/namespace/parse.test.mjs +163 -0
- package/authoring/doctypes/namespace/type.ts +74 -0
- package/authoring/doctypes/parse.d.mts +22 -18
- package/authoring/doctypes/parse.mjs +22 -11
- package/authoring/doctypes/parse.test.mjs +77 -3
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +8 -5
- package/authoring/doctypes/reference/reference.doc.mjs +48 -6
- package/authoring/doctypes/reference/type.ts +70 -7
- 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 +4 -4
- package/authoring/doctypes/template/parse.d.mts +94 -1
- package/authoring/doctypes/template/parse.mjs +40 -2
- package/authoring/doctypes/template/parse.test.mjs +26 -2
- package/authoring/doctypes/template/template.doc.mjs +13 -3
- package/authoring/doctypes/template/type.ts +13 -2
- 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 -10
- 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 +10 -10
- package/authoring/gap-report/parse.mjs +6 -6
- package/authoring/gap-report/type.ts +1 -1
- package/authoring/identity/identity.doc.d.mts +9 -0
- package/authoring/identity/identity.doc.mjs +61 -0
- package/authoring/identity/type.ts +132 -0
- package/authoring/index.d.mts +3 -0
- package/authoring/index.d.ts +62 -17
- package/authoring/index.mjs +4 -1
- package/authoring/integration/integration.doc.mjs +15 -8
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/parse.test.mjs +10 -1
- package/authoring/integration/schema.d.mts +6 -4
- package/authoring/integration/schema.mjs +9 -3
- package/authoring/integration/type.ts +19 -8
- package/authoring/shadcn/receipt.d.mts +6 -6
- 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.adaptations.test.mjs +100 -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 +16 -50
- 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 +16 -8
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
- package/clients/cli/commands/build.mjs +137 -114
- package/clients/cli/commands/build.playbook.test.mjs +75 -0
- package/clients/cli/commands/build.text-fields.test.mjs +81 -0
- package/clients/cli/commands/component/index.mjs +3 -8
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- 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 +52 -5
- package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
- package/clients/cli/commands/discover.doc.mjs +55 -9
- package/clients/cli/commands/discover.mjs +393 -118
- package/clients/cli/commands/discover.sources.test.mjs +267 -0
- package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
- package/clients/cli/commands/docs.doc.mjs +28 -6
- package/clients/cli/commands/docs.mjs +240 -26
- package/clients/cli/commands/docs.test.mjs +193 -1
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
- 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 +90 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +59 -32
- 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 +32 -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/integration.mjs +1 -0
- 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 +28 -9
- package/clients/cli/commands/search.test.mjs +75 -0
- package/clients/cli/commands/setup-nudge.test.mjs +6 -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 +52 -13
- package/clients/cli/commands/template.flag-help.test.mjs +117 -0
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/template.path-help.test.mjs +40 -0
- package/clients/cli/commands/text-json-parity.test.mjs +719 -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 +9 -5
- 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.behavior.test.mjs +4 -3
- 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 +22 -10
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- 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/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +164 -1
- package/clients/cli/formatters/index.test.mjs +97 -0
- package/clients/cli/index.mjs +21 -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 +37 -2
- package/clients/cli/lib/manifest.test.mjs +17 -0
- package/foundation/agent-docs/agent-docs.d.mts +7 -2
- package/foundation/agent-docs/agent-docs.mjs +82 -12
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
- package/foundation/agent-docs/agent-docs.test.mjs +19 -1
- package/foundation/config/integration-debug.test.mjs +28 -3
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +263 -91
- package/foundation/config/project.test.mjs +270 -21
- package/foundation/discovery/authoring-self-docs.d.mts +87 -0
- package/foundation/discovery/authoring-self-docs.mjs +237 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +170 -0
- 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 +119 -0
- package/foundation/discovery/cli-self-docs.mjs +490 -0
- package/foundation/discovery/cli-self-docs.test.mjs +375 -0
- package/foundation/discovery/component-discovery.d.mts +39 -1
- package/foundation/discovery/component-discovery.mjs +50 -1
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +119 -11
- package/foundation/discovery/docs-discovery.mjs +423 -108
- package/foundation/discovery/docs-discovery.test.mjs +365 -20
- package/foundation/discovery/docs-output-budget.d.mts +28 -0
- package/foundation/discovery/docs-output-budget.mjs +50 -0
- package/foundation/discovery/docs-section-key.d.mts +116 -0
- package/foundation/discovery/docs-section-key.mjs +322 -0
- package/foundation/discovery/docs-section-key.test.mjs +246 -0
- package/foundation/discovery/template-adapter.d.mts +113 -11
- 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 +774 -83
- package/foundation/discovery/template-adapter.test.mjs +57 -0
- package/foundation/discovery/template-conflict-release.d.mts +13 -0
- package/foundation/discovery/template-conflict-release.mjs +40 -0
- package/foundation/discovery/template-conflict-release.test.mjs +40 -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 +278 -0
- package/foundation/doc-compiler/bundle.test.mjs +266 -0
- package/foundation/doc-compiler/compile.d.mts +343 -0
- package/foundation/doc-compiler/compile.mjs +558 -0
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +305 -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 +291 -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 +471 -0
- package/foundation/doc-compiler/lenses.d.mts +36 -0
- package/foundation/doc-compiler/lenses.mjs +173 -0
- package/foundation/doc-compiler/links.d.mts +162 -0
- package/foundation/doc-compiler/links.mjs +294 -0
- package/foundation/doc-compiler/links.test.mjs +192 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +495 -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 +127 -0
- package/foundation/doc-compiler/read.mjs +325 -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/doc-compiler/tree.d.mts +288 -0
- package/foundation/doc-compiler/tree.mjs +876 -0
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/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/identity/provider-identity.d.mts +90 -0
- package/foundation/identity/provider-identity.mjs +320 -0
- package/foundation/identity/provider-identity.test.mjs +254 -0
- package/foundation/identity/providers.d.mts +7 -0
- package/foundation/identity/providers.mjs +16 -0
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -45
- package/foundation/integrations/autolink.test.mjs +1 -1
- package/foundation/integrations/cli-requirement.d.mts +45 -0
- package/foundation/integrations/cli-requirement.mjs +154 -0
- package/foundation/integrations/cli-requirement.test.mjs +84 -0
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +3 -2
- package/foundation/integrations/contribution-inventory.mjs +27 -24
- package/foundation/integrations/contribution-inventory.test.mjs +86 -27
- package/foundation/integrations/integration-warnings.d.mts +9 -2
- package/foundation/integrations/integration-warnings.mjs +52 -21
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +63 -3
- package/foundation/integrations/integrations.mjs +122 -9
- package/foundation/integrations/integrations.test.mjs +415 -1
- package/foundation/integrations/provider-conflicts.test.mjs +125 -0
- 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.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +131 -29
- package/foundation/response/base.d.ts +8 -4
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +13 -4
- package/foundation/response/error-codes.mjs +8 -2
- package/foundation/response/error-codes.test.mjs +137 -10
- package/foundation/response/json-contract.test.mjs +57 -17
- package/foundation/response/json.d.mts +4 -2
- package/foundation/response/json.mjs +8 -10
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +41 -21
- package/foundation/response/response-types.doc.test.mjs +158 -0
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.d.mts +8 -0
- package/foundation/text/string-utils.mjs +40 -10
- package/foundation/xle/expand.d.mts +2 -0
- package/foundation/xle/expand.mjs +4 -3
- package/foundation/xle/expand.test.mjs +54 -0
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -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
|
@@ -33,8 +33,19 @@
|
|
|
33
33
|
|
|
34
34
|
import * as fs from 'node:fs';
|
|
35
35
|
import * as path from 'node:path';
|
|
36
|
-
import jscodeshift from 'jscodeshift';
|
|
37
36
|
import {assertWithin} from '../../foundation/fs/path-safety.mjs';
|
|
37
|
+
import {
|
|
38
|
+
THEME_SLUG_RE,
|
|
39
|
+
unreadThemeFolders,
|
|
40
|
+
} from '../../foundation/discovery/theme-discovery.mjs';
|
|
41
|
+
import {
|
|
42
|
+
createFixContext,
|
|
43
|
+
DOC_CANDIDATE_RE,
|
|
44
|
+
pathIsInside,
|
|
45
|
+
stampOf,
|
|
46
|
+
TEMPLATE_CANDIDATE_RE,
|
|
47
|
+
unreachableFix,
|
|
48
|
+
} from '../../foundation/integrations/contribution-fixes.mjs';
|
|
38
49
|
import {
|
|
39
50
|
findManifestPaths,
|
|
40
51
|
loadManifest,
|
|
@@ -90,106 +101,35 @@ const UNREACHABLE_SKIP_DIRS = new Set([
|
|
|
90
101
|
'.next',
|
|
91
102
|
'out',
|
|
92
103
|
]);
|
|
93
|
-
const DOC_CANDIDATE_RE = /\.doc\.(?:ts|mjs|js)$/u;
|
|
94
|
-
const TEMPLATE_CANDIDATE_RE = /\.template\.(?:ts|mjs|js)$/u;
|
|
95
|
-
const STATIC_DOC_TYPES = new Set(['component', 'generic', 'page', 'block']);
|
|
96
|
-
const STATIC_TEMPLATE_TYPES = new Set(['page', 'block']);
|
|
97
|
-
const j = jscodeshift.withParser('tsx');
|
|
98
|
-
|
|
99
|
-
/** @param {any} node @returns {any} */
|
|
100
|
-
function unwrapStaticExpression(node) {
|
|
101
|
-
let current = node;
|
|
102
|
-
while (
|
|
103
|
-
current &&
|
|
104
|
-
[
|
|
105
|
-
'TSSatisfiesExpression',
|
|
106
|
-
'TSAsExpression',
|
|
107
|
-
'TypeCastExpression',
|
|
108
|
-
'ParenthesizedExpression',
|
|
109
|
-
].includes(current.type)
|
|
110
|
-
) {
|
|
111
|
-
current = current.expression;
|
|
112
|
-
}
|
|
113
|
-
if (current?.type === 'CallExpression' && current.arguments.length > 0) {
|
|
114
|
-
current = unwrapStaticExpression(current.arguments[0]);
|
|
115
|
-
}
|
|
116
|
-
return current;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** @param {any} property @param {string} name */
|
|
120
|
-
function staticPropertyNamed(property, name) {
|
|
121
|
-
if (
|
|
122
|
-
!property ||
|
|
123
|
-
!['ObjectProperty', 'Property'].includes(property.type) ||
|
|
124
|
-
property.computed
|
|
125
|
-
) {
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
return (
|
|
129
|
-
(property.key?.type === 'Identifier' && property.key.name === name) ||
|
|
130
|
-
(['Literal', 'StringLiteral'].includes(property.key?.type) &&
|
|
131
|
-
property.key.value === name)
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
104
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* @param {
|
|
141
|
-
* @
|
|
105
|
+
* A warning for each folder under the themes root that holds modules but is
|
|
106
|
+
* not read as a theme. Either branch of its fix leaves nothing to warn about:
|
|
107
|
+
* the folder becomes a theme, or a dot-folder discovery skips.
|
|
108
|
+
* @param {string} packageDir
|
|
109
|
+
* @param {import('../../foundation/integrations/integrations.mjs').LoadedIntegration} loaded
|
|
110
|
+
* @returns {Issue[]}
|
|
142
111
|
*/
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.find(j.ExportNamedDeclaration)
|
|
159
|
-
.forEach((/** @type {any} */ exportPath) => {
|
|
160
|
-
const declaration = exportPath.value.declaration;
|
|
161
|
-
if (declaration?.type !== 'VariableDeclaration') return;
|
|
162
|
-
for (const declarator of declaration.declarations) {
|
|
163
|
-
if (
|
|
164
|
-
declarator.id?.type === 'Identifier' &&
|
|
165
|
-
declarator.id.name === 'docs'
|
|
166
|
-
) {
|
|
167
|
-
candidates.push(declarator.init);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
const allowedTypes = templateOnly ? STATIC_TEMPLATE_TYPES : STATIC_DOC_TYPES;
|
|
173
|
-
for (const candidate of candidates) {
|
|
174
|
-
const object = unwrapStaticExpression(candidate);
|
|
175
|
-
if (object?.type !== 'ObjectExpression') continue;
|
|
176
|
-
const typeProperty = object.properties.find((/** @type {any} */ property) =>
|
|
177
|
-
staticPropertyNamed(property, 'type'),
|
|
178
|
-
);
|
|
179
|
-
const value = unwrapStaticExpression(typeProperty?.value);
|
|
180
|
-
if (
|
|
181
|
-
['Literal', 'StringLiteral'].includes(value?.type) &&
|
|
182
|
-
allowedTypes.has(value.value)
|
|
183
|
-
) {
|
|
184
|
-
return true;
|
|
112
|
+
function unreadThemeFolderIssues(packageDir, loaded) {
|
|
113
|
+
const themes = /** @type {string} */ (loaded.themes);
|
|
114
|
+
return unreadThemeFolders(themes, {
|
|
115
|
+
packageDir,
|
|
116
|
+
packageName: loaded.name,
|
|
117
|
+
}).map(folder => {
|
|
118
|
+
const name = path.basename(folder);
|
|
119
|
+
const shown = `${path.relative(packageDir, folder).split(path.sep).join('/')}/`;
|
|
120
|
+
const hide = `rename it to .${name} so Astryx skips it`;
|
|
121
|
+
let fix;
|
|
122
|
+
if (THEME_SLUG_RE.test(name)) {
|
|
123
|
+
const stem = `${name.replace(/-([a-z0-9])/gu, (_, character) => character.toUpperCase())}Theme`;
|
|
124
|
+
fix = `if it is a theme, add ${stem}.ts and ${stem}.doc.mjs to it (\`astryx integration add theme ${name}\` writes both) and move its code into ${stem}.ts; if not, ${hide}.`;
|
|
125
|
+
} else {
|
|
126
|
+
fix = `${hide}; a theme folder needs a lower-kebab name.`;
|
|
185
127
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
function pathIsInside(candidate, root) {
|
|
192
|
-
return candidate === root || candidate.startsWith(`${root}${path.sep}`);
|
|
128
|
+
return warning(
|
|
129
|
+
'unread_theme_folder',
|
|
130
|
+
`Folder "${shown}" holds modules but no <name>Theme source or .doc.mjs descriptor, so Astryx does not read it as a theme. Fix: ${fix}`,
|
|
131
|
+
);
|
|
132
|
+
});
|
|
193
133
|
}
|
|
194
134
|
|
|
195
135
|
/**
|
|
@@ -214,6 +154,7 @@ async function findUnreachableContributionIssues(packageDir, loaded) {
|
|
|
214
154
|
);
|
|
215
155
|
/** @type {Issue[]} */
|
|
216
156
|
const issues = [];
|
|
157
|
+
const context = createFixContext(packageDir, loaded);
|
|
217
158
|
let scanned = 0;
|
|
218
159
|
let truncated = false;
|
|
219
160
|
|
|
@@ -237,13 +178,18 @@ async function findUnreachableContributionIssues(packageDir, loaded) {
|
|
|
237
178
|
truncated = true;
|
|
238
179
|
return;
|
|
239
180
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
181
|
+
if (
|
|
182
|
+
!TEMPLATE_CANDIDATE_RE.test(entry.name) &&
|
|
183
|
+
!DOC_CANDIDATE_RE.test(entry.name)
|
|
184
|
+
) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const stamp = stampOf(context, full);
|
|
188
|
+
if (stamp == null) continue;
|
|
243
189
|
issues.push(
|
|
244
190
|
warning(
|
|
245
191
|
'unreachable_contribution',
|
|
246
|
-
`Found contribution metadata "${path.relative(packageDir, full)}" outside every declared integration root, so it contributes nothing.
|
|
192
|
+
`Found contribution metadata "${path.relative(packageDir, full)}" outside every declared integration root, so it contributes nothing. ${unreachableFix(context, full, stamp)}`,
|
|
247
193
|
),
|
|
248
194
|
);
|
|
249
195
|
}
|
|
@@ -366,6 +312,8 @@ async function validateAtPackageDir(
|
|
|
366
312
|
// Roots + contribution checks are shared with validateLoadedIntegration so
|
|
367
313
|
// the everyday-command nudge runs the exact same validators.
|
|
368
314
|
issues.push(...(await validateLoadedIntegration(loaded)));
|
|
315
|
+
if (loaded.themes)
|
|
316
|
+
issues.push(...unreadThemeFolderIssues(packageDir, loaded));
|
|
369
317
|
if (scanUnreachable) {
|
|
370
318
|
issues.push(
|
|
371
319
|
...(await findUnreachableContributionIssues(packageDir, loaded)),
|
|
@@ -400,8 +348,10 @@ export async function validateLocalIntegration(cwd = process.cwd()) {
|
|
|
400
348
|
try {
|
|
401
349
|
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
402
350
|
} catch (err) {
|
|
351
|
+
// A null name means "no manifest here"; this package has one.
|
|
403
352
|
return {
|
|
404
353
|
found: true,
|
|
354
|
+
name: '(local package)',
|
|
405
355
|
manifestFile: manifests[0],
|
|
406
356
|
issues: [
|
|
407
357
|
error(
|
|
@@ -13,10 +13,16 @@ import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
|
13
13
|
import * as fs from 'node:fs';
|
|
14
14
|
import * as path from 'node:path';
|
|
15
15
|
import {
|
|
16
|
+
validateIntegration,
|
|
16
17
|
validateLocalIntegration,
|
|
17
18
|
validateInstalledIntegration,
|
|
18
19
|
summarizeIssues,
|
|
19
20
|
} from './validate-integration.mjs';
|
|
21
|
+
import {
|
|
22
|
+
integrationComponentConflicts,
|
|
23
|
+
integrationDocConflicts,
|
|
24
|
+
integrationTemplateConflicts,
|
|
25
|
+
} from './authoring-checks.mjs';
|
|
20
26
|
|
|
21
27
|
let tmpDir;
|
|
22
28
|
|
|
@@ -154,7 +160,7 @@ describe('validate-integration API', () => {
|
|
|
154
160
|
fs.mkdirSync(componentsDir);
|
|
155
161
|
fs.writeFileSync(
|
|
156
162
|
path.join(componentsDir, 'Widget.doc.mjs'),
|
|
157
|
-
`export default {name: 'Widget'};\n`,
|
|
163
|
+
`export default {name: 'Widget', props: []};\n`,
|
|
158
164
|
);
|
|
159
165
|
fs.writeFileSync(
|
|
160
166
|
path.join(componentsDir, 'Widget.tsx'),
|
|
@@ -187,6 +193,39 @@ describe('validate-integration API', () => {
|
|
|
187
193
|
expect(byCode(result.issues, 'invalid_codemod')).toHaveLength(1);
|
|
188
194
|
});
|
|
189
195
|
|
|
196
|
+
it('names a broken codemod of an installed package by its path inside the package', async () => {
|
|
197
|
+
const consumer = path.join(tmpDir, 'consumer');
|
|
198
|
+
fs.mkdirSync(consumer, {recursive: true});
|
|
199
|
+
fs.writeFileSync(
|
|
200
|
+
path.join(consumer, 'package.json'),
|
|
201
|
+
JSON.stringify({name: 'consumer'}),
|
|
202
|
+
);
|
|
203
|
+
const pkgDir = path.join(consumer, 'node_modules', '@acme', 'kit');
|
|
204
|
+
writePackage(pkgDir, {
|
|
205
|
+
name: '@acme/kit',
|
|
206
|
+
manifest: `export default { codemods: './codemods' };\n`,
|
|
207
|
+
});
|
|
208
|
+
fs.mkdirSync(path.join(pkgDir, 'codemods', '1.1.0'), {recursive: true});
|
|
209
|
+
fs.writeFileSync(
|
|
210
|
+
path.join(pkgDir, 'codemods', '1.1.0', 'no-default.mjs'),
|
|
211
|
+
'export const nope = 1;\n',
|
|
212
|
+
);
|
|
213
|
+
fs.writeFileSync(
|
|
214
|
+
path.join(pkgDir, 'codemods', 'stray.mjs'),
|
|
215
|
+
`export default {type: 'code', title: 'Stray', transform: file => file.source};\n`,
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const result = await validateInstalledIntegration('@acme/kit', consumer);
|
|
219
|
+
|
|
220
|
+
const [broken] = byCode(result.issues, 'invalid_codemod');
|
|
221
|
+
expect(broken.message).toContain('(codemods/1.1.0/no-default.mjs)');
|
|
222
|
+
const [stray] = byCode(result.issues, 'codemod_outside_version');
|
|
223
|
+
expect(stray.message).toContain('"codemods/stray.mjs"');
|
|
224
|
+
for (const issue of result.issues) {
|
|
225
|
+
expect(issue.message).not.toContain(tmpDir);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
190
229
|
it('flags a broken template as invalid_template error', async () => {
|
|
191
230
|
const pkgDir = path.join(tmpDir, 'pkg');
|
|
192
231
|
writePackage(pkgDir, {
|
|
@@ -204,33 +243,24 @@ describe('validate-integration API', () => {
|
|
|
204
243
|
expect(byCode(result.issues, 'invalid_template')).toHaveLength(1);
|
|
205
244
|
});
|
|
206
245
|
|
|
207
|
-
it('reports no errors for a valid source-theme
|
|
246
|
+
it('reports no errors for a valid source-theme descriptor', async () => {
|
|
208
247
|
const pkgDir = path.join(tmpDir, 'pkg');
|
|
209
248
|
writePackage(pkgDir, {
|
|
210
|
-
manifest: `export default { themes: './themes' }
|
|
249
|
+
manifest: `export default { themes: './themes' };
|
|
250
|
+
`,
|
|
211
251
|
});
|
|
212
252
|
const themeDir = path.join(pkgDir, 'themes', 'ocean');
|
|
213
253
|
fs.mkdirSync(themeDir, {recursive: true});
|
|
214
254
|
fs.writeFileSync(
|
|
215
|
-
path.join(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
{
|
|
220
|
-
slug: 'ocean',
|
|
221
|
-
displayName: 'Ocean',
|
|
222
|
-
description: 'Blue and calm.',
|
|
223
|
-
maintained: true,
|
|
224
|
-
entry: 'oceanTheme.ts',
|
|
225
|
-
exportName: 'oceanTheme',
|
|
226
|
-
files: ['oceanTheme.ts'],
|
|
227
|
-
},
|
|
228
|
-
],
|
|
229
|
-
}),
|
|
255
|
+
path.join(themeDir, 'oceanTheme.doc.mjs'),
|
|
256
|
+
`/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */
|
|
257
|
+
export default {type: 'theme', name: 'ocean', displayName: 'Ocean', description: 'Blue and calm.', maintained: true};
|
|
258
|
+
`,
|
|
230
259
|
);
|
|
231
260
|
fs.writeFileSync(
|
|
232
261
|
path.join(themeDir, 'oceanTheme.ts'),
|
|
233
|
-
`export const oceanTheme = {}
|
|
262
|
+
`export const oceanTheme = {};
|
|
263
|
+
`,
|
|
234
264
|
);
|
|
235
265
|
|
|
236
266
|
const result = await validateLocalIntegration(pkgDir);
|
|
@@ -238,13 +268,17 @@ describe('validate-integration API', () => {
|
|
|
238
268
|
expect(summarizeIssues(result.issues).errors).toBe(0);
|
|
239
269
|
});
|
|
240
270
|
|
|
241
|
-
it('flags an
|
|
271
|
+
it('flags an obsolete source-theme catalog as invalid_theme', async () => {
|
|
242
272
|
const pkgDir = path.join(tmpDir, 'pkg');
|
|
243
273
|
writePackage(pkgDir, {
|
|
244
|
-
manifest: `export default { themes: './themes' }
|
|
274
|
+
manifest: `export default { themes: './themes' };
|
|
275
|
+
`,
|
|
245
276
|
});
|
|
246
277
|
fs.mkdirSync(path.join(pkgDir, 'themes'), {recursive: true});
|
|
247
|
-
fs.writeFileSync(
|
|
278
|
+
fs.writeFileSync(
|
|
279
|
+
path.join(pkgDir, 'themes', 'manifest.json'),
|
|
280
|
+
'{"version":1}',
|
|
281
|
+
);
|
|
248
282
|
|
|
249
283
|
const result = await validateLocalIntegration(pkgDir);
|
|
250
284
|
expect(byCode(result.issues, 'invalid_theme')).toHaveLength(1);
|
|
@@ -269,6 +303,11 @@ describe('validate-integration API', () => {
|
|
|
269
303
|
message: expect.stringContaining('InvisibleWidget.doc.mjs'),
|
|
270
304
|
}),
|
|
271
305
|
]);
|
|
306
|
+
expect(
|
|
307
|
+
byCode(result.issues, 'source_without_component_doc')[0].message,
|
|
308
|
+
).toContain(
|
|
309
|
+
"Fix: add InvisibleWidget.doc.mjs beside it with type: 'component'",
|
|
310
|
+
);
|
|
272
311
|
});
|
|
273
312
|
|
|
274
313
|
it('reports codemods outside semver folders and invalid folder names', async () => {
|
|
@@ -284,8 +323,12 @@ describe('validate-integration API', () => {
|
|
|
284
323
|
|
|
285
324
|
const result = await validateLocalIntegration(pkgDir);
|
|
286
325
|
|
|
287
|
-
|
|
288
|
-
expect(
|
|
326
|
+
const [stray] = byCode(result.issues, 'codemod_outside_version');
|
|
327
|
+
expect(stray.message).toContain('"codemods/forgotten.mjs"');
|
|
328
|
+
expect(stray.message).toContain('codemods/1.2.0/forgotten.mjs');
|
|
329
|
+
expect(stray.message).not.toContain(tmpDir);
|
|
330
|
+
const [folder] = byCode(result.issues, 'invalid_codemod_version');
|
|
331
|
+
expect(folder.message).toContain('Fix: rename it');
|
|
289
332
|
});
|
|
290
333
|
|
|
291
334
|
it('warns about valid contribution metadata outside every declared root', async () => {
|
|
@@ -327,6 +370,31 @@ describe('validate-integration API', () => {
|
|
|
327
370
|
const unreachable = byCode(result.issues, 'unreachable_contribution');
|
|
328
371
|
expect(unreachable).toHaveLength(1);
|
|
329
372
|
expect(unreachable[0].message).toContain('src/orphan.doc.mjs');
|
|
373
|
+
// No docs root is declared, but src/ also holds a .doc.mjs that is not a
|
|
374
|
+
// topic, which a docs root at src/ would read too; so the fix moves it.
|
|
375
|
+
expect(unreachable[0].message).toContain(
|
|
376
|
+
"Fix: move it into docs/ and set `docs: './docs'` in astryx.integration.mjs.",
|
|
377
|
+
);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('names the root that reads misplaced metadata when one is declared', async () => {
|
|
381
|
+
const pkgDir = path.join(tmpDir, 'pkg');
|
|
382
|
+
writePackage(pkgDir, {
|
|
383
|
+
manifest: `export default { templates: './templates' };\n`,
|
|
384
|
+
});
|
|
385
|
+
fs.mkdirSync(path.join(pkgDir, 'templates'));
|
|
386
|
+
fs.mkdirSync(path.join(pkgDir, 'src', 'blocks'), {recursive: true});
|
|
387
|
+
fs.writeFileSync(
|
|
388
|
+
path.join(pkgDir, 'src', 'blocks', 'Carousel.doc.mjs'),
|
|
389
|
+
`export default {type: 'block', name: 'Carousel', displayName: 'Carousel', aspectRatio: 1};\n`,
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
const result = await validateLocalIntegration(pkgDir);
|
|
393
|
+
|
|
394
|
+
const [issue] = byCode(result.issues, 'unreachable_contribution');
|
|
395
|
+
expect(issue.message).toContain(
|
|
396
|
+
"Fix: move it under templates/ (the templates root), or set `templates: './src/blocks'` in astryx.integration.mjs.",
|
|
397
|
+
);
|
|
330
398
|
});
|
|
331
399
|
|
|
332
400
|
it('never executes unreachable metadata while diagnosing it', async () => {
|
|
@@ -417,7 +485,7 @@ describe('validate-integration API', () => {
|
|
|
417
485
|
fs.mkdirSync(cDir, {recursive: true});
|
|
418
486
|
fs.writeFileSync(
|
|
419
487
|
path.join(cDir, 'Widget.doc.mjs'),
|
|
420
|
-
`export default { name: 'Widget' };\n`,
|
|
488
|
+
`export default { type: 'component', name: 'Widget', props: [] };\n`,
|
|
421
489
|
);
|
|
422
490
|
fs.writeFileSync(
|
|
423
491
|
path.join(cDir, 'Widget.tsx'),
|
|
@@ -439,7 +507,7 @@ describe('validate-integration API', () => {
|
|
|
439
507
|
// Doc with no sibling Widget.tsx.
|
|
440
508
|
fs.writeFileSync(
|
|
441
509
|
path.join(cDir, 'Widget.doc.mjs'),
|
|
442
|
-
`export default { name: 'Widget' };\n`,
|
|
510
|
+
`export default { type: 'component', name: 'Widget', props: [] };\n`,
|
|
443
511
|
);
|
|
444
512
|
|
|
445
513
|
const result = await validateLocalIntegration(pkgDir);
|
|
@@ -472,3 +540,88 @@ describe('validate-integration API', () => {
|
|
|
472
540
|
expect(byCode(result.issues, 'invalid_package_spec')).toHaveLength(1);
|
|
473
541
|
});
|
|
474
542
|
});
|
|
543
|
+
|
|
544
|
+
describe('integration diagnostics are read-only', () => {
|
|
545
|
+
/** Every directory and file under `dir`, with file bytes. */
|
|
546
|
+
function snapshot(dir) {
|
|
547
|
+
/** @type {Record<string, string>} */
|
|
548
|
+
const entries = {};
|
|
549
|
+
/** @param {string} current */
|
|
550
|
+
const walk = current => {
|
|
551
|
+
for (const entry of fs.readdirSync(current, {withFileTypes: true})) {
|
|
552
|
+
const full = path.join(current, entry.name);
|
|
553
|
+
const key = path.relative(dir, full);
|
|
554
|
+
if (entry.isDirectory()) {
|
|
555
|
+
entries[`${key}/`] = '';
|
|
556
|
+
walk(full);
|
|
557
|
+
} else {
|
|
558
|
+
entries[key] = fs.readFileSync(full, 'base64');
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
walk(dir);
|
|
563
|
+
return entries;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/** A package with valid, broken, conflicting, and unreachable contributions. */
|
|
567
|
+
function writeDiagnosedPackage(dir) {
|
|
568
|
+
writePackage(dir, {
|
|
569
|
+
manifest:
|
|
570
|
+
"export default {\n components: './components',\n templates: './templates',\n docs: './docs',\n codemods: './gone',\n themes: './themes',\n};\n",
|
|
571
|
+
});
|
|
572
|
+
const write = (relative, contents) => {
|
|
573
|
+
fs.mkdirSync(path.dirname(path.join(dir, relative)), {recursive: true});
|
|
574
|
+
fs.writeFileSync(path.join(dir, relative), contents);
|
|
575
|
+
};
|
|
576
|
+
write(
|
|
577
|
+
'components/Card.doc.mjs',
|
|
578
|
+
"export default {type: 'component', name: 'Card', props: []};\n",
|
|
579
|
+
);
|
|
580
|
+
write('components/Card.tsx', 'export function Card() { return null; }\n');
|
|
581
|
+
write(
|
|
582
|
+
'components/Orphan.doc.mjs',
|
|
583
|
+
"export default {type: 'component', name: 'Orphan', props: []};\n",
|
|
584
|
+
);
|
|
585
|
+
write('templates/dash.doc.mjs', "export default {type: 'page', name: 'Dash'};\n");
|
|
586
|
+
write(
|
|
587
|
+
'docs/theme.doc.mjs',
|
|
588
|
+
"export default {type: 'generic', name: 'theme', title: 'Theme', description: 'x', sections: [{title: 'A', content: [{type: 'prose', text: 'x'}]}]};\n",
|
|
589
|
+
);
|
|
590
|
+
write('themes/manifest.json', '{"version": 1, "themes": [{"slug": 7}]}\n');
|
|
591
|
+
write(
|
|
592
|
+
'stray/Stray.doc.mjs',
|
|
593
|
+
"export default {type: 'component', name: 'Stray', props: []};\n",
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
it('leaves local and installed packages byte-for-byte unchanged', async () => {
|
|
598
|
+
const pkgDir = path.join(tmpDir, 'pkg');
|
|
599
|
+
writeDiagnosedPackage(pkgDir);
|
|
600
|
+
const consumer = path.join(tmpDir, 'consumer');
|
|
601
|
+
fs.mkdirSync(consumer, {recursive: true});
|
|
602
|
+
fs.writeFileSync(
|
|
603
|
+
path.join(consumer, 'package.json'),
|
|
604
|
+
JSON.stringify({name: 'consumer'}),
|
|
605
|
+
);
|
|
606
|
+
writeDiagnosedPackage(path.join(consumer, 'node_modules', '@acme', 'widgets'));
|
|
607
|
+
const before = {pkg: snapshot(pkgDir), consumer: snapshot(consumer)};
|
|
608
|
+
|
|
609
|
+
const local = await validateIntegration(undefined, {cwd: pkgDir});
|
|
610
|
+
const installed = await validateIntegration('@acme/widgets', {
|
|
611
|
+
cwd: consumer,
|
|
612
|
+
});
|
|
613
|
+
for (const [pkg, cwd] of [
|
|
614
|
+
[undefined, pkgDir],
|
|
615
|
+
['@acme/widgets', consumer],
|
|
616
|
+
]) {
|
|
617
|
+
await integrationTemplateConflicts(pkg, {cwd});
|
|
618
|
+
await integrationComponentConflicts(pkg, {cwd});
|
|
619
|
+
await integrationDocConflicts(pkg, {cwd});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
expect(summarizeIssues(local.data.issues).errors).toBeGreaterThan(0);
|
|
623
|
+
expect(byCode(local.data.issues, 'unreachable_contribution')).toHaveLength(1);
|
|
624
|
+
expect(summarizeIssues(installed.data.issues).errors).toBeGreaterThan(0);
|
|
625
|
+
expect({pkg: snapshot(pkgDir), consumer: snapshot(consumer)}).toEqual(before);
|
|
626
|
+
});
|
|
627
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file `doctor integration validate` warns about a folder under the themes
|
|
5
|
+
* root that holds modules but is not read as a theme, and both branches of
|
|
6
|
+
* its fix leave nothing to warn about.
|
|
7
|
+
*
|
|
8
|
+
* @input a local integration package with a themes root
|
|
9
|
+
* @output the unread_theme_folder warnings validation reports
|
|
10
|
+
* @position packages/cli/api/integration — validation regression tests
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import {validateLocalIntegration} from './validate-integration.mjs';
|
|
17
|
+
import {integrationAddTheme} from './add-theme.mjs';
|
|
18
|
+
|
|
19
|
+
let tmpDir;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-unread-theme-'));
|
|
23
|
+
fs.writeFileSync(
|
|
24
|
+
path.join(tmpDir, 'package.json'),
|
|
25
|
+
JSON.stringify({name: '@acme/kit', version: '1.0.0'}),
|
|
26
|
+
);
|
|
27
|
+
fs.writeFileSync(
|
|
28
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
29
|
+
"export default {themes: './themes'};\n",
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/** @param {Record<string, string>} files paths under themes/ */
|
|
38
|
+
function writeThemes(files) {
|
|
39
|
+
for (const [file, contents] of Object.entries(files)) {
|
|
40
|
+
const target = path.join(tmpDir, 'themes', file);
|
|
41
|
+
fs.mkdirSync(path.dirname(target), {recursive: true});
|
|
42
|
+
fs.writeFileSync(target, contents);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const OCEAN = {
|
|
47
|
+
'ocean/oceanTheme.doc.mjs':
|
|
48
|
+
"/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */\nexport default {type: 'theme', name: 'ocean', displayName: 'Ocean', description: 'Blue.', maintained: true};\n",
|
|
49
|
+
'ocean/oceanTheme.ts':
|
|
50
|
+
"import {blue} from '@acme/kit/themes/shared/palette';\nexport const oceanTheme = {blue};\n",
|
|
51
|
+
'shared/palette.ts': 'export const blue = 1;\n',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
async function unread() {
|
|
55
|
+
const {issues} = await validateLocalIntegration(tmpDir);
|
|
56
|
+
return issues.filter(issue => issue.code === 'unread_theme_folder');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe('unread theme folders', () => {
|
|
60
|
+
it('warns about each folder that looks like a theme but is not read as one', async () => {
|
|
61
|
+
writeThemes({
|
|
62
|
+
...OCEAN,
|
|
63
|
+
'sand/sand.ts': 'export const sand = {};\n',
|
|
64
|
+
'sand/sand.doc.ts': "export default {type: 'theme', name: 'sand'};\n",
|
|
65
|
+
'reef/index.ts': 'export const reefTheme = {};\n',
|
|
66
|
+
'Tide_Pool/index.ts': 'export const tide = {};\n',
|
|
67
|
+
'fonts/inter.woff2': 'x',
|
|
68
|
+
'utils/format.ts': 'export const format = String;\n',
|
|
69
|
+
'.cache/index.ts': 'export {};\n',
|
|
70
|
+
});
|
|
71
|
+
const issues = await unread();
|
|
72
|
+
expect(issues.map(issue => issue.severity)).toEqual([
|
|
73
|
+
'warning',
|
|
74
|
+
'warning',
|
|
75
|
+
'warning',
|
|
76
|
+
]);
|
|
77
|
+
expect(issues.map(issue => issue.message)).toEqual([
|
|
78
|
+
'Folder "themes/Tide_Pool/" holds modules but no <name>Theme source or .doc.mjs descriptor, so Astryx does not read it as a theme. Fix: rename it to .Tide_Pool so Astryx skips it; a theme folder needs a lower-kebab name.',
|
|
79
|
+
'Folder "themes/reef/" holds modules but no <name>Theme source or .doc.mjs descriptor, so Astryx does not read it as a theme. Fix: if it is a theme, add reefTheme.ts and reefTheme.doc.mjs to it (`astryx integration add theme reef` writes both) and move its code into reefTheme.ts; if not, rename it to .reef so Astryx skips it.',
|
|
80
|
+
'Folder "themes/sand/" holds modules but no <name>Theme source or .doc.mjs descriptor, so Astryx does not read it as a theme. Fix: if it is a theme, add sandTheme.ts and sandTheme.doc.mjs to it (`astryx integration add theme sand` writes both) and move its code into sandTheme.ts; if not, rename it to .sand so Astryx skips it.',
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('does not warn about a helper folder a module imports by a relative path', async () => {
|
|
85
|
+
writeThemes({
|
|
86
|
+
...OCEAN,
|
|
87
|
+
'index.ts':
|
|
88
|
+
"export * from './ocean/oceanTheme';\nexport * from './util';\n",
|
|
89
|
+
'util/index.ts': 'export const util = 1;\n',
|
|
90
|
+
});
|
|
91
|
+
expect(await unread()).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('holds when either branch of the fix is followed', async () => {
|
|
95
|
+
writeThemes({
|
|
96
|
+
...OCEAN,
|
|
97
|
+
'sand/sand.ts': 'export const sand = {};\n',
|
|
98
|
+
'reef/index.ts': 'export const reefTheme = {};\n',
|
|
99
|
+
'Tide_Pool/index.ts': 'export const tide = {};\n',
|
|
100
|
+
});
|
|
101
|
+
await integrationAddTheme('sand', {cwd: tmpDir});
|
|
102
|
+
await integrationAddTheme('reef', {cwd: tmpDir});
|
|
103
|
+
fs.renameSync(
|
|
104
|
+
path.join(tmpDir, 'themes', 'Tide_Pool'),
|
|
105
|
+
path.join(tmpDir, 'themes', '.Tide_Pool'),
|
|
106
|
+
);
|
|
107
|
+
const {issues} = await validateLocalIntegration(tmpDir);
|
|
108
|
+
expect(issues).toEqual([]);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -12,6 +12,7 @@ export const doc = {
|
|
|
12
12
|
type: 'function',
|
|
13
13
|
kind: 'api',
|
|
14
14
|
name: 'validateIntegration',
|
|
15
|
+
namespace: 'cli/api',
|
|
15
16
|
displayName: 'validateIntegration()',
|
|
16
17
|
summary:
|
|
17
18
|
'Validate a single Astryx integration package and report its issues.',
|
|
@@ -45,7 +46,7 @@ export const doc = {
|
|
|
45
46
|
{
|
|
46
47
|
type: 'integration.validate',
|
|
47
48
|
description:
|
|
48
|
-
'The result envelope: `data.name` and `data.version` of the validated package (both null when no local manifest is found), plus `data.issues`, an AstryxIntegrationIssue[] of {code, severity: `warning` | `error`, message}.',
|
|
49
|
+
'The result envelope: `data.name` and `data.version` of the validated package (both null only when no local manifest is found; `data.name` is `(local package)` when the local package.json has no readable name), plus `data.issues`, an AstryxIntegrationIssue[] of {code, severity: `warning` | `error`, message}.',
|
|
49
50
|
},
|
|
50
51
|
],
|
|
51
52
|
examples: [
|
|
@@ -59,5 +60,5 @@ export const doc = {
|
|
|
59
60
|
},
|
|
60
61
|
],
|
|
61
62
|
command: 'doctor integration validate',
|
|
62
|
-
related: ['summarizeIssues', '
|
|
63
|
+
related: ['summarizeIssues', 'integrationTemplateConflicts', 'upgrade'],
|
|
63
64
|
};
|