@astryxdesign/cli 0.1.8-canary.0c4d8d7 → 0.1.8-canary.0db5dfd
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/{src/api → api/blog}/blog.mjs +42 -6
- package/{src/api → api/blog}/blog.test.mjs +2 -2
- package/api/build/build.mjs +92 -0
- package/api/build/build.test.mjs +92 -0
- package/{src/api → api/component}/component.mjs +49 -26
- package/{src/api → api/discover}/discover.mjs +55 -18
- package/{src/api → api/docs}/docs.mjs +47 -21
- package/{src/api → api/doctor}/doctor.mjs +11 -8
- package/{src/api → api/hook}/hook.mjs +11 -11
- package/{src/api → api}/index.mjs +16 -9
- package/{src/api → api/integration}/validate-integration.mjs +48 -15
- package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
- package/{src/api → api/layout}/layout.mjs +66 -17
- package/{src/api → api/layout}/layout.test.mjs +1 -1
- package/{src/api → api/search}/search.mjs +71 -12
- package/api/swizzle/swizzle.mjs +283 -0
- package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
- package/{src/api → api/template}/template-integration.test.mjs +2 -2
- package/{src/api → api/template}/template-suffix.test.mjs +3 -3
- package/{src/api → api/template}/template.mjs +96 -19
- package/{src/api → api/theme}/theme-add.mjs +35 -7
- package/{src → authoring}/codemod.mjs +6 -6
- package/{src → authoring}/config.test.mjs +1 -1
- package/{src → authoring}/doc.mjs +1 -1
- package/{src → authoring}/doc.test.mjs +1 -1
- package/{src → authoring}/template.mjs +1 -1
- package/bin/astryx.mjs +12 -10
- package/{src → cli}/commands/blog.mjs +48 -7
- package/{src → cli}/commands/build-theme.mjs +125 -46
- package/{src → cli}/commands/build.mjs +33 -57
- package/{src → cli}/commands/component/index.mjs +49 -22
- package/{src → cli}/commands/component-ownership.test.mjs +3 -3
- package/{src → cli}/commands/component-package.test.mjs +1 -1
- package/{src → cli}/commands/component-resolution.test.mjs +2 -2
- package/{src → cli}/commands/discover.mjs +17 -8
- package/{src → cli}/commands/docs.mjs +39 -7
- package/{src → cli}/commands/docs.test.mjs +1 -1
- package/{src → cli}/commands/doctor.mjs +3 -3
- package/{src → cli}/commands/doctor.test.mjs +2 -2
- package/{src → cli}/commands/ensure-core-built.mjs +3 -2
- package/{src → cli}/commands/external-showcase.test.mjs +1 -1
- package/{src → cli}/commands/hook/index.mjs +37 -14
- package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
- package/{src → cli}/commands/init.mjs +20 -9
- package/{src → cli}/commands/layout.mjs +58 -18
- package/{src → cli}/commands/search.mjs +19 -12
- package/{src → cli}/commands/search.test.mjs +1 -1
- package/{src → cli}/commands/setup-nudge.test.mjs +1 -1
- package/cli/commands/swizzle.mjs +103 -0
- package/{src → cli}/commands/template.mjs +73 -22
- package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
- package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
- package/{src → cli}/commands/upgrade.mjs +160 -52
- package/{src → cli}/commands/upgrade.test.mjs +1 -1
- package/{src → cli}/commands/validate-integration.mjs +17 -37
- package/{src → cli}/index.mjs +17 -15
- package/{src/codemods → codemods}/ensure-jscodeshift.mjs +1 -1
- package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
- package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
- package/{src/codemods → codemods}/integration-runner.mjs +8 -3
- package/{src/codemods → codemods}/registry.mjs +3 -1
- package/{src/codemods → codemods}/run-codemod.mjs +17 -10
- package/{src/codemods → codemods}/runner.mjs +22 -12
- package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
- package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
- package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +19 -14
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +16 -11
- package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
- package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
- package/{src/codemods → codemods}/transforms/v0.1.8/rename-avatar-size-scale.mjs +15 -10
- package/docs/internationalization.doc.mjs +92 -46
- package/{src/commands → lib/agent-docs}/agent-docs.mjs +30 -11
- package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
- package/{src/lib → lib}/component-discovery.mjs +44 -2
- package/{src/lib → lib}/component-format.mjs +65 -24
- package/{src/lib → lib}/component-loader.mjs +27 -13
- package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
- package/{src/lib → lib}/error-codes.test.mjs +1 -1
- package/{src/lib → lib}/hook-discovery.mjs +14 -1
- package/{src/lib → lib}/hook-format.mjs +29 -5
- package/{src/lib → lib}/integration-warnings.mjs +2 -2
- package/{src/lib → lib}/integrations.mjs +20 -0
- package/{src/lib → lib}/integrations.test.mjs +1 -1
- package/{src/lib → lib}/json-contract.test.mjs +1 -1
- package/{src/lib → lib}/json-shim.mjs +10 -5
- package/{src/lib → lib}/json-shim.test.mjs +1 -1
- package/{src/lib → lib}/levenshtein.mjs +6 -0
- package/{src/lib → lib}/manifest.mjs +7 -5
- package/{src/lib → lib}/manifest.test.mjs +2 -2
- package/{src/lib → lib}/module-loader.mjs +1 -0
- package/{src/lib → lib}/package-scanner.mjs +47 -0
- package/{src/lib → lib}/project.mjs +48 -18
- package/{src/lib → lib}/project.test.mjs +1 -1
- package/{src/lib → lib}/resolve-theme.mjs +5 -0
- package/{src/lib → lib}/string-utils.mjs +15 -0
- package/{src/lib → lib}/term-log.mjs +12 -3
- package/{src/lib → lib}/xle/browser.mjs +18 -8
- package/{src/lib → lib}/xle/expand.mjs +155 -22
- package/{src/lib → lib}/xle/parse.mjs +119 -13
- package/{src/lib → lib}/xle/print.mjs +54 -14
- package/{src/lib → lib}/xle/registry-core.mjs +28 -3
- package/{src/lib → lib}/xle/registry.mjs +9 -4
- package/{src/lib → lib}/xle/splice.mjs +13 -2
- package/{src/lib → lib}/xle/validate.mjs +95 -14
- package/lib/xle/xle-ast.d.ts +214 -0
- package/package.json +33 -26
- package/scripts/postinstall.mjs +4 -4
- package/templates/blocks/components/Avatar/AvatarShowcase.tsx +1 -1
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
- package/{src/types → types}/api.contract.assert.ts +17 -8
- package/{src/types → types}/api.d.ts +106 -0
- package/{src/types → types}/base.d.ts +17 -2
- package/types/build.d.ts +53 -0
- package/types/codemod.d.ts +166 -0
- package/{src/types → types}/component.d.ts +1 -1
- package/{src/types → types}/discover.d.ts +1 -1
- package/{src/types → types}/docs.d.ts +1 -4
- package/{src/types → types}/hook.d.ts +1 -1
- package/types/jscodeshift.d.ts +19 -0
- package/types/layout.d.ts +74 -0
- package/types/theme.d.ts +53 -0
- package/{src/types → types}/upgrade.d.ts +8 -1
- package/{src/utils → utils}/paths.mjs +4 -1
- package/src/commands/swizzle.mjs +0 -417
- package/src/types/build.d.ts +0 -23
- package/src/types/codemod.d.ts +0 -81
- package/src/types/theme.d.ts +0 -23
- /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
- /package/{src/api → api}/error.mjs +0 -0
- /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
- /package/{src/api → api/template}/template.test.mjs +0 -0
- /package/{src → authoring}/codemod.test.mjs +0 -0
- /package/{src → authoring}/config.mjs +0 -0
- /package/{src → authoring}/integration.mjs +0 -0
- /package/{src → authoring}/template.test.mjs +0 -0
- /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
- /package/{src → cli}/commands/cli-postinstall.test.mjs +0 -0
- /package/{src → cli}/commands/component.test.mjs +0 -0
- /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
- /package/{src → cli}/commands/init.next-steps.test.mjs +0 -0
- /package/{src → cli}/commands/interactive-guard.test.mjs +0 -0
- /package/{src → cli}/commands/json-contract.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
- /package/{src → cli}/commands/template.test.mjs +0 -0
- /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
- /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
- /package/{src → cli}/update-hint-commands.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/registry.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.8/index.mjs +0 -0
- /package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +0 -0
- /package/{src/lib → lib}/cli-error.mjs +0 -0
- /package/{src/lib → lib}/cli-error.test.mjs +0 -0
- /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
- /package/{src/lib → lib}/component-format.test.mjs +0 -0
- /package/{src/lib → lib}/component-loader.test.mjs +0 -0
- /package/{src/lib → lib}/config-cache.mjs +0 -0
- /package/{src/lib → lib}/config-cache.test.mjs +0 -0
- /package/{src/lib → lib}/config-schema.mjs +0 -0
- /package/{src/lib → lib}/error-codes.mjs +0 -0
- /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
- /package/{src/lib → lib}/json.mjs +0 -0
- /package/{src/lib → lib}/module-loader.test.mjs +0 -0
- /package/{src/lib → lib}/node-version.mjs +0 -0
- /package/{src/lib → lib}/node-version.test.mjs +0 -0
- /package/{src/lib → lib}/parse.mjs +0 -0
- /package/{src/lib → lib}/site.mjs +0 -0
- /package/{src/lib → lib}/xle/browser.d.ts +0 -0
- /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
- /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
- /package/{src/schemas → schemas}/template-schema.mjs +0 -0
- /package/{src/types → types}/config.d.ts +0 -0
- /package/{src/types → types}/doc.d.ts +0 -0
- /package/{src/types → types}/doctor.d.ts +0 -0
- /package/{src/types → types}/error-codes.d.ts +0 -0
- /package/{src/types → types}/index.d.ts +0 -0
- /package/{src/types → types}/integration.d.ts +0 -0
- /package/{src/types → types}/manifest.d.ts +0 -0
- /package/{src/types → types}/search.d.ts +0 -0
- /package/{src/types → types}/swizzle.d.ts +0 -0
- /package/{src/types → types}/template-api.d.ts +0 -0
- /package/{src/types → types}/template.d.ts +0 -0
- /package/{src/types → types}/validate-integration.d.ts +0 -0
- /package/{src/utils → utils}/github.mjs +0 -0
- /package/{src/utils → utils}/package-manager.mjs +0 -0
- /package/{src/utils → utils}/package-manager.test.mjs +0 -0
- /package/{src/utils → utils}/path-safety.mjs +0 -0
- /package/{src/utils → utils}/path-safety.test.mjs +0 -0
- /package/{src/utils → utils}/paths.test.mjs +0 -0
- /package/{src/utils → utils}/semver.mjs +0 -0
- /package/{src/utils → utils}/semver.test.mjs +0 -0
- /package/{src/utils → utils}/update-check.mjs +0 -0
- /package/{src/utils → utils}/update-check.test.mjs +0 -0
|
@@ -17,25 +17,27 @@ import * as path from 'node:path';
|
|
|
17
17
|
import {pathToFileURL, fileURLToPath} from 'node:url';
|
|
18
18
|
import {spawn} from 'node:child_process';
|
|
19
19
|
import {createJiti} from 'jiti';
|
|
20
|
-
import {getCliInvocation} from '
|
|
20
|
+
import {getCliInvocation} from '../../utils/package-manager.mjs';
|
|
21
21
|
import {
|
|
22
22
|
sanitizeName,
|
|
23
23
|
PathSafetyError,
|
|
24
|
-
} from '
|
|
25
|
-
import {jsonOut, humanLog} from '
|
|
26
|
-
import {cliError} from '
|
|
27
|
-
import {ERROR_CODES} from '
|
|
28
|
-
import {themeAdd} from '
|
|
24
|
+
} from '../../utils/path-safety.mjs';
|
|
25
|
+
import {jsonOut, humanLog} from '../../lib/json.mjs';
|
|
26
|
+
import {cliError} from '../../lib/cli-error.mjs';
|
|
27
|
+
import {ERROR_CODES} from '../../lib/error-codes.mjs';
|
|
28
|
+
import {themeAdd} from '../../api/theme/theme-add.mjs';
|
|
29
29
|
|
|
30
30
|
// Import shared theme processing from core. `astryx theme build` MUST produce the
|
|
31
31
|
// exact same CSS as the `<Theme>` runtime, so it has exactly one generation
|
|
32
32
|
// path: core's generator. There is no in-CLI fallback implementation — if this
|
|
33
33
|
// import fails, the build fails (see the ERR_CORE_NOT_FOUND guard in the theme
|
|
34
34
|
// action). A built, resolvable `@astryxdesign/core` is a hard requirement.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let
|
|
38
|
-
let
|
|
35
|
+
// A built, resolvable `@astryxdesign/core` is a hard requirement. These are
|
|
36
|
+
// populated from a dynamic import (a runtime boundary), so `any` is intentional.
|
|
37
|
+
/** @type {any} */ let _defineTheme = null;
|
|
38
|
+
/** @type {any} */ let _generateThemeRulesSplit = null;
|
|
39
|
+
/** @type {any} */ let _generateOnMediaCSS = null;
|
|
40
|
+
/** @type {any} */ let _coreImportError = null;
|
|
39
41
|
try {
|
|
40
42
|
const coreTheme = await import('@astryxdesign/core/theme');
|
|
41
43
|
_defineTheme = coreTheme.defineTheme;
|
|
@@ -75,9 +77,11 @@ function generatedHeader(sourceFile, lang = 'js', command) {
|
|
|
75
77
|
/**
|
|
76
78
|
* Convert a theme name to a valid JS identifier.
|
|
77
79
|
* e.g. 'default-minimal' → 'defaultMinimal', 'ocean' → 'ocean'
|
|
80
|
+
* @param {string} name
|
|
81
|
+
* @returns {string}
|
|
78
82
|
*/
|
|
79
83
|
function toIdentifier(name) {
|
|
80
|
-
return name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
84
|
+
return name.replace(/-([a-z])/g, (/** @type {string} */ _, /** @type {string} */ c) => c.toUpperCase());
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
/**
|
|
@@ -85,6 +89,9 @@ function toIdentifier(name) {
|
|
|
85
89
|
* from the cwd-relative dir (most consumers import from a file under src/) but
|
|
86
90
|
* keeps the rest of the path (e.g. `themes/gothic`). Callers note the path is
|
|
87
91
|
* relative to the consumer's file.
|
|
92
|
+
* @param {string} relDir
|
|
93
|
+
* @param {string} base
|
|
94
|
+
* @returns {string}
|
|
88
95
|
*/
|
|
89
96
|
function importSpecifier(relDir, base) {
|
|
90
97
|
const normalized = relDir === '.' ? '' : relDir;
|
|
@@ -95,11 +102,13 @@ function importSpecifier(relDir, base) {
|
|
|
95
102
|
/**
|
|
96
103
|
* Convert a kebab-case component name to PascalCase.
|
|
97
104
|
* e.g. 'button' → 'Button', 'progress-bar' → 'ProgressBar', 'avatar-status-dot' → 'AvatarStatusDot'
|
|
105
|
+
* @param {string} name
|
|
106
|
+
* @returns {string}
|
|
98
107
|
*/
|
|
99
108
|
function toPascalCase(name) {
|
|
100
109
|
return name
|
|
101
110
|
.split('-')
|
|
102
|
-
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
111
|
+
.map((/** @type {string} */ part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
103
112
|
.join('');
|
|
104
113
|
}
|
|
105
114
|
|
|
@@ -107,6 +116,8 @@ function toPascalCase(name) {
|
|
|
107
116
|
* Load known built-in values for a component's visual props from its .doc.mjs file.
|
|
108
117
|
* Parses the type string (e.g. "'info' | 'warning' | 'error' | 'success'") to extract values.
|
|
109
118
|
* Returns a map of { propName: string[] } for props that are visual (listed in theming targets).
|
|
119
|
+
* @param {string} componentName
|
|
120
|
+
* @returns {Promise<Record<string, string[]>>}
|
|
110
121
|
*/
|
|
111
122
|
async function loadKnownValues(componentName) {
|
|
112
123
|
// Resolve core src relative to the CLI package, not cwd (which may be a theme package)
|
|
@@ -140,6 +151,7 @@ async function loadKnownValues(componentName) {
|
|
|
140
151
|
if (allProps.length === 0) return {};
|
|
141
152
|
|
|
142
153
|
// Collect visual prop names from theming targets
|
|
154
|
+
/** @type {Set<string>} */
|
|
143
155
|
const visualProps = new Set();
|
|
144
156
|
for (const target of doc.theming.targets) {
|
|
145
157
|
if (target.visualProps) {
|
|
@@ -148,6 +160,7 @@ async function loadKnownValues(componentName) {
|
|
|
148
160
|
}
|
|
149
161
|
|
|
150
162
|
// Extract values from prop type strings
|
|
163
|
+
/** @type {Record<string, string[]>} */
|
|
151
164
|
const result = {};
|
|
152
165
|
for (const prop of allProps) {
|
|
153
166
|
if (!visualProps.has(prop.name)) continue;
|
|
@@ -156,7 +169,7 @@ async function loadKnownValues(componentName) {
|
|
|
156
169
|
// Parse union type: "'info' | 'warning' | 'error' | 'success'" → ['info', 'warning', 'error', 'success']
|
|
157
170
|
const matches = prop.type.match(/'([^']+)'/g);
|
|
158
171
|
if (matches) {
|
|
159
|
-
result[prop.name] = matches.map(m => m.replace(/'/g, ''));
|
|
172
|
+
result[prop.name] = matches.map((/** @type {string} */ m) => m.replace(/'/g, ''));
|
|
160
173
|
}
|
|
161
174
|
}
|
|
162
175
|
return result;
|
|
@@ -166,12 +179,17 @@ async function loadKnownValues(componentName) {
|
|
|
166
179
|
}
|
|
167
180
|
|
|
168
181
|
// Cache for loaded known values
|
|
182
|
+
/** @type {Map<string, Record<string, string[]>>} */
|
|
169
183
|
const _knownValuesCache = new Map();
|
|
184
|
+
/**
|
|
185
|
+
* @param {string} componentName
|
|
186
|
+
* @returns {Promise<Record<string, string[]>>}
|
|
187
|
+
*/
|
|
170
188
|
async function getKnownValues(componentName) {
|
|
171
189
|
if (!_knownValuesCache.has(componentName)) {
|
|
172
190
|
_knownValuesCache.set(componentName, await loadKnownValues(componentName));
|
|
173
191
|
}
|
|
174
|
-
return _knownValuesCache.get(componentName);
|
|
192
|
+
return _knownValuesCache.get(componentName) ?? {};
|
|
175
193
|
}
|
|
176
194
|
|
|
177
195
|
/**
|
|
@@ -195,10 +213,15 @@ function resolveCoreRoot() {
|
|
|
195
213
|
* actually sees), falling back to the `src/<Component>/index.ts` in the
|
|
196
214
|
* monorepo. Returns the file contents, or '' if nothing is found.
|
|
197
215
|
*/
|
|
216
|
+
/** @type {Map<string, string>} */
|
|
198
217
|
const _componentDeclCache = new Map();
|
|
218
|
+
/**
|
|
219
|
+
* @param {string} pascalName
|
|
220
|
+
* @returns {string}
|
|
221
|
+
*/
|
|
199
222
|
function readComponentDeclarations(pascalName) {
|
|
200
223
|
if (_componentDeclCache.has(pascalName)) {
|
|
201
|
-
return _componentDeclCache.get(pascalName);
|
|
224
|
+
return _componentDeclCache.get(pascalName) ?? '';
|
|
202
225
|
}
|
|
203
226
|
let contents = '';
|
|
204
227
|
const coreRoot = resolveCoreRoot();
|
|
@@ -230,6 +253,9 @@ function readComponentDeclarations(pascalName) {
|
|
|
230
253
|
* `HeadingType`, `ButtonSize`) are NOT augmentable, so a generated augmentation
|
|
231
254
|
* against them is dead code. We check that the name is exported (directly or
|
|
232
255
|
* re-exported) as a type/interface.
|
|
256
|
+
* @param {string} pascalName
|
|
257
|
+
* @param {string} interfaceName
|
|
258
|
+
* @returns {boolean}
|
|
233
259
|
*/
|
|
234
260
|
function componentHasAugmentableInterface(pascalName, interfaceName) {
|
|
235
261
|
const decl = readComponentDeclarations(pascalName);
|
|
@@ -254,7 +280,7 @@ function componentHasAugmentableInterface(pascalName, interfaceName) {
|
|
|
254
280
|
* generating a `declare module` block for them would be dead code — those are
|
|
255
281
|
* skipped.
|
|
256
282
|
*
|
|
257
|
-
* @param {
|
|
283
|
+
* @param {{components?: Record<string, Record<string, Record<string, unknown>>>}} themeDef - Theme definition (resolved by defineTheme)
|
|
258
284
|
* @returns {Promise<string|null>} TypeScript declaration content, or null if no augmentations needed
|
|
259
285
|
*/
|
|
260
286
|
async function generateVariantDeclarationsAsync(themeDef) {
|
|
@@ -263,6 +289,7 @@ async function generateVariantDeclarationsAsync(themeDef) {
|
|
|
263
289
|
}
|
|
264
290
|
|
|
265
291
|
// Collect custom values: { component: { prop: [value, ...] } }
|
|
292
|
+
/** @type {Record<string, Record<string, Set<string>>>} */
|
|
266
293
|
const customValues = {};
|
|
267
294
|
|
|
268
295
|
for (const [component, rules] of Object.entries(themeDef.components)) {
|
|
@@ -336,6 +363,8 @@ async function generateVariantDeclarationsAsync(themeDef) {
|
|
|
336
363
|
|
|
337
364
|
/**
|
|
338
365
|
* Resolve a token value — [light, dark] tuple becomes light-dark()
|
|
366
|
+
* @param {unknown} value
|
|
367
|
+
* @returns {unknown}
|
|
339
368
|
*/
|
|
340
369
|
function resolveTokenValue(value) {
|
|
341
370
|
if (Array.isArray(value)) {
|
|
@@ -347,12 +376,14 @@ function resolveTokenValue(value) {
|
|
|
347
376
|
// Theme @scope selector helpers. Keep the `astryx` literal in sync with
|
|
348
377
|
// packages/core/src/naming.ts (NAMESPACE) and generateThemeRules.ts.
|
|
349
378
|
// Theme scopes to data-astryx-theme; the static build path must match.
|
|
350
|
-
const themeScopeStart = name => `[data-astryx-theme="${name}"]`;
|
|
379
|
+
const themeScopeStart = (/** @type {string} */ name) => `[data-astryx-theme="${name}"]`;
|
|
351
380
|
const THEME_SCOPE_TO = `[data-astryx-theme]`;
|
|
352
381
|
|
|
353
382
|
/**
|
|
354
383
|
* Import a theme module using jiti and find the defineTheme() result.
|
|
355
384
|
* Returns the resolved DefinedTheme object.
|
|
385
|
+
* @param {string} filePath
|
|
386
|
+
* @returns {Promise<any>}
|
|
356
387
|
*/
|
|
357
388
|
async function importThemeModule(filePath) {
|
|
358
389
|
const jiti = createJiti(import.meta.url, {
|
|
@@ -376,6 +407,10 @@ async function importThemeModule(filePath) {
|
|
|
376
407
|
);
|
|
377
408
|
}
|
|
378
409
|
|
|
410
|
+
/**
|
|
411
|
+
* @param {any} value
|
|
412
|
+
* @returns {boolean}
|
|
413
|
+
*/
|
|
379
414
|
function isThemeObject(value) {
|
|
380
415
|
return (
|
|
381
416
|
value &&
|
|
@@ -389,6 +424,8 @@ function isThemeObject(value) {
|
|
|
389
424
|
/**
|
|
390
425
|
* Extract the theme definition from a JS/TS file.
|
|
391
426
|
* Tries jiti first (full TS support), falls back to regex+eval.
|
|
427
|
+
* @param {string} filePath
|
|
428
|
+
* @returns {Promise<any>}
|
|
392
429
|
*/
|
|
393
430
|
async function extractThemeDefinition(filePath) {
|
|
394
431
|
try {
|
|
@@ -397,8 +434,9 @@ async function extractThemeDefinition(filePath) {
|
|
|
397
434
|
try {
|
|
398
435
|
return extractThemeDefinitionLegacy(filePath);
|
|
399
436
|
} catch {
|
|
437
|
+
const je = /** @type {Error} */ (jitiError);
|
|
400
438
|
throw new Error(
|
|
401
|
-
`Failed to load theme from ${filePath}: ${
|
|
439
|
+
`Failed to load theme from ${filePath}: ${je.message}\n` +
|
|
402
440
|
`Make sure all imports in the theme file are resolvable.`,
|
|
403
441
|
);
|
|
404
442
|
}
|
|
@@ -408,6 +446,8 @@ async function extractThemeDefinition(filePath) {
|
|
|
408
446
|
/**
|
|
409
447
|
* Fallback extraction via regex + eval.
|
|
410
448
|
* Only works for plain object literals — can't follow imports or variables.
|
|
449
|
+
* @param {string} filePath
|
|
450
|
+
* @returns {any}
|
|
411
451
|
*/
|
|
412
452
|
function extractThemeDefinitionLegacy(filePath) {
|
|
413
453
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
@@ -433,8 +473,9 @@ function extractThemeDefinitionLegacy(filePath) {
|
|
|
433
473
|
|
|
434
474
|
return eval(`(${objStr})`);
|
|
435
475
|
} catch (e) {
|
|
476
|
+
const err = /** @type {Error} */ (e);
|
|
436
477
|
throw new Error(
|
|
437
|
-
`Failed to parse theme definition in ${filePath}: ${
|
|
478
|
+
`Failed to parse theme definition in ${filePath}: ${err.message}\n` +
|
|
438
479
|
`Make sure the defineTheme() argument is a plain object literal.`,
|
|
439
480
|
{cause: e},
|
|
440
481
|
);
|
|
@@ -448,6 +489,8 @@ function extractThemeDefinitionLegacy(filePath) {
|
|
|
448
489
|
* Looks for patterns like:
|
|
449
490
|
* import { defaultIconRegistry } from './icons';
|
|
450
491
|
* icons: defaultIconRegistry,
|
|
492
|
+
* @param {string} filePath
|
|
493
|
+
* @returns {{exportName: string, importPath: string} | null}
|
|
451
494
|
*/
|
|
452
495
|
function extractIconInfo(filePath) {
|
|
453
496
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
@@ -456,7 +499,7 @@ function extractIconInfo(filePath) {
|
|
|
456
499
|
const iconsMatch = content.match(/icons:\s*([a-zA-Z_][a-zA-Z0-9_]*)/);
|
|
457
500
|
if (!iconsMatch) return null;
|
|
458
501
|
|
|
459
|
-
const varName = iconsMatch[1];
|
|
502
|
+
const varName = /** @type {string} */ (iconsMatch[1]);
|
|
460
503
|
|
|
461
504
|
// Find the import for that variable
|
|
462
505
|
const importRegex = new RegExp(
|
|
@@ -467,7 +510,7 @@ function extractIconInfo(filePath) {
|
|
|
467
510
|
|
|
468
511
|
return {
|
|
469
512
|
exportName: varName,
|
|
470
|
-
importPath: importMatch[1],
|
|
513
|
+
importPath: /** @type {string} */ (importMatch[1]),
|
|
471
514
|
};
|
|
472
515
|
}
|
|
473
516
|
|
|
@@ -475,6 +518,9 @@ function extractIconInfo(filePath) {
|
|
|
475
518
|
* Generate a minimal JS module for a built theme.
|
|
476
519
|
* Includes the theme name, marker, and re-exports the icon registry.
|
|
477
520
|
* All styling is in the CSS file.
|
|
521
|
+
* @param {any} themeDef
|
|
522
|
+
* @param {{exportName: string, importPath: string} | null} iconInfo
|
|
523
|
+
* @returns {string}
|
|
478
524
|
*/
|
|
479
525
|
function generateBuiltModule(themeDef, iconInfo) {
|
|
480
526
|
const iconImport = iconInfo
|
|
@@ -486,6 +532,7 @@ function generateBuiltModule(themeDef, iconInfo) {
|
|
|
486
532
|
: '';
|
|
487
533
|
|
|
488
534
|
// Resolve token values — tuples become light-dark() strings
|
|
535
|
+
/** @type {Record<string, unknown>} */
|
|
489
536
|
const resolvedTokens = {};
|
|
490
537
|
if (themeDef.tokens) {
|
|
491
538
|
for (const [key, value] of Object.entries(themeDef.tokens)) {
|
|
@@ -516,6 +563,10 @@ ${iconReExport}`;
|
|
|
516
563
|
|
|
517
564
|
/**
|
|
518
565
|
* Generate TypeScript declarations for a built theme module.
|
|
566
|
+
* @param {any} themeDef
|
|
567
|
+
* @param {{exportName: string, importPath: string} | null} iconInfo
|
|
568
|
+
* @param {string | null} variantsFileName
|
|
569
|
+
* @returns {string}
|
|
519
570
|
*/
|
|
520
571
|
function generateBuiltTypes(themeDef, iconInfo, variantsFileName) {
|
|
521
572
|
const iconType = iconInfo
|
|
@@ -543,6 +594,7 @@ ${iconType}export declare const ${toIdentifier(themeDef.name)}Theme: DefinedThem
|
|
|
543
594
|
/**
|
|
544
595
|
* Known Astryx component names and their visual props.
|
|
545
596
|
* Used to warn on typos in defineTheme component overrides.
|
|
597
|
+
* @type {Record<string, string[]>}
|
|
546
598
|
*/
|
|
547
599
|
const KNOWN_COMPONENTS = {
|
|
548
600
|
appshell: ['position'],
|
|
@@ -604,8 +656,11 @@ const KNOWN_COMPONENTS = {
|
|
|
604
656
|
* Validate component overrides in a theme definition.
|
|
605
657
|
* Warns on unknown component names and unknown prop names.
|
|
606
658
|
* Returns array of warning strings.
|
|
659
|
+
* @param {{components?: Record<string, Record<string, unknown>>}} themeDef
|
|
660
|
+
* @returns {string[]}
|
|
607
661
|
*/
|
|
608
662
|
function validateComponentOverrides(themeDef) {
|
|
663
|
+
/** @type {string[]} */
|
|
609
664
|
const warnings = [];
|
|
610
665
|
if (!themeDef.components) return warnings;
|
|
611
666
|
|
|
@@ -668,8 +723,11 @@ function validateComponentOverrides(themeDef) {
|
|
|
668
723
|
* (e.g. borderRadius, padding) instead.
|
|
669
724
|
*
|
|
670
725
|
* Returns array of error strings.
|
|
726
|
+
* @param {{components?: Record<string, Record<string, Record<string, unknown>>>}} themeDef
|
|
727
|
+
* @returns {string[]}
|
|
671
728
|
*/
|
|
672
729
|
function validatePrivateVars(themeDef) {
|
|
730
|
+
/** @type {string[]} */
|
|
673
731
|
const errors = [];
|
|
674
732
|
if (!themeDef.components) return errors;
|
|
675
733
|
|
|
@@ -706,14 +764,14 @@ function resolveCliBin() {
|
|
|
706
764
|
* Resolves with the child's exit code; never rejects.
|
|
707
765
|
*
|
|
708
766
|
* @param {string} file - The theme file argument, as the user passed it.
|
|
709
|
-
* @param {
|
|
767
|
+
* @param {{out?: string}} options - Parsed command options (only `out` is forwarded).
|
|
710
768
|
* @returns {Promise<number>}
|
|
711
769
|
*/
|
|
712
770
|
function runThemeBuildOnceChild(file, options) {
|
|
713
771
|
const cliBin = resolveCliBin();
|
|
714
772
|
const args = [cliBin, 'theme', 'build', file];
|
|
715
773
|
if (options.out) args.push('--out', options.out);
|
|
716
|
-
return new Promise(resolve => {
|
|
774
|
+
return new Promise((/** @type {(code: number) => void} */ resolve) => {
|
|
717
775
|
const child = spawn(process.execPath, args, {
|
|
718
776
|
stdio: 'inherit',
|
|
719
777
|
env: process.env,
|
|
@@ -732,7 +790,7 @@ function runThemeBuildOnceChild(file, options) {
|
|
|
732
790
|
*
|
|
733
791
|
* @param {string} file - The theme file argument, as the user passed it.
|
|
734
792
|
* @param {string} filePath - Absolute path to the theme file.
|
|
735
|
-
* @param {
|
|
793
|
+
* @param {{out?: string}} options - Parsed command options.
|
|
736
794
|
* @returns {Promise<void>} Resolves when the watcher is stopped (Ctrl-C).
|
|
737
795
|
*/
|
|
738
796
|
async function runThemeBuildWatch(file, filePath, options) {
|
|
@@ -745,7 +803,8 @@ async function runThemeBuildWatch(file, filePath, options) {
|
|
|
745
803
|
|
|
746
804
|
let building = false;
|
|
747
805
|
let queued = false;
|
|
748
|
-
|
|
806
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
807
|
+
let debounce;
|
|
749
808
|
|
|
750
809
|
const rebuild = async () => {
|
|
751
810
|
if (building) {
|
|
@@ -776,7 +835,7 @@ async function runThemeBuildWatch(file, filePath, options) {
|
|
|
776
835
|
debounce = setTimeout(rebuild, 100);
|
|
777
836
|
});
|
|
778
837
|
|
|
779
|
-
await new Promise(resolve => {
|
|
838
|
+
await new Promise((/** @type {(value?: void) => void} */ resolve) => {
|
|
780
839
|
const stop = () => {
|
|
781
840
|
clearTimeout(debounce);
|
|
782
841
|
watcher.close();
|
|
@@ -788,11 +847,14 @@ async function runThemeBuildWatch(file, filePath, options) {
|
|
|
788
847
|
});
|
|
789
848
|
}
|
|
790
849
|
|
|
850
|
+
/**
|
|
851
|
+
* @param {import('commander').Command} program
|
|
852
|
+
*/
|
|
791
853
|
export function registerTheme(program) {
|
|
792
854
|
const theme = program
|
|
793
855
|
.command('theme')
|
|
794
856
|
.description('Theme tools — build, export, and manage themes')
|
|
795
|
-
.action((options, cmd) => {
|
|
857
|
+
.action((/** @type {unknown} */ options, /** @type {import('commander').Command} */ cmd) => {
|
|
796
858
|
// Parent group has no default behaviour. If the user passed an
|
|
797
859
|
// unknown subcommand (e.g. `astryx theme bogus`), Commander hands it to
|
|
798
860
|
// us as a positional in cmd.args — exit 1 with a clear error.
|
|
@@ -816,7 +878,7 @@ export function registerTheme(program) {
|
|
|
816
878
|
'-w, --watch',
|
|
817
879
|
'Rebuild automatically when the theme file changes (Ctrl-C to stop)',
|
|
818
880
|
)
|
|
819
|
-
.action(async (file, options) => {
|
|
881
|
+
.action(async (/** @type {string} */ file, /** @type {{out?: string, watch?: boolean}} */ options) => {
|
|
820
882
|
const filePath = path.resolve(process.cwd(), file);
|
|
821
883
|
const json = program.opts().json || false;
|
|
822
884
|
|
|
@@ -846,7 +908,8 @@ export function registerTheme(program) {
|
|
|
846
908
|
try {
|
|
847
909
|
themeDef = await extractThemeDefinition(filePath);
|
|
848
910
|
} catch (e) {
|
|
849
|
-
|
|
911
|
+
const err = /** @type {Error} */ (e);
|
|
912
|
+
cliError(err.message, {code: ERROR_CODES.ERR_THEME_LOAD});
|
|
850
913
|
return;
|
|
851
914
|
}
|
|
852
915
|
|
|
@@ -992,7 +1055,10 @@ export function registerTheme(program) {
|
|
|
992
1055
|
const augmentationSource = resolvedTheme || themeDef;
|
|
993
1056
|
const variantDecl = await generateVariantDeclarationsAsync(augmentationSource);
|
|
994
1057
|
const variantsFileName = variantDecl ? `${baseName}.variants.d.ts` : null;
|
|
995
|
-
const variantDtsPath =
|
|
1058
|
+
const variantDtsPath =
|
|
1059
|
+
variantDecl && variantsFileName
|
|
1060
|
+
? path.join(outDir, variantsFileName)
|
|
1061
|
+
: null;
|
|
996
1062
|
const variantContent = variantDecl
|
|
997
1063
|
? generatedHeader(sourceRelative, 'ts', buildCommand) + variantDecl
|
|
998
1064
|
: null;
|
|
@@ -1013,11 +1079,12 @@ export function registerTheme(program) {
|
|
|
1013
1079
|
{dest: jsPath, content: jsContent},
|
|
1014
1080
|
{dest: dtsPath, content: dtsContent},
|
|
1015
1081
|
];
|
|
1016
|
-
if (variantDtsPath) {
|
|
1082
|
+
if (variantDtsPath && variantContent) {
|
|
1017
1083
|
writes.push({dest: variantDtsPath, content: variantContent});
|
|
1018
1084
|
}
|
|
1019
1085
|
|
|
1020
1086
|
fs.mkdirSync(outDir, {recursive: true});
|
|
1087
|
+
/** @type {Array<{tmp: string, dest: string}>} */
|
|
1021
1088
|
const staged = [];
|
|
1022
1089
|
try {
|
|
1023
1090
|
for (const w of writes) {
|
|
@@ -1033,7 +1100,7 @@ export function registerTheme(program) {
|
|
|
1033
1100
|
for (const s of staged) {
|
|
1034
1101
|
try { fs.rmSync(s.tmp, {force: true}); } catch { /* best-effort */ }
|
|
1035
1102
|
}
|
|
1036
|
-
const msg = `Failed to write theme outputs: ${err.message}`;
|
|
1103
|
+
const msg = `Failed to write theme outputs: ${/** @type {Error} */ (err).message}`;
|
|
1037
1104
|
cliError(msg, {code: ERROR_CODES.ERR_WRITE_FAILED});
|
|
1038
1105
|
return;
|
|
1039
1106
|
}
|
|
@@ -1044,7 +1111,7 @@ export function registerTheme(program) {
|
|
|
1044
1111
|
humanLog(` ${size} KB`);
|
|
1045
1112
|
humanLog(`✓ ${path.relative(process.cwd(), jsPath)}`);
|
|
1046
1113
|
humanLog(`✓ ${path.relative(process.cwd(), dtsPath)}`);
|
|
1047
|
-
if (variantDtsPath) {
|
|
1114
|
+
if (variantDtsPath && variantDecl) {
|
|
1048
1115
|
const augCount = (variantDecl.match(/': true;/g) || []).length;
|
|
1049
1116
|
humanLog(`✓ ${path.relative(process.cwd(), variantDtsPath)} (${augCount} type augmentations)`);
|
|
1050
1117
|
}
|
|
@@ -1060,7 +1127,7 @@ export function registerTheme(program) {
|
|
|
1060
1127
|
css: path.relative(process.cwd(), outPath),
|
|
1061
1128
|
js: path.relative(process.cwd(), jsPath),
|
|
1062
1129
|
dts: path.relative(process.cwd(), dtsPath),
|
|
1063
|
-
...(variantDecl ? {variantsDts: path.relative(process.cwd(), variantDtsPath)} : {}),
|
|
1130
|
+
...(variantDecl && variantDtsPath ? {variantsDts: path.relative(process.cwd(), variantDtsPath)} : {}),
|
|
1064
1131
|
},
|
|
1065
1132
|
warnings: warningMessages,
|
|
1066
1133
|
});
|
|
@@ -1107,15 +1174,21 @@ Or with a <link> tag:
|
|
|
1107
1174
|
.description('List themes available to add')
|
|
1108
1175
|
.action(async () => {
|
|
1109
1176
|
const json = program.opts().json || false;
|
|
1177
|
+
/** @type {import('../../types/theme').ThemeListResponse} */
|
|
1110
1178
|
let result;
|
|
1111
1179
|
try {
|
|
1112
|
-
result =
|
|
1180
|
+
result = /** @type {import('../../types/theme').ThemeListResponse} */ (
|
|
1181
|
+
await themeAdd(undefined, {list: true, cwd: process.cwd()})
|
|
1182
|
+
);
|
|
1113
1183
|
} catch (e) {
|
|
1114
|
-
|
|
1184
|
+
const err = /** @type {import('../../api/error.mjs').AstryxError} */ (e);
|
|
1185
|
+
cliError(err.message, {suggestions: err.suggestions || [], code: err.code});
|
|
1115
1186
|
return;
|
|
1116
1187
|
}
|
|
1117
1188
|
|
|
1118
|
-
|
|
1189
|
+
// theme.list is not registered in CLIResponseType (base.d.ts, owned by the
|
|
1190
|
+
// coordinator) — cast the discriminant until it is added there.
|
|
1191
|
+
if (json) return jsonOut(/** @type {any} */ (result.type), result.data);
|
|
1119
1192
|
|
|
1120
1193
|
const themes = result.data;
|
|
1121
1194
|
if (themes.length === 0) {
|
|
@@ -1137,26 +1210,32 @@ Or with a <link> tag:
|
|
|
1137
1210
|
.description('Scaffold a theme into your project as editable source')
|
|
1138
1211
|
.option('-f, --overwrite', 'Overwrite existing files without prompting')
|
|
1139
1212
|
.option('--list', 'List available themes')
|
|
1140
|
-
.action(async (slug, targetPath, options) => {
|
|
1213
|
+
.action(async (/** @type {string | undefined} */ slug, /** @type {string | undefined} */ targetPath, /** @type {{list?: boolean, overwrite?: boolean}} */ options) => {
|
|
1141
1214
|
const json = program.opts().json || false;
|
|
1142
1215
|
|
|
1143
1216
|
// The CLI is non-interactive: never prompt to confirm an overwrite.
|
|
1144
1217
|
// Existing files require an explicit --overwrite; otherwise themeAdd's
|
|
1145
1218
|
// ERR_FILE_EXISTS guard rejects the write.
|
|
1219
|
+
/** @type {import('../../types/theme').ThemeListResponse | import('../../types/theme').ThemeAddResponse} */
|
|
1146
1220
|
let result;
|
|
1147
1221
|
try {
|
|
1148
|
-
result =
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1222
|
+
result = /** @type {import('../../types/theme').ThemeListResponse | import('../../types/theme').ThemeAddResponse} */ (
|
|
1223
|
+
await themeAdd(slug, {
|
|
1224
|
+
list: options.list,
|
|
1225
|
+
targetPath,
|
|
1226
|
+
overwrite: options.overwrite,
|
|
1227
|
+
cwd: process.cwd(),
|
|
1228
|
+
})
|
|
1229
|
+
);
|
|
1154
1230
|
} catch (e) {
|
|
1155
|
-
|
|
1231
|
+
const err = /** @type {import('../../api/error.mjs').AstryxError} */ (e);
|
|
1232
|
+
cliError(err.message, {suggestions: err.suggestions || [], code: err.code});
|
|
1156
1233
|
return;
|
|
1157
1234
|
}
|
|
1158
1235
|
|
|
1159
|
-
|
|
1236
|
+
// theme.list/theme.add are not registered in CLIResponseType (base.d.ts,
|
|
1237
|
+
// owned by the coordinator) — cast the discriminant until they are added.
|
|
1238
|
+
if (json) return jsonOut(/** @type {any} */ (result.type), result.data);
|
|
1160
1239
|
|
|
1161
1240
|
if (result.type === 'theme.list') {
|
|
1162
1241
|
const themes = result.data;
|