@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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
4
4
|
import { type MigrationProvider, type MigrationResult } from "kysely/migration";
|
|
5
|
+
import { RetainedBudget } from "./retained";
|
|
5
6
|
/**
|
|
6
7
|
* Which database a run is reporting on — what a failure names.
|
|
7
8
|
*
|
|
@@ -16,6 +17,19 @@ export interface MigrationTarget {
|
|
|
16
17
|
/** The database name: a capability's `databases` key. Throw-site context, not the adopter's handle. */
|
|
17
18
|
database: string;
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* What a caller that reverses migrations says about retained rows (#588) — see `./retained`.
|
|
22
|
+
*
|
|
23
|
+
* Optional, and absent is the safe answer: a caller that says nothing has counted nothing, so any `down`
|
|
24
|
+
* against a database holding retained rows is refused.
|
|
25
|
+
*/
|
|
26
|
+
export interface RetainedConsent {
|
|
27
|
+
/**
|
|
28
|
+
* The retained rows the caller agreed to destroy. Pass one budget to every database in a run, so one
|
|
29
|
+
* agreement is spent once; a caller reversing a single database builds its own. Absent means none.
|
|
30
|
+
*/
|
|
31
|
+
budget?: RetainedBudget;
|
|
32
|
+
}
|
|
19
33
|
/** Run every pending migration to latest. An empty provider resolves to `[]`. */
|
|
20
34
|
export declare function runMigrations(database: D1Database, provider: MigrationProvider, target?: MigrationTarget): Promise<MigrationResult[]>;
|
|
21
35
|
/** One database's ledger beside the declaration it is supposed to match — see {@link readMigrationLedger}. */
|
|
@@ -46,24 +60,47 @@ export interface MigrationLedger {
|
|
|
46
60
|
* warn-only "schema is behind" check, and the refusal `pithy migrate` raises before it writes.
|
|
47
61
|
*/
|
|
48
62
|
export declare function readMigrationLedger(database: D1Database, provider: MigrationProvider): Promise<MigrationLedger>;
|
|
49
|
-
/**
|
|
50
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Step this database's latest applied migration back — one step, per database. `pithy migrate --rollback`
|
|
65
|
+
* calls it once for **every** database in its fan-out. Refused while a retained table here holds rows the
|
|
66
|
+
* caller has not counted in `consent` (#588).
|
|
67
|
+
*/
|
|
68
|
+
export declare function rollbackMigration(database: D1Database, provider: MigrationProvider, target?: MigrationTarget, consent?: RetainedConsent): Promise<MigrationResult[]>;
|
|
51
69
|
/**
|
|
52
70
|
* Fully reset one database's schema: every applied migration's `down` runs, in one pass, in reverse
|
|
53
71
|
* chronological order — Kysely's `NO_MIGRATIONS` target, not just the latest — then every migration's
|
|
54
72
|
* `up` reapplies from empty. The seam behind `pithy seed --redo`'s destructive rebuild: because the
|
|
55
73
|
* schema comes back empty, the ordinary non-destructive seed writes (`INSERT OR IGNORE`, KV
|
|
56
74
|
* skip-if-exists) simply work afterward — there is no per-row identity problem to solve. An empty
|
|
57
|
-
* ledger rolls back nothing; an empty provider reapplies nothing.
|
|
75
|
+
* ledger rolls back nothing; an empty provider reapplies nothing. Refused, before the first `down`, while a
|
|
76
|
+
* retained table here holds rows the caller has not counted in `consent` (#588).
|
|
77
|
+
*/
|
|
78
|
+
export declare function resetMigrations(database: D1Database, provider: MigrationProvider, target?: MigrationTarget, consent?: RetainedConsent): Promise<MigrationResult[]>;
|
|
79
|
+
/**
|
|
80
|
+
* What a drop reverses, and the database it reverses it in.
|
|
81
|
+
*
|
|
82
|
+
* Two providers because they answer two questions. `reverse` is the part being removed — one capability's
|
|
83
|
+
* migrations. `database` is every migration composed into that D1, and it is what the retained guard counts:
|
|
84
|
+
* a table is retained in a *database*, and the capability being dropped is the one least likely to declare
|
|
85
|
+
* the vault it shares a database with (#588). Handed only the part, the guard counted what the part declared
|
|
86
|
+
* — nothing — while the vault beside it held rows.
|
|
58
87
|
*/
|
|
59
|
-
export
|
|
88
|
+
export interface DropSelection {
|
|
89
|
+
/** Every migration composed into this database — the set whose retained declarations are counted. */
|
|
90
|
+
database: MigrationProvider;
|
|
91
|
+
/** The migrations to reverse: a part of `database`, by composed name. */
|
|
92
|
+
reverse: MigrationProvider;
|
|
93
|
+
}
|
|
60
94
|
/**
|
|
61
|
-
* Surgically drop **one capability's** migrations: run each of
|
|
95
|
+
* Surgically drop **one capability's** migrations: run each of `drop.reverse`'s `down` functions in
|
|
62
96
|
* reverse order and delete only those ledger rows, leaving every other capability's tables and
|
|
63
97
|
* bookkeeping untouched. The seam behind `pithy remove --drop`. Kysely's stepwise `Migrator` refuses a
|
|
64
98
|
* provider that doesn't span the whole ledger (it reads a foreign row as corrupt state), so a
|
|
65
99
|
* per-capability drop can't go through it — this reverses the capability's own migrations directly.
|
|
66
|
-
* Only migrations recorded in the ledger are reversed; an absent ledger drops nothing.
|
|
100
|
+
* Only migrations recorded in the ledger are reversed; an absent ledger drops nothing. Refused, before the
|
|
101
|
+
* first `down`, while a retained table **anywhere in `drop.database`** holds rows the caller has not counted
|
|
102
|
+
* in `consent` (#588). A name `drop.reverse` carries that `drop.database` does not is an internal fault: the
|
|
103
|
+
* guard would not have counted the database the `down` runs in.
|
|
67
104
|
*/
|
|
68
|
-
export declare function dropMigrations(database: D1Database,
|
|
105
|
+
export declare function dropMigrations(database: D1Database, drop: DropSelection, target?: MigrationTarget, consent?: RetainedConsent): Promise<MigrationResult[]>;
|
|
69
106
|
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/migrations/runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAA2B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/migrations/runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAA2B,MAAM,kBAAkB,CAAC;AAKzG,OAAO,EAAgC,cAAc,EAAE,MAAM,YAAY,CAAC;AA4D1E;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,OAAO,EAAE,MAAM,CAAC;IAChB,uGAAuG;IACvG,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAUD,iFAAiF;AACjF,wBAAsB,aAAa,CACjC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAG5B;AAED,8GAA8G;AAC9G,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAOrH;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC,CAG5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC,CAO5B;AAgBD;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,qGAAqG;IACrG,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,yEAAyE;IACzE,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC,CA4C5B"}
|
|
@@ -4,6 +4,7 @@ import { InternalError } from "../error/pithyError.js";
|
|
|
4
4
|
import { causeMessage } from "../error/cause.js";
|
|
5
5
|
import { MIGRATION_LOCK_TABLE, MIGRATION_TABLE, migrationKysely } from "./bookkeeping.js";
|
|
6
6
|
import { batchedProvider } from "./batch.js";
|
|
7
|
+
import { RetainedBudget, guardRetained, isDownRefusal } from "./retained.js";
|
|
7
8
|
import { sql } from "kysely";
|
|
8
9
|
import { Migrator, NO_MIGRATIONS } from "kysely/migration";
|
|
9
10
|
//#region src/migrations/runner.ts
|
|
@@ -46,18 +47,25 @@ import { Migrator, NO_MIGRATIONS } from "kysely/migration";
|
|
|
46
47
|
* capability arrives with its whole set. Refusing the add with an actionable error was the
|
|
47
48
|
* alternative; it explains the corner instead of removing it.
|
|
48
49
|
*/
|
|
49
|
-
function migrator(database, provider) {
|
|
50
|
+
function migrator(database, provider, target, consent) {
|
|
50
51
|
return new Migrator({
|
|
51
52
|
db: migrationKysely(database),
|
|
52
|
-
provider: batchedProvider(provider, database),
|
|
53
|
+
provider: batchedProvider(guardRetained(provider, database, guardOptions(target, consent)), database),
|
|
53
54
|
migrationTableName: MIGRATION_TABLE,
|
|
54
55
|
migrationLockTableName: MIGRATION_LOCK_TABLE,
|
|
55
56
|
allowUnorderedMigrations: true
|
|
56
57
|
});
|
|
57
58
|
}
|
|
59
|
+
/** The guard's options: the binding its refusal names, and the budget the caller agreed to. */
|
|
60
|
+
function guardOptions(target, consent) {
|
|
61
|
+
return {
|
|
62
|
+
binding: target?.binding ?? "this database",
|
|
63
|
+
budget: consent?.budget ?? new RetainedBudget(void 0)
|
|
64
|
+
};
|
|
65
|
+
}
|
|
58
66
|
/** Run every pending migration to latest. An empty provider resolves to `[]`. */
|
|
59
67
|
async function runMigrations(database, provider, target) {
|
|
60
|
-
const { error, results } = await migrator(database, provider).migrateToLatest();
|
|
68
|
+
const { error, results } = await migrator(database, provider, target, void 0).migrateToLatest();
|
|
61
69
|
return settle("run", error, results, target);
|
|
62
70
|
}
|
|
63
71
|
/**
|
|
@@ -85,9 +93,13 @@ async function readMigrationLedger(database, provider) {
|
|
|
85
93
|
undeclared: [...applied].filter((name) => !declared.includes(name)).sort()
|
|
86
94
|
};
|
|
87
95
|
}
|
|
88
|
-
/**
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Step this database's latest applied migration back — one step, per database. `pithy migrate --rollback`
|
|
98
|
+
* calls it once for **every** database in its fan-out. Refused while a retained table here holds rows the
|
|
99
|
+
* caller has not counted in `consent` (#588).
|
|
100
|
+
*/
|
|
101
|
+
async function rollbackMigration(database, provider, target, consent) {
|
|
102
|
+
const { error, results } = await migrator(database, provider, target, consent).migrateDown();
|
|
91
103
|
return settle("rollback", error, results, target);
|
|
92
104
|
}
|
|
93
105
|
/**
|
|
@@ -96,10 +108,11 @@ async function rollbackMigration(database, provider, target) {
|
|
|
96
108
|
* `up` reapplies from empty. The seam behind `pithy seed --redo`'s destructive rebuild: because the
|
|
97
109
|
* schema comes back empty, the ordinary non-destructive seed writes (`INSERT OR IGNORE`, KV
|
|
98
110
|
* skip-if-exists) simply work afterward — there is no per-row identity problem to solve. An empty
|
|
99
|
-
* ledger rolls back nothing; an empty provider reapplies nothing.
|
|
111
|
+
* ledger rolls back nothing; an empty provider reapplies nothing. Refused, before the first `down`, while a
|
|
112
|
+
* retained table here holds rows the caller has not counted in `consent` (#588).
|
|
100
113
|
*/
|
|
101
|
-
async function resetMigrations(database, provider, target) {
|
|
102
|
-
const runner = migrator(database, provider);
|
|
114
|
+
async function resetMigrations(database, provider, target, consent) {
|
|
115
|
+
const runner = migrator(database, provider, target, consent);
|
|
103
116
|
const down = await runner.migrateTo(NO_MIGRATIONS);
|
|
104
117
|
const downResults = settle("resetDown", down.error, down.results, target);
|
|
105
118
|
const up = await runner.migrateToLatest();
|
|
@@ -117,19 +130,30 @@ async function appliedMigrationNames(db) {
|
|
|
117
130
|
return new Set(rows.map((row) => row.name));
|
|
118
131
|
}
|
|
119
132
|
/**
|
|
120
|
-
* Surgically drop **one capability's** migrations: run each of
|
|
133
|
+
* Surgically drop **one capability's** migrations: run each of `drop.reverse`'s `down` functions in
|
|
121
134
|
* reverse order and delete only those ledger rows, leaving every other capability's tables and
|
|
122
135
|
* bookkeeping untouched. The seam behind `pithy remove --drop`. Kysely's stepwise `Migrator` refuses a
|
|
123
136
|
* provider that doesn't span the whole ledger (it reads a foreign row as corrupt state), so a
|
|
124
137
|
* per-capability drop can't go through it — this reverses the capability's own migrations directly.
|
|
125
|
-
* Only migrations recorded in the ledger are reversed; an absent ledger drops nothing.
|
|
138
|
+
* Only migrations recorded in the ledger are reversed; an absent ledger drops nothing. Refused, before the
|
|
139
|
+
* first `down`, while a retained table **anywhere in `drop.database`** holds rows the caller has not counted
|
|
140
|
+
* in `consent` (#588). A name `drop.reverse` carries that `drop.database` does not is an internal fault: the
|
|
141
|
+
* guard would not have counted the database the `down` runs in.
|
|
126
142
|
*/
|
|
127
|
-
async function dropMigrations(database,
|
|
143
|
+
async function dropMigrations(database, drop, target, consent) {
|
|
128
144
|
const db = migrationKysely(database);
|
|
129
|
-
const
|
|
145
|
+
const guarded = guardRetained(drop.database, database, guardOptions(target, consent));
|
|
146
|
+
const migrations = await batchedProvider(guarded, database).getMigrations();
|
|
147
|
+
const reversing = Object.keys(await drop.reverse.getMigrations());
|
|
148
|
+
const stray = reversing.filter((name) => !(name in migrations));
|
|
149
|
+
if (stray.length > 0) throw new InternalError({
|
|
150
|
+
message: `Couldn't drop ${stray.map((name) => `"${name}"`).join(", ")}${on(target)}. The database's migrations do not carry it.`,
|
|
151
|
+
detail: `${where(target)} A drop counts retained rows over the database's whole set, so every migration it reverses must be in it.`,
|
|
152
|
+
action: "Build the drop from the database's composed migrations. Nothing was dropped."
|
|
153
|
+
});
|
|
130
154
|
const applied = await appliedMigrationNames(db);
|
|
131
155
|
const results = [];
|
|
132
|
-
for (const name of
|
|
156
|
+
for (const name of reversing.sort().reverse()) {
|
|
133
157
|
if (!applied.has(name)) continue;
|
|
134
158
|
const down = migrations[name]?.down;
|
|
135
159
|
if (!down) continue;
|
|
@@ -142,6 +166,7 @@ async function dropMigrations(database, provider, target) {
|
|
|
142
166
|
status: "Success"
|
|
143
167
|
});
|
|
144
168
|
} catch (error) {
|
|
169
|
+
if (isDownRefusal(error)) throw error;
|
|
145
170
|
const dropped = results.map((result) => `"${result.migrationName}"`);
|
|
146
171
|
throw new InternalError({
|
|
147
172
|
message: `Couldn't drop "${name}"${on(target)}. ${reasonOf(error)}`,
|
|
@@ -162,7 +187,7 @@ const VOICE = {
|
|
|
162
187
|
rollback: {
|
|
163
188
|
failed: (key) => `Couldn't roll back "${key}"`,
|
|
164
189
|
fallback: "The rollback failed",
|
|
165
|
-
action: "Fix the migration. Run pithy
|
|
190
|
+
action: "Fix the migration's down. Run pithy doctor to see where each database stands."
|
|
166
191
|
},
|
|
167
192
|
resetDown: {
|
|
168
193
|
failed: (key) => `Couldn't roll back "${key}" during reset`,
|
|
@@ -203,6 +228,7 @@ function reasonOf(error) {
|
|
|
203
228
|
}
|
|
204
229
|
function settle(verb, error, results, target) {
|
|
205
230
|
if (error !== void 0) {
|
|
231
|
+
if (isDownRefusal(error)) throw error;
|
|
206
232
|
const voice = VOICE[verb];
|
|
207
233
|
const failed = results?.find((result) => result.status === "Error");
|
|
208
234
|
const applied = results?.filter((result) => result.status === "Success").map((result) => result.migrationName);
|
|
@@ -43,6 +43,18 @@ export declare const GLOBAL_SCOPE = "global";
|
|
|
43
43
|
* that rejects it would be a cycle.
|
|
44
44
|
*/
|
|
45
45
|
export declare const FEATURE_ENVIRONMENT = "feature";
|
|
46
|
+
/**
|
|
47
|
+
* **The segment a feature takes where an environment sits** — `f<issue>`, as in `<project>-f69-demo-db-d1`.
|
|
48
|
+
*
|
|
49
|
+
* Defined here, beside the environment rule, because the two share a slot in every composed name and the
|
|
50
|
+
* environment rule has to refuse this shape: `feature.ts` composes a feature's head with it, and
|
|
51
|
+
* {@link isValidEnvironment} refuses an environment that starts with one. A marker composed in one module and
|
|
52
|
+
* recognized in another would be two statements of one shape, and the next person to change one would not
|
|
53
|
+
* find the other.
|
|
54
|
+
*/
|
|
55
|
+
export declare function featureMarker(issue: string): string;
|
|
56
|
+
/** Is this whole hyphen-delimited segment a feature's marker? `f1` and `f01` are; `f1a` and `feature` are not. */
|
|
57
|
+
export declare function isFeatureMarker(segment: string): boolean;
|
|
46
58
|
/**
|
|
47
59
|
* The longest an environment name may be — **the longest canonical one, `staging`**.
|
|
48
60
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/naming/environment.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAI,KAAK,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAEhE,wGAAwG;AACxG,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,QAAqE,CAAC;AAEvG;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/naming/environment.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAI,KAAK,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAEhE,wGAAwG;AACxG,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAKD,kHAAkH;AAClH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAgBD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,QAAqE,CAAC;AAEvG;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIxD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmCzD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YAAI,SAAS,EAAE,MAAM,CAAU,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,oBAAoB,yBA2D9B,CAAC;AAEJ,sGAAsG;AACtG,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -49,6 +49,37 @@ const GLOBAL_SCOPE = "global";
|
|
|
49
49
|
*/
|
|
50
50
|
const FEATURE_ENVIRONMENT = "feature";
|
|
51
51
|
/**
|
|
52
|
+
* **The segment a feature takes where an environment sits** — `f<issue>`, as in `<project>-f69-demo-db-d1`.
|
|
53
|
+
*
|
|
54
|
+
* Defined here, beside the environment rule, because the two share a slot in every composed name and the
|
|
55
|
+
* environment rule has to refuse this shape: `feature.ts` composes a feature's head with it, and
|
|
56
|
+
* {@link isValidEnvironment} refuses an environment that starts with one. A marker composed in one module and
|
|
57
|
+
* recognized in another would be two statements of one shape, and the next person to change one would not
|
|
58
|
+
* find the other.
|
|
59
|
+
*/
|
|
60
|
+
function featureMarker(issue) {
|
|
61
|
+
return `f${issue}`;
|
|
62
|
+
}
|
|
63
|
+
/** Every string {@link featureMarker} can compose: an `f` and one or more digits, as a whole segment. */
|
|
64
|
+
const FEATURE_MARKER = /^f[0-9]+$/;
|
|
65
|
+
/** Is this whole hyphen-delimited segment a feature's marker? `f1` and `f01` are; `f1a` and `feature` are not. */
|
|
66
|
+
function isFeatureMarker(segment) {
|
|
67
|
+
return FEATURE_MARKER.test(segment);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Does this environment start where a feature's name does?
|
|
71
|
+
*
|
|
72
|
+
* **Exactly the environments that can collide with a feature (#587).** A declared environment composes
|
|
73
|
+
* `<project>-<env>-<thing>`, a feature `<project>-f<issue>-<slug>-<thing>`, and a feature Worker's name has no
|
|
74
|
+
* kind suffix to tell the two apart. After the shared `<project>-`, the two strings can only be equal when the
|
|
75
|
+
* environment's first segment is the feature's marker — `f1-demo` meets feature 1-demo's Worker `api`, and `f1`
|
|
76
|
+
* meets it too, through a Worker called `demo-api`. Any other first segment differs from every marker, so no
|
|
77
|
+
* name composed under it can be a feature's. So this is the whole rule, not one case of it.
|
|
78
|
+
*/
|
|
79
|
+
function startsWithFeatureMarker(name) {
|
|
80
|
+
return isFeatureMarker(name.split("-")[0] ?? "");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
52
83
|
* The longest an environment name may be — **the longest canonical one, `staging`**.
|
|
53
84
|
*
|
|
54
85
|
* This is a derivation input, not a preference: `WORKFLOW_DERIVED_PROJECT_NAME` and
|
|
@@ -72,6 +103,7 @@ const MAX_ENVIRONMENT_NAME = Math.max(...ENVIRONMENTS.map((environment) => envir
|
|
|
72
103
|
*/
|
|
73
104
|
function isValidEnvironment(name) {
|
|
74
105
|
if (name === "global") return false;
|
|
106
|
+
if (startsWithFeatureMarker(name)) return false;
|
|
75
107
|
return name.length <= MAX_ENVIRONMENT_NAME && NAME_SEGMENT.test(name);
|
|
76
108
|
}
|
|
77
109
|
/**
|
|
@@ -94,6 +126,11 @@ function assertValidEnvironment(name) {
|
|
|
94
126
|
action: `Name the environment one of ${ENVIRONMENTS.join(", ")}.`,
|
|
95
127
|
detail: `${GLOBAL_SCOPE} occupies the environment slot of a composed name for values shared across every environment.`
|
|
96
128
|
});
|
|
129
|
+
if (startsWithFeatureMarker(name)) throw new ValidationError({
|
|
130
|
+
message: `"${name}" starts the way a feature's name does.`,
|
|
131
|
+
action: "Start the environment with something other than f and a number.",
|
|
132
|
+
detail: `A feature takes the environment's slot with f<issue>, so <project>-${name}-<worker> can be a feature's Worker name exactly, and \`pithy feature destroy\` deletes that Worker.`
|
|
133
|
+
});
|
|
97
134
|
if (name.length > MAX_ENVIRONMENT_NAME && NAME_SEGMENT.test(name)) throw new ValidationError({
|
|
98
135
|
message: `"${name}" is ${name.length} characters. An environment stops at ${MAX_ENVIRONMENT_NAME}.`,
|
|
99
136
|
action: `Use one of ${ENVIRONMENTS.join(", ")}, or a shorter name.`,
|
|
@@ -189,4 +226,4 @@ const DeclaredEnvironments = z.array(z.string().describe("One deployed environme
|
|
|
189
226
|
}
|
|
190
227
|
}).describe("Every deployed environment this project has, in the order provisioning walks them — least-production first. Declared once in the root pithy.config.ts, because the set cannot be per-Worker. `dev` is never listed: it is local and always present.");
|
|
191
228
|
//#endregion
|
|
192
|
-
export { DEFAULT_ENVIRONMENTS, DeclaredEnvironments, ENVIRONMENTS, FEATURE_ENVIRONMENT, GLOBAL_SCOPE, LOCAL_ENVIRONMENT, MAX_ENVIRONMENT_NAME, assertValidEnvironment, isValidEnvironment };
|
|
229
|
+
export { DEFAULT_ENVIRONMENTS, DeclaredEnvironments, ENVIRONMENTS, FEATURE_ENVIRONMENT, GLOBAL_SCOPE, LOCAL_ENVIRONMENT, MAX_ENVIRONMENT_NAME, assertValidEnvironment, featureMarker, isFeatureMarker, isValidEnvironment };
|
package/dist/naming/feature.d.ts
CHANGED
|
@@ -65,6 +65,12 @@ export declare function featureSecretEntryName(identity: FeatureIdentity, secret
|
|
|
65
65
|
* floored the slug at one character and never touched the worker segment, so it ran unbounded — 69
|
|
66
66
|
* characters for a worker called `collaboration-realtime-gateway`, 109 for a 70-character one. `apps/<name>`
|
|
67
67
|
* has a charset rule and no length rule, so nothing upstream was going to stop it either.
|
|
68
|
+
*
|
|
69
|
+
* **`app` is the `apps/<app>` directory, never the deploy name.** A scaffolded Worker deploys as
|
|
70
|
+
* `<project>-<app>`, and handing that here composed `<project>-f<issue>-<slug>-<project>-<app>` — the
|
|
71
|
+
* project twice, spent out of the budget above (#587). This function takes a string and cannot tell the
|
|
72
|
+
* two apart, so the provisioning path reaches it only through `featureScope`, which is handed both names
|
|
73
|
+
* and picks.
|
|
68
74
|
*/
|
|
69
|
-
export declare function featureWorkerName(identity: FeatureIdentity,
|
|
75
|
+
export declare function featureWorkerName(identity: FeatureIdentity, app: string): string;
|
|
70
76
|
//# sourceMappingURL=feature.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../src/naming/feature.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../src/naming/feature.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AAEH,iHAAiH;AACjH,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,EAAE,SAAS,mBAAmB,EAAuB,CAAC;AAEzF,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CACd;AAkED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQjH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQxF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhF"}
|
package/dist/naming/feature.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import { ValidationError } from "../error/pithyError.js";
|
|
4
|
+
import { featureMarker } from "./environment.js";
|
|
4
5
|
import { NAMESPACE_LIMITS } from "./limits.js";
|
|
5
6
|
import { assertValidProjectName, fitSegment, kebab } from "./resource.js";
|
|
6
7
|
//#region src/naming/feature.ts
|
|
@@ -32,7 +33,7 @@ function assertIssue(issue) {
|
|
|
32
33
|
function head(identity) {
|
|
33
34
|
assertValidProjectName(identity.project);
|
|
34
35
|
assertIssue(identity.issue);
|
|
35
|
-
return `${kebab(identity.project)}
|
|
36
|
+
return `${kebab(identity.project)}-${featureMarker(identity.issue)}`;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
39
|
* Fit `<head>-<slug>-<tail><fixed>` into `budget`, truncating the slug first and the tail only if the
|
|
@@ -100,9 +101,15 @@ function featureSecretEntryName(identity, secret) {
|
|
|
100
101
|
* floored the slug at one character and never touched the worker segment, so it ran unbounded — 69
|
|
101
102
|
* characters for a worker called `collaboration-realtime-gateway`, 109 for a 70-character one. `apps/<name>`
|
|
102
103
|
* has a charset rule and no length rule, so nothing upstream was going to stop it either.
|
|
104
|
+
*
|
|
105
|
+
* **`app` is the `apps/<app>` directory, never the deploy name.** A scaffolded Worker deploys as
|
|
106
|
+
* `<project>-<app>`, and handing that here composed `<project>-f<issue>-<slug>-<project>-<app>` — the
|
|
107
|
+
* project twice, spent out of the budget above (#587). This function takes a string and cannot tell the
|
|
108
|
+
* two apart, so the provisioning path reaches it only through `featureScope`, which is handed both names
|
|
109
|
+
* and picks.
|
|
103
110
|
*/
|
|
104
|
-
function featureWorkerName(identity,
|
|
105
|
-
return composeFeatureName(head(identity), kebab(identity.slug), kebab(
|
|
111
|
+
function featureWorkerName(identity, app) {
|
|
112
|
+
return composeFeatureName(head(identity), kebab(identity.slug), kebab(app), "", NAMESPACE_LIMITS.worker.maxLength);
|
|
106
113
|
}
|
|
107
114
|
//#endregion
|
|
108
115
|
export { FEATURE_RESOURCE_KINDS, featureResourceName, featureSecretEntryName, featureWorkerName };
|
|
@@ -74,6 +74,27 @@ export interface BindingNaming {
|
|
|
74
74
|
export interface ProjectGlobalNaming extends BindingNaming {
|
|
75
75
|
readonly scope: "global";
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* The two names one Worker answers to before a scope has named it — **and why a scope is handed both.**
|
|
79
|
+
*
|
|
80
|
+
* `pithy init replay --worker board` writes `apps/board/wrangler.jsonc` with `"name": "replay-board"`.
|
|
81
|
+
* So the Worker's directory says `board` and its deploy name says `replay-board`, and the two scopes need
|
|
82
|
+
* different ones. A declared environment's fallback is wrangler's own `<script>-<env>`, which is built on
|
|
83
|
+
* the deploy name. A feature's name is `<project>-f<issue>-<slug>-<app>`, which already leads with the
|
|
84
|
+
* project, so it is built on the directory.
|
|
85
|
+
*
|
|
86
|
+
* This was one string until #587, and the string was the deploy name, so every feature Worker carried the
|
|
87
|
+
* project twice: `replay-f69-demo-replay-board`. That was not only untidy. The name is held to the Worker
|
|
88
|
+
* cap of 63, and the doubled segment spent that budget where the truncation lands on the part that says
|
|
89
|
+
* *which* Worker. Carrying both names is what lets each scope take the one its shape is built from, and
|
|
90
|
+
* lets neither caller choose on the scope's behalf.
|
|
91
|
+
*/
|
|
92
|
+
export interface ProvisionWorkerNames {
|
|
93
|
+
/** The Worker's `apps/<app>` directory basename — the name a sibling's `service` binding targets it by. */
|
|
94
|
+
readonly app: string;
|
|
95
|
+
/** The Worker's deploy name — the top-level `name` of its `wrangler.jsonc`, e.g. `replay-board`. */
|
|
96
|
+
readonly script: string;
|
|
97
|
+
}
|
|
77
98
|
/** Where a provisioning run's resources are named, and where their ids are written. */
|
|
78
99
|
export interface ProvisionScope {
|
|
79
100
|
/** The `env.<stanza>` key in each Worker's config that this scope's ids are written into. */
|
|
@@ -118,8 +139,18 @@ export interface ProvisionScope {
|
|
|
118
139
|
* is created, judged to be the project's, kept out of the teardown record, and orphaned.
|
|
119
140
|
*/
|
|
120
141
|
readonly honorsGlobal: boolean;
|
|
121
|
-
/**
|
|
122
|
-
|
|
142
|
+
/**
|
|
143
|
+
* The script name a Worker deploys under in this scope.
|
|
144
|
+
*
|
|
145
|
+
* `worker` carries **both** of the Worker's names, because the two scopes compose from different ones:
|
|
146
|
+
* a declared environment falls back to wrangler's `<script>-<env>`, and a feature composes
|
|
147
|
+
* `<project>-f<issue>-<slug>-<app>`. See {@link ProvisionWorkerNames}.
|
|
148
|
+
*
|
|
149
|
+
* `declared` is the name that scope's stanza already carries, when it carries one. A scope may honor it
|
|
150
|
+
* or compose its own; see {@link environmentScope} and {@link featureScope}, which answer differently
|
|
151
|
+
* and say why. Passing it is how a caller asks the scope rather than deciding for itself.
|
|
152
|
+
*/
|
|
153
|
+
worker(worker: ProvisionWorkerNames, declared?: string): string;
|
|
123
154
|
/**
|
|
124
155
|
* This scope's CF Secrets Store entry name for a declared secret.
|
|
125
156
|
*
|
|
@@ -158,6 +189,22 @@ export interface ProvisionScope {
|
|
|
158
189
|
*/
|
|
159
190
|
export declare function bindingResourceName(project: string, binding: string, kind: FeatureResourceKind, naming: ProjectGlobalNaming): string;
|
|
160
191
|
export declare function bindingResourceName(project: string, binding: string, kind: FeatureResourceKind, naming: BindingNaming, scoped: (thing: string) => string): string;
|
|
192
|
+
/**
|
|
193
|
+
* **Is this name inside a feature's namespace** — `<project>-f<issue>-…`, the project and then a feature's
|
|
194
|
+
* marker, with something after it?
|
|
195
|
+
*
|
|
196
|
+
* The namespace, not one feature's names, because that is what has to stay disjoint: `pithy feature destroy`
|
|
197
|
+
* deletes by exact name, and a feature Worker's name has no kind suffix, so a declared environment's name
|
|
198
|
+
* that lands anywhere in here is one some branch's teardown can delete (#587). Every name {@link featureScope}
|
|
199
|
+
* composes is inside; {@link environmentScope} refuses to name a Worker inside, and `isValidEnvironment`
|
|
200
|
+
* refuses every environment whose composed names could be.
|
|
201
|
+
*
|
|
202
|
+
* **What it does not see.** It is stated for one project. A second project on the same account whose name is
|
|
203
|
+
* this one's plus `-f<issue>` — `acme-f1` beside `acme` — composes names inside `acme`'s namespace from an
|
|
204
|
+
* ordinary environment, and nothing here can tell, because a project name carries no boundary a later hyphen
|
|
205
|
+
* cannot fake. That is the hyphen ambiguity every composed name carries, one segment further left.
|
|
206
|
+
*/
|
|
207
|
+
export declare function isFeatureName(project: string, name: string): boolean;
|
|
161
208
|
/**
|
|
162
209
|
* A declared environment's scope — `staging`, `prod`, or whatever the root `pithy.config.ts` lists.
|
|
163
210
|
*
|
|
@@ -165,13 +212,25 @@ export declare function bindingResourceName(project: string, binding: string, ki
|
|
|
165
212
|
* every name below, so an illegal one must fail before anything is created rather than at the fourth
|
|
166
213
|
* getter that happened to use it.
|
|
167
214
|
*
|
|
168
|
-
* **A
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
215
|
+
* **A declared name wins; the fallback is wrangler's own, `<script>-<env>`.**
|
|
216
|
+
*
|
|
217
|
+
* This reverses the rule that stood here until #580, and the reversal is worth reading rather than
|
|
218
|
+
* assuming. The old rule *recomputed* `<script>-<env>` on every provision and wrote it over whatever the
|
|
219
|
+
* stanza said, on the argument that wrangler has always appended the environment to the top-level `name`,
|
|
220
|
+
* so every project that ever deployed is already at that address.
|
|
221
|
+
*
|
|
222
|
+
* That argument is still true about the **fallback**, and the fallback is unchanged: a stanza that names
|
|
223
|
+
* nothing gets `<script>-<env>` and every existing adopter deploys exactly where they always did. What was
|
|
224
|
+
* wrong was recomputing over a name somebody wrote down. Since #580 the starter template writes one —
|
|
225
|
+
* `<project>-<env>-<worker>`, the shape every other resource here takes — so recompute would have made the
|
|
226
|
+
* template's stamp pointless, and worse: it would have silently renamed the Worker of every project that
|
|
227
|
+
* had taken the new shape, on their next `pithy provision`. A Worker script is a `refuse`-policy namespace
|
|
228
|
+
* precisely because renaming one orphans the deployment, its routes, and every `service` binding pointing
|
|
229
|
+
* at it. Doing that as a side effect of provisioning is the failure the old rule was written to prevent,
|
|
230
|
+
* arriving from the other direction.
|
|
231
|
+
*
|
|
232
|
+
* So the name is read, not composed, when the file already holds one — and written out when it does not,
|
|
233
|
+
* so a service binding and a deploy still agree on one string that is in the file.
|
|
175
234
|
*/
|
|
176
235
|
export declare function environmentScope(project: string, environment: string): ProvisionScope;
|
|
177
236
|
/**
|
|
@@ -193,6 +252,35 @@ export declare function environmentScope(project: string, environment: string):
|
|
|
193
252
|
* `resource` is ignored for the same reason it is moot: a feature's `<thing>` segment is the binding plus
|
|
194
253
|
* the kind, and the whole name is recomputed on teardown rather than looked up, so nothing outside the
|
|
195
254
|
* feature reads the string.
|
|
255
|
+
*
|
|
256
|
+
* **And a declared Worker name is ignored here too — the other half of the #580 asymmetry.** A declared
|
|
257
|
+
* environment's script name is the adopter's, written in a tracked file, and provisioning reads it. A
|
|
258
|
+
* feature's is the kit's: it is composed from the branch, written into a generated config nobody commits,
|
|
259
|
+
* and **recomputed on teardown**. Honoring a declared one would leave `pithy feature destroy` computing a
|
|
260
|
+
* name the deployment does not answer to, which is a Worker nothing deletes.
|
|
196
261
|
*/
|
|
197
262
|
export declare function featureScope(identity: FeatureIdentity): ProvisionScope;
|
|
263
|
+
/**
|
|
264
|
+
* **Every script name one Worker can be deployed under in a feature — what teardown looks for (#592).**
|
|
265
|
+
*
|
|
266
|
+
* The first is the name {@link featureScope} composes today, taken from the scope rather than composed a
|
|
267
|
+
* second time, so provisioning and teardown cannot disagree about it. The second is the one it composed
|
|
268
|
+
* until #587, from the deploy name: `<project>-f<issue>-<slug>-<project>-<app>`. A feature provisioned and
|
|
269
|
+
* deployed before that upgrade is still running under it, and after its next deploy it runs under both —
|
|
270
|
+
* so teardown looks for both. One entry when the two coincide, as they do for a Worker whose deploy name
|
|
271
|
+
* is its directory.
|
|
272
|
+
*
|
|
273
|
+
* **Exact names, never a prefix.** A prefix scan of `<project>-f<issue>-<slug>-` reaches a sibling whose
|
|
274
|
+
* slug extends this one's. The exact names can still meet a sibling in one shape: the doubled name for
|
|
275
|
+
* slug `demo` and deploy name `acme-api` is the current name for slug `demo-acme` and directory `api`, on
|
|
276
|
+
* the same issue number. That is the same hyphen ambiguity every feature name here carries.
|
|
277
|
+
*
|
|
278
|
+
* **They cannot meet a declared environment's Worker**, which has no suffix either and is `<project>-<env>-<app>`
|
|
279
|
+
* since #580: every name either shape yields is inside {@link isFeatureName}'s namespace, no environment may
|
|
280
|
+
* start with a feature's marker, and {@link environmentScope} refuses a declared or fallback Worker name inside
|
|
281
|
+
* it. What that does not reach is a name nothing in the kit chose — a stanza written by hand and deployed
|
|
282
|
+
* without `pithy provision --env` ever reading it, or another project on the account, as {@link isFeatureName}
|
|
283
|
+
* says.
|
|
284
|
+
*/
|
|
285
|
+
export declare function featureWorkerScriptNames(identity: FeatureIdentity, worker: ProvisionWorkerNames): string[];
|
|
198
286
|
//# sourceMappingURL=provisionScope.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisionScope.d.ts","sourceRoot":"","sources":["../../src/naming/provisionScope.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"provisionScope.d.ts","sourceRoot":"","sources":["../../src/naming/provisionScope.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;AAInB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC,2GAA2G;IAC3G,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC;IACpF;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC;CACnE;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAAC;AACV,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAChC,MAAM,CAAC;AAsBV;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CA6BrF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAetE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAI1G"}
|