@pithy-sh/core 0.1.2 → 0.1.4
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,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Cloudflare will actually accept as a name, per namespace — and, where it publishes nothing,
|
|
3
|
+
* what Pithy chooses instead.
|
|
4
|
+
*
|
|
5
|
+
* Pithy used to hold one number, 63, against every namespace it writes into, justified as "R2's
|
|
6
|
+
* cap". That is true of R2 and of nothing else. It over-truncated a KV title by a factor of eight
|
|
7
|
+
* and truncated D1 databases, Secrets Store entries, and API token labels against limits that do
|
|
8
|
+
* not exist — `secrets-encryption-keys` came out of it as `secrets-encryp-91c2e9`, hashed for
|
|
9
|
+
* nothing. A truncated name is not merely ugly: it is the name teardown must recompute exactly, and
|
|
10
|
+
* the name a human has to recognize in a dashboard listing that cannot be filtered.
|
|
11
|
+
*
|
|
12
|
+
* Every row below carries its source. `cloudflare` means the number is documented (limits page,
|
|
13
|
+
* OpenAPI schema, or wrangler's own constant, verified 2026-07-31); `pithy` means Cloudflare
|
|
14
|
+
* publishes no cap and this is our ceiling, chosen and stated as ours.
|
|
15
|
+
*/
|
|
16
|
+
/** Where a limit comes from — Cloudflare's documentation, or Pithy's own judgment. */
|
|
17
|
+
export type LimitSource = "cloudflare" | "pithy";
|
|
18
|
+
/**
|
|
19
|
+
* What to do with a name that will not fit.
|
|
20
|
+
*
|
|
21
|
+
* **`refuse`** where the name is a durable address: a Workflow (renaming orphans every running
|
|
22
|
+
* instance), a Worker script (renaming orphans the deployment and every `service` binding pointing
|
|
23
|
+
* at it), a Vectorize index (renaming orphans the vectors — they cannot be re-embedded for free).
|
|
24
|
+
* A build error naming the limit is strictly better than a silent rename.
|
|
25
|
+
*
|
|
26
|
+
* **`truncate`** where Pithy recomputes the name from the same inputs on every command — a D1
|
|
27
|
+
* database, a KV namespace, a bucket, a secret entry, a token. Truncation is deterministic and
|
|
28
|
+
* hash-disambiguated, so provision and teardown still agree, and a failed CI run is avoided.
|
|
29
|
+
*/
|
|
30
|
+
export type OverflowPolicy = "refuse" | "truncate";
|
|
31
|
+
/** One namespace's rule: how long a name may be, and what happens when it would be longer. */
|
|
32
|
+
export interface NamespaceLimit {
|
|
33
|
+
/** How an error message names this namespace, e.g. `an R2 bucket name`. */
|
|
34
|
+
readonly label: string;
|
|
35
|
+
/** The longest name the namespace accepts. Pithy composes ASCII only, so characters are bytes. */
|
|
36
|
+
readonly maxLength: number;
|
|
37
|
+
/** The shortest name the namespace accepts. Only R2 states one; everywhere else it is 1. */
|
|
38
|
+
readonly minLength: number;
|
|
39
|
+
/** What happens to a name that would exceed {@link maxLength}. */
|
|
40
|
+
readonly policy: OverflowPolicy;
|
|
41
|
+
/** Whether {@link maxLength} is Cloudflare's number or Pithy's. */
|
|
42
|
+
readonly source: LimitSource;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Pithy's ceiling for a namespace Cloudflare does not cap — D1 database names, Secrets Store
|
|
46
|
+
* entries, API token labels.
|
|
47
|
+
*
|
|
48
|
+
* **This is our number, not Cloudflare's.** No published cap is not the same as no cap: a name is
|
|
49
|
+
* read by humans in unfilterable listings, echoed in CLI output, and pasted into wrangler configs,
|
|
50
|
+
* so it needs an end. 128 is twice the longest limit Cloudflare does publish (64) and roughly twice
|
|
51
|
+
* the longest name Pithy can compose today, which leaves room for a capability with a long tail
|
|
52
|
+
* without ever reaching for the truncator.
|
|
53
|
+
*/
|
|
54
|
+
export declare const MAX_PITHY_NAME = 128;
|
|
55
|
+
/**
|
|
56
|
+
* The rule per namespace. Read it, do not re-derive it — a limit enforced in two places eventually
|
|
57
|
+
* disagrees with itself, and the number an error quotes must be the number the check used.
|
|
58
|
+
*/
|
|
59
|
+
export declare const NAMESPACE_LIMITS: {
|
|
60
|
+
/**
|
|
61
|
+
* A Workflow name: 64 characters, `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$`. Documented on the Workflows
|
|
62
|
+
* limits page, `maxLength: 64` in the OpenAPI schema, and `MAX_WORKFLOW_NAME_LENGTH` in wrangler.
|
|
63
|
+
*/
|
|
64
|
+
readonly workflow: {
|
|
65
|
+
readonly label: "a Workflow name";
|
|
66
|
+
readonly maxLength: 64;
|
|
67
|
+
readonly minLength: 1;
|
|
68
|
+
readonly policy: "refuse";
|
|
69
|
+
readonly source: "cloudflare";
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* A Worker script name: 255 in general, **63 once workers.dev is on**, alphanumeric and dashes
|
|
73
|
+
* with no leading or trailing dash. Pithy holds the 63: it is the only number that stays true
|
|
74
|
+
* after an adopter enables a workers.dev subdomain, and a script cannot be renamed afterwards.
|
|
75
|
+
* Deliberately one *less* than the Workflow cap — they are different resources with different
|
|
76
|
+
* numbers, and collapsing them would loosen this one.
|
|
77
|
+
*/
|
|
78
|
+
readonly worker: {
|
|
79
|
+
readonly label: "a Worker script name";
|
|
80
|
+
readonly maxLength: 63;
|
|
81
|
+
readonly minLength: 1;
|
|
82
|
+
readonly policy: "refuse";
|
|
83
|
+
readonly source: "cloudflare";
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* An R2 bucket: 3–63 characters, lowercase letters, digits and hyphens, and it must **start and
|
|
87
|
+
* end alphanumeric**. The one namespace where 63 was always the right answer.
|
|
88
|
+
*/
|
|
89
|
+
readonly r2: {
|
|
90
|
+
readonly label: "an R2 bucket name";
|
|
91
|
+
readonly maxLength: 63;
|
|
92
|
+
readonly minLength: 3;
|
|
93
|
+
readonly policy: "truncate";
|
|
94
|
+
readonly source: "cloudflare";
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A Vectorize index: 64 bytes, `^([a-z]+[a-z0-9_-]*[a-z0-9]+)$` — it must start with a letter,
|
|
98
|
+
* which the project rule already guarantees. Refused rather than truncated because a renamed
|
|
99
|
+
* index is an empty index until everything is re-embedded.
|
|
100
|
+
*/
|
|
101
|
+
readonly vectorizeIndex: {
|
|
102
|
+
readonly label: "a Vectorize index name";
|
|
103
|
+
readonly maxLength: 64;
|
|
104
|
+
readonly minLength: 2;
|
|
105
|
+
readonly policy: "refuse";
|
|
106
|
+
readonly source: "cloudflare";
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* A KV namespace title: 512 characters, no pattern at all — spaces and mixed case are accepted
|
|
110
|
+
* (`workers-kv_namespace_title.maxLength` in the OpenAPI schema). Pithy still composes a kebab
|
|
111
|
+
* title, for the same reason it composes every other name the same way; what changed is that it
|
|
112
|
+
* no longer hashes one at 63.
|
|
113
|
+
*/
|
|
114
|
+
readonly kv: {
|
|
115
|
+
readonly label: "a KV namespace title";
|
|
116
|
+
readonly maxLength: 512;
|
|
117
|
+
readonly minLength: 1;
|
|
118
|
+
readonly policy: "truncate";
|
|
119
|
+
readonly source: "cloudflare";
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* A D1 database name: `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` in the OpenAPI schema, and **no documented
|
|
123
|
+
* length cap** — the limits page has no row for it. So the ceiling here is {@link MAX_PITHY_NAME}.
|
|
124
|
+
*/
|
|
125
|
+
readonly d1: {
|
|
126
|
+
readonly label: "a D1 database name";
|
|
127
|
+
readonly maxLength: 128;
|
|
128
|
+
readonly minLength: 1;
|
|
129
|
+
readonly policy: "truncate";
|
|
130
|
+
readonly source: "pithy";
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* A Secrets Store entry name: "cannot contain spaces", wrangler enforces `/^[A-z0-9-_]+$/`, and
|
|
134
|
+
* **no documented length cap**. Ours, therefore — {@link MAX_PITHY_NAME}.
|
|
135
|
+
*/
|
|
136
|
+
readonly secretEntry: {
|
|
137
|
+
readonly label: "a Secrets Store entry name";
|
|
138
|
+
readonly maxLength: 128;
|
|
139
|
+
readonly minLength: 1;
|
|
140
|
+
readonly policy: "truncate";
|
|
141
|
+
readonly source: "pithy";
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* A Cloudflare API token name: a free-text label with **no documented cap**. Ours —
|
|
145
|
+
* {@link MAX_PITHY_NAME} — and it matters least of all, since nothing addresses a token by name.
|
|
146
|
+
*/
|
|
147
|
+
readonly apiToken: {
|
|
148
|
+
readonly label: "a Cloudflare API token name";
|
|
149
|
+
readonly maxLength: 128;
|
|
150
|
+
readonly minLength: 1;
|
|
151
|
+
readonly policy: "truncate";
|
|
152
|
+
readonly source: "pithy";
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
/** Every namespace the naming facade can compose into. */
|
|
156
|
+
export type Namespace = keyof typeof NAMESPACE_LIMITS;
|
|
157
|
+
/**
|
|
158
|
+
* The longest `<capability>-<job>` tail any capability registry declares today. Read off the
|
|
159
|
+
* registries, not guessed: `media-audio-transcribe` and `media-video-transcribe` are both 22, ahead
|
|
160
|
+
* of `payments-reconcile` (18), `vector-reprocess` (16), `support-classify` (16), `email-schedule`
|
|
161
|
+
* (14), `secrets-rotate` (14), `storage-sweep` (13), `testers-daily` (13).
|
|
162
|
+
*
|
|
163
|
+
* {@link WORKFLOW_DERIVED_PROJECT_NAME} is derived against it, so the two move together — and
|
|
164
|
+
* `workflowScriptName` refuses a longer tail rather than letting a new capability silently
|
|
165
|
+
* invalidate the project-name cap every existing project was accepted under.
|
|
166
|
+
*/
|
|
167
|
+
export declare const MAX_CAPABILITY_JOB: number;
|
|
168
|
+
/**
|
|
169
|
+
* Digits a feature's issue number may carry. Six — `f999999`, just under a million open issues in one
|
|
170
|
+
* repository, which nothing this toolkit will serve is going to exhaust.
|
|
171
|
+
*
|
|
172
|
+
* The count is not free: every digit reserved here costs one character of **every** adopter's project
|
|
173
|
+
* name, because {@link FEATURE_DERIVED_PROJECT_NAME} is computed against it and a project name cannot
|
|
174
|
+
* be changed once anything is provisioned. Seven digits would buy ten million issues nobody asked for
|
|
175
|
+
* and charge every project a character for them.
|
|
176
|
+
*/
|
|
177
|
+
export declare const MAX_ISSUE_DIGITS = 6;
|
|
178
|
+
/**
|
|
179
|
+
* The slug length a feature resource name keeps verbatim at the worst legal project name.
|
|
180
|
+
*
|
|
181
|
+
* Twelve, because that is where a feature slug stops being readable in a listing: below it,
|
|
182
|
+
* `fitSegment` has to fall back to a short head plus a six-hex disambiguator, and
|
|
183
|
+
* `acme-f95-medi-8f21c4-db-d1` tells a human nothing about which branch owns the database.
|
|
184
|
+
*/
|
|
185
|
+
export declare const MIN_LEGIBLE_SLUG = 12;
|
|
186
|
+
/**
|
|
187
|
+
* The binding length a feature resource name keeps verbatim at the worst legal project name.
|
|
188
|
+
*
|
|
189
|
+
* Also twelve — `MEDIA_BUCKET`, `SESSIONS`, `CACHE`, `ASSETS`, `DB`, `ROOMS` all fit. It is
|
|
190
|
+
* deliberately **not** the longest binding Pithy declares (`EMAIL_SUPPRESSIONS`, 18): reserving
|
|
191
|
+
* that would cost every adopter six characters of project name to protect a purely cosmetic
|
|
192
|
+
* property, since a longer binding truncates deterministically and stays unique through its hash,
|
|
193
|
+
* and teardown recomputes the name rather than matching a prefix.
|
|
194
|
+
*/
|
|
195
|
+
export declare const MIN_VERBATIM_BINDING = 12;
|
|
196
|
+
/** The longest feature resource kind — `d1`, `kv`, `r2` are all two characters. `feature.test.ts` pins it. */
|
|
197
|
+
export declare const MAX_FEATURE_KIND = 2;
|
|
198
|
+
/**
|
|
199
|
+
* What the longest Workflow name leaves a project.
|
|
200
|
+
*
|
|
201
|
+
* ```
|
|
202
|
+
* 64 a Workflow name (NAMESPACE_LIMITS.workflow)
|
|
203
|
+
* - 1 the hyphen before the environment
|
|
204
|
+
* - 7 the longest environment, `staging` (MAX_ENVIRONMENT_NAME)
|
|
205
|
+
* - 1 the hyphen before the tail
|
|
206
|
+
* - 22 the longest <capability>-<job>, `media-audio-transcribe`
|
|
207
|
+
* ----
|
|
208
|
+
* 33
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export declare const WORKFLOW_DERIVED_PROJECT_NAME: number;
|
|
212
|
+
/**
|
|
213
|
+
* What the longest feature resource name leaves a project — `<project>-f<issue>-<slug>-<binding>-<kind>`,
|
|
214
|
+
* against R2's 63 (the strictest of the three kinds a feature provisions, and the same number a
|
|
215
|
+
* feature Worker script gets).
|
|
216
|
+
*
|
|
217
|
+
* ```
|
|
218
|
+
* 63 an R2 bucket name (NAMESPACE_LIMITS.r2)
|
|
219
|
+
* - 2 `-f`
|
|
220
|
+
* - 6 the issue number, six digits — `f999999` (MAX_ISSUE_DIGITS)
|
|
221
|
+
* - 13 `-` + a legible slug (MIN_LEGIBLE_SLUG)
|
|
222
|
+
* - 13 `-` + a binding kept whole (MIN_VERBATIM_BINDING)
|
|
223
|
+
* - 3 `-` + the kind, `d1` | `kv` | `r2`
|
|
224
|
+
* ----
|
|
225
|
+
* 26
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export declare const FEATURE_DERIVED_PROJECT_NAME: number;
|
|
229
|
+
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/naming/limits.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AAEH,sFAAsF;AACtF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnD,8FAA8F;AAC9F,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;OAGG;;iBACS,KAAK,EAAE,iBAAiB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IACzG;;;;;;OAMG;;iBACO,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IAC5G;;;OAGG;;iBACG,KAAK,EAAE,mBAAmB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IACvG;;;;OAIG;;iBAED,KAAK,EAAE,wBAAwB;iBAC/B,SAAS,EAAE,EAAE;iBACb,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,QAAQ;iBAChB,MAAM,EAAE,YAAY;;IAEtB;;;;;OAKG;;iBACG,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,GAAG;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IAC3G;;;OAGG;;iBACG,KAAK,EAAE,oBAAoB;iBAAE,SAAS;iBAAkB,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,OAAO;;IAC/G;;;OAGG;;iBAED,KAAK,EAAE,4BAA4B;iBACnC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;IAEjB;;;OAGG;;iBAED,KAAK,EAAE,6BAA6B;iBACpC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;CAEgC,CAAC;AAEpD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAEtD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,8GAA8G;AAC9G,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAC+C,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,QAMjB,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { MAX_ENVIRONMENT_NAME } from "./environment.js";
|
|
2
|
+
//#region src/naming/limits.ts
|
|
3
|
+
/**
|
|
4
|
+
* Pithy's ceiling for a namespace Cloudflare does not cap — D1 database names, Secrets Store
|
|
5
|
+
* entries, API token labels.
|
|
6
|
+
*
|
|
7
|
+
* **This is our number, not Cloudflare's.** No published cap is not the same as no cap: a name is
|
|
8
|
+
* read by humans in unfilterable listings, echoed in CLI output, and pasted into wrangler configs,
|
|
9
|
+
* so it needs an end. 128 is twice the longest limit Cloudflare does publish (64) and roughly twice
|
|
10
|
+
* the longest name Pithy can compose today, which leaves room for a capability with a long tail
|
|
11
|
+
* without ever reaching for the truncator.
|
|
12
|
+
*/
|
|
13
|
+
const MAX_PITHY_NAME = 128;
|
|
14
|
+
/**
|
|
15
|
+
* The rule per namespace. Read it, do not re-derive it — a limit enforced in two places eventually
|
|
16
|
+
* disagrees with itself, and the number an error quotes must be the number the check used.
|
|
17
|
+
*/
|
|
18
|
+
const NAMESPACE_LIMITS = {
|
|
19
|
+
/**
|
|
20
|
+
* A Workflow name: 64 characters, `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$`. Documented on the Workflows
|
|
21
|
+
* limits page, `maxLength: 64` in the OpenAPI schema, and `MAX_WORKFLOW_NAME_LENGTH` in wrangler.
|
|
22
|
+
*/
|
|
23
|
+
workflow: {
|
|
24
|
+
label: "a Workflow name",
|
|
25
|
+
maxLength: 64,
|
|
26
|
+
minLength: 1,
|
|
27
|
+
policy: "refuse",
|
|
28
|
+
source: "cloudflare"
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* A Worker script name: 255 in general, **63 once workers.dev is on**, alphanumeric and dashes
|
|
32
|
+
* with no leading or trailing dash. Pithy holds the 63: it is the only number that stays true
|
|
33
|
+
* after an adopter enables a workers.dev subdomain, and a script cannot be renamed afterwards.
|
|
34
|
+
* Deliberately one *less* than the Workflow cap — they are different resources with different
|
|
35
|
+
* numbers, and collapsing them would loosen this one.
|
|
36
|
+
*/
|
|
37
|
+
worker: {
|
|
38
|
+
label: "a Worker script name",
|
|
39
|
+
maxLength: 63,
|
|
40
|
+
minLength: 1,
|
|
41
|
+
policy: "refuse",
|
|
42
|
+
source: "cloudflare"
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* An R2 bucket: 3–63 characters, lowercase letters, digits and hyphens, and it must **start and
|
|
46
|
+
* end alphanumeric**. The one namespace where 63 was always the right answer.
|
|
47
|
+
*/
|
|
48
|
+
r2: {
|
|
49
|
+
label: "an R2 bucket name",
|
|
50
|
+
maxLength: 63,
|
|
51
|
+
minLength: 3,
|
|
52
|
+
policy: "truncate",
|
|
53
|
+
source: "cloudflare"
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* A Vectorize index: 64 bytes, `^([a-z]+[a-z0-9_-]*[a-z0-9]+)$` — it must start with a letter,
|
|
57
|
+
* which the project rule already guarantees. Refused rather than truncated because a renamed
|
|
58
|
+
* index is an empty index until everything is re-embedded.
|
|
59
|
+
*/
|
|
60
|
+
vectorizeIndex: {
|
|
61
|
+
label: "a Vectorize index name",
|
|
62
|
+
maxLength: 64,
|
|
63
|
+
minLength: 2,
|
|
64
|
+
policy: "refuse",
|
|
65
|
+
source: "cloudflare"
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* A KV namespace title: 512 characters, no pattern at all — spaces and mixed case are accepted
|
|
69
|
+
* (`workers-kv_namespace_title.maxLength` in the OpenAPI schema). Pithy still composes a kebab
|
|
70
|
+
* title, for the same reason it composes every other name the same way; what changed is that it
|
|
71
|
+
* no longer hashes one at 63.
|
|
72
|
+
*/
|
|
73
|
+
kv: {
|
|
74
|
+
label: "a KV namespace title",
|
|
75
|
+
maxLength: 512,
|
|
76
|
+
minLength: 1,
|
|
77
|
+
policy: "truncate",
|
|
78
|
+
source: "cloudflare"
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* A D1 database name: `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` in the OpenAPI schema, and **no documented
|
|
82
|
+
* length cap** — the limits page has no row for it. So the ceiling here is {@link MAX_PITHY_NAME}.
|
|
83
|
+
*/
|
|
84
|
+
d1: {
|
|
85
|
+
label: "a D1 database name",
|
|
86
|
+
maxLength: 128,
|
|
87
|
+
minLength: 1,
|
|
88
|
+
policy: "truncate",
|
|
89
|
+
source: "pithy"
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* A Secrets Store entry name: "cannot contain spaces", wrangler enforces `/^[A-z0-9-_]+$/`, and
|
|
93
|
+
* **no documented length cap**. Ours, therefore — {@link MAX_PITHY_NAME}.
|
|
94
|
+
*/
|
|
95
|
+
secretEntry: {
|
|
96
|
+
label: "a Secrets Store entry name",
|
|
97
|
+
maxLength: 128,
|
|
98
|
+
minLength: 1,
|
|
99
|
+
policy: "truncate",
|
|
100
|
+
source: "pithy"
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* A Cloudflare API token name: a free-text label with **no documented cap**. Ours —
|
|
104
|
+
* {@link MAX_PITHY_NAME} — and it matters least of all, since nothing addresses a token by name.
|
|
105
|
+
*/
|
|
106
|
+
apiToken: {
|
|
107
|
+
label: "a Cloudflare API token name",
|
|
108
|
+
maxLength: 128,
|
|
109
|
+
minLength: 1,
|
|
110
|
+
policy: "truncate",
|
|
111
|
+
source: "pithy"
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* The longest `<capability>-<job>` tail any capability registry declares today. Read off the
|
|
116
|
+
* registries, not guessed: `media-audio-transcribe` and `media-video-transcribe` are both 22, ahead
|
|
117
|
+
* of `payments-reconcile` (18), `vector-reprocess` (16), `support-classify` (16), `email-schedule`
|
|
118
|
+
* (14), `secrets-rotate` (14), `storage-sweep` (13), `testers-daily` (13).
|
|
119
|
+
*
|
|
120
|
+
* {@link WORKFLOW_DERIVED_PROJECT_NAME} is derived against it, so the two move together — and
|
|
121
|
+
* `workflowScriptName` refuses a longer tail rather than letting a new capability silently
|
|
122
|
+
* invalidate the project-name cap every existing project was accepted under.
|
|
123
|
+
*/
|
|
124
|
+
const MAX_CAPABILITY_JOB = 22;
|
|
125
|
+
/**
|
|
126
|
+
* Digits a feature's issue number may carry. Six — `f999999`, just under a million open issues in one
|
|
127
|
+
* repository, which nothing this toolkit will serve is going to exhaust.
|
|
128
|
+
*
|
|
129
|
+
* The count is not free: every digit reserved here costs one character of **every** adopter's project
|
|
130
|
+
* name, because {@link FEATURE_DERIVED_PROJECT_NAME} is computed against it and a project name cannot
|
|
131
|
+
* be changed once anything is provisioned. Seven digits would buy ten million issues nobody asked for
|
|
132
|
+
* and charge every project a character for them.
|
|
133
|
+
*/
|
|
134
|
+
const MAX_ISSUE_DIGITS = 6;
|
|
135
|
+
/**
|
|
136
|
+
* The slug length a feature resource name keeps verbatim at the worst legal project name.
|
|
137
|
+
*
|
|
138
|
+
* Twelve, because that is where a feature slug stops being readable in a listing: below it,
|
|
139
|
+
* `fitSegment` has to fall back to a short head plus a six-hex disambiguator, and
|
|
140
|
+
* `acme-f95-medi-8f21c4-db-d1` tells a human nothing about which branch owns the database.
|
|
141
|
+
*/
|
|
142
|
+
const MIN_LEGIBLE_SLUG = 12;
|
|
143
|
+
/**
|
|
144
|
+
* The binding length a feature resource name keeps verbatim at the worst legal project name.
|
|
145
|
+
*
|
|
146
|
+
* Also twelve — `MEDIA_BUCKET`, `SESSIONS`, `CACHE`, `ASSETS`, `DB`, `ROOMS` all fit. It is
|
|
147
|
+
* deliberately **not** the longest binding Pithy declares (`EMAIL_SUPPRESSIONS`, 18): reserving
|
|
148
|
+
* that would cost every adopter six characters of project name to protect a purely cosmetic
|
|
149
|
+
* property, since a longer binding truncates deterministically and stays unique through its hash,
|
|
150
|
+
* and teardown recomputes the name rather than matching a prefix.
|
|
151
|
+
*/
|
|
152
|
+
const MIN_VERBATIM_BINDING = 12;
|
|
153
|
+
/** The longest feature resource kind — `d1`, `kv`, `r2` are all two characters. `feature.test.ts` pins it. */
|
|
154
|
+
const MAX_FEATURE_KIND = 2;
|
|
155
|
+
/**
|
|
156
|
+
* What the longest Workflow name leaves a project.
|
|
157
|
+
*
|
|
158
|
+
* ```
|
|
159
|
+
* 64 a Workflow name (NAMESPACE_LIMITS.workflow)
|
|
160
|
+
* - 1 the hyphen before the environment
|
|
161
|
+
* - 7 the longest environment, `staging` (MAX_ENVIRONMENT_NAME)
|
|
162
|
+
* - 1 the hyphen before the tail
|
|
163
|
+
* - 22 the longest <capability>-<job>, `media-audio-transcribe`
|
|
164
|
+
* ----
|
|
165
|
+
* 33
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
const WORKFLOW_DERIVED_PROJECT_NAME = NAMESPACE_LIMITS.workflow.maxLength - 1 - MAX_ENVIRONMENT_NAME - 1 - 22;
|
|
169
|
+
/**
|
|
170
|
+
* What the longest feature resource name leaves a project — `<project>-f<issue>-<slug>-<binding>-<kind>`,
|
|
171
|
+
* against R2's 63 (the strictest of the three kinds a feature provisions, and the same number a
|
|
172
|
+
* feature Worker script gets).
|
|
173
|
+
*
|
|
174
|
+
* ```
|
|
175
|
+
* 63 an R2 bucket name (NAMESPACE_LIMITS.r2)
|
|
176
|
+
* - 2 `-f`
|
|
177
|
+
* - 6 the issue number, six digits — `f999999` (MAX_ISSUE_DIGITS)
|
|
178
|
+
* - 13 `-` + a legible slug (MIN_LEGIBLE_SLUG)
|
|
179
|
+
* - 13 `-` + a binding kept whole (MIN_VERBATIM_BINDING)
|
|
180
|
+
* - 3 `-` + the kind, `d1` | `kv` | `r2`
|
|
181
|
+
* ----
|
|
182
|
+
* 26
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
const FEATURE_DERIVED_PROJECT_NAME = NAMESPACE_LIMITS.r2.maxLength - 2 - 6 - 13 - 13 - 3;
|
|
186
|
+
//#endregion
|
|
187
|
+
export { FEATURE_DERIVED_PROJECT_NAME, MAX_CAPABILITY_JOB, MAX_FEATURE_KIND, MAX_ISSUE_DIGITS, MAX_PITHY_NAME, MIN_LEGIBLE_SLUG, MIN_VERBATIM_BINDING, NAMESPACE_LIMITS, WORKFLOW_DERIVED_PROJECT_NAME };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type FeatureIdentity, type FeatureResourceKind } from "./feature";
|
|
2
|
+
/**
|
|
3
|
+
* **What a provisioning run names its resources, and which `env.<name>` stanza it writes them into —
|
|
4
|
+
* as one object, never two arguments.**
|
|
5
|
+
*
|
|
6
|
+
* Provisioning was specified for ephemeral feature environments and parameterized by `--env` before it
|
|
7
|
+
* was generalized to named ones. That left the namer and the target stanza as independent inputs, and
|
|
8
|
+
* A feature's namer with a declared environment beside it was the reachable consequence: it composed
|
|
9
|
+
* `<project>-f<issue>-<slug>-db` and wrote it in as `staging`'s `DB`. Nothing refused it, the ids went
|
|
10
|
+
* into a checked-in `wrangler.jsonc`, and a remote migrate ran against them.
|
|
11
|
+
*
|
|
12
|
+
* A guard against that combination would be a list of forbidden pairs. This is the invariant instead:
|
|
13
|
+
* **a scope is chosen once, and it carries both halves.** There is no call path that takes an
|
|
14
|
+
* environment name and a naming scheme separately, so there is no pair left to get wrong.
|
|
15
|
+
*
|
|
16
|
+
* Two scopes exist, and they are the two kinds of environment a project has:
|
|
17
|
+
*
|
|
18
|
+
* - {@link environmentScope} — a **declared** environment (`staging`, `prod`, whatever the root
|
|
19
|
+
* `pithy.config.ts` lists). Names are `<project>-<env>-<thing>`, the rule every other namer in the
|
|
20
|
+
* kit follows, so the environment segment of a name is always the stanza the name lives in.
|
|
21
|
+
* - {@link featureScope} — one branch's **ephemeral** environment. Names are
|
|
22
|
+
* `<project>-f<issue>-<slug>-<thing>`, with no environment segment because a feature *is* an
|
|
23
|
+
* environment, and the `f<issue>` marker is what teardown recomputes and what keeps a feature's
|
|
24
|
+
* database from ever being mistaken for a deployed one's.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Whether a secret's value differs per environment or is one value every environment binds.
|
|
28
|
+
*
|
|
29
|
+
* The same two words `@pithy-sh/secrets`' `SecretScope` uses, restated here as a literal union rather
|
|
30
|
+
* than imported: core carries the secret-registry *seam* and not the package, for the same reason
|
|
31
|
+
* `SecretRegistryEntrySeam` types `backend` as a `string`.
|
|
32
|
+
*/
|
|
33
|
+
export type SecretNameScope = "environment" | "global";
|
|
34
|
+
/** Where a provisioning run's resources are named, and where their ids are written. */
|
|
35
|
+
export interface ProvisionScope {
|
|
36
|
+
/** The `env.<stanza>` key in each Worker's config that this scope's ids are written into. */
|
|
37
|
+
readonly stanza: string;
|
|
38
|
+
/**
|
|
39
|
+
* **Are this scope's ids source, or a build artifact?**
|
|
40
|
+
*
|
|
41
|
+
* The same provisioning step produces both, and the difference is not cosmetic. A declared
|
|
42
|
+
* environment's ids are long-lived facts about the repository: they belong in the tracked
|
|
43
|
+
* `wrangler.jsonc`, under review, in a pull request a human reads. A feature's are facts about one
|
|
44
|
+
* job — the branch is deleted, the resources are destroyed, and the ids name nothing afterwards.
|
|
45
|
+
*
|
|
46
|
+
* Writing a feature's into the tracked file was correct as designed *in CI*, where the checkout is
|
|
47
|
+
* throwaway, and an expectation everywhere else: a developer's worktree carried a modified tracked
|
|
48
|
+
* file they never edited, with no note saying it must not be committed, and `git add -A` put ids for
|
|
49
|
+
* deleted resources onto `main`. So a build artifact goes somewhere untracked instead, and the
|
|
50
|
+
* question "which is this?" is answered here, once, by the same object that answers "what is it
|
|
51
|
+
* called?" and "which stanza does it go in?" — because those three answers have to agree.
|
|
52
|
+
*/
|
|
53
|
+
readonly source: boolean;
|
|
54
|
+
/** This scope's Cloudflare name for a provisionable binding. */
|
|
55
|
+
resource(binding: string, kind: FeatureResourceKind): string;
|
|
56
|
+
/** The script name a Worker deploys under in this scope. */
|
|
57
|
+
worker(worker: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* This scope's CF Secrets Store entry name for a declared secret.
|
|
60
|
+
*
|
|
61
|
+
* A `global` secret is the one name that does **not** take the scope's segment: it is a single
|
|
62
|
+
* account-level value every environment binds, so every scope resolves it to the project's
|
|
63
|
+
* `<project>-global-<secret>`. Scoping it would mint a second copy of a value defined as one.
|
|
64
|
+
*/
|
|
65
|
+
secretEntry(secret: string, secretScope: SecretNameScope): string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A declared environment's scope — `staging`, `prod`, or whatever the root `pithy.config.ts` lists.
|
|
69
|
+
*
|
|
70
|
+
* The environment is validated here, once, before a single name exists: it is the middle segment of
|
|
71
|
+
* every name below, so an illegal one must fail before anything is created rather than at the fourth
|
|
72
|
+
* getter that happened to use it.
|
|
73
|
+
*
|
|
74
|
+
* **A Worker's script name is wrangler's own, `<script>-<env>`, deliberately.** It is the one name here
|
|
75
|
+
* that is not `<project>-<env>-<thing>`, because `wrangler deploy --env staging` has always appended the
|
|
76
|
+
* environment to the top-level `name` — so every project that ever deployed is already at that address.
|
|
77
|
+
* A Worker script is a `refuse`-policy namespace precisely because renaming one orphans the deployment
|
|
78
|
+
* and every `service` binding pointing at it; composing a "more correct" name here would do exactly
|
|
79
|
+
* that, silently, on the next deploy. The name is written out rather than left implicit so a service
|
|
80
|
+
* binding and a deploy agree on one string that is in the file.
|
|
81
|
+
*/
|
|
82
|
+
export declare function environmentScope(project: string, environment: string): ProvisionScope;
|
|
83
|
+
/**
|
|
84
|
+
* One feature's scope — the ephemeral environment a branch gets, named from the branch rather than from
|
|
85
|
+
* an environment.
|
|
86
|
+
*
|
|
87
|
+
* Its stanza is {@link FEATURE_ENVIRONMENT} and nothing else, which is what makes a feature's resources
|
|
88
|
+
* in a declared environment's stanza unexpressible rather than merely discouraged.
|
|
89
|
+
*/
|
|
90
|
+
export declare function featureScope(identity: FeatureIdentity): ProvisionScope;
|
|
91
|
+
//# sourceMappingURL=provisionScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisionScope.d.ts","sourceRoot":"","sources":["../../src/naming/provisionScope.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;AAGnB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEvD,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAAC;IAC7D,4DAA4D;IAC5D,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC;CACnE;AAiBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CAYrF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAUtE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { FEATURE_ENVIRONMENT, assertValidEnvironment } from "./environment.js";
|
|
2
|
+
import { featureResourceName, featureSecretEntryName, featureWorkerName } from "./feature.js";
|
|
3
|
+
import { resourceNames } from "./resourceNames.js";
|
|
4
|
+
//#region src/naming/provisionScope.ts
|
|
5
|
+
/** The wrangler binding array a resource kind's name is composed for. */
|
|
6
|
+
const KIND_NAMER = {
|
|
7
|
+
d1: "d1",
|
|
8
|
+
kv: "kv",
|
|
9
|
+
r2: "r2"
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The one branch every scope shares: a `global` secret resolves to the project's single
|
|
13
|
+
* `<project>-global-<secret>` entry, and everything else to the scope's own name for it.
|
|
14
|
+
*
|
|
15
|
+
* Written once here rather than in each scope, because "global is not scoped" is a property of the
|
|
16
|
+
* secret and not of the environment asking — and two copies of it is how one of them would drift.
|
|
17
|
+
*/
|
|
18
|
+
function secretEntryName(project, secret, secretScope, scoped) {
|
|
19
|
+
if (secretScope === "global") return resourceNames(project).global.secretEntry(secret);
|
|
20
|
+
return scoped();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A declared environment's scope — `staging`, `prod`, or whatever the root `pithy.config.ts` lists.
|
|
24
|
+
*
|
|
25
|
+
* The environment is validated here, once, before a single name exists: it is the middle segment of
|
|
26
|
+
* every name below, so an illegal one must fail before anything is created rather than at the fourth
|
|
27
|
+
* getter that happened to use it.
|
|
28
|
+
*
|
|
29
|
+
* **A Worker's script name is wrangler's own, `<script>-<env>`, deliberately.** It is the one name here
|
|
30
|
+
* that is not `<project>-<env>-<thing>`, because `wrangler deploy --env staging` has always appended the
|
|
31
|
+
* environment to the top-level `name` — so every project that ever deployed is already at that address.
|
|
32
|
+
* A Worker script is a `refuse`-policy namespace precisely because renaming one orphans the deployment
|
|
33
|
+
* and every `service` binding pointing at it; composing a "more correct" name here would do exactly
|
|
34
|
+
* that, silently, on the next deploy. The name is written out rather than left implicit so a service
|
|
35
|
+
* binding and a deploy agree on one string that is in the file.
|
|
36
|
+
*/
|
|
37
|
+
function environmentScope(project, environment) {
|
|
38
|
+
assertValidEnvironment(environment);
|
|
39
|
+
const names = resourceNames(project).env(environment);
|
|
40
|
+
return {
|
|
41
|
+
stanza: environment,
|
|
42
|
+
source: true,
|
|
43
|
+
resource: (binding, kind) => names[KIND_NAMER[kind]](binding),
|
|
44
|
+
worker: (worker) => `${worker}-${environment}`,
|
|
45
|
+
secretEntry: (secret, secretScope) => secretEntryName(project, secret, secretScope, () => names.secretEntry(secret))
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* One feature's scope — the ephemeral environment a branch gets, named from the branch rather than from
|
|
50
|
+
* an environment.
|
|
51
|
+
*
|
|
52
|
+
* Its stanza is {@link FEATURE_ENVIRONMENT} and nothing else, which is what makes a feature's resources
|
|
53
|
+
* in a declared environment's stanza unexpressible rather than merely discouraged.
|
|
54
|
+
*/
|
|
55
|
+
function featureScope(identity) {
|
|
56
|
+
return {
|
|
57
|
+
stanza: FEATURE_ENVIRONMENT,
|
|
58
|
+
source: false,
|
|
59
|
+
resource: (binding, kind) => featureResourceName(identity, binding, kind),
|
|
60
|
+
worker: (worker) => featureWorkerName(identity, worker),
|
|
61
|
+
secretEntry: (secret, secretScope) => secretEntryName(identity.project, secret, secretScope, () => featureSecretEntryName(identity, secret))
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { environmentScope, featureScope };
|