@astryxdesign/cli 0.6.3-canary.db4e378 → 0.6.3-canary.db52d98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -15
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/_adapter.d.mts +50 -0
- package/api/build/_adapter.mjs +60 -0
- package/api/build/build.doc.mjs +14 -7
- package/api/build/build.test.mjs +184 -6
- package/api/build/build.type.d.mts +57 -2
- package/api/build/build.type.mjs +30 -7
- package/api/build/help/help.d.mts +4 -0
- package/api/build/help/help.mjs +24 -11
- package/api/build/kit/kit.d.mts +4 -1
- package/api/build/kit/kit.mjs +165 -49
- package/api/build/kit/rank.d.mts +44 -0
- package/api/build/kit/rank.mjs +432 -0
- package/api/build/kit/rank.test.mjs +196 -0
- package/api/component/_adapter.d.mts +6 -12
- package/api/component/_adapter.mjs +20 -10
- package/api/component/component.doc.mjs +1 -0
- package/api/component/component.mjs +60 -12
- package/api/component/list/list.mjs +3 -2
- package/api/discover/discover.doc.mjs +1 -0
- package/api/docs/_adapter.d.mts +252 -34
- package/api/docs/_adapter.mjs +923 -132
- package/api/docs/detail/detail.mjs +11 -3
- package/api/docs/detail/section/section.mjs +24 -13
- package/api/docs/detail/section/section.test.mjs +15 -6
- package/api/docs/docs.d.mts +5 -3
- package/api/docs/docs.doc.mjs +39 -17
- package/api/docs/docs.mjs +44 -8
- package/api/docs/docs.test.mjs +158 -4
- package/api/docs/docs.type.d.mts +181 -2
- package/api/docs/docs.type.mjs +117 -3
- package/api/docs/index/index.mjs +11 -3
- package/api/docs/index/index.test.mjs +1 -1
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +14 -14
- package/api/docs/list/list.mjs +28 -12
- package/api/docs/node/node.d.mts +43 -0
- package/api/docs/node/node.mjs +192 -0
- package/api/docs/reference-blocks.test.mjs +406 -0
- package/api/doctor/doctor.d.mts +54 -4
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +331 -16
- package/api/doctor/doctor.test.mjs +420 -7
- package/api/gap-report/gap-report.doc.mjs +1 -0
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/hook/list/list.mjs +69 -17
- package/api/index.d.mts +1 -1
- package/api/index.mjs +1 -0
- package/api/init/init.doc.mjs +2 -1
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +114 -12
- package/api/integration/add-contribution.test.mjs +174 -3
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.mjs +138 -28
- package/api/integration/authoring-checks.test.mjs +179 -7
- package/api/integration/authoring-checks.type.mjs +6 -1
- package/api/integration/integration-authoring.type.d.mts +2 -0
- package/api/integration/integration-authoring.type.mjs +2 -0
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +7 -0
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +1 -0
- package/api/integration/integrationAddDoc.doc.mjs +8 -1
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +2 -1
- package/api/integration/integrationPackCheck.doc.mjs +2 -1
- package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
- package/api/integration/pack-check.mjs +34 -0
- package/api/integration/pack-check.test.mjs +138 -47
- package/api/integration/pack-check.type.d.mts +26 -2
- package/api/integration/pack-check.type.mjs +14 -1
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/template-conflict-compatibility.test.mjs +73 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +50 -102
- package/api/integration/validate-integration.test.mjs +88 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +2 -1
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +1 -0
- package/api/layout/_adapter.mjs +20 -5
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +1 -0
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search.d.mts +59 -1
- package/api/search/search.doc.mjs +5 -3
- package/api/search/search.mjs +458 -77
- package/api/search/search.test.mjs +91 -2
- package/api/search/search.type.d.mts +13 -1
- package/api/search/search.type.mjs +4 -1
- package/api/swizzle/swizzle.doc.mjs +1 -0
- package/api/template/list/list.mjs +1 -0
- package/api/template/table-floating-bulk-actions.test.mjs +66 -0
- package/api/template/template-integration.test.mjs +1072 -3
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.doc.mjs +28 -7
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +6 -8
- package/api/template/template.type.mjs +3 -2
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +10 -17
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/template/template.test.mjs +5 -0
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +1 -0
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +97 -69
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/upgrade.doc.mjs +6 -1
- package/api/upgrade/upgrade.type.d.mts +34 -0
- package/api/upgrade/upgrade.type.mjs +15 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +8 -2
- package/assets/codemods/integration-discovery.test.mjs +15 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/next/index.mjs +19 -1
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/docs/getting-started.doc.mjs +2 -2
- package/assets/docs/layout.doc.dense.mjs +2 -2
- package/assets/docs/layout.doc.mjs +1 -1
- package/assets/docs/principles.doc.mjs +6 -6
- package/assets/docs/styling-libraries.doc.mjs +3 -3
- package/assets/docs/styling.doc.mjs +4 -4
- package/assets/docs/theme.doc.mjs +5 -5
- package/assets/docs/tokens.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +30 -0
- package/assets/docs/tree/cli.doc.mjs +23 -0
- package/assets/docs/tree/commands.doc.mjs +25 -0
- package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +66 -38
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/working-with-ai.doc.mjs +3 -3
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/codemod/codemod.doc.mjs +1 -1
- package/authoring/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +1 -1
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +3 -3
- package/authoring/doctypes/_schema.d.mts +119 -117
- package/authoring/doctypes/_schema.mjs +54 -3
- package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
- package/authoring/doctypes/base/type.ts +6 -5
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +2 -2
- package/authoring/doctypes/component/type.ts +2 -2
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +1 -1
- package/authoring/doctypes/function/function.doc.mjs +3 -2
- package/authoring/doctypes/function/type.ts +3 -2
- package/authoring/doctypes/hook/type.ts +2 -2
- package/authoring/doctypes/load-contract.test.mjs +28 -2
- package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
- package/authoring/doctypes/namespace/parse.test.mjs +23 -25
- package/authoring/doctypes/namespace/type.ts +5 -2
- package/authoring/doctypes/parse.d.mts +4 -2
- package/authoring/doctypes/parse.mjs +10 -5
- package/authoring/doctypes/reference/reference.doc.mjs +35 -6
- package/authoring/doctypes/reference/type.ts +30 -13
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +1 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +4 -0
- package/authoring/doctypes/template/parse.test.mjs +18 -0
- package/authoring/doctypes/template/template.doc.mjs +9 -3
- package/authoring/doctypes/template/type.ts +8 -0
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +2 -1
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/identity/identity.doc.mjs +2 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +7 -4
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.mjs +11 -45
- package/clients/cli/commands/build.doc.mjs +12 -7
- package/clients/cli/commands/build.mjs +105 -67
- package/clients/cli/commands/build.text-fields.test.mjs +41 -0
- package/clients/cli/commands/component/index.mjs +1 -1
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/discover.broken-integration.test.mjs +7 -8
- package/clients/cli/commands/discover.doc.mjs +1 -1
- package/clients/cli/commands/discover.mjs +1 -1
- package/clients/cli/commands/docs.doc.mjs +21 -9
- package/clients/cli/commands/docs.mjs +184 -70
- package/clients/cli/commands/docs.test.mjs +120 -16
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.test.mjs +90 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +53 -16
- package/clients/cli/commands/gap-report.doc.mjs +1 -1
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/init.doc.mjs +1 -1
- package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
- package/clients/cli/commands/integration-add.doc.mjs +11 -1
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/integration.mjs +1 -0
- package/clients/cli/commands/layout-check.doc.mjs +1 -1
- package/clients/cli/commands/layout-expand.doc.mjs +1 -1
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +1 -1
- package/clients/cli/commands/search.mjs +11 -2
- package/clients/cli/commands/setup-nudge.test.mjs +6 -0
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +24 -7
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/text-json-parity.test.mjs +719 -0
- package/clients/cli/commands/theme-add.doc.mjs +2 -2
- package/clients/cli/commands/theme-build.doc.mjs +1 -1
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.doc.mjs +1 -1
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +3 -2
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +2 -0
- package/clients/cli/formatters/index.test.mjs +6 -0
- package/clients/cli/index.mjs +8 -0
- package/clients/cli/lib/hook-format.mjs +14 -5
- package/clients/cli/lib/manifest.mjs +9 -2
- package/foundation/agent-docs/agent-docs.d.mts +3 -2
- package/foundation/agent-docs/agent-docs.mjs +13 -9
- package/foundation/agent-docs/agent-docs.test.mjs +19 -1
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +123 -80
- package/foundation/config/project.test.mjs +144 -21
- package/foundation/discovery/authoring-self-docs.d.mts +18 -0
- package/foundation/discovery/authoring-self-docs.mjs +37 -15
- package/foundation/discovery/authoring-self-docs.test.mjs +25 -9
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +119 -0
- package/foundation/discovery/cli-self-docs.mjs +490 -0
- package/foundation/discovery/cli-self-docs.test.mjs +375 -0
- package/foundation/discovery/component-discovery.d.mts +38 -0
- package/foundation/discovery/component-discovery.mjs +48 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +112 -11
- package/foundation/discovery/docs-discovery.mjs +231 -36
- package/foundation/discovery/docs-discovery.test.mjs +111 -32
- package/foundation/discovery/docs-output-budget.d.mts +2 -2
- package/foundation/discovery/docs-output-budget.mjs +1 -1
- package/foundation/discovery/docs-section-key.d.mts +28 -10
- package/foundation/discovery/docs-section-key.mjs +134 -33
- package/foundation/discovery/docs-section-key.test.mjs +41 -19
- package/foundation/discovery/template-adapter.d.mts +99 -6
- package/foundation/discovery/template-adapter.mjs +480 -57
- package/foundation/discovery/template-adapter.test.mjs +57 -0
- package/foundation/discovery/template-conflict-release.d.mts +13 -0
- package/foundation/discovery/template-conflict-release.mjs +40 -0
- package/foundation/discovery/template-conflict-release.test.mjs +40 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +278 -0
- package/foundation/doc-compiler/bundle.test.mjs +266 -0
- package/foundation/doc-compiler/compile.d.mts +220 -39
- package/foundation/doc-compiler/compile.mjs +311 -15
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +305 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +291 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +13 -0
- package/foundation/doc-compiler/ir.mjs +196 -12
- package/foundation/doc-compiler/lenses.d.mts +8 -5
- package/foundation/doc-compiler/lenses.mjs +50 -4
- package/foundation/doc-compiler/links.d.mts +162 -0
- package/foundation/doc-compiler/links.mjs +294 -0
- package/foundation/doc-compiler/links.test.mjs +192 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +127 -0
- package/foundation/doc-compiler/read.mjs +325 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/doc-compiler/tree.d.mts +288 -0
- package/foundation/doc-compiler/tree.mjs +876 -0
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -57
- package/foundation/integrations/autolink.test.mjs +1 -1
- package/foundation/integrations/cli-requirement.d.mts +45 -0
- package/foundation/integrations/cli-requirement.mjs +154 -0
- package/foundation/integrations/cli-requirement.test.mjs +84 -0
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +3 -2
- package/foundation/integrations/contribution-inventory.mjs +27 -24
- package/foundation/integrations/contribution-inventory.test.mjs +86 -27
- package/foundation/integrations/integration-warnings.d.mts +9 -2
- package/foundation/integrations/integration-warnings.mjs +51 -26
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.mjs +121 -29
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +12 -2
- package/foundation/response/error-codes.mjs +7 -1
- package/foundation/response/error-codes.test.mjs +55 -11
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +20 -11
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.d.mts +8 -0
- package/foundation/text/string-utils.mjs +40 -10
- package/foundation/xle/expand.mjs +1 -1
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -9
- package/assets/templates/themes/manifest.json +0 -95
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file The public type surface of `@astryxdesign/cli/authoring`, and whether
|
|
5
|
+
* a reader of `astryx docs authoring` can reach the doc for each type in it.
|
|
6
|
+
*
|
|
7
|
+
* @input authoring/index.d.ts and the type modules it re-exports, parsed with
|
|
8
|
+
* jscodeshift and never imported or type-checked (consumer installs have no
|
|
9
|
+
* TypeScript); the self-docs on disk and in AUTHORING_SELF_DOCS; and the
|
|
10
|
+
* section keys `astryx docs authoring --index` lists.
|
|
11
|
+
* @output {@link tracePublicAuthoringTypes}: each exported type and the module
|
|
12
|
+
* that declares it. {@link auditAuthoringSurface}: each module whose exported
|
|
13
|
+
* types a reader cannot reach and why, each export that cannot be traced,
|
|
14
|
+
* and each registered self-doc that documents nothing the surface exports.
|
|
15
|
+
* @position Read by Doctor's authoring-docs check. A type's doc is the self-doc
|
|
16
|
+
* beside the module that declares it, so a new public type needs a
|
|
17
|
+
* `*.doc.mjs` in its folder, listed in AUTHORING_SELF_DOCS. The barrel's
|
|
18
|
+
* parsers read those types and are not a shape anyone writes, so they need
|
|
19
|
+
* no section of their own.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import * as fs from 'node:fs';
|
|
23
|
+
import * as path from 'node:path';
|
|
24
|
+
import jscodeshift from 'jscodeshift';
|
|
25
|
+
import {
|
|
26
|
+
AUTHORING_ROOT,
|
|
27
|
+
AUTHORING_SELF_DOCS,
|
|
28
|
+
buildAuthoringReferenceDoc,
|
|
29
|
+
discoverAuthoringSelfDocSources,
|
|
30
|
+
loadAuthoringSelfDocs,
|
|
31
|
+
} from './authoring-self-docs.mjs';
|
|
32
|
+
import {sectionKey} from './docs-section-key.mjs';
|
|
33
|
+
|
|
34
|
+
const j = jscodeshift.withParser('ts');
|
|
35
|
+
|
|
36
|
+
/** The barrel the `types` condition of `@astryxdesign/cli/authoring` names. */
|
|
37
|
+
export const AUTHORING_SURFACE = 'index.d.ts';
|
|
38
|
+
|
|
39
|
+
/** Modules read by parsing. Anything else is runtime JavaScript. */
|
|
40
|
+
const TYPE_MODULE_RE = /\.(?:ts|tsx|mts|cts)$/u;
|
|
41
|
+
|
|
42
|
+
/** A title only a declaration of that name can match. */
|
|
43
|
+
const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/u;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {object} Tracer
|
|
47
|
+
* @property {string} root
|
|
48
|
+
* @property {Map<string, any[]>} parsed top-level statements by absolute path
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {'no-self-doc' | 'unregistered' | 'failed' | 'missing-section'} UnreadableReason
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} root
|
|
57
|
+
* @param {string} file
|
|
58
|
+
* @returns {string} `file` relative to `root`, with `/` separators
|
|
59
|
+
*/
|
|
60
|
+
function relative(root, file) {
|
|
61
|
+
return path.relative(root, file).split(path.sep).join('/');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {string} source a `/`-separated path relative to the root
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
function folderOf(source) {
|
|
69
|
+
return path.posix.dirname(source);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @param {any} node @returns {string | undefined} */
|
|
73
|
+
function nameOf(node) {
|
|
74
|
+
return node?.name ?? node?.value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Names a top-level statement declares, exported or not.
|
|
79
|
+
* @param {any} node
|
|
80
|
+
* @returns {string[]}
|
|
81
|
+
*/
|
|
82
|
+
function declaredNames(node) {
|
|
83
|
+
if (node?.type === 'VariableDeclaration') {
|
|
84
|
+
return node.declarations.flatMap((/** @type {any} */ d) =>
|
|
85
|
+
d.id?.type === 'Identifier' ? [d.id.name] : [],
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return node?.id?.type === 'Identifier' ? [node.id.name] : [];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {Tracer} t
|
|
93
|
+
* @param {string} file
|
|
94
|
+
* @returns {any[]}
|
|
95
|
+
*/
|
|
96
|
+
function statementsOf(t, file) {
|
|
97
|
+
let body = t.parsed.get(file);
|
|
98
|
+
if (!body) {
|
|
99
|
+
try {
|
|
100
|
+
body = j(fs.readFileSync(file, 'utf8')).get().node.program.body;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`${relative(t.root, file)} could not be parsed: ${error instanceof Error ? error.message : String(error)}`,
|
|
104
|
+
{cause: error},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
t.parsed.set(/** @type {string} */ (file), /** @type {any[]} */ (body));
|
|
108
|
+
}
|
|
109
|
+
return /** @type {any[]} */ (body);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The file a relative specifier names, resolved as TypeScript resolves an ESM
|
|
114
|
+
* import in a type module: `./x.js` is `./x.ts` when that exists.
|
|
115
|
+
* @param {Tracer} t
|
|
116
|
+
* @param {string} from absolute path of the importing module
|
|
117
|
+
* @param {string} specifier
|
|
118
|
+
* @returns {string} absolute path
|
|
119
|
+
* @throws {Error} for a bare specifier, one that leaves the root, or one that
|
|
120
|
+
* names no file
|
|
121
|
+
*/
|
|
122
|
+
function resolveModule(t, from, specifier) {
|
|
123
|
+
const base = path.resolve(path.dirname(from), specifier);
|
|
124
|
+
const inside = relative(t.root, base);
|
|
125
|
+
const candidates = !specifier.startsWith('.')
|
|
126
|
+
? []
|
|
127
|
+
: inside === '..' || inside.startsWith('../') || path.isAbsolute(inside)
|
|
128
|
+
? []
|
|
129
|
+
: /\.js$/u.test(base)
|
|
130
|
+
? [base.replace(/\.js$/u, '.ts'), base.replace(/\.js$/u, '.d.ts'), base]
|
|
131
|
+
: /\.[cm]js$/u.test(base) || TYPE_MODULE_RE.test(base)
|
|
132
|
+
? [base]
|
|
133
|
+
: [
|
|
134
|
+
`${base}.ts`,
|
|
135
|
+
`${base}.d.ts`,
|
|
136
|
+
path.join(base, 'index.ts'),
|
|
137
|
+
path.join(base, 'index.d.ts'),
|
|
138
|
+
];
|
|
139
|
+
const found = candidates.find(file => {
|
|
140
|
+
try {
|
|
141
|
+
return fs.statSync(file).isFile();
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
if (found == null) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`${relative(t.root, from)} names "${specifier}", which is not a file in ${path.basename(t.root)}/`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return found;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The module that declares what `file` exports as `name`, following
|
|
156
|
+
* re-exports. A JavaScript module declares what it exports (its JSDoc
|
|
157
|
+
* typedefs included), so a trace stops there.
|
|
158
|
+
* @param {Tracer} t
|
|
159
|
+
* @param {string} file
|
|
160
|
+
* @param {string} name
|
|
161
|
+
* @param {Set<string>} [seen] `file\0name` pairs already on this trace
|
|
162
|
+
* @returns {string | null} absolute path, or null when `file` does not export
|
|
163
|
+
* `name`
|
|
164
|
+
*/
|
|
165
|
+
function declaringModule(t, file, name, seen = new Set()) {
|
|
166
|
+
if (!TYPE_MODULE_RE.test(file)) return file;
|
|
167
|
+
const visit = `${file}\u0000${name}`;
|
|
168
|
+
if (seen.has(visit)) return null;
|
|
169
|
+
seen.add(visit);
|
|
170
|
+
const body = statementsOf(t, file);
|
|
171
|
+
for (const statement of body) {
|
|
172
|
+
if (
|
|
173
|
+
statement.type === 'ExportNamedDeclaration' &&
|
|
174
|
+
declaredNames(statement.declaration).includes(name)
|
|
175
|
+
) {
|
|
176
|
+
return file;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
for (const statement of body) {
|
|
180
|
+
if (statement.type !== 'ExportNamedDeclaration' || statement.declaration)
|
|
181
|
+
continue;
|
|
182
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
183
|
+
if (nameOf(specifier.exported) !== name) continue;
|
|
184
|
+
const source = statement.source?.value;
|
|
185
|
+
if (specifier.type === 'ExportNamespaceSpecifier') {
|
|
186
|
+
return resolveModule(t, file, source);
|
|
187
|
+
}
|
|
188
|
+
const local = nameOf(specifier.local) ?? name;
|
|
189
|
+
const found =
|
|
190
|
+
source == null
|
|
191
|
+
? localBinding(t, file, body, local, seen)
|
|
192
|
+
: declaringModule(t, resolveModule(t, file, source), local, seen);
|
|
193
|
+
if (found == null) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`${relative(t.root, file)} exports ${name}${source == null ? '' : ` from "${source}"`}, which does not declare it`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
return found;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (const statement of body) {
|
|
202
|
+
if (statement.type !== 'ExportAllDeclaration') continue;
|
|
203
|
+
const from = resolveModule(t, file, statement.source.value);
|
|
204
|
+
if (statement.exported != null) {
|
|
205
|
+
if (nameOf(statement.exported) === name) return from;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// What a JavaScript module exports cannot be listed by parsing, so a star
|
|
209
|
+
// through one never answers for a type.
|
|
210
|
+
if (!TYPE_MODULE_RE.test(from)) continue;
|
|
211
|
+
const found = declaringModule(t, from, name, seen);
|
|
212
|
+
if (found != null) return found;
|
|
213
|
+
}
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The module that declares a binding local to `file`: `file` itself, or the
|
|
219
|
+
* one its import of that name traces to.
|
|
220
|
+
* @param {Tracer} t
|
|
221
|
+
* @param {string} file
|
|
222
|
+
* @param {any[]} body
|
|
223
|
+
* @param {string} local
|
|
224
|
+
* @param {Set<string>} seen
|
|
225
|
+
* @returns {string | null}
|
|
226
|
+
*/
|
|
227
|
+
function localBinding(t, file, body, local, seen) {
|
|
228
|
+
for (const statement of body) {
|
|
229
|
+
const declared =
|
|
230
|
+
statement.type === 'ExportNamedDeclaration'
|
|
231
|
+
? statement.declaration
|
|
232
|
+
: statement;
|
|
233
|
+
if (declaredNames(declared).includes(local)) return file;
|
|
234
|
+
if (statement.type !== 'ImportDeclaration') continue;
|
|
235
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
236
|
+
if (nameOf(specifier.local) !== local) continue;
|
|
237
|
+
const from = resolveModule(t, file, statement.source.value);
|
|
238
|
+
if (specifier.type === 'ImportNamespaceSpecifier') return from;
|
|
239
|
+
const imported =
|
|
240
|
+
specifier.type === 'ImportDefaultSpecifier'
|
|
241
|
+
? 'default'
|
|
242
|
+
: (nameOf(specifier.imported) ?? local);
|
|
243
|
+
return declaringModule(t, from, imported, seen);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Every name a type module exports, stars included.
|
|
251
|
+
* @param {Tracer} t
|
|
252
|
+
* @param {string} file
|
|
253
|
+
* @param {Set<string>} [seen]
|
|
254
|
+
* @returns {string[]}
|
|
255
|
+
* @throws {Error} when a star passes through a JavaScript module, whose types
|
|
256
|
+
* cannot be listed by parsing
|
|
257
|
+
*/
|
|
258
|
+
function exportedNames(t, file, seen = new Set()) {
|
|
259
|
+
/** @type {Set<string>} */
|
|
260
|
+
const names = new Set();
|
|
261
|
+
if (seen.has(file)) return [];
|
|
262
|
+
seen.add(file);
|
|
263
|
+
for (const statement of statementsOf(t, file)) {
|
|
264
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
265
|
+
for (const name of declaredNames(statement.declaration)) names.add(name);
|
|
266
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
267
|
+
const name = nameOf(specifier.exported);
|
|
268
|
+
if (name != null) names.add(name);
|
|
269
|
+
}
|
|
270
|
+
} else if (statement.type === 'ExportAllDeclaration') {
|
|
271
|
+
const from = resolveModule(t, file, statement.source.value);
|
|
272
|
+
if (statement.exported != null) {
|
|
273
|
+
const name = nameOf(statement.exported);
|
|
274
|
+
if (name != null) names.add(name);
|
|
275
|
+
} else if (TYPE_MODULE_RE.test(from)) {
|
|
276
|
+
for (const name of exportedNames(t, from, seen)) {
|
|
277
|
+
if (name !== 'default') names.add(name);
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
throw new Error(
|
|
281
|
+
`${relative(t.root, file)} re-exports every type of "${statement.source.value}", a JavaScript module whose types cannot be listed`,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return [...names];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Every type `@astryxdesign/cli/authoring` exports, in the order index.d.ts
|
|
291
|
+
* lists them, each traced to the module that declares it. A value export that
|
|
292
|
+
* traces to a JavaScript module (a parser) is not a type and is left out;
|
|
293
|
+
* anything else that cannot be traced is reported, never dropped.
|
|
294
|
+
* @param {string} [root]
|
|
295
|
+
* @returns {{
|
|
296
|
+
* types: {name: string, module: string}[],
|
|
297
|
+
* untraced: {name: string, reason: string}[],
|
|
298
|
+
* }} `module` is relative to `root`
|
|
299
|
+
*/
|
|
300
|
+
export function tracePublicAuthoringTypes(root = AUTHORING_ROOT) {
|
|
301
|
+
return traceSurface({root, parsed: new Map()});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @param {Tracer} t
|
|
306
|
+
* @returns {ReturnType<typeof tracePublicAuthoringTypes>}
|
|
307
|
+
*/
|
|
308
|
+
function traceSurface(t) {
|
|
309
|
+
const surface = path.join(t.root, AUTHORING_SURFACE);
|
|
310
|
+
/** @type {{name: string, module: string}[]} */
|
|
311
|
+
const types = [];
|
|
312
|
+
/** @type {{name: string, reason: string}[]} */
|
|
313
|
+
const untraced = [];
|
|
314
|
+
/**
|
|
315
|
+
* @param {string} name
|
|
316
|
+
* @param {() => string | null} trace
|
|
317
|
+
* @param {boolean} typeOnly exported with `export type`
|
|
318
|
+
*/
|
|
319
|
+
const add = (name, trace, typeOnly) => {
|
|
320
|
+
let module;
|
|
321
|
+
try {
|
|
322
|
+
module = trace();
|
|
323
|
+
} catch (error) {
|
|
324
|
+
untraced.push({
|
|
325
|
+
name,
|
|
326
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
327
|
+
});
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (module == null) {
|
|
331
|
+
untraced.push({
|
|
332
|
+
name,
|
|
333
|
+
reason: `${AUTHORING_SURFACE} exports it, but no module declares it`,
|
|
334
|
+
});
|
|
335
|
+
} else if (typeOnly || TYPE_MODULE_RE.test(module)) {
|
|
336
|
+
types.push({name, module: relative(t.root, module)});
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
for (const statement of statementsOf(t, surface)) {
|
|
341
|
+
const typeOnly = statement.exportKind === 'type';
|
|
342
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
343
|
+
for (const name of declaredNames(statement.declaration)) {
|
|
344
|
+
add(name, () => surface, true);
|
|
345
|
+
}
|
|
346
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
347
|
+
const name = nameOf(specifier.exported) ?? '(unnamed)';
|
|
348
|
+
add(
|
|
349
|
+
name,
|
|
350
|
+
() => declaringModule(t, surface, name),
|
|
351
|
+
typeOnly || specifier.exportKind === 'type',
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
} else if (statement.type === 'ExportAllDeclaration') {
|
|
355
|
+
const source = statement.source.value;
|
|
356
|
+
if (statement.exported != null) {
|
|
357
|
+
const name = nameOf(statement.exported) ?? '(unnamed)';
|
|
358
|
+
add(name, () => resolveModule(t, surface, source), typeOnly);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
let names;
|
|
362
|
+
try {
|
|
363
|
+
const from = resolveModule(t, surface, source);
|
|
364
|
+
if (!TYPE_MODULE_RE.test(from)) {
|
|
365
|
+
throw new Error(
|
|
366
|
+
`${AUTHORING_SURFACE} re-exports everything "${source}" exports, and what a JavaScript module exports cannot be listed`,
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
names = exportedNames(t, from);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
untraced.push({
|
|
372
|
+
name: `* from "${source}"`,
|
|
373
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
374
|
+
});
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
for (const name of names) {
|
|
378
|
+
if (name === 'default') continue;
|
|
379
|
+
add(name, () => declaringModule(t, surface, name), typeOnly);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return {types, untraced};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Whether an authored type module in `folder` (relative to the root) declares
|
|
388
|
+
* `name`. Declaration files are skipped: beside a self-doc they are generated
|
|
389
|
+
* from the JavaScript next to them, declare no authored type, and use syntax
|
|
390
|
+
* the parser reads only in declaration mode.
|
|
391
|
+
* @param {Tracer} t
|
|
392
|
+
* @param {string} folder
|
|
393
|
+
* @param {string} name
|
|
394
|
+
* @returns {boolean}
|
|
395
|
+
*/
|
|
396
|
+
function declaredIn(t, folder, name) {
|
|
397
|
+
const dir = path.join(t.root, folder);
|
|
398
|
+
let entries;
|
|
399
|
+
try {
|
|
400
|
+
entries = fs.readdirSync(dir, {withFileTypes: true});
|
|
401
|
+
} catch {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
return entries.some(
|
|
405
|
+
entry =>
|
|
406
|
+
entry.isFile() &&
|
|
407
|
+
TYPE_MODULE_RE.test(entry.name) &&
|
|
408
|
+
!/\.d\.[cm]?ts$|\.test\.[cm]?tsx?$/u.test(entry.name) &&
|
|
409
|
+
statementsOf(t, path.join(dir, entry.name)).some(statement =>
|
|
410
|
+
declaredNames(
|
|
411
|
+
statement.type === 'ExportNamedDeclaration'
|
|
412
|
+
? statement.declaration
|
|
413
|
+
: statement,
|
|
414
|
+
).includes(name),
|
|
415
|
+
),
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* What stands between each type `@astryxdesign/cli/authoring` exports and a
|
|
421
|
+
* reader of `astryx docs authoring`. A type is readable when a self-doc beside
|
|
422
|
+
* the module that declares it is listed in AUTHORING_SELF_DOCS, loads, and
|
|
423
|
+
* renders a section the topic's index lists. A registered self-doc must
|
|
424
|
+
* document something public: a public type declared beside it, and, when its
|
|
425
|
+
* title is the name of a type declared beside it, that type.
|
|
426
|
+
* @param {{root?: string, sources?: string[], topicKeys?: Set<string> | null}} [options]
|
|
427
|
+
* `topicKeys` are the keys `astryx docs authoring --index` lists; null skips
|
|
428
|
+
* that comparison.
|
|
429
|
+
* @returns {Promise<{
|
|
430
|
+
* types: number,
|
|
431
|
+
* unreadable: {module: string, names: string[], reason: UnreadableReason, source?: string, key?: string}[],
|
|
432
|
+
* untraced: {name: string, reason: string}[],
|
|
433
|
+
* unmatched: {source: string, key?: string, subject?: string}[],
|
|
434
|
+
* }>}
|
|
435
|
+
*/
|
|
436
|
+
export async function auditAuthoringSurface({
|
|
437
|
+
root = AUTHORING_ROOT,
|
|
438
|
+
sources = AUTHORING_SELF_DOCS,
|
|
439
|
+
topicKeys = null,
|
|
440
|
+
} = {}) {
|
|
441
|
+
/** @type {Tracer} */
|
|
442
|
+
const t = {root, parsed: new Map()};
|
|
443
|
+
const {types, untraced} = traceSurface(t);
|
|
444
|
+
|
|
445
|
+
/** @type {Map<string, string[]>} folder -> self-docs on disk in it */
|
|
446
|
+
const beside = new Map();
|
|
447
|
+
for (const source of discoverAuthoringSelfDocSources(root)) {
|
|
448
|
+
const folder = folderOf(source);
|
|
449
|
+
beside.set(folder, [...(beside.get(folder) ?? []), source]);
|
|
450
|
+
}
|
|
451
|
+
const registered = new Set(sources);
|
|
452
|
+
const {loaded, failed} = await loadAuthoringSelfDocs(sources, root);
|
|
453
|
+
const failedSources = new Set(failed.map(entry => entry.source));
|
|
454
|
+
const sections = buildAuthoringReferenceDoc(
|
|
455
|
+
loaded.map(entry => entry.doc),
|
|
456
|
+
).sections;
|
|
457
|
+
/** @type {Map<string, string>} */
|
|
458
|
+
const keyOf = new Map(
|
|
459
|
+
loaded.map((entry, i) => [entry.source, sectionKey(sections[i])]),
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @param {string} source
|
|
464
|
+
* @returns {UnreadableReason | null}
|
|
465
|
+
*/
|
|
466
|
+
const blocked = source => {
|
|
467
|
+
if (!registered.has(source)) return 'unregistered';
|
|
468
|
+
if (failedSources.has(source) || !keyOf.has(source)) return 'failed';
|
|
469
|
+
const key = /** @type {string} */ (keyOf.get(source));
|
|
470
|
+
return topicKeys != null && !topicKeys.has(key) ? 'missing-section' : null;
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/** @type {Map<string, string[]>} declaring module -> its public types */
|
|
474
|
+
const byModule = new Map();
|
|
475
|
+
for (const {name, module} of types) {
|
|
476
|
+
byModule.set(module, [...(byModule.get(module) ?? []), name]);
|
|
477
|
+
}
|
|
478
|
+
/** @type {{module: string, names: string[], reason: UnreadableReason, source?: string, key?: string}[]} */
|
|
479
|
+
const unreadable = [];
|
|
480
|
+
for (const [module, names] of byModule) {
|
|
481
|
+
const docs = beside.get(folderOf(module)) ?? [];
|
|
482
|
+
if (docs.length === 0) {
|
|
483
|
+
unreadable.push({module, names, reason: 'no-self-doc'});
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
const reasons = docs.map(blocked);
|
|
487
|
+
if (reasons.includes(null)) continue;
|
|
488
|
+
const source = docs[0];
|
|
489
|
+
const key = keyOf.get(source);
|
|
490
|
+
unreadable.push({
|
|
491
|
+
module,
|
|
492
|
+
names,
|
|
493
|
+
reason: /** @type {UnreadableReason} */ (reasons[0]),
|
|
494
|
+
source,
|
|
495
|
+
...(key != null ? {key} : {}),
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const publicFolders = new Set(types.map(({module}) => folderOf(module)));
|
|
500
|
+
const publicNames = new Set(types.map(({name}) => name));
|
|
501
|
+
/** @type {Map<string, any>} */
|
|
502
|
+
const docOf = new Map(loaded.map(entry => [entry.source, entry.doc]));
|
|
503
|
+
/** @type {{source: string, key?: string, subject?: string}[]} */
|
|
504
|
+
const unmatched = [];
|
|
505
|
+
for (const source of sources) {
|
|
506
|
+
const key = keyOf.get(source);
|
|
507
|
+
const keyed = key != null ? {key} : {};
|
|
508
|
+
const folder = folderOf(source);
|
|
509
|
+
if (!publicFolders.has(folder)) {
|
|
510
|
+
unmatched.push({source, ...keyed});
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
const subject = docOf.get(source)?.displayName;
|
|
514
|
+
if (
|
|
515
|
+
typeof subject === 'string' &&
|
|
516
|
+
IDENTIFIER_RE.test(subject) &&
|
|
517
|
+
!publicNames.has(subject) &&
|
|
518
|
+
declaredIn(t, folder, subject)
|
|
519
|
+
) {
|
|
520
|
+
unmatched.push({source, ...keyed, subject});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return {types: types.length, unreadable, untraced, unmatched};
|
|
525
|
+
}
|