@intentius/chant 0.13.0 → 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/fetch.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/fetch.test.ts +112 -8
- package/src/audit/fetch.ts +53 -8
- 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,111 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
createWaitClusterHealthyCapability,
|
|
4
|
+
createWaitEndpointCapability,
|
|
5
|
+
createHealthGateCapability,
|
|
6
|
+
} from "./wait-verify";
|
|
7
|
+
import { createMockCloudExecutor } from "./__tests__/mock-cloud-executor";
|
|
8
|
+
|
|
9
|
+
describe("wait-cluster-healthy (#557 — Neo4j bolt/quorum probe)", () => {
|
|
10
|
+
it("size mode: resolves once the exact required member count is healthy", async () => {
|
|
11
|
+
const mock = createMockCloudExecutor({ clusters: { "host1:7687": { healthyCount: 1 } } });
|
|
12
|
+
const capability = createWaitClusterHealthyCapability(mock.executor);
|
|
13
|
+
const output = await capability.run(
|
|
14
|
+
{ env: "dev", component: "neo4j-cluster" },
|
|
15
|
+
{ cluster: "host1:7687", size: 1 },
|
|
16
|
+
);
|
|
17
|
+
expect(output.healthyCount).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("quorum mode: resolves once a majority of the cluster list is healthy", async () => {
|
|
21
|
+
const mock = createMockCloudExecutor({
|
|
22
|
+
clusters: { "host1:7687,host2:7687,host3:7687": { healthyCount: 2 } },
|
|
23
|
+
});
|
|
24
|
+
const capability = createWaitClusterHealthyCapability(mock.executor);
|
|
25
|
+
const output = await capability.run(
|
|
26
|
+
{ env: "dev", component: "neo4j-cluster" },
|
|
27
|
+
{ cluster: "host1:7687,host2:7687,host3:7687", quorum: true },
|
|
28
|
+
);
|
|
29
|
+
expect(output.healthyCount).toBe(2);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("quorum mode: does not resolve until a majority (not just >0) is healthy", async () => {
|
|
33
|
+
const mock = createMockCloudExecutor({
|
|
34
|
+
clusters: { "host1:7687,host2:7687,host3:7687": { healthyCount: 1 } },
|
|
35
|
+
});
|
|
36
|
+
const capability = createWaitClusterHealthyCapability(mock.executor);
|
|
37
|
+
await expect(
|
|
38
|
+
capability.run(
|
|
39
|
+
{ env: "dev", component: "neo4j-cluster" },
|
|
40
|
+
{ cluster: "host1:7687,host2:7687,host3:7687", quorum: true, intervalMs: 1, timeoutMs: 5 },
|
|
41
|
+
),
|
|
42
|
+
).rejects.toThrow(/timed out/);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("falls back to ctx.vars.clusterEndpoints when `cluster` is omitted (matches the Neo4j pilot's bare steps)", async () => {
|
|
46
|
+
const mock = createMockCloudExecutor({ clusters: { "az0:7687": { healthyCount: 1 } } });
|
|
47
|
+
const capability = createWaitClusterHealthyCapability(mock.executor);
|
|
48
|
+
const output = await capability.run(
|
|
49
|
+
{ env: "dev", component: "neo4j-cluster", vars: { clusterEndpoints: "az0:7687" } },
|
|
50
|
+
{ size: 1 },
|
|
51
|
+
);
|
|
52
|
+
expect(output.healthyCount).toBe(1);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("declares no rollback — a health probe is read-only", () => {
|
|
56
|
+
const capability = createWaitClusterHealthyCapability(createMockCloudExecutor().executor);
|
|
57
|
+
expect(capability.rollback).toBeUndefined();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const httpCtx = { env: "dev", component: "svc" };
|
|
62
|
+
|
|
63
|
+
describe("wait-endpoint (#557)", () => {
|
|
64
|
+
it("returns the status once the endpoint matches an expected code", async () => {
|
|
65
|
+
let n = 0;
|
|
66
|
+
const cap = createWaitEndpointCapability(async () => (++n < 2 ? { status: 503, ok: false } : { status: 200, ok: true }));
|
|
67
|
+
const out = await cap.run(httpCtx, { url: "http://x/health", intervalMs: 0 });
|
|
68
|
+
expect(out.status).toBe(200);
|
|
69
|
+
expect(n).toBe(2); // retried once before success
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("keeps polling when fetch throws (endpoint not up yet)", async () => {
|
|
73
|
+
let n = 0;
|
|
74
|
+
const cap = createWaitEndpointCapability(async () => {
|
|
75
|
+
if (++n < 2) throw new Error("ECONNREFUSED");
|
|
76
|
+
return { status: 200, ok: true };
|
|
77
|
+
});
|
|
78
|
+
const out = await cap.run(httpCtx, { url: "http://x", intervalMs: 0 });
|
|
79
|
+
expect(out.status).toBe(200);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("times out when the endpoint never matches", async () => {
|
|
83
|
+
const cap = createWaitEndpointCapability(async () => ({ status: 500, ok: false }));
|
|
84
|
+
await expect(cap.run(httpCtx, { url: "http://x", intervalMs: 0, timeoutMs: 0 })).rejects.toThrow("wait-endpoint");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("declares no rollback — a wait is read-only", () => {
|
|
88
|
+
expect(createWaitEndpointCapability().rollback).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("health-gate (#557)", () => {
|
|
93
|
+
it("passes only after the required consecutive successes (a failure resets the streak)", async () => {
|
|
94
|
+
const results = [true, false, true, true];
|
|
95
|
+
let i = 0;
|
|
96
|
+
const cap = createHealthGateCapability(async () => ({ status: 200, ok: results[i++] ?? true }));
|
|
97
|
+
const out = await cap.run(httpCtx, { path: "http://x/healthz", consecutiveSuccesses: 2, intervalMs: 0 });
|
|
98
|
+
expect(out.healthy).toBe(true);
|
|
99
|
+
expect(i).toBe(4); // ok, fail(reset), ok, ok -> two in a row
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("treats a thrown fetch as unhealthy", async () => {
|
|
103
|
+
let i = 0;
|
|
104
|
+
const cap = createHealthGateCapability(async () => {
|
|
105
|
+
if (++i < 2) throw new Error("down");
|
|
106
|
+
return { status: 200, ok: true };
|
|
107
|
+
});
|
|
108
|
+
const out = await cap.run(httpCtx, { path: "http://x", intervalMs: 0 });
|
|
109
|
+
expect(out.healthy).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wait / verify family — poll until a deploy reaches a terminal or healthy
|
|
3
|
+
* state. The *agnostic* members live here: `wait-cluster-healthy` (a Neo4j
|
|
4
|
+
* bolt/quorum probe over the core `CloudExecutor`), and the HTTP waits
|
|
5
|
+
* `wait-endpoint` / `health-gate` (over an injectable `fetch`). The
|
|
6
|
+
* cloud-specific members — `wait-for-stack` (CloudFormation),
|
|
7
|
+
* `wait-steady-state` (ECS), `wait-job` (EMR) — moved to the aws lexicon
|
|
8
|
+
* alongside their executor clients (see docs/components/cloud-boundary).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Capability } from "../capability";
|
|
12
|
+
import { defaultCloudExecutor, sleep, type CloudExecutor } from "./cloud-executor";
|
|
13
|
+
|
|
14
|
+
/** Minimal fetch surface the HTTP waits (`wait-endpoint`, `health-gate`) need — injectable for tests. */
|
|
15
|
+
type Fetcher = (url: string) => Promise<{ status: number; ok: boolean }>;
|
|
16
|
+
const defaultFetcher: Fetcher = (url) => fetch(url);
|
|
17
|
+
|
|
18
|
+
// ── wait-cluster-healthy ─────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
export interface WaitClusterHealthyInput {
|
|
21
|
+
/**
|
|
22
|
+
* Cluster identifier — a comma-separated list of `host:port` bolt
|
|
23
|
+
* endpoints. Optional because a per-instance fan-out phase (e.g. the Neo4j
|
|
24
|
+
* pilot) calls this once per instance without repeating the cluster's
|
|
25
|
+
* member list on every step; when omitted, falls back to
|
|
26
|
+
* `ctx.vars.clusterEndpoints` (env config resolved by the caller) or,
|
|
27
|
+
* failing that, `ctx.component` as a single-endpoint identifier.
|
|
28
|
+
*/
|
|
29
|
+
cluster?: string;
|
|
30
|
+
/** Minimum healthy member count required. */
|
|
31
|
+
size?: number;
|
|
32
|
+
/** Require quorum (majority of expected members healthy) rather than an exact size. Default: false. */
|
|
33
|
+
quorum?: boolean;
|
|
34
|
+
/** Poll interval in ms. Default: 5000. */
|
|
35
|
+
intervalMs?: number;
|
|
36
|
+
/** Overall timeout in ms. Default: 5 minutes. */
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface WaitClusterHealthyOutput {
|
|
41
|
+
/** Number of healthy members observed. */
|
|
42
|
+
healthyCount: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Poll a multi-node cluster (e.g. Neo4j) via a bolt-port TCP probe until it
|
|
47
|
+
* reports healthy: `size` members reachable (exact-count mode, used by a
|
|
48
|
+
* cluster's seed instance) or a majority of the expected member list
|
|
49
|
+
* (`quorum` mode, used once followers exist). No rollback: a health probe is
|
|
50
|
+
* read-only.
|
|
51
|
+
*/
|
|
52
|
+
export function createWaitClusterHealthyCapability(
|
|
53
|
+
executor: CloudExecutor = defaultCloudExecutor(),
|
|
54
|
+
): Capability<WaitClusterHealthyInput, WaitClusterHealthyOutput> {
|
|
55
|
+
return {
|
|
56
|
+
kind: "wait-cluster-healthy",
|
|
57
|
+
async run(ctx, input) {
|
|
58
|
+
const cluster = input.cluster ?? (ctx.vars?.clusterEndpoints as string | undefined) ?? ctx.component;
|
|
59
|
+
const intervalMs = input.intervalMs ?? 5_000;
|
|
60
|
+
const deadline = Date.now() + (input.timeoutMs ?? 5 * 60_000);
|
|
61
|
+
while (true) {
|
|
62
|
+
const { healthyCount, total } = await executor.neo4j.probe({ cluster });
|
|
63
|
+
const required = input.quorum ? Math.floor(total / 2) + 1 : (input.size ?? total);
|
|
64
|
+
if (healthyCount >= required) return { healthyCount };
|
|
65
|
+
if (Date.now() > deadline) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`wait-cluster-healthy "${cluster}" timed out: ${healthyCount}/${total} healthy, needed ${required}`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
await sleep(intervalMs);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Default `wait-cluster-healthy` capability, backed by the real `CloudExecutor`. */
|
|
77
|
+
export const waitClusterHealthyCapability: Capability<WaitClusterHealthyInput, WaitClusterHealthyOutput> =
|
|
78
|
+
createWaitClusterHealthyCapability();
|
|
79
|
+
|
|
80
|
+
// ── wait-endpoint ────────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
export interface WaitEndpointInput {
|
|
83
|
+
/** URL to poll. */
|
|
84
|
+
url: string;
|
|
85
|
+
/** Expected HTTP status codes. Default: [200]. */
|
|
86
|
+
expectStatus?: number[];
|
|
87
|
+
/** Poll interval in ms. Default: 5000. */
|
|
88
|
+
intervalMs?: number;
|
|
89
|
+
/** Overall timeout in ms. */
|
|
90
|
+
timeoutMs?: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface WaitEndpointOutput {
|
|
94
|
+
/** Observed status code on success. */
|
|
95
|
+
status: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Poll an HTTP(S) endpoint until it responds with an expected status. Cloud-agnostic. */
|
|
99
|
+
export function createWaitEndpointCapability(fetcher: Fetcher = defaultFetcher): Capability<WaitEndpointInput, WaitEndpointOutput> {
|
|
100
|
+
return {
|
|
101
|
+
kind: "wait-endpoint",
|
|
102
|
+
async run(_ctx, input) {
|
|
103
|
+
const expect = input.expectStatus ?? [200];
|
|
104
|
+
const intervalMs = input.intervalMs ?? 5_000;
|
|
105
|
+
const timeoutMs = input.timeoutMs ?? 5 * 60_000;
|
|
106
|
+
const deadline = Date.now() + timeoutMs;
|
|
107
|
+
for (;;) {
|
|
108
|
+
try {
|
|
109
|
+
const res = await fetcher(input.url);
|
|
110
|
+
if (expect.includes(res.status)) return { status: res.status };
|
|
111
|
+
} catch {
|
|
112
|
+
// not reachable yet — keep polling until the deadline
|
|
113
|
+
}
|
|
114
|
+
if (Date.now() >= deadline) {
|
|
115
|
+
throw new Error(`wait-endpoint: ${input.url} did not return ${expect.join("/")} within ${timeoutMs}ms`);
|
|
116
|
+
}
|
|
117
|
+
await sleep(intervalMs);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Default `wait-endpoint` capability, backed by the global `fetch`. */
|
|
124
|
+
export const waitEndpointCapability: Capability<WaitEndpointInput, WaitEndpointOutput> = createWaitEndpointCapability();
|
|
125
|
+
|
|
126
|
+
// ── health-gate ──────────────────────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
export interface HealthGateInput {
|
|
129
|
+
/** Health check path or full URL. */
|
|
130
|
+
path: string;
|
|
131
|
+
/** Number of consecutive successes required. Default: 1. */
|
|
132
|
+
consecutiveSuccesses?: number;
|
|
133
|
+
/** Poll interval in ms. Default: 5000. */
|
|
134
|
+
intervalMs?: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface HealthGateOutput {
|
|
138
|
+
/** True once the health check passed the required consecutive count. */
|
|
139
|
+
healthy: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Block progression until a health check passes — the generic post-deploy verification gate. Cloud-agnostic. */
|
|
143
|
+
export function createHealthGateCapability(fetcher: Fetcher = defaultFetcher): Capability<HealthGateInput, HealthGateOutput> {
|
|
144
|
+
return {
|
|
145
|
+
kind: "health-gate",
|
|
146
|
+
async run(_ctx, input) {
|
|
147
|
+
const need = input.consecutiveSuccesses ?? 1;
|
|
148
|
+
const intervalMs = input.intervalMs ?? 5_000;
|
|
149
|
+
// HealthGateInput has no timeout field; cap the wait so a never-healthy target fails rather than hangs.
|
|
150
|
+
const deadline = Date.now() + 5 * 60_000;
|
|
151
|
+
let streak = 0;
|
|
152
|
+
for (;;) {
|
|
153
|
+
let ok = false;
|
|
154
|
+
try {
|
|
155
|
+
ok = (await fetcher(input.path)).ok;
|
|
156
|
+
} catch {
|
|
157
|
+
ok = false;
|
|
158
|
+
}
|
|
159
|
+
streak = ok ? streak + 1 : 0;
|
|
160
|
+
if (streak >= need) return { healthy: true };
|
|
161
|
+
if (Date.now() >= deadline) {
|
|
162
|
+
throw new Error(`health-gate: ${input.path} did not reach ${need} consecutive healthy check(s) within 300000ms`);
|
|
163
|
+
}
|
|
164
|
+
await sleep(intervalMs);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Default `health-gate` capability, backed by the global `fetch`. */
|
|
171
|
+
export const healthGateCapability: Capability<HealthGateInput, HealthGateOutput> = createHealthGateCapability();
|
package/src/config.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { loadChantConfig, DEFAULT_CHANT_CONFIG } from "./config";
|
|
2
|
+
import { loadChantConfig, DEFAULT_CHANT_CONFIG, resolveAutoReleaseDisabled, resolveSbomFormat } from "./config";
|
|
3
3
|
import { writeFileSync, mkdirSync, rmSync } from "fs";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
|
|
@@ -56,6 +56,20 @@ describe("loadChantConfig", () => {
|
|
|
56
56
|
expect(result.configPath).toBe(jsonPath);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
+
// #559, epic #551: `capabilities` mirrors `lexicons` — additional
|
|
60
|
+
// capability plugin package names loaded on top of the built-in starter
|
|
61
|
+
// set (see ./components/capability-plugin-loader.ts's `buildCapabilityRegistry`).
|
|
62
|
+
test("loads chant.config.json with capabilities", async () => {
|
|
63
|
+
const jsonPath = join(TEST_DIR, "chant.config.json");
|
|
64
|
+
writeFileSync(
|
|
65
|
+
jsonPath,
|
|
66
|
+
JSON.stringify({ lexicons: ["aws"], capabilities: ["acme"] }),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const result = await loadChantConfig(TEST_DIR);
|
|
70
|
+
expect(result.config.capabilities).toEqual(["acme"]);
|
|
71
|
+
});
|
|
72
|
+
|
|
59
73
|
test("prefers .ts over .json when both exist", async () => {
|
|
60
74
|
// .ts takes priority — verify by checking configPath ends with .ts
|
|
61
75
|
writeFileSync(
|
|
@@ -88,4 +102,63 @@ describe("loadChantConfig", () => {
|
|
|
88
102
|
expect(result.config.lexicons).toEqual(["testdom"]);
|
|
89
103
|
expect(result.config.lint).toBeUndefined();
|
|
90
104
|
});
|
|
105
|
+
|
|
106
|
+
// #597: release.autoRecord opts out of auto-emitting a release-ledger
|
|
107
|
+
// record from `chant run --components` post-run.
|
|
108
|
+
test("loads chant.config.json with release.autoRecord: false", async () => {
|
|
109
|
+
writeFileSync(
|
|
110
|
+
join(TEST_DIR, "chant.config.json"),
|
|
111
|
+
JSON.stringify({ release: { autoRecord: false } }),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const result = await loadChantConfig(TEST_DIR);
|
|
115
|
+
expect(result.config.release?.autoRecord).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// #606: sbom.format sets the project-wide default SBOM format for every
|
|
119
|
+
// `generate-sbom` step that doesn't specify its own.
|
|
120
|
+
test("loads chant.config.json with sbom.format: cyclonedx", async () => {
|
|
121
|
+
writeFileSync(
|
|
122
|
+
join(TEST_DIR, "chant.config.json"),
|
|
123
|
+
JSON.stringify({ sbom: { format: "cyclonedx" } }),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const result = await loadChantConfig(TEST_DIR);
|
|
127
|
+
expect(result.config.sbom?.format).toBe("cyclonedx");
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe("resolveAutoReleaseDisabled", () => {
|
|
132
|
+
test("default (no flag, no config) → not disabled", () => {
|
|
133
|
+
expect(resolveAutoReleaseDisabled({})).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("the CLI flag disables regardless of config", () => {
|
|
137
|
+
expect(resolveAutoReleaseDisabled({}, true)).toBe(true);
|
|
138
|
+
expect(resolveAutoReleaseDisabled({ release: { autoRecord: true } }, true)).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("release.autoRecord: false disables without the CLI flag", () => {
|
|
142
|
+
expect(resolveAutoReleaseDisabled({ release: { autoRecord: false } })).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("release.autoRecord: true (or unset) does not disable", () => {
|
|
146
|
+
expect(resolveAutoReleaseDisabled({ release: { autoRecord: true } })).toBe(false);
|
|
147
|
+
expect(resolveAutoReleaseDisabled({ release: {} })).toBe(false);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe("resolveSbomFormat (#606)", () => {
|
|
152
|
+
test("defaults to spdx (DEFAULT_SBOM_FORMAT) with no config and no step override", () => {
|
|
153
|
+
expect(resolveSbomFormat({})).toBe("spdx");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("project config sbom.format overrides the built-in default", () => {
|
|
157
|
+
expect(resolveSbomFormat({ sbom: { format: "cyclonedx" } })).toBe("cyclonedx");
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("a step-level format always wins over project config", () => {
|
|
161
|
+
expect(resolveSbomFormat({ sbom: { format: "cyclonedx" } }, "spdx")).toBe("spdx");
|
|
162
|
+
expect(resolveSbomFormat({}, "cyclonedx")).toBe("cyclonedx");
|
|
163
|
+
});
|
|
91
164
|
});
|
package/src/config.ts
CHANGED
|
@@ -3,12 +3,16 @@ import { join } from "path";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import type { LintConfig } from "./lint/config";
|
|
5
5
|
import type { OwnershipMarker } from "./ownership";
|
|
6
|
+
import { DEFAULT_SBOM_FORMAT, type SbomFormat } from "./components/verbs/sbom-generator";
|
|
7
|
+
import type { Severity } from "./components/verbs/vuln-scan";
|
|
8
|
+
import type { VulnPolicy } from "./components/verbs/vuln-gate";
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Zod schema for ChantConfig validation.
|
|
9
12
|
*/
|
|
10
13
|
export const ChantConfigSchema = z.object({
|
|
11
14
|
lexicons: z.array(z.string().min(1)).optional(),
|
|
15
|
+
capabilities: z.array(z.string().min(1)).optional(),
|
|
12
16
|
environments: z.array(z.string().min(1)).optional(),
|
|
13
17
|
sourceDir: z.string().min(1).optional(),
|
|
14
18
|
lint: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -17,6 +21,33 @@ export const ChantConfigSchema = z.object({
|
|
|
17
21
|
env: z.string().min(1).optional(),
|
|
18
22
|
enabled: z.boolean().optional(),
|
|
19
23
|
}).optional(),
|
|
24
|
+
release: z.object({
|
|
25
|
+
autoRecord: z.boolean().optional(),
|
|
26
|
+
}).optional(),
|
|
27
|
+
sbom: z.object({
|
|
28
|
+
format: z.enum(["spdx", "cyclonedx"]).optional(),
|
|
29
|
+
enabled: z.boolean().optional(),
|
|
30
|
+
}).optional(),
|
|
31
|
+
signing: z.object({
|
|
32
|
+
keyless: z.boolean().optional(),
|
|
33
|
+
oidcIssuer: z.string().min(1).optional(),
|
|
34
|
+
identity: z.string().min(1).optional(),
|
|
35
|
+
identityIsRegexp: z.boolean().optional(),
|
|
36
|
+
key: z.string().min(1).optional(),
|
|
37
|
+
}).optional(),
|
|
38
|
+
vulnPolicy: z.object({
|
|
39
|
+
failSeverity: z.enum(["critical", "high", "medium", "low", "negligible", "unknown"]).optional(),
|
|
40
|
+
fixableOnly: z.boolean().optional(),
|
|
41
|
+
warnSeverity: z.enum(["critical", "high", "medium", "low", "negligible", "unknown"]).optional(),
|
|
42
|
+
failOnLicense: z.boolean().optional(),
|
|
43
|
+
failOnUnknownSeverity: z.boolean().optional(),
|
|
44
|
+
license: z.object({
|
|
45
|
+
allow: z.array(z.string()).optional(),
|
|
46
|
+
deny: z.array(z.string()).optional(),
|
|
47
|
+
}).optional(),
|
|
48
|
+
scanner: z.enum(["grype", "trivy"]).optional(),
|
|
49
|
+
vexSources: z.array(z.string()).optional(),
|
|
50
|
+
}).optional(),
|
|
20
51
|
}).passthrough();
|
|
21
52
|
|
|
22
53
|
/**
|
|
@@ -28,6 +59,17 @@ export interface ChantConfig {
|
|
|
28
59
|
/** Lexicon package names to load (e.g. ["aws"]) */
|
|
29
60
|
lexicons?: string[];
|
|
30
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Capability plugin package names to load in addition to the built-in
|
|
64
|
+
* starter set (e.g. ["acme"] loads `@intentius/chant-capability-acme`),
|
|
65
|
+
* mirroring `lexicons` — see {@link CapabilityPlugin} in
|
|
66
|
+
* `./components/capability-plugin.ts` and `buildCapabilityRegistry` in
|
|
67
|
+
* `./components/capability-plugin-loader.ts` (#559, epic #551). The
|
|
68
|
+
* built-in starter verb set (`./components/starter-plugin.ts`) is always
|
|
69
|
+
* loaded regardless of this field.
|
|
70
|
+
*/
|
|
71
|
+
capabilities?: string[];
|
|
72
|
+
|
|
31
73
|
/** Environment names (e.g. ["staging", "prod"]) */
|
|
32
74
|
environments?: string[];
|
|
33
75
|
|
|
@@ -57,6 +99,88 @@ export interface ChantConfig {
|
|
|
57
99
|
/** Set false to disable stamping even when `stack` is present. */
|
|
58
100
|
enabled?: boolean;
|
|
59
101
|
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Release-ledger recording behavior (#597, epic #551). Auto-emitting a
|
|
105
|
+
* release record on a successful `chant run --components <name> --env
|
|
106
|
+
* <env>` deploy is ON by default — this is opt-**out**, not opt-in, per
|
|
107
|
+
* #597's "populate the ledger by construction." See {@link
|
|
108
|
+
* resolveAutoReleaseDisabled}.
|
|
109
|
+
*/
|
|
110
|
+
release?: {
|
|
111
|
+
/** Set false to disable auto-emitting a release record after a successful component deploy project-wide. The `--no-release-record` CLI flag overrides this per-invocation. */
|
|
112
|
+
autoRecord?: boolean;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Project-wide SBOM generation defaults (#606, epic #551 follow-up to
|
|
117
|
+
* #564/#568). Consumed by the `generate-sbom` capability
|
|
118
|
+
* (./components/verbs/sbom.ts) via {@link resolveSbomFormat} — a
|
|
119
|
+
* component's own `build.sbom.format` (see `BuildSpec` in
|
|
120
|
+
* ./components/component.ts) always wins over this project default when
|
|
121
|
+
* set, mirroring how `ownership`/`release` are project-wide defaults a
|
|
122
|
+
* more specific caller can override.
|
|
123
|
+
*/
|
|
124
|
+
sbom?: {
|
|
125
|
+
/** Default SBOM format for every `generate-sbom` step that doesn't specify its own. Defaults to `DEFAULT_SBOM_FORMAT` ("spdx", see ./components/verbs/sbom-generator.ts) when unset — BuildKit natively emits SPDX attestations for images. */
|
|
126
|
+
format?: SbomFormat;
|
|
127
|
+
/** Set false to opt this project out of SBOM generation entirely — components composing a `generate-sbom` step still run it explicitly, but this is the project-wide switch a component author can point to when deciding whether to include the step at all. Purely advisory: `generate-sbom` has no implicit/automatic invocation to suppress (a component's composition always decides), so this flag has no effect unless a component's own authoring code reads it. */
|
|
128
|
+
enabled?: boolean;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Project-wide signing/verification defaults (#622, epic #551 follow-up to
|
|
133
|
+
* #614's reproducibility/provenance material). Consumed by
|
|
134
|
+
* `./components/verbs/sign.ts`'s `sign`/`attest-provenance` capabilities and
|
|
135
|
+
* `./components/verbs/verify.ts`'s `verify` gate via {@link
|
|
136
|
+
* resolveSigningDefaults}. **Keyless is the default** — `keyless: false`
|
|
137
|
+
* plus `key` is the opt-in override for a team with an existing KMS/file
|
|
138
|
+
* key policy (see `./components/verbs/sign.ts`'s module doc for why keyless
|
|
139
|
+
* is never something a beginner has to turn on). `oidcIssuer`/`identity`
|
|
140
|
+
* are the one identity-setup step #622 asks projects to document: the
|
|
141
|
+
* expected signer for `verify`'s identity policy (e.g. GitHub Actions'
|
|
142
|
+
* OIDC issuer + a workflow ref).
|
|
143
|
+
*/
|
|
144
|
+
signing?: {
|
|
145
|
+
/** Set false only alongside `key` to opt into key-based signing instead of the keyless default. Omit (or leave `true`) for the default keyless flow. */
|
|
146
|
+
keyless?: boolean;
|
|
147
|
+
/** Expected OIDC issuer for keyless signing/verification (e.g. `"https://token.actions.githubusercontent.com"` for GitHub Actions). Required for `verify`'s identity policy; optional for `sign`/`attest-provenance`, which can rely on cosign's own ambient OIDC detection in CI. */
|
|
148
|
+
oidcIssuer?: string;
|
|
149
|
+
/** Expected signer identity (e.g. a workflow ref URI) `verify` checks the certificate against. Required for `verify`'s identity policy. */
|
|
150
|
+
identity?: string;
|
|
151
|
+
/** Treat `identity` as a regexp rather than a literal match — see `IdentityPolicy.identityIsRegexp` in `./components/verbs/verify.ts`. */
|
|
152
|
+
identityIsRegexp?: boolean;
|
|
153
|
+
/** Opt-in key-based override (a path, or `kms://`/`awskms://`/... reference) for `sign`/`attest-provenance`/`verify` alike. Presence alone does not disable keyless — pair with `keyless: false` for clarity, though a capability call that explicitly sets its own `key`/`policy.key` always wins over this project default either way. */
|
|
154
|
+
key?: string;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Project-wide vulnerability/license policy-gate defaults (#626, epic #551
|
|
159
|
+
* supply-chain follow-up to the SBOM stack). Consumed by
|
|
160
|
+
* `./components/verbs/vuln-gate.ts`'s `vuln-gate` capability via {@link
|
|
161
|
+
* resolveVulnPolicy}. **Beginner-safe defaults** (see `DEFAULT_VULN_POLICY`
|
|
162
|
+
* in `./components/verbs/vuln-gate.ts`): block only `critical` + `fixable` +
|
|
163
|
+
* not-VEX-suppressed findings, warn on `high`, license report-only. Every
|
|
164
|
+
* field here overrides one of those defaults.
|
|
165
|
+
*/
|
|
166
|
+
vulnPolicy?: {
|
|
167
|
+
/** Minimum severity that FAILS the gate. Default `"critical"`. */
|
|
168
|
+
failSeverity?: Severity;
|
|
169
|
+
/** Only fixable findings at/above `failSeverity` block. Default `true`. */
|
|
170
|
+
fixableOnly?: boolean;
|
|
171
|
+
/** Minimum severity reported as a warning. Default `"high"`. */
|
|
172
|
+
warnSeverity?: Severity;
|
|
173
|
+
/** Block on a license violation (else report-only). Default `false`. */
|
|
174
|
+
failOnLicense?: boolean;
|
|
175
|
+
/** Block on an `unknown`-severity finding (always warned regardless). Default `false`. */
|
|
176
|
+
failOnUnknownSeverity?: boolean;
|
|
177
|
+
/** License allow/deny lists evaluated against the SBOM's declared licenses. */
|
|
178
|
+
license?: { allow?: string[]; deny?: string[] };
|
|
179
|
+
/** Which real scanner a `ProcessRunner`-backed `vuln-gate`/`scan-vulnerabilities` shells out to. Default `"grype"`. Read where the capability/scanner is constructed. */
|
|
180
|
+
scanner?: "grype" | "trivy";
|
|
181
|
+
/** Default VEX document paths (OpenVEX/CycloneDX) applied to every gate. Read where the gate step is composed. */
|
|
182
|
+
vexSources?: string[];
|
|
183
|
+
};
|
|
60
184
|
}
|
|
61
185
|
|
|
62
186
|
/**
|
|
@@ -112,6 +236,101 @@ export function resolveOwnershipMarker(config: ChantConfig): OwnershipMarker | u
|
|
|
112
236
|
return { stack: o.stack, env: o.env };
|
|
113
237
|
}
|
|
114
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Whether auto-emitting a release-ledger record after a successful `chant
|
|
241
|
+
* run --components` deploy should be skipped (#597). Opt-out, not opt-in:
|
|
242
|
+
* recording happens unless the CLI's `--no-release-record` flag was passed
|
|
243
|
+
* (`cliFlag`) or the project config sets `release.autoRecord: false` — the
|
|
244
|
+
* flag always wins for that one invocation, regardless of config.
|
|
245
|
+
*/
|
|
246
|
+
export function resolveAutoReleaseDisabled(config: ChantConfig, cliFlag?: boolean): boolean {
|
|
247
|
+
if (cliFlag) return true;
|
|
248
|
+
return config.release?.autoRecord === false;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Resolve which SBOM format a `generate-sbom` step should request (#606),
|
|
253
|
+
* given the project's `chant.config.ts` `sbom.format` and an optional
|
|
254
|
+
* component/step-level override. Precedence, most to least specific:
|
|
255
|
+
* `stepFormat` (the component's own `build.sbom.format` or an explicit
|
|
256
|
+
* `generate-sbom` step input) > `config.sbom.format` (project default) >
|
|
257
|
+
* `DEFAULT_SBOM_FORMAT` ("spdx", ./components/verbs/sbom-generator.ts).
|
|
258
|
+
* Never hardcodes one format as *the* format — this is purely precedence
|
|
259
|
+
* resolution over the two first-class formats SPDX/CycloneDX.
|
|
260
|
+
*/
|
|
261
|
+
export function resolveSbomFormat(config: ChantConfig, stepFormat?: SbomFormat): SbomFormat {
|
|
262
|
+
return stepFormat ?? config.sbom?.format ?? DEFAULT_SBOM_FORMAT;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Resolved signing defaults a `sign`/`attest-provenance`/`verify` capability
|
|
267
|
+
* call can spread its own `keyless`/`key`/`policy` input over (#622). Shaped
|
|
268
|
+
* to match `./components/verbs/sign.ts`'s `KeyBasedSigningConfig` (the `key`
|
|
269
|
+
* field) and `./components/verbs/verify.ts`'s `IdentityPolicy` (`expectedIssuer`/
|
|
270
|
+
* `expectedIdentity`/`identityIsRegexp`) so a caller can do
|
|
271
|
+
* `{ ...resolveSigningDefaults(config).identityPolicyDefaults, ...override }`
|
|
272
|
+
* without a config module import inside `./components/verbs/*` (no verb
|
|
273
|
+
* module imports `../../config.ts` directly — same convention `resolveSbomFormat`'s
|
|
274
|
+
* callers already follow: the orchestrator/caller resolves config, capabilities
|
|
275
|
+
* stay config-free).
|
|
276
|
+
*/
|
|
277
|
+
export interface ResolvedSigningDefaults {
|
|
278
|
+
/** False only when the project opted into the key-based override (`signing.keyless === false`). True (keyless) otherwise — the #622 default. */
|
|
279
|
+
keyless: boolean;
|
|
280
|
+
/** `./components/verbs/sign.ts`'s `KeyBasedSigningConfig`, present only when key-based signing is configured (`signing.key` set). */
|
|
281
|
+
key?: { key: string };
|
|
282
|
+
/** Partial `./components/verbs/verify.ts` `IdentityPolicy` fields resolved from project config — a caller still supplies any per-call override and must ensure `expectedIssuer`/`expectedIdentity` end up set before calling `verify` (config alone does not guarantee both are present). */
|
|
283
|
+
identityPolicyDefaults: {
|
|
284
|
+
expectedIssuer?: string;
|
|
285
|
+
expectedIdentity?: string;
|
|
286
|
+
identityIsRegexp?: boolean;
|
|
287
|
+
key?: string;
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Resolve project-wide signing defaults from `chant.config.ts`'s `signing`
|
|
293
|
+
* section (#622). Keyless unless `signing.keyless === false` — the same
|
|
294
|
+
* "default is the safe choice, override is explicit" precedence
|
|
295
|
+
* `resolveOwnershipMarker`/`resolveAutoReleaseDisabled` already use for their
|
|
296
|
+
* respective opt-outs.
|
|
297
|
+
*/
|
|
298
|
+
export function resolveSigningDefaults(config: ChantConfig): ResolvedSigningDefaults {
|
|
299
|
+
const s = config.signing;
|
|
300
|
+
const keyless = s?.keyless !== false;
|
|
301
|
+
return {
|
|
302
|
+
keyless,
|
|
303
|
+
...(!keyless && s?.key ? { key: { key: s.key } } : {}),
|
|
304
|
+
identityPolicyDefaults: {
|
|
305
|
+
expectedIssuer: s?.oidcIssuer,
|
|
306
|
+
expectedIdentity: s?.identity,
|
|
307
|
+
identityIsRegexp: s?.identityIsRegexp,
|
|
308
|
+
key: s?.keyless === false ? s?.key : undefined,
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Resolve the `vuln-gate` policy overrides from `chant.config.ts`'s
|
|
315
|
+
* `vulnPolicy` section (#626). Returns only the fields the project set; the
|
|
316
|
+
* gate merges these over its own `DEFAULT_VULN_POLICY`
|
|
317
|
+
* (`./components/verbs/vuln-gate.ts`), so an empty/absent section yields the
|
|
318
|
+
* beginner-safe defaults. `scanner`/`vexSources` are not policy fields — they
|
|
319
|
+
* configure how the capability is constructed and are read separately.
|
|
320
|
+
*/
|
|
321
|
+
export function resolveVulnPolicy(config: ChantConfig): Partial<VulnPolicy> {
|
|
322
|
+
const v = config.vulnPolicy;
|
|
323
|
+
if (!v) return {};
|
|
324
|
+
const out: Partial<VulnPolicy> = {};
|
|
325
|
+
if (v.failSeverity) out.failSeverity = v.failSeverity;
|
|
326
|
+
if (v.fixableOnly !== undefined) out.fixableOnly = v.fixableOnly;
|
|
327
|
+
if (v.warnSeverity) out.warnSeverity = v.warnSeverity;
|
|
328
|
+
if (v.failOnLicense !== undefined) out.failOnLicense = v.failOnLicense;
|
|
329
|
+
if (v.failOnUnknownSeverity !== undefined) out.failOnUnknownSeverity = v.failOnUnknownSeverity;
|
|
330
|
+
if (v.license) out.license = v.license;
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
|
|
115
334
|
/**
|
|
116
335
|
* Validate and normalize a raw config object into ChantConfig shape.
|
|
117
336
|
*/
|
package/src/index.ts
CHANGED
|
@@ -60,6 +60,38 @@ export * from "./codegen/typecheck";
|
|
|
60
60
|
export * from "./codegen/coverage";
|
|
61
61
|
export * from "./codegen/validate";
|
|
62
62
|
export * from "./codegen/docs";
|
|
63
|
+
export * from "./codegen/surface-snapshot";
|
|
64
|
+
export {
|
|
65
|
+
regenLexicon,
|
|
66
|
+
writeSurfaceSnapshot,
|
|
67
|
+
SNAPSHOT_FILENAME,
|
|
68
|
+
type RegenOptions,
|
|
69
|
+
type RegenResult,
|
|
70
|
+
type RegenFailure,
|
|
71
|
+
} from "./codegen/lexicon-regen";
|
|
72
|
+
export {
|
|
73
|
+
checkRollingUpgrade,
|
|
74
|
+
classifyDelta,
|
|
75
|
+
diffRollingSurface,
|
|
76
|
+
computeAzureApiVersionDelta,
|
|
77
|
+
diffAzureApiVersions,
|
|
78
|
+
extractAzureProvider,
|
|
79
|
+
type RollingLexicon,
|
|
80
|
+
type RollingUpgradeResult,
|
|
81
|
+
type CheckRollingUpgradeOptions,
|
|
82
|
+
type AzureApiVersionChange,
|
|
83
|
+
} from "./codegen/rolling-upgrade";
|
|
84
|
+
export {
|
|
85
|
+
checkPinnedUpgrade,
|
|
86
|
+
applyPinnedVersionBump,
|
|
87
|
+
isNewer,
|
|
88
|
+
parseVersion,
|
|
89
|
+
isPreRelease,
|
|
90
|
+
type LexiconId,
|
|
91
|
+
type UpgradeCheckResult,
|
|
92
|
+
type CheckPinnedUpgradeOptions,
|
|
93
|
+
type UpstreamResolver,
|
|
94
|
+
} from "./codegen/pinned-upgrade";
|
|
63
95
|
export * from "./runtime";
|
|
64
96
|
export * from "./runtime-adapter";
|
|
65
97
|
export * from "./resource-attributes";
|