@mannyc1/ts-release 0.0.7 → 0.3.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/ARCHITECTURE.md +184 -92
- package/CHANGELOG.md +197 -0
- package/LICENSE +21 -0
- package/README.md +404 -327
- package/SPEC.md +257 -310
- package/apps/release-ts/README.md +39 -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 +122 -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 +39346 -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 +9 -0
- package/dist/drivers/archive.d.ts.map +1 -0
- package/dist/drivers/archive.js +105 -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/python-wheel.d.ts +21 -0
- package/dist/drivers/python-wheel.d.ts.map +1 -0
- package/dist/drivers/python-wheel.js +109 -0
- package/dist/drivers/python-wheel.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 +9 -0
- package/dist/drivers/workspace.d.ts.map +1 -0
- package/dist/drivers/workspace.js +53 -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/operation-journal/authority.d.ts +3 -0
- package/dist/operation-journal/authority.d.ts.map +1 -0
- package/dist/operation-journal/authority.js +147 -0
- package/dist/operation-journal/authority.js.map +1 -0
- package/dist/operation-journal/aws/deadline.d.ts +12 -0
- package/dist/operation-journal/aws/deadline.d.ts.map +1 -0
- package/dist/operation-journal/aws/deadline.js +38 -0
- package/dist/operation-journal/aws/deadline.js.map +1 -0
- package/dist/operation-journal/aws/oidc.d.ts +27 -0
- package/dist/operation-journal/aws/oidc.d.ts.map +1 -0
- package/dist/operation-journal/aws/oidc.js +361 -0
- package/dist/operation-journal/aws/oidc.js.map +1 -0
- package/dist/operation-journal/aws/policy.d.ts +42 -0
- package/dist/operation-journal/aws/policy.d.ts.map +1 -0
- package/dist/operation-journal/aws/policy.js +404 -0
- package/dist/operation-journal/aws/policy.js.map +1 -0
- package/dist/operation-journal/aws/s3-boundary.d.ts +17 -0
- package/dist/operation-journal/aws/s3-boundary.d.ts.map +1 -0
- package/dist/operation-journal/aws/s3-boundary.js +417 -0
- package/dist/operation-journal/aws/s3-boundary.js.map +1 -0
- package/dist/operation-journal/aws.d.ts +11 -0
- package/dist/operation-journal/aws.d.ts.map +1 -0
- package/dist/operation-journal/aws.js +50 -0
- package/dist/operation-journal/aws.js.map +1 -0
- package/dist/operation-journal/canonical.d.ts +52 -0
- package/dist/operation-journal/canonical.d.ts.map +1 -0
- package/dist/operation-journal/canonical.js +282 -0
- package/dist/operation-journal/canonical.js.map +1 -0
- package/dist/operation-journal/model.d.ts +251 -0
- package/dist/operation-journal/model.d.ts.map +1 -0
- package/dist/operation-journal/model.js +56 -0
- package/dist/operation-journal/model.js.map +1 -0
- package/dist/operation-journal/reducer.d.ts +28 -0
- package/dist/operation-journal/reducer.d.ts.map +1 -0
- package/dist/operation-journal/reducer.js +73 -0
- package/dist/operation-journal/reducer.js.map +1 -0
- package/dist/operation-journal/s3.d.ts +7 -0
- package/dist/operation-journal/s3.d.ts.map +1 -0
- package/dist/operation-journal/s3.js +667 -0
- package/dist/operation-journal/s3.js.map +1 -0
- package/dist/operation-journal.d.ts +14 -0
- package/dist/operation-journal.d.ts.map +1 -0
- package/dist/operation-journal.js +12 -0
- package/dist/operation-journal.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 +834 -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 +695 -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 +1115 -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 +339 -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 +73 -154
- 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 +111 -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 +339 -0
- package/src/drivers/python-wheel.ts +145 -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 +46 -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/operation-journal/authority.ts +162 -0
- package/src/operation-journal/aws/deadline.ts +41 -0
- package/src/operation-journal/aws/oidc.ts +439 -0
- package/src/operation-journal/aws/policy.ts +491 -0
- package/src/operation-journal/aws/s3-boundary.ts +562 -0
- package/src/operation-journal/aws.ts +60 -0
- package/src/operation-journal/canonical.ts +373 -0
- package/src/operation-journal/model.ts +301 -0
- package/src/operation-journal/reducer.ts +112 -0
- package/src/operation-journal/s3.ts +884 -0
- package/src/operation-journal.ts +51 -0
- package/src/platform/bun.ts +38 -0
- package/src/platform/credentials.ts +1151 -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 +1022 -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 +460 -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 +1329 -0
- package/src/release/prepared-ref.ts +193 -0
- package/src/release/prepared-store.ts +378 -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 +74 -0
- package/templates/github-actions/reviewed-release.yml +115 -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,237 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
import { encodeCanonicalJson } from "./canonical.js"
|
|
3
|
+
import { sha256Digest } from "./digest.js"
|
|
4
|
+
import { OperationId, OutputId, SafeRelativePath } from "./primitives.js"
|
|
5
|
+
|
|
6
|
+
export const ArtifactCollectionId = Schema.NonEmptyString.check(Schema.makeFilter((value: string) =>
|
|
7
|
+
/^[A-Za-z0-9._-]+$/u.test(value)
|
|
8
|
+
? undefined
|
|
9
|
+
: "Artifact collection id must be a portable ASCII identifier."
|
|
10
|
+
)).pipe(Schema.brand("ArtifactCollectionId"))
|
|
11
|
+
export type ArtifactCollectionId = typeof ArtifactCollectionId.Type
|
|
12
|
+
|
|
13
|
+
export const CollectionArtifactKind = Schema.Literals([
|
|
14
|
+
"file",
|
|
15
|
+
"executable",
|
|
16
|
+
"archive",
|
|
17
|
+
"digest"
|
|
18
|
+
])
|
|
19
|
+
export type CollectionArtifactKind = typeof CollectionArtifactKind.Type
|
|
20
|
+
|
|
21
|
+
export const ArtifactPathSuffix = Schema.NonEmptyString.check(Schema.makeFilter((value: string) =>
|
|
22
|
+
/^\.[A-Za-z0-9._-]+$/u.test(value)
|
|
23
|
+
? undefined
|
|
24
|
+
: "Artifact collection pathSuffix must be a canonical dot suffix without path separators."
|
|
25
|
+
)).pipe(Schema.brand("ArtifactPathSuffix"))
|
|
26
|
+
export type ArtifactPathSuffix = typeof ArtifactPathSuffix.Type
|
|
27
|
+
|
|
28
|
+
export const ArtifactCollectionRoot = SafeRelativePath.check(Schema.makeFilter((value: string) =>
|
|
29
|
+
value !== "." && value.split("/").every((part) => /^[A-Za-z0-9._-]+$/u.test(part) && part !== "." && part !== "..")
|
|
30
|
+
? undefined
|
|
31
|
+
: "Artifact collection root must be a canonical NFC POSIX subdirectory."
|
|
32
|
+
)).pipe(Schema.brand("ArtifactCollectionRoot"))
|
|
33
|
+
export type ArtifactCollectionRoot = typeof ArtifactCollectionRoot.Type
|
|
34
|
+
|
|
35
|
+
const nonNegativeInteger = Schema.Number.check(Schema.makeFilter((value: number) =>
|
|
36
|
+
Number.isSafeInteger(value) && value >= 0
|
|
37
|
+
? undefined
|
|
38
|
+
: "Collection cardinality bounds must be nonnegative safe integers."
|
|
39
|
+
))
|
|
40
|
+
|
|
41
|
+
export class OneArtifactCardinality
|
|
42
|
+
extends Schema.Class<OneArtifactCardinality>("OneArtifactCardinality")({
|
|
43
|
+
kind: Schema.Literal("one")
|
|
44
|
+
}) {}
|
|
45
|
+
|
|
46
|
+
export class OneOrMoreArtifactCardinality
|
|
47
|
+
extends Schema.Class<OneOrMoreArtifactCardinality>("OneOrMoreArtifactCardinality")({
|
|
48
|
+
kind: Schema.Literal("one-or-more")
|
|
49
|
+
}) {}
|
|
50
|
+
|
|
51
|
+
export class BoundedArtifactCardinality
|
|
52
|
+
extends Schema.Class<BoundedArtifactCardinality>("BoundedArtifactCardinality")({
|
|
53
|
+
kind: Schema.Literal("bounded"),
|
|
54
|
+
minimum: nonNegativeInteger,
|
|
55
|
+
maximum: nonNegativeInteger
|
|
56
|
+
}) {}
|
|
57
|
+
|
|
58
|
+
const ArtifactCardinalityVariants = Schema.Union([
|
|
59
|
+
OneArtifactCardinality,
|
|
60
|
+
OneOrMoreArtifactCardinality,
|
|
61
|
+
BoundedArtifactCardinality
|
|
62
|
+
])
|
|
63
|
+
|
|
64
|
+
export const ArtifactCardinality = ArtifactCardinalityVariants.pipe(Schema.check(
|
|
65
|
+
Schema.makeFilter((value) => value.kind !== "bounded" || value.minimum <= value.maximum
|
|
66
|
+
? undefined
|
|
67
|
+
: "Bounded collection cardinality minimum must not exceed maximum.")
|
|
68
|
+
))
|
|
69
|
+
export type ArtifactCardinality = typeof ArtifactCardinality.Type
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* One command-owned dynamic output set. A collection intentionally permits one
|
|
73
|
+
* artifact kind and one filename suffix: heterogeneous output sets must be
|
|
74
|
+
* split into independently selectable contracts.
|
|
75
|
+
*/
|
|
76
|
+
export class ArtifactCollectionContract
|
|
77
|
+
extends Schema.Class<ArtifactCollectionContract>("ArtifactCollectionContract")({
|
|
78
|
+
id: ArtifactCollectionId,
|
|
79
|
+
producer: OperationId,
|
|
80
|
+
root: ArtifactCollectionRoot,
|
|
81
|
+
artifactKind: CollectionArtifactKind,
|
|
82
|
+
pathSuffix: ArtifactPathSuffix,
|
|
83
|
+
mediaType: Schema.NonEmptyString,
|
|
84
|
+
cardinality: ArtifactCardinality
|
|
85
|
+
}) {}
|
|
86
|
+
|
|
87
|
+
/** A downstream requirement over a stable collection identity. */
|
|
88
|
+
export class ArtifactCollectionSelector
|
|
89
|
+
extends Schema.Class<ArtifactCollectionSelector>("ArtifactCollectionSelector")({
|
|
90
|
+
collection: ArtifactCollectionId,
|
|
91
|
+
artifactKind: CollectionArtifactKind,
|
|
92
|
+
pathSuffix: ArtifactPathSuffix,
|
|
93
|
+
mediaType: Schema.NonEmptyString,
|
|
94
|
+
cardinality: ArtifactCardinality
|
|
95
|
+
}) {}
|
|
96
|
+
|
|
97
|
+
/** Exact runtime member identity persisted beside the prepared artifacts. */
|
|
98
|
+
export class ArtifactCollectionMember
|
|
99
|
+
extends Schema.Class<ArtifactCollectionMember>("ArtifactCollectionMember")({
|
|
100
|
+
key: SafeRelativePath,
|
|
101
|
+
artifactId: OutputId
|
|
102
|
+
}) {}
|
|
103
|
+
|
|
104
|
+
export interface CardinalityRange {
|
|
105
|
+
readonly minimum: number
|
|
106
|
+
readonly maximum?: number
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const cardinalityRange = (value: ArtifactCardinality): CardinalityRange => {
|
|
110
|
+
switch (value.kind) {
|
|
111
|
+
case "one": return { minimum: 1, maximum: 1 }
|
|
112
|
+
case "one-or-more": return { minimum: 1 }
|
|
113
|
+
case "bounded": return { minimum: value.minimum, maximum: value.maximum }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const cardinalityIssue = (value: ArtifactCardinality): string | undefined => {
|
|
118
|
+
const range = cardinalityRange(value)
|
|
119
|
+
return !Number.isSafeInteger(range.minimum) || range.minimum < 0 ||
|
|
120
|
+
(range.maximum !== undefined && (!Number.isSafeInteger(range.maximum) || range.maximum < range.minimum))
|
|
121
|
+
? "Collection cardinality must define a valid nonnegative integer range."
|
|
122
|
+
: undefined
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Reject kind/media/suffix combinations whose observable claims conflict. */
|
|
126
|
+
export const collectionContractIssue = (
|
|
127
|
+
value: Pick<ArtifactCollectionContract, "artifactKind" | "pathSuffix" | "mediaType">
|
|
128
|
+
): string | undefined => {
|
|
129
|
+
const suffix = value.pathSuffix.toString()
|
|
130
|
+
switch (value.artifactKind) {
|
|
131
|
+
case "archive":
|
|
132
|
+
if (value.mediaType === "application/zip" && suffix === ".zip") return undefined
|
|
133
|
+
if (value.mediaType === "application/gzip" && [".gz", ".tgz", ".tar.gz"].includes(suffix)) return undefined
|
|
134
|
+
return "Archive collections support application/zip with .zip or application/gzip with .gz, .tgz, or .tar.gz."
|
|
135
|
+
case "digest":
|
|
136
|
+
return value.mediaType === "text/plain" && [".sha256", ".sha512"].includes(suffix)
|
|
137
|
+
? undefined
|
|
138
|
+
: "Digest collections require text/plain with .sha256 or .sha512."
|
|
139
|
+
case "executable":
|
|
140
|
+
return value.mediaType === "application/octet-stream"
|
|
141
|
+
? undefined
|
|
142
|
+
: "Executable collections require application/octet-stream; executable mode is observed at capture."
|
|
143
|
+
case "file":
|
|
144
|
+
return value.mediaType === "application/zip" || value.mediaType === "application/gzip"
|
|
145
|
+
? "Archive media types require the archive artifact kind."
|
|
146
|
+
: undefined
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Byte-level checks for the formats whose kind is portable and observable. */
|
|
151
|
+
export const collectionMemberBytesIssue = (
|
|
152
|
+
contract: ArtifactCollectionContract,
|
|
153
|
+
bytes: Uint8Array
|
|
154
|
+
): string | undefined => {
|
|
155
|
+
if (contract.artifactKind === "archive") {
|
|
156
|
+
if (contract.mediaType === "application/zip") {
|
|
157
|
+
return bytes.length >= 4 && bytes[0] === 0x50 && bytes[1] === 0x4b &&
|
|
158
|
+
((bytes[2] === 0x03 && bytes[3] === 0x04) ||
|
|
159
|
+
(bytes[2] === 0x05 && bytes[3] === 0x06) ||
|
|
160
|
+
(bytes[2] === 0x07 && bytes[3] === 0x08))
|
|
161
|
+
? undefined
|
|
162
|
+
: "declared ZIP member does not have a ZIP file signature"
|
|
163
|
+
}
|
|
164
|
+
if (contract.mediaType === "application/gzip") {
|
|
165
|
+
return bytes.length >= 3 && bytes[0] === 0x1f && bytes[1] === 0x8b && bytes[2] === 0x08
|
|
166
|
+
? undefined
|
|
167
|
+
: "declared gzip member does not have a gzip file signature"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (contract.artifactKind === "digest") {
|
|
171
|
+
let text: string
|
|
172
|
+
try { text = new TextDecoder("utf-8", { fatal: true }).decode(bytes) } catch {
|
|
173
|
+
return "declared digest member is not UTF-8 text"
|
|
174
|
+
}
|
|
175
|
+
const digits = contract.pathSuffix === ".sha256" ? 64 : 128
|
|
176
|
+
const rows = text.endsWith("\n") ? text.slice(0, -1).split("\n") : text.split("\n")
|
|
177
|
+
return rows.length > 0 && rows.every((row) => new RegExp(`^[a-f0-9]{${digits}} [^\\s/](?:.*[^\\s/])?$`, "u").test(row))
|
|
178
|
+
? undefined
|
|
179
|
+
: `declared digest member does not contain canonical ${digits}-hex checksum rows`
|
|
180
|
+
}
|
|
181
|
+
return undefined
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const cardinalityAccepts = (value: ArtifactCardinality, count: number): boolean => {
|
|
185
|
+
const range = cardinalityRange(value)
|
|
186
|
+
return Number.isSafeInteger(count) && count >= range.minimum &&
|
|
187
|
+
(range.maximum === undefined || count <= range.maximum)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export const cardinalitiesOverlap = (
|
|
191
|
+
left: ArtifactCardinality,
|
|
192
|
+
right: ArtifactCardinality
|
|
193
|
+
): boolean => {
|
|
194
|
+
const a = cardinalityRange(left)
|
|
195
|
+
const b = cardinalityRange(right)
|
|
196
|
+
const maximum = a.maximum === undefined
|
|
197
|
+
? b.maximum
|
|
198
|
+
: b.maximum === undefined
|
|
199
|
+
? a.maximum
|
|
200
|
+
: Math.min(a.maximum, b.maximum)
|
|
201
|
+
return maximum === undefined || Math.max(a.minimum, b.minimum) <= maximum
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Paths discovered from directory entries must already be portable canon. */
|
|
205
|
+
export const normalizeCollectionMemberKey = (value: string): SafeRelativePath => {
|
|
206
|
+
if (value.split("/").some((part) => !/^[A-Za-z0-9._-]+$/u.test(part) || part === "." || part === "..")) {
|
|
207
|
+
throw new Error(`Collection member path ${JSON.stringify(value)} is not portable ASCII POSIX form.`)
|
|
208
|
+
}
|
|
209
|
+
return SafeRelativePath.make(value)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Stable output identity is a digest of the declared producer/contract and the
|
|
214
|
+
* normalized member key. No guessed runtime filename becomes graph authority.
|
|
215
|
+
*/
|
|
216
|
+
export const collectionMemberId = (
|
|
217
|
+
contract: ArtifactCollectionContract,
|
|
218
|
+
key: SafeRelativePath
|
|
219
|
+
): OutputId => OutputId.make(`collection-sha256-${sha256Digest(new TextEncoder().encode(
|
|
220
|
+
encodeCanonicalJson({
|
|
221
|
+
producer: contract.producer.toString(),
|
|
222
|
+
collection: contract.id.toString(),
|
|
223
|
+
root: contract.root.toString(),
|
|
224
|
+
artifactKind: contract.artifactKind,
|
|
225
|
+
pathSuffix: contract.pathSuffix.toString(),
|
|
226
|
+
mediaType: contract.mediaType,
|
|
227
|
+
cardinality: contract.cardinality.kind === "bounded"
|
|
228
|
+
? { kind: contract.cardinality.kind, minimum: contract.cardinality.minimum, maximum: contract.cardinality.maximum }
|
|
229
|
+
: { kind: contract.cardinality.kind },
|
|
230
|
+
key: key.toString()
|
|
231
|
+
})
|
|
232
|
+
)).hex}`)
|
|
233
|
+
|
|
234
|
+
export const collectionMemberPath = (
|
|
235
|
+
contract: ArtifactCollectionContract,
|
|
236
|
+
key: SafeRelativePath
|
|
237
|
+
): SafeRelativePath => SafeRelativePath.make(`${contract.root}/${key}`)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
|
|
3
|
+
const identifier = <const Name extends string>(name: Name) =>
|
|
4
|
+
Schema.NonEmptyString.pipe(Schema.brand(name))
|
|
5
|
+
|
|
6
|
+
/** Stable identity of one remotely observable publication/correction subject. */
|
|
7
|
+
export const SubjectId = identifier("SubjectId")
|
|
8
|
+
export type SubjectId = typeof SubjectId.Type
|
|
9
|
+
|
|
10
|
+
export const ProviderId = identifier("ProviderId")
|
|
11
|
+
export type ProviderId = typeof ProviderId.Type
|
|
12
|
+
|
|
13
|
+
/** Canonical provider audience, including any authority-relevant base path. */
|
|
14
|
+
export const CanonicalAudience = identifier("CanonicalAudience")
|
|
15
|
+
export type CanonicalAudience = typeof CanonicalAudience.Type
|
|
16
|
+
|
|
17
|
+
/** A host-owned secret reference. It is a name/handle, never secret material. */
|
|
18
|
+
export const CredentialRef = identifier("CredentialRef")
|
|
19
|
+
export type CredentialRef = typeof CredentialRef.Type
|
|
20
|
+
|
|
21
|
+
export const EnvironmentName = Schema.String.check(
|
|
22
|
+
Schema.makeFilter((value: string) => /^[A-Za-z_][A-Za-z0-9_]*$/u.test(value)
|
|
23
|
+
? undefined
|
|
24
|
+
: "EnvironmentName must be a portable environment variable name.")
|
|
25
|
+
).pipe(Schema.brand("EnvironmentName"))
|
|
26
|
+
export type EnvironmentName = typeof EnvironmentName.Type
|
|
27
|
+
|
|
28
|
+
export const CredentialPurpose = Schema.Literals(["observe", "publish", "correct"])
|
|
29
|
+
export type CredentialPurpose = typeof CredentialPurpose.Type
|
|
30
|
+
|
|
31
|
+
/** Exact verified source revision projected into npm's GitHub provenance statement. */
|
|
32
|
+
export const TrustedPublishingSourceCommit = Schema.String.check(
|
|
33
|
+
Schema.makeFilter((value: string) => /^[a-f0-9]{40}(?:[a-f0-9]{24})?$/u.test(value)
|
|
34
|
+
? undefined
|
|
35
|
+
: "TrustedPublishingSourceCommit must be a lowercase full Git SHA (40 or 64 hex characters).")
|
|
36
|
+
).pipe(Schema.brand("TrustedPublishingSourceCommit"))
|
|
37
|
+
export type TrustedPublishingSourceCommit = typeof TrustedPublishingSourceCommit.Type
|
|
38
|
+
|
|
39
|
+
export class AnonymousAuthStrategy
|
|
40
|
+
extends Schema.Class<AnonymousAuthStrategy>("AnonymousAuthStrategy")({
|
|
41
|
+
kind: Schema.Literal("anonymous")
|
|
42
|
+
}) {}
|
|
43
|
+
|
|
44
|
+
export class TokenAuthStrategy
|
|
45
|
+
extends Schema.Class<TokenAuthStrategy>("TokenAuthStrategy")({
|
|
46
|
+
kind: Schema.Literal("token"),
|
|
47
|
+
credential: CredentialRef
|
|
48
|
+
}) {}
|
|
49
|
+
|
|
50
|
+
export class TrustedPublishingAuthStrategy
|
|
51
|
+
extends Schema.Class<TrustedPublishingAuthStrategy>("TrustedPublishingAuthStrategy")({
|
|
52
|
+
kind: Schema.Literal("trusted-publishing"),
|
|
53
|
+
identityProvider: Schema.Literal("github-actions"),
|
|
54
|
+
runnerClass: Schema.Literal("github-hosted"),
|
|
55
|
+
repository: Schema.NonEmptyString,
|
|
56
|
+
workflow: Schema.NonEmptyString,
|
|
57
|
+
workflowRef: Schema.NonEmptyString,
|
|
58
|
+
sourceCommit: TrustedPublishingSourceCommit,
|
|
59
|
+
provenanceEnvironmentContract: Schema.Literal("github-actions-npm-provenance-v1"),
|
|
60
|
+
allowedAction: Schema.Literal("npm-publish-direct"),
|
|
61
|
+
publisherSink: Schema.Literal("certified-npm-cli")
|
|
62
|
+
}) {}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A supported external workflow owner. The stock coordinator persists and
|
|
66
|
+
* reports this identity but deliberately cannot mint or consume its token.
|
|
67
|
+
*/
|
|
68
|
+
export class ExternalTrustedPublishingAuthStrategy
|
|
69
|
+
extends Schema.Class<ExternalTrustedPublishingAuthStrategy>("ExternalTrustedPublishingAuthStrategy")({
|
|
70
|
+
kind: Schema.Literal("trusted-publishing"),
|
|
71
|
+
identityProvider: Schema.Literal("github-actions"),
|
|
72
|
+
runnerClass: Schema.Literal("github-hosted"),
|
|
73
|
+
repository: Schema.NonEmptyString,
|
|
74
|
+
workflow: Schema.NonEmptyString,
|
|
75
|
+
workflowRef: Schema.NonEmptyString,
|
|
76
|
+
sourceCommit: TrustedPublishingSourceCommit,
|
|
77
|
+
provenanceEnvironmentContract: Schema.Literal("external-pypa-action-v1"),
|
|
78
|
+
allowedAction: Schema.Literal("external-pypa-action"),
|
|
79
|
+
publisherSink: Schema.Literal("external-host-owned"),
|
|
80
|
+
environment: Schema.NonEmptyString,
|
|
81
|
+
projects: Schema.NonEmptyArray(Schema.NonEmptyString)
|
|
82
|
+
}) {}
|
|
83
|
+
|
|
84
|
+
export const ResolvedTrustedPublishingAuthStrategy = Schema.Union([
|
|
85
|
+
TrustedPublishingAuthStrategy,
|
|
86
|
+
ExternalTrustedPublishingAuthStrategy
|
|
87
|
+
])
|
|
88
|
+
export type ResolvedTrustedPublishingAuthStrategy = typeof ResolvedTrustedPublishingAuthStrategy.Type
|
|
89
|
+
|
|
90
|
+
export const ResolvedAuthStrategy = Schema.Union([
|
|
91
|
+
AnonymousAuthStrategy,
|
|
92
|
+
TokenAuthStrategy,
|
|
93
|
+
ResolvedTrustedPublishingAuthStrategy
|
|
94
|
+
])
|
|
95
|
+
export type ResolvedAuthStrategy = typeof ResolvedAuthStrategy.Type
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Exact authority requested for a verified prepared subject. This value is
|
|
99
|
+
* safe to report and persist: it contains only host references and intent.
|
|
100
|
+
*/
|
|
101
|
+
export class CredentialRequest
|
|
102
|
+
extends Schema.Class<CredentialRequest>("CredentialRequest")({
|
|
103
|
+
subject: SubjectId,
|
|
104
|
+
provider: ProviderId,
|
|
105
|
+
audience: CanonicalAudience,
|
|
106
|
+
purpose: CredentialPurpose,
|
|
107
|
+
strategy: ResolvedAuthStrategy
|
|
108
|
+
}) {}
|
|
109
|
+
|
|
110
|
+
export type ObservationCredentialRequest = CredentialRequest & {
|
|
111
|
+
readonly purpose: "observe"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export type MutationCredentialRequest = CredentialRequest & {
|
|
115
|
+
readonly purpose: "publish" | "correct"
|
|
116
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one advertised Bun artifact-target vocabulary. Config decoding, graph
|
|
3
|
+
* compilation, capability documentation, and cross-compile certification all
|
|
4
|
+
* project from these values.
|
|
5
|
+
*/
|
|
6
|
+
export const bunArtifactTargets = Object.freeze([
|
|
7
|
+
{ id: "linux-x64", bunTarget: "bun-linux-x64", format: "elf", architecture: "x86_64" },
|
|
8
|
+
{ id: "linux-arm64", bunTarget: "bun-linux-arm64", format: "elf", architecture: "aarch64" },
|
|
9
|
+
{ id: "darwin-x64", bunTarget: "bun-darwin-x64", format: "mach-o", architecture: "x86_64" },
|
|
10
|
+
{ id: "darwin-arm64", bunTarget: "bun-darwin-arm64", format: "mach-o", architecture: "aarch64" }
|
|
11
|
+
] as const)
|
|
12
|
+
|
|
13
|
+
// Windows targets are deliberately not advertised or shipped by this
|
|
14
|
+
// candidate. Header-valid cross-compilation alone cannot certify execution.
|
|
15
|
+
// Reopen one only after its public CLI binary executes on that Windows host in
|
|
16
|
+
// the same clean-candidate gate.
|
|
17
|
+
export type BunArtifactTarget = typeof bunArtifactTargets[number]
|
|
18
|
+
export type BunArtifactTargetId = BunArtifactTarget["id"]
|
|
19
|
+
export type BunBinaryFormat = BunArtifactTarget["format"]
|
|
20
|
+
export type BunBinaryArchitecture = BunArtifactTarget["architecture"]
|
|
21
|
+
|
|
22
|
+
const idsOf = <const Entries extends ReadonlyArray<{ readonly id: string }>>(
|
|
23
|
+
entries: Entries
|
|
24
|
+
): { readonly [Index in keyof Entries]: Entries[Index] extends { readonly id: infer Id } ? Id : never } =>
|
|
25
|
+
Object.freeze(entries.map(({ id }) => id)) as never
|
|
26
|
+
|
|
27
|
+
export const bunArtifactTargetIds = idsOf(bunArtifactTargets)
|
|
28
|
+
|
|
29
|
+
const byId = new Map<BunArtifactTargetId, BunArtifactTarget>(
|
|
30
|
+
bunArtifactTargets.map((target) => [target.id, target])
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
/** Total after strict config decoding against `bunArtifactTargetIds`. */
|
|
34
|
+
export const bunArtifactTarget = (id: BunArtifactTargetId): BunArtifactTarget => byId.get(id)!
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createHash } from "node:crypto"
|
|
2
|
+
|
|
3
|
+
export type Json =
|
|
4
|
+
| boolean
|
|
5
|
+
| null
|
|
6
|
+
| number
|
|
7
|
+
| string
|
|
8
|
+
| ReadonlyArray<Json>
|
|
9
|
+
| { readonly [key: string]: Json }
|
|
10
|
+
|
|
11
|
+
class StrictJsonParser {
|
|
12
|
+
private index = 0
|
|
13
|
+
constructor(private readonly text: string) {}
|
|
14
|
+
|
|
15
|
+
parse(): Json {
|
|
16
|
+
this.space()
|
|
17
|
+
const value = this.value()
|
|
18
|
+
this.space()
|
|
19
|
+
if (this.index !== this.text.length) this.fail("trailing input")
|
|
20
|
+
return value
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private fail(reason: string): never {
|
|
24
|
+
throw new Error(`Invalid strict JSON at ${this.index}: ${reason}`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private space(): void {
|
|
28
|
+
while (/[\t\n\r ]/u.test(this.text[this.index] ?? "")) this.index += 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private take(expected: string): void {
|
|
32
|
+
if (!this.text.startsWith(expected, this.index)) this.fail(`expected ${expected}`)
|
|
33
|
+
this.index += expected.length
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private value(): Json {
|
|
37
|
+
const token = this.text[this.index]
|
|
38
|
+
if (token === "{") return this.object()
|
|
39
|
+
if (token === "[") return this.array()
|
|
40
|
+
if (token === '"') return this.string()
|
|
41
|
+
if (token === "t") {
|
|
42
|
+
this.take("true")
|
|
43
|
+
return true
|
|
44
|
+
}
|
|
45
|
+
if (token === "f") {
|
|
46
|
+
this.take("false")
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
if (token === "n") {
|
|
50
|
+
this.take("null")
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
if (token === "-" || token !== undefined && /[0-9]/u.test(token)) return this.number()
|
|
54
|
+
return this.fail("expected value")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private string(): string {
|
|
58
|
+
const start = this.index
|
|
59
|
+
this.index += 1
|
|
60
|
+
let escaped = false
|
|
61
|
+
while (this.index < this.text.length) {
|
|
62
|
+
const character = this.text[this.index]!
|
|
63
|
+
if (!escaped && character === '"') {
|
|
64
|
+
this.index += 1
|
|
65
|
+
const value = JSON.parse(this.text.slice(start, this.index)) as string
|
|
66
|
+
if (value !== value.normalize("NFC")) this.fail("non-NFC string")
|
|
67
|
+
return value
|
|
68
|
+
}
|
|
69
|
+
if (!escaped && character.codePointAt(0)! < 0x20) this.fail("control character")
|
|
70
|
+
escaped = !escaped && character === "\\"
|
|
71
|
+
this.index += 1
|
|
72
|
+
}
|
|
73
|
+
return this.fail("unterminated string")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private number(): number {
|
|
77
|
+
const match = /^-?(?:0|[1-9][0-9]*)/u.exec(this.text.slice(this.index))
|
|
78
|
+
if (match === null) return this.fail("invalid number")
|
|
79
|
+
const token = match[0]
|
|
80
|
+
const next = this.text[this.index + token.length]
|
|
81
|
+
if (next === "." || next === "e" || next === "E") this.fail("float")
|
|
82
|
+
this.index += token.length
|
|
83
|
+
const value = Number(token)
|
|
84
|
+
if (!Number.isSafeInteger(value) || Object.is(value, -0)) this.fail("unsafe integer")
|
|
85
|
+
return value
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private array(): ReadonlyArray<Json> {
|
|
89
|
+
this.index += 1
|
|
90
|
+
this.space()
|
|
91
|
+
const result: Array<Json> = []
|
|
92
|
+
if (this.text[this.index] === "]") {
|
|
93
|
+
this.index += 1
|
|
94
|
+
return result
|
|
95
|
+
}
|
|
96
|
+
while (true) {
|
|
97
|
+
result.push(this.value())
|
|
98
|
+
this.space()
|
|
99
|
+
if (this.text[this.index] === "]") {
|
|
100
|
+
this.index += 1
|
|
101
|
+
return result
|
|
102
|
+
}
|
|
103
|
+
this.take(",")
|
|
104
|
+
this.space()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private object(): { readonly [key: string]: Json } {
|
|
109
|
+
this.index += 1
|
|
110
|
+
this.space()
|
|
111
|
+
const result: Record<string, Json> = {}
|
|
112
|
+
if (this.text[this.index] === "}") {
|
|
113
|
+
this.index += 1
|
|
114
|
+
return result
|
|
115
|
+
}
|
|
116
|
+
while (true) {
|
|
117
|
+
if (this.text[this.index] !== '"') this.fail("expected object key")
|
|
118
|
+
const key = this.string()
|
|
119
|
+
if (Object.hasOwn(result, key)) this.fail(`duplicate key ${key}`)
|
|
120
|
+
this.space()
|
|
121
|
+
this.take(":")
|
|
122
|
+
this.space()
|
|
123
|
+
result[key] = this.value()
|
|
124
|
+
this.space()
|
|
125
|
+
if (this.text[this.index] === "}") {
|
|
126
|
+
this.index += 1
|
|
127
|
+
return result
|
|
128
|
+
}
|
|
129
|
+
this.take(",")
|
|
130
|
+
this.space()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const codePointOrder = (left: string, right: string): number => {
|
|
136
|
+
const a = [...left]
|
|
137
|
+
const b = [...right]
|
|
138
|
+
let index = 0
|
|
139
|
+
while (index < Math.min(a.length, b.length)) {
|
|
140
|
+
const difference = a[index]!.codePointAt(0)! - b[index]!.codePointAt(0)!
|
|
141
|
+
if (difference !== 0) return difference
|
|
142
|
+
index += 1
|
|
143
|
+
}
|
|
144
|
+
return a.length - b.length
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const canonicalArray = (value: ReadonlyArray<unknown>, parents: Set<object>): string => {
|
|
148
|
+
let index = 0
|
|
149
|
+
while (index < value.length) {
|
|
150
|
+
if (!Object.hasOwn(value, index)) throw new Error("sparse array")
|
|
151
|
+
index += 1
|
|
152
|
+
}
|
|
153
|
+
return `[${value.map((item) => canonical(item, parents)).join(",")}]`
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const canonicalObject = (value: object, parents: Set<object>): string => {
|
|
157
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) throw new Error("non-plain object")
|
|
158
|
+
const entries = Object.entries(value).map(([key, item]) => [key.normalize("NFC"), item] as const)
|
|
159
|
+
if (new Set(entries.map(([key]) => key)).size !== entries.length) {
|
|
160
|
+
throw new Error("normalized key collision")
|
|
161
|
+
}
|
|
162
|
+
entries.sort(([left], [right]) => codePointOrder(left, right))
|
|
163
|
+
return `{${entries.map(([key, item]) =>
|
|
164
|
+
`${JSON.stringify(key)}:${canonical(item, parents)}`).join(",")}}`
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const canonical = (value: unknown, parents: Set<object>): string => {
|
|
168
|
+
if (value === null || typeof value === "boolean") return JSON.stringify(value)
|
|
169
|
+
if (typeof value === "string") return JSON.stringify(value.normalize("NFC"))
|
|
170
|
+
if (typeof value === "number") {
|
|
171
|
+
if (!Number.isSafeInteger(value) || Object.is(value, -0)) throw new Error("unsafe number")
|
|
172
|
+
return String(value)
|
|
173
|
+
}
|
|
174
|
+
if (typeof value !== "object") throw new Error("non-JSON value")
|
|
175
|
+
if (parents.has(value)) throw new Error("cyclic value")
|
|
176
|
+
parents.add(value)
|
|
177
|
+
try {
|
|
178
|
+
return Array.isArray(value)
|
|
179
|
+
? canonicalArray(value, parents)
|
|
180
|
+
: canonicalObject(value, parents)
|
|
181
|
+
} finally {
|
|
182
|
+
parents.delete(value)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const frame = (value: Uint8Array): Uint8Array => {
|
|
187
|
+
const result = new Uint8Array(value.length + 4)
|
|
188
|
+
new DataView(result.buffer).setUint32(0, value.length, false)
|
|
189
|
+
result.set(value, 4)
|
|
190
|
+
return result
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export const parseStrictJson = (text: string): Json => new StrictJsonParser(text).parse()
|
|
194
|
+
export const encodeCanonicalJson = (value: unknown): string =>
|
|
195
|
+
`${canonical(value, new Set())}\n`
|
|
196
|
+
export const hashFramed = (domain: string, parts: ReadonlyArray<Uint8Array>): string => {
|
|
197
|
+
const hash = createHash("sha256")
|
|
198
|
+
hash.update(frame(new TextEncoder().encode(domain.normalize("NFC"))))
|
|
199
|
+
parts.forEach((part) => {
|
|
200
|
+
hash.update(frame(part))
|
|
201
|
+
})
|
|
202
|
+
return hash.digest("hex")
|
|
203
|
+
}
|
|
204
|
+
export const hashCanonical = (domain: string, value: unknown): string =>
|
|
205
|
+
hashFramed(domain, [new TextEncoder().encode(encodeCanonicalJson(value))])
|