@mannyc1/ts-release 0.0.7 → 0.2.2
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/ARCHITECTURE.md +124 -92
- package/CHANGELOG.md +115 -0
- package/LICENSE +21 -0
- package/README.md +278 -324
- package/SPEC.md +206 -310
- package/apps/release-ts/README.md +32 -0
- package/apps/release-ts/src/cli/command.ts +164 -0
- package/apps/release-ts/src/cli/commands.ts +351 -0
- package/apps/release-ts/src/cli/main.ts +43 -0
- package/apps/release-ts/src/cli/node-main.ts +49 -0
- package/apps/ts-release-agents/LICENSE +21 -0
- package/apps/ts-release-agents/README.md +21 -0
- package/apps/ts-release-agents/evals/cases.json +11 -0
- package/apps/ts-release-agents/manifests/claude.json +5 -0
- package/apps/ts-release-agents/manifests/codex.json +5 -0
- package/apps/ts-release-agents/package.json +11 -0
- package/apps/ts-release-agents/skills/release/SKILL.md +48 -0
- package/apps/ts-release-agents/skills/release/references/configuration.md +18 -0
- package/apps/ts-release-agents/skills/release/references/recovery.md +10 -0
- package/apps/ts-release-agents/skills/release/references/staged-workflow.md +12 -0
- package/apps/ts-release-agents/skills/release/references/target-selection.md +13 -0
- package/apps/ts-release-agents/skills/release/references/verification.md +14 -0
- package/apps/ts-release-agents/src/build.ts +105 -0
- package/apps/ts-release-agents/src/check.ts +117 -0
- package/apps/ts-release-agents/src/install.ts +121 -0
- package/apps/ts-release-agents/test/contract.test.ts +56 -0
- package/apps/ts-release-agents/tsconfig.json +5 -0
- package/dist/api/api.d.ts +15 -0
- package/dist/api/api.d.ts.map +1 -0
- package/dist/api/api.js +244 -0
- package/dist/api/api.js.map +1 -0
- package/dist/api/errors.d.ts +39 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +32 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/input.d.ts +10 -0
- package/dist/api/input.d.ts.map +1 -0
- package/dist/api/input.js +73 -0
- package/dist/api/input.js.map +1 -0
- package/dist/api/runtime.d.ts +18 -0
- package/dist/api/runtime.d.ts.map +1 -0
- package/dist/api/runtime.js +7 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/types.d.ts +76 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +17 -0
- package/dist/api/types.js.map +1 -0
- package/dist/bin/ts-release.js +39239 -0
- package/dist/capabilities/bun-targets.d.ts +3 -0
- package/dist/capabilities/bun-targets.d.ts.map +1 -0
- package/dist/capabilities/bun-targets.js +3 -0
- package/dist/capabilities/bun-targets.js.map +1 -0
- package/dist/capabilities/field-ownership.d.ts +17 -0
- package/dist/capabilities/field-ownership.d.ts.map +1 -0
- package/dist/capabilities/field-ownership.js +40 -0
- package/dist/capabilities/field-ownership.js.map +1 -0
- package/dist/capabilities/module.d.ts +91 -0
- package/dist/capabilities/module.d.ts.map +1 -0
- package/dist/capabilities/module.js +2 -0
- package/dist/capabilities/module.js.map +1 -0
- package/dist/capabilities/registry.d.ts +829 -0
- package/dist/capabilities/registry.d.ts.map +1 -0
- package/dist/capabilities/registry.js +291 -0
- package/dist/capabilities/registry.js.map +1 -0
- package/dist/config/config.d.ts +6 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +42 -0
- package/dist/config/config.js.map +1 -0
- package/dist/correction/coordinator.d.ts +248 -0
- package/dist/correction/coordinator.d.ts.map +1 -0
- package/dist/correction/coordinator.js +274 -0
- package/dist/correction/coordinator.js.map +1 -0
- package/dist/correction/index.d.ts +3 -0
- package/dist/correction/index.d.ts.map +1 -0
- package/dist/correction/index.js +3 -0
- package/dist/correction/index.js.map +1 -0
- package/dist/correction/intent.d.ts +111 -0
- package/dist/correction/intent.d.ts.map +1 -0
- package/dist/correction/intent.js +146 -0
- package/dist/correction/intent.js.map +1 -0
- package/dist/drivers/archive.d.ts +8 -0
- package/dist/drivers/archive.d.ts.map +1 -0
- package/dist/drivers/archive.js +101 -0
- package/dist/drivers/archive.js.map +1 -0
- package/dist/drivers/contain.d.ts +6 -0
- package/dist/drivers/contain.d.ts.map +1 -0
- package/dist/drivers/contain.js +17 -0
- package/dist/drivers/contain.js.map +1 -0
- package/dist/drivers/environment.d.ts +4 -0
- package/dist/drivers/environment.d.ts.map +1 -0
- package/dist/drivers/environment.js +18 -0
- package/dist/drivers/environment.js.map +1 -0
- package/dist/drivers/errors.d.ts +9 -0
- package/dist/drivers/errors.d.ts.map +1 -0
- package/dist/drivers/errors.js +6 -0
- package/dist/drivers/errors.js.map +1 -0
- package/dist/drivers/glob.d.ts +2 -0
- package/dist/drivers/glob.d.ts.map +1 -0
- package/dist/drivers/glob.js +162 -0
- package/dist/drivers/glob.js.map +1 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.d.ts.map +1 -0
- package/dist/drivers/process.js +257 -0
- package/dist/drivers/process.js.map +1 -0
- package/dist/drivers/redact.d.ts +4 -0
- package/dist/drivers/redact.d.ts.map +1 -0
- package/dist/drivers/redact.js +24 -0
- package/dist/drivers/redact.js.map +1 -0
- package/dist/drivers/seccomp-helper-source.d.ts +7 -0
- package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
- package/dist/drivers/seccomp-helper-source.js +121 -0
- package/dist/drivers/seccomp-helper-source.js.map +1 -0
- package/dist/drivers/utils.d.ts +4 -0
- package/dist/drivers/utils.d.ts.map +1 -0
- package/dist/drivers/utils.js +5 -0
- package/dist/drivers/utils.js.map +1 -0
- package/dist/drivers/workspace.d.ts +6 -0
- package/dist/drivers/workspace.d.ts.map +1 -0
- package/dist/drivers/workspace.js +49 -0
- package/dist/drivers/workspace.js.map +1 -0
- package/dist/extensions/provider-adapter.d.ts +48 -0
- package/dist/extensions/provider-adapter.d.ts.map +1 -0
- package/dist/extensions/provider-adapter.js +64 -0
- package/dist/extensions/provider-adapter.js.map +1 -0
- package/dist/host.d.ts +33 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +20 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/model/artifact-collection.d.ts +84 -0
- package/dist/model/artifact-collection.d.ts.map +1 -0
- package/dist/model/artifact-collection.js +185 -0
- package/dist/model/artifact-collection.js.map +1 -0
- package/dist/model/authority.d.ts +89 -0
- package/dist/model/authority.d.ts.map +1 -0
- package/dist/model/authority.js +80 -0
- package/dist/model/authority.js.map +1 -0
- package/dist/model/bun-targets.d.ts +34 -0
- package/dist/model/bun-targets.d.ts.map +1 -0
- package/dist/model/bun-targets.js +17 -0
- package/dist/model/bun-targets.js.map +1 -0
- package/dist/model/canonical.d.ts +8 -0
- package/dist/model/canonical.d.ts.map +1 -0
- package/dist/model/canonical.js +205 -0
- package/dist/model/canonical.js.map +1 -0
- package/dist/model/catalog.d.ts +76 -0
- package/dist/model/catalog.d.ts.map +1 -0
- package/dist/model/catalog.js +174 -0
- package/dist/model/catalog.js.map +1 -0
- package/dist/model/digest.d.ts +53 -0
- package/dist/model/digest.d.ts.map +1 -0
- package/dist/model/digest.js +127 -0
- package/dist/model/digest.js.map +1 -0
- package/dist/model/errors.d.ts +14 -0
- package/dist/model/errors.d.ts.map +1 -0
- package/dist/model/errors.js +8 -0
- package/dist/model/errors.js.map +1 -0
- package/dist/model/primitives.d.ts +19 -0
- package/dist/model/primitives.d.ts.map +1 -0
- package/dist/model/primitives.js +18 -0
- package/dist/model/primitives.js.map +1 -0
- package/dist/model/pypi.d.ts +12 -0
- package/dist/model/pypi.d.ts.map +1 -0
- package/dist/model/pypi.js +20 -0
- package/dist/model/pypi.js.map +1 -0
- package/dist/model/python-distribution.d.ts +33 -0
- package/dist/model/python-distribution.d.ts.map +1 -0
- package/dist/model/python-distribution.js +367 -0
- package/dist/model/python-distribution.js.map +1 -0
- package/dist/model/secret-patterns.d.ts +2 -0
- package/dist/model/secret-patterns.d.ts.map +1 -0
- package/dist/model/secret-patterns.js +12 -0
- package/dist/model/secret-patterns.js.map +1 -0
- package/dist/platform/bun.d.ts +7 -0
- package/dist/platform/bun.d.ts.map +1 -0
- package/dist/platform/bun.js +15 -0
- package/dist/platform/bun.js.map +1 -0
- package/dist/platform/credentials.d.ts +32 -0
- package/dist/platform/credentials.d.ts.map +1 -0
- package/dist/platform/credentials.js +772 -0
- package/dist/platform/credentials.js.map +1 -0
- package/dist/platform/host-support.d.ts +2 -0
- package/dist/platform/host-support.d.ts.map +1 -0
- package/dist/platform/host-support.js +4 -0
- package/dist/platform/host-support.js.map +1 -0
- package/dist/platform/node.d.ts +7 -0
- package/dist/platform/node.d.ts.map +1 -0
- package/dist/platform/node.js +15 -0
- package/dist/platform/node.js.map +1 -0
- package/dist/platform/release-runtime.d.ts +11 -0
- package/dist/platform/release-runtime.d.ts.map +1 -0
- package/dist/platform/release-runtime.js +34 -0
- package/dist/platform/release-runtime.js.map +1 -0
- package/dist/platform/services.d.ts +15 -0
- package/dist/platform/services.d.ts.map +1 -0
- package/dist/platform/services.js +30 -0
- package/dist/platform/services.js.map +1 -0
- package/dist/platform/source-observer.d.ts +5 -0
- package/dist/platform/source-observer.d.ts.map +1 -0
- package/dist/platform/source-observer.js +159 -0
- package/dist/platform/source-observer.js.map +1 -0
- package/dist/provider-sdk.d.ts +14 -0
- package/dist/provider-sdk.d.ts.map +1 -0
- package/dist/provider-sdk.js +10 -0
- package/dist/provider-sdk.js.map +1 -0
- package/dist/publication/adapter.d.ts +212 -0
- package/dist/publication/adapter.d.ts.map +1 -0
- package/dist/publication/adapter.js +83 -0
- package/dist/publication/adapter.js.map +1 -0
- package/dist/publication/authority.d.ts +137 -0
- package/dist/publication/authority.d.ts.map +1 -0
- package/dist/publication/authority.js +233 -0
- package/dist/publication/authority.js.map +1 -0
- package/dist/publication/catalog-git.d.ts +37 -0
- package/dist/publication/catalog-git.d.ts.map +1 -0
- package/dist/publication/catalog-git.js +451 -0
- package/dist/publication/catalog-git.js.map +1 -0
- package/dist/publication/claim.d.ts +39 -0
- package/dist/publication/claim.d.ts.map +1 -0
- package/dist/publication/claim.js +31 -0
- package/dist/publication/claim.js.map +1 -0
- package/dist/publication/coordinator.d.ts +246 -0
- package/dist/publication/coordinator.d.ts.map +1 -0
- package/dist/publication/coordinator.js +370 -0
- package/dist/publication/coordinator.js.map +1 -0
- package/dist/publication/github.d.ts +36 -0
- package/dist/publication/github.d.ts.map +1 -0
- package/dist/publication/github.js +644 -0
- package/dist/publication/github.js.map +1 -0
- package/dist/publication/http.d.ts +69 -0
- package/dist/publication/http.d.ts.map +1 -0
- package/dist/publication/http.js +29 -0
- package/dist/publication/http.js.map +1 -0
- package/dist/publication/index.d.ts +5 -0
- package/dist/publication/index.d.ts.map +1 -0
- package/dist/publication/index.js +5 -0
- package/dist/publication/index.js.map +1 -0
- package/dist/publication/npm.d.ts +40 -0
- package/dist/publication/npm.d.ts.map +1 -0
- package/dist/publication/npm.js +359 -0
- package/dist/publication/npm.js.map +1 -0
- package/dist/publication/profiles.d.ts +136 -0
- package/dist/publication/profiles.d.ts.map +1 -0
- package/dist/publication/profiles.js +90 -0
- package/dist/publication/profiles.js.map +1 -0
- package/dist/publication/publisher.d.ts +82 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/publisher.js +53 -0
- package/dist/publication/publisher.js.map +1 -0
- package/dist/publication/pypi.d.ts +45 -0
- package/dist/publication/pypi.d.ts.map +1 -0
- package/dist/publication/pypi.js +369 -0
- package/dist/publication/pypi.js.map +1 -0
- package/dist/publication/recovery.d.ts +663 -0
- package/dist/publication/recovery.d.ts.map +1 -0
- package/dist/publication/recovery.js +252 -0
- package/dist/publication/recovery.js.map +1 -0
- package/dist/publication/report.d.ts +1061 -0
- package/dist/publication/report.d.ts.map +1 -0
- package/dist/publication/report.js +441 -0
- package/dist/publication/report.js.map +1 -0
- package/dist/recipes/config.d.ts +296 -0
- package/dist/recipes/config.d.ts.map +1 -0
- package/dist/recipes/config.js +325 -0
- package/dist/recipes/config.js.map +1 -0
- package/dist/release/capabilities.d.ts +12 -0
- package/dist/release/capabilities.d.ts.map +1 -0
- package/dist/release/capabilities.js +395 -0
- package/dist/release/capabilities.js.map +1 -0
- package/dist/release/compiler.d.ts +5 -0
- package/dist/release/compiler.d.ts.map +1 -0
- package/dist/release/compiler.js +19 -0
- package/dist/release/compiler.js.map +1 -0
- package/dist/release/config.d.ts +5 -0
- package/dist/release/config.d.ts.map +1 -0
- package/dist/release/config.js +10 -0
- package/dist/release/config.js.map +1 -0
- package/dist/release/context.d.ts +96 -0
- package/dist/release/context.d.ts.map +1 -0
- package/dist/release/context.js +168 -0
- package/dist/release/context.js.map +1 -0
- package/dist/release/graph.d.ts +271 -0
- package/dist/release/graph.d.ts.map +1 -0
- package/dist/release/graph.js +766 -0
- package/dist/release/graph.js.map +1 -0
- package/dist/release/inspect.d.ts +88 -0
- package/dist/release/inspect.d.ts.map +1 -0
- package/dist/release/inspect.js +75 -0
- package/dist/release/inspect.js.map +1 -0
- package/dist/release/prepare.d.ts +24 -0
- package/dist/release/prepare.d.ts.map +1 -0
- package/dist/release/prepare.js +1116 -0
- package/dist/release/prepare.js.map +1 -0
- package/dist/release/prepared-ref.d.ts +60 -0
- package/dist/release/prepared-ref.d.ts.map +1 -0
- package/dist/release/prepared-ref.js +131 -0
- package/dist/release/prepared-ref.js.map +1 -0
- package/dist/release/prepared-store.d.ts +90 -0
- package/dist/release/prepared-store.d.ts.map +1 -0
- package/dist/release/prepared-store.js +337 -0
- package/dist/release/prepared-store.js.map +1 -0
- package/dist/release/prepared.d.ts +172 -0
- package/dist/release/prepared.d.ts.map +1 -0
- package/dist/release/prepared.js +268 -0
- package/dist/release/prepared.js.map +1 -0
- package/dist/release/staging.d.ts +31 -0
- package/dist/release/staging.d.ts.map +1 -0
- package/dist/release/staging.js +218 -0
- package/dist/release/staging.js.map +1 -0
- package/dist/resolve/authored.d.ts +53 -0
- package/dist/resolve/authored.d.ts.map +1 -0
- package/dist/resolve/authored.js +55 -0
- package/dist/resolve/authored.js.map +1 -0
- package/dist/resolve/encode.d.ts +3 -0
- package/dist/resolve/encode.d.ts.map +1 -0
- package/dist/resolve/encode.js +21 -0
- package/dist/resolve/encode.js.map +1 -0
- package/dist/resolve/errors.d.ts +7 -0
- package/dist/resolve/errors.d.ts.map +1 -0
- package/dist/resolve/errors.js +17 -0
- package/dist/resolve/errors.js.map +1 -0
- package/dist/resolve/facts.d.ts +12 -0
- package/dist/resolve/facts.d.ts.map +1 -0
- package/dist/resolve/facts.js +18 -0
- package/dist/resolve/facts.js.map +1 -0
- package/dist/resolve/resolve.d.ts +10 -0
- package/dist/resolve/resolve.d.ts.map +1 -0
- package/dist/resolve/resolve.js +242 -0
- package/dist/resolve/resolve.js.map +1 -0
- package/dist/store.d.ts +11 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +9 -0
- package/dist/store.js.map +1 -0
- package/examples/README.md +20 -30
- package/examples/github-release/release.config.json +11 -18
- package/examples/homebrew-tap/README.md +11 -0
- package/examples/homebrew-tap/release.config.json +40 -28
- package/examples/multi-target/release.config.json +28 -53
- package/examples/npm-first-publish/release.config.json +23 -25
- package/examples/npm-only/release.config.json +22 -30
- package/examples/portable-cli/README.md +17 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
- package/examples/portable-cli/package.json +9 -0
- package/examples/portable-cli/release.config.json +53 -0
- package/examples/portable-cli/src/cli.ts +3 -0
- package/examples/pypi-registry/README.md +8 -0
- package/examples/scoop-bucket/README.md +10 -0
- package/examples/scoop-bucket/release.config.json +40 -30
- package/package.json +60 -156
- package/src/api/api.ts +365 -0
- package/src/api/errors.ts +36 -0
- package/src/api/input.ts +92 -0
- package/src/api/runtime.ts +14 -0
- package/src/api/types.ts +103 -0
- package/src/capabilities/bun-targets.ts +2 -0
- package/src/capabilities/field-ownership.ts +60 -0
- package/src/capabilities/module.ts +158 -0
- package/src/capabilities/registry.ts +333 -0
- package/src/config/config.ts +48 -0
- package/src/correction/coordinator.ts +336 -0
- package/src/correction/index.ts +2 -0
- package/src/correction/intent.ts +172 -0
- package/src/drivers/archive.ts +102 -0
- package/src/drivers/contain.ts +20 -0
- package/src/drivers/environment.ts +28 -0
- package/src/drivers/errors.ts +6 -0
- package/src/drivers/glob.ts +137 -0
- package/src/drivers/process.ts +340 -0
- package/src/drivers/redact.ts +31 -0
- package/src/drivers/seccomp-helper-source.ts +121 -0
- package/src/drivers/utils.ts +10 -0
- package/src/drivers/workspace.ts +40 -0
- package/src/extensions/provider-adapter.ts +99 -0
- package/src/host.ts +140 -0
- package/src/index.ts +64 -0
- package/src/model/artifact-collection.ts +237 -0
- package/src/model/authority.ts +116 -0
- package/src/model/bun-targets.ts +34 -0
- package/src/model/canonical.ts +205 -0
- package/src/model/catalog.ts +220 -0
- package/src/model/digest.ts +172 -0
- package/src/model/errors.ts +6 -0
- package/src/model/primitives.ts +37 -0
- package/src/model/pypi.ts +30 -0
- package/src/model/python-distribution.ts +360 -0
- package/src/model/secret-patterns.ts +11 -0
- package/src/platform/bun.ts +38 -0
- package/src/platform/credentials.ts +1083 -0
- package/src/platform/host-support.ts +4 -0
- package/src/platform/node.ts +38 -0
- package/src/platform/release-runtime.ts +47 -0
- package/src/platform/services.ts +57 -0
- package/src/platform/source-observer.ts +193 -0
- package/src/provider-sdk.ts +48 -0
- package/src/publication/adapter.ts +132 -0
- package/src/publication/authority.ts +397 -0
- package/src/publication/catalog-git.ts +603 -0
- package/src/publication/claim.ts +51 -0
- package/src/publication/coordinator.ts +578 -0
- package/src/publication/github.ts +954 -0
- package/src/publication/http.ts +101 -0
- package/src/publication/index.ts +4 -0
- package/src/publication/npm.ts +525 -0
- package/src/publication/profiles.ts +94 -0
- package/src/publication/publisher.ts +130 -0
- package/src/publication/pypi.ts +463 -0
- package/src/publication/recovery.ts +349 -0
- package/src/publication/report.ts +628 -0
- package/src/recipes/config.ts +395 -0
- package/src/release/capabilities.ts +459 -0
- package/src/release/compiler.ts +28 -0
- package/src/release/config.ts +12 -0
- package/src/release/context.ts +223 -0
- package/src/release/graph.ts +866 -0
- package/src/release/inspect.ts +83 -0
- package/src/release/prepare.ts +1331 -0
- package/src/release/prepared-ref.ts +193 -0
- package/src/release/prepared-store.ts +377 -0
- package/src/release/prepared.ts +299 -0
- package/src/release/staging.ts +257 -0
- package/src/resolve/authored.ts +64 -0
- package/src/resolve/encode.ts +22 -0
- package/src/resolve/errors.ts +15 -0
- package/src/resolve/facts.ts +18 -0
- package/src/resolve/resolve.ts +328 -0
- package/src/store.ts +28 -0
- package/templates/README.md +55 -72
- package/templates/bun-cli-github/README.md +7 -9
- package/templates/bun-cli-github/release.config.json +35 -73
- package/templates/github-actions/release.yml +57 -0
- package/templates/github-actions/reviewed-release.yml +80 -0
- package/templates/multi-target-homebrew/README.md +10 -0
- package/templates/multi-target-homebrew/release.config.json +43 -60
- package/templates/multi-target-scoop/README.md +10 -0
- package/templates/multi-target-scoop/release.config.json +43 -62
- package/templates/npm-github/release.config.json +25 -38
- package/templates/npm-github/reviewed-release.config.json +37 -0
- package/templates/npm-only/README.md +10 -0
- package/templates/npm-only/release.config.json +15 -30
- package/templates/portable-cli/README.md +13 -0
- package/templates/portable-cli/release.config.json +53 -0
- package/dist/artifacts/adapter.d.ts +0 -39
- package/dist/artifacts/adapter.d.ts.map +0 -1
- package/dist/artifacts/adapter.js +0 -23
- package/dist/artifacts/adapter.js.map +0 -1
- package/dist/artifacts/registry.d.ts +0 -21
- package/dist/artifacts/registry.d.ts.map +0 -1
- package/dist/artifacts/registry.js +0 -21
- package/dist/artifacts/registry.js.map +0 -1
- package/dist/config/errors.d.ts +0 -24
- package/dist/config/errors.d.ts.map +0 -1
- package/dist/config/errors.js +0 -19
- package/dist/config/errors.js.map +0 -1
- package/dist/config/load.d.ts +0 -9
- package/dist/config/load.d.ts.map +0 -1
- package/dist/config/load.js +0 -29
- package/dist/config/load.js.map +0 -1
- package/dist/config/schema.d.ts +0 -12
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/config/schema.js +0 -19
- package/dist/config/schema.js.map +0 -1
- package/dist/domain/artifact.d.ts +0 -118
- package/dist/domain/artifact.d.ts.map +0 -1
- package/dist/domain/artifact.js +0 -197
- package/dist/domain/artifact.js.map +0 -1
- package/dist/domain/evidence.d.ts +0 -59
- package/dist/domain/evidence.d.ts.map +0 -1
- package/dist/domain/evidence.js +0 -51
- package/dist/domain/evidence.js.map +0 -1
- package/dist/domain/operation.d.ts +0 -143
- package/dist/domain/operation.d.ts.map +0 -1
- package/dist/domain/operation.js +0 -198
- package/dist/domain/operation.js.map +0 -1
- package/dist/domain/release.d.ts +0 -93
- package/dist/domain/release.d.ts.map +0 -1
- package/dist/domain/release.js +0 -82
- package/dist/domain/release.js.map +0 -1
- package/dist/domain/remote-state.d.ts +0 -58
- package/dist/domain/remote-state.d.ts.map +0 -1
- package/dist/domain/remote-state.js +0 -55
- package/dist/domain/remote-state.js.map +0 -1
- package/dist/domain/target.d.ts +0 -148
- package/dist/domain/target.d.ts.map +0 -1
- package/dist/domain/target.js +0 -151
- package/dist/domain/target.js.map +0 -1
- package/dist/host/host.d.ts +0 -32
- package/dist/host/host.d.ts.map +0 -1
- package/dist/host/host.js +0 -24
- package/dist/host/host.js.map +0 -1
- package/dist/host/http-live.d.ts +0 -6
- package/dist/host/http-live.d.ts.map +0 -1
- package/dist/host/http-live.js +0 -86
- package/dist/host/http-live.js.map +0 -1
- package/dist/host/http.d.ts +0 -43
- package/dist/host/http.d.ts.map +0 -1
- package/dist/host/http.js +0 -59
- package/dist/host/http.js.map +0 -1
- package/dist/host/platform.d.ts +0 -10
- package/dist/host/platform.d.ts.map +0 -1
- package/dist/host/platform.js +0 -114
- package/dist/host/platform.js.map +0 -1
- package/dist/host/test.d.ts +0 -23
- package/dist/host/test.d.ts.map +0 -1
- package/dist/host/test.js +0 -222
- package/dist/host/test.js.map +0 -1
- package/dist/internal/workspace-path.d.ts +0 -15
- package/dist/internal/workspace-path.d.ts.map +0 -1
- package/dist/internal/workspace-path.js +0 -36
- package/dist/internal/workspace-path.js.map +0 -1
- package/dist/planner/artifact-inventory.d.ts +0 -9
- package/dist/planner/artifact-inventory.d.ts.map +0 -1
- package/dist/planner/artifact-inventory.js +0 -86
- package/dist/planner/artifact-inventory.js.map +0 -1
- package/dist/planner/create-release-plan.d.ts +0 -5
- package/dist/planner/create-release-plan.d.ts.map +0 -1
- package/dist/planner/create-release-plan.js +0 -25
- package/dist/planner/create-release-plan.js.map +0 -1
- package/dist/planner/errors.d.ts +0 -67
- package/dist/planner/errors.d.ts.map +0 -1
- package/dist/planner/errors.js +0 -58
- package/dist/planner/errors.js.map +0 -1
- package/dist/planner/evidence-recorder.d.ts +0 -28
- package/dist/planner/evidence-recorder.d.ts.map +0 -1
- package/dist/planner/evidence-recorder.js +0 -362
- package/dist/planner/evidence-recorder.js.map +0 -1
- package/dist/planner/executor.d.ts +0 -58
- package/dist/planner/executor.d.ts.map +0 -1
- package/dist/planner/executor.js +0 -147
- package/dist/planner/executor.js.map +0 -1
- package/dist/planner/normalize-release.d.ts +0 -19
- package/dist/planner/normalize-release.d.ts.map +0 -1
- package/dist/planner/normalize-release.js +0 -342
- package/dist/planner/normalize-release.js.map +0 -1
- package/dist/planner/reconcile.d.ts +0 -17
- package/dist/planner/reconcile.d.ts.map +0 -1
- package/dist/planner/reconcile.js +0 -259
- package/dist/planner/reconcile.js.map +0 -1
- package/dist/planner/render-plan.d.ts +0 -15
- package/dist/planner/render-plan.d.ts.map +0 -1
- package/dist/planner/render-plan.js +0 -231
- package/dist/planner/render-plan.js.map +0 -1
- package/dist/targets/adapter-helpers.d.ts +0 -79
- package/dist/targets/adapter-helpers.d.ts.map +0 -1
- package/dist/targets/adapter-helpers.js +0 -194
- package/dist/targets/adapter-helpers.js.map +0 -1
- package/dist/targets/adapter.d.ts +0 -17
- package/dist/targets/adapter.d.ts.map +0 -1
- package/dist/targets/adapter.js +0 -2
- package/dist/targets/adapter.js.map +0 -1
- package/dist/targets/github-release.d.ts +0 -25
- package/dist/targets/github-release.d.ts.map +0 -1
- package/dist/targets/github-release.js +0 -82
- package/dist/targets/github-release.js.map +0 -1
- package/dist/targets/github.d.ts +0 -11
- package/dist/targets/github.d.ts.map +0 -1
- package/dist/targets/github.js +0 -117
- package/dist/targets/github.js.map +0 -1
- package/dist/targets/homebrew.d.ts +0 -11
- package/dist/targets/homebrew.d.ts.map +0 -1
- package/dist/targets/homebrew.js +0 -210
- package/dist/targets/homebrew.js.map +0 -1
- package/dist/targets/live.d.ts +0 -5
- package/dist/targets/live.d.ts.map +0 -1
- package/dist/targets/live.js +0 -50
- package/dist/targets/live.js.map +0 -1
- package/dist/targets/npm.d.ts +0 -10
- package/dist/targets/npm.d.ts.map +0 -1
- package/dist/targets/npm.js +0 -112
- package/dist/targets/npm.js.map +0 -1
- package/dist/targets/pypi.d.ts +0 -11
- package/dist/targets/pypi.d.ts.map +0 -1
- package/dist/targets/pypi.js +0 -141
- package/dist/targets/pypi.js.map +0 -1
- package/dist/targets/registry.d.ts +0 -25
- package/dist/targets/registry.d.ts.map +0 -1
- package/dist/targets/registry.js +0 -34
- package/dist/targets/registry.js.map +0 -1
- package/dist/targets/scoop.d.ts +0 -11
- package/dist/targets/scoop.d.ts.map +0 -1
- package/dist/targets/scoop.js +0 -88
- package/dist/targets/scoop.js.map +0 -1
- package/dist/types/effect-internal.d.ts +0 -5
- package/dist/types/effect-internal.d.ts.map +0 -1
- package/dist/types/effect-internal.js +0 -2
- package/dist/types/effect-internal.js.map +0 -1
- package/dist/workflows/config.d.ts +0 -202
- package/dist/workflows/config.d.ts.map +0 -1
- package/dist/workflows/config.js +0 -420
- package/dist/workflows/config.js.map +0 -1
- package/dist/workflows/diagnostics.d.ts +0 -62
- package/dist/workflows/diagnostics.d.ts.map +0 -1
- package/dist/workflows/diagnostics.js +0 -530
- package/dist/workflows/diagnostics.js.map +0 -1
- package/dist/workflows/distribution.d.ts +0 -25
- package/dist/workflows/distribution.d.ts.map +0 -1
- package/dist/workflows/distribution.js +0 -24
- package/dist/workflows/distribution.js.map +0 -1
- package/dist/workflows/evidence.d.ts +0 -17
- package/dist/workflows/evidence.d.ts.map +0 -1
- package/dist/workflows/evidence.js +0 -32
- package/dist/workflows/evidence.js.map +0 -1
- package/dist/workflows/index.d.ts +0 -8
- package/dist/workflows/index.d.ts.map +0 -1
- package/dist/workflows/index.js +0 -7
- package/dist/workflows/index.js.map +0 -1
- package/dist/workflows/init.d.ts +0 -84
- package/dist/workflows/init.d.ts.map +0 -1
- package/dist/workflows/init.js +0 -487
- package/dist/workflows/init.js.map +0 -1
- package/dist/workflows/live.d.ts +0 -9
- package/dist/workflows/live.d.ts.map +0 -1
- package/dist/workflows/live.js +0 -7
- package/dist/workflows/live.js.map +0 -1
- package/dist/workflows/options.d.ts +0 -30
- package/dist/workflows/options.d.ts.map +0 -1
- package/dist/workflows/options.js +0 -16
- package/dist/workflows/options.js.map +0 -1
- package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
- package/examples/non-strict-skips/release.config.json +0 -31
- package/examples/pypi-registry/release.config.json +0 -31
- package/templates/github-actions/plan-and-approved-execute.yml +0 -58
- package/templates/github-actions/plan-only.yml +0 -33
- package/templates/github-actions/trusted-publishing.yml +0 -61
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import * as Context from "effect/Context"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import * as Schema from "effect/Schema"
|
|
4
|
+
import type {
|
|
5
|
+
CanonicalAudience,
|
|
6
|
+
CredentialPurpose,
|
|
7
|
+
CredentialRef,
|
|
8
|
+
CredentialRequest,
|
|
9
|
+
EnvironmentName,
|
|
10
|
+
ProviderId,
|
|
11
|
+
SubjectId,
|
|
12
|
+
ResolvedTrustedPublishingAuthStrategy
|
|
13
|
+
} from "../model/authority.js"
|
|
14
|
+
import type { MutationDecision } from "./report.js"
|
|
15
|
+
|
|
16
|
+
const CredentialGrantTypeId: unique symbol = Symbol("ts-release/CredentialGrant")
|
|
17
|
+
|
|
18
|
+
interface CredentialGrantBase<Tag extends string> {
|
|
19
|
+
readonly [CredentialGrantTypeId]: Tag
|
|
20
|
+
readonly _tag: Tag
|
|
21
|
+
readonly subject: SubjectId
|
|
22
|
+
readonly provider: ProviderId
|
|
23
|
+
readonly audience: CanonicalAudience
|
|
24
|
+
readonly purposes: ReadonlySet<CredentialPurpose>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Observe-only capability. It carries no credential or credential accessor. */
|
|
28
|
+
export interface AnonymousAccess extends CredentialGrantBase<"AnonymousAccess"> {}
|
|
29
|
+
|
|
30
|
+
/** Capability backed by a host-owned credential reference, never its value. */
|
|
31
|
+
export interface ScopedSecret extends CredentialGrantBase<"ScopedSecret"> {
|
|
32
|
+
readonly ref: CredentialRef
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Certified workload identity names; token material remains host-owned. */
|
|
36
|
+
export interface WorkloadIdentity extends CredentialGrantBase<"WorkloadIdentity"> {
|
|
37
|
+
readonly names: ReadonlySet<EnvironmentName>
|
|
38
|
+
/** Exact non-secret prepared strategy rechecked by the certified sink. */
|
|
39
|
+
readonly strategy: ResolvedTrustedPublishingAuthStrategy
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type CredentialGrant = AnonymousAccess | ScopedSecret | WorkloadIdentity
|
|
43
|
+
export type MutationCredentialGrant = ScopedSecret | WorkloadIdentity
|
|
44
|
+
|
|
45
|
+
export type NonEmptyPurposes = readonly [CredentialPurpose, ...Array<CredentialPurpose>]
|
|
46
|
+
export type NonEmptyEnvironmentNames = readonly [EnvironmentName, ...Array<EnvironmentName>]
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Metadata returned by a host acquirer. Secret values never cross this seam.
|
|
50
|
+
* `makeCredentialProvider` validates it against the exact prepared request
|
|
51
|
+
* before privately minting an opaque grant.
|
|
52
|
+
*/
|
|
53
|
+
export type CredentialGrantDescriptor =
|
|
54
|
+
| { readonly _tag: "AnonymousAccess", readonly purposes: readonly ["observe"] }
|
|
55
|
+
| { readonly _tag: "ScopedSecret", readonly purposes: NonEmptyPurposes, readonly ref: CredentialRef }
|
|
56
|
+
| { readonly _tag: "WorkloadIdentity", readonly purposes: NonEmptyPurposes, readonly names: NonEmptyEnvironmentNames }
|
|
57
|
+
|
|
58
|
+
export class CredentialUnavailable
|
|
59
|
+
extends Schema.TaggedErrorClass<CredentialUnavailable>()("CredentialUnavailable", {
|
|
60
|
+
subject: Schema.String,
|
|
61
|
+
provider: Schema.String,
|
|
62
|
+
purpose: Schema.String,
|
|
63
|
+
reason: Schema.String
|
|
64
|
+
}) {}
|
|
65
|
+
|
|
66
|
+
export class CredentialAudienceMismatch
|
|
67
|
+
extends Schema.TaggedErrorClass<CredentialAudienceMismatch>()("CredentialAudienceMismatch", {
|
|
68
|
+
subject: Schema.String,
|
|
69
|
+
expected: Schema.String,
|
|
70
|
+
observed: Schema.String
|
|
71
|
+
}) {}
|
|
72
|
+
|
|
73
|
+
export class CredentialPurposeMismatch
|
|
74
|
+
extends Schema.TaggedErrorClass<CredentialPurposeMismatch>()("CredentialPurposeMismatch", {
|
|
75
|
+
subject: Schema.String,
|
|
76
|
+
required: Schema.String,
|
|
77
|
+
granted: Schema.Array(Schema.String)
|
|
78
|
+
}) {}
|
|
79
|
+
|
|
80
|
+
export class CredentialStrategyUnsupported
|
|
81
|
+
extends Schema.TaggedErrorClass<CredentialStrategyUnsupported>()("CredentialStrategyUnsupported", {
|
|
82
|
+
subject: Schema.String,
|
|
83
|
+
provider: Schema.String,
|
|
84
|
+
strategy: Schema.String,
|
|
85
|
+
reason: Schema.String
|
|
86
|
+
}) {}
|
|
87
|
+
|
|
88
|
+
export class CredentialSubjectMismatch
|
|
89
|
+
extends Schema.TaggedErrorClass<CredentialSubjectMismatch>()("CredentialSubjectMismatch", {
|
|
90
|
+
expected: Schema.String,
|
|
91
|
+
observed: Schema.String
|
|
92
|
+
}) {}
|
|
93
|
+
|
|
94
|
+
export class PublisherDispatchError
|
|
95
|
+
extends Schema.TaggedErrorClass<PublisherDispatchError>()("PublisherDispatchError", {
|
|
96
|
+
subject: Schema.String,
|
|
97
|
+
reason: Schema.String
|
|
98
|
+
}) {}
|
|
99
|
+
|
|
100
|
+
export type CredentialAuthorityError =
|
|
101
|
+
| CredentialUnavailable
|
|
102
|
+
| CredentialAudienceMismatch
|
|
103
|
+
| CredentialPurposeMismatch
|
|
104
|
+
| CredentialStrategyUnsupported
|
|
105
|
+
| CredentialSubjectMismatch
|
|
106
|
+
|
|
107
|
+
export interface CredentialGrantAcquirer {
|
|
108
|
+
readonly acquire: (
|
|
109
|
+
request: CredentialRequest
|
|
110
|
+
) => Effect.Effect<CredentialGrantDescriptor, CredentialUnavailable | CredentialStrategyUnsupported>
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface CredentialProviderShape {
|
|
114
|
+
readonly acquireForObservation: (
|
|
115
|
+
request: CredentialRequest
|
|
116
|
+
) => Effect.Effect<CredentialGrant, CredentialAuthorityError>
|
|
117
|
+
readonly acquireForMutation: (
|
|
118
|
+
request: CredentialRequest,
|
|
119
|
+
decision: MutationDecision
|
|
120
|
+
) => Effect.Effect<MutationCredentialGrant, CredentialAuthorityError>
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export class CredentialProvider
|
|
124
|
+
extends Context.Service<CredentialProvider, CredentialProviderShape>()(
|
|
125
|
+
"ts-release/CredentialProvider"
|
|
126
|
+
) {}
|
|
127
|
+
|
|
128
|
+
type GrantMetadata = {
|
|
129
|
+
readonly subject: SubjectId
|
|
130
|
+
readonly provider: ProviderId
|
|
131
|
+
readonly audience: CanonicalAudience
|
|
132
|
+
readonly purposes: ReadonlySet<CredentialPurpose>
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const grantMetadata = new WeakMap<CredentialGrant, GrantMetadata>()
|
|
136
|
+
|
|
137
|
+
const purposeSet = (purposes: NonEmptyPurposes): ReadonlySet<CredentialPurpose> =>
|
|
138
|
+
new Set(purposes)
|
|
139
|
+
|
|
140
|
+
const remember = <Grant extends CredentialGrant>(grant: Grant): Grant => {
|
|
141
|
+
grantMetadata.set(grant, {
|
|
142
|
+
subject: grant.subject,
|
|
143
|
+
provider: grant.provider,
|
|
144
|
+
audience: grant.audience,
|
|
145
|
+
purposes: new Set(grant.purposes)
|
|
146
|
+
})
|
|
147
|
+
return grant
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
class AnonymousAccessGrant implements AnonymousAccess {
|
|
151
|
+
readonly [CredentialGrantTypeId] = "AnonymousAccess" as const
|
|
152
|
+
readonly _tag = "AnonymousAccess" as const
|
|
153
|
+
readonly purposes = purposeSet(["observe"])
|
|
154
|
+
|
|
155
|
+
constructor(
|
|
156
|
+
readonly subject: SubjectId,
|
|
157
|
+
readonly provider: ProviderId,
|
|
158
|
+
readonly audience: CanonicalAudience
|
|
159
|
+
) {
|
|
160
|
+
Object.freeze(this)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
class ScopedSecretGrant implements ScopedSecret {
|
|
165
|
+
readonly [CredentialGrantTypeId] = "ScopedSecret" as const
|
|
166
|
+
readonly _tag = "ScopedSecret" as const
|
|
167
|
+
readonly purposes: ReadonlySet<CredentialPurpose>
|
|
168
|
+
|
|
169
|
+
constructor(
|
|
170
|
+
readonly subject: SubjectId,
|
|
171
|
+
readonly provider: ProviderId,
|
|
172
|
+
readonly audience: CanonicalAudience,
|
|
173
|
+
purposes: NonEmptyPurposes,
|
|
174
|
+
readonly ref: CredentialRef
|
|
175
|
+
) {
|
|
176
|
+
this.purposes = purposeSet(purposes)
|
|
177
|
+
Object.freeze(this)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
class WorkloadIdentityGrant implements WorkloadIdentity {
|
|
182
|
+
readonly [CredentialGrantTypeId] = "WorkloadIdentity" as const
|
|
183
|
+
readonly _tag = "WorkloadIdentity" as const
|
|
184
|
+
readonly purposes: ReadonlySet<CredentialPurpose>
|
|
185
|
+
readonly names: ReadonlySet<EnvironmentName>
|
|
186
|
+
|
|
187
|
+
constructor(
|
|
188
|
+
readonly subject: SubjectId,
|
|
189
|
+
readonly provider: ProviderId,
|
|
190
|
+
readonly audience: CanonicalAudience,
|
|
191
|
+
purposes: NonEmptyPurposes,
|
|
192
|
+
names: NonEmptyEnvironmentNames,
|
|
193
|
+
readonly strategy: ResolvedTrustedPublishingAuthStrategy
|
|
194
|
+
) {
|
|
195
|
+
this.purposes = purposeSet(purposes)
|
|
196
|
+
this.names = new Set(names)
|
|
197
|
+
Object.freeze(this)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const unsupported = (request: CredentialRequest, reason: string) =>
|
|
202
|
+
new CredentialStrategyUnsupported({
|
|
203
|
+
subject: request.subject,
|
|
204
|
+
provider: request.provider,
|
|
205
|
+
strategy: request.strategy.kind,
|
|
206
|
+
reason
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
const validatePurposes = (
|
|
210
|
+
request: CredentialRequest,
|
|
211
|
+
purposes: NonEmptyPurposes
|
|
212
|
+
): Effect.Effect<ReadonlySet<CredentialPurpose>, CredentialPurposeMismatch | CredentialStrategyUnsupported> => {
|
|
213
|
+
const unique = new Set(purposes)
|
|
214
|
+
if (unique.size !== purposes.length) {
|
|
215
|
+
return Effect.fail(unsupported(request, "The host returned duplicate credential purposes."))
|
|
216
|
+
}
|
|
217
|
+
if (!unique.has(request.purpose)) {
|
|
218
|
+
return Effect.fail(new CredentialPurposeMismatch({
|
|
219
|
+
subject: request.subject,
|
|
220
|
+
required: request.purpose,
|
|
221
|
+
granted: [...unique]
|
|
222
|
+
}))
|
|
223
|
+
}
|
|
224
|
+
return Effect.succeed(unique)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const mintGrant = Effect.fn("CredentialProvider.mintGrant")(function*(
|
|
228
|
+
request: CredentialRequest,
|
|
229
|
+
descriptor: CredentialGrantDescriptor
|
|
230
|
+
) {
|
|
231
|
+
yield* validatePurposes(request, descriptor.purposes)
|
|
232
|
+
switch (descriptor._tag) {
|
|
233
|
+
case "AnonymousAccess":
|
|
234
|
+
if (request.strategy.kind !== "anonymous" || request.purpose !== "observe") {
|
|
235
|
+
return yield* unsupported(request, "Anonymous access is valid only for anonymous observation.")
|
|
236
|
+
}
|
|
237
|
+
return remember(new AnonymousAccessGrant(request.subject, request.provider, request.audience))
|
|
238
|
+
case "ScopedSecret":
|
|
239
|
+
if (request.strategy.kind !== "token" || descriptor.ref !== request.strategy.credential) {
|
|
240
|
+
return yield* unsupported(request, "The scoped-secret descriptor does not match the exact token strategy and credential reference.")
|
|
241
|
+
}
|
|
242
|
+
return remember(new ScopedSecretGrant(
|
|
243
|
+
request.subject,
|
|
244
|
+
request.provider,
|
|
245
|
+
request.audience,
|
|
246
|
+
descriptor.purposes,
|
|
247
|
+
descriptor.ref
|
|
248
|
+
))
|
|
249
|
+
case "WorkloadIdentity":
|
|
250
|
+
if (request.strategy.kind !== "trusted-publishing") {
|
|
251
|
+
return yield* unsupported(request, "Workload identity requires the prepared trusted-publishing strategy.")
|
|
252
|
+
}
|
|
253
|
+
if (new Set(descriptor.names).size !== descriptor.names.length) {
|
|
254
|
+
return yield* unsupported(request, "The certified workload environment-name set contains duplicates.")
|
|
255
|
+
}
|
|
256
|
+
return remember(new WorkloadIdentityGrant(
|
|
257
|
+
request.subject,
|
|
258
|
+
request.provider,
|
|
259
|
+
request.audience,
|
|
260
|
+
descriptor.purposes,
|
|
261
|
+
descriptor.names,
|
|
262
|
+
request.strategy
|
|
263
|
+
))
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
/** Builds a host-friendly provider without exposing a grant constructor. */
|
|
268
|
+
export const makeCredentialProvider = (host: CredentialGrantAcquirer): CredentialProviderShape => {
|
|
269
|
+
const acquire = Effect.fn("CredentialProvider.acquire")(function*(request: CredentialRequest) {
|
|
270
|
+
const descriptor = yield* host.acquire(request)
|
|
271
|
+
return yield* mintGrant(request, descriptor)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
acquireForObservation: Effect.fn("CredentialProvider.acquireForObservation")(function*(request) {
|
|
276
|
+
if (request.purpose !== "observe") {
|
|
277
|
+
return yield* new CredentialPurposeMismatch({
|
|
278
|
+
subject: request.subject,
|
|
279
|
+
required: "observe",
|
|
280
|
+
granted: [request.purpose]
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
return yield* acquire(request)
|
|
284
|
+
}),
|
|
285
|
+
acquireForMutation: Effect.fn("CredentialProvider.acquireForMutation")(function*(request, decision) {
|
|
286
|
+
if (request.purpose === "observe") {
|
|
287
|
+
return yield* new CredentialPurposeMismatch({
|
|
288
|
+
subject: request.subject,
|
|
289
|
+
required: "publish-or-correct",
|
|
290
|
+
granted: [request.purpose]
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
if (decision.subject !== request.subject) {
|
|
294
|
+
return yield* new CredentialSubjectMismatch({
|
|
295
|
+
expected: request.subject,
|
|
296
|
+
observed: decision.subject
|
|
297
|
+
})
|
|
298
|
+
}
|
|
299
|
+
const grant = yield* acquire(request)
|
|
300
|
+
if (grant._tag === "AnonymousAccess") {
|
|
301
|
+
return yield* unsupported(request, "Anonymous access cannot authorize mutation.")
|
|
302
|
+
}
|
|
303
|
+
return grant
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export type PublisherOperation =
|
|
309
|
+
| {
|
|
310
|
+
readonly _tag: "PublishOperation"
|
|
311
|
+
readonly subject: SubjectId
|
|
312
|
+
readonly provider: ProviderId
|
|
313
|
+
readonly audience: CanonicalAudience
|
|
314
|
+
readonly purpose: "publish"
|
|
315
|
+
readonly decision: MutationDecision
|
|
316
|
+
}
|
|
317
|
+
| {
|
|
318
|
+
readonly _tag: "CorrectionOperation"
|
|
319
|
+
readonly subject: SubjectId
|
|
320
|
+
readonly provider: ProviderId
|
|
321
|
+
readonly audience: CanonicalAudience
|
|
322
|
+
readonly purpose: "correct"
|
|
323
|
+
readonly decision: MutationDecision
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* The publisher is a host-owned elimination boundary. Provider adapters pass
|
|
328
|
+
* only typed operation data and a capability; no generic command accepts one.
|
|
329
|
+
*/
|
|
330
|
+
export interface PublisherSinkShape {
|
|
331
|
+
readonly dispatch: (
|
|
332
|
+
operation: PublisherOperation,
|
|
333
|
+
grant: MutationCredentialGrant
|
|
334
|
+
) => Effect.Effect<void, CredentialAuthorityError | PublisherDispatchError>
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export class PublisherSink
|
|
338
|
+
extends Context.Service<PublisherSink, PublisherSinkShape>()(
|
|
339
|
+
"ts-release/PublisherSink"
|
|
340
|
+
) {}
|
|
341
|
+
|
|
342
|
+
/** Shared sink-side recheck. It trusts private issuance metadata, not fields. */
|
|
343
|
+
export const validateGrantForOperation = Effect.fn("validateGrantForOperation")(function*(
|
|
344
|
+
operation: PublisherOperation,
|
|
345
|
+
grant: MutationCredentialGrant
|
|
346
|
+
) {
|
|
347
|
+
const issued = grantMetadata.get(grant)
|
|
348
|
+
if (issued === undefined) {
|
|
349
|
+
return yield* new CredentialUnavailable({
|
|
350
|
+
subject: operation.subject,
|
|
351
|
+
provider: operation.provider,
|
|
352
|
+
purpose: operation.purpose,
|
|
353
|
+
reason: "The supplied grant was not issued by this authority boundary."
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
if (issued.subject !== operation.subject) {
|
|
357
|
+
return yield* new CredentialSubjectMismatch({
|
|
358
|
+
expected: operation.subject,
|
|
359
|
+
observed: issued.subject
|
|
360
|
+
})
|
|
361
|
+
}
|
|
362
|
+
if (operation.decision.subject !== operation.subject) {
|
|
363
|
+
return yield* new CredentialSubjectMismatch({
|
|
364
|
+
expected: operation.subject,
|
|
365
|
+
observed: operation.decision.subject
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
if (issued.provider !== operation.provider || issued.audience !== operation.audience) {
|
|
369
|
+
return yield* new CredentialAudienceMismatch({
|
|
370
|
+
subject: operation.subject,
|
|
371
|
+
expected: `${operation.provider}:${operation.audience}`,
|
|
372
|
+
observed: `${issued.provider}:${issued.audience}`
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
if (!issued.purposes.has(operation.purpose)) {
|
|
376
|
+
return yield* new CredentialPurposeMismatch({
|
|
377
|
+
subject: operation.subject,
|
|
378
|
+
required: operation.purpose,
|
|
379
|
+
granted: [...issued.purposes]
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
export interface PublisherDispatcher {
|
|
385
|
+
readonly dispatch: (
|
|
386
|
+
operation: PublisherOperation,
|
|
387
|
+
grant: MutationCredentialGrant
|
|
388
|
+
) => Effect.Effect<void, PublisherDispatchError>
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/** Wraps a host dispatcher so every mutation rechecks opaque authority first. */
|
|
392
|
+
export const makePublisherSink = (host: PublisherDispatcher): PublisherSinkShape => ({
|
|
393
|
+
dispatch: Effect.fn("PublisherSink.dispatch")(function*(operation, grant) {
|
|
394
|
+
yield* validateGrantForOperation(operation, grant)
|
|
395
|
+
yield* host.dispatch(operation, grant)
|
|
396
|
+
})
|
|
397
|
+
})
|