@pithy-sh/core 0.6.1 → 0.7.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/capability/capability.d.ts.map +1 -1
- package/dist/capability/capability.js +2 -0
- package/dist/capability/settings.d.ts +15 -2
- package/dist/capability/settings.d.ts.map +1 -1
- package/dist/data/databases.d.ts +11 -0
- package/dist/data/databases.d.ts.map +1 -1
- package/dist/migrations/registry.d.ts +6 -0
- package/dist/migrations/registry.d.ts.map +1 -1
- package/dist/migrations/registry.js +2 -0
- package/dist/migrations/retained.d.ts +101 -0
- package/dist/migrations/retained.d.ts.map +1 -0
- package/dist/migrations/retained.js +243 -0
- package/dist/migrations/retainedDeclaration.d.ts +15 -0
- package/dist/migrations/retainedDeclaration.d.ts.map +1 -0
- package/dist/migrations/retainedDeclaration.js +49 -0
- package/dist/migrations/runner.d.ts +44 -7
- package/dist/migrations/runner.d.ts.map +1 -1
- package/dist/migrations/runner.js +41 -15
- package/dist/naming/environment.d.ts +12 -0
- package/dist/naming/environment.d.ts.map +1 -1
- package/dist/naming/environment.js +38 -1
- package/dist/naming/feature.d.ts +7 -1
- package/dist/naming/feature.d.ts.map +1 -1
- package/dist/naming/feature.js +10 -3
- package/dist/naming/provisionScope.d.ts +97 -9
- package/dist/naming/provisionScope.d.ts.map +1 -1
- package/dist/naming/provisionScope.js +87 -12
- package/dist/naming/resourceNames.d.ts +5 -2
- package/dist/naming/resourceNames.d.ts.map +1 -1
- package/dist/naming/resourceNames.js +1 -1
- package/dist/text/comments.d.ts +14 -0
- package/dist/text/comments.d.ts.map +1 -1
- package/dist/text/comments.js +28 -2
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/workflow/host.d.ts +8 -0
- package/dist/workflow/host.d.ts.map +1 -1
- package/dist/workflow/host.js +5 -2
- package/dist/workflow/hostEnv.d.ts +1 -1
- package/dist/workflow/hostEnv.js +1 -1
- package/package.json +1 -1
- package/src/capability/capability.ts +6 -0
- package/src/capability/settings.ts +15 -2
- package/src/data/databases.ts +11 -0
- package/src/migrations/registry.ts +10 -0
- package/src/migrations/retained.ts +319 -0
- package/src/migrations/retainedDeclaration.ts +56 -0
- package/src/migrations/runner.ts +89 -15
- package/src/naming/environment.ts +43 -0
- package/src/naming/feature.ts +10 -3
- package/src/naming/provisionScope.ts +130 -13
- package/src/naming/resourceNames.ts +6 -3
- package/src/text/comments.ts +31 -1
- package/src/version.generated.ts +1 -1
- package/src/workflow/host.ts +14 -4
- package/src/workflow/hostEnv.ts +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
import { InternalError } from "../error/pithyError";
|
|
5
|
-
import { assertValidEnvironment, FEATURE_ENVIRONMENT, GLOBAL_SCOPE } from "./environment";
|
|
4
|
+
import { InternalError, ValidationError } from "../error/pithyError";
|
|
5
|
+
import { assertValidEnvironment, FEATURE_ENVIRONMENT, GLOBAL_SCOPE, isFeatureMarker } from "./environment";
|
|
6
6
|
import {
|
|
7
7
|
type FeatureIdentity,
|
|
8
8
|
type FeatureResourceKind,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
featureSecretEntryName,
|
|
11
11
|
featureWorkerName,
|
|
12
12
|
} from "./feature";
|
|
13
|
+
import { kebab } from "./resource";
|
|
13
14
|
import { resourceNames } from "./resourceNames";
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -89,6 +90,28 @@ export interface ProjectGlobalNaming extends BindingNaming {
|
|
|
89
90
|
readonly scope: "global";
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
/**
|
|
94
|
+
* The two names one Worker answers to before a scope has named it — **and why a scope is handed both.**
|
|
95
|
+
*
|
|
96
|
+
* `pithy init replay --worker board` writes `apps/board/wrangler.jsonc` with `"name": "replay-board"`.
|
|
97
|
+
* So the Worker's directory says `board` and its deploy name says `replay-board`, and the two scopes need
|
|
98
|
+
* different ones. A declared environment's fallback is wrangler's own `<script>-<env>`, which is built on
|
|
99
|
+
* the deploy name. A feature's name is `<project>-f<issue>-<slug>-<app>`, which already leads with the
|
|
100
|
+
* project, so it is built on the directory.
|
|
101
|
+
*
|
|
102
|
+
* This was one string until #587, and the string was the deploy name, so every feature Worker carried the
|
|
103
|
+
* project twice: `replay-f69-demo-replay-board`. That was not only untidy. The name is held to the Worker
|
|
104
|
+
* cap of 63, and the doubled segment spent that budget where the truncation lands on the part that says
|
|
105
|
+
* *which* Worker. Carrying both names is what lets each scope take the one its shape is built from, and
|
|
106
|
+
* lets neither caller choose on the scope's behalf.
|
|
107
|
+
*/
|
|
108
|
+
export interface ProvisionWorkerNames {
|
|
109
|
+
/** The Worker's `apps/<app>` directory basename — the name a sibling's `service` binding targets it by. */
|
|
110
|
+
readonly app: string;
|
|
111
|
+
/** The Worker's deploy name — the top-level `name` of its `wrangler.jsonc`, e.g. `replay-board`. */
|
|
112
|
+
readonly script: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
92
115
|
/** Where a provisioning run's resources are named, and where their ids are written. */
|
|
93
116
|
export interface ProvisionScope {
|
|
94
117
|
/** The `env.<stanza>` key in each Worker's config that this scope's ids are written into. */
|
|
@@ -133,8 +156,18 @@ export interface ProvisionScope {
|
|
|
133
156
|
* is created, judged to be the project's, kept out of the teardown record, and orphaned.
|
|
134
157
|
*/
|
|
135
158
|
readonly honorsGlobal: boolean;
|
|
136
|
-
/**
|
|
137
|
-
|
|
159
|
+
/**
|
|
160
|
+
* The script name a Worker deploys under in this scope.
|
|
161
|
+
*
|
|
162
|
+
* `worker` carries **both** of the Worker's names, because the two scopes compose from different ones:
|
|
163
|
+
* a declared environment falls back to wrangler's `<script>-<env>`, and a feature composes
|
|
164
|
+
* `<project>-f<issue>-<slug>-<app>`. See {@link ProvisionWorkerNames}.
|
|
165
|
+
*
|
|
166
|
+
* `declared` is the name that scope's stanza already carries, when it carries one. A scope may honor it
|
|
167
|
+
* or compose its own; see {@link environmentScope} and {@link featureScope}, which answer differently
|
|
168
|
+
* and say why. Passing it is how a caller asks the scope rather than deciding for itself.
|
|
169
|
+
*/
|
|
170
|
+
worker(worker: ProvisionWorkerNames, declared?: string): string;
|
|
138
171
|
/**
|
|
139
172
|
* This scope's CF Secrets Store entry name for a declared secret.
|
|
140
173
|
*
|
|
@@ -221,6 +254,28 @@ export function bindingResourceName(
|
|
|
221
254
|
return scoped(thing);
|
|
222
255
|
}
|
|
223
256
|
|
|
257
|
+
/**
|
|
258
|
+
* **Is this name inside a feature's namespace** — `<project>-f<issue>-…`, the project and then a feature's
|
|
259
|
+
* marker, with something after it?
|
|
260
|
+
*
|
|
261
|
+
* The namespace, not one feature's names, because that is what has to stay disjoint: `pithy feature destroy`
|
|
262
|
+
* deletes by exact name, and a feature Worker's name has no kind suffix, so a declared environment's name
|
|
263
|
+
* that lands anywhere in here is one some branch's teardown can delete (#587). Every name {@link featureScope}
|
|
264
|
+
* composes is inside; {@link environmentScope} refuses to name a Worker inside, and `isValidEnvironment`
|
|
265
|
+
* refuses every environment whose composed names could be.
|
|
266
|
+
*
|
|
267
|
+
* **What it does not see.** It is stated for one project. A second project on the same account whose name is
|
|
268
|
+
* this one's plus `-f<issue>` — `acme-f1` beside `acme` — composes names inside `acme`'s namespace from an
|
|
269
|
+
* ordinary environment, and nothing here can tell, because a project name carries no boundary a later hyphen
|
|
270
|
+
* cannot fake. That is the hyphen ambiguity every composed name carries, one segment further left.
|
|
271
|
+
*/
|
|
272
|
+
export function isFeatureName(project: string, name: string): boolean {
|
|
273
|
+
const head = `${kebab(project)}-`;
|
|
274
|
+
if (!name.startsWith(head)) return false;
|
|
275
|
+
const [marker, ...rest] = name.slice(head.length).split("-");
|
|
276
|
+
return isFeatureMarker(marker ?? "") && rest.length > 0;
|
|
277
|
+
}
|
|
278
|
+
|
|
224
279
|
/**
|
|
225
280
|
* A declared environment's scope — `staging`, `prod`, or whatever the root `pithy.config.ts` lists.
|
|
226
281
|
*
|
|
@@ -228,13 +283,25 @@ export function bindingResourceName(
|
|
|
228
283
|
* every name below, so an illegal one must fail before anything is created rather than at the fourth
|
|
229
284
|
* getter that happened to use it.
|
|
230
285
|
*
|
|
231
|
-
* **A
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
286
|
+
* **A declared name wins; the fallback is wrangler's own, `<script>-<env>`.**
|
|
287
|
+
*
|
|
288
|
+
* This reverses the rule that stood here until #580, and the reversal is worth reading rather than
|
|
289
|
+
* assuming. The old rule *recomputed* `<script>-<env>` on every provision and wrote it over whatever the
|
|
290
|
+
* stanza said, on the argument that wrangler has always appended the environment to the top-level `name`,
|
|
291
|
+
* so every project that ever deployed is already at that address.
|
|
292
|
+
*
|
|
293
|
+
* That argument is still true about the **fallback**, and the fallback is unchanged: a stanza that names
|
|
294
|
+
* nothing gets `<script>-<env>` and every existing adopter deploys exactly where they always did. What was
|
|
295
|
+
* wrong was recomputing over a name somebody wrote down. Since #580 the starter template writes one —
|
|
296
|
+
* `<project>-<env>-<worker>`, the shape every other resource here takes — so recompute would have made the
|
|
297
|
+
* template's stamp pointless, and worse: it would have silently renamed the Worker of every project that
|
|
298
|
+
* had taken the new shape, on their next `pithy provision`. A Worker script is a `refuse`-policy namespace
|
|
299
|
+
* precisely because renaming one orphans the deployment, its routes, and every `service` binding pointing
|
|
300
|
+
* at it. Doing that as a side effect of provisioning is the failure the old rule was written to prevent,
|
|
301
|
+
* arriving from the other direction.
|
|
302
|
+
*
|
|
303
|
+
* So the name is read, not composed, when the file already holds one — and written out when it does not,
|
|
304
|
+
* so a service binding and a deploy still agree on one string that is in the file.
|
|
238
305
|
*/
|
|
239
306
|
export function environmentScope(project: string, environment: string): ProvisionScope {
|
|
240
307
|
assertValidEnvironment(environment);
|
|
@@ -247,7 +314,21 @@ export function environmentScope(project: string, environment: string): Provisio
|
|
|
247
314
|
honorsGlobal: true,
|
|
248
315
|
resource: (binding, kind, naming) =>
|
|
249
316
|
bindingResourceName(project, binding, kind, naming, (thing) => names[KIND_NAMER[kind]](thing)),
|
|
250
|
-
worker: (
|
|
317
|
+
worker: ({ script }, declared) => {
|
|
318
|
+
const name = declared ?? `${script}-${environment}`;
|
|
319
|
+
// The environment rule already keeps every name composed from the environment out of a feature's
|
|
320
|
+
// namespace. A declared name and wrangler's fallback are not composed from it — the stanza says one,
|
|
321
|
+
// the deploy name leads the other — so either can still sit there, and a branch's teardown would
|
|
322
|
+
// delete the Worker (#587). Refused here, where the name is chosen, rather than spared at teardown.
|
|
323
|
+
if (isFeatureName(project, name)) {
|
|
324
|
+
throw new ValidationError({
|
|
325
|
+
message: `The ${environment} Worker "${name}" is named the way a feature's Worker is.`,
|
|
326
|
+
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.`,
|
|
327
|
+
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 \`pithy feature destroy\` deletes it by that exact name.`,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
return name;
|
|
331
|
+
},
|
|
251
332
|
secretEntry: (secret, secretScope) =>
|
|
252
333
|
secretEntryName(project, secret, secretScope, () => names.secretEntry(secret)),
|
|
253
334
|
};
|
|
@@ -272,6 +353,12 @@ export function environmentScope(project: string, environment: string): Provisio
|
|
|
272
353
|
* `resource` is ignored for the same reason it is moot: a feature's `<thing>` segment is the binding plus
|
|
273
354
|
* the kind, and the whole name is recomputed on teardown rather than looked up, so nothing outside the
|
|
274
355
|
* feature reads the string.
|
|
356
|
+
*
|
|
357
|
+
* **And a declared Worker name is ignored here too — the other half of the #580 asymmetry.** A declared
|
|
358
|
+
* environment's script name is the adopter's, written in a tracked file, and provisioning reads it. A
|
|
359
|
+
* feature's is the kit's: it is composed from the branch, written into a generated config nobody commits,
|
|
360
|
+
* and **recomputed on teardown**. Honoring a declared one would leave `pithy feature destroy` computing a
|
|
361
|
+
* name the deployment does not answer to, which is a Worker nothing deletes.
|
|
275
362
|
*/
|
|
276
363
|
export function featureScope(identity: FeatureIdentity): ProvisionScope {
|
|
277
364
|
return {
|
|
@@ -282,8 +369,38 @@ export function featureScope(identity: FeatureIdentity): ProvisionScope {
|
|
|
282
369
|
// part company here.
|
|
283
370
|
honorsGlobal: false,
|
|
284
371
|
resource: (binding, kind) => featureResourceName(identity, binding, kind),
|
|
285
|
-
|
|
372
|
+
// The directory, not the deploy name: the head already carries the project, and the deploy name
|
|
373
|
+
// usually leads with it too, which composed `<project>-f<issue>-<slug>-<project>-<app>` (#587).
|
|
374
|
+
worker: ({ app }) => featureWorkerName(identity, app),
|
|
286
375
|
secretEntry: (secret, secretScope) =>
|
|
287
376
|
secretEntryName(identity.project, secret, secretScope, () => featureSecretEntryName(identity, secret)),
|
|
288
377
|
};
|
|
289
378
|
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* **Every script name one Worker can be deployed under in a feature — what teardown looks for (#592).**
|
|
382
|
+
*
|
|
383
|
+
* The first is the name {@link featureScope} composes today, taken from the scope rather than composed a
|
|
384
|
+
* second time, so provisioning and teardown cannot disagree about it. The second is the one it composed
|
|
385
|
+
* until #587, from the deploy name: `<project>-f<issue>-<slug>-<project>-<app>`. A feature provisioned and
|
|
386
|
+
* deployed before that upgrade is still running under it, and after its next deploy it runs under both —
|
|
387
|
+
* so teardown looks for both. One entry when the two coincide, as they do for a Worker whose deploy name
|
|
388
|
+
* is its directory.
|
|
389
|
+
*
|
|
390
|
+
* **Exact names, never a prefix.** A prefix scan of `<project>-f<issue>-<slug>-` reaches a sibling whose
|
|
391
|
+
* slug extends this one's. The exact names can still meet a sibling in one shape: the doubled name for
|
|
392
|
+
* slug `demo` and deploy name `acme-api` is the current name for slug `demo-acme` and directory `api`, on
|
|
393
|
+
* the same issue number. That is the same hyphen ambiguity every feature name here carries.
|
|
394
|
+
*
|
|
395
|
+
* **They cannot meet a declared environment's Worker**, which has no suffix either and is `<project>-<env>-<app>`
|
|
396
|
+
* since #580: every name either shape yields is inside {@link isFeatureName}'s namespace, no environment may
|
|
397
|
+
* start with a feature's marker, and {@link environmentScope} refuses a declared or fallback Worker name inside
|
|
398
|
+
* it. What that does not reach is a name nothing in the kit chose — a stanza written by hand and deployed
|
|
399
|
+
* without `pithy provision --env` ever reading it, or another project on the account, as {@link isFeatureName}
|
|
400
|
+
* says.
|
|
401
|
+
*/
|
|
402
|
+
export function featureWorkerScriptNames(identity: FeatureIdentity, worker: ProvisionWorkerNames): string[] {
|
|
403
|
+
const current = featureScope(identity).worker(worker);
|
|
404
|
+
const beforeSingleProject = featureWorkerName(identity, worker.script);
|
|
405
|
+
return current === beforeSingleProject ? [current] : [current, beforeSingleProject];
|
|
406
|
+
}
|
|
@@ -69,8 +69,11 @@ export interface ScopedNames {
|
|
|
69
69
|
export interface FeatureNames {
|
|
70
70
|
/** A feature's D1, KV, or R2 resource — `<project>-f<issue>-<slug>-<binding>-<kind>`. */
|
|
71
71
|
resource(binding: string, kind: FeatureResourceKind): string;
|
|
72
|
-
/**
|
|
73
|
-
|
|
72
|
+
/**
|
|
73
|
+
* A feature's Worker script — `<project>-f<issue>-<slug>-<app>`, from the `apps/<app>` directory and
|
|
74
|
+
* never the deploy name, which already leads with the project (#587).
|
|
75
|
+
*/
|
|
76
|
+
worker(app: string): string;
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
/** Everything a project can be asked to name. Created once, from the project, by {@link resourceNames}. */
|
|
@@ -167,7 +170,7 @@ export function resourceNames(project: string): ProjectNames {
|
|
|
167
170
|
const full: FeatureIdentity = { ...identity, project: normalized };
|
|
168
171
|
return {
|
|
169
172
|
resource: (binding, kind) => featureResourceName(full, binding, kind),
|
|
170
|
-
worker: (
|
|
173
|
+
worker: (app) => featureWorkerName(full, app),
|
|
171
174
|
};
|
|
172
175
|
},
|
|
173
176
|
};
|
package/src/text/comments.ts
CHANGED
|
@@ -62,6 +62,28 @@
|
|
|
62
62
|
* `worker-safety.test.ts` exists to enforce, so the gate now polices the stripper it reads with.
|
|
63
63
|
*/
|
|
64
64
|
export function blankComments(source: string): string {
|
|
65
|
+
return blank(source, false);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* `source` with every comment **and every string's contents** blanked — for a gate asking whether a name is
|
|
70
|
+
* *called*, where {@link blankComments}' own rule points the wrong way.
|
|
71
|
+
*
|
|
72
|
+
* `blankComments` keeps strings because its callers look for a forbidden read, and a string that merely contains
|
|
73
|
+
* one is a false positive, the safe direction. A gate looking for a *required* call inverts that: a validator named
|
|
74
|
+
* only inside an error message — `"requireEnvironment(args.env)"` — is a call that never runs, and counting it
|
|
75
|
+
* passes the file. So this blanks the contents too, delimiters kept, character for character.
|
|
76
|
+
*
|
|
77
|
+
* **A template literal goes whole, `${}` included.** A call written only inside an interpolation is not seen. For
|
|
78
|
+
* a presence check that is the safe direction again — the file is flagged, never passed — and a scan for a read
|
|
79
|
+
* belongs on {@link blankComments}, where the interpolation stays.
|
|
80
|
+
*/
|
|
81
|
+
export function blankCommentsAndStrings(source: string): string {
|
|
82
|
+
return blank(source, true);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The one walk behind both: comments always blanked, a quoted run kept or blanked inside its delimiters. */
|
|
86
|
+
function blank(source: string, strings: boolean): string {
|
|
65
87
|
let out = "";
|
|
66
88
|
let previous = "";
|
|
67
89
|
let index = 0;
|
|
@@ -76,7 +98,8 @@ export function blankComments(source: string): string {
|
|
|
76
98
|
}
|
|
77
99
|
if (char === '"' || char === "'" || char === "`") {
|
|
78
100
|
const stop = endOfQuoted(source, index, char, char !== "`");
|
|
79
|
-
|
|
101
|
+
const run = source.slice(index, stop);
|
|
102
|
+
out += strings ? blankInside(run, char) : run;
|
|
80
103
|
index = stop;
|
|
81
104
|
previous = char;
|
|
82
105
|
continue;
|
|
@@ -95,6 +118,13 @@ export function blankComments(source: string): string {
|
|
|
95
118
|
return out;
|
|
96
119
|
}
|
|
97
120
|
|
|
121
|
+
/** A quoted run with everything between its delimiters blanked, newlines kept. An unterminated run has no closer. */
|
|
122
|
+
function blankInside(run: string, quote: string): string {
|
|
123
|
+
const closed = run.length > 1 && run.endsWith(quote);
|
|
124
|
+
const body = run.slice(1, closed ? -1 : undefined).replace(/[^\n]/g, " ");
|
|
125
|
+
return `${quote}${body}${closed ? quote : ""}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
98
128
|
/**
|
|
99
129
|
* After one of these, a `/` opens a regex literal; after anything else it divides. The empty string is
|
|
100
130
|
* the start of the file. A wrong guess is bounded — see {@link endOfRegex}.
|
package/src/version.generated.ts
CHANGED
package/src/workflow/host.ts
CHANGED
|
@@ -139,6 +139,14 @@ export interface WorkflowHostParams {
|
|
|
139
139
|
* not depend on `@pithy-sh/secrets`, which owns that naming.
|
|
140
140
|
*/
|
|
141
141
|
masterKeySecretName?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Secrets Store binding name → the entry it resolves to in this environment, for every store secret the
|
|
144
|
+
* host reads besides the master key. Filled **only** for the bindings listed, like
|
|
145
|
+
* {@link databaseNames}; the names come from the capability, which composes them with the same namer
|
|
146
|
+
* provisioning created the entries with. Core composes none of them itself, for the reason
|
|
147
|
+
* {@link masterKeySecretName} gives.
|
|
148
|
+
*/
|
|
149
|
+
secretNames?: Record<string, string>;
|
|
142
150
|
/** Vars merged over the template's, e.g. the capability's config serialized as one JSON blob. */
|
|
143
151
|
vars?: Record<string, string>;
|
|
144
152
|
/**
|
|
@@ -241,13 +249,15 @@ export function resolveWorkflowHost(template: WorkflowHostTemplate, params: Work
|
|
|
241
249
|
|
|
242
250
|
if (resolved.secrets_store_secrets && params.secretsStoreId !== undefined) {
|
|
243
251
|
const storeId = params.secretsStoreId;
|
|
244
|
-
const
|
|
252
|
+
const names: Record<string, string> = {
|
|
253
|
+
...(params.masterKeySecretName !== undefined ? { SECRETS_ENCRYPTION_KEYS: params.masterKeySecretName } : {}),
|
|
254
|
+
...params.secretNames,
|
|
255
|
+
};
|
|
245
256
|
resolved.secrets_store_secrets = resolved.secrets_store_secrets.map((entry) => ({
|
|
246
257
|
...entry,
|
|
247
258
|
store_id: storeId,
|
|
248
|
-
//
|
|
249
|
-
secret_name:
|
|
250
|
-
masterKey !== undefined && entry.binding === "SECRETS_ENCRYPTION_KEYS" ? masterKey : entry.secret_name,
|
|
259
|
+
// A named binding takes the entry its capability composed; an unnamed one keeps its declared name.
|
|
260
|
+
secret_name: Object.hasOwn(names, entry.binding) ? (names[entry.binding] as string) : entry.secret_name,
|
|
251
261
|
}));
|
|
252
262
|
}
|
|
253
263
|
|
package/src/workflow/hostEnv.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type HostEnvProviderKind = z.infer<typeof HostEnvProviderKind>;
|
|
|
45
45
|
/**
|
|
46
46
|
* What provides one field. The whole point of the declaration: a report that says `BASE_URL is
|
|
47
47
|
* missing` sends a developer looking, and a report that says `Var BASE_URL in the host's
|
|
48
|
-
* wrangler.jsonc. Run pithy email provision
|
|
48
|
+
* wrangler.jsonc. Run pithy email provision.` ends the search.
|
|
49
49
|
*/
|
|
50
50
|
export const HostEnvProvider = z
|
|
51
51
|
.object({
|