@intentius/chant 0.124.51 → 0.124.54
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/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/discover.js +3 -1
- package/dist/behaviour.d.ts +1 -1
- package/dist/behaviour.d.ts.map +1 -1
- package/dist/capabilities/templates.d.ts +65 -0
- package/dist/capabilities/templates.d.ts.map +1 -0
- package/dist/capabilities/templates.js +193 -0
- package/dist/capabilities/templates.json +145 -0
- package/dist/change-set-graph.d.ts +35 -3
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +60 -9
- package/dist/change-set.d.ts +65 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +23 -12
- package/dist/ci-identity.d.ts +7 -2
- package/dist/ci-identity.d.ts.map +1 -1
- package/dist/ci-identity.js +4 -1
- package/dist/cli/commands/import-index.d.ts +52 -0
- package/dist/cli/commands/import-index.d.ts.map +1 -0
- package/dist/cli/commands/import-index.js +226 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +4 -2
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/components.js +11 -2
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +16 -3
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +22 -4
- package/dist/cli/handlers/index-cloud.d.ts +14 -0
- package/dist/cli/handlers/index-cloud.d.ts.map +1 -0
- package/dist/cli/handlers/index-cloud.js +22 -0
- package/dist/cli/handlers/index-diff.d.ts +18 -0
- package/dist/cli/handlers/index-diff.d.ts.map +1 -0
- package/dist/cli/handlers/index-diff.js +142 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts +25 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-drift.js +64 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.js +188 -28
- package/dist/cli/handlers/misc.d.ts +9 -0
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +77 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +17 -3
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +89 -15
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +28 -4
- package/dist/cli/handlers/scenario.d.ts.map +1 -1
- package/dist/cli/handlers/scenario.js +8 -7
- package/dist/cli/handlers/search.d.ts +34 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +216 -36
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +55 -1
- package/dist/cli/mcp/lifecycle-tools.d.ts.map +1 -1
- package/dist/cli/mcp/lifecycle-tools.js +3 -2
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.js +4 -3
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +55 -2
- package/dist/cli/registry.d.ts +19 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cloud-lister/aws.d.ts +35 -0
- package/dist/cloud-lister/aws.d.ts.map +1 -0
- package/dist/cloud-lister/aws.js +203 -0
- package/dist/cloud-lister/azure.d.ts +34 -0
- package/dist/cloud-lister/azure.d.ts.map +1 -0
- package/dist/cloud-lister/azure.js +129 -0
- package/dist/cloud-lister/common.d.ts +40 -0
- package/dist/cloud-lister/common.d.ts.map +1 -0
- package/dist/cloud-lister/common.js +83 -0
- package/dist/cloud-lister/credentials.d.ts +50 -0
- package/dist/cloud-lister/credentials.d.ts.map +1 -0
- package/dist/cloud-lister/credentials.js +86 -0
- package/dist/cloud-lister/fakes.d.ts +27 -0
- package/dist/cloud-lister/fakes.d.ts.map +1 -0
- package/dist/cloud-lister/fakes.js +50 -0
- package/dist/cloud-lister/gcp.d.ts +42 -0
- package/dist/cloud-lister/gcp.d.ts.map +1 -0
- package/dist/cloud-lister/gcp.js +143 -0
- package/dist/cloud-lister/guard.d.ts +49 -0
- package/dist/cloud-lister/guard.d.ts.map +1 -0
- package/dist/cloud-lister/guard.js +103 -0
- package/dist/cloud-lister/ids.d.ts +23 -0
- package/dist/cloud-lister/ids.d.ts.map +1 -0
- package/dist/cloud-lister/ids.js +42 -0
- package/dist/cloud-lister/index.d.ts +67 -0
- package/dist/cloud-lister/index.d.ts.map +1 -0
- package/dist/cloud-lister/index.js +102 -0
- package/dist/cloud-lister/kubernetes.d.ts +64 -0
- package/dist/cloud-lister/kubernetes.d.ts.map +1 -0
- package/dist/cloud-lister/kubernetes.js +276 -0
- package/dist/cloud-lister/markers.d.ts +31 -0
- package/dist/cloud-lister/markers.d.ts.map +1 -0
- package/dist/cloud-lister/markers.js +73 -0
- package/dist/cloud-lister/mask.d.ts +31 -0
- package/dist/cloud-lister/mask.d.ts.map +1 -0
- package/dist/cloud-lister/mask.js +74 -0
- package/dist/cloud-lister/sigv4.d.ts +29 -0
- package/dist/cloud-lister/sigv4.d.ts.map +1 -0
- package/dist/cloud-lister/sigv4.js +54 -0
- package/dist/cloud-lister/transport.d.ts +55 -0
- package/dist/cloud-lister/transport.d.ts.map +1 -0
- package/dist/cloud-lister/transport.js +86 -0
- package/dist/cloud-lister/types.d.ts +121 -0
- package/dist/cloud-lister/types.d.ts.map +1 -0
- package/dist/cloud-lister/types.js +24 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +6 -0
- package/dist/components/capability-plugin.d.ts +9 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability.d.ts +224 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +21 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +58 -14
- package/dist/components/covered-round.d.ts +173 -0
- package/dist/components/covered-round.d.ts.map +1 -0
- package/dist/components/covered-round.js +200 -0
- package/dist/components/declared-reads.d.ts +38 -0
- package/dist/components/declared-reads.d.ts.map +1 -0
- package/dist/components/declared-reads.js +131 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +4 -0
- package/dist/components/driver.d.ts +42 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +74 -3
- package/dist/components/fan-out-run.d.ts +23 -1
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +82 -14
- package/dist/components/fan-out-support.d.ts +6 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out-support.js +4 -1
- package/dist/components/fan-out.d.ts +28 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/groups.d.ts +229 -0
- package/dist/components/groups.d.ts.map +1 -0
- package/dist/components/groups.js +760 -0
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -0
- package/dist/components/plan-shape-conformance.d.ts +48 -0
- package/dist/components/plan-shape-conformance.d.ts.map +1 -0
- package/dist/components/plan-shape-conformance.js +122 -0
- package/dist/components/pr-run.d.ts +62 -7
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +354 -53
- package/dist/components/promote-rounds.d.ts +9 -0
- package/dist/components/promote-rounds.d.ts.map +1 -1
- package/dist/components/promote-rounds.js +23 -2
- package/dist/components/promote.d.ts +17 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +36 -6
- package/dist/components/release-gate.d.ts +23 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +97 -33
- package/dist/components/run-groups.d.ts +58 -0
- package/dist/components/run-groups.d.ts.map +1 -0
- package/dist/components/run-groups.js +78 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +6 -1
- package/dist/components/verbs/index.d.ts +1 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +1 -0
- package/dist/components/verbs/member-outputs.d.ts +187 -0
- package/dist/components/verbs/member-outputs.d.ts.map +1 -0
- package/dist/components/verbs/member-outputs.js +218 -0
- package/dist/components/wave-plan.d.ts +2 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +4 -1
- package/dist/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -0
- package/dist/deep-observation.d.ts +1 -13
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/deep-observation.js +5 -22
- package/dist/drift-record.d.ts +542 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +886 -0
- package/dist/engine-facts.d.ts +144 -0
- package/dist/engine-facts.d.ts.map +1 -0
- package/dist/engine-facts.js +14 -0
- package/dist/graph-ir.d.ts +153 -2
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +224 -6
- package/dist/graph-refs.d.ts +145 -0
- package/dist/graph-refs.d.ts.map +1 -1
- package/dist/graph-refs.js +305 -0
- package/dist/graph-schema/fixtures/adopt.json +15 -0
- package/dist/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/dist/graph-schema/fixtures/index.json +68 -0
- package/dist/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/dist/graph-schema/fixtures.d.ts +23 -0
- package/dist/graph-schema/fixtures.d.ts.map +1 -0
- package/dist/graph-schema/fixtures.js +246 -0
- package/dist/graph-schema/generate.d.ts +15 -0
- package/dist/graph-schema/generate.d.ts.map +1 -0
- package/dist/graph-schema/generate.js +267 -0
- package/dist/graph-schema/graph.schema.json +1387 -0
- package/dist/health.schema.json +2 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/instance-nodes.d.ts +159 -0
- package/dist/instance-nodes.d.ts.map +1 -0
- package/dist/instance-nodes.js +231 -0
- package/dist/lexicon.d.ts +72 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/adoption-file.d.ts +56 -0
- package/dist/lifecycle/adoption-file.d.ts.map +1 -0
- package/dist/lifecycle/adoption-file.js +123 -0
- package/dist/lifecycle/cloud-index.d.ts +186 -0
- package/dist/lifecycle/cloud-index.d.ts.map +1 -0
- package/dist/lifecycle/cloud-index.js +618 -0
- package/dist/lifecycle/derive-edges.d.ts +59 -0
- package/dist/lifecycle/derive-edges.d.ts.map +1 -0
- package/dist/lifecycle/derive-edges.js +126 -0
- package/dist/lifecycle/git.d.ts +10 -9
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +7 -1
- package/dist/lifecycle/identity-match.d.ts +133 -0
- package/dist/lifecycle/identity-match.d.ts.map +1 -0
- package/dist/lifecycle/identity-match.js +147 -0
- package/dist/lifecycle/index-diff.d.ts +224 -0
- package/dist/lifecycle/index-diff.d.ts.map +1 -0
- package/dist/lifecycle/index-diff.js +327 -0
- package/dist/lifecycle/index-document.d.ts +130 -0
- package/dist/lifecycle/index-document.d.ts.map +1 -0
- package/dist/lifecycle/index-document.js +189 -0
- package/dist/lifecycle/index-drift.d.ts +121 -0
- package/dist/lifecycle/index-drift.d.ts.map +1 -0
- package/dist/lifecycle/index-drift.js +178 -0
- package/dist/lifecycle/index-import.d.ts +168 -0
- package/dist/lifecycle/index-import.d.ts.map +1 -0
- package/dist/lifecycle/index-import.js +515 -0
- package/dist/lifecycle/index-join.d.ts +129 -0
- package/dist/lifecycle/index-join.d.ts.map +1 -0
- package/dist/lifecycle/index-join.js +248 -0
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/observation-baseline.d.ts +61 -21
- package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
- package/dist/lifecycle/observation-baseline.js +144 -19
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +6 -1
- package/dist/lifecycle/query.d.ts +45 -4
- package/dist/lifecycle/query.d.ts.map +1 -1
- package/dist/lifecycle/query.js +89 -7
- package/dist/lifecycle/replay.d.ts +10 -3
- package/dist/lifecycle/replay.d.ts.map +1 -1
- package/dist/lifecycle/replay.js +10 -6
- package/dist/lifecycle/scenario.d.ts +4 -3
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/snapshot-store-fake.d.ts +9 -0
- package/dist/lifecycle/snapshot-store-fake.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-fake.js +21 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts +102 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-s3.js +254 -0
- package/dist/lifecycle/snapshot-store.d.ts +170 -0
- package/dist/lifecycle/snapshot-store.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store.js +832 -0
- package/dist/lifecycle/snapshot.d.ts +11 -0
- package/dist/lifecycle/snapshot.d.ts.map +1 -1
- package/dist/lifecycle/snapshot.js +18 -5
- package/dist/lifecycle/type-listing.d.ts +148 -0
- package/dist/lifecycle/type-listing.d.ts.map +1 -0
- package/dist/lifecycle/type-listing.js +166 -0
- package/dist/lint/component-checks.d.ts +15 -1
- package/dist/lint/component-checks.d.ts.map +1 -1
- package/dist/lint/component-checks.js +1 -0
- package/dist/lint/presets/relaxed.json +2 -1
- package/dist/lint/presets/strict.json +2 -1
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.js +13 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.js +8 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts +33 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.js +123 -0
- package/dist/lint/rules/comp/index.d.ts +2 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/comp/index.js +4 -1
- package/dist/observation.d.ts +19 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +18 -1
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +1 -1
- package/dist/op/activities/change-set.d.ts +6 -4
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +4 -2
- package/dist/op/activity-failure.d.ts +27 -0
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +5 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +22 -8
- package/dist/pr-loop.d.ts +92 -3
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +62 -3
- package/dist/pulumi-urn.d.ts +101 -0
- package/dist/pulumi-urn.d.ts.map +1 -0
- package/dist/pulumi-urn.js +131 -0
- package/dist/release-floors.d.ts +23 -0
- package/dist/release-floors.d.ts.map +1 -0
- package/dist/release-floors.js +22 -0
- package/dist/sensitive-key.d.ts +23 -0
- package/dist/sensitive-key.d.ts.map +1 -0
- package/dist/sensitive-key.js +31 -0
- package/dist/wave-runtime.mjs +234 -234
- package/dist/workspace/adoption-report.d.ts +53 -0
- package/dist/workspace/adoption-report.d.ts.map +1 -0
- package/dist/workspace/adoption-report.js +76 -0
- package/dist/workspace/capabilities-contract.d.ts +7 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -1
- package/dist/workspace/capabilities-contract.js +2 -1
- package/dist/workspace/capabilities.schema.json +98 -0
- package/dist/workspace/change-set.schema.json +42 -3
- package/dist/workspace/ci-cloud-identity.d.ts +13 -1
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
- package/dist/workspace/ci-cloud-identity.js +30 -1
- package/dist/workspace/compose-graph.d.ts +10 -1
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +6 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +6 -1
- package/dist/workspace/drift-cli.d.ts +81 -0
- package/dist/workspace/drift-cli.d.ts.map +1 -0
- package/dist/workspace/drift-cli.js +317 -0
- package/dist/workspace/drift.schema.json +672 -0
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +3 -0
- package/dist/workspace/graph.schema.json +72 -0
- package/dist/workspace/init.d.ts +5 -1
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/init.js +55 -9
- package/dist/workspace/ledger.schema.json +1 -1
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +2 -0
- package/dist/workspace/pr-report.schema.json +76 -3
- package/dist/workspace/promote-waves.d.ts +112 -0
- package/dist/workspace/promote-waves.d.ts.map +1 -0
- package/dist/workspace/promote-waves.js +290 -0
- package/dist/workspace/promote.d.ts +84 -2
- package/dist/workspace/promote.d.ts.map +1 -1
- package/dist/workspace/promote.js +347 -61
- package/dist/workspace/reason-codes.d.ts +12 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +14 -0
- package/dist/workspace/search-contract.d.ts +3 -3
- package/dist/workspace/search-contract.d.ts.map +1 -1
- package/dist/workspace/search-contract.js +2 -0
- package/dist/workspace/search.schema.json +103 -5
- package/package.json +14 -1
- package/src/__fixtures__/drift-record/README.md +58 -0
- package/src/__fixtures__/drift-record/choudoufu-cone.ndjson +4 -0
- package/src/__fixtures__/drift-record/choudoufu-resource.ndjson +3 -0
- package/src/__fixtures__/drift-record/component-status-ledger.json +65 -0
- package/src/__fixtures__/drift-record/component-status.json +91 -0
- package/src/__fixtures__/drift-record/deep-diff.json +259 -0
- package/src/__fixtures__/drift-record/lifecycle-diff-live.json +825 -0
- package/src/__fixtures__/drift-record/live-diff.json +125 -0
- package/src/audit/discover.e2e.test.ts +14 -0
- package/src/audit/discover.ts +3 -1
- package/src/behaviour.ts +1 -1
- package/src/capabilities/templates.json +145 -0
- package/src/capabilities/templates.test.ts +212 -0
- package/src/capabilities/templates.ts +204 -0
- package/src/change-set-bundle.test.ts +83 -0
- package/src/change-set-graph.ts +80 -9
- package/src/change-set.test.ts +24 -0
- package/src/change-set.ts +77 -14
- package/src/ci-identity-targets.test.ts +23 -0
- package/src/ci-identity.ts +10 -4
- package/src/cli/commands/import-index.test.ts +117 -0
- package/src/cli/commands/import-index.ts +265 -0
- package/src/cli/commands/lint.ts +4 -2
- package/src/cli/handlers/components.test.ts +9 -0
- package/src/cli/handlers/components.ts +12 -2
- package/src/cli/handlers/fan-out.ts +17 -3
- package/src/cli/handlers/graph.test.ts +42 -0
- package/src/cli/handlers/graph.ts +26 -4
- package/src/cli/handlers/index-cloud.ts +32 -0
- package/src/cli/handlers/index-diff.test.ts +68 -0
- package/src/cli/handlers/index-diff.ts +146 -0
- package/src/cli/handlers/ledger-root-member.test.ts +161 -0
- package/src/cli/handlers/lifecycle-drift.ts +68 -0
- package/src/cli/handlers/lifecycle.test.ts +33 -11
- package/src/cli/handlers/lifecycle.ts +205 -30
- package/src/cli/handlers/misc.ts +73 -0
- package/src/cli/handlers/pr-waves-blocked.test.ts +37 -2
- package/src/cli/handlers/pr.ts +16 -3
- package/src/cli/handlers/promote.test.ts +64 -0
- package/src/cli/handlers/promote.ts +81 -6
- package/src/cli/handlers/query.ts +27 -4
- package/src/cli/handlers/run-declared-reads-cli.test.ts +187 -0
- package/src/cli/handlers/run-groups-cli.test.ts +229 -0
- package/src/cli/handlers/scenario.test.ts +13 -0
- package/src/cli/handlers/scenario.ts +8 -7
- package/src/cli/handlers/search-index.test.ts +255 -0
- package/src/cli/handlers/search-json.test.ts +1 -1
- package/src/cli/handlers/search-ownership.test.ts +194 -0
- package/src/cli/handlers/search.ts +271 -38
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +56 -1
- package/src/cli/mcp/lifecycle-tools.ts +3 -2
- package/src/cli/mcp/resource-handlers.ts +4 -3
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +40 -2
- package/src/cli/registry.ts +19 -1
- package/src/cloud-lister/aws.test.ts +202 -0
- package/src/cloud-lister/aws.ts +226 -0
- package/src/cloud-lister/azure.test.ts +132 -0
- package/src/cloud-lister/azure.ts +142 -0
- package/src/cloud-lister/common.ts +115 -0
- package/src/cloud-lister/credentials.ts +110 -0
- package/src/cloud-lister/fakes.ts +66 -0
- package/src/cloud-lister/gcp.test.ts +121 -0
- package/src/cloud-lister/gcp.ts +159 -0
- package/src/cloud-lister/guard.test.ts +198 -0
- package/src/cloud-lister/guard.ts +111 -0
- package/src/cloud-lister/ids.ts +54 -0
- package/src/cloud-lister/index.ts +134 -0
- package/src/cloud-lister/kubernetes.test.ts +160 -0
- package/src/cloud-lister/kubernetes.ts +284 -0
- package/src/cloud-lister/markers.ts +74 -0
- package/src/cloud-lister/mask.ts +77 -0
- package/src/cloud-lister/shape.test.ts +81 -0
- package/src/cloud-lister/sigv4.ts +70 -0
- package/src/cloud-lister/transport.ts +118 -0
- package/src/cloud-lister/types.ts +135 -0
- package/src/components/capability-plugin-loader.ts +4 -0
- package/src/components/capability-plugin.ts +10 -0
- package/src/components/capability.ts +238 -0
- package/src/components/cli-support.ts +70 -14
- package/src/components/covered-round.test.ts +166 -0
- package/src/components/covered-round.ts +293 -0
- package/src/components/declared-reads.test.ts +103 -0
- package/src/components/declared-reads.ts +134 -0
- package/src/components/deploy-units.ts +4 -0
- package/src/components/driver.ts +101 -4
- package/src/components/fan-out-run.ts +95 -15
- package/src/components/fan-out-support.ts +10 -1
- package/src/components/fan-out.ts +30 -0
- package/src/components/groups.test.ts +320 -0
- package/src/components/groups.ts +880 -0
- package/src/components/index.ts +59 -0
- package/src/components/plan-shape-conformance.ts +130 -0
- package/src/components/pr-env-run-bundle.test.ts +2 -0
- package/src/components/pr-run.test.ts +728 -4
- package/src/components/pr-run.ts +395 -55
- package/src/components/promote-rounds.ts +25 -2
- package/src/components/promote.ts +55 -5
- package/src/components/registry.test.ts +1 -1
- package/src/components/release-gate.ts +115 -30
- package/src/components/release-groups.test.ts +362 -0
- package/src/components/run-groups.ts +113 -0
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +1 -0
- package/src/components/verbs/member-outputs.test.ts +205 -0
- package/src/components/verbs/member-outputs.ts +308 -0
- package/src/components/wave-plan.ts +5 -2
- package/src/config.ts +44 -0
- package/src/deep-observation.ts +5 -23
- package/src/drift-record.test.ts +596 -0
- package/src/drift-record.ts +1206 -0
- package/src/engine-facts.guard.test.ts +111 -0
- package/src/engine-facts.test.ts +178 -0
- package/src/engine-facts.ts +154 -0
- package/src/gated-waves-bundle.test.ts +2 -0
- package/src/graph-ir-live.test.ts +92 -0
- package/src/graph-ir.ts +317 -7
- package/src/graph-refs.ts +416 -0
- package/src/graph-schema/fixtures/adopt.json +15 -0
- package/src/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/src/graph-schema/fixtures/index.json +68 -0
- package/src/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/src/graph-schema/fixtures.ts +267 -0
- package/src/graph-schema/generate.ts +263 -0
- package/src/graph-schema/graph-schema.test.ts +153 -0
- package/src/graph-schema/graph.schema.json +1387 -0
- package/src/health.schema.json +2 -1
- package/src/identity.ts +2 -0
- package/src/index.ts +2 -0
- package/src/instance-nodes.ts +288 -0
- package/src/lexicon.ts +76 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T120000Z-aaaaaaaaaaaa.json +149 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T130000Z-bbbbbbbbbbbb.json +127 -0
- package/src/lifecycle/adoption-file.test.ts +100 -0
- package/src/lifecycle/adoption-file.ts +154 -0
- package/src/lifecycle/cloud-index.test.ts +517 -0
- package/src/lifecycle/cloud-index.ts +736 -0
- package/src/lifecycle/derive-edges.test.ts +193 -0
- package/src/lifecycle/derive-edges.ts +182 -0
- package/src/lifecycle/git.ts +10 -4
- package/src/lifecycle/identity-match.test.ts +308 -0
- package/src/lifecycle/identity-match.ts +257 -0
- package/src/lifecycle/index-diff.test.ts +198 -0
- package/src/lifecycle/index-diff.ts +476 -0
- package/src/lifecycle/index-document.test.ts +64 -0
- package/src/lifecycle/index-document.ts +299 -0
- package/src/lifecycle/index-drift.test.ts +191 -0
- package/src/lifecycle/index-drift.ts +304 -0
- package/src/lifecycle/index-import.test.ts +255 -0
- package/src/lifecycle/index-import.ts +634 -0
- package/src/lifecycle/index-join.test.ts +250 -0
- package/src/lifecycle/index-join.ts +304 -0
- package/src/lifecycle/index-store-load-bearing.test.ts +187 -0
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/member-ledger.test.ts +25 -7
- package/src/lifecycle/observation-baseline.test.ts +72 -1
- package/src/lifecycle/observation-baseline.ts +190 -27
- package/src/lifecycle/observe.ts +6 -1
- package/src/lifecycle/query.test.ts +69 -1
- package/src/lifecycle/query.ts +103 -10
- package/src/lifecycle/replay.test.ts +9 -5
- package/src/lifecycle/replay.ts +9 -5
- package/src/lifecycle/scenario.ts +4 -3
- package/src/lifecycle/snapshot-store-fake.ts +29 -0
- package/src/lifecycle/snapshot-store-s3.ts +316 -0
- package/src/lifecycle/snapshot-store.test.ts +385 -0
- package/src/lifecycle/snapshot-store.ts +981 -0
- package/src/lifecycle/snapshot.test.ts +13 -0
- package/src/lifecycle/snapshot.ts +23 -6
- package/src/lifecycle/type-listing.test.ts +166 -0
- package/src/lifecycle/type-listing.ts +309 -0
- package/src/lint/component-checks.ts +17 -1
- package/src/lint/config.test.ts +3 -0
- package/src/lint/presets/relaxed.json +2 -1
- package/src/lint/presets/strict.json +2 -1
- package/src/lint/rules/__fixtures__/comp/comp008/fail/dns.component.ts +15 -0
- package/src/lint/rules/__fixtures__/comp/comp008/pass/dns.component.ts +10 -0
- package/src/lint/rules/comp/comp.test.ts +2 -1
- package/src/lint/rules/comp/comp008-applies-signal-only-root.ts +121 -0
- package/src/lint/rules/comp/comp008.test.ts +77 -0
- package/src/lint/rules/comp/index.ts +4 -1
- package/src/observation-edges.test.ts +33 -0
- package/src/observation.ts +36 -1
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +8 -5
- package/src/op/activity-failure.ts +36 -0
- package/src/op/index.ts +2 -1
- package/src/op/local-executor.test.ts +80 -0
- package/src/op/local-executor.ts +27 -9
- package/src/pr-loop-bundle.test.ts +5 -2
- package/src/pr-loop.test.ts +57 -1
- package/src/pr-loop.ts +154 -6
- package/src/pulumi-urn.ts +151 -0
- package/src/release-floors.ts +22 -0
- package/src/sensitive-key.ts +34 -0
- package/src/workspace/adoption-report.test.ts +61 -0
- package/src/workspace/adoption-report.ts +103 -0
- package/src/workspace/capabilities-contract.test.ts +4 -0
- package/src/workspace/capabilities-contract.ts +9 -1
- package/src/workspace/capabilities.schema.json +98 -0
- package/src/workspace/change-set.schema.json +42 -3
- package/src/workspace/ci-cloud-identity.ts +31 -1
- package/src/workspace/compose-graph.test.ts +12 -0
- package/src/workspace/compose-graph.ts +12 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.ts +6 -1
- package/src/workspace/drift-cli.test.ts +65 -0
- package/src/workspace/drift-cli.ts +365 -0
- package/src/workspace/drift.schema.json +672 -0
- package/src/workspace/graph-cli.ts +5 -0
- package/src/workspace/graph.schema.json +72 -0
- package/src/workspace/init.test.ts +38 -1
- package/src/workspace/init.ts +50 -8
- package/src/workspace/intent-gaps.test.ts +18 -2
- package/src/workspace/ledger.schema.json +1 -1
- package/src/workspace/nested-graph.ts +1 -0
- package/src/workspace/pr-report.schema.json +76 -3
- package/src/workspace/promote-waves.test.ts +296 -0
- package/src/workspace/promote-waves.ts +340 -0
- package/src/workspace/promote.test.ts +158 -4
- package/src/workspace/promote.ts +398 -57
- package/src/workspace/reason-codes.test.ts +4 -1
- package/src/workspace/reason-codes.ts +14 -0
- package/src/workspace/search-contract.ts +2 -0
- package/src/workspace/search.schema.json +103 -5
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates the graph JSON Schema set from chant core's TypeScript types
|
|
3
|
+
* (#4527; schema home ruled on INTENTIUS/behold#1025 Q5, 2026-10-26).
|
|
4
|
+
*
|
|
5
|
+
* One schema file, ./graph.schema.json, covers the documents a Go engine or
|
|
6
|
+
* a non-chant reader has to write or read without importing chant:
|
|
7
|
+
*
|
|
8
|
+
* - `EngineGraphDocument` (../engine-facts.ts): what `choudoufu live-graph
|
|
9
|
+
* -json` and `plunge graph --json` print, a `GraphIR` at version 1 with
|
|
10
|
+
* `meta.engineGraph`, node `facts` and edge `grain`;
|
|
11
|
+
* - `IndexDocument` (../lifecycle/index-document.ts): one index version;
|
|
12
|
+
* - `AdoptionFile` (../lifecycle/adoption-file.ts): the `adopt: "v1"` file
|
|
13
|
+
* choudoufu, plunge and chant adopt indexed resources from (#4536).
|
|
14
|
+
*
|
|
15
|
+
* Each is a `$defs` entry, so a test validates against
|
|
16
|
+
* `<$id>#/$defs/EngineGraphDocument`, `<$id>#/$defs/IndexDocument` or
|
|
17
|
+
* `<$id>#/$defs/AdoptionFile`. The
|
|
18
|
+
* fixtures in ./fixtures are written from ./fixtures.ts, which the compiler
|
|
19
|
+
* checks against the same types.
|
|
20
|
+
*
|
|
21
|
+
* The emitter is a small walk over the TypeScript checker, not a dependency:
|
|
22
|
+
* the repo already ships `typescript`, and the types use only what JSON can
|
|
23
|
+
* hold (strings, numbers, booleans, literals, unions, arrays, records and
|
|
24
|
+
* interfaces). Anything else (a function, a class, a generic interface) is
|
|
25
|
+
* refused with its path, so a type that cannot be printed fails generation
|
|
26
|
+
* rather than printing a loose schema.
|
|
27
|
+
*
|
|
28
|
+
* Object schemas are closed (`additionalProperties: false`) unless the type
|
|
29
|
+
* has an index signature, so an engine's test catches a misspelled field.
|
|
30
|
+
* Readers still ignore fields they do not know (GRAPH_IR_VERSION's rule): the
|
|
31
|
+
* closed schema is for writers testing their output against the chant they
|
|
32
|
+
* target.
|
|
33
|
+
*
|
|
34
|
+
* `npm run generate:graph-schema` writes the files; `-- --check` exits 1 when
|
|
35
|
+
* the checked-in files differ, and ./graph-schema.test.ts asserts the same.
|
|
36
|
+
*/
|
|
37
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
38
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
39
|
+
import { fileURLToPath } from "node:url";
|
|
40
|
+
import * as ts from "typescript";
|
|
41
|
+
import { GRAPH_SCHEMA_FIXTURES } from "./fixtures";
|
|
42
|
+
|
|
43
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
44
|
+
const coreSrc = resolve(here, "..");
|
|
45
|
+
|
|
46
|
+
/** The schema's `$id`. */
|
|
47
|
+
export const GRAPH_SCHEMA_ID = "https://intentius.io/chant/schemas/graph/v1/graph.schema.json";
|
|
48
|
+
|
|
49
|
+
/** Where the generated schema is checked in. */
|
|
50
|
+
export const GRAPH_SCHEMA_PATH = join(here, "graph.schema.json");
|
|
51
|
+
|
|
52
|
+
/** Where the generated fixtures are checked in. */
|
|
53
|
+
export const GRAPH_SCHEMA_FIXTURE_DIR = join(here, "fixtures");
|
|
54
|
+
|
|
55
|
+
/** The root types, by the file that declares each. */
|
|
56
|
+
const ROOTS: ReadonlyArray<{ file: string; name: string }> = [
|
|
57
|
+
{ file: join(coreSrc, "engine-facts.ts"), name: "EngineGraphDocument" },
|
|
58
|
+
{ file: join(coreSrc, "lifecycle", "index-document.ts"), name: "IndexDocument" },
|
|
59
|
+
{ file: join(coreSrc, "lifecycle", "adoption-file.ts"), name: "AdoptionFile" },
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
type Schema = Record<string, unknown>;
|
|
63
|
+
|
|
64
|
+
/** `{@link X}` and `{@link X text}` as plain text. */
|
|
65
|
+
function plainDoc(text: string): string {
|
|
66
|
+
return text
|
|
67
|
+
.replace(/\{@link(?:code|plain)?\s+([^}\s|]+)(?:[\s|]+([^}]*))?\}/g, (_m, name: string, label?: string) => (label?.trim() ? label.trim() : name))
|
|
68
|
+
.replace(/\r\n/g, "\n")
|
|
69
|
+
// Unwrap hard-wrapped lines; keep paragraph breaks and list items.
|
|
70
|
+
.replace(/([^\n])\n(?!\n|\s*[-*] |\s*\d+\. )\s*/g, "$1 ")
|
|
71
|
+
.trim();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function docOf(symbol: ts.Symbol | undefined, checker: ts.TypeChecker): string | undefined {
|
|
75
|
+
if (!symbol) return undefined;
|
|
76
|
+
const text = plainDoc(ts.displayPartsToString(symbol.getDocumentationComment(checker)));
|
|
77
|
+
return text === "" ? undefined : text;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Declared under packages/core/src, so the name is chant's and not the standard library's. */
|
|
81
|
+
function isCoreDeclaration(symbol: ts.Symbol | undefined): boolean {
|
|
82
|
+
const decl = symbol?.declarations?.[0];
|
|
83
|
+
if (!decl) return false;
|
|
84
|
+
const file = resolve(decl.getSourceFile().fileName);
|
|
85
|
+
return file.startsWith(coreSrc + sep) && !file.includes(`${sep}node_modules${sep}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function stableJson(value: unknown): string {
|
|
89
|
+
return JSON.stringify(value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
class Emitter {
|
|
93
|
+
readonly defs = new Map<string, Schema>();
|
|
94
|
+
private readonly defTypes = new Map<string, ts.Type>();
|
|
95
|
+
|
|
96
|
+
constructor(private readonly checker: ts.TypeChecker) {}
|
|
97
|
+
|
|
98
|
+
/** A `$ref` for a named chant type, else its structure inline. */
|
|
99
|
+
emit(type: ts.Type, path: string): Schema {
|
|
100
|
+
const name = this.defName(type, path);
|
|
101
|
+
if (name === undefined) return this.structure(type, path);
|
|
102
|
+
const seen = this.defTypes.get(name);
|
|
103
|
+
if (seen !== undefined && seen !== type) throw new Error(`graph schema: two types are named ${name} (at ${path})`);
|
|
104
|
+
if (seen === undefined) {
|
|
105
|
+
this.defTypes.set(name, type);
|
|
106
|
+
this.defs.set(name, {}); // placeholder, so a recursive type refers to itself
|
|
107
|
+
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
108
|
+
const description = docOf(symbol, this.checker);
|
|
109
|
+
this.defs.set(name, { ...(description ? { description } : {}), ...this.structure(type, name) });
|
|
110
|
+
}
|
|
111
|
+
return { $ref: `#/$defs/${name}` };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private defName(type: ts.Type, path: string): string | undefined {
|
|
115
|
+
if (type.aliasSymbol && !type.aliasTypeArguments?.length && isCoreDeclaration(type.aliasSymbol)) {
|
|
116
|
+
return type.aliasSymbol.getName();
|
|
117
|
+
}
|
|
118
|
+
const symbol = type.getSymbol();
|
|
119
|
+
if (
|
|
120
|
+
symbol &&
|
|
121
|
+
type.flags & ts.TypeFlags.Object &&
|
|
122
|
+
symbol.flags & ts.SymbolFlags.Interface &&
|
|
123
|
+
isCoreDeclaration(symbol)
|
|
124
|
+
) {
|
|
125
|
+
if ((type as ts.TypeReference).typeArguments?.length) throw new Error(`graph schema: generic interface ${symbol.getName()} at ${path}`);
|
|
126
|
+
return symbol.getName();
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private structure(type: ts.Type, path: string): Schema {
|
|
132
|
+
const f = type.flags;
|
|
133
|
+
if (f & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return {};
|
|
134
|
+
if (f & ts.TypeFlags.String) return { type: "string" };
|
|
135
|
+
if (f & ts.TypeFlags.Number) return { type: "number" };
|
|
136
|
+
if (f & ts.TypeFlags.Boolean) return { type: "boolean" };
|
|
137
|
+
if (f & ts.TypeFlags.Null) return { type: "null" };
|
|
138
|
+
if (f & ts.TypeFlags.StringLiteral) return { const: (type as ts.StringLiteralType).value };
|
|
139
|
+
if (f & ts.TypeFlags.NumberLiteral) return { const: (type as ts.NumberLiteralType).value };
|
|
140
|
+
if (f & ts.TypeFlags.BooleanLiteral) return { const: (type as unknown as { intrinsicName: string }).intrinsicName === "true" };
|
|
141
|
+
if (type.isUnion()) return this.union(type, path);
|
|
142
|
+
if (this.checker.isTupleType(type)) {
|
|
143
|
+
const args = this.checker.getTypeArguments(type as ts.TypeReference);
|
|
144
|
+
return { type: "array", prefixItems: args.map((a, i) => this.emit(a, `${path}[${i}]`)), items: false };
|
|
145
|
+
}
|
|
146
|
+
if (this.checker.isArrayType(type)) {
|
|
147
|
+
const [item] = this.checker.getTypeArguments(type as ts.TypeReference);
|
|
148
|
+
return { type: "array", items: this.emit(item!, `${path}[]`) };
|
|
149
|
+
}
|
|
150
|
+
if (f & ts.TypeFlags.Object || type.isIntersection()) return this.object(type, path);
|
|
151
|
+
throw new Error(`graph schema: cannot print the type at ${path} (${this.checker.typeToString(type)})`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private union(type: ts.UnionType, path: string): Schema {
|
|
155
|
+
let members = type.types.filter((t) => !(t.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)));
|
|
156
|
+
const bools = members.filter((t) => t.flags & ts.TypeFlags.BooleanLiteral);
|
|
157
|
+
const hasBoolean = bools.length === 2;
|
|
158
|
+
if (hasBoolean) members = members.filter((t) => !(t.flags & ts.TypeFlags.BooleanLiteral));
|
|
159
|
+
const strings = members.filter((t) => t.flags & ts.TypeFlags.StringLiteral).map((t) => (t as ts.StringLiteralType).value);
|
|
160
|
+
const rest = members.filter((t) => !(t.flags & ts.TypeFlags.StringLiteral));
|
|
161
|
+
const out: Schema[] = [];
|
|
162
|
+
if (strings.length > 0) out.push({ type: "string", enum: [...new Set(strings)].sort() });
|
|
163
|
+
if (hasBoolean) out.push({ type: "boolean" });
|
|
164
|
+
for (const t of rest) out.push(this.emit(t, path));
|
|
165
|
+
if (out.length === 1) return out[0]!;
|
|
166
|
+
if (out.length === 0) throw new Error(`graph schema: an empty union at ${path}`);
|
|
167
|
+
return { anyOf: out.sort((a, b) => (stableJson(a) < stableJson(b) ? -1 : stableJson(a) > stableJson(b) ? 1 : 0)) };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private object(type: ts.Type, path: string): Schema {
|
|
171
|
+
if (type.getCallSignatures().length > 0 || type.getConstructSignatures().length > 0) {
|
|
172
|
+
throw new Error(`graph schema: a function type at ${path}`);
|
|
173
|
+
}
|
|
174
|
+
const properties: Record<string, Schema> = {};
|
|
175
|
+
const required: string[] = [];
|
|
176
|
+
for (const prop of this.checker.getPropertiesOfType(type)) {
|
|
177
|
+
const name = prop.getName();
|
|
178
|
+
const propPath = `${path}.${name}`;
|
|
179
|
+
const decl = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
180
|
+
if (decl && (ts.isMethodSignature(decl) || ts.isMethodDeclaration(decl))) throw new Error(`graph schema: a method at ${propPath}`);
|
|
181
|
+
// The declared type node keeps an alias (`EdgeGrain`) that the optional
|
|
182
|
+
// property's `T | undefined` loses.
|
|
183
|
+
const typeNode = decl && (ts.isPropertySignature(decl) || ts.isPropertyDeclaration(decl)) ? decl.type : undefined;
|
|
184
|
+
const propType = typeNode ? this.checker.getTypeFromTypeNode(typeNode) : this.checker.getTypeOfSymbol(prop);
|
|
185
|
+
const description = docOf(prop, this.checker);
|
|
186
|
+
const schema = this.emit(propType, propPath);
|
|
187
|
+
properties[name] = description ? { description, ...schema } : schema;
|
|
188
|
+
if (!(prop.flags & ts.SymbolFlags.Optional)) required.push(name);
|
|
189
|
+
}
|
|
190
|
+
const index = this.checker.getIndexInfoOfType(type, ts.IndexKind.String);
|
|
191
|
+
const out: Schema = { type: "object" };
|
|
192
|
+
if (Object.keys(properties).length > 0) out.properties = properties;
|
|
193
|
+
if (required.length > 0) out.required = required;
|
|
194
|
+
if (index) {
|
|
195
|
+
if (!(index.type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown))) out.additionalProperties = this.emit(index.type, `${path}[string]`);
|
|
196
|
+
} else {
|
|
197
|
+
out.additionalProperties = false;
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function program(): ts.Program {
|
|
204
|
+
return ts.createProgram(
|
|
205
|
+
ROOTS.map((r) => r.file),
|
|
206
|
+
{
|
|
207
|
+
strict: true,
|
|
208
|
+
noEmit: true,
|
|
209
|
+
skipLibCheck: true,
|
|
210
|
+
target: ts.ScriptTarget.ES2022,
|
|
211
|
+
module: ts.ModuleKind.ESNext,
|
|
212
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
213
|
+
allowImportingTsExtensions: true,
|
|
214
|
+
resolveJsonModule: true,
|
|
215
|
+
types: [],
|
|
216
|
+
},
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The schema set, as an object. */
|
|
221
|
+
export function generateGraphSchema(): Schema {
|
|
222
|
+
const prog = program();
|
|
223
|
+
const checker = prog.getTypeChecker();
|
|
224
|
+
const emitter = new Emitter(checker);
|
|
225
|
+
const roots: Schema[] = [];
|
|
226
|
+
for (const root of ROOTS) {
|
|
227
|
+
const source = prog.getSourceFile(root.file);
|
|
228
|
+
if (!source) throw new Error(`graph schema: ${root.file} is not in the program`);
|
|
229
|
+
const moduleSymbol = checker.getSymbolAtLocation(source);
|
|
230
|
+
const symbol = moduleSymbol && checker.getExportsOfModule(moduleSymbol).find((s) => s.getName() === root.name);
|
|
231
|
+
if (!symbol) throw new Error(`graph schema: ${root.file} exports no ${root.name}`);
|
|
232
|
+
roots.push(emitter.emit(checker.getDeclaredTypeOfSymbol(symbol), root.name));
|
|
233
|
+
}
|
|
234
|
+
const defs = Object.fromEntries([...emitter.defs.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
|
|
235
|
+
return {
|
|
236
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
237
|
+
$id: GRAPH_SCHEMA_ID,
|
|
238
|
+
title: "chant-graph/v1",
|
|
239
|
+
description:
|
|
240
|
+
"Generated from chant core's TypeScript types (packages/core/src/engine-facts.ts, packages/core/src/lifecycle/index-document.ts, packages/core/src/lifecycle/adoption-file.ts) by `npm run generate:graph-schema`; do not edit by hand. Three documents: an engine graph (`#/$defs/EngineGraphDocument`, what `choudoufu live-graph -json` and `plunge graph --json` print, chant#4520), an index version (`#/$defs/IndexDocument`, behold#1025) and an adoption file (`#/$defs/AdoptionFile`, the `adopt: v1` input choudoufu, plunge and chant adopt from, chant#4536). Objects are closed so a writer's test catches a misspelled field; a reader ignores fields it does not know.",
|
|
241
|
+
anyOf: roots,
|
|
242
|
+
$defs: defs,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Every generated file, by path, with its contents. */
|
|
247
|
+
export function generatedGraphSchemaFiles(): Map<string, string> {
|
|
248
|
+
const files = new Map<string, string>();
|
|
249
|
+
files.set(GRAPH_SCHEMA_PATH, `${JSON.stringify(generateGraphSchema(), null, 2)}\n`);
|
|
250
|
+
for (const [name, doc] of Object.entries(GRAPH_SCHEMA_FIXTURES)) {
|
|
251
|
+
files.set(join(GRAPH_SCHEMA_FIXTURE_DIR, `${name}.json`), `${JSON.stringify(doc, null, 2)}\n`);
|
|
252
|
+
}
|
|
253
|
+
return files;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** The generated files whose checked-in copy is missing or differs. */
|
|
257
|
+
export function staleGraphSchemaFiles(): string[] {
|
|
258
|
+
const stale: string[] = [];
|
|
259
|
+
for (const [path, contents] of generatedGraphSchemaFiles()) {
|
|
260
|
+
if (!existsSync(path) || readFileSync(path, "utf-8") !== contents) stale.push(path);
|
|
261
|
+
}
|
|
262
|
+
return stale;
|
|
263
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// The graph JSON Schema set and its fixtures (#4527): generated from the
|
|
2
|
+
// TypeScript types, checked in, and in sync. Engines (choudoufu#2285,
|
|
3
|
+
// plunge#40) validate their output against the same files.
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { join, relative } from "node:path";
|
|
7
|
+
import Ajv2020 from "ajv/dist/2020";
|
|
8
|
+
import { GRAPH_SCHEMA_FIXTURES, GRAPH_SCHEMA_FIXTURE_DEFS } from "./fixtures";
|
|
9
|
+
import { GRAPH_SCHEMA_FIXTURE_DIR, GRAPH_SCHEMA_ID, GRAPH_SCHEMA_PATH, generateGraphSchema, staleGraphSchemaFiles } from "./generate";
|
|
10
|
+
import { validateIndexDocument, type IndexDocument } from "../lifecycle/index-document";
|
|
11
|
+
import { adoptionFileProblemsAgainst, type AdoptionFile } from "../lifecycle/adoption-file";
|
|
12
|
+
import { GRAPH_IR_VERSION } from "../graph-ir";
|
|
13
|
+
|
|
14
|
+
const schema = JSON.parse(readFileSync(GRAPH_SCHEMA_PATH, "utf-8")) as { $id: string; $defs: Record<string, unknown> };
|
|
15
|
+
const ajv = new Ajv2020({ allErrors: true, strict: true });
|
|
16
|
+
ajv.addSchema(schema);
|
|
17
|
+
const validator = (def: string) => ajv.getSchema(`${GRAPH_SCHEMA_ID}#/$defs/${def}`)!;
|
|
18
|
+
const fixture = (name: string): Record<string, unknown> =>
|
|
19
|
+
JSON.parse(readFileSync(join(GRAPH_SCHEMA_FIXTURE_DIR, `${name}.json`), "utf-8")) as Record<string, unknown>;
|
|
20
|
+
const clone = <T>(x: T): T => JSON.parse(JSON.stringify(x)) as T;
|
|
21
|
+
|
|
22
|
+
describe("graph schema sync (#4527)", () => {
|
|
23
|
+
it("the checked-in schema and fixtures match the TypeScript types (npm run generate:graph-schema if this fails)", () => {
|
|
24
|
+
const stale = staleGraphSchemaFiles().map((p) => relative(GRAPH_SCHEMA_FIXTURE_DIR, p));
|
|
25
|
+
expect(stale).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("covers the three documents in one set, with the engine facts and edge grain", () => {
|
|
29
|
+
const generated = generateGraphSchema() as { $defs: Record<string, unknown> };
|
|
30
|
+
for (const def of ["EngineGraphDocument", "IndexDocument", "AdoptionFile", "AdoptionSelection", "AdoptionIndexRef", "GraphIR", "IRNode", "IREdge", "EngineFacts", "EngineGraphMeta", "EdgeGrain"]) {
|
|
31
|
+
expect(Object.keys(generated.$defs)).toContain(def);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("keeps GraphIR at version 1", () => {
|
|
36
|
+
expect(GRAPH_IR_VERSION).toBe(1);
|
|
37
|
+
const doc = (schema.$defs.EngineGraphDocument as { properties: { version: unknown } }).properties.version;
|
|
38
|
+
expect(doc).toEqual({ const: 1 });
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("graph schema fixtures (#4527)", () => {
|
|
43
|
+
for (const [name, def] of Object.entries(GRAPH_SCHEMA_FIXTURE_DEFS)) {
|
|
44
|
+
it(`${name}.json validates as ${def}`, () => {
|
|
45
|
+
const validate = validator(def);
|
|
46
|
+
const ok = validate(fixture(name));
|
|
47
|
+
expect(validate.errors ?? []).toEqual([]);
|
|
48
|
+
expect(ok).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
it("the index fixture's stamp agrees with itself", () => {
|
|
53
|
+
expect(() => validateIndexDocument(GRAPH_SCHEMA_FIXTURES.index as IndexDocument)).not.toThrow();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("the adoption fixture names the index fixture's version, digest and node (#4536)", () => {
|
|
57
|
+
expect(adoptionFileProblemsAgainst(fixture("adopt") as unknown as AdoptionFile, fixture("index") as unknown as IndexDocument)).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("each engine fixture names its engine and carries facts and grain", () => {
|
|
61
|
+
for (const [name, engine, grains] of [
|
|
62
|
+
["choudoufu.engine-graph", "choudoufu", ["block"]],
|
|
63
|
+
["plunge.engine-graph", "plunge", ["instance", "property"]],
|
|
64
|
+
] as const) {
|
|
65
|
+
const doc = fixture(name) as { meta: { engineGraph: { engine: { name: string } } }; nodes: Array<{ facts?: unknown }>; edges: Array<{ grain?: string }> };
|
|
66
|
+
expect(doc.meta.engineGraph.engine.name).toBe(engine);
|
|
67
|
+
expect(doc.nodes.some((n) => n.facts !== undefined)).toBe(true);
|
|
68
|
+
expect([...new Set(doc.edges.map((e) => e.grain))].sort()).toEqual(grains);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("plunge's markers come from the record and its ownership stops at bound or pending (#4520 Q5)", () => {
|
|
73
|
+
const doc = fixture("plunge.engine-graph") as { nodes: Array<{ facts?: { ownership?: string; markers?: { source: string } } }> };
|
|
74
|
+
for (const n of doc.nodes) {
|
|
75
|
+
if (n.facts?.markers) expect(n.facts.markers.source).toBe("record");
|
|
76
|
+
if (n.facts?.ownership) expect(["bound", "pending"]).toContain(n.facts.ownership);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("graph schema refusals (#4527)", () => {
|
|
82
|
+
const engine = validator("EngineGraphDocument");
|
|
83
|
+
const base = () => clone(fixture("choudoufu.engine-graph")) as {
|
|
84
|
+
version: unknown;
|
|
85
|
+
meta: Record<string, unknown> & { engineGraph: Record<string, unknown> };
|
|
86
|
+
nodes: Array<Record<string, unknown> & { facts?: Record<string, unknown> }>;
|
|
87
|
+
edges: Array<Record<string, unknown>>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
it("refuses a misspelled facts field", () => {
|
|
91
|
+
const doc = base();
|
|
92
|
+
doc.nodes[0]!.facts = { ...doc.nodes[0]!.facts, ownedby: "marker" };
|
|
93
|
+
expect(engine(doc)).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("refuses an ownership value outside bound, unowned, pending and foreign", () => {
|
|
97
|
+
const doc = base();
|
|
98
|
+
doc.nodes[0]!.facts = { ...doc.nodes[0]!.facts, ownership: "owned" };
|
|
99
|
+
expect(engine(doc)).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("refuses a grain outside block, instance and property", () => {
|
|
103
|
+
const doc = base();
|
|
104
|
+
doc.edges[0]!.grain = "module";
|
|
105
|
+
expect(engine(doc)).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("refuses markers without encoding and source", () => {
|
|
109
|
+
const doc = base();
|
|
110
|
+
doc.nodes[0]!.facts = { markers: { owner: "web" } };
|
|
111
|
+
expect(engine(doc)).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("refuses a document with no meta.engineGraph, or at another version", () => {
|
|
115
|
+
const noMeta = base();
|
|
116
|
+
delete (noMeta.meta as { engineGraph?: unknown }).engineGraph;
|
|
117
|
+
expect(engine(noMeta)).toBe(false);
|
|
118
|
+
const v2 = base();
|
|
119
|
+
v2.version = 2;
|
|
120
|
+
expect(engine(v2)).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("lets other keys sit in meta beside engineGraph (meta is an open bag)", () => {
|
|
124
|
+
const doc = base();
|
|
125
|
+
doc.meta._behaviour = { engine: "x" };
|
|
126
|
+
expect(engine(doc)).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("refuses an adoption file at another version, with no select, or with a misspelled field (#4536)", () => {
|
|
130
|
+
const adopt = validator("AdoptionFile");
|
|
131
|
+
const base = () => clone(fixture("adopt")) as Record<string, unknown> & { select: Array<Record<string, unknown>> };
|
|
132
|
+
expect(adopt(base())).toBe(true);
|
|
133
|
+
const v2 = base();
|
|
134
|
+
v2.adopt = "v2";
|
|
135
|
+
expect(adopt(v2)).toBe(false);
|
|
136
|
+
const noSelect = base();
|
|
137
|
+
delete (noSelect as { select?: unknown }).select;
|
|
138
|
+
expect(adopt(noSelect)).toBe(false);
|
|
139
|
+
const typo = base();
|
|
140
|
+
typo.select[0]!.address = "aws_s3_bucket.x";
|
|
141
|
+
expect(adopt(typo)).toBe(false);
|
|
142
|
+
const noType = base();
|
|
143
|
+
delete noType.select[0]!.type;
|
|
144
|
+
expect(adopt(noType)).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("refuses an index coverage verdict outside listed and the unobserved reasons", () => {
|
|
148
|
+
const index = validator("IndexDocument");
|
|
149
|
+
const doc = clone(fixture("index")) as { coverage: Array<Record<string, unknown>> };
|
|
150
|
+
doc.coverage[0]!.verdict = "missing";
|
|
151
|
+
expect(index(doc)).toBe(false);
|
|
152
|
+
});
|
|
153
|
+
});
|