@astryxdesign/cli 0.7.2-canary.fdd384f → 0.7.2
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 +119 -0
- package/README.md +169 -149
- package/api/build/_adapter.d.mts +8 -0
- package/api/build/_adapter.mjs +12 -1
- package/api/build/build.doc.mjs +4 -0
- package/api/build/kit/kit.mjs +3 -11
- package/api/component/_adapter.d.mts +31 -0
- package/api/component/_adapter.mjs +119 -11
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +60 -10
- package/api/component/doc-links.test.mjs +386 -0
- package/api/discover/_adapter.d.mts +132 -12
- package/api/discover/_adapter.mjs +488 -27
- package/api/discover/_adapter.test.mjs +599 -17
- package/api/discover/_catalog-view.d.mts +16 -5
- package/api/discover/_catalog-view.mjs +32 -8
- package/api/discover/detail/doc/doc.mjs +9 -1
- package/api/discover/discover.d.mts +11 -0
- package/api/discover/discover.doc.mjs +9 -7
- package/api/discover/discover.mjs +121 -19
- package/api/discover/discover.type.d.mts +20 -7
- package/api/discover/discover.type.mjs +17 -7
- package/api/discover/list/list.d.mts +4 -3
- package/api/discover/list/list.mjs +17 -10
- package/api/docs/_adapter.d.mts +63 -0
- package/api/docs/_adapter.mjs +312 -18
- package/api/docs/docs.doc.mjs +2 -1
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +5 -2
- package/api/docs/integration-tree.test.mjs +22 -0
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/reference-blocks.test.mjs +1 -3
- package/api/doctor/_adapter.d.mts +108 -0
- package/api/doctor/_adapter.mjs +223 -4
- package/api/doctor/doctor.d.mts +199 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +530 -34
- package/api/doctor/doctor.test.mjs +180 -14
- package/api/doctor/release-checks.test.mjs +156 -0
- package/api/doctor/theme-checks.mjs +16 -3
- package/api/doctor/theme-checks.test.mjs +223 -7
- package/api/error.d.mts +10 -0
- package/api/error.mjs +25 -0
- package/api/gap-report/gap-report.d.mts +3 -0
- package/api/gap-report/gap-report.doc.mjs +11 -3
- package/api/gap-report/gap-report.mjs +152 -48
- package/api/gap-report/gap-report.test.mjs +233 -0
- package/api/gap-report/gap-report.type.d.mts +41 -0
- package/api/gap-report/gap-report.type.mjs +18 -0
- package/api/hook/_adapter.mjs +3 -11
- package/api/hook/hook.doc.mjs +4 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/init/_adapter.d.mts +22 -0
- package/api/init/_adapter.mjs +59 -0
- package/api/init/init.d.mts +7 -5
- package/api/init/init.doc.mjs +28 -7
- package/api/init/init.mjs +28 -4
- package/api/init/init.type.d.mts +48 -3
- package/api/init/init.type.mjs +37 -3
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +15 -4
- package/api/init/user/user.d.mts +14 -0
- package/api/init/user/user.mjs +87 -0
- package/api/init/user/user.test.mjs +232 -0
- package/api/integration/_adapter.d.mts +33 -0
- package/api/integration/_adapter.mjs +58 -0
- package/api/integration/authoring-checks.mjs +100 -5
- package/api/integration/authoring-checks.test.mjs +769 -0
- package/api/integration/authoring-checks.type.d.mts +134 -0
- package/api/integration/authoring-checks.type.mjs +60 -1
- package/api/integration/integrationCheck.doc.mjs +1 -1
- package/api/integration/integrationComponentConflicts.doc.mjs +11 -3
- package/api/integration/integrationDocConflicts.doc.mjs +22 -5
- package/api/integration/pack-check.mjs +303 -13
- package/api/integration/pack-check.test.mjs +371 -10
- package/api/integration/validate-integration-fixes.test.mjs +67 -0
- package/api/integration/validate-integration.d.mts +8 -0
- package/api/integration/validate-integration.mjs +55 -9
- package/api/integration/validate-integration.test.mjs +77 -8
- package/api/integration/validate-integration.type.d.mts +8 -0
- package/api/integration/validate-integration.type.mjs +3 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +4 -2
- package/api/search/_adapter.d.mts +11 -0
- package/api/search/_adapter.mjs +25 -0
- package/api/search/search.d.mts +73 -13
- package/api/search/search.doc.mjs +8 -3
- package/api/search/search.domain-priority.test.mjs +108 -18
- package/api/search/search.mjs +541 -52
- package/api/search/search.test.mjs +143 -1
- package/api/search/search.type.d.mts +14 -1
- package/api/search/search.type.mjs +6 -1
- package/api/swizzle/_adapter.mjs +2 -2
- package/api/swizzle/copy/copy.mjs +1 -1
- package/api/template/template-integration.test.mjs +1 -1
- package/api/theme/_adapter.d.mts +16 -0
- package/api/theme/_adapter.mjs +32 -5
- package/api/theme/build/build.d.mts +2 -1
- package/api/theme/build/build.mjs +70 -14
- package/api/theme/build/build.packed-old-core.test.mjs +20 -3
- package/api/theme/build/font-warning.mjs +5 -3
- package/api/theme/build/font-warning.test.mjs +2 -1
- package/api/theme/remove/remove.test.mjs +2 -2
- package/api/theme/targets/targets.mjs +3 -10
- package/api/theme/themeTargets.doc.mjs +4 -0
- package/api/theme/use/use.test.mjs +1 -1
- package/api/upgrade/_adapter.d.mts +40 -2
- package/api/upgrade/_adapter.mjs +118 -5
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.mjs +35 -2
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +6 -3
- package/api/upgrade/upgrade.mjs +5 -1
- package/api/upgrade/upgrade.type.d.mts +23 -0
- package/api/upgrade/upgrade.type.mjs +16 -1
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/runner.mjs +7 -1
- package/assets/codemods/transforms/next/index.mjs +1 -11
- package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
- package/assets/discover/official-packages.json +367 -0
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +23 -3
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +12 -2
- package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
- package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
- package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
- package/assets/docs/tree/block-template.doc.mjs +6 -18
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +4 -0
- package/assets/docs/tree/check-the-props.doc.mjs +8 -3
- package/assets/docs/tree/check-your-docs.doc.mjs +30 -13
- package/assets/docs/tree/checks.doc.mjs +17 -17
- package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +6 -0
- package/assets/docs/tree/codemods.doc.mjs +17 -7
- package/assets/docs/tree/commands.doc.mjs +7 -1
- package/assets/docs/tree/component-family.doc.mjs +3 -5
- package/assets/docs/tree/component-imports.doc.mjs +13 -3
- package/assets/docs/tree/components.doc.mjs +7 -1
- package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
- package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
- package/assets/docs/tree/configuration.doc.mjs +7 -3
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
- package/assets/docs/tree/describe-the-component.doc.mjs +2 -2
- package/assets/docs/tree/docs.doc.mjs +9 -3
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
- package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
- package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
- package/assets/docs/tree/global-integrations.doc.mjs +124 -0
- package/assets/docs/tree/global.doc.mjs +131 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- package/assets/docs/tree/integrations.doc.mjs +13 -1
- package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
- package/assets/docs/tree/layout.doc.mjs +6 -6
- package/assets/docs/tree/links.doc.mjs +6 -5
- package/assets/docs/tree/migration-setup.doc.mjs +3 -2
- package/assets/docs/tree/migration-verification.doc.mjs +0 -1
- package/assets/docs/tree/migration.doc.mjs +0 -1
- package/assets/docs/tree/monorepos.doc.mjs +84 -0
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +3 -7
- package/assets/docs/tree/problems.doc.mjs +205 -0
- package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
- package/assets/docs/tree/publishing.doc.mjs +6 -6
- package/assets/docs/tree/quick-start.doc.mjs +52 -26
- package/assets/docs/tree/reference.doc.mjs +192 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
- package/assets/docs/tree/replace-a-core-template.doc.mjs +9 -11
- package/assets/docs/tree/scaffold.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
- package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
- package/assets/docs/tree/single-component.doc.mjs +14 -6
- package/assets/docs/tree/start-a-template.doc.mjs +18 -8
- package/assets/docs/tree/subcomponent.doc.mjs +6 -6
- package/assets/docs/tree/template-assets.doc.mjs +2 -2
- package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +2 -2
- package/assets/docs/tree/templates.doc.mjs +7 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
- package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
- package/assets/docs/tree/themes.doc.mjs +4 -0
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/troubleshooting.doc.mjs +22 -14
- package/assets/docs/tree/uninstall.doc.mjs +109 -0
- package/assets/docs/tree/updates.doc.mjs +92 -0
- package/assets/docs/tree/upgrading.doc.mjs +6 -6
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +9 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +5 -5
- package/assets/docs/working-with-ai.doc.mjs +23 -9
- package/authoring/codemod/codemod.doc.mjs +7 -3
- package/authoring/config/config.doc.mjs +9 -6
- package/authoring/config/type.ts +4 -2
- package/authoring/debug/parse.d.mts +5 -5
- package/authoring/discover/discover.doc.mjs +7 -1
- package/authoring/doctypes/_schema.d.mts +8 -3
- package/authoring/doctypes/_schema.mjs +1 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
- package/authoring/doctypes/command/command.doc.mjs +20 -12
- package/authoring/doctypes/command/type.ts +14 -0
- package/authoring/doctypes/component/component.doc.mjs +29 -26
- package/authoring/doctypes/component/type.ts +15 -5
- package/authoring/doctypes/enum/enum.doc.mjs +7 -4
- package/authoring/doctypes/function/function.doc.mjs +9 -8
- package/authoring/doctypes/hook/hook.doc.mjs +5 -4
- package/authoring/doctypes/hook/type.ts +4 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
- package/authoring/doctypes/reference/reference.doc.mjs +12 -11
- package/authoring/doctypes/schema/schema.doc.mjs +9 -9
- package/authoring/doctypes/template/template.doc.mjs +2 -2
- package/authoring/doctypes/theme/theme.doc.mjs +2 -2
- package/authoring/gap-report/gap-report.doc.mjs +2 -2
- package/authoring/identity/identity.doc.mjs +3 -3
- package/authoring/index.d.ts +1 -0
- package/authoring/integration/integration.doc.mjs +22 -5
- package/authoring/integration/parse.test.mjs +11 -0
- package/authoring/integration/schema.d.mts +14 -3
- package/authoring/integration/schema.mjs +33 -2
- package/authoring/integration/type.ts +8 -0
- package/clients/cli/bin/astryx.mjs +20 -3
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/commands/blog.doc.mjs +1 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +14 -2
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- package/clients/cli/commands/build-theme.mjs +25 -12
- package/clients/cli/commands/build.doc.mjs +1 -0
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
- package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
- package/clients/cli/commands/component.doc.mjs +1 -0
- package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
- package/clients/cli/commands/discover.doc.mjs +9 -1
- package/clients/cli/commands/discover.mjs +144 -93
- package/clients/cli/commands/discover.no-source.test.mjs +448 -33
- package/clients/cli/commands/discover.sources.test.mjs +20 -1
- package/clients/cli/commands/docs.doc.mjs +1 -0
- package/clients/cli/commands/docs.mjs +49 -19
- package/clients/cli/commands/docs.test.mjs +2 -2
- package/clients/cli/commands/doctor-integration-components.doc.mjs +7 -3
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +13 -2
- package/clients/cli/commands/doctor-integration.test.mjs +52 -4
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +102 -7
- package/clients/cli/commands/doctor.test.mjs +10 -4
- package/clients/cli/commands/gap-report.doc.mjs +15 -2
- package/clients/cli/commands/gap-report.mjs +24 -2
- package/clients/cli/commands/gap-report.test.mjs +79 -0
- package/clients/cli/commands/hook.doc.mjs +1 -0
- package/clients/cli/commands/init.behavior.test.mjs +5 -0
- package/clients/cli/commands/init.doc.mjs +29 -3
- package/clients/cli/commands/integration-add.doc.mjs +7 -0
- package/clients/cli/commands/integration-authoring.test.mjs +49 -3
- package/clients/cli/commands/integration-check.doc.mjs +10 -2
- package/clients/cli/commands/integration-check.test.mjs +175 -1
- package/clients/cli/commands/integration-pack.doc.mjs +8 -1
- package/clients/cli/commands/integration-verify.doc.mjs +8 -1
- package/clients/cli/commands/integration.mjs +15 -9
- package/clients/cli/commands/json-contract.test.mjs +11 -2
- package/clients/cli/commands/manifest.doc.mjs +1 -0
- package/clients/cli/commands/outside-project.test.mjs +774 -0
- package/clients/cli/commands/search.doc.mjs +1 -0
- package/clients/cli/commands/search.mjs +16 -11
- package/clients/cli/commands/search.test.mjs +429 -296
- package/clients/cli/commands/setup-nudge.test.mjs +102 -2
- package/clients/cli/commands/swizzle.doc.mjs +7 -0
- package/clients/cli/commands/swizzle.mjs +5 -3
- package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
- package/clients/cli/commands/template.doc.mjs +1 -0
- package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
- package/clients/cli/commands/theme-add.doc.mjs +8 -1
- package/clients/cli/commands/theme-build.doc.mjs +1 -0
- package/clients/cli/commands/theme-eject.doc.mjs +1 -0
- package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
- package/clients/cli/commands/theme-list.doc.mjs +1 -0
- package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
- package/clients/cli/commands/theme-remove.doc.mjs +7 -0
- package/clients/cli/commands/theme-targets.doc.mjs +1 -0
- package/clients/cli/commands/theme-template.doc.mjs +1 -0
- package/clients/cli/commands/theme-use.doc.mjs +7 -0
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +22 -1
- package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
- package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/index.mjs +111 -16
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +2 -2
- package/clients/cli/lib/json-shim.mjs +3 -1
- package/clients/cli/lib/manifest.d.ts +9 -0
- package/clients/cli/lib/manifest.mjs +17 -1
- package/clients/cli/lib/manifest.test.mjs +25 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
- package/foundation/agent-docs/agent-doc-state.mjs +66 -6
- package/foundation/agent-docs/agent-docs.d.mts +4 -3
- package/foundation/agent-docs/agent-docs.mjs +11 -9
- package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
- package/foundation/agent-docs/computer-agent-text.mjs +623 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +145 -8
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.mjs +1 -1
- package/foundation/discovery/cli-self-docs.mjs +20 -3
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-replacement.mjs +2 -1
- package/foundation/discovery/copied-passages.d.mts +216 -0
- package/foundation/discovery/copied-passages.mjs +720 -0
- package/foundation/discovery/copied-passages.test.mjs +124 -0
- package/foundation/discovery/doc-consistency.d.mts +34 -0
- package/foundation/discovery/doc-consistency.mjs +513 -0
- package/foundation/discovery/doc-consistency.test.mjs +347 -0
- package/foundation/discovery/doc-fluff.d.mts +112 -0
- package/foundation/discovery/doc-fluff.mjs +328 -0
- package/foundation/discovery/doc-fluff.test.mjs +142 -0
- package/foundation/discovery/doc-types.d.mts +1 -1
- package/foundation/discovery/doc-types.mjs +15 -8
- package/foundation/discovery/doc-types.test.mjs +94 -2
- package/foundation/discovery/docs-discovery.d.mts +7 -0
- package/foundation/discovery/docs-discovery.mjs +26 -2
- package/foundation/discovery/project-typescript.d.mts +11 -2
- package/foundation/discovery/project-typescript.mjs +32 -4
- package/foundation/discovery/prop-drift.d.mts +26 -7
- package/foundation/discovery/prop-drift.mjs +173 -8
- package/foundation/discovery/prop-drift.test.mjs +120 -2
- package/foundation/discovery/runner-allowlist.d.mts +40 -0
- package/foundation/discovery/runner-allowlist.mjs +53 -0
- package/foundation/discovery/stray-pointers.d.mts +52 -0
- package/foundation/discovery/stray-pointers.mjs +293 -0
- package/foundation/discovery/stray-pointers.test.mjs +86 -0
- package/foundation/discovery/template-needs.mjs +5 -2
- package/foundation/discovery/theme-imports.mjs +8 -4
- package/foundation/discovery/theme-imports.test.mjs +1 -1
- package/foundation/discovery/type-text.mjs +1 -1
- package/foundation/discovery/type-text.test.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +42 -2
- package/foundation/doc-compiler/inputs.mjs +4 -1
- package/foundation/doc-compiler/links.d.mts +32 -0
- package/foundation/doc-compiler/links.mjs +163 -26
- package/foundation/doc-compiler/links.test.mjs +97 -4
- package/foundation/doc-compiler/read.d.mts +1 -1
- package/foundation/doc-compiler/tree.mjs +30 -1
- package/foundation/doc-compiler/tree.test.mjs +8 -1
- package/foundation/env/cli-command.d.mts +83 -0
- package/foundation/env/cli-command.mjs +152 -0
- package/foundation/env/cli-command.test.mjs +129 -0
- package/foundation/env/node-version.test.mjs +15 -3
- package/foundation/env/package-manager.d.mts +93 -9
- package/foundation/env/package-manager.global.test.mjs +66 -0
- package/foundation/env/package-manager.mjs +184 -13
- package/foundation/env/package-manager.test.mjs +341 -15
- package/foundation/env/project-scope.d.mts +9 -0
- package/foundation/env/project-scope.mjs +33 -0
- package/foundation/env/search-path.d.mts +42 -0
- package/foundation/env/search-path.mjs +205 -0
- package/foundation/env/search-path.test.mjs +122 -0
- package/foundation/env/user-dirs.d.mts +39 -0
- package/foundation/env/user-dirs.mjs +93 -0
- package/foundation/env/user-dirs.test.mjs +72 -0
- package/foundation/env/user-settings.d.mts +46 -0
- package/foundation/env/user-settings.mjs +106 -0
- package/foundation/env/user-settings.test.mjs +64 -0
- package/foundation/fs/file-protection.mjs +15 -1
- package/foundation/fs/module-loader.d.mts +2 -1
- package/foundation/fs/module-loader.mjs +60 -4
- package/foundation/fs/module-loader.stdout.test.mjs +3 -2
- package/foundation/fs/module-loader.test.mjs +194 -0
- package/foundation/fs/path-compare.d.mts +33 -0
- package/foundation/fs/path-compare.mjs +73 -0
- package/foundation/fs/paths.d.mts +57 -1
- package/foundation/fs/paths.mjs +131 -3
- package/foundation/fs/paths.test.mjs +10 -1
- package/foundation/integrations/computer-integrations.d.mts +78 -0
- package/foundation/integrations/computer-integrations.mjs +316 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +11 -0
- package/foundation/integrations/contribution-inventory.mjs +50 -2
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +25 -1
- package/foundation/integrations/integrations.mjs +46 -3
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +41 -1
- package/foundation/release/agent-text-worker.d.mts +4 -0
- package/foundation/release/agent-text-worker.mjs +52 -0
- package/foundation/release/cache.d.mts +310 -0
- package/foundation/release/cache.mjs +1216 -0
- package/foundation/release/cache.test.mjs +920 -0
- package/foundation/release/choose.d.mts +207 -0
- package/foundation/release/choose.mjs +677 -0
- package/foundation/release/choose.test.mjs +427 -0
- package/foundation/release/core-worker.d.mts +4 -0
- package/foundation/release/core-worker.mjs +38 -0
- package/foundation/release/global-state.d.mts +259 -0
- package/foundation/release/global-state.mjs +472 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +60 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +357 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +253 -0
- package/foundation/release/notices.mjs +596 -0
- package/foundation/release/notices.test.mjs +565 -0
- package/foundation/release/npm-guard.d.mts +4 -0
- package/foundation/release/npm-guard.mjs +126 -0
- package/foundation/release/project.d.mts +141 -0
- package/foundation/release/project.mjs +466 -0
- package/foundation/release/project.test.mjs +288 -0
- package/foundation/release/refresh-worker.d.mts +4 -0
- package/foundation/release/refresh-worker.mjs +27 -0
- package/foundation/release/run-context.d.mts +47 -0
- package/foundation/release/run-context.mjs +149 -0
- package/foundation/release/update-notice-env.d.mts +28 -0
- package/foundation/release/update-notice-env.mjs +39 -0
- package/foundation/response/base.d.ts +26 -3
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.doc.mjs +12 -0
- package/foundation/response/error-codes.mjs +17 -0
- package/foundation/response/error-codes.test.mjs +2 -0
- package/foundation/response/json-contract.test.mjs +7 -2
- package/foundation/response/json.mjs +4 -1
- package/foundation/response/response-types.doc.mjs +17 -11
- package/foundation/response/response-types.doc.test.mjs +46 -0
- package/foundation/response/response.doc.mjs +3 -3
- package/foundation/xle/browser-imports.test.mjs +74 -0
- package/package.json +11 -11
- package/scripts/postinstall.mjs +24 -5
- /package/assets/codemods/transforms/{next → v0.7.2}/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +0 -0
- /package/assets/codemods/transforms/{next → v0.7.2}/migrate-list-edge-compensation-to-edge.mjs +0 -0
|
@@ -117,6 +117,23 @@ export function discoverBuiltinTopics() {
|
|
|
117
117
|
return topics;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* The CLI's own guide files: every flat topic and every doc in its docs tree,
|
|
122
|
+
* without the dense, translated, and draft variants.
|
|
123
|
+
*
|
|
124
|
+
* @returns {string[]}
|
|
125
|
+
*/
|
|
126
|
+
export function builtinGuideFiles() {
|
|
127
|
+
const files = Object.values(discoverBuiltinTopics());
|
|
128
|
+
const tree = path.join(BUILTIN_DOCS_DIR, 'tree');
|
|
129
|
+
if (fs.existsSync(tree)) {
|
|
130
|
+
for (const file of fs.readdirSync(tree).sort()) {
|
|
131
|
+
if (BUILTIN_TOPIC_FILE_RE.test(file)) files.push(path.join(tree, file));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return files;
|
|
135
|
+
}
|
|
136
|
+
|
|
120
137
|
/**
|
|
121
138
|
* Load a topic doc from disk. A `.ts` doc is loaded through jiti, the rest
|
|
122
139
|
* natively; both the historical `export const docs` and the stamped
|
|
@@ -384,7 +401,11 @@ export function problemsInNamespace(doc) {
|
|
|
384
401
|
}
|
|
385
402
|
}
|
|
386
403
|
const slots = doc?.slots;
|
|
387
|
-
if (
|
|
404
|
+
if (
|
|
405
|
+
slots == null ||
|
|
406
|
+
typeof slots !== 'object' ||
|
|
407
|
+
Object.keys(slots).length === 0
|
|
408
|
+
) {
|
|
388
409
|
problems.push('slots: expected at least one slot');
|
|
389
410
|
return problems;
|
|
390
411
|
}
|
|
@@ -392,7 +413,10 @@ export function problemsInNamespace(doc) {
|
|
|
392
413
|
if (typeof slot?.title !== 'string' || slot.title === '') {
|
|
393
414
|
problems.push(`slots.${name}.title: expected a non-empty string`);
|
|
394
415
|
}
|
|
395
|
-
if (
|
|
416
|
+
if (
|
|
417
|
+
!Array.isArray(slot?.accepts?.kinds) ||
|
|
418
|
+
slot.accepts.kinds.length === 0
|
|
419
|
+
) {
|
|
396
420
|
problems.push(`slots.${name}.accepts.kinds: expected at least one kind`);
|
|
397
421
|
}
|
|
398
422
|
}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Resolve the project's own `typescript`, trying each directory in order
|
|
5
|
+
* Resolve the project's own `typescript`, trying each directory in order;
|
|
6
|
+
* where it has no JavaScript compiler API (TypeScript 7), the TypeScript 6
|
|
7
|
+
* API package installed beside it.
|
|
6
8
|
* @param {Array<string | null | undefined>} dirs
|
|
7
9
|
* @returns {{ts: any, version: string} | {ts: null, version: string} | null}
|
|
8
10
|
* `ts: null` when a TypeScript is installed but has no `createProgram`
|
|
@@ -16,8 +18,15 @@ export function resolveProjectTypeScript(dirs: Array<string | null | undefined>)
|
|
|
16
18
|
} | null;
|
|
17
19
|
/**
|
|
18
20
|
* Why a check that needs the compiler did not run, when the TypeScript
|
|
19
|
-
* installed has no JavaScript compiler API.
|
|
21
|
+
* installed has no JavaScript compiler API, and what to do.
|
|
20
22
|
* @param {string} version
|
|
21
23
|
* @param {string} outcome what was not done, such as `docs were not checked`
|
|
22
24
|
*/
|
|
23
25
|
export function unusableTypeScriptReason(version: string, outcome: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* What to do when the project's TypeScript is missing or cannot be used:
|
|
28
|
+
* beside TypeScript 7, the TypeScript 6 API package it ships for tools;
|
|
29
|
+
* otherwise a version every check here reads, 5.0 (the oldest that checks a
|
|
30
|
+
* JavaScript doc) through 6.
|
|
31
|
+
*/
|
|
32
|
+
export const TYPESCRIPT_FIX: "On TypeScript 7, add its TypeScript 6 API package (`npm install -D @typescript/typescript6`); otherwise install TypeScript 5.0 through 6 (`npm install -D typescript@6`). Then run this check again.";
|
|
@@ -15,7 +15,16 @@ import * as path from 'node:path';
|
|
|
15
15
|
import {createRequire} from 'node:module';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* The package TypeScript publishes beside TypeScript 7 for tools that need a
|
|
19
|
+
* JavaScript compiler API: TypeScript 6's. Kept in a constant so the type
|
|
20
|
+
* check does not treat the load as a static import of an uninstalled package.
|
|
21
|
+
*/
|
|
22
|
+
const TYPESCRIPT_6_API = '@typescript/typescript6';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the project's own `typescript`, trying each directory in order;
|
|
26
|
+
* where it has no JavaScript compiler API (TypeScript 7), the TypeScript 6
|
|
27
|
+
* API package installed beside it.
|
|
19
28
|
* @param {Array<string | null | undefined>} dirs
|
|
20
29
|
* @returns {{ts: any, version: string} | {ts: null, version: string} | null}
|
|
21
30
|
* `ts: null` when a TypeScript is installed but has no `createProgram`
|
|
@@ -43,19 +52,38 @@ export function resolveProjectTypeScript(dirs) {
|
|
|
43
52
|
unusable ??= installed();
|
|
44
53
|
} catch {
|
|
45
54
|
// Not installed from here, or installed without an entry this CLI can
|
|
46
|
-
// load
|
|
55
|
+
// load.
|
|
47
56
|
unusable ??= installed();
|
|
48
57
|
}
|
|
58
|
+
// TypeScript 7 has no JavaScript compiler API; the package TypeScript
|
|
59
|
+
// ships beside it for tools that need one carries TypeScript 6's.
|
|
60
|
+
try {
|
|
61
|
+
const ts = require(TYPESCRIPT_6_API);
|
|
62
|
+
if (ts && typeof ts.createProgram === 'function') {
|
|
63
|
+
return {ts, version: String(ts.version)};
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
// Not installed from here; try the next directory.
|
|
67
|
+
}
|
|
49
68
|
}
|
|
50
69
|
return unusable ? {ts: null, version: unusable} : null;
|
|
51
70
|
}
|
|
52
71
|
|
|
72
|
+
/**
|
|
73
|
+
* What to do when the project's TypeScript is missing or cannot be used:
|
|
74
|
+
* beside TypeScript 7, the TypeScript 6 API package it ships for tools;
|
|
75
|
+
* otherwise a version every check here reads, 5.0 (the oldest that checks a
|
|
76
|
+
* JavaScript doc) through 6.
|
|
77
|
+
*/
|
|
78
|
+
export const TYPESCRIPT_FIX =
|
|
79
|
+
'On TypeScript 7, add its TypeScript 6 API package (`npm install -D @typescript/typescript6`); otherwise install TypeScript 5.0 through 6 (`npm install -D typescript@6`). Then run this check again.';
|
|
80
|
+
|
|
53
81
|
/**
|
|
54
82
|
* Why a check that needs the compiler did not run, when the TypeScript
|
|
55
|
-
* installed has no JavaScript compiler API.
|
|
83
|
+
* installed has no JavaScript compiler API, and what to do.
|
|
56
84
|
* @param {string} version
|
|
57
85
|
* @param {string} outcome what was not done, such as `docs were not checked`
|
|
58
86
|
*/
|
|
59
87
|
export function unusableTypeScriptReason(version, outcome) {
|
|
60
|
-
return `TypeScript ${version} is installed in this project, but it has no JavaScript compiler API (\`createProgram\`) to read types with, so ${outcome}
|
|
88
|
+
return `TypeScript ${version} is installed in this project, but it has no JavaScript compiler API (\`createProgram\`) to read types with (TypeScript 7 ships none), so ${outcome}. ${TYPESCRIPT_FIX}`;
|
|
61
89
|
}
|
|
@@ -25,7 +25,7 @@ export function comparePropDocs(components: PropDriftComponent[], options: {
|
|
|
25
25
|
loadDoc?: (docPath: string) => Promise<any>;
|
|
26
26
|
}): Promise<PropDriftReport>;
|
|
27
27
|
/**
|
|
28
|
-
* @typedef {'not_in_code' | 'not_in_doc' | 'required_mismatch' | 'type_mismatch'} PropDriftKind
|
|
28
|
+
* @typedef {'not_in_code' | 'not_in_doc' | 'required_mismatch' | 'type_mismatch' | 'default_mismatch'} PropDriftKind
|
|
29
29
|
*/
|
|
30
30
|
/**
|
|
31
31
|
* @typedef {object} PropDriftFinding
|
|
@@ -40,6 +40,9 @@ export function comparePropDocs(components: PropDriftComponent[], options: {
|
|
|
40
40
|
* @property {string} [codeType] the type as the source declares it
|
|
41
41
|
* @property {boolean} [docRequired]
|
|
42
42
|
* @property {boolean} [codeRequired]
|
|
43
|
+
* @property {string} [docDefault] the documented default, as written
|
|
44
|
+
* @property {string} [codeDefault] the literal default the code writes
|
|
45
|
+
* @property {string} [fix] what to change, ready to paste
|
|
43
46
|
*/
|
|
44
47
|
/**
|
|
45
48
|
* @typedef {object} PropDriftUnchecked
|
|
@@ -53,8 +56,10 @@ export function comparePropDocs(components: PropDriftComponent[], options: {
|
|
|
53
56
|
* @property {string} doc the doc file, relative to the package root
|
|
54
57
|
* @property {string} reason why: not a form the check judges exactly, a
|
|
55
58
|
* field the prop's variants give different types, a standard prop
|
|
56
|
-
* (`className`, `style`, …),
|
|
57
|
-
*
|
|
59
|
+
* (`className`, `style`, …), a prop declared outside the package, or a
|
|
60
|
+
* default that is not a literal on one side
|
|
61
|
+
* @property {string[]} props documented props whose types, or defaults, were
|
|
62
|
+
* not compared
|
|
58
63
|
*/
|
|
59
64
|
/**
|
|
60
65
|
* @typedef {object} PropDriftReport
|
|
@@ -96,7 +101,7 @@ export function comparePropDocs(components: PropDriftComponent[], options: {
|
|
|
96
101
|
*/
|
|
97
102
|
export const PROPS_NOT_DOCUMENTED: readonly string[];
|
|
98
103
|
/** The line both surfaces print when the compiler is missing. */
|
|
99
|
-
export const TYPESCRIPT_MISSING_REASON: "TypeScript is not installed in this project, so documented props were not compared with the code.
|
|
104
|
+
export const TYPESCRIPT_MISSING_REASON: "TypeScript is not installed in this project, so documented props were not compared with the code. On TypeScript 7, add its TypeScript 6 API package (`npm install -D @typescript/typescript6`); otherwise install TypeScript 5.0 through 6 (`npm install -D typescript@6`). Then run this check again.";
|
|
100
105
|
export type CodeProp = {
|
|
101
106
|
name: string;
|
|
102
107
|
/**
|
|
@@ -146,7 +151,7 @@ export type CodeProp = {
|
|
|
146
151
|
*/
|
|
147
152
|
location: any;
|
|
148
153
|
};
|
|
149
|
-
export type PropDriftKind = "not_in_code" | "not_in_doc" | "required_mismatch" | "type_mismatch";
|
|
154
|
+
export type PropDriftKind = "not_in_code" | "not_in_doc" | "required_mismatch" | "type_mismatch" | "default_mismatch";
|
|
150
155
|
export type PropDriftFinding = {
|
|
151
156
|
/**
|
|
152
157
|
* the documented component (export) name
|
|
@@ -174,6 +179,18 @@ export type PropDriftFinding = {
|
|
|
174
179
|
codeType?: string | undefined;
|
|
175
180
|
docRequired?: boolean | undefined;
|
|
176
181
|
codeRequired?: boolean | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* the documented default, as written
|
|
184
|
+
*/
|
|
185
|
+
docDefault?: string | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* the literal default the code writes
|
|
188
|
+
*/
|
|
189
|
+
codeDefault?: string | undefined;
|
|
190
|
+
/**
|
|
191
|
+
* what to change, ready to paste
|
|
192
|
+
*/
|
|
193
|
+
fix?: string | undefined;
|
|
177
194
|
};
|
|
178
195
|
export type PropDriftUnchecked = {
|
|
179
196
|
component: string;
|
|
@@ -195,11 +212,13 @@ export type PropDriftTypesNotCompared = {
|
|
|
195
212
|
/**
|
|
196
213
|
* why: not a form the check judges exactly, a
|
|
197
214
|
* field the prop's variants give different types, a standard prop
|
|
198
|
-
* (`className`, `style`, …),
|
|
215
|
+
* (`className`, `style`, …), a prop declared outside the package, or a
|
|
216
|
+
* default that is not a literal on one side
|
|
199
217
|
*/
|
|
200
218
|
reason: string;
|
|
201
219
|
/**
|
|
202
|
-
* documented props whose types
|
|
220
|
+
* documented props whose types, or defaults, were
|
|
221
|
+
* not compared
|
|
203
222
|
*/
|
|
204
223
|
props: string[];
|
|
205
224
|
};
|
|
@@ -31,7 +31,11 @@
|
|
|
31
31
|
* each);
|
|
32
32
|
* - `type_mismatch`: for a prop declared in the package, the documented type
|
|
33
33
|
* differs from the code's where both sides read exactly (type-match.mjs
|
|
34
|
-
* states the rules); every other type is listed as not compared
|
|
34
|
+
* states the rules); every other type is listed as not compared;
|
|
35
|
+
* - `default_mismatch`: the doc's `default` and the literal default the
|
|
36
|
+
* component writes in its props parameter's destructuring (`size = 'md'`)
|
|
37
|
+
* differ, quotes and whitespace aside; where both write a default and
|
|
38
|
+
* either is not a literal, it is listed under `typesNotCompared`.
|
|
35
39
|
*
|
|
36
40
|
* @input Component records (name, docPath, sourcePath), or prop tables, the
|
|
37
41
|
* package root, and the directories to resolve `typescript` from.
|
|
@@ -47,6 +51,7 @@ import {loadComponentDoc} from './component-loader.mjs';
|
|
|
47
51
|
import {readPackageTsconfig} from './package-tsconfig.mjs';
|
|
48
52
|
import {
|
|
49
53
|
resolveProjectTypeScript,
|
|
54
|
+
TYPESCRIPT_FIX,
|
|
50
55
|
unusableTypeScriptReason,
|
|
51
56
|
} from './project-typescript.mjs';
|
|
52
57
|
import {judgeType} from './type-match.mjs';
|
|
@@ -57,7 +62,7 @@ import {
|
|
|
57
62
|
} from './unresolved-references.mjs';
|
|
58
63
|
|
|
59
64
|
/**
|
|
60
|
-
* @typedef {'not_in_code' | 'not_in_doc' | 'required_mismatch' | 'type_mismatch'} PropDriftKind
|
|
65
|
+
* @typedef {'not_in_code' | 'not_in_doc' | 'required_mismatch' | 'type_mismatch' | 'default_mismatch'} PropDriftKind
|
|
61
66
|
*/
|
|
62
67
|
|
|
63
68
|
/**
|
|
@@ -73,6 +78,9 @@ import {
|
|
|
73
78
|
* @property {string} [codeType] the type as the source declares it
|
|
74
79
|
* @property {boolean} [docRequired]
|
|
75
80
|
* @property {boolean} [codeRequired]
|
|
81
|
+
* @property {string} [docDefault] the documented default, as written
|
|
82
|
+
* @property {string} [codeDefault] the literal default the code writes
|
|
83
|
+
* @property {string} [fix] what to change, ready to paste
|
|
76
84
|
*/
|
|
77
85
|
|
|
78
86
|
/**
|
|
@@ -88,8 +96,10 @@ import {
|
|
|
88
96
|
* @property {string} doc the doc file, relative to the package root
|
|
89
97
|
* @property {string} reason why: not a form the check judges exactly, a
|
|
90
98
|
* field the prop's variants give different types, a standard prop
|
|
91
|
-
* (`className`, `style`, …),
|
|
92
|
-
*
|
|
99
|
+
* (`className`, `style`, …), a prop declared outside the package, or a
|
|
100
|
+
* default that is not a literal on one side
|
|
101
|
+
* @property {string[]} props documented props whose types, or defaults, were
|
|
102
|
+
* not compared
|
|
93
103
|
*/
|
|
94
104
|
|
|
95
105
|
/**
|
|
@@ -148,6 +158,15 @@ const SKIP_TAGS = new Set(['internal']);
|
|
|
148
158
|
const NOT_EXACT = 'not a form the check judges exactly';
|
|
149
159
|
/** A field documented with one variant's type, where they differ. */
|
|
150
160
|
const VARIANTS = "the prop's variants give this field different types";
|
|
161
|
+
|
|
162
|
+
/** A default the code writes that is not a literal (a constant, a call). */
|
|
163
|
+
const NOT_LITERAL = Symbol('not a literal');
|
|
164
|
+
|
|
165
|
+
/** Why a documented default was not compared with the code's. */
|
|
166
|
+
const CODE_DEFAULT_NOT_LITERAL =
|
|
167
|
+
'its default in the code is not a literal, so the documented default was not compared';
|
|
168
|
+
const DOC_DEFAULT_NOT_LITERAL =
|
|
169
|
+
"its documented default is not a literal, so it was not compared with the code's";
|
|
151
170
|
/** @type {(name: string, code?: CodeProp) => string} why a prop is not judged */
|
|
152
171
|
const outside = (name, code) =>
|
|
153
172
|
code?.untraced
|
|
@@ -158,8 +177,7 @@ const outside = (name, code) =>
|
|
|
158
177
|
const HOOK_NAME = /^use[A-Z0-9]/;
|
|
159
178
|
|
|
160
179
|
/** The line both surfaces print when the compiler is missing. */
|
|
161
|
-
export const TYPESCRIPT_MISSING_REASON =
|
|
162
|
-
'TypeScript is not installed in this project, so documented props were not compared with the code. Install typescript and run this check again.';
|
|
180
|
+
export const TYPESCRIPT_MISSING_REASON = `TypeScript is not installed in this project, so documented props were not compared with the code. ${TYPESCRIPT_FIX}`;
|
|
163
181
|
|
|
164
182
|
/**
|
|
165
183
|
* @template T
|
|
@@ -252,7 +270,7 @@ function ownFileTest(root) {
|
|
|
252
270
|
* @param {import('./unresolved-references.mjs').UnresolvedReference | null} ambient
|
|
253
271
|
* what the program's other roots cannot resolve, which any component may
|
|
254
272
|
* use
|
|
255
|
-
* @returns {{ok: true, props: Map<string, CodeProp>, accepts: (name: string) => any} | {ok: false, reason: string}}
|
|
273
|
+
* @returns {{ok: true, props: Map<string, CodeProp>, accepts: (name: string) => any, defaults?: Map<string, string | number | boolean | null | symbol>} | {ok: false, reason: string}}
|
|
256
274
|
*/
|
|
257
275
|
function readCodeProps(
|
|
258
276
|
ts,
|
|
@@ -580,7 +598,118 @@ function readCodeProps(
|
|
|
580
598
|
/** The index signatures of the props type that take this name. */
|
|
581
599
|
const accepts = (/** @type {string} */ name) =>
|
|
582
600
|
indexesFor(ts, checker, members, name);
|
|
583
|
-
return {ok: true, props, accepts};
|
|
601
|
+
return {ok: true, props, accepts, defaults: literalDefaults(ts, symbol)};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* The defaults a component writes in its props parameter's destructuring
|
|
606
|
+
* (`{size = 'md'}`), by prop name, each as its value: a string, number,
|
|
607
|
+
* boolean, or null, or NOT_LITERAL for any other default (a constant, a call,
|
|
608
|
+
* an object), which is listed as not compared.
|
|
609
|
+
* @param {any} ts
|
|
610
|
+
* @param {any} symbol the component
|
|
611
|
+
* @returns {Map<string, string | number | boolean | null | symbol>}
|
|
612
|
+
*/
|
|
613
|
+
function literalDefaults(ts, symbol) {
|
|
614
|
+
/** @type {Map<string, string | number | boolean | null | symbol>} */
|
|
615
|
+
const out = new Map();
|
|
616
|
+
/** @param {any} node @param {number} depth @returns {any} */
|
|
617
|
+
const fnOf = (node, depth) => {
|
|
618
|
+
if (!node || depth > 4) return null;
|
|
619
|
+
if (
|
|
620
|
+
ts.isFunctionDeclaration(node) ||
|
|
621
|
+
ts.isArrowFunction(node) ||
|
|
622
|
+
ts.isFunctionExpression(node)
|
|
623
|
+
) {
|
|
624
|
+
return node;
|
|
625
|
+
}
|
|
626
|
+
if (ts.isVariableDeclaration(node))
|
|
627
|
+
return fnOf(node.initializer, depth + 1);
|
|
628
|
+
if (
|
|
629
|
+
ts.isParenthesizedExpression(node) ||
|
|
630
|
+
ts.isAsExpression(node) ||
|
|
631
|
+
(ts.isSatisfiesExpression && ts.isSatisfiesExpression(node))
|
|
632
|
+
) {
|
|
633
|
+
return fnOf(node.expression, depth + 1);
|
|
634
|
+
}
|
|
635
|
+
// `forwardRef(function …)`, `memo(…)`: the function they wrap.
|
|
636
|
+
if (ts.isCallExpression(node)) {
|
|
637
|
+
for (const argument of node.arguments) {
|
|
638
|
+
const found = fnOf(argument, depth + 1);
|
|
639
|
+
if (found) return found;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
return null;
|
|
643
|
+
};
|
|
644
|
+
const fn = fnOf(symbol?.valueDeclaration, 0);
|
|
645
|
+
const pattern = fn?.parameters?.[0]?.name;
|
|
646
|
+
if (!pattern || !ts.isObjectBindingPattern(pattern)) return out;
|
|
647
|
+
for (const element of pattern.elements) {
|
|
648
|
+
if (element.dotDotDotToken || !element.initializer) continue;
|
|
649
|
+
const key = element.propertyName ?? element.name;
|
|
650
|
+
if (!(
|
|
651
|
+
ts.isIdentifier(key) ||
|
|
652
|
+
ts.isStringLiteral(key) ||
|
|
653
|
+
ts.isNumericLiteral(key)
|
|
654
|
+
)) {
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
const value = literalValue(ts, element.initializer);
|
|
658
|
+
out.set(key.text, value === undefined ? NOT_LITERAL : value);
|
|
659
|
+
}
|
|
660
|
+
return out;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* A literal expression's value, or undefined for anything else.
|
|
665
|
+
* @param {any} ts
|
|
666
|
+
* @param {any} node
|
|
667
|
+
* @returns {string | number | boolean | null | undefined}
|
|
668
|
+
*/
|
|
669
|
+
function literalValue(ts, node) {
|
|
670
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
671
|
+
return node.text;
|
|
672
|
+
}
|
|
673
|
+
if (ts.isNumericLiteral(node)) return Number(node.text);
|
|
674
|
+
if (
|
|
675
|
+
ts.isPrefixUnaryExpression(node) &&
|
|
676
|
+
node.operator === ts.SyntaxKind.MinusToken &&
|
|
677
|
+
ts.isNumericLiteral(node.operand)
|
|
678
|
+
) {
|
|
679
|
+
return -Number(node.operand.text);
|
|
680
|
+
}
|
|
681
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword) return true;
|
|
682
|
+
if (node.kind === ts.SyntaxKind.FalseKeyword) return false;
|
|
683
|
+
if (node.kind === ts.SyntaxKind.NullKeyword) return null;
|
|
684
|
+
return undefined;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* A documented default as a literal value: a quoted string (quotes of any
|
|
689
|
+
* kind, whitespace around it ignored), a number, `true`, `false`, or
|
|
690
|
+
* `null`; undefined for prose or an expression, which is never compared.
|
|
691
|
+
* @param {unknown} written
|
|
692
|
+
* @returns {string | number | boolean | null | undefined}
|
|
693
|
+
*/
|
|
694
|
+
function documentedDefault(written) {
|
|
695
|
+
if (typeof written === 'number' || typeof written === 'boolean') {
|
|
696
|
+
return written;
|
|
697
|
+
}
|
|
698
|
+
if (written === null) return null;
|
|
699
|
+
if (typeof written !== 'string') return undefined;
|
|
700
|
+
const text = written.trim();
|
|
701
|
+
const quoted = /^(['"`])([^'"`]*)\1$/.exec(text);
|
|
702
|
+
if (quoted) return quoted[2];
|
|
703
|
+
if (/^-?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(text)) return Number(text);
|
|
704
|
+
if (text === 'true') return true;
|
|
705
|
+
if (text === 'false') return false;
|
|
706
|
+
if (text === 'null') return null;
|
|
707
|
+
return undefined;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/** @param {string | number | boolean | null} value */
|
|
711
|
+
function defaultText(value) {
|
|
712
|
+
return typeof value === 'string' ? `'${value}'` : String(value);
|
|
584
713
|
}
|
|
585
714
|
|
|
586
715
|
/**
|
|
@@ -1952,6 +2081,42 @@ export function comparePropTables(tables, options) {
|
|
|
1952
2081
|
codeRequired: code.required,
|
|
1953
2082
|
});
|
|
1954
2083
|
}
|
|
2084
|
+
// A literal default the code writes in its props destructuring and a
|
|
2085
|
+
// literal the doc writes must agree; where both write a default and
|
|
2086
|
+
// either is not a literal, the default is listed as not compared.
|
|
2087
|
+
const codeDefault = read.defaults?.get(propName);
|
|
2088
|
+
const docWrites =
|
|
2089
|
+
entries.length === 1 &&
|
|
2090
|
+
raw.default !== undefined &&
|
|
2091
|
+
raw.default !== '';
|
|
2092
|
+
const docDefault = docWrites
|
|
2093
|
+
? documentedDefault(raw.default)
|
|
2094
|
+
: undefined;
|
|
2095
|
+
if (codeDefault !== undefined && docWrites) {
|
|
2096
|
+
if (codeDefault === NOT_LITERAL) {
|
|
2097
|
+
skip(CODE_DEFAULT_NOT_LITERAL, propName);
|
|
2098
|
+
} else if (docDefault === undefined) {
|
|
2099
|
+
skip(DOC_DEFAULT_NOT_LITERAL, propName);
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
if (
|
|
2103
|
+
codeDefault !== undefined &&
|
|
2104
|
+
codeDefault !== NOT_LITERAL &&
|
|
2105
|
+
docDefault !== undefined &&
|
|
2106
|
+
codeDefault !== docDefault
|
|
2107
|
+
) {
|
|
2108
|
+
const shown = defaultText(
|
|
2109
|
+
/** @type {string | number | boolean | null} */ (codeDefault),
|
|
2110
|
+
);
|
|
2111
|
+
findings.push({
|
|
2112
|
+
...base,
|
|
2113
|
+
kind: 'default_mismatch',
|
|
2114
|
+
message: `"${propName}" is documented with default ${String(raw.default).trim()}, but the code defaults it to ${shown}.`,
|
|
2115
|
+
fix: `In ${table.doc}, set the "${propName}" prop's default to the code's: default: ${JSON.stringify(shown)}.`,
|
|
2116
|
+
docDefault: String(raw.default),
|
|
2117
|
+
codeDefault: shown,
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
1955
2120
|
if (!code.own && typeof entry.type === 'string') {
|
|
1956
2121
|
skip(outside(propName, code), propName);
|
|
1957
2122
|
}
|
|
@@ -58,6 +58,37 @@ function withTypeScript() {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* TypeScript 7 (no JavaScript compiler API) with the TypeScript 6 API package
|
|
63
|
+
* beside it, which re-exports a real TypeScript.
|
|
64
|
+
*/
|
|
65
|
+
function withTypeScript7AndItsTypeScript6Api() {
|
|
66
|
+
const ts7 = path.join(pkg, 'node_modules', 'typescript');
|
|
67
|
+
fs.mkdirSync(ts7, {recursive: true});
|
|
68
|
+
fs.writeFileSync(
|
|
69
|
+
path.join(ts7, 'package.json'),
|
|
70
|
+
JSON.stringify({
|
|
71
|
+
name: 'typescript',
|
|
72
|
+
version: '7.0.2',
|
|
73
|
+
exports: {'./package.json': './package.json'},
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
const ts6 = path.join(pkg, 'node_modules', '@typescript', 'typescript6');
|
|
77
|
+
fs.mkdirSync(ts6, {recursive: true});
|
|
78
|
+
fs.writeFileSync(
|
|
79
|
+
path.join(ts6, 'package.json'),
|
|
80
|
+
JSON.stringify({
|
|
81
|
+
name: '@typescript/typescript6',
|
|
82
|
+
version: '6.0.2',
|
|
83
|
+
main: 'index.js',
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
|
+
fs.writeFileSync(
|
|
87
|
+
path.join(ts6, 'index.js'),
|
|
88
|
+
`module.exports = require(${JSON.stringify(TYPESCRIPT_DIR)});\n`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
61
92
|
/**
|
|
62
93
|
* Write `components/<name>.tsx` and its doc; returns its prop table, which
|
|
63
94
|
* also carries the component record (name, docPath, sourcePath).
|
|
@@ -176,7 +207,8 @@ describe('comparePropTables', () => {
|
|
|
176
207
|
expect(await compare([component('Badge', source, doc)])).toMatchObject({
|
|
177
208
|
findings: [],
|
|
178
209
|
typesCompared: 0,
|
|
179
|
-
typesSkipped:
|
|
210
|
+
typesSkipped:
|
|
211
|
+
'TypeScript 4.7.4 is older than 4.8, the oldest the type comparison reads; install TypeScript 5.0 through 6 (`npm install -D typescript@6`), or on TypeScript 7 add `@typescript/typescript6`, to judge them',
|
|
180
212
|
});
|
|
181
213
|
});
|
|
182
214
|
|
|
@@ -334,6 +366,71 @@ export function Badge(props: BadgeProps) { return null; }`,
|
|
|
334
366
|
).toMatchObject({docRequired: false, codeRequired: true});
|
|
335
367
|
});
|
|
336
368
|
|
|
369
|
+
it('compares a documented default with a literal default in the props destructuring, quotes and whitespace aside, and skips any other default', async () => {
|
|
370
|
+
withTypeScript();
|
|
371
|
+
const widget = component(
|
|
372
|
+
'Widget',
|
|
373
|
+
`const SIZE = 'md';
|
|
374
|
+
export interface WidgetProps { size?: 'sm' | 'md'; tone?: string; count?: number; open?: boolean; label?: string; gap?: number; mode?: string }
|
|
375
|
+
export function Widget({size = 'md', tone = "info", count = -2, open = false, label = SIZE, gap = 4, mode}: WidgetProps) { return null; }`,
|
|
376
|
+
{
|
|
377
|
+
props: [
|
|
378
|
+
prop('size', "'sm' | 'md'", {default: "'sm'"}),
|
|
379
|
+
prop('tone', 'string', {default: ' "info" '}),
|
|
380
|
+
prop('count', 'number', {default: '-2'}),
|
|
381
|
+
prop('open', 'boolean', {default: 'true'}),
|
|
382
|
+
prop('label', 'string', {default: "'x'"}),
|
|
383
|
+
prop('gap', 'number', {default: 'the theme gap'}),
|
|
384
|
+
prop('mode', 'string', {default: "'a'"}),
|
|
385
|
+
],
|
|
386
|
+
},
|
|
387
|
+
);
|
|
388
|
+
const forwarded = component(
|
|
389
|
+
'Forwarded',
|
|
390
|
+
`declare function forwardRef<T>(render: T): T;
|
|
391
|
+
export const Forwarded = forwardRef(function Forwarded({variant = 'solid'}: {variant?: string}) { return null; });`,
|
|
392
|
+
{props: [prop('variant', 'string', {default: "'ghost'"})]},
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
const report = await compare([widget, forwarded]);
|
|
396
|
+
|
|
397
|
+
expect(kinds(report)).toEqual([
|
|
398
|
+
'Forwarded.variant default_mismatch',
|
|
399
|
+
'Widget.open default_mismatch',
|
|
400
|
+
'Widget.size default_mismatch',
|
|
401
|
+
]);
|
|
402
|
+
// A default that is not a literal on either side is listed, not skipped.
|
|
403
|
+
expect(report.typesNotCompared).toEqual(
|
|
404
|
+
expect.arrayContaining([
|
|
405
|
+
expect.objectContaining({
|
|
406
|
+
component: 'Widget',
|
|
407
|
+
reason: expect.stringContaining(
|
|
408
|
+
'default in the code is not a literal',
|
|
409
|
+
),
|
|
410
|
+
props: ['label'],
|
|
411
|
+
}),
|
|
412
|
+
expect.objectContaining({
|
|
413
|
+
component: 'Widget',
|
|
414
|
+
reason: expect.stringContaining(
|
|
415
|
+
'documented default is not a literal',
|
|
416
|
+
),
|
|
417
|
+
props: ['gap'],
|
|
418
|
+
}),
|
|
419
|
+
]),
|
|
420
|
+
);
|
|
421
|
+
expect(report.typesNotCompared.flatMap(entry => entry.props)).not.toContain(
|
|
422
|
+
'mode',
|
|
423
|
+
);
|
|
424
|
+
expect(report.findings.find(f => f.prop === 'size')).toMatchObject({
|
|
425
|
+
severity: 'warning',
|
|
426
|
+
message:
|
|
427
|
+
"\"size\" is documented with default 'sm', but the code defaults it to 'md'.",
|
|
428
|
+
fix: 'In components/Widget.doc.mjs, set the "size" prop\'s default to the code\'s: default: "\'md\'".',
|
|
429
|
+
docDefault: "'sm'",
|
|
430
|
+
codeDefault: "'md'",
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
|
|
337
434
|
it("judges a field, a name an index signature takes, and a prop declared in another file by the type's name where the prop is declared, not by the name the type was declared with", async () => {
|
|
338
435
|
withTypeScript();
|
|
339
436
|
const dir = path.join(pkg, 'components');
|
|
@@ -2179,6 +2276,23 @@ export const Hoc = withName((props: {label?: string}) => null);`;
|
|
|
2179
2276
|
]);
|
|
2180
2277
|
});
|
|
2181
2278
|
|
|
2279
|
+
it("compares with TypeScript 7's TypeScript 6 API package when the project has one", async () => {
|
|
2280
|
+
const badge = component(
|
|
2281
|
+
'Badge',
|
|
2282
|
+
'export function Badge(props: {label: string}) { return null; }\n',
|
|
2283
|
+
{props: [prop('label', 'number')]},
|
|
2284
|
+
);
|
|
2285
|
+
withTypeScript7AndItsTypeScript6Api();
|
|
2286
|
+
|
|
2287
|
+
const report = await compare([badge]);
|
|
2288
|
+
|
|
2289
|
+
expect(report.status).toBe('checked');
|
|
2290
|
+
// The comparison ran: the documented `number` is judged against `string`.
|
|
2291
|
+
expect(
|
|
2292
|
+
report.findings.map(f => `${f.component}.${f.prop} ${f.kind}`),
|
|
2293
|
+
).toContain('Badge.label type_mismatch');
|
|
2294
|
+
});
|
|
2295
|
+
|
|
2182
2296
|
it('skips with a reason, and compares nothing, without a TypeScript it can use', async () => {
|
|
2183
2297
|
const badge = component(
|
|
2184
2298
|
'Badge',
|
|
@@ -2196,6 +2310,7 @@ export const Hoc = withName((props: {label?: string}) => null);`;
|
|
|
2196
2310
|
});
|
|
2197
2311
|
|
|
2198
2312
|
expect(await compare([badge])).toEqual(skipped(TYPESCRIPT_MISSING_REASON));
|
|
2313
|
+
expect(TYPESCRIPT_MISSING_REASON).toContain('npm install -D typescript@6');
|
|
2199
2314
|
// TypeScript 7 has no JavaScript compiler API to load.
|
|
2200
2315
|
const dir = path.join(pkg, 'node_modules', 'typescript');
|
|
2201
2316
|
fs.mkdirSync(dir, {recursive: true});
|
|
@@ -2207,7 +2322,10 @@ export const Hoc = withName((props: {label?: string}) => null);`;
|
|
|
2207
2322
|
exports: {'./package.json': './package.json'},
|
|
2208
2323
|
}),
|
|
2209
2324
|
);
|
|
2210
|
-
|
|
2325
|
+
const report = await compare([badge]);
|
|
2326
|
+
expect(report.reason).toContain('TypeScript 7.0.0');
|
|
2327
|
+
expect(report.reason).toContain('npm install -D @typescript/typescript6');
|
|
2328
|
+
expect(report).toEqual(
|
|
2211
2329
|
skipped(
|
|
2212
2330
|
unusableTypeScriptReason(
|
|
2213
2331
|
'7.0.0',
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file Where a runner may stand in front of an Astryx command in Astryx's own
|
|
6
|
+
* docs. Docs write commands bare (`astryx <command>`): the CLI prefixes each
|
|
7
|
+
* one with the reader's command when it prints a doc, and the docsite with
|
|
8
|
+
* `npx @astryxdesign/cli`. A few files show a runner on purpose, and some files
|
|
9
|
+
* are not docs at all. The rules, checked by test/runner-commands.test.mjs:
|
|
10
|
+
*
|
|
11
|
+
* - npx (or another download runner) with the unscoped name `astryx` is never
|
|
12
|
+
* written outside `skip`: it fetches an unrelated npm package.
|
|
13
|
+
* - In a doc (`*.doc.mjs`, and Core's docs.mjs), no runner precedes an Astryx
|
|
14
|
+
* command, except in `runnerExamples`, where `npx @astryxdesign/cli …` and a
|
|
15
|
+
* project's runner may (still never the unscoped name through npx).
|
|
16
|
+
*
|
|
17
|
+
* TODO(doctor-runner-check): the Doctor lane's integration-docs runner check
|
|
18
|
+
* (foundation/discovery/runner-commands.mjs) becomes the single rule; then the
|
|
19
|
+
* repo test runs that check over Core's and the CLI's own docs with this
|
|
20
|
+
* allowlist.
|
|
21
|
+
*
|
|
22
|
+
* @input nothing
|
|
23
|
+
* @output the allowlist
|
|
24
|
+
* @position packages/cli/foundation/discovery — data shared by the repo test
|
|
25
|
+
* and the Doctor runner check
|
|
26
|
+
*/
|
|
27
|
+
export const RUNNER_COMMAND_ALLOWLIST: Readonly<{
|
|
28
|
+
/** Files never scanned: release notes, tests, and the helpers that build runner forms. */
|
|
29
|
+
skip: readonly RegExp[];
|
|
30
|
+
/** Docs that show a runner on purpose, and why. */
|
|
31
|
+
runnerExamples: Readonly<{
|
|
32
|
+
'packages/core/docs.mjs': "Core's setup banner, for a project that has no CLI installed yet";
|
|
33
|
+
'packages/cli/assets/docs/tree/updates.doc.mjs': "quotes the CLI's own update notice, which names the project's runner";
|
|
34
|
+
'packages/cli/assets/docs/tree/cli-command.doc.mjs': "explains how printed commands start, the pinned `npx @astryxdesign/cli@<version>` among them";
|
|
35
|
+
'packages/cli/assets/docs/tree/who-answers.doc.mjs': "explains how printed commands start, the pinned `npx @astryxdesign/cli@<version>` among them";
|
|
36
|
+
'packages/cli/assets/docs/tree/project-global-or-both.doc.mjs': "compares running the CLI with npx to installing it, and is found by searching for that command";
|
|
37
|
+
'packages/cli/assets/docs/tree/install-once.doc.mjs': "names a pinned release, `npx @astryxdesign/cli@<version>`, which answers as that version";
|
|
38
|
+
'packages/cli/clients/cli/commands/upgrade.doc.mjs': "quotes the command upgrade prints when the CLI is older than Core, pinned to the matching release";
|
|
39
|
+
}>;
|
|
40
|
+
}>;
|