@astrale-os/sdk 0.6.0-beta.2 → 0.6.0-beta.21
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/README.md +74 -14
- package/dist/application/action/action.d.ts +6 -0
- package/dist/application/action/authoring.d.ts +1 -1
- package/dist/application/action/context.d.ts +17 -8
- package/dist/application/action/define.d.ts +3 -3
- package/dist/application/action/index.d.ts +1 -1
- package/dist/application/define.d.ts +5 -5
- package/dist/application/define.js +13 -13
- package/dist/application/dependency/index.d.ts +1 -1
- package/dist/application/dependency/invoker.d.ts +11 -6
- package/dist/application/domain.d.ts +28 -0
- package/dist/application/index.d.ts +3 -3
- package/dist/application/index.js +1 -1
- package/dist/application/mutation/authoring/properties.d.ts +5 -3
- package/dist/application/mutation/authoring/properties.js +35 -2
- package/dist/application/mutation/authoring/transition.js +4 -1
- package/dist/application/routes/admission.d.ts +2 -2
- package/dist/application/routes/admission.js +1 -1
- package/dist/application/routes/route.d.ts +2 -2
- package/dist/application/runtime/actions.js +3 -0
- package/dist/application/runtime/workflows.d.ts +2 -0
- package/dist/application/runtime/workflows.js +5 -0
- package/dist/application/workflow/authoring.d.ts +3 -2
- package/dist/application/workflow/context.d.ts +8 -2
- package/dist/application/workflow/define.d.ts +3 -3
- package/dist/application/workflow/define.js +19 -3
- package/dist/application/workflow/durable.d.ts +83 -0
- package/dist/application/workflow/index.d.ts +3 -2
- package/dist/application/workflow/runner/inline.js +3 -4
- package/dist/application/workflow/runner/runner.d.ts +2 -2
- package/dist/application/workflow/step/output.d.ts +2 -0
- package/dist/application/workflow/step/output.js +73 -0
- package/dist/application/workflow/workflow.d.ts +12 -0
- package/dist/deployment/adapter/adapter.d.ts +59 -11
- package/dist/deployment/adapter/bundle/bundle.d.ts +36 -0
- package/dist/deployment/adapter/bundle/file.d.ts +10 -0
- package/dist/deployment/adapter/bundle/index.d.ts +2 -0
- package/dist/deployment/adapter/define.d.ts +25 -3
- package/dist/deployment/adapter/define.js +101 -24
- package/dist/deployment/adapter/index.d.ts +6 -3
- package/dist/deployment/adapter/index.js +1 -0
- package/dist/deployment/adapter/legacy/adapter.d.ts +40 -0
- package/dist/deployment/adapter/{deploy → legacy/deploy}/context.d.ts +6 -2
- package/dist/deployment/adapter/legacy/deploy/index.d.ts +2 -0
- package/dist/deployment/adapter/legacy/deploy/index.js +1 -0
- package/dist/deployment/adapter/legacy/deploy/result.d.ts +89 -0
- package/dist/deployment/adapter/legacy/deploy/result.js +1 -0
- package/dist/deployment/adapter/legacy/index.d.ts +24 -0
- package/dist/deployment/adapter/legacy/index.js +1 -0
- package/dist/deployment/adapter/legacy/prepare/artifact.d.ts +43 -0
- package/dist/deployment/adapter/legacy/prepare/artifact.js +1 -0
- package/dist/deployment/adapter/legacy/prepare/context.d.ts +33 -0
- package/dist/deployment/adapter/legacy/prepare/context.js +1 -0
- package/dist/deployment/adapter/legacy/prepare/index.d.ts +2 -0
- package/dist/deployment/adapter/legacy/prepare/index.js +1 -0
- package/dist/deployment/adapter/release/context.d.ts +95 -0
- package/dist/deployment/adapter/release/context.js +1 -0
- package/dist/deployment/adapter/release/index.d.ts +3 -0
- package/dist/deployment/adapter/release/index.js +1 -0
- package/dist/deployment/adapter/release/list.d.ts +53 -0
- package/dist/deployment/adapter/release/list.js +1 -0
- package/dist/deployment/adapter/release/refusal.d.ts +10 -0
- package/dist/deployment/adapter/release/refusal.js +14 -0
- package/dist/deployment/adapter/release/result.d.ts +56 -0
- package/dist/deployment/adapter/release/result.js +1 -0
- package/dist/deployment/address/configuration.d.ts +83 -0
- package/dist/deployment/address/configuration.js +262 -0
- package/dist/deployment/address/fingerprint.d.ts +5 -0
- package/dist/deployment/address/fingerprint.js +27 -0
- package/dist/deployment/address/index.d.ts +5 -0
- package/dist/deployment/address/index.js +5 -0
- package/dist/deployment/address/label.d.ts +42 -0
- package/dist/deployment/address/label.js +80 -0
- package/dist/deployment/address/line.d.ts +29 -0
- package/dist/deployment/address/line.js +53 -0
- package/dist/deployment/address/record.d.ts +52 -0
- package/dist/deployment/address/record.js +104 -0
- package/dist/deployment/address/summary.d.ts +57 -0
- package/dist/deployment/address/summary.js +117 -0
- package/dist/deployment/address/vectors.d.ts +60 -0
- package/dist/deployment/address/vectors.js +517 -0
- package/dist/deployment/build/build.d.ts +2 -2
- package/dist/deployment/build/compile.d.ts +4 -4
- package/dist/deployment/build/compile.js +17 -17
- package/dist/deployment/build/index.d.ts +1 -0
- package/dist/deployment/build/index.js +1 -0
- package/dist/deployment/build/manifest.d.ts +59 -0
- package/dist/deployment/build/manifest.js +118 -0
- package/dist/deployment/build/material.js +2 -2
- package/dist/deployment/build/schema.d.ts +2 -2
- package/dist/deployment/deploy.d.ts +10 -10
- package/dist/deployment/deploy.js +3 -3
- package/dist/deployment/deployment.d.ts +9 -4
- package/dist/deployment/environment.d.ts +6 -0
- package/dist/deployment/environment.js +6 -0
- package/dist/deployment/index.d.ts +4 -4
- package/dist/deployment/index.js +1 -1
- package/dist/deployment/release/addressing.d.ts +9 -1
- package/dist/deployment/release/assemble.d.ts +6 -3
- package/dist/deployment/release/assemble.js +12 -10
- package/dist/deployment/release/index.d.ts +2 -0
- package/dist/deployment/release/index.js +2 -0
- package/dist/deployment/release/legacy/admission.d.ts +3 -0
- package/dist/deployment/release/legacy/admission.js +8 -0
- package/dist/deployment/release/legacy/assemble.d.ts +5 -0
- package/dist/deployment/release/legacy/assemble.js +20 -0
- package/dist/deployment/release/legacy/index.d.ts +35 -0
- package/dist/deployment/release/legacy/index.js +34 -0
- package/dist/deployment/release/legacy/release.d.ts +12 -0
- package/dist/deployment/release/legacy/release.js +1 -0
- package/dist/deployment/release/{publication → legacy}/seal.d.ts +3 -3
- package/dist/deployment/release/legacy/seal.js +17 -0
- package/dist/deployment/release/release.d.ts +16 -5
- package/dist/deployment/release/runtime.d.ts +2 -0
- package/dist/deployment/release/runtime.js +2 -0
- package/dist/deployment/release/seal.d.ts +14 -0
- package/dist/deployment/release/seal.js +22 -0
- package/dist/deployment/release/{publication → served}/callables.d.ts +2 -2
- package/dist/deployment/release/{publication → served}/callables.js +2 -2
- package/dist/deployment/release/served/index.d.ts +12 -0
- package/dist/deployment/release/served/index.js +22 -0
- package/dist/deployment/release/{publication → served}/views.d.ts +2 -2
- package/dist/deployment/runtime/admission.d.ts +2 -2
- package/dist/deployment/runtime/admission.js +5 -5
- package/dist/deployment/verify/index.d.ts +2 -1
- package/dist/deployment/verify/index.js +1 -0
- package/dist/deployment/verify/preflight/artifact.d.ts +1 -1
- package/dist/deployment/verify/preflight/bundle.d.ts +18 -0
- package/dist/deployment/verify/preflight/bundle.js +71 -0
- package/dist/deployment/verify/preflight/index.d.ts +2 -1
- package/dist/deployment/verify/preflight/index.js +1 -0
- package/dist/deployment/verify/preflight/publication.d.ts +2 -2
- package/dist/deployment/verify/preflight/publication.js +4 -3
- package/dist/deployment/verify/readiness/deployment.js +7 -15
- package/dist/deployment/verify/readiness/fetch.d.ts +13 -0
- package/dist/deployment/verify/readiness/fetch.js +26 -0
- package/dist/deployment/verify/readiness/identity.d.ts +3 -6
- package/dist/deployment/verify/readiness/identity.js +3 -3
- package/dist/deployment/verify/readiness/index.d.ts +11 -7
- package/dist/deployment/verify/readiness/index.js +15 -4
- package/dist/deployment/verify/readiness/legacy/index.d.ts +2 -0
- package/dist/deployment/verify/readiness/legacy/index.js +2 -0
- package/dist/deployment/verify/readiness/legacy/publication.d.ts +12 -0
- package/dist/deployment/verify/readiness/legacy/publication.js +23 -0
- package/dist/deployment/verify/readiness/release.d.ts +8 -0
- package/dist/deployment/verify/readiness/release.js +22 -0
- package/dist/execution/identity/authentication.d.ts +23 -2
- package/dist/execution/identity/authentication.js +64 -40
- package/dist/execution/identity/callback.d.ts +16 -15
- package/dist/execution/identity/callback.js +21 -16
- package/dist/execution/identity/delivery.d.ts +11 -4
- package/dist/execution/identity/delivery.js +47 -20
- package/dist/execution/identity/identity.d.ts +18 -3
- package/dist/execution/identity/identity.js +8 -4
- package/dist/execution/identity/jwks.js +57 -12
- package/dist/execution/index.d.ts +4 -2
- package/dist/execution/index.js +2 -1
- package/dist/execution/invocation/admission/authentication.d.ts +3 -8
- package/dist/execution/invocation/admission/authentication.js +10 -24
- package/dist/execution/invocation/admission/authority.d.ts +15 -8
- package/dist/execution/invocation/admission/authority.js +5 -0
- package/dist/execution/invocation/admission/input.d.ts +2 -2
- package/dist/execution/invocation/admission/input.js +16 -2
- package/dist/execution/invocation/dependency/bind.d.ts +1 -1
- package/dist/execution/invocation/dependency/bind.js +35 -14
- package/dist/execution/invocation/dispatch/context.d.ts +2 -1
- package/dist/execution/invocation/dispatch/context.js +1 -1
- package/dist/execution/invocation/invocation.js +58 -16
- package/dist/execution/invocation/result/project.js +41 -1
- package/dist/execution/node/serve.d.ts +2 -2
- package/dist/execution/node/serve.js +1 -1
- package/dist/execution/runtime/index.d.ts +1 -0
- package/dist/execution/runtime/index.js +1 -0
- package/dist/execution/runtime/load.d.ts +3 -3
- package/dist/execution/runtime/load.js +3 -2
- package/dist/execution/runtime/release.d.ts +22 -0
- package/dist/execution/runtime/release.js +14 -0
- package/dist/execution/serve.d.ts +10 -4
- package/dist/execution/serve.js +3 -0
- package/dist/execution/service/create.js +39 -7
- package/dist/execution/service/initialization.d.ts +4 -4
- package/dist/execution/service/initialization.js +23 -14
- package/dist/execution/service/release.d.ts +2 -2
- package/dist/execution/service/release.js +3 -2
- package/dist/execution/service/service.d.ts +15 -5
- package/dist/execution/service/serving/delivery.d.ts +6 -0
- package/dist/execution/service/{publication → serving}/delivery.js +5 -1
- package/dist/execution/service/{publication → serving}/index.d.ts +1 -1
- package/dist/execution/service/serving/installation.d.ts +4 -0
- package/dist/execution/service/serving/installation.js +9 -0
- package/dist/execution/service/serving/legacy/index.d.ts +15 -0
- package/dist/execution/service/serving/legacy/index.js +19 -0
- package/dist/execution/service/serving/source.d.ts +18 -0
- package/dist/execution/service/serving/source.js +19 -0
- package/dist/execution/workflows/discovery.d.ts +14 -0
- package/dist/execution/workflows/discovery.js +151 -0
- package/dist/execution/workflows/engine.d.ts +52 -0
- package/dist/execution/workflows/engine.js +1 -0
- package/dist/execution/workflows/envelope.d.ts +12 -0
- package/dist/execution/workflows/envelope.js +46 -0
- package/dist/execution/workflows/failure.d.ts +11 -0
- package/dist/execution/workflows/failure.js +43 -0
- package/dist/execution/workflows/index.d.ts +4 -0
- package/dist/execution/workflows/index.js +3 -0
- package/dist/execution/workflows/options.d.ts +40 -0
- package/dist/execution/workflows/options.js +83 -0
- package/dist/execution/workflows/receiver.d.ts +22 -0
- package/dist/execution/workflows/receiver.js +99 -0
- package/dist/execution/workflows/route.d.ts +14 -0
- package/dist/execution/workflows/route.js +40 -0
- package/dist/execution/workflows/run.d.ts +22 -0
- package/dist/execution/workflows/run.js +211 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/platform/release/index.d.ts +27 -0
- package/dist/platform/release/index.js +27 -0
- package/dist/platform/schema/index.d.ts +2 -1
- package/dist/platform/schema/property-input.d.ts +15 -0
- package/dist/platform/schema/property-input.js +1 -0
- package/dist/platform/schema/property.d.ts +5 -0
- package/dist/platform/versioning/dependents.d.ts +18 -0
- package/dist/platform/versioning/dependents.js +15 -0
- package/dist/platform/versioning/index.d.ts +5 -0
- package/dist/platform/versioning/index.js +5 -0
- package/dist/platform/versioning/name.d.ts +38 -0
- package/dist/platform/versioning/name.js +58 -0
- package/dist/platform/versioning/reference.d.ts +48 -0
- package/dist/platform/versioning/reference.js +95 -0
- package/dist/platform/versioning/version.d.ts +72 -0
- package/dist/platform/versioning/version.js +98 -0
- package/dist/project/admit.js +2 -2
- package/dist/project/define.d.ts +4 -4
- package/dist/project/define.js +55 -35
- package/dist/project/index.d.ts +1 -1
- package/dist/project/install-command.d.ts +10 -0
- package/dist/project/install-command.js +13 -0
- package/dist/project/project.d.ts +10 -8
- package/dist/testing/dataset/builder.d.ts +3 -3
- package/dist/testing/dataset/define.d.ts +1 -1
- package/dist/testing/load.js +1 -1
- package/dist/tooling/cli/arguments.d.ts +10 -5
- package/dist/tooling/cli/arguments.js +123 -52
- package/dist/tooling/cli/build.d.ts +55 -0
- package/dist/tooling/cli/build.js +77 -0
- package/dist/tooling/cli/bun.d.ts +0 -1
- package/dist/tooling/cli/bun.js +0 -7
- package/dist/tooling/cli/commit.d.ts +35 -0
- package/dist/tooling/cli/commit.js +235 -0
- package/dist/tooling/cli/deploy-mode.d.ts +82 -0
- package/dist/tooling/cli/deploy-mode.js +135 -0
- package/dist/tooling/cli/deploy-result.d.ts +85 -0
- package/dist/tooling/cli/deploy-result.js +64 -0
- package/dist/tooling/cli/diff/declared.d.ts +7 -0
- package/dist/tooling/cli/diff/declared.js +27 -0
- package/dist/tooling/cli/diff/index.d.ts +30 -0
- package/dist/tooling/cli/diff/index.js +58 -0
- package/dist/tooling/cli/diff/render.d.ts +15 -0
- package/dist/tooling/cli/diff/render.js +131 -0
- package/dist/tooling/cli/diff/report.d.ts +88 -0
- package/dist/tooling/cli/diff/report.js +154 -0
- package/dist/tooling/cli/dotenv.d.ts +2 -2
- package/dist/tooling/cli/dotenv.js +3 -33
- package/dist/tooling/cli/help.js +176 -59
- package/dist/tooling/cli/immutable-deployment.d.ts +83 -0
- package/dist/tooling/cli/immutable-deployment.js +135 -0
- package/dist/tooling/cli/index.d.ts +10 -4
- package/dist/tooling/cli/index.js +5 -3
- package/dist/tooling/cli/installed-on.d.ts +83 -0
- package/dist/tooling/cli/installed-on.js +156 -0
- package/dist/tooling/cli/legacy/deploy-result.d.ts +28 -0
- package/dist/tooling/cli/legacy/deploy-result.js +37 -0
- package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +21 -0
- package/dist/tooling/cli/legacy/stable-target-adapter.js +14 -0
- package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +40 -0
- package/dist/tooling/cli/legacy/stable-target-deploy.js +102 -0
- package/dist/tooling/cli/legacy/uploaded-build.d.ts +11 -0
- package/dist/tooling/cli/legacy/uploaded-build.js +22 -0
- package/dist/tooling/cli/list.d.ts +154 -0
- package/dist/tooling/cli/list.js +381 -0
- package/dist/tooling/cli/log.d.ts +5 -0
- package/dist/tooling/cli/log.js +9 -0
- package/dist/tooling/cli/orchestrate.d.ts +0 -6
- package/dist/tooling/cli/orchestrate.js +236 -88
- package/dist/tooling/cli/project.d.ts +3 -3
- package/dist/tooling/cli/publish/index.d.ts +73 -0
- package/dist/tooling/cli/publish/index.js +346 -0
- package/dist/tooling/cli/publish/report.d.ts +49 -0
- package/dist/tooling/cli/publish/report.js +15 -0
- package/dist/tooling/cli/registry/client.d.ts +114 -0
- package/dist/tooling/cli/registry/client.js +346 -0
- package/dist/tooling/cli/registry/error.d.ts +11 -0
- package/dist/tooling/cli/registry/error.js +17 -0
- package/dist/tooling/cli/registry/executable.d.ts +29 -0
- package/dist/tooling/cli/registry/executable.js +90 -0
- package/dist/tooling/cli/registry/index.d.ts +9 -0
- package/dist/tooling/cli/registry/index.js +8 -0
- package/dist/tooling/cli/registry/installations.d.ts +67 -0
- package/dist/tooling/cli/registry/installations.js +108 -0
- package/dist/tooling/cli/registry/process.d.ts +36 -0
- package/dist/tooling/cli/registry/process.js +119 -0
- package/dist/tooling/cli/secrets.d.ts +9 -0
- package/dist/tooling/cli/secrets.js +19 -0
- package/dist/tooling/cli/yank.d.ts +34 -0
- package/dist/tooling/cli/yank.js +32 -0
- package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +1 -1
- package/dist/tooling/linter/implementations/source/callable-requirements.js +10 -10
- package/dist/tooling/linter/implementations/source/dependencies.js +12 -10
- package/dist/tooling/linter/implementations/source/global.js +1 -1
- package/dist/tooling/linter/implementations/source/mutations.js +17 -17
- package/dist/tooling/linter/implementations/source/providers.js +5 -5
- package/dist/tooling/linter/implementations/source/views.js +2 -2
- package/dist/tooling/linter/policy/generated.js +16 -16
- package/dist/tooling/packaging/declarations/ownership.js +1 -1
- package/dist/tooling/packaging/finalize.d.ts +1 -1
- package/dist/tooling/packaging/finalize.js +1 -1
- package/package.json +32 -11
- package/dist/application/application.d.ts +0 -28
- package/dist/deployment/adapter/deploy/index.d.ts +0 -2
- package/dist/deployment/adapter/deploy/result.d.ts +0 -50
- package/dist/deployment/adapter/prepare/artifact.d.ts +0 -33
- package/dist/deployment/adapter/prepare/context.d.ts +0 -23
- package/dist/deployment/adapter/prepare/index.d.ts +0 -2
- package/dist/deployment/release/publication/index.d.ts +0 -6
- package/dist/deployment/release/publication/index.js +0 -6
- package/dist/deployment/release/publication/manifest.d.ts +0 -3
- package/dist/deployment/release/publication/manifest.js +0 -5
- package/dist/deployment/release/publication/requirements.d.ts +0 -3
- package/dist/deployment/release/publication/requirements.js +0 -3
- package/dist/deployment/release/publication/seal.js +0 -39
- package/dist/deployment/verify/readiness/publication.d.ts +0 -11
- package/dist/deployment/verify/readiness/publication.js +0 -41
- package/dist/execution/service/publication/delivery.d.ts +0 -2
- package/dist/execution/service/publication/installation.d.ts +0 -3
- package/dist/execution/service/publication/installation.js +0 -8
- package/dist/execution/service/publication/source.d.ts +0 -3
- package/dist/execution/service/publication/source.js +0 -11
- package/dist/platform/publication/index.d.ts +0 -2
- package/dist/platform/publication/index.js +0 -2
- package/dist/tooling/cli/astrale/authority.d.ts +0 -5
- package/dist/tooling/cli/astrale/authority.js +0 -11
- package/dist/tooling/cli/astrale/executable.d.ts +0 -2
- package/dist/tooling/cli/astrale/executable.js +0 -47
- package/dist/tooling/cli/astrale/failure.d.ts +0 -6
- package/dist/tooling/cli/astrale/failure.js +0 -48
- package/dist/tooling/cli/astrale/instance.d.ts +0 -11
- package/dist/tooling/cli/astrale/instance.js +0 -52
- package/dist/tooling/cli/astrale/process.d.ts +0 -13
- package/dist/tooling/cli/astrale/process.js +0 -94
- package/dist/tooling/cli/astrale/version.d.ts +0 -18
- package/dist/tooling/cli/astrale/version.js +0 -55
- package/dist/tooling/cli/credential.d.ts +0 -2
- package/dist/tooling/cli/credential.js +0 -57
- package/dist/tooling/cli/development/candidate.d.ts +0 -25
- package/dist/tooling/cli/development/candidate.js +0 -176
- package/dist/tooling/cli/development/deployment.d.ts +0 -16
- package/dist/tooling/cli/development/deployment.js +0 -39
- package/dist/tooling/cli/development/develop.d.ts +0 -11
- package/dist/tooling/cli/development/develop.js +0 -243
- package/dist/tooling/cli/development/lease.d.ts +0 -18
- package/dist/tooling/cli/development/lease.js +0 -163
- package/dist/tooling/cli/development/lifecycle.d.ts +0 -9
- package/dist/tooling/cli/development/lifecycle.js +0 -43
- package/dist/tooling/cli/development/project-imports.d.ts +0 -22
- package/dist/tooling/cli/development/project-imports.js +0 -39
- package/dist/tooling/cli/development/project-lock.d.ts +0 -16
- package/dist/tooling/cli/development/project-lock.js +0 -41
- package/dist/tooling/cli/development/rebuild.d.ts +0 -13
- package/dist/tooling/cli/development/rebuild.js +0 -58
- package/dist/tooling/cli/development/release-evidence.d.ts +0 -4
- package/dist/tooling/cli/development/release-evidence.js +0 -10
- package/dist/tooling/cli/development/report.d.ts +0 -6
- package/dist/tooling/cli/development/report.js +0 -14
- package/dist/tooling/cli/development/session-file.d.ts +0 -53
- package/dist/tooling/cli/development/session-file.js +0 -337
- package/dist/tooling/cli/development/source-watch.d.ts +0 -14
- package/dist/tooling/cli/development/source-watch.js +0 -140
- package/dist/tooling/cli/development/sources.d.ts +0 -7
- package/dist/tooling/cli/development/sources.js +0 -48
- package/dist/tooling/cli/development/target-lock.d.ts +0 -16
- package/dist/tooling/cli/development/target-lock.js +0 -68
- package/dist/tooling/cli/development/view.d.ts +0 -28
- package/dist/tooling/cli/development/view.js +0 -151
- package/dist/tooling/cli/environment-release.d.ts +0 -21
- package/dist/tooling/cli/environment-release.js +0 -46
- package/dist/tooling/cli/evidence.d.ts +0 -11
- package/dist/tooling/cli/evidence.js +0 -53
- package/dist/tooling/cli/installation/index.d.ts +0 -2
- package/dist/tooling/cli/installation/index.js +0 -1
- package/dist/tooling/cli/installation/observation.d.ts +0 -10
- package/dist/tooling/cli/installation/observation.js +0 -44
- package/dist/tooling/cli/installation/reconcile.d.ts +0 -32
- package/dist/tooling/cli/installation/reconcile.js +0 -122
- /package/dist/application/{application.js → domain.js} +0 -0
- /package/dist/{deployment/adapter/deploy/context.js → application/workflow/durable.js} +0 -0
- /package/dist/deployment/adapter/{deploy/index.js → bundle/bundle.js} +0 -0
- /package/dist/deployment/adapter/{deploy/result.js → bundle/file.js} +0 -0
- /package/dist/deployment/adapter/{prepare → bundle}/index.js +0 -0
- /package/dist/deployment/adapter/{prepare/artifact.js → legacy/adapter.js} +0 -0
- /package/dist/deployment/adapter/{prepare → legacy/deploy}/context.js +0 -0
- /package/dist/deployment/release/{publication → served}/routes.d.ts +0 -0
- /package/dist/deployment/release/{publication → served}/routes.js +0 -0
- /package/dist/deployment/release/{publication → served}/views.js +0 -0
- /package/dist/execution/service/{publication → serving}/index.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { DeploymentRecordV1 } from '../../address/index.js';
|
|
2
|
+
/** What one operation knows it changed at a provider. */
|
|
3
|
+
export type MutationKnowledge<Evidence = unknown> = {
|
|
4
|
+
readonly kind: 'none';
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'partial';
|
|
7
|
+
readonly evidence?: Evidence;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: 'applied';
|
|
10
|
+
readonly evidence: Evidence;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'unknown';
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* How a deploy left the Environment's secrets on the deployment it made or reused: `bound` to a
|
|
16
|
+
* new deployment, or `updated` or left `unchanged` in place on the reused one.
|
|
17
|
+
*/
|
|
18
|
+
export type DeploymentSecretsState = 'bound' | 'updated' | 'unchanged';
|
|
19
|
+
/**
|
|
20
|
+
* The immutable deployment of one release, ready at its URL.
|
|
21
|
+
*
|
|
22
|
+
* - `created`: a new deployment now serves the release, and the Environment's secrets are `bound`
|
|
23
|
+
* to it.
|
|
24
|
+
* - `reused`: the deployment of this exact release (same label, build and configuration) already
|
|
25
|
+
* existed; its own declared secrets were `updated` or left `unchanged` in place.
|
|
26
|
+
*/
|
|
27
|
+
export interface ReadyReleaseDeployResult {
|
|
28
|
+
readonly status: 'ready';
|
|
29
|
+
readonly state: 'created' | 'reused';
|
|
30
|
+
/** The record the deployment declares, as the host stored it. */
|
|
31
|
+
readonly record: DeploymentRecordV1;
|
|
32
|
+
/** The deployment URL, which is also the issuer of the release it serves. */
|
|
33
|
+
readonly url: string;
|
|
34
|
+
readonly secrets: {
|
|
35
|
+
readonly state: DeploymentSecretsState;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Where a deploy of one release stopped:
|
|
40
|
+
* - `prerequisite`: before any effect at the host (a missing tool, credential or hosting answer);
|
|
41
|
+
* - `provider`: at the host, while it created or reused the deployment;
|
|
42
|
+
* - `readiness`: the deployment exists but did not serve its release before the deadline.
|
|
43
|
+
*/
|
|
44
|
+
export type ReleaseDeploymentPhase = 'prerequisite' | 'provider' | 'readiness';
|
|
45
|
+
/**
|
|
46
|
+
* A deploy of one release that did not reach a ready deployment. Rerunning the same deploy
|
|
47
|
+
* converges: the deployment's label is its content, so a partial or applied deployment is reused.
|
|
48
|
+
*/
|
|
49
|
+
export interface FailedReleaseDeployResult {
|
|
50
|
+
readonly status: 'failed';
|
|
51
|
+
readonly phase: ReleaseDeploymentPhase;
|
|
52
|
+
/** What the host may now hold of the deployment. */
|
|
53
|
+
readonly provider: MutationKnowledge;
|
|
54
|
+
readonly error: Error;
|
|
55
|
+
}
|
|
56
|
+
export type ReleaseDeployResult = ReadyReleaseDeployResult | FailedReleaseDeployResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Digest } from '@astrale-os/kernel-protocol/artifact';
|
|
2
|
+
export declare const FROZEN_CONFIGURATION_FORMAT = "astrale.deployment.configuration";
|
|
3
|
+
export declare const FROZEN_CONFIGURATION_VERSION = 1;
|
|
4
|
+
/**
|
|
5
|
+
* What a deploy freezes into one deployment beside its build: the author's plain variables and the
|
|
6
|
+
* execution settings, defaults resolved, the durable Workflow options it declares, and the services
|
|
7
|
+
* and dispatch namespaces it binds. It names the secrets a deployment binds, never their values,
|
|
8
|
+
* and leaves out what the host derives (the deployment URL, the build digest, the signing key). A
|
|
9
|
+
* changed variable, setting or binding is another configuration, so another address; a rotated
|
|
10
|
+
* secret is not.
|
|
11
|
+
*
|
|
12
|
+
* Its admission is canonical form only. Whether a Worker can run under it stays with the host that
|
|
13
|
+
* binds it: `encodeWorkerSettings` (`@astrale-os/adapter-cloudflare/worker`) refuses settings past
|
|
14
|
+
* the Worker bounds when the host writes `ASTRALE_SETTINGS`, before anything is uploaded, and the
|
|
15
|
+
* host's binding namespace admits the binding names.
|
|
16
|
+
*/
|
|
17
|
+
export interface FrozenConfigurationV1 {
|
|
18
|
+
readonly format: typeof FROZEN_CONFIGURATION_FORMAT;
|
|
19
|
+
readonly version: typeof FROZEN_CONFIGURATION_VERSION;
|
|
20
|
+
/** The author's plain variables, never secrets. */
|
|
21
|
+
readonly vars: Readonly<Record<string, string>>;
|
|
22
|
+
readonly settings: {
|
|
23
|
+
readonly maximumRequestBytes: number;
|
|
24
|
+
readonly invocationTimeoutMs: number;
|
|
25
|
+
readonly tokenExchange: false | {
|
|
26
|
+
readonly maximumLifetimeSeconds: number;
|
|
27
|
+
};
|
|
28
|
+
/** The durable Workflow options the Environment declares; absent when it declares none. */
|
|
29
|
+
readonly durableOptions?: FrozenDurableOptions;
|
|
30
|
+
};
|
|
31
|
+
readonly runtime: {
|
|
32
|
+
readonly compatibilityDate: string;
|
|
33
|
+
/** Sorted, unique. */
|
|
34
|
+
readonly compatibilityFlags: readonly string[];
|
|
35
|
+
};
|
|
36
|
+
readonly bindings: {
|
|
37
|
+
/** Sorted by name, unique; never the `ROUTER` binding, which `router` describes. */
|
|
38
|
+
readonly services: readonly {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly service: string;
|
|
41
|
+
}[];
|
|
42
|
+
/**
|
|
43
|
+
* Dispatch namespaces the deployment binds, sorted by binding name, unique; empty when it binds
|
|
44
|
+
* none. A binding name is a Worker binding name other than `ROUTER`, a namespace a Cloudflare
|
|
45
|
+
* dispatch namespace name. Which namespaces a deployment may bind is the host's to decide.
|
|
46
|
+
*/
|
|
47
|
+
readonly dispatchNamespaces: readonly {
|
|
48
|
+
readonly name: string;
|
|
49
|
+
readonly namespace: string;
|
|
50
|
+
}[];
|
|
51
|
+
/** Names of the secrets the deployment binds, sorted, unique. */
|
|
52
|
+
readonly secrets: readonly string[];
|
|
53
|
+
};
|
|
54
|
+
readonly router: false | {
|
|
55
|
+
readonly service: string;
|
|
56
|
+
readonly hostSuffix: string;
|
|
57
|
+
readonly minLabels: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The durable Workflow options of one deployment, as declared: every field optional, each a
|
|
62
|
+
* positive integer. The SDK's durable serving bounds and defaults them when the Worker runs.
|
|
63
|
+
*/
|
|
64
|
+
export interface FrozenDurableOptions {
|
|
65
|
+
readonly retentionMs?: number;
|
|
66
|
+
readonly retry?: {
|
|
67
|
+
readonly initialIntervalMs?: number;
|
|
68
|
+
readonly maxAttempts?: number;
|
|
69
|
+
readonly maxIntervalMs?: number;
|
|
70
|
+
};
|
|
71
|
+
readonly stepTimeoutMs?: number;
|
|
72
|
+
}
|
|
73
|
+
/** A configuration before its canonical order: lists in any order, no format header. */
|
|
74
|
+
export type FrozenConfigurationInput = Omit<FrozenConfigurationV1, 'format' | 'version'>;
|
|
75
|
+
/** Freeze one deployment configuration in the one canonical order its digest is taken in. */
|
|
76
|
+
export declare function frozenConfiguration(input: FrozenConfigurationInput): FrozenConfigurationV1;
|
|
77
|
+
/**
|
|
78
|
+
* `sha256` of the canonical JSON (RFC 8785) of one exact, canonical frozen configuration. A
|
|
79
|
+
* deployment record keeps it whole; the deployment address keeps 80 bits of it with the build.
|
|
80
|
+
* It refuses a configuration that is not canonical, and checks nothing past that: a configuration
|
|
81
|
+
* it digests may still be one no Worker runs under (see `FrozenConfigurationV1`).
|
|
82
|
+
*/
|
|
83
|
+
export declare function configurationDigest(configuration: FrozenConfigurationV1): Digest;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { identify } from '@astrale-os/kernel-protocol/artifact';
|
|
3
|
+
export const FROZEN_CONFIGURATION_FORMAT = 'astrale.deployment.configuration';
|
|
4
|
+
export const FROZEN_CONFIGURATION_VERSION = 1;
|
|
5
|
+
/** Service binding through which an immutable deployment reaches the instance router. */
|
|
6
|
+
const ROUTER_BINDING = 'ROUTER';
|
|
7
|
+
const MEDIA_TYPE = 'application/vnd.astrale.deployment-configuration+json;v=1';
|
|
8
|
+
const COMPATIBILITY_DATE = /^\d{4}-\d{2}-\d{2}$/u;
|
|
9
|
+
/** A Cloudflare Worker binding name. */
|
|
10
|
+
const BINDING_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/u;
|
|
11
|
+
/** A Cloudflare dispatch namespace name. */
|
|
12
|
+
const NAMESPACE_NAME = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u;
|
|
13
|
+
/** Freeze one deployment configuration in the one canonical order its digest is taken in. */
|
|
14
|
+
export function frozenConfiguration(input) {
|
|
15
|
+
if (input === null || typeof input !== 'object')
|
|
16
|
+
invalid();
|
|
17
|
+
const { settings, runtime, bindings } = input;
|
|
18
|
+
if (settings === null || typeof settings !== 'object')
|
|
19
|
+
invalid();
|
|
20
|
+
if (runtime === null || typeof runtime !== 'object')
|
|
21
|
+
invalid();
|
|
22
|
+
if (bindings === null || typeof bindings !== 'object')
|
|
23
|
+
invalid();
|
|
24
|
+
if (!Array.isArray(runtime.compatibilityFlags))
|
|
25
|
+
invalid();
|
|
26
|
+
if (!Array.isArray(bindings.services) ||
|
|
27
|
+
!Array.isArray(bindings.dispatchNamespaces) ||
|
|
28
|
+
!Array.isArray(bindings.secrets)) {
|
|
29
|
+
invalid();
|
|
30
|
+
}
|
|
31
|
+
return admit({
|
|
32
|
+
format: FROZEN_CONFIGURATION_FORMAT,
|
|
33
|
+
version: FROZEN_CONFIGURATION_VERSION,
|
|
34
|
+
vars: input.vars,
|
|
35
|
+
settings: declaredSettings(settings),
|
|
36
|
+
runtime: {
|
|
37
|
+
compatibilityDate: runtime.compatibilityDate,
|
|
38
|
+
compatibilityFlags: [...runtime.compatibilityFlags].sort(compare),
|
|
39
|
+
},
|
|
40
|
+
bindings: {
|
|
41
|
+
services: [...bindings.services].sort(byName),
|
|
42
|
+
dispatchNamespaces: [...bindings.dispatchNamespaces].sort(byName),
|
|
43
|
+
secrets: [...bindings.secrets].sort(compare),
|
|
44
|
+
},
|
|
45
|
+
router: input.router,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `sha256` of the canonical JSON (RFC 8785) of one exact, canonical frozen configuration. A
|
|
50
|
+
* deployment record keeps it whole; the deployment address keeps 80 bits of it with the build.
|
|
51
|
+
* It refuses a configuration that is not canonical, and checks nothing past that: a configuration
|
|
52
|
+
* it digests may still be one no Worker runs under (see `FrozenConfigurationV1`).
|
|
53
|
+
*/
|
|
54
|
+
export function configurationDigest(configuration) {
|
|
55
|
+
return identify(json.encode(admit(configuration)), MEDIA_TYPE).digest;
|
|
56
|
+
}
|
|
57
|
+
function admit(input) {
|
|
58
|
+
exact(input, ['format', 'version', 'vars', 'settings', 'runtime', 'bindings', 'router']);
|
|
59
|
+
if (input.format !== FROZEN_CONFIGURATION_FORMAT ||
|
|
60
|
+
input.version !== FROZEN_CONFIGURATION_VERSION) {
|
|
61
|
+
invalid();
|
|
62
|
+
}
|
|
63
|
+
const vars = variables(input.vars);
|
|
64
|
+
exact(input.settings, ['maximumRequestBytes', 'invocationTimeoutMs', 'tokenExchange'], ['durableOptions']);
|
|
65
|
+
const { tokenExchange } = input.settings;
|
|
66
|
+
if (tokenExchange !== false)
|
|
67
|
+
exact(tokenExchange, ['maximumLifetimeSeconds']);
|
|
68
|
+
exact(input.runtime, ['compatibilityDate', 'compatibilityFlags']);
|
|
69
|
+
const { compatibilityDate } = input.runtime;
|
|
70
|
+
if (!isDate(compatibilityDate))
|
|
71
|
+
invalid();
|
|
72
|
+
exact(input.bindings, ['services', 'dispatchNamespaces', 'secrets']);
|
|
73
|
+
if (!Array.isArray(input.bindings.services))
|
|
74
|
+
invalid();
|
|
75
|
+
if (!Array.isArray(input.bindings.dispatchNamespaces))
|
|
76
|
+
invalid();
|
|
77
|
+
const services = input.bindings.services.map((binding) => {
|
|
78
|
+
exact(binding, ['name', 'service']);
|
|
79
|
+
if (binding.name === ROUTER_BINDING) {
|
|
80
|
+
throw new TypeError('Frozen configuration service bindings never include ROUTER.');
|
|
81
|
+
}
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
name: stable(binding.name, 'Service binding name'),
|
|
84
|
+
service: stable(binding.service, 'Service binding target'),
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
ordered(services.map((binding) => binding.name), 'Service bindings');
|
|
88
|
+
const dispatchNamespaces = input.bindings.dispatchNamespaces.map((binding) => {
|
|
89
|
+
exact(binding, ['name', 'namespace']);
|
|
90
|
+
if (binding.name === ROUTER_BINDING) {
|
|
91
|
+
throw new TypeError('Frozen configuration dispatch namespace bindings never include ROUTER.');
|
|
92
|
+
}
|
|
93
|
+
if (typeof binding.name !== 'string' || !BINDING_NAME.test(binding.name)) {
|
|
94
|
+
throw new TypeError('Dispatch namespace binding name must be a Worker binding name.');
|
|
95
|
+
}
|
|
96
|
+
if (typeof binding.namespace !== 'string' || !NAMESPACE_NAME.test(binding.namespace)) {
|
|
97
|
+
throw new TypeError('Dispatch namespace must be a Cloudflare dispatch namespace name.');
|
|
98
|
+
}
|
|
99
|
+
return Object.freeze({ name: binding.name, namespace: binding.namespace });
|
|
100
|
+
});
|
|
101
|
+
ordered(dispatchNamespaces.map((binding) => binding.name), 'Dispatch namespace bindings');
|
|
102
|
+
const secrets = names(input.bindings.secrets, 'Secret names');
|
|
103
|
+
const router = input.router === false ? false : routerOf(input.router);
|
|
104
|
+
const bound = [
|
|
105
|
+
...Object.keys(vars),
|
|
106
|
+
...services.map((binding) => binding.name),
|
|
107
|
+
...dispatchNamespaces.map((binding) => binding.name),
|
|
108
|
+
...secrets,
|
|
109
|
+
...(router === false ? [] : [ROUTER_BINDING]),
|
|
110
|
+
];
|
|
111
|
+
if (new Set(bound).size !== bound.length) {
|
|
112
|
+
throw new TypeError('Frozen configuration binding names must be unique.');
|
|
113
|
+
}
|
|
114
|
+
return Object.freeze({
|
|
115
|
+
format: FROZEN_CONFIGURATION_FORMAT,
|
|
116
|
+
version: FROZEN_CONFIGURATION_VERSION,
|
|
117
|
+
vars,
|
|
118
|
+
settings: Object.freeze({
|
|
119
|
+
maximumRequestBytes: positive(input.settings.maximumRequestBytes),
|
|
120
|
+
invocationTimeoutMs: positive(input.settings.invocationTimeoutMs),
|
|
121
|
+
tokenExchange: tokenExchange === false
|
|
122
|
+
? false
|
|
123
|
+
: Object.freeze({
|
|
124
|
+
maximumLifetimeSeconds: positive(tokenExchange.maximumLifetimeSeconds),
|
|
125
|
+
}),
|
|
126
|
+
...(Object.hasOwn(input.settings, 'durableOptions')
|
|
127
|
+
? { durableOptions: durableOptionsOf(input.settings.durableOptions) }
|
|
128
|
+
: {}),
|
|
129
|
+
}),
|
|
130
|
+
runtime: Object.freeze({
|
|
131
|
+
compatibilityDate,
|
|
132
|
+
compatibilityFlags: names(input.runtime.compatibilityFlags, 'Compatibility flags'),
|
|
133
|
+
}),
|
|
134
|
+
bindings: Object.freeze({
|
|
135
|
+
services: Object.freeze(services),
|
|
136
|
+
dispatchNamespaces: Object.freeze(dispatchNamespaces),
|
|
137
|
+
secrets,
|
|
138
|
+
}),
|
|
139
|
+
router,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/** A calendar date written `YYYY-MM-DD`, as a Worker compatibility date is. */
|
|
143
|
+
function isDate(input) {
|
|
144
|
+
if (typeof input !== 'string' || !COMPATIBILITY_DATE.test(input))
|
|
145
|
+
return false;
|
|
146
|
+
const time = Date.parse(`${input}T00:00:00Z`);
|
|
147
|
+
return !Number.isNaN(time) && new Date(time).toISOString().slice(0, 10) === input;
|
|
148
|
+
}
|
|
149
|
+
function variables(input) {
|
|
150
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input))
|
|
151
|
+
invalid();
|
|
152
|
+
const entries = Reflect.ownKeys(input).map((name) => {
|
|
153
|
+
if (typeof name !== 'string')
|
|
154
|
+
invalid();
|
|
155
|
+
const value = input[name];
|
|
156
|
+
if (typeof value !== 'string')
|
|
157
|
+
invalid();
|
|
158
|
+
return [stable(name, 'Variable name'), value];
|
|
159
|
+
});
|
|
160
|
+
return Object.freeze(Object.fromEntries(entries));
|
|
161
|
+
}
|
|
162
|
+
/** The settings as written, without a `durableOptions` or durable field left `undefined`. */
|
|
163
|
+
function declaredSettings(settings) {
|
|
164
|
+
const { durableOptions, ...rest } = settings;
|
|
165
|
+
if (durableOptions === undefined)
|
|
166
|
+
return rest;
|
|
167
|
+
const { retry, ...options } = defined(durableOptions);
|
|
168
|
+
return {
|
|
169
|
+
...rest,
|
|
170
|
+
durableOptions: {
|
|
171
|
+
...options,
|
|
172
|
+
...(retry === undefined ? {} : { retry: defined(retry) }),
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function defined(input) {
|
|
177
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input))
|
|
178
|
+
invalid();
|
|
179
|
+
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
180
|
+
}
|
|
181
|
+
/** The declared durable options in their canonical form: sorted keys, positive integers. */
|
|
182
|
+
function durableOptionsOf(input) {
|
|
183
|
+
exact(input, [], ['retentionMs', 'retry', 'stepTimeoutMs']);
|
|
184
|
+
const options = input;
|
|
185
|
+
let retry;
|
|
186
|
+
if (Object.hasOwn(options, 'retry')) {
|
|
187
|
+
exact(options.retry, [], ['initialIntervalMs', 'maxAttempts', 'maxIntervalMs']);
|
|
188
|
+
const value = options.retry;
|
|
189
|
+
retry = Object.freeze({
|
|
190
|
+
...optional(value, 'initialIntervalMs'),
|
|
191
|
+
...optional(value, 'maxAttempts'),
|
|
192
|
+
...optional(value, 'maxIntervalMs'),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return Object.freeze({
|
|
196
|
+
...optional(options, 'retentionMs'),
|
|
197
|
+
...(retry === undefined ? {} : { retry }),
|
|
198
|
+
...optional(options, 'stepTimeoutMs'),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function optional(input, key) {
|
|
202
|
+
return Object.hasOwn(input, key)
|
|
203
|
+
? { [key]: positive(input[key]) }
|
|
204
|
+
: {};
|
|
205
|
+
}
|
|
206
|
+
function routerOf(input) {
|
|
207
|
+
exact(input, ['service', 'hostSuffix', 'minLabels']);
|
|
208
|
+
const router = input;
|
|
209
|
+
if (typeof router.hostSuffix !== 'string')
|
|
210
|
+
invalid();
|
|
211
|
+
if (!Number.isSafeInteger(router.minLabels) || router.minLabels < 0)
|
|
212
|
+
invalid();
|
|
213
|
+
return Object.freeze({
|
|
214
|
+
service: stable(router.service, 'Router service'),
|
|
215
|
+
hostSuffix: router.hostSuffix,
|
|
216
|
+
minLabels: router.minLabels,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function names(input, label) {
|
|
220
|
+
if (!Array.isArray(input))
|
|
221
|
+
invalid();
|
|
222
|
+
const values = input.map((value) => stable(value, label));
|
|
223
|
+
ordered(values, label);
|
|
224
|
+
return Object.freeze(values);
|
|
225
|
+
}
|
|
226
|
+
function ordered(values, label) {
|
|
227
|
+
for (let index = 1; index < values.length; index += 1) {
|
|
228
|
+
if (compare(values[index - 1], values[index]) >= 0) {
|
|
229
|
+
throw new TypeError(`${label} must be unique and sorted.`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/** Exactly `keys`, plus any of `optional`, and nothing else. */
|
|
234
|
+
function exact(input, keys, optionalKeys = []) {
|
|
235
|
+
if (input === null ||
|
|
236
|
+
typeof input !== 'object' ||
|
|
237
|
+
Array.isArray(input) ||
|
|
238
|
+
Reflect.ownKeys(input).some((key) => typeof key !== 'string' || (!keys.includes(key) && !optionalKeys.includes(key))) ||
|
|
239
|
+
keys.some((key) => !Object.hasOwn(input, key))) {
|
|
240
|
+
invalid();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function positive(input) {
|
|
244
|
+
if (!Number.isSafeInteger(input) || input < 1)
|
|
245
|
+
invalid();
|
|
246
|
+
return input;
|
|
247
|
+
}
|
|
248
|
+
function stable(input, label) {
|
|
249
|
+
if (typeof input !== 'string' || input.length === 0 || input.trim() !== input) {
|
|
250
|
+
throw new TypeError(`${label} must be non-empty stable text.`);
|
|
251
|
+
}
|
|
252
|
+
return input;
|
|
253
|
+
}
|
|
254
|
+
function byName(left, right) {
|
|
255
|
+
return compare(String(left?.name), String(right?.name));
|
|
256
|
+
}
|
|
257
|
+
function compare(left, right) {
|
|
258
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
259
|
+
}
|
|
260
|
+
function invalid() {
|
|
261
|
+
throw new TypeError('Frozen configuration is invalid.');
|
|
262
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first 80 bits of `sha256(utf8(parts[0]) ‖ 0x00 ‖ utf8(parts[1]) ‖ …)` as 16 characters of
|
|
3
|
+
* RFC 4648 base32, lower case and unpadded. Callers admit every part first, so no part holds 0x00.
|
|
4
|
+
*/
|
|
5
|
+
export declare function first80(...parts: readonly string[]): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { identify } from '@astrale-os/kernel-protocol/artifact';
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
const ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
4
|
+
const PREIMAGE_MEDIA_TYPE = 'application/octet-stream';
|
|
5
|
+
/**
|
|
6
|
+
* The first 80 bits of `sha256(utf8(parts[0]) ‖ 0x00 ‖ utf8(parts[1]) ‖ …)` as 16 characters of
|
|
7
|
+
* RFC 4648 base32, lower case and unpadded. Callers admit every part first, so no part holds 0x00.
|
|
8
|
+
*/
|
|
9
|
+
export function first80(...parts) {
|
|
10
|
+
const encoded = parts.map((part) => encoder.encode(part));
|
|
11
|
+
const preimage = new Uint8Array(encoded.reduce((size, part) => size + part.byteLength, encoded.length - 1));
|
|
12
|
+
let offset = 0;
|
|
13
|
+
for (const [index, part] of encoded.entries()) {
|
|
14
|
+
if (index > 0)
|
|
15
|
+
offset += 1;
|
|
16
|
+
preimage.set(part, offset);
|
|
17
|
+
offset += part.byteLength;
|
|
18
|
+
}
|
|
19
|
+
// `sha256:` then 20 hexadecimal digits: the first 10 bytes of the hash.
|
|
20
|
+
let bits = BigInt(`0x${identify(preimage, PREIMAGE_MEDIA_TYPE).digest.slice(7, 27)}`);
|
|
21
|
+
let text = '';
|
|
22
|
+
for (let index = 0; index < 16; index += 1) {
|
|
23
|
+
text = ALPHABET[Number(bits & 31n)] + text;
|
|
24
|
+
bits >>= 5n;
|
|
25
|
+
}
|
|
26
|
+
return text;
|
|
27
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { configurationDigest, frozenConfiguration, FROZEN_CONFIGURATION_FORMAT, FROZEN_CONFIGURATION_VERSION, type FrozenConfigurationInput, type FrozenDurableOptions, type FrozenConfigurationV1, } from './configuration.js';
|
|
2
|
+
export { DEPLOYMENT_LABEL, deploymentContent, deploymentLabel, deploymentUrl, parseDeploymentLabel, type DeploymentLabelParts, } from './label.js';
|
|
3
|
+
export { deploymentLine, lineFingerprint, readablePart, type DeploymentLineInput, type LineAddressing, } from './line.js';
|
|
4
|
+
export { acceptDeploymentRecord, DEPLOYMENT_RECORD_FORMAT, DEPLOYMENT_RECORD_VERSION, type DeploymentCommitV1, type DeploymentRecordV1, } from './record.js';
|
|
5
|
+
export { acceptPlatformDeploymentSummary, encodePlatformDeploymentSummary, PLATFORM_OWNER, type DeploymentSummaryV1, type PlatformDeploymentSummaryV1, } from './summary.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { configurationDigest, frozenConfiguration, FROZEN_CONFIGURATION_FORMAT, FROZEN_CONFIGURATION_VERSION, } from './configuration.js';
|
|
2
|
+
export { DEPLOYMENT_LABEL, deploymentContent, deploymentLabel, deploymentUrl, parseDeploymentLabel, } from './label.js';
|
|
3
|
+
export { deploymentLine, lineFingerprint, readablePart, } from './line.js';
|
|
4
|
+
export { acceptDeploymentRecord, DEPLOYMENT_RECORD_FORMAT, DEPLOYMENT_RECORD_VERSION, } from './record.js';
|
|
5
|
+
export { acceptPlatformDeploymentSummary, encodePlatformDeploymentSummary, PLATFORM_OWNER, } from './summary.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Digest } from '@astrale-os/kernel-protocol/artifact';
|
|
2
|
+
import type { BuildDigest } from '../build/manifest.js';
|
|
3
|
+
import type { FrozenConfigurationV1 } from './configuration.js';
|
|
4
|
+
/**
|
|
5
|
+
* Every deployment label: an optional readable part, the 16-character line fingerprint and the
|
|
6
|
+
* 16-character content, both lower-case base32. A legacy provider name (a UUID, a stable Worker
|
|
7
|
+
* name) never matches, so one dispatcher tells the two apart by the label alone. The pattern
|
|
8
|
+
* bounds no length; `parseDeploymentLabel` also refuses a label longer than the 57 characters
|
|
9
|
+
* `deploymentLabel` can produce.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEPLOYMENT_LABEL: RegExp;
|
|
12
|
+
export interface DeploymentLabelParts {
|
|
13
|
+
readonly line: string;
|
|
14
|
+
readonly fingerprint: string;
|
|
15
|
+
readonly content: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The 16-character content of one deployment: the first 80 bits of
|
|
19
|
+
* `sha256(utf8(buildDigest) ‖ 0x00 ‖ utf8(configurationDigest(configuration)))` in lower-case
|
|
20
|
+
* base32. It covers the build and the frozen configuration, never a secret: one address serves
|
|
21
|
+
* one release, and a changed variable gives another address.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deploymentContent(build: BuildDigest, configuration: FrozenConfigurationV1): string;
|
|
24
|
+
/** The content of a build and a full configuration digest, as a deployment record holds them. */
|
|
25
|
+
export declare function contentOf(build: BuildDigest, configuration: Digest): string;
|
|
26
|
+
/**
|
|
27
|
+
* The DNS label of one deployment, `<line>-<content>`: at most 57 characters, below the 63 of a
|
|
28
|
+
* DNS label.
|
|
29
|
+
*/
|
|
30
|
+
export declare function deploymentLabel(line: string, content: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* The URL of one deployment under the host's routing domain. It is the issuer of the release the
|
|
33
|
+
* deployment serves, and no other deployment ever answers at it. The label is admitted as
|
|
34
|
+
* `parseDeploymentLabel` admits it, so its host never holds a label longer than 57 characters.
|
|
35
|
+
*/
|
|
36
|
+
export declare function deploymentUrl(label: string, routingDomain: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Split a deployment label into its line, the line fingerprint and its content. It admits exactly
|
|
39
|
+
* the labels `deploymentLabel` produces: `DEPLOYMENT_LABEL`, and at most 57 characters, so a line
|
|
40
|
+
* of at most 40.
|
|
41
|
+
*/
|
|
42
|
+
export declare function parseDeploymentLabel(label: string): DeploymentLabelParts;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { configurationDigest } from './configuration.js';
|
|
2
|
+
import { first80 } from './fingerprint.js';
|
|
3
|
+
/**
|
|
4
|
+
* Every deployment label: an optional readable part, the 16-character line fingerprint and the
|
|
5
|
+
* 16-character content, both lower-case base32. A legacy provider name (a UUID, a stable Worker
|
|
6
|
+
* name) never matches, so one dispatcher tells the two apart by the label alone. The pattern
|
|
7
|
+
* bounds no length; `parseDeploymentLabel` also refuses a label longer than the 57 characters
|
|
8
|
+
* `deploymentLabel` can produce.
|
|
9
|
+
*/
|
|
10
|
+
export const DEPLOYMENT_LABEL = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*-)?[a-z2-7]{16}-[a-z2-7]{16}$/u;
|
|
11
|
+
const LINE = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*-)?[a-z2-7]{16}$/u;
|
|
12
|
+
const CONTENT = /^[a-z2-7]{16}$/u;
|
|
13
|
+
const DIGEST = /^sha256:[0-9a-f]{64}$/u;
|
|
14
|
+
const DNS_NAME = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/u;
|
|
15
|
+
const MAXIMUM_LINE_LENGTH = 40;
|
|
16
|
+
/** A line, a dash and the content: below the 63 characters of a DNS label. */
|
|
17
|
+
const MAXIMUM_LABEL_LENGTH = MAXIMUM_LINE_LENGTH + 17;
|
|
18
|
+
const MAXIMUM_HOST_LENGTH = 253;
|
|
19
|
+
/**
|
|
20
|
+
* The 16-character content of one deployment: the first 80 bits of
|
|
21
|
+
* `sha256(utf8(buildDigest) ‖ 0x00 ‖ utf8(configurationDigest(configuration)))` in lower-case
|
|
22
|
+
* base32. It covers the build and the frozen configuration, never a secret: one address serves
|
|
23
|
+
* one release, and a changed variable gives another address.
|
|
24
|
+
*/
|
|
25
|
+
export function deploymentContent(build, configuration) {
|
|
26
|
+
return contentOf(build, configurationDigest(configuration));
|
|
27
|
+
}
|
|
28
|
+
/** The content of a build and a full configuration digest, as a deployment record holds them. */
|
|
29
|
+
export function contentOf(build, configuration) {
|
|
30
|
+
return first80(digest(build, 'Build digest'), digest(configuration, 'Configuration digest'));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The DNS label of one deployment, `<line>-<content>`: at most 57 characters, below the 63 of a
|
|
34
|
+
* DNS label.
|
|
35
|
+
*/
|
|
36
|
+
export function deploymentLabel(line, content) {
|
|
37
|
+
if (typeof line !== 'string' || line.length > MAXIMUM_LINE_LENGTH || !LINE.test(line)) {
|
|
38
|
+
throw new TypeError('Deployment line is invalid.');
|
|
39
|
+
}
|
|
40
|
+
if (typeof content !== 'string' || !CONTENT.test(content)) {
|
|
41
|
+
throw new TypeError('Deployment content is invalid.');
|
|
42
|
+
}
|
|
43
|
+
return `${line}-${content}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The URL of one deployment under the host's routing domain. It is the issuer of the release the
|
|
47
|
+
* deployment serves, and no other deployment ever answers at it. The label is admitted as
|
|
48
|
+
* `parseDeploymentLabel` admits it, so its host never holds a label longer than 57 characters.
|
|
49
|
+
*/
|
|
50
|
+
export function deploymentUrl(label, routingDomain) {
|
|
51
|
+
parseDeploymentLabel(label);
|
|
52
|
+
if (typeof routingDomain !== 'string' || !DNS_NAME.test(routingDomain)) {
|
|
53
|
+
throw new TypeError('Deployment routing domain must be a lower-case DNS name.');
|
|
54
|
+
}
|
|
55
|
+
const host = `${label}.${routingDomain}`;
|
|
56
|
+
if (host.length > MAXIMUM_HOST_LENGTH) {
|
|
57
|
+
throw new TypeError('Deployment host exceeds the length of a DNS name.');
|
|
58
|
+
}
|
|
59
|
+
return `https://${host}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Split a deployment label into its line, the line fingerprint and its content. It admits exactly
|
|
63
|
+
* the labels `deploymentLabel` produces: `DEPLOYMENT_LABEL`, and at most 57 characters, so a line
|
|
64
|
+
* of at most 40.
|
|
65
|
+
*/
|
|
66
|
+
export function parseDeploymentLabel(label) {
|
|
67
|
+
if (typeof label !== 'string' ||
|
|
68
|
+
label.length > MAXIMUM_LABEL_LENGTH ||
|
|
69
|
+
!DEPLOYMENT_LABEL.test(label)) {
|
|
70
|
+
throw new TypeError('Deployment label is invalid.');
|
|
71
|
+
}
|
|
72
|
+
const line = label.slice(0, -17);
|
|
73
|
+
return Object.freeze({ line, fingerprint: line.slice(-16), content: label.slice(-16) });
|
|
74
|
+
}
|
|
75
|
+
function digest(input, label) {
|
|
76
|
+
if (typeof input !== 'string' || !DIGEST.test(input)) {
|
|
77
|
+
throw new TypeError(`${label} is invalid.`);
|
|
78
|
+
}
|
|
79
|
+
return input;
|
|
80
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a line reads. Platform lines are `readable` (`agencies-staging-354iwg4avm6wdmrs`); tenant
|
|
3
|
+
* lines are `opaque`, their fingerprint alone, so a hosted address says nothing of whose code it
|
|
4
|
+
* serves. Both derive from the same inputs, never from stored state.
|
|
5
|
+
*/
|
|
6
|
+
export type LineAddressing = 'readable' | 'opaque';
|
|
7
|
+
export interface DeploymentLineInput {
|
|
8
|
+
readonly origin: string;
|
|
9
|
+
readonly environment: string;
|
|
10
|
+
readonly addressing: LineAddressing;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The 16-character fingerprint of the line of `(origin, environment)`: the first 80 bits of
|
|
14
|
+
* `sha256(utf8(origin) ‖ 0x00 ‖ utf8(environment))` in lower-case base32. It alone makes a line
|
|
15
|
+
* unique; the readable part in front of it is cosmetic.
|
|
16
|
+
*/
|
|
17
|
+
export declare function lineFingerprint(origin: string, environment: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* The cosmetic part of a readable line: the first label of the origin (12 characters at most) and
|
|
20
|
+
* the environment (10 at most), lower case, each run of characters outside `[a-z0-9]` replaced by
|
|
21
|
+
* one dash and dashes removed at both edges. Neither part is ever empty: an origin label and an
|
|
22
|
+
* environment name both start with a letter or a digit.
|
|
23
|
+
*/
|
|
24
|
+
export declare function readablePart(origin: string, environment: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* The line every deployment of one origin in one environment shares: `<readable>-<fingerprint>`
|
|
27
|
+
* when readable, the fingerprint alone when opaque. At most 40 characters.
|
|
28
|
+
*/
|
|
29
|
+
export declare function deploymentLine(input: DeploymentLineInput): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { patterns } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { ENVIRONMENT_NAME } from '../environment.js';
|
|
3
|
+
import { first80 } from './fingerprint.js';
|
|
4
|
+
/**
|
|
5
|
+
* The 16-character fingerprint of the line of `(origin, environment)`: the first 80 bits of
|
|
6
|
+
* `sha256(utf8(origin) ‖ 0x00 ‖ utf8(environment))` in lower-case base32. It alone makes a line
|
|
7
|
+
* unique; the readable part in front of it is cosmetic.
|
|
8
|
+
*/
|
|
9
|
+
export function lineFingerprint(origin, environment) {
|
|
10
|
+
admitLine(origin, environment);
|
|
11
|
+
return first80(origin, environment);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The cosmetic part of a readable line: the first label of the origin (12 characters at most) and
|
|
15
|
+
* the environment (10 at most), lower case, each run of characters outside `[a-z0-9]` replaced by
|
|
16
|
+
* one dash and dashes removed at both edges. Neither part is ever empty: an origin label and an
|
|
17
|
+
* environment name both start with a letter or a digit.
|
|
18
|
+
*/
|
|
19
|
+
export function readablePart(origin, environment) {
|
|
20
|
+
admitLine(origin, environment);
|
|
21
|
+
return `${normalize(origin.split('.')[0], 12)}-${normalize(environment, 10)}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The line every deployment of one origin in one environment shares: `<readable>-<fingerprint>`
|
|
25
|
+
* when readable, the fingerprint alone when opaque. At most 40 characters.
|
|
26
|
+
*/
|
|
27
|
+
export function deploymentLine(input) {
|
|
28
|
+
if (input === null || typeof input !== 'object') {
|
|
29
|
+
throw new TypeError('Deployment line input is invalid.');
|
|
30
|
+
}
|
|
31
|
+
const fingerprint = lineFingerprint(input.origin, input.environment);
|
|
32
|
+
if (input.addressing === 'opaque')
|
|
33
|
+
return fingerprint;
|
|
34
|
+
if (input.addressing !== 'readable') {
|
|
35
|
+
throw new TypeError('Deployment line addressing must be readable or opaque.');
|
|
36
|
+
}
|
|
37
|
+
return `${readablePart(input.origin, input.environment)}-${fingerprint}`;
|
|
38
|
+
}
|
|
39
|
+
function admitLine(origin, environment) {
|
|
40
|
+
if (typeof origin !== 'string' || !patterns.origin.test(origin)) {
|
|
41
|
+
throw new TypeError('Deployment origin must be a Domain origin.');
|
|
42
|
+
}
|
|
43
|
+
if (typeof environment !== 'string' || !ENVIRONMENT_NAME.test(environment)) {
|
|
44
|
+
throw new TypeError('Deployment environment must be a project environment name.');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function normalize(input, length) {
|
|
48
|
+
return input
|
|
49
|
+
.toLowerCase()
|
|
50
|
+
.replace(/[^a-z0-9]+/gu, '-')
|
|
51
|
+
.slice(0, length)
|
|
52
|
+
.replace(/^-+|-+$/gu, '');
|
|
53
|
+
}
|