@intentius/chant 0.13.1 → 0.15.0
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/catalog.d.ts +45 -5
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/proof.d.ts +3 -0
- package/dist/audit/proof.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +4 -1
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts +3 -0
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts +8 -2
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts +37 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts.map +1 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts +48 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts.map +1 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +41 -0
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +39 -0
- package/dist/cli/handlers/components.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts +3 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts +4 -2
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts +49 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +35 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +22 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/lexicon-regen.d.ts +110 -0
- package/dist/codegen/lexicon-regen.d.ts.map +1 -0
- package/dist/codegen/pinned-upgrade.d.ts +153 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -0
- package/dist/codegen/rolling-upgrade.d.ts +138 -0
- package/dist/codegen/rolling-upgrade.d.ts.map +1 -0
- package/dist/codegen/surface-snapshot.d.ts +173 -0
- package/dist/codegen/surface-snapshot.d.ts.map +1 -0
- package/dist/codegen/version-bump.d.ts +21 -0
- package/dist/codegen/version-bump.d.ts.map +1 -0
- package/dist/components/auto-release.d.ts +93 -0
- package/dist/components/auto-release.d.ts.map +1 -0
- package/dist/components/builders.d.ts +37 -0
- package/dist/components/builders.d.ts.map +1 -0
- package/dist/components/capability-plugin-loader.d.ts +111 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -0
- package/dist/components/capability-plugin-schema.d.ts +24 -0
- package/dist/components/capability-plugin-schema.d.ts.map +1 -0
- package/dist/components/capability-plugin.d.ts +85 -0
- package/dist/components/capability-plugin.d.ts.map +1 -0
- package/dist/components/capability.d.ts +89 -0
- package/dist/components/capability.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +204 -0
- package/dist/components/cli-support.d.ts.map +1 -0
- package/dist/components/component.d.ts +179 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/config-defaults.d.ts +41 -0
- package/dist/components/config-defaults.d.ts.map +1 -0
- package/dist/components/discover.d.ts +60 -0
- package/dist/components/discover.d.ts.map +1 -0
- package/dist/components/driver-output.d.ts +20 -0
- package/dist/components/driver-output.d.ts.map +1 -0
- package/dist/components/driver.d.ts +209 -0
- package/dist/components/driver.d.ts.map +1 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/manifest-persistence.d.ts +79 -0
- package/dist/components/manifest-persistence.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +27 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts +22 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts.map +1 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts +37 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts.map +1 -0
- package/dist/components/pilots/lambda.pilot.d.ts +35 -0
- package/dist/components/pilots/lambda.pilot.d.ts.map +1 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts +17 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts.map +1 -0
- package/dist/components/pilots/project.d.ts +13 -0
- package/dist/components/pilots/project.d.ts.map +1 -0
- package/dist/components/presets/ecs-fargate.d.ts +59 -0
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -0
- package/dist/components/presets/index.d.ts +29 -0
- package/dist/components/presets/index.d.ts.map +1 -0
- package/dist/components/presets/lambda.d.ts +35 -0
- package/dist/components/presets/lambda.d.ts.map +1 -0
- package/dist/components/presets/single-host-compose.d.ts +43 -0
- package/dist/components/presets/single-host-compose.d.ts.map +1 -0
- package/dist/components/registry.d.ts +29 -0
- package/dist/components/registry.d.ts.map +1 -0
- package/dist/components/starter-plugin.d.ts +51 -0
- package/dist/components/starter-plugin.d.ts.map +1 -0
- package/dist/components/temporal-codegen-loader.d.ts +27 -0
- package/dist/components/temporal-codegen-loader.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts +35 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts +45 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts +33 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/bom-writer.d.ts +155 -0
- package/dist/components/verbs/bom-writer.d.ts.map +1 -0
- package/dist/components/verbs/build-archive.d.ts +205 -0
- package/dist/components/verbs/build-archive.d.ts.map +1 -0
- package/dist/components/verbs/build.d.ts +150 -0
- package/dist/components/verbs/build.d.ts.map +1 -0
- package/dist/components/verbs/cloud-executor.d.ts +88 -0
- package/dist/components/verbs/cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/component-bom.d.ts +103 -0
- package/dist/components/verbs/component-bom.d.ts.map +1 -0
- package/dist/components/verbs/index.d.ts +49 -0
- package/dist/components/verbs/index.d.ts.map +1 -0
- package/dist/components/verbs/license-policy.d.ts +56 -0
- package/dist/components/verbs/license-policy.d.ts.map +1 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts +81 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/process-runner.d.ts +64 -0
- package/dist/components/verbs/process-runner.d.ts.map +1 -0
- package/dist/components/verbs/reproducibility.d.ts +80 -0
- package/dist/components/verbs/reproducibility.d.ts.map +1 -0
- package/dist/components/verbs/sbom-generator.d.ts +157 -0
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/sbom.d.ts +79 -0
- package/dist/components/verbs/sbom.d.ts.map +1 -0
- package/dist/components/verbs/shell.d.ts +35 -0
- package/dist/components/verbs/shell.d.ts.map +1 -0
- package/dist/components/verbs/sign.d.ts +222 -0
- package/dist/components/verbs/sign.d.ts.map +1 -0
- package/dist/components/verbs/stub.d.ts +18 -0
- package/dist/components/verbs/stub.d.ts.map +1 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts +51 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/verify.d.ts +106 -0
- package/dist/components/verbs/verify.d.ts.map +1 -0
- package/dist/components/verbs/vex.d.ts +65 -0
- package/dist/components/verbs/vex.d.ts.map +1 -0
- package/dist/components/verbs/vuln-gate.d.ts +91 -0
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -0
- package/dist/components/verbs/vuln-scan.d.ts +116 -0
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -0
- package/dist/components/verbs/wait-verify.d.ts +85 -0
- package/dist/components/verbs/wait-verify.d.ts.map +1 -0
- package/dist/config.d.ts +205 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon.d.ts +78 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts +121 -0
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -0
- package/dist/lifecycle/build-ledger.d.ts +225 -0
- package/dist/lifecycle/build-ledger.d.ts.map +1 -0
- package/dist/lifecycle/git.d.ts +84 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +5 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/oras-referrer-lookup.d.ts +41 -0
- package/dist/lifecycle/oras-referrer-lookup.d.ts.map +1 -0
- package/dist/lifecycle/release-ledger.d.ts +122 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -0
- package/dist/lifecycle/status.d.ts +150 -0
- package/dist/lifecycle/status.d.ts.map +1 -0
- package/dist/lint/component-checks.d.ts +95 -0
- package/dist/lint/component-checks.d.ts.map +1 -0
- package/dist/lint/engine.d.ts +23 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/presets/strict.json +8 -1
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts +20 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts +28 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +39 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +37 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts +43 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts +22 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts +33 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts.map +1 -0
- package/dist/lint/rules/comp/index.d.ts +18 -0
- package/dist/lint/rules/comp/index.d.ts.map +1 -0
- package/dist/lint/rules/comp/support.d.ts +71 -0
- package/dist/lint/rules/comp/support.d.ts.map +1 -0
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts +11 -6
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/activity-runtime.d.ts +24 -0
- package/dist/op/activity-runtime.d.ts.map +1 -0
- package/dist/op/builders.d.ts +56 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/ownership.d.ts +20 -14
- package/dist/ownership.d.ts.map +1 -1
- package/package.json +14 -1
- package/src/audit/catalog.test.ts +74 -22
- package/src/audit/catalog.ts +74 -471
- package/src/audit/proof.ts +4 -2
- package/src/audit/report-html.test.ts +14 -7
- package/src/audit/report-model.ts +20 -9
- package/src/audit/report.test.ts +36 -13
- package/src/audit/report.ts +2 -0
- package/src/audit/rules-doc.test.ts +8 -6
- package/src/audit/rules-doc.ts +13 -5
- package/src/cli/commands/audit.ts +23 -18
- package/src/cli/commands/component-lint.test.ts +158 -0
- package/src/cli/commands/doctor.test.ts +116 -2
- package/src/cli/commands/doctor.ts +46 -0
- package/src/cli/commands/lexicon-rolling-upgrade.ts +198 -0
- package/src/cli/commands/lexicon-surface-diff.test.ts +104 -0
- package/src/cli/commands/lexicon-surface-diff.ts +185 -0
- package/src/cli/commands/lint.ts +142 -1
- package/src/cli/commands/pinned-upgrade.ts +204 -0
- package/src/cli/handlers/build.ts +58 -1
- package/src/cli/handlers/components.test.ts +504 -0
- package/src/cli/handlers/components.ts +404 -0
- package/src/cli/handlers/dev.ts +60 -1
- package/src/cli/handlers/graph.ts +47 -2
- package/src/cli/handlers/misc.ts +45 -1
- package/src/cli/handlers/run.test.ts +967 -3
- package/src/cli/handlers/run.ts +618 -11
- package/src/cli/main.test.ts +66 -0
- package/src/cli/main.ts +105 -2
- package/src/cli/registry.ts +35 -0
- package/src/codegen/fetch.test.ts +84 -3
- package/src/codegen/fetch.ts +76 -2
- package/src/codegen/lexicon-regen.test.ts +298 -0
- package/src/codegen/lexicon-regen.ts +545 -0
- package/src/codegen/pinned-upgrade.test.ts +399 -0
- package/src/codegen/pinned-upgrade.ts +423 -0
- package/src/codegen/rolling-upgrade.test.ts +333 -0
- package/src/codegen/rolling-upgrade.ts +320 -0
- package/src/codegen/surface-snapshot.test.ts +461 -0
- package/src/codegen/surface-snapshot.ts +546 -0
- package/src/codegen/version-bump.test.ts +47 -0
- package/src/codegen/version-bump.ts +39 -0
- package/src/components/README.md +130 -0
- package/src/components/SPRAWL-VALIDATION.md +181 -0
- package/src/components/__fixtures__/alb-ecs-service.json +51 -0
- package/src/components/__fixtures__/dynamodb-infra.json +32 -0
- package/src/components/__fixtures__/emr-job-consumer.json +26 -0
- package/src/components/__fixtures__/jar-lib-producer.json +16 -0
- package/src/components/__fixtures__/lambda-image-processor.json +28 -0
- package/src/components/__fixtures__/neo4j-fanout.json +34 -0
- package/src/components/__fixtures__/single-host-compose.json +29 -0
- package/src/components/auto-release.test.ts +217 -0
- package/src/components/auto-release.ts +216 -0
- package/src/components/builders.test.ts +45 -0
- package/src/components/builders.ts +71 -0
- package/src/components/capability-plugin-loader.ts +218 -0
- package/src/components/capability-plugin-schema.ts +56 -0
- package/src/components/capability-plugin.test.ts +235 -0
- package/src/components/capability-plugin.ts +108 -0
- package/src/components/capability.ts +117 -0
- package/src/components/cli-support.test.ts +579 -0
- package/src/components/cli-support.ts +481 -0
- package/src/components/component-schema.test.ts +265 -0
- package/src/components/component.schema.json +235 -0
- package/src/components/component.test.ts +251 -0
- package/src/components/component.ts +255 -0
- package/src/components/config-defaults.test.ts +263 -0
- package/src/components/config-defaults.ts +145 -0
- package/src/components/discover.test.ts +352 -0
- package/src/components/discover.ts +167 -0
- package/src/components/driver-output.ts +71 -0
- package/src/components/driver.test.ts +638 -0
- package/src/components/driver.ts +690 -0
- package/src/components/index.ts +113 -0
- package/src/components/manifest-persistence.test.ts +152 -0
- package/src/components/manifest-persistence.ts +164 -0
- package/src/components/pilots/README.md +33 -0
- package/src/components/pilots/alb-ecs.pilot.ts +63 -0
- package/src/components/pilots/dynamodb.pilot.ts +59 -0
- package/src/components/pilots/jar-emr.pilot.ts +69 -0
- package/src/components/pilots/lambda.pilot.ts +55 -0
- package/src/components/pilots/neo4j-fanout.pilot.ts +92 -0
- package/src/components/pilots/pilots-lint-clean.test.ts +78 -0
- package/src/components/pilots/pilots.test.ts +126 -0
- package/src/components/pilots/project.ts +13 -0
- package/src/components/presets/comp007-reduction.test.ts +122 -0
- package/src/components/presets/ecs-fargate.test.ts +84 -0
- package/src/components/presets/ecs-fargate.ts +103 -0
- package/src/components/presets/index.ts +32 -0
- package/src/components/presets/lambda.test.ts +35 -0
- package/src/components/presets/lambda.ts +53 -0
- package/src/components/presets/single-host-compose.test.ts +65 -0
- package/src/components/presets/single-host-compose.ts +64 -0
- package/src/components/registry.test.ts +112 -0
- package/src/components/registry.ts +37 -0
- package/src/components/starter-plugin.ts +105 -0
- package/src/components/temporal-codegen-loader.ts +41 -0
- package/src/components/verbs/__fixtures__/package-lock.json +45 -0
- package/src/components/verbs/__fixtures__/pom.xml +37 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-1.5.schema.json +3800 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-spdx-license.schema.json +621 -0
- package/src/components/verbs/__fixtures__/schemas/jsf-0.82.schema.json +240 -0
- package/src/components/verbs/__fixtures__/schemas/spdx-2.3.schema.json +740 -0
- package/src/components/verbs/__tests__/mock-cloud-executor.ts +102 -0
- package/src/components/verbs/__tests__/mock-process-runner.ts +79 -0
- package/src/components/verbs/__tests__/mock-sbom-generator.ts +85 -0
- package/src/components/verbs/bom-writer.test.ts +331 -0
- package/src/components/verbs/bom-writer.ts +386 -0
- package/src/components/verbs/build-archive.test.ts +251 -0
- package/src/components/verbs/build-archive.ts +296 -0
- package/src/components/verbs/build.test.ts +222 -0
- package/src/components/verbs/build.ts +252 -0
- package/src/components/verbs/cloud-executor.ts +181 -0
- package/src/components/verbs/component-bom.test.ts +219 -0
- package/src/components/verbs/component-bom.ts +189 -0
- package/src/components/verbs/index.ts +49 -0
- package/src/components/verbs/license-policy.ts +115 -0
- package/src/components/verbs/lockfile-sbom-generator.test.ts +195 -0
- package/src/components/verbs/lockfile-sbom-generator.ts +236 -0
- package/src/components/verbs/process-runner.test.ts +79 -0
- package/src/components/verbs/process-runner.ts +113 -0
- package/src/components/verbs/reproducibility.test.ts +24 -0
- package/src/components/verbs/reproducibility.ts +100 -0
- package/src/components/verbs/sbom-generator.test.ts +96 -0
- package/src/components/verbs/sbom-generator.ts +209 -0
- package/src/components/verbs/sbom.test.ts +184 -0
- package/src/components/verbs/sbom.ts +152 -0
- package/src/components/verbs/shell.test.ts +36 -0
- package/src/components/verbs/shell.ts +51 -0
- package/src/components/verbs/sign.test.ts +210 -0
- package/src/components/verbs/sign.ts +350 -0
- package/src/components/verbs/stub.ts +34 -0
- package/src/components/verbs/tool-sbom-generator.test.ts +194 -0
- package/src/components/verbs/tool-sbom-generator.ts +192 -0
- package/src/components/verbs/verify.test.ts +159 -0
- package/src/components/verbs/verify.ts +179 -0
- package/src/components/verbs/vex.ts +182 -0
- package/src/components/verbs/vuln-gate.test.ts +201 -0
- package/src/components/verbs/vuln-gate.ts +170 -0
- package/src/components/verbs/vuln-scan.test.ts +145 -0
- package/src/components/verbs/vuln-scan.ts +266 -0
- package/src/components/verbs/wait-verify.test.ts +111 -0
- package/src/components/verbs/wait-verify.ts +171 -0
- package/src/config.test.ts +74 -1
- package/src/config.ts +219 -0
- package/src/index.ts +32 -0
- package/src/lexicon.ts +88 -0
- package/src/lifecycle/build-ledger-store.test.ts +217 -0
- package/src/lifecycle/build-ledger-store.ts +165 -0
- package/src/lifecycle/build-ledger.test.ts +349 -0
- package/src/lifecycle/build-ledger.ts +305 -0
- package/src/lifecycle/git.test.ts +118 -0
- package/src/lifecycle/git.ts +149 -14
- package/src/lifecycle/index.ts +5 -0
- package/src/lifecycle/oras-referrer-lookup.test.ts +116 -0
- package/src/lifecycle/oras-referrer-lookup.ts +110 -0
- package/src/lifecycle/release-ledger.test.ts +209 -0
- package/src/lifecycle/release-ledger.ts +185 -0
- package/src/lifecycle/status.test.ts +330 -0
- package/src/lifecycle/status.ts +278 -0
- package/src/lint/component-checks.ts +148 -0
- package/src/lint/config.test.ts +21 -0
- package/src/lint/engine.ts +11 -2
- package/src/lint/presets/relaxed.json +8 -1
- package/src/lint/presets/strict.json +8 -1
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.ts +27 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.ts +19 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.ts +20 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.ts +18 -0
- package/src/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.ts +12 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.ts +18 -0
- package/src/lint/rules/comp/comp.test.ts +378 -0
- package/src/lint/rules/comp/comp001-publishes-never-applies.ts +78 -0
- package/src/lint/rules/comp/comp002-dangling-wiring-ref.ts +94 -0
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +115 -0
- package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +66 -0
- package/src/lint/rules/comp/comp005-capability-kind-is-noun.ts +113 -0
- package/src/lint/rules/comp/comp006-shell-needs-reason.ts +55 -0
- package/src/lint/rules/comp/comp007-composition-sprawl.ts +71 -0
- package/src/lint/rules/comp/index.ts +37 -0
- package/src/lint/rules/comp/support.ts +173 -0
- package/src/lsp/lexicon-providers.test.ts +55 -0
- package/src/lsp/lexicon-providers.ts +13 -3
- package/src/op/activity-registry.test.ts +38 -0
- package/src/op/activity-registry.ts +31 -12
- package/src/op/activity-runtime.ts +73 -0
- package/src/op/builders.ts +92 -0
- package/src/op/index.ts +3 -1
- package/src/ownership.test.ts +24 -26
- package/src/ownership.ts +26 -38
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the typed `Component` authoring form (#560, epic #551):
|
|
3
|
+
* the `phase()`/`gate()`/`stackOutput()` builders, `isComponent`,
|
|
4
|
+
* `inferArchetype`, and `projectToJson`. Schema-validation and
|
|
5
|
+
* fixture-equality coverage for real components lives in
|
|
6
|
+
* `./component-schema.test.ts` and `./pilots/pilots.test.ts`; this file
|
|
7
|
+
* covers the authoring API's own behavior in isolation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
import {
|
|
12
|
+
phase,
|
|
13
|
+
gate,
|
|
14
|
+
stackOutput,
|
|
15
|
+
isComponent,
|
|
16
|
+
inferArchetype,
|
|
17
|
+
projectToJson,
|
|
18
|
+
type Component,
|
|
19
|
+
} from "./component";
|
|
20
|
+
|
|
21
|
+
describe("phase()", () => {
|
|
22
|
+
it("builds a Phase with no parallel flag by default", () => {
|
|
23
|
+
expect(phase("Apply", [{ kind: "shell" }])).toEqual({
|
|
24
|
+
phase: "Apply",
|
|
25
|
+
steps: [{ kind: "shell" }],
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("sets parallel: true when requested", () => {
|
|
30
|
+
expect(phase("Verify", [{ kind: "shell" }], { parallel: true })).toEqual({
|
|
31
|
+
phase: "Verify",
|
|
32
|
+
steps: [{ kind: "shell" }],
|
|
33
|
+
parallel: true,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("gate()", () => {
|
|
39
|
+
it("builds a minimal Gate", () => {
|
|
40
|
+
expect(gate("approve-x")).toEqual({ kind: "gate", signalName: "approve-x" });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("carries optional timeout/description", () => {
|
|
44
|
+
expect(gate("approve-x", { timeout: "24h", description: "confirm" })).toEqual({
|
|
45
|
+
kind: "gate",
|
|
46
|
+
signalName: "approve-x",
|
|
47
|
+
timeout: "24h",
|
|
48
|
+
description: "confirm",
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("stackOutput()", () => {
|
|
54
|
+
it("builds a StackOutputReference", () => {
|
|
55
|
+
expect(stackOutput("shared-alb", "ListenerArn")).toEqual({
|
|
56
|
+
stackOutput: { stack: "shared-alb", name: "ListenerArn" },
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("isComponent()", () => {
|
|
62
|
+
it("accepts a minimal valid Component shape", () => {
|
|
63
|
+
expect(isComponent({ name: "x", dependsOn: [], deploy: [] })).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("rejects null/non-objects", () => {
|
|
67
|
+
expect(isComponent(null)).toBe(false);
|
|
68
|
+
expect(isComponent(42)).toBe(false);
|
|
69
|
+
expect(isComponent("x")).toBe(false);
|
|
70
|
+
expect(isComponent(undefined)).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("rejects an object missing dependsOn or deploy", () => {
|
|
74
|
+
expect(isComponent({ name: "x" })).toBe(false);
|
|
75
|
+
expect(isComponent({ name: "x", dependsOn: [] })).toBe(false);
|
|
76
|
+
expect(isComponent({ dependsOn: [], deploy: [] })).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("rejects a plain non-Component object (e.g. a helper/const export)", () => {
|
|
80
|
+
expect(isComponent({ foo: "bar" })).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe("inferArchetype()", () => {
|
|
85
|
+
it("infers infra when there is no build", () => {
|
|
86
|
+
expect(
|
|
87
|
+
inferArchetype({
|
|
88
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
89
|
+
}),
|
|
90
|
+
).toBe("infra");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("infers producer-library when build is present and every step is publish-family", () => {
|
|
94
|
+
expect(
|
|
95
|
+
inferArchetype({
|
|
96
|
+
build: { kind: "jvm-build" },
|
|
97
|
+
deploy: [phase("Publish", [{ kind: "publish-artifact" }])],
|
|
98
|
+
}),
|
|
99
|
+
).toBe("producer-library");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("infers producer-library when the only non-publish steps are gates", () => {
|
|
103
|
+
expect(
|
|
104
|
+
inferArchetype({
|
|
105
|
+
build: { kind: "docker-build" },
|
|
106
|
+
deploy: [phase("Publish", [gate("approve"), { kind: "publish-image" }])],
|
|
107
|
+
}),
|
|
108
|
+
).toBe("producer-library");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("infers service when build is present and an apply/verify step follows publish", () => {
|
|
112
|
+
expect(
|
|
113
|
+
inferArchetype({
|
|
114
|
+
build: { kind: "docker-build" },
|
|
115
|
+
deploy: [
|
|
116
|
+
phase("Publish", [{ kind: "publish-image" }]),
|
|
117
|
+
phase("Apply", [{ kind: "cfn-deploy" }]),
|
|
118
|
+
],
|
|
119
|
+
}),
|
|
120
|
+
).toBe("service");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("infers service for load-image-on-host + a non-publish apply step (single-host compose shape)", () => {
|
|
124
|
+
expect(
|
|
125
|
+
inferArchetype({
|
|
126
|
+
build: { kind: "docker-build" },
|
|
127
|
+
deploy: [
|
|
128
|
+
phase("Publish", [{ kind: "load-image-on-host" }]),
|
|
129
|
+
phase("Apply", [{ kind: "remote-exec" }]),
|
|
130
|
+
],
|
|
131
|
+
}),
|
|
132
|
+
).toBe("service");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("looks inside nested fan-out phases", () => {
|
|
136
|
+
expect(
|
|
137
|
+
inferArchetype({
|
|
138
|
+
build: { kind: "docker-build" },
|
|
139
|
+
deploy: [
|
|
140
|
+
phase("Rolling", [
|
|
141
|
+
phase("Node 1", [{ kind: "publish-image" }]),
|
|
142
|
+
phase("Node 2", [{ kind: "cfn-deploy" }]),
|
|
143
|
+
]),
|
|
144
|
+
],
|
|
145
|
+
}),
|
|
146
|
+
).toBe("service");
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("projectToJson()", () => {
|
|
151
|
+
it("fills in archetype via inferArchetype when the author omits it", () => {
|
|
152
|
+
const component: Component = {
|
|
153
|
+
name: "table",
|
|
154
|
+
dependsOn: [],
|
|
155
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
156
|
+
};
|
|
157
|
+
const projected = projectToJson(component) as { archetype: string };
|
|
158
|
+
expect(projected.archetype).toBe("infra");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("keeps an explicit archetype as authored, even if it disagrees with the inferred shape", () => {
|
|
162
|
+
const component: Component = {
|
|
163
|
+
name: "table",
|
|
164
|
+
archetype: "service",
|
|
165
|
+
dependsOn: [],
|
|
166
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
167
|
+
};
|
|
168
|
+
const projected = projectToJson(component) as { archetype: string };
|
|
169
|
+
expect(projected.archetype).toBe("service");
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("drops undefined optional fields (build/verify/rollback) rather than emitting nulls", () => {
|
|
173
|
+
const component: Component = {
|
|
174
|
+
name: "table",
|
|
175
|
+
dependsOn: [],
|
|
176
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
177
|
+
};
|
|
178
|
+
const projected = projectToJson(component) as Record<string, unknown>;
|
|
179
|
+
expect("build" in projected).toBe(false);
|
|
180
|
+
expect("verify" in projected).toBe(false);
|
|
181
|
+
expect("rollback" in projected).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("projects an explicit liveNames mapping through unchanged (#598)", () => {
|
|
185
|
+
const component: Component = {
|
|
186
|
+
name: "search-svc",
|
|
187
|
+
dependsOn: [],
|
|
188
|
+
liveNames: ["search-service-v2"],
|
|
189
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
190
|
+
};
|
|
191
|
+
const projected = projectToJson(component) as { liveNames?: string[] };
|
|
192
|
+
expect(projected.liveNames).toEqual(["search-service-v2"]);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("omits liveNames from the projection when not authored (#598)", () => {
|
|
196
|
+
const component: Component = {
|
|
197
|
+
name: "table",
|
|
198
|
+
dependsOn: [],
|
|
199
|
+
deploy: [phase("Apply", [{ kind: "cfn-deploy" }])],
|
|
200
|
+
};
|
|
201
|
+
const projected = projectToJson(component) as Record<string, unknown>;
|
|
202
|
+
expect("liveNames" in projected).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("projects a stackOutput() wiring reference to its plain-JSON form", () => {
|
|
206
|
+
const component: Component = {
|
|
207
|
+
name: "svc",
|
|
208
|
+
dependsOn: ["shared-alb"],
|
|
209
|
+
deploy: [
|
|
210
|
+
phase("Apply", [
|
|
211
|
+
{ kind: "cfn-deploy", inputs: { listenerArn: stackOutput("shared-alb", "ListenerArn") } },
|
|
212
|
+
]),
|
|
213
|
+
],
|
|
214
|
+
};
|
|
215
|
+
const projected = projectToJson(component) as {
|
|
216
|
+
deploy: Array<{ steps: Array<{ inputs: Record<string, unknown> }> }>;
|
|
217
|
+
};
|
|
218
|
+
expect(projected.deploy[0]!.steps[0]!.inputs.listenerArn).toEqual({
|
|
219
|
+
stackOutput: { stack: "shared-alb", name: "ListenerArn" },
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("BuildSpec.sbom (#606 — component-level SBOM authoring hint)", () => {
|
|
225
|
+
it("projects an authored sbom hint through unchanged, riding BuildSpec's open additionalProperties shape", () => {
|
|
226
|
+
const component: Component = {
|
|
227
|
+
name: "search-service",
|
|
228
|
+
dependsOn: [],
|
|
229
|
+
build: { kind: "docker-build", context: ".", sbom: { format: "cyclonedx" } },
|
|
230
|
+
deploy: [phase("Publish", [{ kind: "publish-image" }])],
|
|
231
|
+
};
|
|
232
|
+
const projected = projectToJson(component) as { build: { sbom?: { format?: string; optOut?: boolean } } };
|
|
233
|
+
expect(projected.build.sbom).toEqual({ format: "cyclonedx" });
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it("omits sbom from the projection when not authored (no behavior change for existing components)", () => {
|
|
237
|
+
const component: Component = {
|
|
238
|
+
name: "search-service",
|
|
239
|
+
dependsOn: [],
|
|
240
|
+
build: { kind: "docker-build", context: "." },
|
|
241
|
+
deploy: [phase("Publish", [{ kind: "publish-image" }])],
|
|
242
|
+
};
|
|
243
|
+
const projected = projectToJson(component) as { build: Record<string, unknown> };
|
|
244
|
+
expect("sbom" in projected.build).toBe(false);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("supports an explicit opt-out hint", () => {
|
|
248
|
+
const build = { kind: "docker-build", sbom: { optOut: true } };
|
|
249
|
+
expect(build.sbom.optOut).toBe(true);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed `Component` authoring form — Phase 2 (#560, epic #551).
|
|
3
|
+
*
|
|
4
|
+
* This is the real authoring frontend the docs (component-contract.mdx,
|
|
5
|
+
* composition-and-wiring.mdx) describe and that `pilots/authoring-shape.ts`
|
|
6
|
+
* (#555's stopgap) explicitly deferred to this issue. It mirrors
|
|
7
|
+
* `component.schema.json` field-for-field, so `projectToJson` stays a
|
|
8
|
+
* structural no-op — the interesting content lives in each component's
|
|
9
|
+
* composition, not in a bespoke serializer.
|
|
10
|
+
*
|
|
11
|
+
* See https://intentius.io/chant/components/component-contract/ and
|
|
12
|
+
* https://intentius.io/chant/components/composition-and-wiring/.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Mirrors `$defs.Archetype` in component.schema.json. */
|
|
16
|
+
export type Archetype = "service" | "infra" | "producer-library";
|
|
17
|
+
|
|
18
|
+
/** Mirrors `$defs.StackOutputReference`. */
|
|
19
|
+
export interface StackOutputReference {
|
|
20
|
+
stackOutput: { stack: string; name: string };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Mirrors `$defs.WiringValue` — a literal, or one of the reference forms
|
|
25
|
+
* (`$env.*`, `@Phase.field`, `@<component>.publish.uri|digest|key`, or a
|
|
26
|
+
* `{ stackOutput }` object), all resolved by the graph rather than by
|
|
27
|
+
* orchestrator code. Loosened to `string` for the literal/`$env`/prior-step/
|
|
28
|
+
* artifact-reference forms since they share one representation; only
|
|
29
|
+
* `stackOutput` needs its own shape.
|
|
30
|
+
*/
|
|
31
|
+
export type Wiring = string | StackOutputReference;
|
|
32
|
+
|
|
33
|
+
/** Mirrors `$defs.BuildSpec`. */
|
|
34
|
+
export interface BuildSpec {
|
|
35
|
+
/** Build capability verb, keyed by artifact type, e.g. "docker-build", "zip-package", "jvm-build". */
|
|
36
|
+
kind: string;
|
|
37
|
+
/** Build context path (e.g. a Docker build context directory). */
|
|
38
|
+
context?: string;
|
|
39
|
+
/** Build output always lands in the self-contained BuildArchive. */
|
|
40
|
+
into?: "archive";
|
|
41
|
+
/**
|
|
42
|
+
* Optional component-level SBOM authoring hint (#606, epic #551 follow-up
|
|
43
|
+
* to #564/#568) — not itself a `generate-sbom` step (that is composed
|
|
44
|
+
* explicitly in `deploy`/build tooling, see
|
|
45
|
+
* ../verbs/sbom.ts's `GenerateSbomInput`); this is metadata an authoring
|
|
46
|
+
* frontend or generator can read when deciding whether/how to compose
|
|
47
|
+
* that step for this component. Rides `BuildSpec`'s existing
|
|
48
|
+
* `additionalProperties: true` in component.schema.json — no schema change
|
|
49
|
+
* needed for this extension.
|
|
50
|
+
*/
|
|
51
|
+
sbom?: {
|
|
52
|
+
/** Preferred SBOM format for this component, overriding `chant.config.ts`'s project-wide `sbom.format` default (see ../../config.ts's `resolveSbomFormat`). */
|
|
53
|
+
format?: "spdx" | "cyclonedx";
|
|
54
|
+
/** Set true to skip SBOM generation for this component even where a project default would otherwise include it. `generate-sbom` is never invoked implicitly — this only documents intent for whatever composes the component's build phase. */
|
|
55
|
+
optOut?: boolean;
|
|
56
|
+
};
|
|
57
|
+
[extra: string]: unknown;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Mirrors `$defs.Step` — one capability invocation, the leaf unit of a
|
|
62
|
+
* composition. `kind` selects the capability (a verb, e.g. "cfn-deploy",
|
|
63
|
+
* "publish-image", "ecs-update-service"); the remaining properties are that
|
|
64
|
+
* capability's typed input. `kind: "gate"` is reserved for `Gate` below, not
|
|
65
|
+
* a capability — use `gate()` to author one.
|
|
66
|
+
*/
|
|
67
|
+
export interface Step {
|
|
68
|
+
kind: string;
|
|
69
|
+
/** Reference to a published image digest, typically `"@Publish.digest"`. */
|
|
70
|
+
imageRef?: Wiring;
|
|
71
|
+
/** Reference to a published JAR/artifact location, e.g. `"@jar-lib.publish.uri"`. */
|
|
72
|
+
jar?: Wiring;
|
|
73
|
+
/** Reference to a published revision/bundle location for host/code-delivery capabilities. */
|
|
74
|
+
revision?: Wiring;
|
|
75
|
+
/** Named inputs passed into an apply step; each may be a literal or any wiring reference. */
|
|
76
|
+
inputs?: Record<string, Wiring>;
|
|
77
|
+
[param: string]: unknown;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Mirrors `$defs.Gate` — pauses the composition for an external signal (typically human approval). */
|
|
81
|
+
export interface Gate {
|
|
82
|
+
kind: "gate";
|
|
83
|
+
signalName: string;
|
|
84
|
+
/** Duration string bounding the wait, e.g. "48h". Default: "48h". */
|
|
85
|
+
timeout?: string;
|
|
86
|
+
/** Human-readable description of the action required to unblock this gate. */
|
|
87
|
+
description?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Mirrors `$defs.Phase` — one named phase of a deploy composition. A step may
|
|
92
|
+
* itself be a nested `Phase`, which is how a fan-out unit becomes a mini-
|
|
93
|
+
* composition (see composition-and-wiring.mdx).
|
|
94
|
+
*/
|
|
95
|
+
export interface Phase {
|
|
96
|
+
phase: string;
|
|
97
|
+
steps: Array<Step | Gate | Phase>;
|
|
98
|
+
/** Run all steps in this phase concurrently instead of sequentially. */
|
|
99
|
+
parallel?: boolean;
|
|
100
|
+
/** Compensation phases for this phase, executed in reverse order on failure. */
|
|
101
|
+
onFailure?: Phase[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The typed `Component` authoring form — projects 1:1 to the JSON contract
|
|
106
|
+
* (component.schema.json). `archetype` is optional on both sides: when
|
|
107
|
+
* omitted here, `projectToJson` infers it structurally (see
|
|
108
|
+
* `inferArchetype`) so the JSON projection always carries an explicit value,
|
|
109
|
+
* matching how the merged fixtures are authored.
|
|
110
|
+
*/
|
|
111
|
+
export interface Component {
|
|
112
|
+
name: string;
|
|
113
|
+
/** Optional explicit archetype hint; inferred from the composition shape when omitted (see `inferArchetype`). */
|
|
114
|
+
archetype?: Archetype;
|
|
115
|
+
/** Other component names that must complete before this one runs. Ordering only — no logic. */
|
|
116
|
+
dependsOn: string[];
|
|
117
|
+
/** Optional: source -> BuildArchive. Omitted entirely for config-only / infra components. */
|
|
118
|
+
build?: BuildSpec;
|
|
119
|
+
/** The component's own composition over shared capabilities. */
|
|
120
|
+
deploy: Phase[];
|
|
121
|
+
/** Optional standalone verify phases, for components that separate verification from `deploy`. */
|
|
122
|
+
verify?: Phase[];
|
|
123
|
+
/** Optional explicit compensation phases, executed in reverse order on terminal failure of `deploy`. */
|
|
124
|
+
rollback?: Phase[];
|
|
125
|
+
/**
|
|
126
|
+
* Optional: the live lexicon entity/resource name(s) this component owns,
|
|
127
|
+
* when they differ from `name` (#598). `chant components status --live`
|
|
128
|
+
* joins the release ledger against live evidence by name; components and
|
|
129
|
+
* lexicon entities are different namespaces in general (see
|
|
130
|
+
* `../lifecycle/status.ts`), so a component whose deploy composition
|
|
131
|
+
* targets an entity/resource declared under a different name must say so
|
|
132
|
+
* explicitly here. A component that owns several entities (e.g. a fan-out
|
|
133
|
+
* cluster with one stack per node) may list them all — live evidence is
|
|
134
|
+
* aggregated across every name. Omitted entirely (the common case for the
|
|
135
|
+
* pilot components) falls back to `[name]`, preserving the original
|
|
136
|
+
* name == entity join with no behavior change.
|
|
137
|
+
*/
|
|
138
|
+
liveNames?: string[];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Author a named phase. `steps` may mix capability `Step`s, `Gate`s, and nested `Phase`s (fan-out). */
|
|
142
|
+
export function phase(name: string, steps: Array<Step | Gate | Phase>, opts?: { parallel?: boolean }): Phase {
|
|
143
|
+
return { phase: name, steps, ...(opts?.parallel ? { parallel: true } : {}) };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Author a gate step — pauses the composition for an external signal (typically human approval). */
|
|
147
|
+
export function gate(signalName: string, opts?: { timeout?: string; description?: string }): Gate {
|
|
148
|
+
return { kind: "gate", signalName, ...opts };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Author a cross-stack output reference — the TypeScript-side equivalent of
|
|
153
|
+
* the JSON contract's `{ stackOutput: { stack, name } }` (schema
|
|
154
|
+
* `StackOutputReference`), e.g. `stackOutput("shared-alb", "ListenerArn")`.
|
|
155
|
+
* Resolved by `chant graph --stacks`, never by orchestrator code.
|
|
156
|
+
*/
|
|
157
|
+
export function stackOutput(stack: string, name: string): StackOutputReference {
|
|
158
|
+
return { stackOutput: { stack, name } };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Every capability-family marker `inferArchetype` looks for, grouped the same
|
|
163
|
+
* way component-contract.mdx's archetype table groups phases. Kept as a plain
|
|
164
|
+
* list (not the full starter verb set) so this module has no dependency on
|
|
165
|
+
* `./registry`/`./verbs` — inference is a structural, name-based heuristic
|
|
166
|
+
* over the composition, not a capability-registry lookup.
|
|
167
|
+
*/
|
|
168
|
+
const BUILD_ONLY_HINT = new Set(["docker-build", "zip-package", "jvm-build"]);
|
|
169
|
+
const PUBLISH_KIND_PREFIX = /^(publish-|load-image-on-host)/;
|
|
170
|
+
|
|
171
|
+
/** True if a step's `kind` looks like a publish-family capability (`publish-image`, `publish-artifact`, `load-image-on-host`, ...). */
|
|
172
|
+
function isPublishStep(step: Step): boolean {
|
|
173
|
+
return PUBLISH_KIND_PREFIX.test(step.kind);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Distinguishes a nested fan-out `Phase` from a `Step`/`Gate` within a
|
|
178
|
+
* phase's `steps` array. `Step` carries an open index signature
|
|
179
|
+
* (`[param: string]: unknown`), so a plain `"phase" in s` structural check
|
|
180
|
+
* cannot narrow `Step` away from `Phase` — checking the concrete field types
|
|
181
|
+
* (`phase` is a string, `steps` is an array) here is what actually
|
|
182
|
+
* disambiguates them.
|
|
183
|
+
*/
|
|
184
|
+
function isNestedPhase(s: Step | Gate | Phase): s is Phase {
|
|
185
|
+
return typeof (s as Phase).phase === "string" && Array.isArray((s as Phase).steps);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Flatten every step across every phase (including nested fan-out phases) into one list, for structural inspection. */
|
|
189
|
+
function allSteps(phases: Phase[]): Array<Step | Gate> {
|
|
190
|
+
const out: Array<Step | Gate> = [];
|
|
191
|
+
const walk = (ps: Phase[]) => {
|
|
192
|
+
for (const p of ps) {
|
|
193
|
+
for (const s of p.steps) {
|
|
194
|
+
if (isNestedPhase(s)) walk([s]);
|
|
195
|
+
else out.push(s);
|
|
196
|
+
}
|
|
197
|
+
if (p.onFailure) walk(p.onFailure);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
walk(phases);
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Infer a component's archetype from the shape of its composition, when no
|
|
206
|
+
* explicit `archetype` is authored — matching the archetype table in
|
|
207
|
+
* component-contract.mdx:
|
|
208
|
+
* - **producer-library**: has a `build`, and every step across `deploy` is a
|
|
209
|
+
* publish-family step (or a gate) — build -> publish only, no apply.
|
|
210
|
+
* - **service**: has a `build` and at least one non-publish, non-gate step
|
|
211
|
+
* (an apply/verify step) — build -> publish -> apply -> verify.
|
|
212
|
+
* - **infra**: no `build` — apply -> verify only.
|
|
213
|
+
*
|
|
214
|
+
* This is a structural heuristic, not a capability-registry lookup (see
|
|
215
|
+
* `BUILD_ONLY_HINT`/`isPublishStep` above): it only needs to distinguish
|
|
216
|
+
* "nothing but publish" from "something else happens after publish", which
|
|
217
|
+
* every merged pilot/fixture satisfies without consulting the registry.
|
|
218
|
+
*/
|
|
219
|
+
export function inferArchetype(component: Pick<Component, "build" | "deploy">): Archetype {
|
|
220
|
+
if (!component.build) return "infra";
|
|
221
|
+
|
|
222
|
+
const steps = allSteps(component.deploy);
|
|
223
|
+
const nonGateSteps = steps.filter((s): s is Step => s.kind !== "gate");
|
|
224
|
+
const hasNonPublishStep = nonGateSteps.some((s) => !isPublishStep(s));
|
|
225
|
+
|
|
226
|
+
return hasNonPublishStep ? "service" : "producer-library";
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Project a typed `Component` to its plain-JSON contract form
|
|
231
|
+
* (component.schema.json). Field names already match the schema 1:1, so
|
|
232
|
+
* projection is mechanical: a deep `JSON.parse(JSON.stringify())` round-trip
|
|
233
|
+
* (dropping `undefined` optional fields) plus filling in `archetype` via
|
|
234
|
+
* `inferArchetype` when the author didn't supply one explicitly. Kept
|
|
235
|
+
* intentionally dumb beyond that inference — the schema/fixtures stay the
|
|
236
|
+
* source of truth for shape, not this function.
|
|
237
|
+
*/
|
|
238
|
+
export function projectToJson(component: Component): unknown {
|
|
239
|
+
const withArchetype: Component = {
|
|
240
|
+
...component,
|
|
241
|
+
archetype: component.archetype ?? inferArchetype(component),
|
|
242
|
+
};
|
|
243
|
+
return JSON.parse(JSON.stringify(withArchetype));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Runtime type guard: true if `value` looks like a `Component` (has the required `name`/`dependsOn`/`deploy` shape). Used by discovery to pick exported `Component` values out of a `*.component.ts` module without requiring a class/marker symbol. */
|
|
247
|
+
export function isComponent(value: unknown): value is Component {
|
|
248
|
+
if (typeof value !== "object" || value === null) return false;
|
|
249
|
+
const v = value as Record<string, unknown>;
|
|
250
|
+
return (
|
|
251
|
+
typeof v.name === "string" &&
|
|
252
|
+
Array.isArray(v.dependsOn) &&
|
|
253
|
+
Array.isArray(v.deploy)
|
|
254
|
+
);
|
|
255
|
+
}
|