@pithy-sh/core 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/address/address.d.ts +57 -0
- package/dist/address/address.d.ts.map +1 -0
- package/dist/address/address.js +71 -0
- package/dist/audit/auditEvent.d.ts +89 -0
- package/dist/audit/auditEvent.d.ts.map +1 -0
- package/dist/audit/auditEvent.js +69 -0
- package/dist/audit/recorder.d.ts +18 -0
- package/dist/audit/recorder.d.ts.map +1 -0
- package/dist/audit/recorder.js +8 -0
- package/dist/capability/bindings.d.ts +62 -0
- package/dist/capability/bindings.d.ts.map +1 -0
- package/dist/capability/bindings.js +97 -0
- package/dist/capability/capability.d.ts +501 -0
- package/dist/capability/capability.d.ts.map +1 -0
- package/dist/capability/capability.js +16 -0
- package/dist/capability/client.d.ts +70 -0
- package/dist/capability/client.d.ts.map +1 -0
- package/dist/capability/client.js +86 -0
- package/dist/capability/compose.d.ts +25 -0
- package/dist/capability/compose.d.ts.map +1 -0
- package/dist/capability/compose.js +54 -0
- package/dist/capability/composition.d.ts +26 -0
- package/dist/capability/composition.d.ts.map +1 -0
- package/dist/capability/composition.js +84 -0
- package/dist/capability/config.d.ts +7 -0
- package/dist/capability/config.d.ts.map +1 -0
- package/dist/capability/config.js +14 -0
- package/dist/capability/devSecret.d.ts +32 -0
- package/dist/capability/devSecret.d.ts.map +1 -0
- package/dist/capability/devSecret.js +28 -0
- package/dist/capability/manifest.d.ts +298 -0
- package/dist/capability/manifest.d.ts.map +1 -0
- package/dist/capability/manifest.js +356 -0
- package/dist/capability/secretOrigin.d.ts +121 -0
- package/dist/capability/secretOrigin.d.ts.map +1 -0
- package/dist/capability/secretOrigin.js +134 -0
- package/dist/capability/settings.d.ts +119 -0
- package/dist/capability/settings.d.ts.map +1 -0
- package/dist/capability/settings.js +66 -0
- package/dist/capability/validateBindings.d.ts +4 -0
- package/dist/capability/validateBindings.d.ts.map +1 -0
- package/dist/capability/validateBindings.js +34 -0
- package/dist/capability/vanishingKey.d.ts +31 -0
- package/dist/capability/vanishingKey.d.ts.map +1 -0
- package/dist/capability/vanishingKey.js +79 -0
- package/dist/controlPlane/audit/actions.d.ts +70 -0
- package/dist/controlPlane/audit/actions.d.ts.map +1 -0
- package/dist/controlPlane/audit/actions.js +76 -0
- package/dist/controlPlane/capability.d.ts +47 -0
- package/dist/controlPlane/capability.d.ts.map +1 -0
- package/dist/controlPlane/capability.js +138 -0
- package/dist/controlPlane/config/config.d.ts +19 -0
- package/dist/controlPlane/config/config.d.ts.map +1 -0
- package/dist/controlPlane/config/config.js +85 -0
- package/dist/controlPlane/context.d.ts +27 -0
- package/dist/controlPlane/context.d.ts.map +1 -0
- package/dist/controlPlane/context.js +29 -0
- package/dist/controlPlane/data/connection.d.ts +79 -0
- package/dist/controlPlane/data/connection.d.ts.map +1 -0
- package/dist/controlPlane/data/connection.js +55 -0
- package/dist/controlPlane/data/keyLifecycle.d.ts +62 -0
- package/dist/controlPlane/data/keyLifecycle.d.ts.map +1 -0
- package/dist/controlPlane/data/keyLifecycle.js +126 -0
- package/dist/controlPlane/data/replay.d.ts +18 -0
- package/dist/controlPlane/data/replay.d.ts.map +1 -0
- package/dist/controlPlane/data/replay.js +20 -0
- package/dist/controlPlane/data/tables.d.ts +34 -0
- package/dist/controlPlane/data/tables.d.ts.map +1 -0
- package/dist/controlPlane/data/tables.js +37 -0
- package/dist/controlPlane/discovery/adminRoute.d.ts +313 -0
- package/dist/controlPlane/discovery/adminRoute.d.ts.map +1 -0
- package/dist/controlPlane/discovery/adminRoute.js +136 -0
- package/dist/controlPlane/discovery/configuration.d.ts +108 -0
- package/dist/controlPlane/discovery/configuration.d.ts.map +1 -0
- package/dist/controlPlane/discovery/configuration.js +187 -0
- package/dist/controlPlane/discovery/drift.d.ts +64 -0
- package/dist/controlPlane/discovery/drift.d.ts.map +1 -0
- package/dist/controlPlane/discovery/drift.js +58 -0
- package/dist/controlPlane/discovery/health.d.ts +99 -0
- package/dist/controlPlane/discovery/health.d.ts.map +1 -0
- package/dist/controlPlane/discovery/health.js +151 -0
- package/dist/controlPlane/discovery/healthSummary.d.ts +236 -0
- package/dist/controlPlane/discovery/healthSummary.d.ts.map +1 -0
- package/dist/controlPlane/discovery/healthSummary.js +278 -0
- package/dist/controlPlane/error/errors.d.ts +67 -0
- package/dist/controlPlane/error/errors.d.ts.map +1 -0
- package/dist/controlPlane/error/errors.js +79 -0
- package/dist/controlPlane/http/cors.d.ts +112 -0
- package/dist/controlPlane/http/cors.d.ts.map +1 -0
- package/dist/controlPlane/http/cors.js +192 -0
- package/dist/controlPlane/http/guard.d.ts +77 -0
- package/dist/controlPlane/http/guard.d.ts.map +1 -0
- package/dist/controlPlane/http/guard.js +142 -0
- package/dist/controlPlane/http/handlers.d.ts +179 -0
- package/dist/controlPlane/http/handlers.d.ts.map +1 -0
- package/dist/controlPlane/http/handlers.js +245 -0
- package/dist/controlPlane/http/responses.d.ts +99 -0
- package/dist/controlPlane/http/responses.d.ts.map +1 -0
- package/dist/controlPlane/http/responses.js +63 -0
- package/dist/controlPlane/http/routes.d.ts +40 -0
- package/dist/controlPlane/http/routes.d.ts.map +1 -0
- package/dist/controlPlane/http/routes.js +83 -0
- package/dist/controlPlane/http/schemas.d.ts +39 -0
- package/dist/controlPlane/http/schemas.d.ts.map +1 -0
- package/dist/controlPlane/http/schemas.js +31 -0
- package/dist/controlPlane/http/verify.d.ts +84 -0
- package/dist/controlPlane/http/verify.d.ts.map +1 -0
- package/dist/controlPlane/http/verify.js +65 -0
- package/dist/controlPlane/migrations/0001_init.d.ts +51 -0
- package/dist/controlPlane/migrations/0001_init.d.ts.map +1 -0
- package/dist/controlPlane/migrations/0001_init.js +65 -0
- package/dist/controlPlane/replay/d1Guard.d.ts +29 -0
- package/dist/controlPlane/replay/d1Guard.d.ts.map +1 -0
- package/dist/controlPlane/replay/d1Guard.js +39 -0
- package/dist/controlPlane/replay/guard.d.ts +52 -0
- package/dist/controlPlane/replay/guard.d.ts.map +1 -0
- package/dist/controlPlane/replay/guard.js +0 -0
- package/dist/controlPlane/replay/kvGuard.d.ts +99 -0
- package/dist/controlPlane/replay/kvGuard.d.ts.map +1 -0
- package/dist/controlPlane/replay/kvGuard.js +101 -0
- package/dist/controlPlane/scope/scope.d.ts +68 -0
- package/dist/controlPlane/scope/scope.d.ts.map +1 -0
- package/dist/controlPlane/scope/scope.js +63 -0
- package/dist/controlPlane/token/base64url.d.ts +10 -0
- package/dist/controlPlane/token/base64url.d.ts.map +1 -0
- package/dist/controlPlane/token/base64url.js +48 -0
- package/dist/controlPlane/token/claims.d.ts +83 -0
- package/dist/controlPlane/token/claims.d.ts.map +1 -0
- package/dist/controlPlane/token/claims.js +86 -0
- package/dist/controlPlane/token/digest.d.ts +44 -0
- package/dist/controlPlane/token/digest.d.ts.map +1 -0
- package/dist/controlPlane/token/digest.js +56 -0
- package/dist/controlPlane/token/jws.d.ts +52 -0
- package/dist/controlPlane/token/jws.d.ts.map +1 -0
- package/dist/controlPlane/token/jws.js +65 -0
- package/dist/controlPlane/token/mint.d.ts +56 -0
- package/dist/controlPlane/token/mint.d.ts.map +1 -0
- package/dist/controlPlane/token/mint.js +55 -0
- package/dist/controlPlane/wire.d.ts +122 -0
- package/dist/controlPlane/wire.d.ts.map +1 -0
- package/dist/controlPlane/wire.js +123 -0
- package/dist/createBackend.d.ts +58 -0
- package/dist/createBackend.d.ts.map +1 -0
- package/dist/createBackend.js +170 -0
- package/dist/createEntrypoint.d.ts +53 -0
- package/dist/createEntrypoint.d.ts.map +1 -0
- package/dist/createEntrypoint.js +52 -0
- package/dist/data/boundParameters.d.ts +83 -0
- package/dist/data/boundParameters.d.ts.map +1 -0
- package/dist/data/boundParameters.js +162 -0
- package/dist/data/codecs.d.ts +34 -0
- package/dist/data/codecs.d.ts.map +1 -0
- package/dist/data/codecs.js +135 -0
- package/dist/data/cursor.d.ts +81 -0
- package/dist/data/cursor.d.ts.map +1 -0
- package/dist/data/cursor.js +104 -0
- package/dist/data/databases.d.ts +55 -0
- package/dist/data/databases.d.ts.map +1 -0
- package/dist/data/databases.js +32 -0
- package/dist/data/db.d.ts +42 -0
- package/dist/data/db.d.ts.map +1 -0
- package/dist/data/db.js +24 -0
- package/dist/data/withD1Retry.d.ts +91 -0
- package/dist/data/withD1Retry.d.ts.map +1 -0
- package/dist/data/withD1Retry.js +152 -0
- package/dist/entitlement/entitlement.d.ts +118 -0
- package/dist/entitlement/entitlement.d.ts.map +1 -0
- package/dist/entitlement/entitlement.js +59 -0
- package/dist/entitlement/gateScan.d.ts +26 -0
- package/dist/entitlement/gateScan.d.ts.map +1 -0
- package/dist/entitlement/gateScan.js +96 -0
- package/dist/entitlement/require.d.ts +12 -0
- package/dist/entitlement/require.d.ts.map +1 -0
- package/dist/entitlement/require.js +123 -0
- package/dist/env/ambient.d.ts +52 -0
- package/dist/env/ambient.d.ts.map +1 -0
- package/dist/env/ambient.js +35 -0
- package/dist/env/ci.d.ts +36 -0
- package/dist/env/ci.d.ts.map +1 -0
- package/dist/env/ci.js +40 -0
- package/dist/env/stem.d.ts +23 -0
- package/dist/env/stem.d.ts.map +1 -0
- package/dist/env/stem.js +29 -0
- package/dist/error/cause.d.ts +143 -0
- package/dist/error/cause.d.ts.map +1 -0
- package/dist/error/cause.js +192 -0
- package/dist/error/client.d.ts +35 -0
- package/dist/error/client.d.ts.map +1 -0
- package/dist/error/client.js +38 -0
- package/dist/error/extend.d.ts +101 -0
- package/dist/error/extend.d.ts.map +1 -0
- package/dist/error/extend.js +76 -0
- package/dist/error/http.d.ts +1516 -0
- package/dist/error/http.d.ts.map +1 -0
- package/dist/error/http.js +72 -0
- package/dist/error/payload.d.ts +3034 -0
- package/dist/error/payload.d.ts.map +1 -0
- package/dist/error/payload.js +1110 -0
- package/dist/error/pithyError.d.ts +154 -0
- package/dist/error/pithyError.d.ts.map +1 -0
- package/dist/error/pithyError.js +197 -0
- package/dist/error/terminal.d.ts +28 -0
- package/dist/error/terminal.d.ts.map +1 -0
- package/dist/error/terminal.js +33 -0
- package/dist/http/authContext.d.ts +21 -0
- package/dist/http/authContext.d.ts.map +1 -0
- package/dist/http/authContext.js +23 -0
- package/dist/http/routeContract.d.ts +39 -0
- package/dist/http/routeContract.d.ts.map +1 -0
- package/dist/http/routeContract.js +82 -0
- package/dist/http/sameOrigin.d.ts +47 -0
- package/dist/http/sameOrigin.d.ts.map +1 -0
- package/dist/http/sameOrigin.js +24 -0
- package/dist/http/signedWebhook.d.ts +225 -0
- package/dist/http/signedWebhook.d.ts.map +1 -0
- package/dist/http/signedWebhook.js +247 -0
- package/dist/http/validation.d.ts +37 -0
- package/dist/http/validation.d.ts.map +1 -0
- package/dist/http/validation.js +14 -0
- package/dist/http/verification.d.ts +10 -0
- package/dist/http/verification.d.ts.map +1 -0
- package/dist/http/verification.js +17 -0
- package/dist/i18n/acceptLanguage.d.ts +22 -0
- package/dist/i18n/acceptLanguage.d.ts.map +1 -0
- package/dist/i18n/acceptLanguage.js +55 -0
- package/dist/i18n/catalog.d.ts +39 -0
- package/dist/i18n/catalog.d.ts.map +1 -0
- package/dist/i18n/catalog.js +57 -0
- package/dist/i18n/locale.d.ts +74 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/locale.js +109 -0
- package/dist/i18n/localeMarker.d.ts +29 -0
- package/dist/i18n/localeMarker.d.ts.map +1 -0
- package/dist/i18n/localeMarker.js +112 -0
- package/dist/i18n/match.d.ts +26 -0
- package/dist/i18n/match.d.ts.map +1 -0
- package/dist/i18n/match.js +88 -0
- package/dist/i18n/registry.d.ts +25 -0
- package/dist/i18n/registry.d.ts.map +1 -0
- package/dist/i18n/registry.js +51 -0
- package/dist/i18n/translator.d.ts +107 -0
- package/dist/i18n/translator.d.ts.map +1 -0
- package/dist/i18n/translator.js +80 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/kv/kv.d.ts +166 -0
- package/dist/kv/kv.d.ts.map +1 -0
- package/dist/kv/kv.js +261 -0
- package/dist/kv/namespaces.d.ts +58 -0
- package/dist/kv/namespaces.d.ts.map +1 -0
- package/dist/kv/namespaces.js +40 -0
- package/dist/logger/local.d.ts +41 -0
- package/dist/logger/local.d.ts.map +1 -0
- package/dist/logger/local.js +45 -0
- package/dist/logger/logger.d.ts +56 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +83 -0
- package/dist/logger/record.d.ts +919 -0
- package/dist/logger/record.d.ts.map +1 -0
- package/dist/logger/record.js +79 -0
- package/dist/logger/worker.d.ts +74 -0
- package/dist/logger/worker.d.ts.map +1 -0
- package/dist/logger/worker.js +54 -0
- package/dist/migrations/batch.d.ts +10 -0
- package/dist/migrations/batch.d.ts.map +1 -0
- package/dist/migrations/batch.js +193 -0
- package/dist/migrations/bookkeeping.d.ts +24 -0
- package/dist/migrations/bookkeeping.d.ts.map +1 -0
- package/dist/migrations/bookkeeping.js +57 -0
- package/dist/migrations/owner.d.ts +41 -0
- package/dist/migrations/owner.d.ts.map +1 -0
- package/dist/migrations/owner.js +105 -0
- package/dist/migrations/registry.d.ts +36 -0
- package/dist/migrations/registry.d.ts.map +1 -0
- package/dist/migrations/registry.js +70 -0
- package/dist/migrations/runner.d.ts +67 -0
- package/dist/migrations/runner.d.ts.map +1 -0
- package/dist/migrations/runner.js +218 -0
- package/dist/naming/domains.d.ts +108 -0
- package/dist/naming/domains.d.ts.map +1 -0
- package/dist/naming/domains.js +156 -0
- package/dist/naming/environment.d.ts +118 -0
- package/dist/naming/environment.d.ts.map +1 -0
- package/dist/naming/environment.js +190 -0
- package/dist/naming/feature.d.ts +68 -0
- package/dist/naming/feature.d.ts.map +1 -0
- package/dist/naming/feature.js +106 -0
- package/dist/naming/limits.d.ts +229 -0
- package/dist/naming/limits.d.ts.map +1 -0
- package/dist/naming/limits.js +187 -0
- package/dist/naming/provisionScope.d.ts +91 -0
- package/dist/naming/provisionScope.d.ts.map +1 -0
- package/dist/naming/provisionScope.js +65 -0
- package/dist/naming/resource.d.ts +169 -0
- package/dist/naming/resource.d.ts.map +1 -0
- package/dist/naming/resource.js +220 -0
- package/dist/naming/resourceNames.d.ts +83 -0
- package/dist/naming/resourceNames.d.ts.map +1 -0
- package/dist/naming/resourceNames.js +102 -0
- package/dist/naming/segment.d.ts +29 -0
- package/dist/naming/segment.d.ts.map +1 -0
- package/dist/naming/segment.js +31 -0
- package/dist/projection/asRead.d.ts +72 -0
- package/dist/projection/asRead.d.ts.map +1 -0
- package/dist/projection/asRead.js +169 -0
- package/dist/projection/published.d.ts +95 -0
- package/dist/projection/published.d.ts.map +1 -0
- package/dist/projection/published.js +114 -0
- package/dist/schema/describedness.d.ts +55 -0
- package/dist/schema/describedness.d.ts.map +1 -0
- package/dist/schema/describedness.js +180 -0
- package/dist/seed/compose.d.ts +41 -0
- package/dist/seed/compose.d.ts.map +1 -0
- package/dist/seed/compose.js +51 -0
- package/dist/seed/devLogin.d.ts +50 -0
- package/dist/seed/devLogin.d.ts.map +1 -0
- package/dist/seed/devLogin.js +52 -0
- package/dist/seed/exampleIdentities.d.ts +58 -0
- package/dist/seed/exampleIdentities.d.ts.map +1 -0
- package/dist/seed/exampleIdentities.js +26 -0
- package/dist/seed/metadata.d.ts +20 -0
- package/dist/seed/metadata.d.ts.map +1 -0
- package/dist/seed/metadata.js +27 -0
- package/dist/seed/seed.d.ts +264 -0
- package/dist/seed/seed.d.ts.map +1 -0
- package/dist/seed/seed.js +37 -0
- package/dist/seed/seededRows.d.ts +26 -0
- package/dist/seed/seededRows.d.ts.map +1 -0
- package/dist/seed/seededRows.js +20 -0
- package/dist/seed/writeD1.d.ts +43 -0
- package/dist/seed/writeD1.d.ts.map +1 -0
- package/dist/seed/writeD1.js +73 -0
- package/dist/seed/writeKv.d.ts +29 -0
- package/dist/seed/writeKv.d.ts.map +1 -0
- package/dist/seed/writeKv.js +63 -0
- package/dist/semver/semver.d.ts +62 -0
- package/dist/semver/semver.d.ts.map +1 -0
- package/dist/semver/semver.js +137 -0
- package/dist/text/comments.d.ts +62 -0
- package/dist/text/comments.d.ts.map +1 -0
- package/dist/text/comments.js +161 -0
- package/dist/version.generated.d.ts +5 -0
- package/dist/version.generated.d.ts.map +1 -0
- package/dist/version.generated.js +7 -0
- package/dist/worker/health.d.ts +39 -0
- package/dist/worker/health.d.ts.map +1 -0
- package/dist/worker/health.js +41 -0
- package/dist/worker/identity.d.ts +191 -0
- package/dist/worker/identity.d.ts.map +1 -0
- package/dist/worker/identity.js +162 -0
- package/dist/workflow/bindings.d.ts +41 -0
- package/dist/workflow/bindings.d.ts.map +1 -0
- package/dist/workflow/bindings.js +53 -0
- package/dist/workflow/dispatch.d.ts +98 -0
- package/dist/workflow/dispatch.d.ts.map +1 -0
- package/dist/workflow/dispatch.js +148 -0
- package/dist/workflow/dispatchRoute.d.ts +80 -0
- package/dist/workflow/dispatchRoute.d.ts.map +1 -0
- package/dist/workflow/dispatchRoute.js +134 -0
- package/dist/workflow/faults.d.ts +97 -0
- package/dist/workflow/faults.d.ts.map +1 -0
- package/dist/workflow/faults.js +111 -0
- package/dist/workflow/host.d.ts +176 -0
- package/dist/workflow/host.d.ts.map +1 -0
- package/dist/workflow/host.js +116 -0
- package/dist/workflow/hostEntry.d.ts +50 -0
- package/dist/workflow/hostEntry.d.ts.map +1 -0
- package/dist/workflow/hostEntry.js +24 -0
- package/dist/workflow/hostEnv.d.ts +143 -0
- package/dist/workflow/hostEnv.d.ts.map +1 -0
- package/dist/workflow/hostEnv.js +170 -0
- package/dist/workflow/loopback.d.ts +52 -0
- package/dist/workflow/loopback.d.ts.map +1 -0
- package/dist/workflow/loopback.js +76 -0
- package/dist/workflow/naming.d.ts +79 -0
- package/dist/workflow/naming.d.ts.map +1 -0
- package/dist/workflow/naming.js +138 -0
- package/dist/workflow/register.d.ts +19 -0
- package/dist/workflow/register.d.ts.map +1 -0
- package/dist/workflow/register.js +40 -0
- package/dist/workflow/schemas.d.ts +44 -0
- package/dist/workflow/schemas.d.ts.map +1 -0
- package/dist/workflow/schemas.js +43 -0
- package/dist/workflow/spec.d.ts +81 -0
- package/dist/workflow/spec.d.ts.map +1 -0
- package/dist/workflow/spec.js +0 -0
- package/dist/workflow/stepMessage.d.ts +122 -0
- package/dist/workflow/stepMessage.d.ts.map +1 -0
- package/dist/workflow/stepMessage.js +152 -0
- package/package.json +20 -9
- package/src/capability/manifest.ts +21 -0
- package/src/version.generated.ts +1 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a running Worker knows about itself — the three vars every Pithy Worker is scaffolded with, and
|
|
3
|
+
* the one reader for them.
|
|
4
|
+
*
|
|
5
|
+
* The Cloudflare runtime hands a script **nothing** about its own identity. `TraceItem.scriptName` is
|
|
6
|
+
* what a *tail consumer* sees about someone else, `version_metadata` carries an id, a tag and a
|
|
7
|
+
* creation time but no name, and `navigator.userAgent` is the constant `"Cloudflare-Workers"` in every
|
|
8
|
+
* Worker alive. So
|
|
9
|
+
* identity is stamped, not derived: `pithy init` and `pithy worker add` write `PROJECT`, `ENVIRONMENT`,
|
|
10
|
+
* and `WORKER` into every environment stanza of the Worker's own `wrangler.jsonc`.
|
|
11
|
+
*
|
|
12
|
+
* Stamping also beats deriving even where a value looks recoverable. A host's script name leads with
|
|
13
|
+
* its project, but `<project>-<env>-<capability>` cannot be parsed back into its parts once a project
|
|
14
|
+
* name contains a hyphen — and wrangler appends `-staging`/`-prod` at deploy, so the script name is not
|
|
15
|
+
* even stable across environments while `apps/<name>/` is.
|
|
16
|
+
*
|
|
17
|
+
* The names live here because they had already been copied: `ENVIRONMENT_VAR` was declared privately in
|
|
18
|
+
* both `workflow/host.ts` and `controlPlane/capability.ts`, character for character. A third copy for
|
|
19
|
+
* `WORKER` would have made the drift structural — the arrangement where a rule stops being one rule.
|
|
20
|
+
*/
|
|
21
|
+
/** The var naming the owning project: the root `pithy.config.ts` `name`, kebabed. */
|
|
22
|
+
export declare const PROJECT_VAR = "PROJECT";
|
|
23
|
+
/** The var naming the environment this deployment serves — `dev`, `staging`, or `prod`. */
|
|
24
|
+
export declare const ENVIRONMENT_VAR = "ENVIRONMENT";
|
|
25
|
+
/**
|
|
26
|
+
* The var carrying a Worker's **own** dev origin, from `pithy dev` to whatever launches that Worker.
|
|
27
|
+
*
|
|
28
|
+
* Not stamped into `wrangler.jsonc` like the three above, and that is the whole point of it. A dev port
|
|
29
|
+
* is *allocated* — every checkout reserves its own block — so this is the one identity value a file in
|
|
30
|
+
* the repository cannot state: written down, it is right in the first checkout on a machine and wrong
|
|
31
|
+
* in every other one (#462).
|
|
32
|
+
*
|
|
33
|
+
* It lives here for the reason the others do. `pithy dev` writes it and `@pithy-sh/vite` reads it, and
|
|
34
|
+
* those two packages cannot import each other — the CLI depends on vite's package, and vite's may not
|
|
35
|
+
* depend on the CLI. A privately declared copy on each side is the arrangement where one rule quietly
|
|
36
|
+
* becomes two.
|
|
37
|
+
*
|
|
38
|
+
* **A carrier, not a binding.** It reaches a *process*, not a Worker: `process.env` inside workerd is
|
|
39
|
+
* that script's own vars and nothing else. `@pithy-sh/vite`'s `devWorkerConfig()` is what turns it into
|
|
40
|
+
* the Worker's `BASE_URL`, which is the binding anything at runtime actually reads.
|
|
41
|
+
*/
|
|
42
|
+
export declare const WORKER_ORIGIN_VAR = "PITHY_WORKER_ORIGIN";
|
|
43
|
+
/**
|
|
44
|
+
* The var naming the Worker itself: its `apps/<name>` **directory** name, not its deploy name.
|
|
45
|
+
*
|
|
46
|
+
* The directory name is the identity everything else already keys on — the `apps/*` registry, the
|
|
47
|
+
* `--worker` flag, the `.dev.config.json` port block. The deploy name (`<project>-<name>`) would
|
|
48
|
+
* re-encode the project as noise beside a `project` column that already carries it, and the deployed
|
|
49
|
+
* script's real name varies by environment where the directory does not.
|
|
50
|
+
*/
|
|
51
|
+
export declare const WORKER_VAR = "WORKER";
|
|
52
|
+
/**
|
|
53
|
+
* The version-metadata binding Cloudflare injects, naming the exact build that is running.
|
|
54
|
+
*
|
|
55
|
+
* Not a var — a binding, declared as `"version_metadata": { "binding": "CF_VERSION_METADATA" }` and
|
|
56
|
+
* populated by the platform rather than by the scaffold. It belongs beside the three vars anyway,
|
|
57
|
+
* because it answers the same question they do and is read on the same path: this is what a Worker knows
|
|
58
|
+
* about itself.
|
|
59
|
+
*
|
|
60
|
+
* **The name is the join.** It is what `pithy init` and `pithy worker add` write and what this module
|
|
61
|
+
* reads; binding a differently-named one creates a binding nothing consumes, which is the failure this
|
|
62
|
+
* whole thread is repairing — the reader shipped, the template never declared it, and the field was
|
|
63
|
+
* silently absent in every scaffolded project.
|
|
64
|
+
*/
|
|
65
|
+
export declare const VERSION_METADATA_BINDING = "CF_VERSION_METADATA";
|
|
66
|
+
/** Where a Worker is running, as it can state about itself. Every field is `null` when unstamped. */
|
|
67
|
+
export interface WorkerIdentity {
|
|
68
|
+
/** The owning project, or `null` when the Worker carries no `PROJECT` var. */
|
|
69
|
+
project: string | null;
|
|
70
|
+
/** The environment this deployment serves, or `null` when unstamped. */
|
|
71
|
+
environment: string | null;
|
|
72
|
+
/** The Worker's `apps/<name>` directory name, or `null` when unstamped. */
|
|
73
|
+
worker: string | null;
|
|
74
|
+
/**
|
|
75
|
+
* The deployed build's Cloudflare version id, or `null` off-platform and wherever the
|
|
76
|
+
* `CF_VERSION_METADATA` binding is absent.
|
|
77
|
+
*
|
|
78
|
+
* Opaque and per-deploy: it identifies *exactly which build* is running, which is the right answer for
|
|
79
|
+
* forensics, for reproducing a report, and for pinning what an audited action ran against. It carries
|
|
80
|
+
* no version semantics, so it says nothing about which features a Worker has — that is what the
|
|
81
|
+
* composed package versions in the control-plane manifest are for.
|
|
82
|
+
*/
|
|
83
|
+
version: string | null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Everything the `CF_VERSION_METADATA` binding carries about the build that is running.
|
|
87
|
+
*
|
|
88
|
+
* **Measured, not read off the docs.** A `wrangler dev` (4.120.1 / miniflare 4) against a Worker
|
|
89
|
+
* declaring `version_metadata` hands the binding as `{ id, tag, timestamp }` — three own keys, every
|
|
90
|
+
* value a string, `timestamp` an ISO-8601 instant. Every field is independently `null` here, because a
|
|
91
|
+
* partial binding is what a platform change looks like from inside a Worker and losing the id over a
|
|
92
|
+
* renamed sibling would be the worse trade.
|
|
93
|
+
*
|
|
94
|
+
* **It names a *version*, never a deployment.** That distinction is the whole ceiling on what a client
|
|
95
|
+
* can conclude from it — see {@link workerVersionMetadata}.
|
|
96
|
+
*/
|
|
97
|
+
export interface WorkerVersionMetadata {
|
|
98
|
+
/** The version id: opaque, per version, and the answer to "which build". `null` where the binding is. */
|
|
99
|
+
id: string | null;
|
|
100
|
+
/**
|
|
101
|
+
* The version tag, set only by `wrangler versions upload --tag`, or `null`.
|
|
102
|
+
*
|
|
103
|
+
* Empty in every local dev and in every deploy nobody tagged, so `""` reads as absent rather than as a
|
|
104
|
+
* tag to compare against. Read here so this reader mirrors the binding; deliberately **not** stamped
|
|
105
|
+
* on the control-plane header — it is adopter-authored free text, and the two questions a management
|
|
106
|
+
* client asks are answered without it.
|
|
107
|
+
*/
|
|
108
|
+
tag: string | null;
|
|
109
|
+
/**
|
|
110
|
+
* When this **version was uploaded**, ISO-8601, verbatim as the platform issued it — or `null`.
|
|
111
|
+
*
|
|
112
|
+
* **Cloudflare has two objects here, and this binding describes one of them.** A *version* is an
|
|
113
|
+
* immutable upload of code and config: an id, a created timestamp and a tag, fixed at upload and never
|
|
114
|
+
* again. A *deployment* points at one or more versions with traffic percentages, and is its own object
|
|
115
|
+
* with its own id and its own time. `CF_VERSION_METADATA` reports the **version**, faithfully — and
|
|
116
|
+
* the runtime hands a script **no binding for the deployment at all**.
|
|
117
|
+
*
|
|
118
|
+
* Everything else follows from that. A rollback creates a *new deployment* aimed at an *existing
|
|
119
|
+
* version*, so nothing in this binding moves: not staleness, not ambiguity, a different object. The
|
|
120
|
+
* same answer covers the next question and the one after — a traffic split, a gradual rollout, which
|
|
121
|
+
* deployment is serving: a Worker cannot see any of it. An ordinary redeploy is not affected, because
|
|
122
|
+
* every `wrangler deploy` uploads and so mints a new version, id and all, even for a one-character
|
|
123
|
+
* change.
|
|
124
|
+
*
|
|
125
|
+
* Measured, 2026-08-10, which is what turned that from a reading of the docs into a fact: a probe
|
|
126
|
+
* Worker on a real account, version `A` uploaded, `B` four seconds later, then a real `wrangler
|
|
127
|
+
* rollback` to `A`. Two minutes on, the Worker reported `A`'s id **and `A`'s original timestamp**,
|
|
128
|
+
* unmoved — while wrangler's own rollback output named the new deployment's version list.
|
|
129
|
+
*
|
|
130
|
+
* The value is relayed for comparison and never interpreted. A consumer's rule is
|
|
131
|
+
* `workerBuildChanged` in `controlPlane/wire.ts`: anything that moved is a change, and a direction is
|
|
132
|
+
* not a meaning — propagation lag alone can make an older version answer for a while after a deploy.
|
|
133
|
+
*
|
|
134
|
+
* `null` for anything that is not a parseable instant. That is the one place this reader refuses
|
|
135
|
+
* rather than relays, and the consumer is the reason: a client does `Date.parse` on it and compares,
|
|
136
|
+
* an unparseable string is `NaN`, and every `NaN` comparison is false — so garbage would read as
|
|
137
|
+
* "not newer", which is silently indistinguishable from "unchanged".
|
|
138
|
+
*/
|
|
139
|
+
createdAt: string | null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Read a Worker's stamped identity off its `env`.
|
|
143
|
+
*
|
|
144
|
+
* **Never throws, and never guesses.** Both matter on the one call path this exists for: the audit
|
|
145
|
+
* recorder stamps origin onto every event, and the recorder is contractually non-fatal — a throw here
|
|
146
|
+
* would turn "this row has no origin" into "there is no row", which is the strictly worse failure. An
|
|
147
|
+
* absent var is an ordinary, permanent state: a Worker scaffolded before these vars existed carries
|
|
148
|
+
* none of them and nothing back-fills it, so `null` is reported rather than inferred. An invented
|
|
149
|
+
* origin would be indistinguishable from a real one for as long as the trail is kept.
|
|
150
|
+
*/
|
|
151
|
+
export declare function workerIdentity(env: unknown): WorkerIdentity;
|
|
152
|
+
/**
|
|
153
|
+
* Read the whole `CF_VERSION_METADATA` binding: which build is running, and when that build was made.
|
|
154
|
+
*
|
|
155
|
+
* **The one reader of the binding**, which is why it returns all of it. The seam used to take the id and
|
|
156
|
+
* drop the rest, and the module docstring above described a two-field binding — so the field this
|
|
157
|
+
* function exists for was discarded by a reader that did not know it was there.
|
|
158
|
+
*
|
|
159
|
+
* ## What a client can conclude
|
|
160
|
+
*
|
|
161
|
+
* Holding the last `(id, createdAt)` it saw, and comparing field by field only where both sides carried
|
|
162
|
+
* a value: anything that differs is a change. Absence on either side is silence, never change.
|
|
163
|
+
* `workerBuildChanged` in `controlPlane/wire.ts` is that rule, written once so no client hand-rolls it.
|
|
164
|
+
*
|
|
165
|
+
* ## What it cannot see, and why that is a boundary rather than a gap
|
|
166
|
+
*
|
|
167
|
+
* **This binding describes a version. Nothing inside a Worker can observe a deployment** — see
|
|
168
|
+
* {@link WorkerVersionMetadata.createdAt} for the two objects and the measurement. So a rollback, a
|
|
169
|
+
* traffic split, a gradual rollout: all invisible here, and no field the seam could add would change
|
|
170
|
+
* that, because the runtime hands a script no binding for the object that carries them. A client that
|
|
171
|
+
* needs a deployment reads Cloudflare's deployments API, in the customer's own account.
|
|
172
|
+
*
|
|
173
|
+
* The temptation is to synthesise one. Isolate boot time is the only in-Worker candidate and it is
|
|
174
|
+
* worse than nothing: it changes on every cold start, so it would report a redeploy dozens of times a
|
|
175
|
+
* day, and a false change costs more than a missed one for a client that invalidates a rendered pane on
|
|
176
|
+
* it. Nothing is stamped.
|
|
177
|
+
*
|
|
178
|
+
* Same never-throws, never-guesses contract as {@link workerIdentity}.
|
|
179
|
+
*/
|
|
180
|
+
export declare function workerVersionMetadata(env: unknown): WorkerVersionMetadata;
|
|
181
|
+
/**
|
|
182
|
+
* The deployed build's version id, off the `CF_VERSION_METADATA` binding, or `null`.
|
|
183
|
+
*
|
|
184
|
+
* Kept on its own because four callers want the id and nothing else: the request logger's `version`
|
|
185
|
+
* correlation field, `/health`, the control-plane manifest, and the seam's response header. Its shape
|
|
186
|
+
* is unchanged and deliberately so — every one of those compares or records a single opaque string, and
|
|
187
|
+
* widening it would have rewritten an audit column and a wire field to carry something none of them
|
|
188
|
+
* asked for. {@link workerVersionMetadata} is where the rest of the binding lives.
|
|
189
|
+
*/
|
|
190
|
+
export declare function workerVersion(env: unknown): string | null;
|
|
191
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/worker/identity.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qFAAqF;AACrF,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,2FAA2F;AAC3F,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wEAAwE;IACxE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAW3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CAazE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEzD"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
//#region src/worker/identity.ts
|
|
2
|
+
/**
|
|
3
|
+
* What a running Worker knows about itself — the three vars every Pithy Worker is scaffolded with, and
|
|
4
|
+
* the one reader for them.
|
|
5
|
+
*
|
|
6
|
+
* The Cloudflare runtime hands a script **nothing** about its own identity. `TraceItem.scriptName` is
|
|
7
|
+
* what a *tail consumer* sees about someone else, `version_metadata` carries an id, a tag and a
|
|
8
|
+
* creation time but no name, and `navigator.userAgent` is the constant `"Cloudflare-Workers"` in every
|
|
9
|
+
* Worker alive. So
|
|
10
|
+
* identity is stamped, not derived: `pithy init` and `pithy worker add` write `PROJECT`, `ENVIRONMENT`,
|
|
11
|
+
* and `WORKER` into every environment stanza of the Worker's own `wrangler.jsonc`.
|
|
12
|
+
*
|
|
13
|
+
* Stamping also beats deriving even where a value looks recoverable. A host's script name leads with
|
|
14
|
+
* its project, but `<project>-<env>-<capability>` cannot be parsed back into its parts once a project
|
|
15
|
+
* name contains a hyphen — and wrangler appends `-staging`/`-prod` at deploy, so the script name is not
|
|
16
|
+
* even stable across environments while `apps/<name>/` is.
|
|
17
|
+
*
|
|
18
|
+
* The names live here because they had already been copied: `ENVIRONMENT_VAR` was declared privately in
|
|
19
|
+
* both `workflow/host.ts` and `controlPlane/capability.ts`, character for character. A third copy for
|
|
20
|
+
* `WORKER` would have made the drift structural — the arrangement where a rule stops being one rule.
|
|
21
|
+
*/
|
|
22
|
+
/** The var naming the owning project: the root `pithy.config.ts` `name`, kebabed. */
|
|
23
|
+
const PROJECT_VAR = "PROJECT";
|
|
24
|
+
/** The var naming the environment this deployment serves — `dev`, `staging`, or `prod`. */
|
|
25
|
+
const ENVIRONMENT_VAR = "ENVIRONMENT";
|
|
26
|
+
/**
|
|
27
|
+
* The var carrying a Worker's **own** dev origin, from `pithy dev` to whatever launches that Worker.
|
|
28
|
+
*
|
|
29
|
+
* Not stamped into `wrangler.jsonc` like the three above, and that is the whole point of it. A dev port
|
|
30
|
+
* is *allocated* — every checkout reserves its own block — so this is the one identity value a file in
|
|
31
|
+
* the repository cannot state: written down, it is right in the first checkout on a machine and wrong
|
|
32
|
+
* in every other one (#462).
|
|
33
|
+
*
|
|
34
|
+
* It lives here for the reason the others do. `pithy dev` writes it and `@pithy-sh/vite` reads it, and
|
|
35
|
+
* those two packages cannot import each other — the CLI depends on vite's package, and vite's may not
|
|
36
|
+
* depend on the CLI. A privately declared copy on each side is the arrangement where one rule quietly
|
|
37
|
+
* becomes two.
|
|
38
|
+
*
|
|
39
|
+
* **A carrier, not a binding.** It reaches a *process*, not a Worker: `process.env` inside workerd is
|
|
40
|
+
* that script's own vars and nothing else. `@pithy-sh/vite`'s `devWorkerConfig()` is what turns it into
|
|
41
|
+
* the Worker's `BASE_URL`, which is the binding anything at runtime actually reads.
|
|
42
|
+
*/
|
|
43
|
+
const WORKER_ORIGIN_VAR = "PITHY_WORKER_ORIGIN";
|
|
44
|
+
/**
|
|
45
|
+
* The var naming the Worker itself: its `apps/<name>` **directory** name, not its deploy name.
|
|
46
|
+
*
|
|
47
|
+
* The directory name is the identity everything else already keys on — the `apps/*` registry, the
|
|
48
|
+
* `--worker` flag, the `.dev.config.json` port block. The deploy name (`<project>-<name>`) would
|
|
49
|
+
* re-encode the project as noise beside a `project` column that already carries it, and the deployed
|
|
50
|
+
* script's real name varies by environment where the directory does not.
|
|
51
|
+
*/
|
|
52
|
+
const WORKER_VAR = "WORKER";
|
|
53
|
+
/**
|
|
54
|
+
* The version-metadata binding Cloudflare injects, naming the exact build that is running.
|
|
55
|
+
*
|
|
56
|
+
* Not a var — a binding, declared as `"version_metadata": { "binding": "CF_VERSION_METADATA" }` and
|
|
57
|
+
* populated by the platform rather than by the scaffold. It belongs beside the three vars anyway,
|
|
58
|
+
* because it answers the same question they do and is read on the same path: this is what a Worker knows
|
|
59
|
+
* about itself.
|
|
60
|
+
*
|
|
61
|
+
* **The name is the join.** It is what `pithy init` and `pithy worker add` write and what this module
|
|
62
|
+
* reads; binding a differently-named one creates a binding nothing consumes, which is the failure this
|
|
63
|
+
* whole thread is repairing — the reader shipped, the template never declared it, and the field was
|
|
64
|
+
* silently absent in every scaffolded project.
|
|
65
|
+
*/
|
|
66
|
+
const VERSION_METADATA_BINDING = "CF_VERSION_METADATA";
|
|
67
|
+
/** One binding field, or `null` for anything that is not a non-empty string. */
|
|
68
|
+
function carried(meta, field) {
|
|
69
|
+
const value = meta[field];
|
|
70
|
+
return typeof value === "string" && value.trim() !== "" ? value : null;
|
|
71
|
+
}
|
|
72
|
+
/** One var, trimmed, or `null` for anything that is not a non-empty string. */
|
|
73
|
+
function stamped(env, name) {
|
|
74
|
+
const value = env[name];
|
|
75
|
+
if (typeof value !== "string") return null;
|
|
76
|
+
const trimmed = value.trim();
|
|
77
|
+
return trimmed === "" ? null : trimmed;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Read a Worker's stamped identity off its `env`.
|
|
81
|
+
*
|
|
82
|
+
* **Never throws, and never guesses.** Both matter on the one call path this exists for: the audit
|
|
83
|
+
* recorder stamps origin onto every event, and the recorder is contractually non-fatal — a throw here
|
|
84
|
+
* would turn "this row has no origin" into "there is no row", which is the strictly worse failure. An
|
|
85
|
+
* absent var is an ordinary, permanent state: a Worker scaffolded before these vars existed carries
|
|
86
|
+
* none of them and nothing back-fills it, so `null` is reported rather than inferred. An invented
|
|
87
|
+
* origin would be indistinguishable from a real one for as long as the trail is kept.
|
|
88
|
+
*/
|
|
89
|
+
function workerIdentity(env) {
|
|
90
|
+
if (typeof env !== "object" || env === null || Array.isArray(env)) return {
|
|
91
|
+
project: null,
|
|
92
|
+
environment: null,
|
|
93
|
+
worker: null,
|
|
94
|
+
version: null
|
|
95
|
+
};
|
|
96
|
+
const vars = env;
|
|
97
|
+
return {
|
|
98
|
+
project: stamped(vars, PROJECT_VAR),
|
|
99
|
+
environment: stamped(vars, ENVIRONMENT_VAR),
|
|
100
|
+
worker: stamped(vars, WORKER_VAR),
|
|
101
|
+
version: workerVersion(env)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Read the whole `CF_VERSION_METADATA` binding: which build is running, and when that build was made.
|
|
106
|
+
*
|
|
107
|
+
* **The one reader of the binding**, which is why it returns all of it. The seam used to take the id and
|
|
108
|
+
* drop the rest, and the module docstring above described a two-field binding — so the field this
|
|
109
|
+
* function exists for was discarded by a reader that did not know it was there.
|
|
110
|
+
*
|
|
111
|
+
* ## What a client can conclude
|
|
112
|
+
*
|
|
113
|
+
* Holding the last `(id, createdAt)` it saw, and comparing field by field only where both sides carried
|
|
114
|
+
* a value: anything that differs is a change. Absence on either side is silence, never change.
|
|
115
|
+
* `workerBuildChanged` in `controlPlane/wire.ts` is that rule, written once so no client hand-rolls it.
|
|
116
|
+
*
|
|
117
|
+
* ## What it cannot see, and why that is a boundary rather than a gap
|
|
118
|
+
*
|
|
119
|
+
* **This binding describes a version. Nothing inside a Worker can observe a deployment** — see
|
|
120
|
+
* {@link WorkerVersionMetadata.createdAt} for the two objects and the measurement. So a rollback, a
|
|
121
|
+
* traffic split, a gradual rollout: all invisible here, and no field the seam could add would change
|
|
122
|
+
* that, because the runtime hands a script no binding for the object that carries them. A client that
|
|
123
|
+
* needs a deployment reads Cloudflare's deployments API, in the customer's own account.
|
|
124
|
+
*
|
|
125
|
+
* The temptation is to synthesise one. Isolate boot time is the only in-Worker candidate and it is
|
|
126
|
+
* worse than nothing: it changes on every cold start, so it would report a redeploy dozens of times a
|
|
127
|
+
* day, and a false change costs more than a missed one for a client that invalidates a rendered pane on
|
|
128
|
+
* it. Nothing is stamped.
|
|
129
|
+
*
|
|
130
|
+
* Same never-throws, never-guesses contract as {@link workerIdentity}.
|
|
131
|
+
*/
|
|
132
|
+
function workerVersionMetadata(env) {
|
|
133
|
+
const absent = {
|
|
134
|
+
id: null,
|
|
135
|
+
tag: null,
|
|
136
|
+
createdAt: null
|
|
137
|
+
};
|
|
138
|
+
if (typeof env !== "object" || env === null || Array.isArray(env)) return absent;
|
|
139
|
+
const meta = env[VERSION_METADATA_BINDING];
|
|
140
|
+
if (typeof meta !== "object" || meta === null) return absent;
|
|
141
|
+
const fields = meta;
|
|
142
|
+
const createdAt = carried(fields, "timestamp");
|
|
143
|
+
return {
|
|
144
|
+
id: carried(fields, "id"),
|
|
145
|
+
tag: carried(fields, "tag"),
|
|
146
|
+
createdAt: createdAt !== null && Number.isFinite(Date.parse(createdAt)) ? createdAt : null
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The deployed build's version id, off the `CF_VERSION_METADATA` binding, or `null`.
|
|
151
|
+
*
|
|
152
|
+
* Kept on its own because four callers want the id and nothing else: the request logger's `version`
|
|
153
|
+
* correlation field, `/health`, the control-plane manifest, and the seam's response header. Its shape
|
|
154
|
+
* is unchanged and deliberately so — every one of those compares or records a single opaque string, and
|
|
155
|
+
* widening it would have rewritten an audit column and a wire field to carry something none of them
|
|
156
|
+
* asked for. {@link workerVersionMetadata} is where the rest of the binding lives.
|
|
157
|
+
*/
|
|
158
|
+
function workerVersion(env) {
|
|
159
|
+
return workerVersionMetadata(env).id;
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { ENVIRONMENT_VAR, PROJECT_VAR, VERSION_METADATA_BINDING, WORKER_ORIGIN_VAR, WORKER_VAR, workerIdentity, workerVersion, workerVersionMetadata };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BindingSpecInput } from "../capability/bindings";
|
|
2
|
+
import type { RegisteredWorkflow, WorkflowSpec, WorkflowSpecMap } from "./spec";
|
|
3
|
+
/**
|
|
4
|
+
* The one derivation from a durable job to the `workflow` binding that job needs.
|
|
5
|
+
*
|
|
6
|
+
* **Every capability that owns a Workflow wrote this by hand, and six of them wrote it wrong.**
|
|
7
|
+
* `Object.values(map).map((spec) => ({ type: "workflow", name: spec.binding, optional: spec.optional }))`
|
|
8
|
+
* appeared verbatim in payments, storage, support, vector, testers and media, and once more in
|
|
9
|
+
* `createBackend`. It drops two fields, and dropping them is not cosmetic: `project/bindingEntries.ts`
|
|
10
|
+
* needs `job` to compose the deployed Workflow's name and `className` to emit `class_name`, refuses to
|
|
11
|
+
* write a partial `workflows` entry because wrangler rejects one, and returns `undefined` instead. So
|
|
12
|
+
* `pithy upgrade` reported adding five bindings it had silently declined to write, and `pithy doctor`
|
|
13
|
+
* — run seconds later against the same tree — correctly still called them missing (#318).
|
|
14
|
+
*
|
|
15
|
+
* **The `job` is the map key.** That is the whole reason `Object.values` was the wrong iterator: the
|
|
16
|
+
* field the writer needs most is the one a values-only walk cannot see. `Object.entries` is not a
|
|
17
|
+
* detail to remember at six call sites; it is this function.
|
|
18
|
+
*
|
|
19
|
+
* `className` rides through as declared — a spec may honestly omit it, for a job whose host config is
|
|
20
|
+
* hand-maintained — and `capabilities/requiredBindings.test.ts` is what turns an omission that reaches
|
|
21
|
+
* a shipped manifest into a build failure rather than a binding nothing writes.
|
|
22
|
+
*/
|
|
23
|
+
export declare function workflowBinding(job: string, spec: WorkflowSpec): BindingSpecInput;
|
|
24
|
+
/**
|
|
25
|
+
* Every binding a capability's durable jobs require, derived from the job map itself.
|
|
26
|
+
*
|
|
27
|
+
* What a capability's `requiredBindings` spreads, so the declaration is one line that cannot lose a
|
|
28
|
+
* field. A binding rename, a new job, or a class rename travels from the spec to `wrangler.jsonc`
|
|
29
|
+
* without anything in between being edited.
|
|
30
|
+
*/
|
|
31
|
+
export declare function workflowBindings(workflows: WorkflowSpecMap): BindingSpecInput[];
|
|
32
|
+
/**
|
|
33
|
+
* The same derivation from a {@link RegisteredWorkflow} — a spec already resolved against the
|
|
34
|
+
* capability that declared it, which is the shape `createBackend`'s composed registry holds.
|
|
35
|
+
*
|
|
36
|
+
* It exists so the assembly-time derivation and the capability-time one are the same function rather
|
|
37
|
+
* than the same four lines twice. `entry.job` is the registry's own copy of the map key, so the
|
|
38
|
+
* binding it derives is byte-identical to the one the capability declared.
|
|
39
|
+
*/
|
|
40
|
+
export declare function registeredWorkflowBinding(entry: RegisteredWorkflow): BindingSpecInput;
|
|
41
|
+
//# sourceMappingURL=bindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../src/workflow/bindings.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAQjF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,gBAAgB,EAAE,CAE/E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,kBAAkB,GAAG,gBAAgB,CAErF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/workflow/bindings.ts
|
|
2
|
+
/**
|
|
3
|
+
* The one derivation from a durable job to the `workflow` binding that job needs.
|
|
4
|
+
*
|
|
5
|
+
* **Every capability that owns a Workflow wrote this by hand, and six of them wrote it wrong.**
|
|
6
|
+
* `Object.values(map).map((spec) => ({ type: "workflow", name: spec.binding, optional: spec.optional }))`
|
|
7
|
+
* appeared verbatim in payments, storage, support, vector, testers and media, and once more in
|
|
8
|
+
* `createBackend`. It drops two fields, and dropping them is not cosmetic: `project/bindingEntries.ts`
|
|
9
|
+
* needs `job` to compose the deployed Workflow's name and `className` to emit `class_name`, refuses to
|
|
10
|
+
* write a partial `workflows` entry because wrangler rejects one, and returns `undefined` instead. So
|
|
11
|
+
* `pithy upgrade` reported adding five bindings it had silently declined to write, and `pithy doctor`
|
|
12
|
+
* — run seconds later against the same tree — correctly still called them missing (#318).
|
|
13
|
+
*
|
|
14
|
+
* **The `job` is the map key.** That is the whole reason `Object.values` was the wrong iterator: the
|
|
15
|
+
* field the writer needs most is the one a values-only walk cannot see. `Object.entries` is not a
|
|
16
|
+
* detail to remember at six call sites; it is this function.
|
|
17
|
+
*
|
|
18
|
+
* `className` rides through as declared — a spec may honestly omit it, for a job whose host config is
|
|
19
|
+
* hand-maintained — and `capabilities/requiredBindings.test.ts` is what turns an omission that reaches
|
|
20
|
+
* a shipped manifest into a build failure rather than a binding nothing writes.
|
|
21
|
+
*/
|
|
22
|
+
function workflowBinding(job, spec) {
|
|
23
|
+
return {
|
|
24
|
+
type: "workflow",
|
|
25
|
+
name: spec.binding,
|
|
26
|
+
job,
|
|
27
|
+
...spec.className === void 0 ? {} : { className: spec.className },
|
|
28
|
+
optional: spec.optional ?? false
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Every binding a capability's durable jobs require, derived from the job map itself.
|
|
33
|
+
*
|
|
34
|
+
* What a capability's `requiredBindings` spreads, so the declaration is one line that cannot lose a
|
|
35
|
+
* field. A binding rename, a new job, or a class rename travels from the spec to `wrangler.jsonc`
|
|
36
|
+
* without anything in between being edited.
|
|
37
|
+
*/
|
|
38
|
+
function workflowBindings(workflows) {
|
|
39
|
+
return Object.entries(workflows).map(([job, spec]) => workflowBinding(job, spec));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The same derivation from a {@link RegisteredWorkflow} — a spec already resolved against the
|
|
43
|
+
* capability that declared it, which is the shape `createBackend`'s composed registry holds.
|
|
44
|
+
*
|
|
45
|
+
* It exists so the assembly-time derivation and the capability-time one are the same function rather
|
|
46
|
+
* than the same four lines twice. `entry.job` is the registry's own copy of the map key, so the
|
|
47
|
+
* binding it derives is byte-identical to the one the capability declared.
|
|
48
|
+
*/
|
|
49
|
+
function registeredWorkflowBinding(entry) {
|
|
50
|
+
return workflowBinding(entry.job, entry.spec);
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { registeredWorkflowBinding, workflowBinding, workflowBindings };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Logger } from "../logger/logger";
|
|
2
|
+
import { type LoopbackFetch } from "./loopback";
|
|
3
|
+
import type { WorkflowBinding, WorkflowRegistry } from "./spec";
|
|
4
|
+
/**
|
|
5
|
+
* Dispatch: start a registered job by its `<capability>/<job>` key.
|
|
6
|
+
*
|
|
7
|
+
* Two things happen before the binding is touched, in this order. The key resolves against the
|
|
8
|
+
* registry, so a typo is `core/unknown_workflow` rather than a `TypeError` on `undefined.create`.
|
|
9
|
+
* Then the params parse through the spec's schema, so a malformed payload is
|
|
10
|
+
* `core/invalid_workflow_params` at the call site — with the offending field named — instead of a
|
|
11
|
+
* failed step inside a running instance, where the only signal is a retry budget burning down and
|
|
12
|
+
* the payload is no longer in anyone's hands.
|
|
13
|
+
*
|
|
14
|
+
* The dispatcher is a closure over the per-request `env`, built once per request by
|
|
15
|
+
* `createBackend` and served as `c.var.workflows`.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The typed dispatcher. `Params` maps each `<capability>/<job>` key to that job's parameter type,
|
|
19
|
+
* derived by `createBackend` from the composed capabilities — so `trigger` autocompletes the key
|
|
20
|
+
* set and type-checks the payload against the declaring capability's schema.
|
|
21
|
+
*/
|
|
22
|
+
export interface WorkflowDispatcher<Params extends Record<string, unknown> = Record<string, unknown>> {
|
|
23
|
+
/**
|
|
24
|
+
* Start an instance of one job. Resolves once Cloudflare has accepted the instance; it does not
|
|
25
|
+
* wait for the Workflow to finish. Instance status and termination are deliberately not on this
|
|
26
|
+
* seam — a Workflow is durable precisely so the caller need not hold its progress.
|
|
27
|
+
*/
|
|
28
|
+
trigger<Key extends keyof Params & string>(key: Key, params: Params[Key]): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read a binding off the per-request env, narrowed to the one method dispatch needs.
|
|
32
|
+
*
|
|
33
|
+
* Exported because the host's dispatch route ({@link ./dispatchRoute.ts}) asks the same question of
|
|
34
|
+
* the same env, and a second duck-type would be a second answer to "is this a Workflow binding" the
|
|
35
|
+
* first day one of them learned about a new shape.
|
|
36
|
+
*/
|
|
37
|
+
export declare function workflowBindingFor(env: Record<string, unknown>, name: string): WorkflowBinding | undefined;
|
|
38
|
+
/** What resolving a binding needs to know: which one, whose, and how to reach a sibling. */
|
|
39
|
+
export interface WorkflowBindingRequest {
|
|
40
|
+
/** The binding name on the caller's own env — `EMAIL_SENDER`. */
|
|
41
|
+
binding: string;
|
|
42
|
+
/** The capability that owns the host. Names the origin var, and names the worker in a failure. */
|
|
43
|
+
capability: string;
|
|
44
|
+
/** Where a substitution is noted. Defaults to silence. */
|
|
45
|
+
log?: Logger;
|
|
46
|
+
/** The loopback transport. Defaults to the runtime's `fetch`; injectable for tests. */
|
|
47
|
+
fetch?: LoopbackFetch;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The binding to dispatch on: the real one, or — under `pithy dev` — a loopback stand-in for it.
|
|
51
|
+
*
|
|
52
|
+
* ## Why a stand-in exists at all
|
|
53
|
+
*
|
|
54
|
+
* A deployed app Worker starts a capability's Workflow through a **cross-script** binding pointing at
|
|
55
|
+
* `<project>-<env>-email`. `pithy dev` runs no script under that name, so locally that binding cannot
|
|
56
|
+
* work — it is absent, or it is present and every `create` on it fails — and every dispatch it carried
|
|
57
|
+
* went nowhere (pithy-sh/pithy#410). What *does* exist locally is the capability host itself, on a
|
|
58
|
+
* pinned port, with its address in this Worker's own vars as `<STEM>_ORIGIN`. So the seam is filled
|
|
59
|
+
* rather than left empty, and the call site — `enqueueEmail`, the cron handler, `c.var.workflows` — is
|
|
60
|
+
* byte-identical either way.
|
|
61
|
+
*
|
|
62
|
+
* ## Three rules, and each of them is a refusal
|
|
63
|
+
*
|
|
64
|
+
* **In `dev`, a published origin wins over the binding.** The deliberate order, and the one that
|
|
65
|
+
* closes #410 whatever wrangler decides to hand a local Worker for a script it is not running: a
|
|
66
|
+
* binding that is present but cannot reach anything is indistinguishable at runtime from one that
|
|
67
|
+
* works, so preferring it would leave the silence in place and depend on a wrangler behavior nothing
|
|
68
|
+
* here controls. Preferring the origin costs nothing, because a published origin is not something a
|
|
69
|
+
* composition can have by accident — see the next rule.
|
|
70
|
+
*
|
|
71
|
+
* **A published origin names a host `pithy dev` is running.** The orchestrator writes one `--var` per
|
|
72
|
+
* *capability host* in the dev set, and never hands a host its own address. So `EMAIL_ORIGIN` on a
|
|
73
|
+
* Worker's env means exactly one thing: the email host is up, locally, there. An adopter's own
|
|
74
|
+
* app-owned Workflow — the same-script shape, which `wrangler dev` implements unchanged — is never
|
|
75
|
+
* published an origin and so is never diverted.
|
|
76
|
+
*
|
|
77
|
+
* **Only `dev`.** Not `staging`, not `prod`, and — the case that matters — not a composition that
|
|
78
|
+
* stamped no environment at all. A gate that reads silence as `dev` opens itself in exactly the
|
|
79
|
+
* deployment whose `wrangler.jsonc` lost the var.
|
|
80
|
+
*
|
|
81
|
+
* **The environment comes off the request env, not off the host's shell.** `--var ENVIRONMENT` is
|
|
82
|
+
* what puts it on a Worker, and the shell that ran `wrangler dev` does not cross into workerd. The
|
|
83
|
+
* dispatch *route* reads the ambient env instead, because it is registered before any request exists;
|
|
84
|
+
* here there is a request env in hand, and it is the truthful one.
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveWorkflowBinding(env: Record<string, unknown>, request: WorkflowBindingRequest): WorkflowBinding | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Start one registered job. The single dispatch path — `createBackend`'s per-request dispatcher and
|
|
89
|
+
* `createEntrypoint`'s cron handler both route through here, so a scheduled run and a manual one
|
|
90
|
+
* validate identically.
|
|
91
|
+
*/
|
|
92
|
+
export declare function triggerWorkflow(env: Record<string, unknown>, registry: WorkflowRegistry, key: string, params: unknown, log?: Logger): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Build the per-request dispatcher over one registry. A closure rather than a lazily-built registry
|
|
95
|
+
* object: there is one method and no per-job resource to construct, so there is nothing to defer.
|
|
96
|
+
*/
|
|
97
|
+
export declare function buildWorkflowDispatcher<Params extends Record<string, unknown> = Record<string, unknown>>(env: Record<string, unknown>, registry: WorkflowRegistry, log?: Logger): WorkflowDispatcher<Params>;
|
|
98
|
+
//# sourceMappingURL=dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/workflow/dispatch.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,KAAK,aAAa,EAA2B,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAEhE;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClG;;;;OAIG;IACH,OAAO,CAAC,GAAG,SAAS,MAAM,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAK1G;AAKD,4FAA4F;AAC5F,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,sBAAsB,GAC9B,eAAe,GAAG,SAAS,CAqB7B;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,GAAG,GAAE,MAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CA0Ef;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtG,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,GAAE,MAAmB,GACvB,kBAAkB,CAAC,MAAM,CAAC,CAI5B"}
|