@pithy-sh/core 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access/access.d.ts +172 -0
- package/dist/access/access.d.ts.map +1 -0
- package/dist/access/access.js +147 -0
- package/dist/access/acting.d.ts +49 -0
- package/dist/access/acting.d.ts.map +1 -0
- package/dist/access/acting.js +21 -0
- package/dist/access/policyCheck.d.ts +33 -0
- package/dist/access/policyCheck.d.ts.map +1 -0
- package/dist/access/policyCheck.js +48 -0
- package/dist/access/usage.d.ts +83 -0
- package/dist/access/usage.d.ts.map +1 -0
- package/dist/access/usage.js +104 -0
- package/dist/access/visibility.d.ts +66 -0
- package/dist/access/visibility.d.ts.map +1 -0
- package/dist/access/visibility.js +86 -0
- package/dist/asyncapi/document.d.ts +46 -0
- package/dist/asyncapi/document.d.ts.map +1 -0
- package/dist/asyncapi/document.js +115 -0
- package/dist/audit/auditEvent.d.ts +5 -0
- package/dist/audit/auditEvent.d.ts.map +1 -1
- package/dist/audit/auditEvent.js +2 -0
- package/dist/capability/bindings.d.ts +47 -2
- package/dist/capability/bindings.d.ts.map +1 -1
- package/dist/capability/bindings.js +117 -7
- package/dist/capability/capability.d.ts +105 -28
- package/dist/capability/capability.d.ts.map +1 -1
- package/dist/capability/composition.d.ts.map +1 -1
- package/dist/capability/composition.js +5 -1
- package/dist/capability/manifest.d.ts +2 -1
- package/dist/capability/manifest.d.ts.map +1 -1
- package/dist/capability/manifest.js +1 -1
- package/dist/capability/settings.d.ts +96 -4
- package/dist/capability/settings.d.ts.map +1 -1
- package/dist/capability/settings.js +85 -4
- package/dist/cli/command.d.ts +364 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +418 -0
- package/dist/cli/commandCatalog.generated.d.ts +2437 -0
- package/dist/cli/commandCatalog.generated.d.ts.map +1 -0
- package/dist/cli/commandCatalog.generated.js +2564 -0
- package/dist/cli/commandFacts.d.ts +164 -0
- package/dist/cli/commandFacts.d.ts.map +1 -0
- package/dist/cli/commandFacts.js +216 -0
- package/dist/controlPlane/capability.d.ts.map +1 -1
- package/dist/controlPlane/capability.js +12 -2
- package/dist/controlPlane/context.d.ts +5 -0
- package/dist/controlPlane/context.d.ts.map +1 -1
- package/dist/controlPlane/context.js +3 -1
- package/dist/controlPlane/data/connection.d.ts +47 -0
- package/dist/controlPlane/data/connection.d.ts.map +1 -1
- package/dist/controlPlane/data/connection.js +55 -1
- package/dist/controlPlane/error/errors.d.ts.map +1 -1
- package/dist/controlPlane/error/errors.js +4 -3
- package/dist/controlPlane/http/cors.d.ts +4 -4
- package/dist/controlPlane/http/cors.js +4 -4
- package/dist/controlPlane/http/guard.d.ts +11 -0
- package/dist/controlPlane/http/guard.d.ts.map +1 -1
- package/dist/controlPlane/http/guard.js +28 -2
- package/dist/controlPlane/http/handlers.d.ts +60 -0
- package/dist/controlPlane/http/handlers.d.ts.map +1 -1
- package/dist/controlPlane/http/handlers.js +31 -2
- package/dist/controlPlane/http/readiness.d.ts +33 -0
- package/dist/controlPlane/http/readiness.d.ts.map +1 -0
- package/dist/controlPlane/http/readiness.js +39 -0
- package/dist/controlPlane/http/responses.d.ts +147 -0
- package/dist/controlPlane/http/responses.d.ts.map +1 -1
- package/dist/controlPlane/http/responses.js +61 -4
- package/dist/controlPlane/http/routes.d.ts +2 -1
- package/dist/controlPlane/http/routes.d.ts.map +1 -1
- package/dist/controlPlane/http/routes.js +50 -9
- package/dist/controlPlane/http/verify.d.ts.map +1 -1
- package/dist/controlPlane/http/verify.js +2 -1
- package/dist/controlPlane/migrationState/migrationState.d.ts +102 -0
- package/dist/controlPlane/migrationState/migrationState.d.ts.map +1 -0
- package/dist/controlPlane/migrationState/migrationState.js +142 -0
- package/dist/controlPlane/migrations/0003_connection_principal.d.ts +21 -0
- package/dist/controlPlane/migrations/0003_connection_principal.d.ts.map +1 -0
- package/dist/controlPlane/migrations/0003_connection_principal.js +33 -0
- package/dist/controlPlane/scope/scope.d.ts +13 -2
- package/dist/controlPlane/scope/scope.d.ts.map +1 -1
- package/dist/controlPlane/scope/scope.js +14 -3
- package/dist/createBackend.d.ts +7 -0
- package/dist/createBackend.d.ts.map +1 -1
- package/dist/createBackend.js +41 -6
- package/dist/createEntrypoint.d.ts.map +1 -1
- package/dist/createEntrypoint.js +5 -3
- package/dist/entitlement/allowance.d.ts +25 -0
- package/dist/entitlement/allowance.d.ts.map +1 -0
- package/dist/entitlement/allowance.js +80 -0
- package/dist/entitlement/entitlement.d.ts +41 -0
- package/dist/entitlement/entitlement.d.ts.map +1 -1
- package/dist/entitlement/meter.d.ts +57 -0
- package/dist/entitlement/meter.d.ts.map +1 -0
- package/dist/entitlement/meter.js +13 -0
- package/dist/entitlement/require.js +1 -1
- package/dist/error/cause.d.ts +16 -116
- package/dist/error/cause.d.ts.map +1 -1
- package/dist/error/cause.js +19 -153
- package/dist/error/http.d.ts +184 -0
- package/dist/error/http.d.ts.map +1 -1
- package/dist/error/payload.d.ts +368 -0
- package/dist/error/payload.d.ts.map +1 -1
- package/dist/error/payload.js +126 -4
- package/dist/error/pithyError.d.ts +44 -0
- package/dist/error/pithyError.d.ts.map +1 -1
- package/dist/error/pithyError.js +56 -1
- package/dist/error/unresolved.d.ts +265 -0
- package/dist/error/unresolved.d.ts.map +1 -0
- package/dist/error/unresolved.js +599 -0
- package/dist/error/wire.d.ts +20 -0
- package/dist/error/wire.d.ts.map +1 -0
- package/dist/error/wire.js +19 -0
- package/dist/http/authContext.d.ts +7 -0
- package/dist/http/authContext.d.ts.map +1 -1
- package/dist/http/authContext.js +8 -1
- package/dist/http/oidcWebhook.d.ts +3 -3
- package/dist/http/oidcWebhook.js +3 -3
- package/dist/http/routeContract.js +1 -1
- package/dist/http/routeSpec.d.ts +66 -0
- package/dist/http/routeSpec.d.ts.map +1 -0
- package/dist/http/routeSpec.js +40 -0
- package/dist/http/sameOrigin.d.ts +1 -1
- package/dist/http/sameOrigin.js +1 -1
- package/dist/http/scopeGates.d.ts +20 -0
- package/dist/http/scopeGates.d.ts.map +1 -0
- package/dist/http/scopeGates.js +36 -0
- package/dist/http/signedWebhook.d.ts +3 -3
- package/dist/http/signedWebhook.js +3 -3
- package/dist/http/socket.d.ts +52 -0
- package/dist/http/socket.d.ts.map +1 -0
- package/dist/http/socket.js +2 -0
- package/dist/http/subprotocol.d.ts +29 -0
- package/dist/http/subprotocol.d.ts.map +1 -0
- package/dist/http/subprotocol.js +37 -0
- package/dist/http/validation.d.ts +40 -8
- package/dist/http/validation.d.ts.map +1 -1
- package/dist/http/validation.js +25 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/logger/record.d.ts +107 -0
- package/dist/logger/record.d.ts.map +1 -1
- package/dist/migrations/bookkeeping.d.ts +21 -0
- package/dist/migrations/bookkeeping.d.ts.map +1 -1
- package/dist/migrations/bookkeeping.js +32 -3
- package/dist/migrations/capabilitySets.d.ts +23 -0
- package/dist/migrations/capabilitySets.d.ts.map +1 -0
- package/dist/migrations/capabilitySets.js +74 -0
- package/dist/migrations/groups.d.ts +140 -0
- package/dist/migrations/groups.d.ts.map +1 -0
- package/dist/migrations/groups.js +191 -0
- package/dist/migrations/migrateStep.d.ts +13 -0
- package/dist/migrations/migrateStep.d.ts.map +1 -0
- package/dist/migrations/migrateStep.js +20 -0
- package/dist/migrations/owner.d.ts +7 -0
- package/dist/migrations/owner.d.ts.map +1 -1
- package/dist/migrations/owner.js +11 -7
- package/dist/migrations/registry.d.ts +26 -0
- package/dist/migrations/registry.d.ts.map +1 -1
- package/dist/migrations/registry.js +38 -7
- package/dist/migrations/retained.js +2 -2
- package/dist/migrations/runner.d.ts +76 -5
- package/dist/migrations/runner.d.ts.map +1 -1
- package/dist/migrations/runner.js +130 -19
- package/dist/migrations/state.d.ts +60 -0
- package/dist/migrations/state.d.ts.map +1 -0
- package/dist/migrations/state.js +46 -0
- package/dist/naming/domains.d.ts +17 -0
- package/dist/naming/domains.d.ts.map +1 -1
- package/dist/naming/domains.js +62 -4
- package/dist/naming/environment.d.ts.map +1 -1
- package/dist/naming/environment.js +2 -1
- package/dist/naming/feature.d.ts +27 -5
- package/dist/naming/feature.d.ts.map +1 -1
- package/dist/naming/feature.js +36 -6
- package/dist/naming/limits.d.ts +47 -3
- package/dist/naming/limits.d.ts.map +1 -1
- package/dist/naming/limits.js +47 -3
- package/dist/naming/packageName.d.ts +17 -0
- package/dist/naming/packageName.d.ts.map +1 -0
- package/dist/naming/packageName.js +22 -0
- package/dist/naming/provisionScope.d.ts +6 -0
- package/dist/naming/provisionScope.d.ts.map +1 -1
- package/dist/naming/provisionScope.js +10 -4
- package/dist/naming/resourceNames.d.ts +21 -2
- package/dist/naming/resourceNames.d.ts.map +1 -1
- package/dist/naming/resourceNames.js +21 -3
- package/dist/openapi/document.d.ts +106 -0
- package/dist/openapi/document.d.ts.map +1 -0
- package/dist/openapi/document.js +314 -0
- package/dist/openapi/routeGroups.d.ts +8 -0
- package/dist/openapi/routeGroups.d.ts.map +1 -0
- package/dist/openapi/routeGroups.js +23 -0
- package/dist/seed/writeD1.d.ts +7 -1
- package/dist/seed/writeD1.d.ts.map +1 -1
- package/dist/seed/writeD1.js +9 -3
- package/dist/seed/writeKv.d.ts +2 -0
- package/dist/seed/writeKv.d.ts.map +1 -1
- package/dist/seed/writeKv.js +6 -2
- package/dist/text/comments.js +66 -4
- package/dist/text/literals.d.ts +43 -0
- package/dist/text/literals.d.ts.map +1 -0
- package/dist/text/literals.js +293 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.d.ts.map +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/worker/serviceLoopback.d.ts +36 -0
- package/dist/worker/serviceLoopback.d.ts.map +1 -0
- package/dist/worker/serviceLoopback.js +74 -0
- package/dist/workflow/dispatchRoute.d.ts.map +1 -1
- package/dist/workflow/dispatchRoute.js +12 -6
- package/dist/workflow/faults.d.ts +12 -1
- package/dist/workflow/faults.d.ts.map +1 -1
- package/dist/workflow/faults.js +24 -18
- package/dist/workflow/hostEnv.d.ts +1 -0
- package/dist/workflow/hostEnv.d.ts.map +1 -1
- package/dist/workflow/hostEnv.js +4 -2
- package/dist/workflow/loopback.d.ts.map +1 -1
- package/dist/workflow/loopback.js +2 -1
- package/package.json +4 -4
- package/src/access/access.ts +298 -0
- package/src/access/acting.ts +59 -0
- package/src/access/policyCheck.ts +77 -0
- package/src/access/usage.ts +141 -0
- package/src/access/visibility.ts +109 -0
- package/src/asyncapi/document.ts +164 -0
- package/src/audit/auditEvent.ts +4 -0
- package/src/capability/bindings.ts +159 -13
- package/src/capability/capability.ts +106 -29
- package/src/capability/composition.ts +2 -1
- package/src/capability/settings.ts +165 -4
- package/src/cli/command.ts +865 -0
- package/src/cli/commandCatalog.generated.ts +2723 -0
- package/src/cli/commandFacts.ts +220 -0
- package/src/controlPlane/capability.ts +25 -1
- package/src/controlPlane/context.ts +4 -0
- package/src/controlPlane/data/connection.ts +90 -0
- package/src/controlPlane/error/errors.ts +10 -3
- package/src/controlPlane/http/cors.ts +4 -4
- package/src/controlPlane/http/guard.ts +35 -2
- package/src/controlPlane/http/handlers.ts +41 -0
- package/src/controlPlane/http/readiness.ts +50 -0
- package/src/controlPlane/http/responses.ts +140 -2
- package/src/controlPlane/http/routes.ts +82 -10
- package/src/controlPlane/http/verify.ts +2 -0
- package/src/controlPlane/migrationState/migrationState.ts +200 -0
- package/src/controlPlane/migrations/0003_connection_principal.ts +37 -0
- package/src/controlPlane/scope/scope.ts +14 -2
- package/src/createBackend.ts +59 -8
- package/src/createEntrypoint.ts +9 -3
- package/src/entitlement/allowance.ts +85 -0
- package/src/entitlement/entitlement.ts +38 -0
- package/src/entitlement/meter.ts +69 -0
- package/src/entitlement/require.ts +1 -1
- package/src/error/cause.ts +18 -181
- package/src/error/payload.ts +270 -4
- package/src/error/pithyError.ts +76 -0
- package/src/error/unresolved.ts +853 -0
- package/src/error/wire.ts +40 -0
- package/src/http/authContext.ts +13 -1
- package/src/http/oidcWebhook.ts +3 -3
- package/src/http/routeContract.ts +1 -1
- package/src/http/routeSpec.ts +81 -0
- package/src/http/sameOrigin.ts +1 -1
- package/src/http/scopeGates.ts +34 -0
- package/src/http/signedWebhook.ts +3 -3
- package/src/http/socket.ts +55 -0
- package/src/http/subprotocol.ts +47 -0
- package/src/http/validation.ts +50 -8
- package/src/index.ts +1 -0
- package/src/migrations/bookkeeping.ts +39 -2
- package/src/migrations/capabilitySets.ts +87 -0
- package/src/migrations/groups.ts +295 -0
- package/src/migrations/migrateStep.ts +19 -0
- package/src/migrations/owner.ts +10 -6
- package/src/migrations/registry.ts +46 -2
- package/src/migrations/retained.ts +2 -2
- package/src/migrations/runner.ts +214 -22
- package/src/migrations/state.ts +94 -0
- package/src/naming/domains.ts +75 -16
- package/src/naming/environment.ts +2 -1
- package/src/naming/feature.ts +46 -7
- package/src/naming/limits.ts +35 -3
- package/src/naming/packageName.ts +20 -0
- package/src/naming/provisionScope.ts +21 -2
- package/src/naming/resourceNames.ts +52 -5
- package/src/openapi/document.ts +412 -0
- package/src/openapi/routeGroups.ts +25 -0
- package/src/seed/writeD1.ts +13 -4
- package/src/seed/writeKv.ts +6 -2
- package/src/text/comments.ts +56 -4
- package/src/text/literals.ts +294 -0
- package/src/version.generated.ts +1 -1
- package/src/worker/serviceLoopback.ts +105 -0
- package/src/workflow/dispatchRoute.ts +13 -6
- package/src/workflow/faults.ts +56 -27
- package/src/workflow/hostEnv.ts +9 -1
- package/src/workflow/loopback.ts +2 -1
package/src/naming/limits.ts
CHANGED
|
@@ -107,6 +107,35 @@ export const NAMESPACE_LIMITS = {
|
|
|
107
107
|
* no longer hashes one at 63.
|
|
108
108
|
*/
|
|
109
109
|
kv: { label: "a KV namespace title", maxLength: 512, minLength: 1, policy: "truncate", source: "cloudflare" },
|
|
110
|
+
/**
|
|
111
|
+
* A Queue name: **1 to 63 characters**, lowercase letters, digits and dashes, starting and ending with a letter
|
|
112
|
+
* or number ([Queues · Get started](https://developers.cloudflare.com/queues/get-started/), verified
|
|
113
|
+
* 2026-10-18). Truncated rather than refused: Pithy recomputes a queue's name from its binding on every run,
|
|
114
|
+
* as it does a bucket's, so a deterministic hash is safe (#662). The same 63 as R2, so a feature's queue fits
|
|
115
|
+
* the shape {@link FEATURE_DERIVED_PROJECT_NAME} is derived against and moves no budget.
|
|
116
|
+
*/
|
|
117
|
+
queue: { label: "a Queue name", maxLength: 63, minLength: 1, policy: "truncate", source: "cloudflare" },
|
|
118
|
+
/**
|
|
119
|
+
* An Artifacts namespace: **2 to 63 characters**, starting with a letter or digit, the rest letters, digits, `.`,
|
|
120
|
+
* `_` and `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified
|
|
121
|
+
* 2026-10-18). Truncated rather than refused: the kit derives it from the project and the environment on every
|
|
122
|
+
* run, like an R2 bucket name, and the longest project and environment compose 34 characters, so it never is (#673).
|
|
123
|
+
*/
|
|
124
|
+
artifactsNamespace: {
|
|
125
|
+
label: "an Artifacts namespace name",
|
|
126
|
+
maxLength: 63,
|
|
127
|
+
minLength: 2,
|
|
128
|
+
policy: "truncate",
|
|
129
|
+
source: "cloudflare",
|
|
130
|
+
},
|
|
131
|
+
/**
|
|
132
|
+
* An Artifacts repo name. **The charset is Cloudflare's** — a letter or digit, then letters, digits, `.`, `_` and
|
|
133
|
+
* `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified 2026-10-18) —
|
|
134
|
+
* and **the length is ours**: that page states one for a namespace and none for a repo, so 2 to 63 mirrors the
|
|
135
|
+
* namespace rather than inventing a second number. Refused, never truncated: a repo name is either a UUID or a
|
|
136
|
+
* name somebody chose, and a name somebody chose is never silently shortened (#673).
|
|
137
|
+
*/
|
|
138
|
+
artifactsRepo: { label: "an Artifacts repo name", maxLength: 63, minLength: 2, policy: "refuse", source: "pithy" },
|
|
110
139
|
/**
|
|
111
140
|
* A D1 database name: `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` in the OpenAPI schema, and **no documented
|
|
112
141
|
* length cap** — the limits page has no row for it. So the ceiling here is {@link MAX_PITHY_NAME}.
|
|
@@ -196,7 +225,10 @@ export const FEATURE_TAIL_SEPARATOR = "--";
|
|
|
196
225
|
*/
|
|
197
226
|
export const MIN_VERBATIM_BINDING = 12;
|
|
198
227
|
|
|
199
|
-
/**
|
|
228
|
+
/**
|
|
229
|
+
* The longest feature resource kind segment — `d1`, `kv`, `r2`, and a queue's `q` (#662). `feature.test.ts` pins
|
|
230
|
+
* every kind's `FEATURE_KIND_SEGMENT` to it, so a longer segment fails rather than shrinking every project's budget.
|
|
231
|
+
*/
|
|
200
232
|
export const MAX_FEATURE_KIND = 2;
|
|
201
233
|
|
|
202
234
|
/**
|
|
@@ -217,7 +249,7 @@ export const WORKFLOW_DERIVED_PROJECT_NAME =
|
|
|
217
249
|
|
|
218
250
|
/**
|
|
219
251
|
* What the longest feature resource name leaves a project — `<project>-f<issue>-<slug>--<binding>-<kind>`,
|
|
220
|
-
* against R2's 63 (the strictest of the
|
|
252
|
+
* against R2's 63 (the strictest of the kinds a feature provisions, a queue's number too, and the same number a
|
|
221
253
|
* feature Worker script gets).
|
|
222
254
|
*
|
|
223
255
|
* ```
|
|
@@ -226,7 +258,7 @@ export const WORKFLOW_DERIVED_PROJECT_NAME =
|
|
|
226
258
|
* - 6 the issue number, six digits — `f999999` (MAX_ISSUE_DIGITS)
|
|
227
259
|
* - 12 `-` + a legible slug (MIN_LEGIBLE_SLUG)
|
|
228
260
|
* - 14 `--` + a binding kept whole (FEATURE_TAIL_SEPARATOR, MIN_VERBATIM_BINDING)
|
|
229
|
-
* - 3 `-` + the kind, `d1` | `kv` | `r2`
|
|
261
|
+
* - 3 `-` + the kind, `d1` | `kv` | `r2` | `q`
|
|
230
262
|
* ----
|
|
231
263
|
* 26
|
|
232
264
|
* ```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The package a bare specifier names: `@pithy-sh/payments` from `@pithy-sh/payments/src/capability`, and
|
|
6
|
+
* `stripe` from `stripe/lib/x` — **scope-aware, and the only copy in the kit (#709)**.
|
|
7
|
+
*
|
|
8
|
+
* There were five. Three took the first segment or two depending on a leading `@`; two took the first two
|
|
9
|
+
* segments whatever they were, which is right for every `@pithy-sh/*` name they were written against and
|
|
10
|
+
* wrong for the first unscoped dependency anyone passed them. A rule that small drifts precisely because
|
|
11
|
+
* nobody thinks it needs a home, so it has one. That it is the only copy is a gate, not a claim: `packages/cli/src/ci/packageOfCopies.test.ts` fails on any source that writes the rule out by hand, because the first migration left three behind and said it had not.
|
|
12
|
+
*
|
|
13
|
+
* Total, and deliberately unopinionated about what it is handed: a caller with a relative path, a `#`
|
|
14
|
+
* import or a URL gets the first segment back. Deciding whether a specifier is a package at all is the
|
|
15
|
+
* unresolved-import classifier's job (`error/unresolved.ts`), not this function's.
|
|
16
|
+
*/
|
|
17
|
+
export function packageOf(specifier: string): string {
|
|
18
|
+
const parts = specifier.split("/");
|
|
19
|
+
return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : (parts[0] ?? specifier);
|
|
20
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
+
import { commandName } from "../cli/command";
|
|
4
5
|
import { InternalError, ValidationError } from "../error/pithyError";
|
|
5
6
|
import type { WorkflowHostNameParts } from "../workflow/naming";
|
|
6
7
|
import { assertValidEnvironment, FEATURE_ENVIRONMENT, GLOBAL_SCOPE, isFeatureMarker } from "./environment";
|
|
7
8
|
import {
|
|
8
9
|
type FeatureIdentity,
|
|
9
10
|
type FeatureResourceKind,
|
|
11
|
+
featureArtifactsNamespace,
|
|
10
12
|
featureResourceName,
|
|
11
13
|
featureSecretEntryName,
|
|
12
14
|
featureWorkerName,
|
|
@@ -188,10 +190,21 @@ export interface ProvisionScope {
|
|
|
188
190
|
* `<project>-feature-email-send` would be one Workflow every open branch deployed over every other's.
|
|
189
191
|
*/
|
|
190
192
|
readonly workflowHost: Omit<WorkflowHostNameParts, "capability">;
|
|
193
|
+
/**
|
|
194
|
+
* The Artifacts namespace an `artifacts` binding names in this scope (#673): `<project>-<env>` in a declared
|
|
195
|
+
* environment, `<project>-f<issue>-<slug>--artifacts` in a feature. On the scope for the reason every other name
|
|
196
|
+
* is: the stanza a run writes and the namespace it writes into it are one decision.
|
|
197
|
+
*/
|
|
198
|
+
readonly artifactsNamespace: string;
|
|
191
199
|
}
|
|
192
200
|
|
|
193
201
|
/** The wrangler binding array a resource kind's name is composed for. */
|
|
194
|
-
const KIND_NAMER: Record<FeatureResourceKind, "d1" | "kv" | "r2"
|
|
202
|
+
const KIND_NAMER: Record<FeatureResourceKind, "d1" | "kv" | "r2" | "queue"> = {
|
|
203
|
+
d1: "d1",
|
|
204
|
+
kv: "kv",
|
|
205
|
+
r2: "r2",
|
|
206
|
+
queue: "queue",
|
|
207
|
+
};
|
|
195
208
|
|
|
196
209
|
/**
|
|
197
210
|
* The one branch every scope shares: a `global` secret resolves to the project's single
|
|
@@ -336,7 +349,7 @@ export function environmentScope(project: string, environment: string): Provisio
|
|
|
336
349
|
throw new ValidationError({
|
|
337
350
|
message: `The ${environment} Worker "${name}" is named the way a feature's Worker is.`,
|
|
338
351
|
action: `Rename it in env.${environment}.name, or the Worker's top-level name, so it does not follow ${kebab(project)}- with f and a number.`,
|
|
339
|
-
detail: `${declared === undefined ? "Composed by wrangler from the deploy name" : `Declared in env.${environment}.name`}. A feature's Worker is <project>-f<issue>-<slug>-<app>, and
|
|
352
|
+
detail: `${declared === undefined ? "Composed by wrangler from the deploy name" : `Declared in env.${environment}.name`}. A feature's Worker is <project>-f<issue>-<slug>-<app>, and \`${commandName("feature destroy")}\` deletes it by that exact name.`,
|
|
340
353
|
});
|
|
341
354
|
}
|
|
342
355
|
return name;
|
|
@@ -344,6 +357,7 @@ export function environmentScope(project: string, environment: string): Provisio
|
|
|
344
357
|
secretEntry: (secret, secretScope) =>
|
|
345
358
|
secretEntryName(project, secret, secretScope, () => names.secretEntry(secret)),
|
|
346
359
|
workflowHost: { project, env: environment },
|
|
360
|
+
artifactsNamespace: names.artifactsNamespace(),
|
|
347
361
|
};
|
|
348
362
|
}
|
|
349
363
|
|
|
@@ -391,6 +405,11 @@ export function featureScope(identity: FeatureIdentity): ProvisionScope {
|
|
|
391
405
|
secretEntry: (secret) => featureSecretEntryName(identity, secret),
|
|
392
406
|
// `env` is the stanza — what the host's `ENVIRONMENT` var says — and `feature` is what its names take.
|
|
393
407
|
workflowHost: { project: identity.project, env: FEATURE_ENVIRONMENT, feature: identity },
|
|
408
|
+
// The feature's own, read back as its own by `isFeatureOwnedName`, so teardown reaps no sibling's repos. A
|
|
409
|
+
// getter, so a slug too long for it refuses where the namespace is asked for, never where the scope is made.
|
|
410
|
+
get artifactsNamespace() {
|
|
411
|
+
return featureArtifactsNamespace(identity);
|
|
412
|
+
},
|
|
394
413
|
};
|
|
395
414
|
}
|
|
396
415
|
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
import { InternalError, ValidationError } from "../error/pithyError";
|
|
5
5
|
import { workflowHostName, workflowScriptName } from "../workflow/naming";
|
|
6
6
|
import { assertValidEnvironment, GLOBAL_SCOPE } from "./environment";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type FeatureIdentity,
|
|
9
|
+
type FeatureResourceKind,
|
|
10
|
+
featureArtifactsNamespace,
|
|
11
|
+
featureResourceName,
|
|
12
|
+
featureWorkerName,
|
|
13
|
+
} from "./feature";
|
|
8
14
|
import { NAMESPACE_LIMITS, type NamespaceLimit } from "./limits";
|
|
9
15
|
import { assertValidProjectName, kebab, resourceName } from "./resource";
|
|
10
16
|
|
|
@@ -57,6 +63,8 @@ export interface ScopedNames {
|
|
|
57
63
|
kv(binding: string): string;
|
|
58
64
|
/** An R2 bucket. Cloudflare's 63 — the one namespace where that number was always right. */
|
|
59
65
|
r2(binding: string): string;
|
|
66
|
+
/** A Queue. Cloudflare's 63, truncated with a stable hash like a bucket (#662). */
|
|
67
|
+
queue(binding: string): string;
|
|
60
68
|
/** A Vectorize index. 64 bytes, refused rather than truncated: a renamed index has no vectors. */
|
|
61
69
|
vectorizeIndex(index: string): string;
|
|
62
70
|
/** A Secrets Store entry. No Cloudflare cap; Pithy's ceiling. */
|
|
@@ -65,15 +73,33 @@ export interface ScopedNames {
|
|
|
65
73
|
apiToken(profile: string): string;
|
|
66
74
|
}
|
|
67
75
|
|
|
76
|
+
/**
|
|
77
|
+
* The names in one declared environment: everything a scope has, and the one name that exists per environment
|
|
78
|
+
* and never at `global`.
|
|
79
|
+
*/
|
|
80
|
+
export interface EnvironmentNames extends ScopedNames {
|
|
81
|
+
/**
|
|
82
|
+
* The Artifacts namespace — `<project>-<env>`, with no `<thing>` (#673). One per environment, so a feature's
|
|
83
|
+
* repos never sit beside production's and the per-namespace rate limit splits per environment. There is no
|
|
84
|
+
* global one, because a namespace shared across environments is exactly that mix.
|
|
85
|
+
*/
|
|
86
|
+
artifactsNamespace(): string;
|
|
87
|
+
}
|
|
88
|
+
|
|
68
89
|
/** The names a feature environment provisions under, with the project already bound. */
|
|
69
90
|
export interface FeatureNames {
|
|
70
|
-
/** A feature's D1, KV, or
|
|
91
|
+
/** A feature's D1, KV, R2 or Queue resource — `<project>-f<issue>-<slug>--<binding>-<kind>`. */
|
|
71
92
|
resource(binding: string, kind: FeatureResourceKind): string;
|
|
72
93
|
/**
|
|
73
94
|
* A feature's Worker script — `<project>-f<issue>-<slug>-<app>`, from the `apps/<app>` directory and
|
|
74
95
|
* never the deploy name, which already leads with the project (#587).
|
|
75
96
|
*/
|
|
76
97
|
worker(app: string): string;
|
|
98
|
+
/**
|
|
99
|
+
* A feature's Artifacts namespace — `<project>-f<issue>-<slug>--artifacts` (#673). The tail is what makes it a
|
|
100
|
+
* feature name `isFeatureOwnedName` reads back, so teardown reaps this feature's repos and no sibling's.
|
|
101
|
+
*/
|
|
102
|
+
artifactsNamespace(): string;
|
|
77
103
|
}
|
|
78
104
|
|
|
79
105
|
/** Everything a project can be asked to name. Created once, from the project, by {@link resourceNames}. */
|
|
@@ -81,7 +107,7 @@ export interface ProjectNames {
|
|
|
81
107
|
/** The kebabbed project name every name below leads with. */
|
|
82
108
|
readonly project: string;
|
|
83
109
|
/** The names in one environment. Throws if the environment is not one this scheme accepts. */
|
|
84
|
-
env(environment: string):
|
|
110
|
+
env(environment: string): EnvironmentNames;
|
|
85
111
|
/** The names shared by every environment — the `global` scope, without typing the word. */
|
|
86
112
|
readonly global: ScopedNames;
|
|
87
113
|
/** The names a feature environment provisions under. */
|
|
@@ -134,6 +160,22 @@ function scopedName(project: string, scope: string, thing: string, limit: Namesp
|
|
|
134
160
|
return name;
|
|
135
161
|
}
|
|
136
162
|
|
|
163
|
+
/**
|
|
164
|
+
* `<project>-<env>`, under the Artifacts namespace rule. The project and environment are both validated by now, and
|
|
165
|
+
* the longest of each compose 34 characters, so the cap is a check rather than a truncation that ever happens.
|
|
166
|
+
*/
|
|
167
|
+
function artifactsNamespaceName(project: string, environment: string): string {
|
|
168
|
+
const limit = NAMESPACE_LIMITS.artifactsNamespace;
|
|
169
|
+
const name = `${project}-${environment}`;
|
|
170
|
+
if (name.length > limit.maxLength || name.length < limit.minLength) {
|
|
171
|
+
throw new InternalError({
|
|
172
|
+
message: `"${name}" does not fit ${limit.label}, which takes ${limit.minLength} to ${limit.maxLength} characters.`,
|
|
173
|
+
action: "Shorten the project or environment name.",
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return name;
|
|
177
|
+
}
|
|
178
|
+
|
|
137
179
|
/** The getters for one scope. `global` and every environment share this, so nothing special-cases either. */
|
|
138
180
|
function scopedNames(project: string, scope: string): ScopedNames {
|
|
139
181
|
return {
|
|
@@ -142,6 +184,7 @@ function scopedNames(project: string, scope: string): ScopedNames {
|
|
|
142
184
|
d1: (binding) => scopedName(project, scope, binding, NAMESPACE_LIMITS.d1),
|
|
143
185
|
kv: (binding) => scopedName(project, scope, binding, NAMESPACE_LIMITS.kv),
|
|
144
186
|
r2: (binding) => scopedName(project, scope, binding, NAMESPACE_LIMITS.r2),
|
|
187
|
+
queue: (binding) => scopedName(project, scope, binding, NAMESPACE_LIMITS.queue),
|
|
145
188
|
vectorizeIndex: (index) => scopedName(project, scope, index, NAMESPACE_LIMITS.vectorizeIndex),
|
|
146
189
|
secretEntry: (secret) => scopedName(project, scope, secret, NAMESPACE_LIMITS.secretEntry),
|
|
147
190
|
apiToken: (profile) => scopedName(project, scope, profile, NAMESPACE_LIMITS.apiToken),
|
|
@@ -161,9 +204,12 @@ export function resourceNames(project: string): ProjectNames {
|
|
|
161
204
|
|
|
162
205
|
return {
|
|
163
206
|
project: normalized,
|
|
164
|
-
env(environment: string):
|
|
207
|
+
env(environment: string): EnvironmentNames {
|
|
165
208
|
assertValidEnvironment(environment);
|
|
166
|
-
return
|
|
209
|
+
return {
|
|
210
|
+
...scopedNames(normalized, environment),
|
|
211
|
+
artifactsNamespace: () => artifactsNamespaceName(normalized, environment),
|
|
212
|
+
};
|
|
167
213
|
},
|
|
168
214
|
global: scopedNames(normalized, GLOBAL_SCOPE),
|
|
169
215
|
feature(identity): FeatureNames {
|
|
@@ -171,6 +217,7 @@ export function resourceNames(project: string): ProjectNames {
|
|
|
171
217
|
return {
|
|
172
218
|
resource: (binding, kind) => featureResourceName(full, binding, kind),
|
|
173
219
|
worker: (app) => featureWorkerName(full, app),
|
|
220
|
+
artifactsNamespace: () => featureArtifactsNamespace(full),
|
|
174
221
|
};
|
|
175
222
|
},
|
|
176
223
|
};
|