@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,546 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lexicon API surface snapshot and diff.
|
|
3
|
+
*
|
|
4
|
+
* Extracts a stable, serializable representation of a lexicon's public API
|
|
5
|
+
* surface from the generated lexicon JSON. Diffs a fresh snapshot against a
|
|
6
|
+
* committed baseline and classifies each change as additive or breaking.
|
|
7
|
+
*
|
|
8
|
+
* The surface is derived from the lexicon registry JSON that every lexicon's
|
|
9
|
+
* `generate` step writes to `src/generated/<name>.json`. Resource and
|
|
10
|
+
* property-type names, together with their structural metadata (attrs, props,
|
|
11
|
+
* kind), form the baseline. The generated .d.ts is not used for diffing
|
|
12
|
+
* because: (a) it is not self-describing without parsing TypeScript, and
|
|
13
|
+
* (b) the registry JSON already encodes everything a consumer needs.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// ── Surface types ───────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A single entry in the surface snapshot.
|
|
20
|
+
* "resource" entries carry attrs and props; "property" entries are lightweight.
|
|
21
|
+
*/
|
|
22
|
+
export interface SurfaceEntry {
|
|
23
|
+
kind: "resource" | "property";
|
|
24
|
+
/** The cloud-provider resource type string (e.g. "AWS::S3::Bucket"). */
|
|
25
|
+
resourceType: string;
|
|
26
|
+
/** Readonly attribute names (resource entries only). */
|
|
27
|
+
attrs?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Property names with their required flag. Stored as
|
|
30
|
+
* `name:required` strings (e.g. "BucketName:false", "Tags:false").
|
|
31
|
+
* Sorting is stable so the snapshot is deterministic.
|
|
32
|
+
*/
|
|
33
|
+
props?: string[];
|
|
34
|
+
/** Names that are create-only / immutable after creation. */
|
|
35
|
+
createOnly?: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Whether the resource supports tagging.
|
|
38
|
+
* Present when known; absent means not known or not applicable.
|
|
39
|
+
*/
|
|
40
|
+
taggable?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The complete surface snapshot for one lexicon.
|
|
45
|
+
*/
|
|
46
|
+
export interface SurfaceSnapshot {
|
|
47
|
+
/**
|
|
48
|
+
* Schema version for forward-compatibility. Bump when the shape changes
|
|
49
|
+
* in a way that makes old snapshots unreadable by newer tooling.
|
|
50
|
+
*/
|
|
51
|
+
schemaVersion: 1;
|
|
52
|
+
/** When this snapshot was generated (ISO 8601 UTC). */
|
|
53
|
+
generatedAt: string;
|
|
54
|
+
/**
|
|
55
|
+
* Per-entry map keyed by the TS export name (e.g. "Bucket",
|
|
56
|
+
* "Bucket_Tag"). Sorted alphabetically for stable diffs.
|
|
57
|
+
*/
|
|
58
|
+
entries: Record<string, SurfaceEntry>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── Delta types ─────────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
export type ChangeSeverity = "additive" | "breaking" | "none";
|
|
64
|
+
|
|
65
|
+
export interface AddedEntry {
|
|
66
|
+
name: string;
|
|
67
|
+
entry: SurfaceEntry;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface RemovedEntry {
|
|
71
|
+
name: string;
|
|
72
|
+
entry: SurfaceEntry;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface ChangedEntry {
|
|
76
|
+
name: string;
|
|
77
|
+
/** New resourceType (breaking). */
|
|
78
|
+
resourceTypeChanged?: { before: string; after: string };
|
|
79
|
+
/** kind changed from resource to property or vice-versa (breaking). */
|
|
80
|
+
kindChanged?: { before: string; after: string };
|
|
81
|
+
/** Props that were removed (breaking). */
|
|
82
|
+
removedProps?: string[];
|
|
83
|
+
/** Props that switched from optional to required (breaking). */
|
|
84
|
+
nowRequired?: string[];
|
|
85
|
+
/** Attrs that were removed (breaking). */
|
|
86
|
+
removedAttrs?: string[];
|
|
87
|
+
/** Props that were newly added. */
|
|
88
|
+
addedProps?: string[];
|
|
89
|
+
/** Props that switched from required to optional (additive). */
|
|
90
|
+
nowOptional?: string[];
|
|
91
|
+
/** Attrs that were newly added. */
|
|
92
|
+
addedAttrs?: string[];
|
|
93
|
+
/** createOnly set changed. */
|
|
94
|
+
createOnlyChanged?: { before: string[]; after: string[] };
|
|
95
|
+
/** taggable flag changed. */
|
|
96
|
+
taggableChanged?: { before?: boolean; after?: boolean };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface SurfaceDelta {
|
|
100
|
+
added: AddedEntry[];
|
|
101
|
+
changed: ChangedEntry[];
|
|
102
|
+
removed: RemovedEntry[];
|
|
103
|
+
/**
|
|
104
|
+
* Rolled-up severity. "none" means no surface changes at all.
|
|
105
|
+
* "additive" means only new resources / new optional props / new attrs.
|
|
106
|
+
* "breaking" means any removal or change that could break existing consumers.
|
|
107
|
+
*/
|
|
108
|
+
severity: ChangeSeverity;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ── LexiconEntry ── raw shape from lexicon JSON ──────────────────────
|
|
112
|
+
|
|
113
|
+
interface LexiconEntry {
|
|
114
|
+
kind?: "resource" | "property";
|
|
115
|
+
resourceType?: string;
|
|
116
|
+
attrs?: Record<string, string>;
|
|
117
|
+
createOnly?: string[];
|
|
118
|
+
tagging?: { taggable?: boolean };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ── Extraction ───────────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Extract a surface snapshot from the lexicon JSON and the generated index.d.ts.
|
|
125
|
+
*
|
|
126
|
+
* The lexicon JSON contains the resource/property registry (names, kinds,
|
|
127
|
+
* attrs, createOnly, tagging). The .d.ts provides per-prop names and their
|
|
128
|
+
* required flags for resource constructor shapes.
|
|
129
|
+
*
|
|
130
|
+
* @param lexiconJSON Contents of `src/generated/<name>.json`
|
|
131
|
+
* @param typesDTS Contents of `src/generated/index.d.ts`
|
|
132
|
+
*/
|
|
133
|
+
export function extractSurface(lexiconJSON: string, typesDTS: string): SurfaceSnapshot {
|
|
134
|
+
const registry = JSON.parse(lexiconJSON) as Record<string, LexiconEntry>;
|
|
135
|
+
|
|
136
|
+
// Build prop map from .d.ts
|
|
137
|
+
const propsMap = extractPropsFromDts(typesDTS);
|
|
138
|
+
|
|
139
|
+
const entries: Record<string, SurfaceEntry> = {};
|
|
140
|
+
|
|
141
|
+
for (const [name, raw] of Object.entries(registry)) {
|
|
142
|
+
const kind = raw.kind ?? "property";
|
|
143
|
+
const resourceType = raw.resourceType ?? "";
|
|
144
|
+
|
|
145
|
+
const entry: SurfaceEntry = { kind, resourceType };
|
|
146
|
+
|
|
147
|
+
if (kind === "resource") {
|
|
148
|
+
const attrs = raw.attrs ? Object.keys(raw.attrs).sort() : [];
|
|
149
|
+
if (attrs.length > 0) entry.attrs = attrs;
|
|
150
|
+
|
|
151
|
+
// Props from .d.ts
|
|
152
|
+
const props = propsMap.get(name);
|
|
153
|
+
if (props && props.length > 0) entry.props = props;
|
|
154
|
+
|
|
155
|
+
const createOnly = raw.createOnly ? [...raw.createOnly].sort() : [];
|
|
156
|
+
if (createOnly.length > 0) entry.createOnly = createOnly;
|
|
157
|
+
|
|
158
|
+
if (raw.tagging?.taggable !== undefined) {
|
|
159
|
+
entry.taggable = raw.tagging.taggable;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
entries[name] = entry;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Sort keys for stable output
|
|
167
|
+
const sorted: Record<string, SurfaceEntry> = {};
|
|
168
|
+
for (const key of Object.keys(entries).sort()) {
|
|
169
|
+
sorted[key] = entries[key];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
schemaVersion: 1,
|
|
174
|
+
generatedAt: new Date().toISOString(),
|
|
175
|
+
entries: sorted,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Lightweight extractor: pull constructor prop names and required flags
|
|
181
|
+
* from a `.d.ts` string.
|
|
182
|
+
*
|
|
183
|
+
* Handles the pattern generated by writeConstructor:
|
|
184
|
+
* ```
|
|
185
|
+
* export declare class Bucket {
|
|
186
|
+
* constructor(props: {
|
|
187
|
+
* BucketName?: string;
|
|
188
|
+
* Tags: Bucket_Tag[];
|
|
189
|
+
* }, attributes?: CFResourceAttributes);
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* Returns a Map<className, ["PropName:required", ...]>
|
|
194
|
+
* where each entry is sorted alphabetically.
|
|
195
|
+
*/
|
|
196
|
+
export function extractPropsFromDts(dts: string): Map<string, string[]> {
|
|
197
|
+
const map = new Map<string, string[]>();
|
|
198
|
+
const lines = dts.split("\n");
|
|
199
|
+
|
|
200
|
+
let className: string | null = null;
|
|
201
|
+
let inConstructorProps = false;
|
|
202
|
+
let braceDepth = 0;
|
|
203
|
+
const currentProps: string[] = [];
|
|
204
|
+
// Track class-body brace depth separately
|
|
205
|
+
let classBraceDepth = 0;
|
|
206
|
+
|
|
207
|
+
for (const line of lines) {
|
|
208
|
+
const trimmed = line.trim();
|
|
209
|
+
|
|
210
|
+
// Start of a class
|
|
211
|
+
const classMatch = /^export declare class (\w+)/.exec(trimmed);
|
|
212
|
+
if (classMatch) {
|
|
213
|
+
className = classMatch[1];
|
|
214
|
+
inConstructorProps = false;
|
|
215
|
+
braceDepth = 0;
|
|
216
|
+
classBraceDepth = 1; // opening { is on this line
|
|
217
|
+
currentProps.length = 0;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!className) continue;
|
|
222
|
+
|
|
223
|
+
// Track class-body braces when not in constructor props
|
|
224
|
+
if (!inConstructorProps) {
|
|
225
|
+
// End of class block (classBraceDepth back to 0)
|
|
226
|
+
let delta = 0;
|
|
227
|
+
for (const ch of trimmed) {
|
|
228
|
+
if (ch === "{") delta++;
|
|
229
|
+
if (ch === "}") delta--;
|
|
230
|
+
}
|
|
231
|
+
classBraceDepth += delta;
|
|
232
|
+
|
|
233
|
+
if (classBraceDepth <= 0) {
|
|
234
|
+
// Leaving class body — record and reset
|
|
235
|
+
if (currentProps.length > 0) {
|
|
236
|
+
map.set(className, [...currentProps].sort());
|
|
237
|
+
currentProps.length = 0;
|
|
238
|
+
}
|
|
239
|
+
className = null;
|
|
240
|
+
classBraceDepth = 0;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Constructor start
|
|
245
|
+
if (trimmed.startsWith("constructor(props: {")) {
|
|
246
|
+
inConstructorProps = true;
|
|
247
|
+
braceDepth = 1;
|
|
248
|
+
currentProps.length = 0;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
// Constructor with empty props object on one line (no sub-braces needed)
|
|
252
|
+
// constructor(props: Record<string, unknown>) — skip
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Inside constructor props block
|
|
257
|
+
|
|
258
|
+
// Track brace depth
|
|
259
|
+
let delta = 0;
|
|
260
|
+
for (const ch of trimmed) {
|
|
261
|
+
if (ch === "{") delta++;
|
|
262
|
+
if (ch === "}") delta--;
|
|
263
|
+
}
|
|
264
|
+
braceDepth += delta;
|
|
265
|
+
|
|
266
|
+
// End of constructor props block
|
|
267
|
+
if (braceDepth <= 0) {
|
|
268
|
+
inConstructorProps = false;
|
|
269
|
+
braceDepth = 0;
|
|
270
|
+
// Record the props collected so far
|
|
271
|
+
if (!map.has(className) && currentProps.length > 0) {
|
|
272
|
+
map.set(className, [...currentProps].sort());
|
|
273
|
+
currentProps.length = 0;
|
|
274
|
+
}
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Skip comments
|
|
279
|
+
if (trimmed.startsWith("/**") || trimmed.startsWith("*") || trimmed.startsWith("//")) continue;
|
|
280
|
+
|
|
281
|
+
// Match a prop: `PropName?: type;` or `PropName: type;`
|
|
282
|
+
// Prop names may be quoted for non-identifier keys
|
|
283
|
+
const propMatch = /^(?:"([^"]+)"|(\w+))(\??):/.exec(trimmed);
|
|
284
|
+
if (propMatch) {
|
|
285
|
+
const propName = propMatch[1] ?? propMatch[2];
|
|
286
|
+
const optional = propMatch[3] === "?";
|
|
287
|
+
// Encode as "name:required" — "true" means required
|
|
288
|
+
currentProps.push(`${propName}:${!optional}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return map;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ── Diff ─────────────────────────────────────────────────────────────
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Diff a fresh snapshot against a committed baseline.
|
|
299
|
+
*
|
|
300
|
+
* Classification rules:
|
|
301
|
+
* - Added entry → additive
|
|
302
|
+
* - Removed entry → breaking
|
|
303
|
+
* - Changed entry:
|
|
304
|
+
* - resourceType changed → breaking
|
|
305
|
+
* - kind changed → breaking
|
|
306
|
+
* - prop removed → breaking
|
|
307
|
+
* - prop now required (was optional) → breaking
|
|
308
|
+
* - attr removed → breaking
|
|
309
|
+
* - createOnly changed → breaking (changes immutability contract)
|
|
310
|
+
* - taggable: false→undefined or true→false → breaking
|
|
311
|
+
* - prop added (optional) → additive
|
|
312
|
+
* - prop now optional (was required) → additive
|
|
313
|
+
* - attr added → additive
|
|
314
|
+
* - taggable: false→true or undefined→true → additive
|
|
315
|
+
*/
|
|
316
|
+
export function diffSurface(baseline: SurfaceSnapshot, fresh: SurfaceSnapshot): SurfaceDelta {
|
|
317
|
+
const added: AddedEntry[] = [];
|
|
318
|
+
const changed: ChangedEntry[] = [];
|
|
319
|
+
const removed: RemovedEntry[] = [];
|
|
320
|
+
|
|
321
|
+
const baseNames = new Set(Object.keys(baseline.entries));
|
|
322
|
+
const freshNames = new Set(Object.keys(fresh.entries));
|
|
323
|
+
|
|
324
|
+
// Added
|
|
325
|
+
for (const name of freshNames) {
|
|
326
|
+
if (!baseNames.has(name)) {
|
|
327
|
+
added.push({ name, entry: fresh.entries[name] });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Removed
|
|
332
|
+
for (const name of baseNames) {
|
|
333
|
+
if (!freshNames.has(name)) {
|
|
334
|
+
removed.push({ name, entry: baseline.entries[name] });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Changed
|
|
339
|
+
for (const name of baseNames) {
|
|
340
|
+
if (!freshNames.has(name)) continue;
|
|
341
|
+
|
|
342
|
+
const before = baseline.entries[name];
|
|
343
|
+
const after = fresh.entries[name];
|
|
344
|
+
|
|
345
|
+
const change: ChangedEntry = { name };
|
|
346
|
+
let hasChange = false;
|
|
347
|
+
|
|
348
|
+
if (before.resourceType !== after.resourceType) {
|
|
349
|
+
change.resourceTypeChanged = { before: before.resourceType, after: after.resourceType };
|
|
350
|
+
hasChange = true;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (before.kind !== after.kind) {
|
|
354
|
+
change.kindChanged = { before: before.kind, after: after.kind };
|
|
355
|
+
hasChange = true;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Props diff (only meaningful for resource entries)
|
|
359
|
+
const beforeProps = new Map(
|
|
360
|
+
(before.props ?? []).map((p) => {
|
|
361
|
+
const [nm, req] = splitProp(p);
|
|
362
|
+
return [nm, req === "true"];
|
|
363
|
+
}),
|
|
364
|
+
);
|
|
365
|
+
const afterProps = new Map(
|
|
366
|
+
(after.props ?? []).map((p) => {
|
|
367
|
+
const [nm, req] = splitProp(p);
|
|
368
|
+
return [nm, req === "true"];
|
|
369
|
+
}),
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const removedProps = [...beforeProps.keys()].filter((k) => !afterProps.has(k));
|
|
373
|
+
const addedProps = [...afterProps.keys()].filter((k) => !beforeProps.has(k));
|
|
374
|
+
const nowRequired = [...beforeProps.keys()].filter(
|
|
375
|
+
(k) => afterProps.has(k) && !beforeProps.get(k) && afterProps.get(k),
|
|
376
|
+
);
|
|
377
|
+
const nowOptional = [...beforeProps.keys()].filter(
|
|
378
|
+
(k) => afterProps.has(k) && beforeProps.get(k) && !afterProps.get(k),
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
if (removedProps.length > 0) { change.removedProps = removedProps.sort(); hasChange = true; }
|
|
382
|
+
if (addedProps.length > 0) { change.addedProps = addedProps.sort(); hasChange = true; }
|
|
383
|
+
if (nowRequired.length > 0) { change.nowRequired = nowRequired.sort(); hasChange = true; }
|
|
384
|
+
if (nowOptional.length > 0) { change.nowOptional = nowOptional.sort(); hasChange = true; }
|
|
385
|
+
|
|
386
|
+
// Attrs diff
|
|
387
|
+
const beforeAttrs = new Set(before.attrs ?? []);
|
|
388
|
+
const afterAttrs = new Set(after.attrs ?? []);
|
|
389
|
+
const removedAttrs = [...beforeAttrs].filter((a) => !afterAttrs.has(a));
|
|
390
|
+
const addedAttrs = [...afterAttrs].filter((a) => !beforeAttrs.has(a));
|
|
391
|
+
if (removedAttrs.length > 0) { change.removedAttrs = removedAttrs.sort(); hasChange = true; }
|
|
392
|
+
if (addedAttrs.length > 0) { change.addedAttrs = addedAttrs.sort(); hasChange = true; }
|
|
393
|
+
|
|
394
|
+
// createOnly diff
|
|
395
|
+
const beforeCO = JSON.stringify((before.createOnly ?? []).sort());
|
|
396
|
+
const afterCO = JSON.stringify((after.createOnly ?? []).sort());
|
|
397
|
+
if (beforeCO !== afterCO) {
|
|
398
|
+
change.createOnlyChanged = {
|
|
399
|
+
before: before.createOnly ?? [],
|
|
400
|
+
after: after.createOnly ?? [],
|
|
401
|
+
};
|
|
402
|
+
hasChange = true;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// taggable diff
|
|
406
|
+
if (before.taggable !== after.taggable) {
|
|
407
|
+
change.taggableChanged = { before: before.taggable, after: after.taggable };
|
|
408
|
+
hasChange = true;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (hasChange) changed.push(change);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Severity
|
|
415
|
+
let severity: ChangeSeverity = "none";
|
|
416
|
+
|
|
417
|
+
if (added.length > 0) {
|
|
418
|
+
severity = "additive";
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Additive-only changes in the changed[] set
|
|
422
|
+
const hasAdditiveChanges = changed.some((c) =>
|
|
423
|
+
(c.addedProps?.length ?? 0) > 0 ||
|
|
424
|
+
(c.nowOptional?.length ?? 0) > 0 ||
|
|
425
|
+
(c.addedAttrs?.length ?? 0) > 0 ||
|
|
426
|
+
// gaining tagging is additive
|
|
427
|
+
(c.taggableChanged !== undefined && c.taggableChanged.after === true && c.taggableChanged.before !== true),
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
if (hasAdditiveChanges && severity === "none") {
|
|
431
|
+
severity = "additive";
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const hasBreaking =
|
|
435
|
+
removed.length > 0 ||
|
|
436
|
+
changed.some(
|
|
437
|
+
(c) =>
|
|
438
|
+
c.resourceTypeChanged !== undefined ||
|
|
439
|
+
c.kindChanged !== undefined ||
|
|
440
|
+
(c.removedProps?.length ?? 0) > 0 ||
|
|
441
|
+
(c.nowRequired?.length ?? 0) > 0 ||
|
|
442
|
+
(c.removedAttrs?.length ?? 0) > 0 ||
|
|
443
|
+
(c.createOnlyChanged !== undefined) ||
|
|
444
|
+
// losing taggable is breaking
|
|
445
|
+
(c.taggableChanged !== undefined && c.taggableChanged.before === true && c.taggableChanged.after !== true),
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
if (hasBreaking) severity = "breaking";
|
|
449
|
+
|
|
450
|
+
return { added, changed, removed, severity };
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// ── Serialization ────────────────────────────────────────────────────
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Serialize a snapshot to stable JSON. Suitable for writing to
|
|
457
|
+
* `surface.snapshot.json` at the lexicon root.
|
|
458
|
+
*/
|
|
459
|
+
export function serializeSnapshot(snapshot: SurfaceSnapshot): string {
|
|
460
|
+
return JSON.stringify(snapshot, null, 2) + "\n";
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Parse a snapshot from JSON.
|
|
465
|
+
*/
|
|
466
|
+
export function parseSnapshot(json: string): SurfaceSnapshot {
|
|
467
|
+
return JSON.parse(json) as SurfaceSnapshot;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// ── Human-readable output ────────────────────────────────────────────
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Render a surface delta as human-readable text.
|
|
474
|
+
*/
|
|
475
|
+
export function formatDelta(delta: SurfaceDelta): string {
|
|
476
|
+
const lines: string[] = [];
|
|
477
|
+
|
|
478
|
+
if (delta.added.length > 0) {
|
|
479
|
+
lines.push(`Added (${delta.added.length}):`);
|
|
480
|
+
for (const e of delta.added) {
|
|
481
|
+
lines.push(` + ${e.name} [${e.entry.kind}] (${e.entry.resourceType})`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (delta.removed.length > 0) {
|
|
486
|
+
lines.push(`Removed (${delta.removed.length}):`);
|
|
487
|
+
for (const e of delta.removed) {
|
|
488
|
+
lines.push(` - ${e.name} [${e.entry.kind}] (${e.entry.resourceType})`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (delta.changed.length > 0) {
|
|
493
|
+
lines.push(`Changed (${delta.changed.length}):`);
|
|
494
|
+
for (const c of delta.changed) {
|
|
495
|
+
lines.push(` ~ ${c.name}`);
|
|
496
|
+
if (c.resourceTypeChanged) {
|
|
497
|
+
lines.push(` resourceType: ${c.resourceTypeChanged.before} -> ${c.resourceTypeChanged.after}`);
|
|
498
|
+
}
|
|
499
|
+
if (c.kindChanged) {
|
|
500
|
+
lines.push(` kind: ${c.kindChanged.before} -> ${c.kindChanged.after}`);
|
|
501
|
+
}
|
|
502
|
+
if (c.removedProps?.length) {
|
|
503
|
+
lines.push(` removed props: ${c.removedProps.join(", ")}`);
|
|
504
|
+
}
|
|
505
|
+
if (c.nowRequired?.length) {
|
|
506
|
+
lines.push(` now required: ${c.nowRequired.join(", ")}`);
|
|
507
|
+
}
|
|
508
|
+
if (c.addedProps?.length) {
|
|
509
|
+
lines.push(` added props: ${c.addedProps.join(", ")}`);
|
|
510
|
+
}
|
|
511
|
+
if (c.nowOptional?.length) {
|
|
512
|
+
lines.push(` now optional: ${c.nowOptional.join(", ")}`);
|
|
513
|
+
}
|
|
514
|
+
if (c.removedAttrs?.length) {
|
|
515
|
+
lines.push(` removed attrs: ${c.removedAttrs.join(", ")}`);
|
|
516
|
+
}
|
|
517
|
+
if (c.addedAttrs?.length) {
|
|
518
|
+
lines.push(` added attrs: ${c.addedAttrs.join(", ")}`);
|
|
519
|
+
}
|
|
520
|
+
if (c.createOnlyChanged) {
|
|
521
|
+
const before = c.createOnlyChanged.before.join(", ") || "(none)";
|
|
522
|
+
const after = c.createOnlyChanged.after.join(", ") || "(none)";
|
|
523
|
+
lines.push(` createOnly: [${before}] -> [${after}]`);
|
|
524
|
+
}
|
|
525
|
+
if (c.taggableChanged) {
|
|
526
|
+
lines.push(` taggable: ${c.taggableChanged.before ?? "(unset)"} -> ${c.taggableChanged.after ?? "(unset)"}`);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (lines.length === 0) {
|
|
532
|
+
lines.push("No surface changes.");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
lines.push("");
|
|
536
|
+
lines.push(`Severity: ${delta.severity}`);
|
|
537
|
+
|
|
538
|
+
return lines.join("\n");
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
542
|
+
|
|
543
|
+
function splitProp(encoded: string): [string, string] {
|
|
544
|
+
const idx = encoded.lastIndexOf(":");
|
|
545
|
+
return [encoded.slice(0, idx), encoded.slice(idx + 1)];
|
|
546
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
|
+
import { mkdtempSync, writeFileSync, readFileSync, rmSync } from "fs";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { bumpForSeverity, bumpPackageJsonVersion } from "./version-bump";
|
|
6
|
+
|
|
7
|
+
describe("bumpForSeverity", () => {
|
|
8
|
+
test("pre-1.0: additive bumps the patch, breaking bumps the minor (never auto-1.0.0)", () => {
|
|
9
|
+
expect(bumpForSeverity("0.13.1", "additive")).toBe("0.13.2");
|
|
10
|
+
expect(bumpForSeverity("0.13.1", "breaking")).toBe("0.14.0");
|
|
11
|
+
expect(bumpForSeverity("0.0.9", "breaking")).toBe("0.1.0");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test(">= 1.0.0: additive bumps the minor, breaking bumps the major", () => {
|
|
15
|
+
expect(bumpForSeverity("1.2.3", "additive")).toBe("1.3.0");
|
|
16
|
+
expect(bumpForSeverity("1.2.3", "breaking")).toBe("2.0.0");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("tolerates a leading v", () => {
|
|
20
|
+
expect(bumpForSeverity("v0.14.0", "additive")).toBe("0.14.1");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("returns null for none or an unparseable version", () => {
|
|
24
|
+
expect(bumpForSeverity("0.13.1", "none")).toBeNull();
|
|
25
|
+
expect(bumpForSeverity("1.2", "additive")).toBeNull();
|
|
26
|
+
expect(bumpForSeverity("not-a-version", "breaking")).toBeNull();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("bumpPackageJsonVersion", () => {
|
|
31
|
+
test("rewrites only the version, preserving other fields + trailing newline", () => {
|
|
32
|
+
const dir = mkdtempSync(join(tmpdir(), "vbump-"));
|
|
33
|
+
try {
|
|
34
|
+
const pkgPath = join(dir, "package.json");
|
|
35
|
+
writeFileSync(pkgPath, JSON.stringify({ name: "x", version: "0.13.1", scripts: { build: "tsc" } }, null, 2));
|
|
36
|
+
bumpPackageJsonVersion(pkgPath, "0.14.0");
|
|
37
|
+
const raw = readFileSync(pkgPath, "utf-8");
|
|
38
|
+
const pkg = JSON.parse(raw) as { name: string; version: string; scripts: Record<string, string> };
|
|
39
|
+
expect(pkg.version).toBe("0.14.0");
|
|
40
|
+
expect(pkg.name).toBe("x");
|
|
41
|
+
expect(pkg.scripts.build).toBe("tsc");
|
|
42
|
+
expect(raw.endsWith("\n")).toBe(true);
|
|
43
|
+
} finally {
|
|
44
|
+
rmSync(dir, { recursive: true, force: true });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 0.x-aware version bumping, shared by the pinned upgrade Op (#549) and the
|
|
3
|
+
* rolling drift re-baseline (#616). Centralised here so the single source of
|
|
4
|
+
* truth for the semver rule can't drift between the two callers.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
8
|
+
|
|
9
|
+
/** Surface-change severity that drives a bump. */
|
|
10
|
+
export type BumpSeverity = "additive" | "breaking" | "none";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Compute a bumped semver from a current version and a surface severity.
|
|
14
|
+
*
|
|
15
|
+
* Pre-1.0 (major 0) never auto-promotes to 1.0.0: breaking → minor, additive →
|
|
16
|
+
* patch. At >= 1.0.0: breaking → major, additive → minor. Returns null for
|
|
17
|
+
* "none" or a version string that can't be parsed as MAJOR.MINOR.PATCH.
|
|
18
|
+
*/
|
|
19
|
+
export function bumpForSeverity(current: string, severity: BumpSeverity): string | null {
|
|
20
|
+
if (severity === "none") return null;
|
|
21
|
+
const parts = current.replace(/^v/, "").split(".").map(Number);
|
|
22
|
+
if (parts.length < 3 || parts.some((n) => Number.isNaN(n) || n < 0)) return null;
|
|
23
|
+
const [major, minor, patch] = parts as [number, number, number];
|
|
24
|
+
if (major === 0) {
|
|
25
|
+
return severity === "breaking" ? `0.${minor + 1}.0` : `0.${minor}.${patch + 1}`;
|
|
26
|
+
}
|
|
27
|
+
return severity === "breaking" ? `${major + 1}.0.0` : `${major}.${minor + 1}.0`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Read a package.json, set its `version`, and write it back — preserving all
|
|
32
|
+
* other fields, 2-space indent, and a trailing newline.
|
|
33
|
+
*/
|
|
34
|
+
export function bumpPackageJsonVersion(packageJsonPath: string, newVersion: string): void {
|
|
35
|
+
const raw = readFileSync(packageJsonPath, "utf-8");
|
|
36
|
+
const pkg = JSON.parse(raw) as Record<string, unknown>;
|
|
37
|
+
pkg["version"] = newVersion;
|
|
38
|
+
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
39
|
+
}
|