@astryxdesign/cli 0.7.2 → 0.7.3-canary.0bf23bd
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 +104 -71
- package/api/build/_adapter.d.mts +58 -0
- package/api/build/_adapter.mjs +115 -3
- package/api/build/blocks/blocks.d.mts +42 -0
- package/api/build/blocks/blocks.mjs +169 -0
- package/api/build/blocks/blocks.test.mjs +108 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.mjs +25 -6
- package/api/build/kit/answer.d.mts +14 -0
- package/api/build/kit/answer.mjs +85 -0
- package/api/build/kit/answer.test.mjs +38 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -398
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +60 -0
- package/api/build/kit/signals.mjs +284 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +52 -0
- package/api/build/tree.test.mjs +177 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/component.mjs +17 -3
- package/api/component/component.test.mjs +15 -0
- package/api/component/doc-links.test.mjs +2 -2
- package/api/discover/_adapter.mjs +36 -9
- package/api/discover/_adapter.test.mjs +42 -0
- package/api/docs/_adapter.d.mts +2 -2
- package/api/docs/_adapter.mjs +78 -23
- package/api/docs/docs-homes.test.mjs +127 -0
- package/api/docs/docs.doc.mjs +3 -3
- package/api/docs/docs.test.mjs +35 -19
- package/api/docs/integration-tree.test.mjs +20 -20
- package/api/docs/integrationDocs.test.mjs +1 -1
- package/api/docs/namespace-section.test.mjs +6 -6
- package/api/docs/reference-blocks.test.mjs +2 -2
- package/api/doctor/doctor.mjs +102 -24
- package/api/doctor/doctor.test.mjs +37 -12
- package/api/hook/hook.mjs +1 -1
- package/api/init/init.doc.mjs +20 -6
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +3 -3
- package/api/init/init.type.mjs +3 -3
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.mjs +69 -6
- package/api/integration/_adapter.d.mts +8 -0
- package/api/integration/_adapter.mjs +21 -1
- package/api/integration/authoring-checks.mjs +83 -9
- package/api/integration/authoring-checks.test.mjs +220 -0
- package/api/integration/pack-check.mjs +123 -4
- package/api/integration/pack-check.test.mjs +87 -0
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-gaps.test.mjs +1964 -0
- package/api/integration/validate-integration.d.mts +11 -2
- package/api/integration/validate-integration.mjs +250 -32
- package/api/integration/validate-integration.type.d.mts +59 -1
- package/api/integration/validate-integration.type.mjs +46 -2
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +82 -2
- package/api/search/_adapter.mjs +157 -10
- package/api/search/_adapter.test.mjs +173 -0
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +52 -0
- package/api/search/_entries.mjs +214 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -305
- package/api/search/search.doc.mjs +8 -6
- package/api/search/search.mjs +56 -2482
- package/api/search/search.test.mjs +14 -14
- package/api/search/search.type.d.mts +6 -1
- package/api/search/search.type.mjs +6 -1
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- package/api/theme/build/build.packed-old-core.test.mjs +1 -0
- package/api/upgrade/_adapter.d.mts +57 -9
- package/api/upgrade/_adapter.mjs +198 -28
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +13 -2
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/upgrade.doc.mjs +10 -5
- package/api/upgrade/upgrade.mjs +13 -2
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +5 -3
- package/api/upgrade/upgrade.type.mjs +8 -6
- package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- package/assets/docs/tree/add-a-component.doc.mjs +1 -1
- package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-topic.doc.mjs +2 -2
- package/assets/docs/tree/agent-guidance.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +6 -0
- package/assets/docs/tree/{integrations.doc.mjs → authoring.doc.mjs} +15 -6
- package/assets/docs/tree/block-template.doc.mjs +1 -1
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +2 -2
- package/assets/docs/tree/check-the-props.doc.mjs +1 -1
- package/assets/docs/tree/check-your-docs.doc.mjs +2 -2
- package/assets/docs/tree/checks.doc.mjs +2 -2
- package/assets/docs/tree/cli-command.doc.mjs +1 -1
- package/assets/docs/tree/cli.doc.mjs +1 -1
- package/assets/docs/tree/codemods.doc.mjs +1 -1
- package/assets/docs/tree/component-family.doc.mjs +1 -1
- package/assets/docs/tree/component-imports.doc.mjs +1 -1
- package/assets/docs/tree/components.doc.mjs +1 -1
- package/assets/docs/tree/configuration.doc.mjs +1 -1
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +1 -1
- package/assets/docs/tree/define-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/docs.doc.mjs +1 -1
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +1 -1
- package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
- package/assets/docs/tree/fonts-and-assets.doc.mjs +1 -1
- package/assets/docs/tree/generate-a-palette.doc.mjs +1 -1
- package/assets/docs/tree/global-integrations.doc.mjs +2 -2
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +4 -4
- package/assets/docs/tree/help.doc.mjs +2 -2
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/links.doc.mjs +1 -1
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +1 -1
- package/assets/docs/tree/publishing.doc.mjs +1 -1
- package/assets/docs/tree/quick-start.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-component.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-template.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +1 -1
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/ship.doc.mjs +2 -2
- package/assets/docs/tree/short-and-findable.doc.mjs +1 -1
- package/assets/docs/tree/single-component.doc.mjs +1 -1
- package/assets/docs/tree/start-a-template.doc.mjs +1 -1
- package/assets/docs/tree/subcomponent.doc.mjs +1 -1
- package/assets/docs/tree/template-assets.doc.mjs +1 -1
- package/assets/docs/tree/template-doc-overview.doc.mjs +2 -2
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
- 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 +1 -1
- package/assets/docs/tree/templates.doc.mjs +1 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
- package/assets/docs/tree/themes.doc.mjs +1 -1
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- package/assets/docs/tree/troubleshooting.doc.mjs +1 -1
- package/assets/docs/tree/upgrading.doc.mjs +1 -1
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
- package/assets/docs/tree/versioning.doc.mjs +1 -1
- package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
- package/assets/docs/tree/write-the-template-file.doc.mjs +1 -1
- package/assets/docs/use-integrations.doc.mjs +120 -0
- package/assets/docs/working-with-ai.doc.mjs +6 -2
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- package/authoring/debug/parse.d.mts +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/integration/integration.doc.mjs +1 -1
- package/authoring/integration/type.ts +1 -1
- package/clients/cli/bin/astryx.mjs +7 -78
- package/clients/cli/command-result-coverage.test.mjs +6 -5
- package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
- package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
- package/clients/cli/commands/component.test.mjs +6 -6
- package/clients/cli/commands/docs.doc.mjs +2 -2
- package/clients/cli/commands/docs.mjs +1 -1
- package/clients/cli/commands/docs.test.mjs +14 -14
- package/clients/cli/commands/doctor.mjs +30 -0
- package/clients/cli/commands/doctor.test.mjs +65 -0
- package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
- package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
- package/clients/cli/commands/init.behavior.test.mjs +230 -1
- package/clients/cli/commands/init.doc.mjs +28 -9
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- package/clients/cli/commands/integration-check.test.mjs +48 -0
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/manifest.mjs +67 -0
- package/clients/cli/commands/outside-project.test.mjs +2 -1
- package/clients/cli/commands/postinstall.doc.mjs +23 -0
- package/clients/cli/commands/postinstall.mjs +31 -0
- package/clients/cli/commands/setup-nudge.test.mjs +61 -0
- package/clients/cli/commands/{build-theme.mjs → theme.mjs} +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +4 -2
- package/clients/cli/commands/upgrade.mjs +9 -2
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +29 -86
- package/clients/cli/lib/component-format.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +12 -7
- package/clients/cli/lib/exit-codes.test.mjs +5 -0
- package/clients/cli/lib/manifest.test.mjs +12 -0
- package/clients/cli/lib/welcome-box.mjs +50 -0
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +20 -7
- package/foundation/agent-docs/agent-doc-state.mjs +35 -8
- package/foundation/agent-docs/agent-docs.d.mts +100 -12
- package/foundation/agent-docs/agent-docs.mjs +1012 -100
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +683 -39
- package/foundation/config/project.mjs +20 -22
- package/foundation/config/project.test.mjs +56 -0
- package/foundation/discovery/authoring-self-docs.d.mts +7 -0
- package/foundation/discovery/authoring-self-docs.mjs +16 -4
- package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
- package/foundation/discovery/authoring-surface.d.mts +1 -1
- package/foundation/discovery/authoring-surface.mjs +2 -2
- package/foundation/discovery/authoring-surface.test.mjs +1 -1
- package/foundation/discovery/cli-self-docs.d.mts +2 -1
- package/foundation/discovery/cli-self-docs.mjs +4 -3
- package/foundation/discovery/cli-self-docs.test.mjs +2 -2
- package/foundation/discovery/component-discovery.d.mts +37 -0
- package/foundation/discovery/component-discovery.mjs +80 -5
- package/foundation/discovery/component-loader.d.mts +1 -1
- package/foundation/discovery/docs-discovery.mjs +14 -1
- package/foundation/discovery/module-exports.d.mts +41 -0
- package/foundation/discovery/module-exports.mjs +253 -0
- package/foundation/discovery/runner-allowlist.d.mts +2 -4
- package/foundation/discovery/runner-allowlist.mjs +2 -4
- package/foundation/discovery/runner-commands.d.mts +77 -0
- package/foundation/discovery/runner-commands.mjs +294 -0
- package/foundation/discovery/runner-commands.test.mjs +128 -0
- package/foundation/discovery/stray-pointers.test.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +18 -1
- package/foundation/discovery/template-needs.mjs +1 -44
- package/foundation/discovery/theme-discovery.mjs +147 -3
- package/foundation/doc-compiler/doc-loads.test.mjs +33 -9
- package/foundation/doc-compiler/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
- package/foundation/doc-compiler/tree.d.mts +32 -6
- package/foundation/doc-compiler/tree.mjs +77 -43
- package/foundation/doc-compiler/tree.test.mjs +7 -7
- package/foundation/fs/paths.d.mts +70 -8
- package/foundation/fs/paths.mjs +556 -38
- package/foundation/fs/paths.test.mjs +430 -54
- package/foundation/fs/read-record.d.mts +18 -0
- package/foundation/fs/read-record.mjs +131 -0
- package/foundation/fs/read-record.test.mjs +77 -0
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/computer-integrations.d.mts +6 -3
- package/foundation/integrations/computer-integrations.mjs +38 -9
- package/foundation/integrations/contribution-inventory.d.mts +15 -20
- package/foundation/integrations/contribution-inventory.mjs +41 -5
- package/foundation/integrations/integrations.d.mts +27 -1
- package/foundation/integrations/integrations.mjs +61 -2
- package/foundation/integrations/validate-contributions.d.mts +115 -0
- package/foundation/integrations/validate-contributions.mjs +1168 -13
- package/foundation/release/handoff.d.mts +23 -4
- package/foundation/release/handoff.mjs +175 -8
- package/foundation/release/run-context.mjs +14 -0
- package/foundation/response/response-types.doc.mjs +1 -1
- package/foundation/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +14 -9
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export function validateLocalIntegration(cwd?: string): Promise<ValidateResult>;
|
|
12
12
|
/**
|
|
13
|
-
* Validate an INSTALLED integration package
|
|
13
|
+
* Validate an INSTALLED integration package: the nearest `node_modules/<spec>`
|
|
14
|
+
* at or above `cwd`, resolved the way the project loads it.
|
|
14
15
|
* @param {string} spec package name
|
|
15
16
|
* @param {string} [cwd]
|
|
16
17
|
* @returns {Promise<ValidateResult>}
|
|
@@ -43,7 +44,6 @@ export function summarizeIssues(issues: Issue[]): {
|
|
|
43
44
|
errors: number;
|
|
44
45
|
warnings: number;
|
|
45
46
|
};
|
|
46
|
-
export { validateLoadedIntegration };
|
|
47
47
|
export type Issue = import("../../foundation/integrations/issue").AstryxIntegrationIssue;
|
|
48
48
|
export type ValidateResult = {
|
|
49
49
|
/**
|
|
@@ -75,6 +75,15 @@ export type ValidateResult = {
|
|
|
75
75
|
code: string;
|
|
76
76
|
message: string;
|
|
77
77
|
}[] | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Layout findings added after the last minor
|
|
80
|
+
* release: validate lists them as notes, which count nowhere, since they
|
|
81
|
+
* may not fail `--strict` until the next (architecture:cli-surface INV35);
|
|
82
|
+
* `integration verify` still fails on a package.json npm cannot pack.
|
|
83
|
+
*/
|
|
84
|
+
listed?: import("../../foundation/integrations/issue").AstryxIntegrationIssue[] | undefined;
|
|
78
85
|
integration?: import("../../foundation/integrations/integrations.mjs").LoadedIntegration | undefined;
|
|
79
86
|
};
|
|
80
87
|
import { validateLoadedIntegration } from '../../foundation/integrations/validate-contributions.mjs';
|
|
88
|
+
import { isListedIssue } from '../../foundation/integrations/validate-contributions.mjs';
|
|
89
|
+
export { validateLoadedIntegration, isListedIssue };
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - validateLocalIntegration(cwd) — the package rooted at `cwd` (nearest
|
|
13
13
|
* package.json + sibling astryx.integration.{ts,mjs,js}).
|
|
14
14
|
* - validateInstalledIntegration(spec, cwd) — an installed package resolved
|
|
15
|
-
* from `cwd
|
|
15
|
+
* from the node_modules chain at or above `cwd`.
|
|
16
16
|
*
|
|
17
17
|
* Both return a { found, name, version, manifestFile, issues } result. `found`
|
|
18
18
|
* is false only for the no-manifest local case, which is guidance (not an
|
|
@@ -34,8 +34,10 @@
|
|
|
34
34
|
import * as fs from 'node:fs';
|
|
35
35
|
import * as path from 'node:path';
|
|
36
36
|
import {assertWithin} from '../../foundation/fs/path-safety.mjs';
|
|
37
|
+
import {normalizeProviderId} from '../../foundation/identity/provider-identity.mjs';
|
|
37
38
|
import {integrationDocTypes} from '../docs/_adapter.mjs';
|
|
38
39
|
import {integrationDocConsistency} from '../../foundation/discovery/doc-consistency.mjs';
|
|
40
|
+
import {integrationRunnerCommands} from './_adapter.mjs';
|
|
39
41
|
import {
|
|
40
42
|
THEME_SLUG_RE,
|
|
41
43
|
unreadThemeFolders,
|
|
@@ -51,20 +53,25 @@ import {
|
|
|
51
53
|
import {
|
|
52
54
|
findManifestPaths,
|
|
53
55
|
loadManifest,
|
|
54
|
-
|
|
56
|
+
resolveInstalledIntegrationDir,
|
|
55
57
|
} from '../../foundation/integrations/integrations.mjs';
|
|
56
58
|
// The on-disk contribution validators live in foundation: Project and
|
|
57
59
|
// integration-warnings need them too, and foundation must not depend on api.
|
|
58
60
|
import {
|
|
61
|
+
blockComponentsCheck,
|
|
62
|
+
componentDocNamesCheck,
|
|
59
63
|
INVALID_CLI_COMMAND,
|
|
64
|
+
isListedIssue,
|
|
65
|
+
issueListed as listed,
|
|
60
66
|
validateLoadedIntegration,
|
|
67
|
+
validateLoadedIntegrationListed,
|
|
61
68
|
issueError as error,
|
|
62
69
|
issueWarning as warning,
|
|
63
70
|
rootProblem,
|
|
64
71
|
} from '../../foundation/integrations/validate-contributions.mjs';
|
|
65
72
|
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
66
73
|
|
|
67
|
-
export {validateLoadedIntegration};
|
|
74
|
+
export {validateLoadedIntegration, isListedIssue};
|
|
68
75
|
|
|
69
76
|
/**
|
|
70
77
|
* @typedef {import('../../foundation/integrations/issue').AstryxIntegrationIssue} Issue
|
|
@@ -80,6 +87,10 @@ export {validateLoadedIntegration};
|
|
|
80
87
|
* @property {Issue[]} issues
|
|
81
88
|
* @property {Array<{code: string, message: string}>} [notes] Information that
|
|
82
89
|
* fails nothing, such as `invalid_cli_command` (a malformed `cliCommand`).
|
|
90
|
+
* @property {Issue[]} [listed] Layout findings added after the last minor
|
|
91
|
+
* release: validate lists them as notes, which count nowhere, since they
|
|
92
|
+
* may not fail `--strict` until the next (architecture:cli-surface INV35);
|
|
93
|
+
* `integration verify` still fails on a package.json npm cannot pack.
|
|
83
94
|
* @property {import('../../foundation/integrations/integrations.mjs').LoadedIntegration} [integration]
|
|
84
95
|
*/
|
|
85
96
|
|
|
@@ -99,6 +110,14 @@ function findNearestPackageJson(cwd) {
|
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
|
|
113
|
+
const ROOT_KINDS = /** @type {const} */ ([
|
|
114
|
+
'components',
|
|
115
|
+
'templates',
|
|
116
|
+
'codemods',
|
|
117
|
+
'docs',
|
|
118
|
+
'themes',
|
|
119
|
+
]);
|
|
120
|
+
|
|
102
121
|
const UNREACHABLE_SCAN_LIMIT = 5_000;
|
|
103
122
|
const UNREACHABLE_SKIP_DIRS = new Set([
|
|
104
123
|
'node_modules',
|
|
@@ -148,27 +167,51 @@ function unreadThemeFolderIssues(packageDir, loaded) {
|
|
|
148
167
|
*
|
|
149
168
|
* @param {string} packageDir
|
|
150
169
|
* @param {import('../../foundation/integrations/integrations.mjs').LoadedIntegration} loaded
|
|
170
|
+
* @param {string[]} [reported] folders whose files another issue already covers
|
|
151
171
|
* @returns {Promise<Issue[]>}
|
|
152
172
|
*/
|
|
153
|
-
async function findUnreachableContributionIssues(
|
|
173
|
+
async function findUnreachableContributionIssues(
|
|
174
|
+
packageDir,
|
|
175
|
+
loaded,
|
|
176
|
+
reported = [],
|
|
177
|
+
) {
|
|
178
|
+
// A root that is not a readable folder holds nothing: a fix must never
|
|
179
|
+
// send a file into it.
|
|
180
|
+
const usable = {...loaded};
|
|
181
|
+
for (const kind of ROOT_KINDS) {
|
|
182
|
+
const root = usable[kind];
|
|
183
|
+
if (root != null && rootProblem(root)) usable[kind] = undefined;
|
|
184
|
+
}
|
|
185
|
+
// Every declared root is skipped, readable or not: one that cannot be read
|
|
186
|
+
// has its own issue.
|
|
154
187
|
const roots = /** @type {string[]} */ (
|
|
155
|
-
[
|
|
156
|
-
loaded.components,
|
|
157
|
-
loaded.templates,
|
|
158
|
-
loaded.codemods,
|
|
159
|
-
loaded.docs,
|
|
160
|
-
loaded.themes,
|
|
161
|
-
].filter(Boolean)
|
|
188
|
+
ROOT_KINDS.map(kind => loaded[kind]).filter(Boolean)
|
|
162
189
|
);
|
|
190
|
+
// A folder a symlinked root points at is read through that root.
|
|
191
|
+
const realRoots = roots.map(root => {
|
|
192
|
+
try {
|
|
193
|
+
return fs.realpathSync(root);
|
|
194
|
+
} catch {
|
|
195
|
+
return root;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
163
198
|
/** @type {Issue[]} */
|
|
164
199
|
const issues = [];
|
|
165
|
-
const context = createFixContext(packageDir,
|
|
200
|
+
const context = createFixContext(packageDir, usable);
|
|
166
201
|
let scanned = 0;
|
|
167
202
|
let truncated = false;
|
|
168
203
|
|
|
169
204
|
/** @param {string} dir */
|
|
170
205
|
async function walk(dir) {
|
|
171
206
|
if (roots.some(root => pathIsInside(dir, root))) return;
|
|
207
|
+
if (reported.some(folder => pathIsInside(dir, folder))) return;
|
|
208
|
+
let realDir = dir;
|
|
209
|
+
try {
|
|
210
|
+
realDir = fs.realpathSync(dir);
|
|
211
|
+
} catch {
|
|
212
|
+
// Unreadable: reported below.
|
|
213
|
+
}
|
|
214
|
+
if (realRoots.some(root => pathIsInside(realDir, root))) return;
|
|
172
215
|
let entries;
|
|
173
216
|
try {
|
|
174
217
|
entries = fs
|
|
@@ -286,12 +329,14 @@ async function validateAtPackageDir(
|
|
|
286
329
|
let manifest;
|
|
287
330
|
/** @type {string[]} */
|
|
288
331
|
let unknownKeys;
|
|
332
|
+
/** @type {string[]} */
|
|
333
|
+
let declaredKeys;
|
|
289
334
|
/** @type {string | undefined} */
|
|
290
335
|
let agentDocsError;
|
|
291
336
|
/** @type {string | undefined} */
|
|
292
337
|
let cliCommandError;
|
|
293
338
|
try {
|
|
294
|
-
({manifest, unknownKeys, agentDocsError, cliCommandError} =
|
|
339
|
+
({manifest, unknownKeys, declaredKeys, agentDocsError, cliCommandError} =
|
|
295
340
|
await loadManifest(
|
|
296
341
|
manifestFile,
|
|
297
342
|
`Integration manifest (${path.basename(manifestFile)})`,
|
|
@@ -301,9 +346,36 @@ async function validateAtPackageDir(
|
|
|
301
346
|
return result;
|
|
302
347
|
}
|
|
303
348
|
|
|
304
|
-
/** @
|
|
305
|
-
const
|
|
349
|
+
/** @type {string[]} absolute roots inside the package */
|
|
350
|
+
const absoluteRoots = [];
|
|
351
|
+
/**
|
|
352
|
+
* @param {string | null | undefined} value
|
|
353
|
+
* @param {string} key the manifest key that declares it
|
|
354
|
+
*/
|
|
355
|
+
const resolveRoot = (value, key, kind = 'contribution root') => {
|
|
306
356
|
if (value == null) return undefined;
|
|
357
|
+
if (path.isAbsolute(value)) {
|
|
358
|
+
// An absolute root names this machine's disk, which no install shares,
|
|
359
|
+
// even when it happens to point inside the package.
|
|
360
|
+
const inside = path.relative(packageDir, value);
|
|
361
|
+
const relative =
|
|
362
|
+
inside === '' || (!inside.startsWith('..') && !path.isAbsolute(inside))
|
|
363
|
+
? `./${inside.split(path.sep).join('/')}`.replace(/\/$/u, '')
|
|
364
|
+
: null;
|
|
365
|
+
// The code an absolute root has always carried, reworded.
|
|
366
|
+
result.issues.push(
|
|
367
|
+
error(
|
|
368
|
+
'root_outside_package',
|
|
369
|
+
`The ${key} root "${value}" is an absolute path, so Astryx reads nothing from it: a root is relative to the package, so it resolves the same wherever the package is installed.` +
|
|
370
|
+
(relative
|
|
371
|
+
? ` Fix: set \`${key}: '${relative === './' ? '.' : relative}'\` in ${path.basename(manifestFile)}.`
|
|
372
|
+
: ` It also points outside the package. Fix: move the files into the package and set \`${key}\` to their folder relative to package.json, such as './${key}'.`),
|
|
373
|
+
),
|
|
374
|
+
);
|
|
375
|
+
// Its files are reported through this issue, not one by one.
|
|
376
|
+
if (relative) absoluteRoots.push(path.resolve(value));
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
307
379
|
try {
|
|
308
380
|
return assertWithin(value, packageDir, {label: kind});
|
|
309
381
|
} catch {
|
|
@@ -320,18 +392,20 @@ async function validateAtPackageDir(
|
|
|
320
392
|
const loaded = {
|
|
321
393
|
name: identity.name,
|
|
322
394
|
version: identity.version,
|
|
323
|
-
components: resolveRoot(manifest.components),
|
|
324
|
-
templates: resolveRoot(manifest.templates),
|
|
325
|
-
codemods: resolveRoot(manifest.codemods),
|
|
326
|
-
docs: resolveRoot(manifest.docs),
|
|
327
|
-
themes: resolveRoot(manifest.themes),
|
|
395
|
+
components: resolveRoot(manifest.components, 'components'),
|
|
396
|
+
templates: resolveRoot(manifest.templates, 'templates'),
|
|
397
|
+
codemods: resolveRoot(manifest.codemods, 'codemods'),
|
|
398
|
+
docs: resolveRoot(manifest.docs, 'docs'),
|
|
399
|
+
themes: resolveRoot(manifest.themes, 'themes'),
|
|
328
400
|
issuesUrl: manifest.issuesUrl,
|
|
329
401
|
agentDocs: manifest.agentDocs,
|
|
330
402
|
cliCommand: manifest.cliCommand,
|
|
331
403
|
__cliCommandError: cliCommandError,
|
|
332
404
|
__agentDocsError: agentDocsError,
|
|
333
405
|
__unknownKeys: unknownKeys,
|
|
406
|
+
__declaredKeys: declaredKeys,
|
|
334
407
|
__spec: identity.name,
|
|
408
|
+
__declaredProviderId: manifest.providerId,
|
|
335
409
|
__packageDir: packageDir,
|
|
336
410
|
__manifestFile: manifestFile,
|
|
337
411
|
};
|
|
@@ -343,7 +417,9 @@ async function validateAtPackageDir(
|
|
|
343
417
|
// `integration check --strict` fails on any warning, and a new failure code
|
|
344
418
|
// joins only in a minor release (architecture:cli-surface INV35). Doctor's
|
|
345
419
|
// project check still warns about it.
|
|
346
|
-
|
|
420
|
+
const contribution = await validateLoadedIntegrationListed(loaded);
|
|
421
|
+
(result.listed ??= []).push(...contribution.listed);
|
|
422
|
+
for (const issue of contribution.issues) {
|
|
347
423
|
if (issue.code === INVALID_CLI_COMMAND) {
|
|
348
424
|
(result.notes ??= []).push({code: issue.code, message: issue.message});
|
|
349
425
|
} else {
|
|
@@ -370,7 +446,11 @@ async function validateAtPackageDir(
|
|
|
370
446
|
);
|
|
371
447
|
if (scanUnreachable) {
|
|
372
448
|
issues.push(
|
|
373
|
-
...(await findUnreachableContributionIssues(
|
|
449
|
+
...(await findUnreachableContributionIssues(
|
|
450
|
+
packageDir,
|
|
451
|
+
loaded,
|
|
452
|
+
absoluteRoots,
|
|
453
|
+
)),
|
|
374
454
|
);
|
|
375
455
|
}
|
|
376
456
|
|
|
@@ -397,7 +477,7 @@ export async function validateLocalIntegration(cwd = process.cwd()) {
|
|
|
397
477
|
return {found: false, issues: []};
|
|
398
478
|
}
|
|
399
479
|
|
|
400
|
-
/** @type {{name?: string, version?: string}} */
|
|
480
|
+
/** @type {{name?: string, version?: string, private?: boolean}} */
|
|
401
481
|
let pkg;
|
|
402
482
|
try {
|
|
403
483
|
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
@@ -416,31 +496,121 @@ export async function validateLocalIntegration(cwd = process.cwd()) {
|
|
|
416
496
|
};
|
|
417
497
|
}
|
|
418
498
|
|
|
419
|
-
|
|
499
|
+
// npm publishes nothing without a name and a version, and the name is the
|
|
500
|
+
// provider ID every reader keys the package's contributions on.
|
|
501
|
+
// A package without one is still checked, under a placeholder name.
|
|
502
|
+
const fields = packageJsonFieldIssues(pkg, pkgJsonPath);
|
|
503
|
+
const name =
|
|
504
|
+
typeof pkg.name === 'string' && pkg.name !== ''
|
|
505
|
+
? pkg.name
|
|
506
|
+
: '(local package)';
|
|
507
|
+
const result = await validateAtPackageDir(
|
|
420
508
|
packageDir,
|
|
421
|
-
{
|
|
422
|
-
name: pkg.name ?? '(local package)',
|
|
423
|
-
version: pkg.version,
|
|
424
|
-
},
|
|
509
|
+
{name, version: pkg.version},
|
|
425
510
|
{scanUnreachable: true},
|
|
426
511
|
);
|
|
512
|
+
(result.listed ??= []).unshift(
|
|
513
|
+
...fields,
|
|
514
|
+
// Only a manifest that loaded says whether it declares a providerId; one
|
|
515
|
+
// that did not is reported as invalid_manifest.
|
|
516
|
+
...(result.integration
|
|
517
|
+
? providerIdIssues(
|
|
518
|
+
pkg.name,
|
|
519
|
+
result.integration.__declaredProviderId,
|
|
520
|
+
result.integration.__manifestFile,
|
|
521
|
+
)
|
|
522
|
+
: []),
|
|
523
|
+
);
|
|
524
|
+
return result;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Whether `name` is a bare npm package name, the form a provider ID takes.
|
|
529
|
+
* @param {string} name
|
|
530
|
+
*/
|
|
531
|
+
function isPackageName(name) {
|
|
532
|
+
try {
|
|
533
|
+
normalizeProviderId(name);
|
|
534
|
+
return true;
|
|
535
|
+
} catch {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
427
538
|
}
|
|
428
539
|
|
|
429
540
|
/**
|
|
430
|
-
*
|
|
541
|
+
* A warning when no provider ID can be derived for the package: its
|
|
542
|
+
* package.json `name` is not a bare package name and its manifest declares
|
|
543
|
+
* no `providerId` that is one. Readers key the package's contributions on
|
|
544
|
+
* that ID; a missing name is its own warning.
|
|
545
|
+
* @param {unknown} name package.json `name`
|
|
546
|
+
* @param {unknown} declared the manifest's `providerId`
|
|
547
|
+
* @param {string} manifestFile
|
|
548
|
+
* @returns {Issue[]}
|
|
549
|
+
*/
|
|
550
|
+
function providerIdIssues(name, declared, manifestFile) {
|
|
551
|
+
if (typeof name !== 'string' || name === '') return [];
|
|
552
|
+
if (isPackageName(name)) return [];
|
|
553
|
+
if (typeof declared === 'string' && isPackageName(declared)) return [];
|
|
554
|
+
const manifest = path.basename(manifestFile);
|
|
555
|
+
return [
|
|
556
|
+
listed(
|
|
557
|
+
'no_provider_id',
|
|
558
|
+
`No provider ID can be derived for this package: package.json "name" ${JSON.stringify(name)} is not a bare package name (an optional @scope/ and a name, each starting with a lowercase letter or digit and holding only lowercase letters, digits, "-", ".", "_" and "~"), and ${manifest} declares no providerId that is one. Astryx files the package's components, templates and docs under that ID, so links to them and selecting the package cannot work. Fix: rename the package, such as "@your-scope/your-package", or set \`providerId: '@your-scope/your-package'\` in ${manifest}.`,
|
|
559
|
+
),
|
|
560
|
+
];
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* A warning for each field npm needs that package.json lacks.
|
|
565
|
+
* @param {{name?: unknown, version?: unknown, private?: unknown}} pkg
|
|
566
|
+
* @param {string} pkgJsonPath
|
|
567
|
+
* @returns {Issue[]}
|
|
568
|
+
*/
|
|
569
|
+
function packageJsonFieldIssues(pkg, pkgJsonPath) {
|
|
570
|
+
/** @type {Issue[]} */
|
|
571
|
+
const issues = [];
|
|
572
|
+
const shown = path.basename(pkgJsonPath);
|
|
573
|
+
// Listed, so validate and `--strict` keep the result they had for these
|
|
574
|
+
// packages; `integration verify`, which packs, reports them as errors.
|
|
575
|
+
if (typeof pkg.name !== 'string' || pkg.name === '') {
|
|
576
|
+
issues.push(
|
|
577
|
+
listed(
|
|
578
|
+
'invalid_package_json',
|
|
579
|
+
`${shown} has no "name", so npm cannot pack or publish the package, and a project that installs it has no name to select it by. Fix: add "name": "@your-scope/your-package" to ${shown}.`,
|
|
580
|
+
),
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
// A private package is never published, so it needs no version.
|
|
584
|
+
if (
|
|
585
|
+
pkg.private !== true &&
|
|
586
|
+
(typeof pkg.version !== 'string' || pkg.version === '')
|
|
587
|
+
) {
|
|
588
|
+
issues.push(
|
|
589
|
+
listed(
|
|
590
|
+
'invalid_package_json',
|
|
591
|
+
`${shown} has no "version", so npm cannot pack or publish the package. Fix: add "version": "0.1.0" to ${shown}.`,
|
|
592
|
+
),
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
return issues;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Validate an INSTALLED integration package: the nearest `node_modules/<spec>`
|
|
600
|
+
* at or above `cwd`, resolved the way the project loads it.
|
|
431
601
|
* @param {string} spec package name
|
|
432
602
|
* @param {string} [cwd]
|
|
433
603
|
* @returns {Promise<ValidateResult>}
|
|
434
604
|
*/
|
|
435
605
|
export async function validateInstalledIntegration(spec, cwd = process.cwd()) {
|
|
436
|
-
//
|
|
606
|
+
// The resolver throws (path-safety guard) on a spec with path segments,
|
|
437
607
|
// `..`, or an absolute path. Every other malformed input to this command
|
|
438
608
|
// degrades into a diagnostic — so catch it here and return an issue instead
|
|
439
609
|
// of letting the throw escape to a raw stack (human) / generic ERR_UNKNOWN
|
|
440
610
|
// (--json).
|
|
441
611
|
let packageDir;
|
|
442
612
|
try {
|
|
443
|
-
packageDir =
|
|
613
|
+
packageDir = resolveInstalledIntegrationDir(spec, cwd);
|
|
444
614
|
} catch (err) {
|
|
445
615
|
return {
|
|
446
616
|
found: true,
|
|
@@ -478,6 +648,24 @@ export async function validateInstalledIntegration(spec, cwd = process.cwd()) {
|
|
|
478
648
|
});
|
|
479
649
|
}
|
|
480
650
|
|
|
651
|
+
/**
|
|
652
|
+
* The runner-command notes for a package's topics: each Astryx command a topic
|
|
653
|
+
* writes with a package runner, where the doc file is, and the bare command to
|
|
654
|
+
* write.
|
|
655
|
+
* @param {any} integration a loaded integration
|
|
656
|
+
* @returns {Promise<Array<{code: string, message: string}>>}
|
|
657
|
+
*/
|
|
658
|
+
async function runnerCommandNotes(integration) {
|
|
659
|
+
const packageDir = integration.__packageDir;
|
|
660
|
+
return (await integrationRunnerCommands(integration)).map(each => ({
|
|
661
|
+
code: 'runner_command',
|
|
662
|
+
message:
|
|
663
|
+
typeof packageDir === 'string'
|
|
664
|
+
? `${path.relative(packageDir, each.file).split(path.sep).join('/')}: ${each.message}`
|
|
665
|
+
: each.message,
|
|
666
|
+
}));
|
|
667
|
+
}
|
|
668
|
+
|
|
481
669
|
/**
|
|
482
670
|
* Unified entry: validate the LOCAL integration (no `pkg`) or an INSTALLED one
|
|
483
671
|
* (`pkg` given) and return the `integration.validate` envelope. The no-manifest
|
|
@@ -504,7 +692,35 @@ export async function validateIntegration(pkg, options = {}) {
|
|
|
504
692
|
const docTypes = integration
|
|
505
693
|
? await integrationDocTypes(integration, cwd)
|
|
506
694
|
: undefined;
|
|
507
|
-
|
|
695
|
+
// The component names docs and blocks give: those that cannot be judged
|
|
696
|
+
// are listed in their reports, and those judged wrong are notes.
|
|
697
|
+
const names = integration
|
|
698
|
+
? [
|
|
699
|
+
await componentDocNamesCheck(integration),
|
|
700
|
+
await blockComponentsCheck(integration),
|
|
701
|
+
]
|
|
702
|
+
: undefined;
|
|
703
|
+
const docNames = names?.[0].report;
|
|
704
|
+
const blockComponents = names?.[1].report;
|
|
705
|
+
// Notes fail nothing: a malformed `cliCommand`, and the findings added
|
|
706
|
+
// after the last minor release, each with its fix in the message, which
|
|
707
|
+
// may not fail `--strict` until the next (architecture:cli-surface INV35):
|
|
708
|
+
// the layout findings and the component names judged wrong.
|
|
709
|
+
const notes = result.found
|
|
710
|
+
? [
|
|
711
|
+
...(result.notes ?? []),
|
|
712
|
+
...(result.listed ?? []).map(issue => ({
|
|
713
|
+
code: issue.code,
|
|
714
|
+
message: issue.message,
|
|
715
|
+
})),
|
|
716
|
+
...(names ?? []).flatMap(each => each.notes),
|
|
717
|
+
]
|
|
718
|
+
: [];
|
|
719
|
+
// Each Astryx command a topic writes with a package runner, as a
|
|
720
|
+
// `runner_command` note with its fix, the same way.
|
|
721
|
+
if (integration?.docs) {
|
|
722
|
+
notes.push(...(await runnerCommandNotes(integration)));
|
|
723
|
+
}
|
|
508
724
|
return {
|
|
509
725
|
type: 'integration.validate',
|
|
510
726
|
data: {
|
|
@@ -526,6 +742,8 @@ export async function validateIntegration(pkg, options = {}) {
|
|
|
526
742
|
: result.issues,
|
|
527
743
|
...(notes.length > 0 ? {notes} : {}),
|
|
528
744
|
...(docTypes ? {docTypes} : {}),
|
|
745
|
+
...(docNames ? {docNames} : {}),
|
|
746
|
+
...(blockComponents ? {blockComponents} : {}),
|
|
529
747
|
},
|
|
530
748
|
};
|
|
531
749
|
}
|
|
@@ -14,6 +14,7 @@ export type LoadedIntegration = {
|
|
|
14
14
|
codemods?: string | undefined;
|
|
15
15
|
docs?: string | undefined;
|
|
16
16
|
issuesUrl?: string | undefined;
|
|
17
|
+
__declaredKeys?: string[] | undefined;
|
|
17
18
|
__unknownKeys?: string[] | undefined;
|
|
18
19
|
__spec: string;
|
|
19
20
|
__packageDir: string;
|
|
@@ -36,7 +37,18 @@ export type ValidateIntegrationResponse = {
|
|
|
36
37
|
type: "integration.validate";
|
|
37
38
|
/**
|
|
38
39
|
* `notes`: information beside the issues that fails nothing, such as
|
|
39
|
-
* `invalid_cli_command`, a `cliCommand` that was ignored as malformed
|
|
40
|
+
* `invalid_cli_command`, a `cliCommand` that was ignored as malformed, and
|
|
41
|
+
* the package layout findings added after the last minor release, each with
|
|
42
|
+
* its fix in the message: two docs for one component
|
|
43
|
+
* (`duplicate_component_doc`), a root reached through a symlink
|
|
44
|
+
* (`symlinked_root`), a contribution file that cannot be read
|
|
45
|
+
* (`unreadable_file`), a package.json without `name` or `version`
|
|
46
|
+
* (`invalid_package_json`), no provider ID (`no_provider_id`), and a doc
|
|
47
|
+
* whose file name differs from its source only in letter case where the two
|
|
48
|
+
* still pair (`source_without_component_doc`); and `doc_name_mismatch` and
|
|
49
|
+
* `unknown_block_component` (see `docNames` and `blockComponents`); they
|
|
50
|
+
* become warnings in the next minor release; and `runner_command`, an
|
|
51
|
+
* Astryx command a topic writes with a package runner
|
|
40
52
|
*/
|
|
41
53
|
data: {
|
|
42
54
|
validated: boolean;
|
|
@@ -48,6 +60,8 @@ export type ValidateIntegrationResponse = {
|
|
|
48
60
|
message: string;
|
|
49
61
|
}>;
|
|
50
62
|
docTypes?: DocTypesReport;
|
|
63
|
+
docNames?: DocNamesReport;
|
|
64
|
+
blockComponents?: BlockComponentsReport;
|
|
51
65
|
};
|
|
52
66
|
};
|
|
53
67
|
/**
|
|
@@ -57,3 +71,47 @@ export type ValidateIntegrationResponse = {
|
|
|
57
71
|
export type DocTypesReport = import("../../foundation/discovery/doc-types.mjs").DocTypesReport & {
|
|
58
72
|
fixtures?: number;
|
|
59
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Each component doc whose `name` differs from the name it is listed under,
|
|
76
|
+
* judged against its source. Present when the manifest loads. A name the
|
|
77
|
+
* module its printed import names provably does not export is a
|
|
78
|
+
* `doc_name_mismatch` note beside the issues, with its fix in the message
|
|
79
|
+
* (it becomes a warning in the next minor release), so `findings` is always
|
|
80
|
+
* empty; `unchecked` lists each doc whose source's
|
|
81
|
+
* exports could not all be read (a re-export from another package, `export
|
|
82
|
+
* =`, a destructured binding, a namespace): `file` (the doc, package-relative),
|
|
83
|
+
* `name` (what the doc says), and `reason`.
|
|
84
|
+
*/
|
|
85
|
+
export type DocNamesReport = {
|
|
86
|
+
status: "checked";
|
|
87
|
+
findings: [];
|
|
88
|
+
unchecked: Array<{
|
|
89
|
+
file: string;
|
|
90
|
+
name: string;
|
|
91
|
+
reason: string;
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Each component name a template gives in `exampleFor` or `componentsUsed`
|
|
96
|
+
* that could not be judged. Present when the manifest loads. A name neither
|
|
97
|
+
* the package nor Core has, and the template does not import, is an
|
|
98
|
+
* `unknown_block_component` note beside the issues, with its fix in the
|
|
99
|
+
* message (it becomes a warning in the next minor release), so `findings` is
|
|
100
|
+
* always empty;
|
|
101
|
+
* `unchecked` lists each name that cannot be judged: one the template may
|
|
102
|
+
* reach through anything other than named imports and re-exports from
|
|
103
|
+
* Core, React, StyleX, local helpers or the package's own entry (an import from another
|
|
104
|
+
* package, a default or namespace import, an alias of or member read off an imported
|
|
105
|
+
* binding, require(), a dynamic import(), a local module this check cannot
|
|
106
|
+
* read), or, without Core installed, any name Core would have to resolve: `file` (the template doc, package-relative),
|
|
107
|
+
* `name`, and `reason`.
|
|
108
|
+
*/
|
|
109
|
+
export type BlockComponentsReport = {
|
|
110
|
+
status: "checked";
|
|
111
|
+
findings: [];
|
|
112
|
+
unchecked: Array<{
|
|
113
|
+
file: string;
|
|
114
|
+
name: string;
|
|
115
|
+
reason: string;
|
|
116
|
+
}>;
|
|
117
|
+
};
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* @property {string} [codemods]
|
|
19
19
|
* @property {string} [docs]
|
|
20
20
|
* @property {string} [issuesUrl]
|
|
21
|
+
* @property {string[]} [__declaredKeys]
|
|
21
22
|
* @property {string[]} [__unknownKeys]
|
|
22
23
|
* @property {string} __spec
|
|
23
24
|
* @property {string} __packageDir
|
|
@@ -38,9 +39,20 @@
|
|
|
38
39
|
* "healthy" — the two are otherwise byte-identical.
|
|
39
40
|
* @typedef {object} ValidateIntegrationResponse
|
|
40
41
|
* @property {'integration.validate'} type
|
|
41
|
-
* @property {{validated: boolean, name: string | null, version: string | null, issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[], notes?: Array<{code: string, message: string}>, docTypes?: DocTypesReport}} data
|
|
42
|
+
* @property {{validated: boolean, name: string | null, version: string | null, issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[], notes?: Array<{code: string, message: string}>, docTypes?: DocTypesReport, docNames?: DocNamesReport, blockComponents?: BlockComponentsReport}} data
|
|
42
43
|
* `notes`: information beside the issues that fails nothing, such as
|
|
43
|
-
* `invalid_cli_command`, a `cliCommand` that was ignored as malformed
|
|
44
|
+
* `invalid_cli_command`, a `cliCommand` that was ignored as malformed, and
|
|
45
|
+
* the package layout findings added after the last minor release, each with
|
|
46
|
+
* its fix in the message: two docs for one component
|
|
47
|
+
* (`duplicate_component_doc`), a root reached through a symlink
|
|
48
|
+
* (`symlinked_root`), a contribution file that cannot be read
|
|
49
|
+
* (`unreadable_file`), a package.json without `name` or `version`
|
|
50
|
+
* (`invalid_package_json`), no provider ID (`no_provider_id`), and a doc
|
|
51
|
+
* whose file name differs from its source only in letter case where the two
|
|
52
|
+
* still pair (`source_without_component_doc`); and `doc_name_mismatch` and
|
|
53
|
+
* `unknown_block_component` (see `docNames` and `blockComponents`); they
|
|
54
|
+
* become warnings in the next minor release; and `runner_command`, an
|
|
55
|
+
* Astryx command a topic writes with a package runner
|
|
44
56
|
*/
|
|
45
57
|
|
|
46
58
|
/**
|
|
@@ -54,4 +66,36 @@
|
|
|
54
66
|
* components or docs root, which those readers skip) were not checked
|
|
55
67
|
*/
|
|
56
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Each component doc whose `name` differs from the name it is listed under,
|
|
71
|
+
* judged against its source. Present when the manifest loads. A name the
|
|
72
|
+
* module its printed import names provably does not export is a
|
|
73
|
+
* `doc_name_mismatch` note beside the issues, with its fix in the message
|
|
74
|
+
* (it becomes a warning in the next minor release), so `findings` is always
|
|
75
|
+
* empty; `unchecked` lists each doc whose source's
|
|
76
|
+
* exports could not all be read (a re-export from another package, `export
|
|
77
|
+
* =`, a destructured binding, a namespace): `file` (the doc, package-relative),
|
|
78
|
+
* `name` (what the doc says), and `reason`.
|
|
79
|
+
*
|
|
80
|
+
* @typedef {{status: 'checked', findings: [], unchecked: Array<{file: string, name: string, reason: string}>}} DocNamesReport
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Each component name a template gives in `exampleFor` or `componentsUsed`
|
|
85
|
+
* that could not be judged. Present when the manifest loads. A name neither
|
|
86
|
+
* the package nor Core has, and the template does not import, is an
|
|
87
|
+
* `unknown_block_component` note beside the issues, with its fix in the
|
|
88
|
+
* message (it becomes a warning in the next minor release), so `findings` is
|
|
89
|
+
* always empty;
|
|
90
|
+
* `unchecked` lists each name that cannot be judged: one the template may
|
|
91
|
+
* reach through anything other than named imports and re-exports from
|
|
92
|
+
* Core, React, StyleX, local helpers or the package's own entry (an import from another
|
|
93
|
+
* package, a default or namespace import, an alias of or member read off an imported
|
|
94
|
+
* binding, require(), a dynamic import(), a local module this check cannot
|
|
95
|
+
* read), or, without Core installed, any name Core would have to resolve: `file` (the template doc, package-relative),
|
|
96
|
+
* `name`, and `reason`.
|
|
97
|
+
*
|
|
98
|
+
* @typedef {{status: 'checked', findings: [], unchecked: Array<{file: string, name: string, reason: string}>}} BlockComponentsReport
|
|
99
|
+
*/
|
|
100
|
+
|
|
57
101
|
export {};
|
|
@@ -62,7 +62,7 @@ export const doc = {
|
|
|
62
62
|
{
|
|
63
63
|
type: 'integration.validate',
|
|
64
64
|
description:
|
|
65
|
-
'The result envelope: `data.validated`, false when nothing was validated — with no `package.json` at all, `data.issues` carries one `no_package` error-severity issue so the command exits 1; with a `package.json` but no integration manifest, `data.issues` is empty, which means "not looked at", not "healthy"; `data.name` and `data.version` of the validated package (both null when `data.validated` is false; `data.name` is `(local package)` when the local package.json has no readable name), plus `data.issues`, an AstryxIntegrationIssue[] of {code, severity: `warning` | `error`, message, fix?, file?, line?}: `fix` is the change that resolves the issue, and `file` and `line` where it is, relative to the package, when the check knows them; and `data.notes` when there are any: {code, message} information that fails nothing, such as `invalid_cli_command` for a `cliCommand` that was ignored as malformed. When the manifest loads, `data.docTypes` holds the doc type check: `status` (`checked` | `skipped`), `reason` when skipped, `typescript`, `docs` (doc values checked), `findings` ({doc, line, export, type, field, problem: `unknown_field` | `missing_field` | `wrong_type`, severity: `warning`, message, fix}), `unchecked` ({doc, reason}: a doc that could not be fully checked, or a root its reader cannot read), and `fixtures` when the components or docs root holds test fixture docs under `__tests__`: how many, none of them checked.',
|
|
65
|
+
'The result envelope: `data.validated`, false when nothing was validated — with no `package.json` at all, `data.issues` carries one `no_package` error-severity issue so the command exits 1; with a `package.json` but no integration manifest, `data.issues` is empty, which means "not looked at", not "healthy"; `data.name` and `data.version` of the validated package (both null when `data.validated` is false; `data.name` is `(local package)` when the local package.json has no readable name), plus `data.issues`, an AstryxIntegrationIssue[] of {code, severity: `warning` | `error`, message, fix?, file?, line?}: `fix` is the change that resolves the issue, and `file` and `line` where it is, relative to the package, when the check knows them; and `data.notes` when there are any: {code, message} information that fails nothing, such as `invalid_cli_command` for a `cliCommand` that was ignored as malformed, and the package layout findings added after the last minor release, each with its fix in the message: `duplicate_component_doc`, `symlinked_root`, `unreadable_file`, `invalid_package_json` (no `name` or `version`), `no_provider_id`, and `source_without_component_doc` for a doc whose file name differs from its source only in letter case where the two still pair; and `doc_name_mismatch` and `unknown_block_component` (see `docNames` and `blockComponents`); they become warnings in the next minor release. A `runner_command` note lists each Astryx command a topic writes with a package runner, with its file, line and the bare command to write. When the manifest loads, `data.docTypes` holds the doc type check: `status` (`checked` | `skipped`), `reason` when skipped, `typescript`, `docs` (doc values checked), `findings` ({doc, line, export, type, field, problem: `unknown_field` | `missing_field` | `wrong_type`, severity: `warning`, message, fix}), `unchecked` ({doc, reason}: a doc that could not be fully checked, or a root its reader cannot read), and `fixtures` when the components or docs root holds test fixture docs under `__tests__`: how many, none of them checked. When the manifest loads, `data.docNames` lists the component doc names it could not judge: `status` (`checked`), `findings` (always empty; a doc name the module its import names provably does not export is a `doc_name_mismatch` note, with its fix in the message) and `unchecked` ({file, name, reason}: a doc whose `name` differs from the name it is listed under and whose source exports cannot all be read, such as a re-export from another package). When the manifest loads, `data.blockComponents` lists the component names templates give in `exampleFor` or `componentsUsed` that could not be judged: `status` (`checked`), `findings` (always empty; a name neither the package nor Core has, and the template does not import, is an `unknown_block_component` note, with its fix in the message) and `unchecked` ({file, name, reason}: a name the template may reach through anything other than named imports and re-exports from Core, React, StyleX, local helpers or the entry of the package itself, such as an import from another package, a default or namespace import, an alias of or member read off an imported binding, require() or a dynamic import(), or a local module that cannot be read, or any name Core would have to resolve when Core is not installed).',
|
|
66
66
|
},
|
|
67
67
|
],
|
|
68
68
|
examples: [
|