@dragonmastery/tamer 0.34.0 → 0.35.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/{apply-BsVQ9cbK.mjs → apply-B2wMY64Q.mjs} +10 -10
- package/dist/{apply-BsVQ9cbK.mjs.map → apply-B2wMY64Q.mjs.map} +1 -1
- package/dist/{applyTarget-BJlVrED9.mjs → applyTarget-KBomh7SL.mjs} +2 -2
- package/dist/{applyTarget-BJlVrED9.mjs.map → applyTarget-KBomh7SL.mjs.map} +1 -1
- package/dist/{bootstrap-CV6OT-c9.mjs → bootstrap-C7CZYHzb.mjs} +7 -7
- package/dist/bootstrap-C7CZYHzb.mjs.map +1 -0
- package/dist/{cloudflareSnapshot-CMbPQIsN.mjs → cloudflareSnapshot-BVlpH5K6.mjs} +3 -3
- package/dist/{cloudflareSnapshot-CMbPQIsN.mjs.map → cloudflareSnapshot-BVlpH5K6.mjs.map} +1 -1
- package/dist/{deploy-dNygCucr.mjs → deploy-C4Mi_qwz.mjs} +7 -7
- package/dist/{deploy-dNygCucr.mjs.map → deploy-C4Mi_qwz.mjs.map} +1 -1
- package/dist/{destroy-C0cKkpWe.mjs → destroy-DDVWxl7U.mjs} +18 -12
- package/dist/destroy-DDVWxl7U.mjs.map +1 -0
- package/dist/{destroy-tenant-hyEb1gEz.mjs → destroy-tenant-DL99EoRZ.mjs} +2 -2
- package/dist/{destroy-tenant-hyEb1gEz.mjs.map → destroy-tenant-DL99EoRZ.mjs.map} +1 -1
- package/dist/{dev-Bug5l5OZ.mjs → dev-BiPXBOKk.mjs} +6 -6
- package/dist/{dev-Bug5l5OZ.mjs.map → dev-BiPXBOKk.mjs.map} +1 -1
- package/dist/{doctor-BwuEPYM6.mjs → doctor-DDwsA2V6.mjs} +2 -2
- package/dist/{doctor-BwuEPYM6.mjs.map → doctor-DDwsA2V6.mjs.map} +1 -1
- package/dist/{drift-DENAf1Oe.mjs → drift-DqMtlwkg.mjs} +4 -4
- package/dist/{drift-B5y9LF5X.mjs → drift-RpShXwG7.mjs} +5 -5
- package/dist/{drift-B5y9LF5X.mjs.map → drift-RpShXwG7.mjs.map} +1 -1
- package/dist/{emit-DTpaIMkn.mjs → emit-BUPlQH-r.mjs} +2 -2
- package/dist/{emit-DTpaIMkn.mjs.map → emit-BUPlQH-r.mjs.map} +1 -1
- package/dist/{events-B7Lencm8.mjs → events-D9kQWwH8.mjs} +2 -2
- package/dist/{events-B7Lencm8.mjs.map → events-D9kQWwH8.mjs.map} +1 -1
- package/dist/{generator-ZTEeHlft.mjs → generator-BCcu_eoO.mjs} +2 -2
- package/dist/{generator-ZTEeHlft.mjs.map → generator-BCcu_eoO.mjs.map} +1 -1
- package/dist/{import-Ciq9MN3v.mjs → import-DHmLtue3.mjs} +3 -3
- package/dist/{import-Ciq9MN3v.mjs.map → import-DHmLtue3.mjs.map} +1 -1
- package/dist/{migrate-DWyUVN1I.mjs → migrate-36WDEaFz.mjs} +4 -4
- package/dist/{migrate-DWyUVN1I.mjs.map → migrate-36WDEaFz.mjs.map} +1 -1
- package/dist/{plan-Blxn-yKr.mjs → plan-k0jLGYyw.mjs} +8 -8
- package/dist/{plan-Blxn-yKr.mjs.map → plan-k0jLGYyw.mjs.map} +1 -1
- package/dist/{provision-tenant-BHDWTC2U.mjs → provision-tenant-BjFpVm-y.mjs} +6 -5
- package/dist/provision-tenant-BjFpVm-y.mjs.map +1 -0
- package/dist/{registry-BlHEOKlN.mjs → registry-DyToEush.mjs} +2 -2
- package/dist/{registry-BlHEOKlN.mjs.map → registry-DyToEush.mjs.map} +1 -1
- package/dist/{status-PlMHsDzT.mjs → status-DaaOPBEf.mjs} +3 -3
- package/dist/{status-PlMHsDzT.mjs.map → status-DaaOPBEf.mjs.map} +1 -1
- package/dist/{sync-YKZ5HD8v.mjs → sync-DEudPgQc.mjs} +4 -4
- package/dist/{sync-YKZ5HD8v.mjs.map → sync-DEudPgQc.mjs.map} +1 -1
- package/dist/tamer.mjs +135 -85
- package/dist/tamer.mjs.map +1 -1
- package/dist/tamerArtifactsR2-7qUbhOLD.mjs +51 -0
- package/dist/tamerArtifactsR2-7qUbhOLD.mjs.map +1 -0
- package/dist/{types-CADr4Kck.mjs → types-BQajHdJb.mjs} +4 -4
- package/dist/{types-CADr4Kck.mjs.map → types-BQajHdJb.mjs.map} +1 -1
- package/dist/{verifyPlanFile-BBAwWzUo.mjs → verifyPlanFile-CpxwOxrV.mjs} +2 -2
- package/dist/{verifyPlanFile-BBAwWzUo.mjs.map → verifyPlanFile-CpxwOxrV.mjs.map} +1 -1
- package/dist/{wfp-delete-CQc9tveU.mjs → wfp-delete-DsfqSBxt.mjs} +2 -2
- package/dist/{wfp-delete-CQc9tveU.mjs.map → wfp-delete-DsfqSBxt.mjs.map} +1 -1
- package/dist/{wfp-put-CVw8cloM.mjs → wfp-put-DX_bH-s7.mjs} +2 -2
- package/dist/{wfp-put-CVw8cloM.mjs.map → wfp-put-DX_bH-s7.mjs.map} +1 -1
- package/dist/{worker-route-CqBDvjgo.mjs → worker-route-CUQBu9xe.mjs} +2 -2
- package/dist/{worker-route-CqBDvjgo.mjs.map → worker-route-CUQBu9xe.mjs.map} +1 -1
- package/dist/{workers-y9RTOzbC.mjs → workers-BjDCuyVv.mjs} +2 -2
- package/dist/{workers-y9RTOzbC.mjs.map → workers-BjDCuyVv.mjs.map} +1 -1
- package/package.json +6 -2
- package/dist/bootstrap-CV6OT-c9.mjs.map +0 -1
- package/dist/destroy-C0cKkpWe.mjs.map +0 -1
- package/dist/provision-tenant-BHDWTC2U.mjs.map +0 -1
- package/dist/tamerArtifactsR2-Ba29OVp9.mjs +0 -52
- package/dist/tamerArtifactsR2-Ba29OVp9.mjs.map +0 -1
package/dist/tamer.mjs
CHANGED
|
@@ -5495,12 +5495,19 @@ var CFApiClient = class {
|
|
|
5495
5495
|
//#region src/core/secrets/secretsDb.ts
|
|
5496
5496
|
/** Max audit rows retained per secret name (oldest dropped on insert). */
|
|
5497
5497
|
const SECRET_HISTORY_CAP = 50;
|
|
5498
|
-
/**
|
|
5499
|
-
|
|
5500
|
-
|
|
5498
|
+
/**
|
|
5499
|
+
* Account-scoped D1 database for encrypted secrets (`tamer-secrets`).
|
|
5500
|
+
* Each env's secrets are isolated by row key: `{env}:{secretName}`.
|
|
5501
|
+
*/
|
|
5502
|
+
function tamerSecretsDatabaseName() {
|
|
5503
|
+
return "tamer-secrets";
|
|
5501
5504
|
}
|
|
5502
|
-
|
|
5503
|
-
|
|
5505
|
+
/** Row key for a secret in the shared D1: `{env}:{secretName}`. */
|
|
5506
|
+
function secretRowKey(env, secretName) {
|
|
5507
|
+
return `${env}:${secretName}`;
|
|
5508
|
+
}
|
|
5509
|
+
async function findTamerSecretsDatabaseUuid(api) {
|
|
5510
|
+
const name = tamerSecretsDatabaseName();
|
|
5504
5511
|
return (await api.d1ListAll()).find((d) => d.name === name)?.uuid;
|
|
5505
5512
|
}
|
|
5506
5513
|
const SECRETS_TABLE_DDL = `CREATE TABLE IF NOT EXISTS secrets (
|
|
@@ -5520,16 +5527,28 @@ const SECRET_HISTORY_TABLE_DDL = `CREATE TABLE IF NOT EXISTS secret_history (
|
|
|
5520
5527
|
updated_by TEXT
|
|
5521
5528
|
)`;
|
|
5522
5529
|
/**
|
|
5523
|
-
* Create `tamer-secrets
|
|
5524
|
-
* tables. Idempotent — safe to call on every bootstrap or
|
|
5530
|
+
* Create `tamer-secrets` (account-scoped) if missing and ensure `secrets` /
|
|
5531
|
+
* `secret_history` tables. Idempotent — safe to call on every bootstrap or
|
|
5532
|
+
* first vault touch.
|
|
5525
5533
|
*/
|
|
5526
|
-
async function ensureTamerSecretsDatabase(api
|
|
5527
|
-
let uuid$1 = await findTamerSecretsDatabaseUuid(api
|
|
5528
|
-
if (!uuid$1) uuid$1 = (await api.d1Create(tamerSecretsDatabaseName(
|
|
5534
|
+
async function ensureTamerSecretsDatabase(api) {
|
|
5535
|
+
let uuid$1 = await findTamerSecretsDatabaseUuid(api);
|
|
5536
|
+
if (!uuid$1) uuid$1 = (await api.d1Create(tamerSecretsDatabaseName())).uuid;
|
|
5529
5537
|
await api.d1Query(uuid$1, SECRETS_TABLE_DDL);
|
|
5530
5538
|
await api.d1Query(uuid$1, SECRET_HISTORY_TABLE_DDL);
|
|
5531
5539
|
return uuid$1;
|
|
5532
5540
|
}
|
|
5541
|
+
/**
|
|
5542
|
+
* Delete all secret rows for a specific env from the shared account-scoped D1.
|
|
5543
|
+
* Used by `tamer destroy --wipe-metadata`.
|
|
5544
|
+
*/
|
|
5545
|
+
async function deleteEnvSecretRows(api, env) {
|
|
5546
|
+
const uuid$1 = await findTamerSecretsDatabaseUuid(api);
|
|
5547
|
+
if (!uuid$1) return false;
|
|
5548
|
+
await api.d1Query(uuid$1, `DELETE FROM secrets WHERE name LIKE ?`, [`${env}:%`]);
|
|
5549
|
+
await api.d1Query(uuid$1, `DELETE FROM secret_history WHERE name LIKE ?`, [`${env}:%`]);
|
|
5550
|
+
return true;
|
|
5551
|
+
}
|
|
5533
5552
|
|
|
5534
5553
|
//#endregion
|
|
5535
5554
|
//#region src/core/secrets/masterKey.ts
|
|
@@ -6147,7 +6166,7 @@ function resolveCrossResourceReferences(merged, ctx) {
|
|
|
6147
6166
|
return next;
|
|
6148
6167
|
}
|
|
6149
6168
|
function stripTamerFields(config$1) {
|
|
6150
|
-
const { path, config: configPath, resources, local, env, scriptName: _scriptName, wranglerOutFile: _out, dispatchNamespace: _dispatchNs, tamerRoutes: _tamerRoutes, tamerStaleRouteSweepZones: _tamerStaleRouteSweepZones, ...rest$1 } = config$1;
|
|
6169
|
+
const { path, config: configPath, resources, local, env, scriptName: _scriptName, wranglerOutFile: _out, dispatchNamespace: _dispatchNs, tamerRoutes: _tamerRoutes, tamerStaleRouteSweepZones: _tamerStaleRouteSweepZones, build: _build, secrets: _secrets, alias: _alias, ...rest$1 } = config$1;
|
|
6151
6170
|
return rest$1;
|
|
6152
6171
|
}
|
|
6153
6172
|
/**
|
|
@@ -6556,9 +6575,21 @@ function stackNameForConfig(config$1) {
|
|
|
6556
6575
|
* 5: + `secret` state entries (fingerprints only; additive resource rows).
|
|
6557
6576
|
*/
|
|
6558
6577
|
const STATE_SCHEMA_VERSION = 5;
|
|
6559
|
-
/**
|
|
6560
|
-
|
|
6561
|
-
|
|
6578
|
+
/**
|
|
6579
|
+
* Account-scoped D1 database that holds JSON state for **all** envs
|
|
6580
|
+
* (`tamer-state`). Each env's state is isolated by row key:
|
|
6581
|
+
* `cfi_state:{env}:{stackName}`.
|
|
6582
|
+
*/
|
|
6583
|
+
function tamerStateDatabaseName() {
|
|
6584
|
+
return "tamer-state";
|
|
6585
|
+
}
|
|
6586
|
+
/**
|
|
6587
|
+
* D1 `tamer_kv.k` value for a given env + stack's state row.
|
|
6588
|
+
* Format: `cfi_state:{env}:{stackName}` — env namespacing ensures
|
|
6589
|
+
* cross-env isolation within the shared account-scoped D1.
|
|
6590
|
+
*/
|
|
6591
|
+
function stateRowKey(env, stackName) {
|
|
6592
|
+
return `cfi_state:${env}:${stackName}`;
|
|
6562
6593
|
}
|
|
6563
6594
|
function createEmptyCfiState(tenantId, env) {
|
|
6564
6595
|
return {
|
|
@@ -6587,24 +6618,24 @@ function migrateRawCfiStateInPlace(raw) {
|
|
|
6587
6618
|
if (raw.schemaVersion === 3) raw.schemaVersion = 4;
|
|
6588
6619
|
if (raw.schemaVersion === 4) raw.schemaVersion = STATE_SCHEMA_VERSION;
|
|
6589
6620
|
}
|
|
6590
|
-
async function findTamerStateDatabaseUuid(api
|
|
6591
|
-
const name = tamerStateDatabaseName(
|
|
6621
|
+
async function findTamerStateDatabaseUuid(api) {
|
|
6622
|
+
const name = tamerStateDatabaseName();
|
|
6592
6623
|
return (await api.d1ListAll()).find((d) => d.name === name)?.uuid;
|
|
6593
6624
|
}
|
|
6594
6625
|
/**
|
|
6595
|
-
* Create `tamer-state
|
|
6596
|
-
* initial empty `cfi_state:{stackName}` row when this stack
|
|
6597
|
-
* Idempotent — re-running for the same stack is a no-op;
|
|
6598
|
-
*
|
|
6626
|
+
* Create `tamer-state` (account-scoped) if missing, ensure `tamer_kv` table,
|
|
6627
|
+
* and seed an initial empty `cfi_state:{env}:{stackName}` row when this stack
|
|
6628
|
+
* has no row yet. Idempotent — re-running for the same env+stack is a no-op;
|
|
6629
|
+
* re-running for a different env or stack just adds another row.
|
|
6599
6630
|
*/
|
|
6600
6631
|
async function ensureTamerStateDatabase(api, tenantId, env, stackName = DEFAULT_STACK_NAME) {
|
|
6601
|
-
let uuid$1 = await findTamerStateDatabaseUuid(api
|
|
6602
|
-
if (!uuid$1) uuid$1 = (await api.d1Create(tamerStateDatabaseName(
|
|
6632
|
+
let uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6633
|
+
if (!uuid$1) uuid$1 = (await api.d1Create(tamerStateDatabaseName())).uuid;
|
|
6603
6634
|
await api.d1Query(uuid$1, `CREATE TABLE IF NOT EXISTS tamer_kv (
|
|
6604
6635
|
k TEXT PRIMARY KEY,
|
|
6605
6636
|
v TEXT NOT NULL
|
|
6606
6637
|
)`);
|
|
6607
|
-
const rowKey =
|
|
6638
|
+
const rowKey = stateRowKey(env, stackName);
|
|
6608
6639
|
const { rows } = await api.d1Query(uuid$1, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6609
6640
|
if (rows.length === 0) {
|
|
6610
6641
|
const initial = createEmptyCfiState(tenantId, env);
|
|
@@ -6619,10 +6650,19 @@ function parseCfiStateJson(json) {
|
|
|
6619
6650
|
if (!result.success) throw new Error(`Invalid tamer state JSON: ${result.error.message}`);
|
|
6620
6651
|
return result.data;
|
|
6621
6652
|
}
|
|
6622
|
-
|
|
6623
|
-
|
|
6653
|
+
/**
|
|
6654
|
+
* Delete all state rows for a specific env from the shared account-scoped D1.
|
|
6655
|
+
* Used by `tamer destroy --wipe-metadata` to clean up an env's state without
|
|
6656
|
+
* affecting other envs that share the same `tamer-state` database.
|
|
6657
|
+
*
|
|
6658
|
+
* Note: this does NOT delete the D1 database itself — the shared `tamer-state`
|
|
6659
|
+
* database persists for other envs. To remove Tamer entirely from an account,
|
|
6660
|
+
* delete the D1/R2 resources manually via the Cloudflare dashboard.
|
|
6661
|
+
*/
|
|
6662
|
+
async function deleteEnvStateRows(api, env) {
|
|
6663
|
+
const uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6624
6664
|
if (!uuid$1) return false;
|
|
6625
|
-
await api.
|
|
6665
|
+
await api.d1Query(uuid$1, `DELETE FROM tamer_kv WHERE k LIKE ?`, [`cfi_state:${env}:%`]);
|
|
6626
6666
|
return true;
|
|
6627
6667
|
}
|
|
6628
6668
|
|
|
@@ -6705,15 +6745,13 @@ var StateConflictError = class extends Error {
|
|
|
6705
6745
|
|
|
6706
6746
|
//#endregion
|
|
6707
6747
|
//#region src/core/state/StateManager.ts
|
|
6708
|
-
/** D1 `tamer_kv.k` value for a given stack's state row. */
|
|
6709
|
-
function stateRowKey(stackName) {
|
|
6710
|
-
return `cfi_state:${stackName}`;
|
|
6711
|
-
}
|
|
6712
6748
|
const OPERATION_HISTORY_CAP = 50;
|
|
6713
6749
|
/**
|
|
6714
6750
|
* Authoritative deployment state for an env.
|
|
6715
6751
|
*
|
|
6716
|
-
* - **Non-local:** stored as JSON in Cloudflare D1 (`tamer-state
|
|
6752
|
+
* - **Non-local:** stored as JSON in Cloudflare D1 (`tamer-state`,
|
|
6753
|
+
* account-scoped). Each env's state is isolated by row key:
|
|
6754
|
+
* `cfi_state:{env}:{stackName}`.
|
|
6717
6755
|
* Call {@link hydrate} before {@link load}, then {@link persist} after mutations.
|
|
6718
6756
|
* - **local:** in-memory only (no persistence).
|
|
6719
6757
|
*/
|
|
@@ -6730,14 +6768,13 @@ var StateManager = class {
|
|
|
6730
6768
|
/**
|
|
6731
6769
|
* @param tenantId `config.tenant.id` — recorded on the state row for
|
|
6732
6770
|
* diagnostics; not part of the row key.
|
|
6733
|
-
* @param env Cloudflare environment name;
|
|
6734
|
-
* `
|
|
6771
|
+
* @param env Cloudflare environment name; included in the D1 row key
|
|
6772
|
+
* (`cfi_state:{env}:{stackName}`) for isolation within the
|
|
6773
|
+
* shared account-scoped `tamer-state` database.
|
|
6735
6774
|
* @param stackName Stack identity (`config.stack.name ?? tenant.slug`).
|
|
6736
|
-
*
|
|
6737
|
-
*
|
|
6738
|
-
* clobbering each other. Defaults to `"default"
|
|
6739
|
-
* unit tests that synthesize a StateManager without
|
|
6740
|
-
* a config get a stable key without extra plumbing.
|
|
6775
|
+
* Combined with env to form the D1 row key, so multiple
|
|
6776
|
+
* stacks and multiple envs coexist in one D1 without
|
|
6777
|
+
* clobbering each other. Defaults to `"default"`.
|
|
6741
6778
|
*/
|
|
6742
6779
|
constructor(tenantId, env, stackName = DEFAULT_STACK_NAME) {
|
|
6743
6780
|
this.tenantId = tenantId;
|
|
@@ -6755,11 +6792,10 @@ var StateManager = class {
|
|
|
6755
6792
|
this.baselineRevision = this.state.revision ?? 0;
|
|
6756
6793
|
return;
|
|
6757
6794
|
}
|
|
6758
|
-
const
|
|
6759
|
-
|
|
6760
|
-
if (!uuid$1) throw new Error(`Tamer state database "${name}" not found. Run: tamer bootstrap --env ${this.env}`);
|
|
6795
|
+
const uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6796
|
+
if (!uuid$1) throw new Error(`Tamer state database "tamer-state" not found. Run: tamer bootstrap --env ${this.env}`);
|
|
6761
6797
|
this.tamerStateDbUuid = uuid$1;
|
|
6762
|
-
const rowKey = stateRowKey(this.stackName);
|
|
6798
|
+
const rowKey = stateRowKey(this.env, this.stackName);
|
|
6763
6799
|
const { rows } = await api.d1Query(uuid$1, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6764
6800
|
if (rows.length === 0) {
|
|
6765
6801
|
this.state = createEmptyCfiState(this.tenantId, this.env);
|
|
@@ -6951,7 +6987,7 @@ var StateManager = class {
|
|
|
6951
6987
|
return;
|
|
6952
6988
|
}
|
|
6953
6989
|
if (!this.dirty || !this.state || !this.tamerStateDbUuid) return;
|
|
6954
|
-
const rowKey = stateRowKey(this.stackName);
|
|
6990
|
+
const rowKey = stateRowKey(this.env, this.stackName);
|
|
6955
6991
|
const { rows } = await api.d1Query(this.tamerStateDbUuid, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6956
6992
|
let remoteRev = 0;
|
|
6957
6993
|
if (rows.length > 0) {
|
|
@@ -7333,7 +7369,8 @@ function namingFromConfig(config$1) {
|
|
|
7333
7369
|
//#endregion
|
|
7334
7370
|
//#region src/core/secrets/SecretsVault.ts
|
|
7335
7371
|
/**
|
|
7336
|
-
* Encrypted secrets vault backed by `tamer-secrets
|
|
7372
|
+
* Encrypted secrets vault backed by account-scoped `tamer-secrets` D1.
|
|
7373
|
+
* Each env's secrets are isolated by row key: `{env}:{secretName}`.
|
|
7337
7374
|
* Stores ciphertext only — never plaintext.
|
|
7338
7375
|
*/
|
|
7339
7376
|
var SecretsVault = class {
|
|
@@ -7343,10 +7380,19 @@ var SecretsVault = class {
|
|
|
7343
7380
|
this.env = env;
|
|
7344
7381
|
this.databaseId = databaseId;
|
|
7345
7382
|
}
|
|
7383
|
+
/** Convert a logical secret name to its D1 row key: `{env}:{name}`. */
|
|
7384
|
+
key(name) {
|
|
7385
|
+
return secretRowKey(this.env, name);
|
|
7386
|
+
}
|
|
7387
|
+
/** Reverse: strip the `{env}:` prefix from a D1 row key. */
|
|
7388
|
+
unkey(rowKey) {
|
|
7389
|
+
const prefix = `${this.env}:`;
|
|
7390
|
+
return rowKey.startsWith(prefix) ? rowKey.slice(prefix.length) : rowKey;
|
|
7391
|
+
}
|
|
7346
7392
|
async dbId() {
|
|
7347
7393
|
if (this.databaseId) return this.databaseId;
|
|
7348
|
-
const uuid$1 = await findTamerSecretsDatabaseUuid(this.api
|
|
7349
|
-
if (!uuid$1) throw new Error(`secrets vault not provisioned
|
|
7394
|
+
const uuid$1 = await findTamerSecretsDatabaseUuid(this.api);
|
|
7395
|
+
if (!uuid$1) throw new Error(`secrets vault not provisioned (expected D1 "tamer-secrets"); run tamer bootstrap`);
|
|
7350
7396
|
this.databaseId = uuid$1;
|
|
7351
7397
|
return uuid$1;
|
|
7352
7398
|
}
|
|
@@ -7354,6 +7400,7 @@ var SecretsVault = class {
|
|
|
7354
7400
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7355
7401
|
const updatedBy = options?.updatedBy;
|
|
7356
7402
|
const db = await this.dbId();
|
|
7403
|
+
const key = this.key(name);
|
|
7357
7404
|
await this.api.d1Query(db, `INSERT INTO secrets (
|
|
7358
7405
|
name, ciphertext, iv, wrapped_dek, dek_iv, value_hash, updated_at, updated_by
|
|
7359
7406
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -7365,7 +7412,7 @@ var SecretsVault = class {
|
|
|
7365
7412
|
value_hash = excluded.value_hash,
|
|
7366
7413
|
updated_at = excluded.updated_at,
|
|
7367
7414
|
updated_by = excluded.updated_by`, [
|
|
7368
|
-
|
|
7415
|
+
key,
|
|
7369
7416
|
blobParam(encrypted.ciphertext),
|
|
7370
7417
|
blobParam(encrypted.iv),
|
|
7371
7418
|
blobParam(encrypted.wrappedDek),
|
|
@@ -7376,7 +7423,7 @@ var SecretsVault = class {
|
|
|
7376
7423
|
]);
|
|
7377
7424
|
await this.api.d1Query(db, `INSERT INTO secret_history (name, value_hash, updated_at, updated_by)
|
|
7378
7425
|
VALUES (?, ?, ?, ?)`, [
|
|
7379
|
-
|
|
7426
|
+
key,
|
|
7380
7427
|
valueHash,
|
|
7381
7428
|
updatedAt,
|
|
7382
7429
|
updatedBy ?? null
|
|
@@ -7391,24 +7438,24 @@ var SecretsVault = class {
|
|
|
7391
7438
|
LIMIT -1 OFFSET ?
|
|
7392
7439
|
)
|
|
7393
7440
|
)`, [
|
|
7394
|
-
|
|
7395
|
-
|
|
7441
|
+
key,
|
|
7442
|
+
key,
|
|
7396
7443
|
SECRET_HISTORY_CAP
|
|
7397
7444
|
]);
|
|
7398
7445
|
}
|
|
7399
7446
|
async get(name) {
|
|
7400
7447
|
const db = await this.dbId();
|
|
7401
7448
|
const { rows } = await this.api.d1Query(db, `SELECT name, ciphertext, iv, wrapped_dek, dek_iv, value_hash, updated_at, updated_by
|
|
7402
|
-
FROM secrets WHERE name = ?`, [name]);
|
|
7449
|
+
FROM secrets WHERE name = ?`, [this.key(name)]);
|
|
7403
7450
|
if (rows.length === 0) return void 0;
|
|
7404
|
-
return rowToVaultSecret(rows[0]);
|
|
7451
|
+
return rowToVaultSecret(rows[0], this.env);
|
|
7405
7452
|
}
|
|
7406
7453
|
async list() {
|
|
7407
7454
|
const db = await this.dbId();
|
|
7408
7455
|
const { rows } = await this.api.d1Query(db, `SELECT name, value_hash, updated_at, updated_by
|
|
7409
|
-
FROM secrets ORDER BY name
|
|
7456
|
+
FROM secrets WHERE name LIKE ? ORDER BY name`, [`${this.env}:%`]);
|
|
7410
7457
|
return rows.map((row) => ({
|
|
7411
|
-
name: String(row.name),
|
|
7458
|
+
name: this.unkey(String(row.name)),
|
|
7412
7459
|
valueHash: row.value_hash,
|
|
7413
7460
|
updatedAt: String(row.updated_at),
|
|
7414
7461
|
updatedBy: row.updated_by != null ? String(row.updated_by) : void 0
|
|
@@ -7416,7 +7463,7 @@ var SecretsVault = class {
|
|
|
7416
7463
|
}
|
|
7417
7464
|
async delete(name) {
|
|
7418
7465
|
const db = await this.dbId();
|
|
7419
|
-
const { rows } = await this.api.d1Query(db, `DELETE FROM secrets WHERE name = ? RETURNING name`, [name]);
|
|
7466
|
+
const { rows } = await this.api.d1Query(db, `DELETE FROM secrets WHERE name = ? RETURNING name`, [this.key(name)]);
|
|
7420
7467
|
return rows.length > 0;
|
|
7421
7468
|
}
|
|
7422
7469
|
/** Append an audit row (e.g. after `secrets get`) without changing the secret. */
|
|
@@ -7426,9 +7473,10 @@ var SecretsVault = class {
|
|
|
7426
7473
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7427
7474
|
const updatedBy = options?.updatedBy;
|
|
7428
7475
|
const db = await this.dbId();
|
|
7476
|
+
const key = this.key(name);
|
|
7429
7477
|
await this.api.d1Query(db, `INSERT INTO secret_history (name, value_hash, updated_at, updated_by)
|
|
7430
7478
|
VALUES (?, ?, ?, ?)`, [
|
|
7431
|
-
|
|
7479
|
+
key,
|
|
7432
7480
|
record$1.valueHash,
|
|
7433
7481
|
updatedAt,
|
|
7434
7482
|
updatedBy ?? null
|
|
@@ -7443,8 +7491,8 @@ var SecretsVault = class {
|
|
|
7443
7491
|
LIMIT -1 OFFSET ?
|
|
7444
7492
|
)
|
|
7445
7493
|
)`, [
|
|
7446
|
-
|
|
7447
|
-
|
|
7494
|
+
key,
|
|
7495
|
+
key,
|
|
7448
7496
|
SECRET_HISTORY_CAP
|
|
7449
7497
|
]);
|
|
7450
7498
|
}
|
|
@@ -7453,18 +7501,20 @@ var SecretsVault = class {
|
|
|
7453
7501
|
const { rows } = await this.api.d1Query(db, `SELECT name, value_hash, updated_at, updated_by
|
|
7454
7502
|
FROM secret_history
|
|
7455
7503
|
WHERE name = ?
|
|
7456
|
-
ORDER BY updated_at DESC`, [name]);
|
|
7504
|
+
ORDER BY updated_at DESC`, [this.key(name)]);
|
|
7457
7505
|
return rows.map((row) => ({
|
|
7458
|
-
name: String(row.name),
|
|
7506
|
+
name: this.unkey(String(row.name)),
|
|
7459
7507
|
valueHash: row.value_hash,
|
|
7460
7508
|
updatedAt: String(row.updated_at),
|
|
7461
7509
|
updatedBy: row.updated_by != null ? String(row.updated_by) : void 0
|
|
7462
7510
|
}));
|
|
7463
7511
|
}
|
|
7464
7512
|
};
|
|
7465
|
-
function rowToVaultSecret(row) {
|
|
7513
|
+
function rowToVaultSecret(row, env) {
|
|
7514
|
+
const rawName = String(row.name);
|
|
7515
|
+
const prefix = `${env}:`;
|
|
7466
7516
|
return {
|
|
7467
|
-
name:
|
|
7517
|
+
name: rawName.startsWith(prefix) ? rawName.slice(prefix.length) : rawName,
|
|
7468
7518
|
ciphertext: blobFromRow(row.ciphertext),
|
|
7469
7519
|
iv: blobFromRow(row.iv),
|
|
7470
7520
|
wrappedDek: blobFromRow(row.wrapped_dek),
|
|
@@ -7512,7 +7562,7 @@ async function createSecretsContext(options) {
|
|
|
7512
7562
|
const accountId = config$1.account_id ?? cloudflareAccountIdFromEnv();
|
|
7513
7563
|
if (!accountId) throw new Error("account_id required in config or CLOUDFLARE_ACCOUNT_ID env var");
|
|
7514
7564
|
const api = new CFApiClient(accountId);
|
|
7515
|
-
const vault = new SecretsVault(api, env, await ensureTamerSecretsDatabase(api
|
|
7565
|
+
const vault = new SecretsVault(api, env, await ensureTamerSecretsDatabase(api));
|
|
7516
7566
|
const state = new StateManager(config$1.tenant.id, env, stackNameForConfig(config$1));
|
|
7517
7567
|
await state.hydrate(api);
|
|
7518
7568
|
const masterKey = readMasterKeyFromEnv(env);
|
|
@@ -7593,7 +7643,7 @@ function displayPathFromCwd(absOrRel) {
|
|
|
7593
7643
|
async function createDeploySecretsResources(api, env) {
|
|
7594
7644
|
const resolvedEnv = resolveSecretsEnv(env);
|
|
7595
7645
|
return {
|
|
7596
|
-
vault: new SecretsVault(api, resolvedEnv, await ensureTamerSecretsDatabase(api
|
|
7646
|
+
vault: new SecretsVault(api, resolvedEnv, await ensureTamerSecretsDatabase(api)),
|
|
7597
7647
|
masterKey: readMasterKeyFromEnv(resolvedEnv)
|
|
7598
7648
|
};
|
|
7599
7649
|
}
|
|
@@ -7606,8 +7656,8 @@ async function runSecretsInit(options) {
|
|
|
7606
7656
|
if (!accountId) throw new Error("account_id required in config or CLOUDFLARE_ACCOUNT_ID env var");
|
|
7607
7657
|
const masterKey = generateMasterKey();
|
|
7608
7658
|
const varName = masterKeyEnvVarName(env);
|
|
7609
|
-
const uuid$1 = await ensureTamerSecretsDatabase(new CFApiClient(accountId)
|
|
7610
|
-
console.log(`Secrets vault ready: D1 uuid=${uuid$1} name=${tamerSecretsDatabaseName(
|
|
7659
|
+
const uuid$1 = await ensureTamerSecretsDatabase(new CFApiClient(accountId));
|
|
7660
|
+
console.log(`Secrets vault ready: D1 uuid=${uuid$1} name=${tamerSecretsDatabaseName()}`);
|
|
7611
7661
|
console.log("");
|
|
7612
7662
|
console.log(`Generated master key for env "${env}" (store in two durable places — CI + password manager):`);
|
|
7613
7663
|
console.log("");
|
|
@@ -8654,14 +8704,14 @@ async function main() {
|
|
|
8654
8704
|
try {
|
|
8655
8705
|
switch (command) {
|
|
8656
8706
|
case "bootstrap":
|
|
8657
|
-
await import("./bootstrap-
|
|
8707
|
+
await import("./bootstrap-C7CZYHzb.mjs").then((m) => m.runBootstrap(parseBootstrapArgs(rest)));
|
|
8658
8708
|
break;
|
|
8659
8709
|
case "sync":
|
|
8660
|
-
await import("./sync-
|
|
8710
|
+
await import("./sync-DEudPgQc.mjs").then((m) => m.runSync(parseSyncArgs(rest)));
|
|
8661
8711
|
break;
|
|
8662
8712
|
case "apply": {
|
|
8663
8713
|
const a = parseApplyArgs(rest);
|
|
8664
|
-
await import("./apply-
|
|
8714
|
+
await import("./apply-B2wMY64Q.mjs").then((m) => m.runApply({
|
|
8665
8715
|
env: a.env,
|
|
8666
8716
|
addShard: a.addShard,
|
|
8667
8717
|
configPath: a.configPath,
|
|
@@ -8673,11 +8723,11 @@ async function main() {
|
|
|
8673
8723
|
break;
|
|
8674
8724
|
}
|
|
8675
8725
|
case "dev":
|
|
8676
|
-
await import("./dev-
|
|
8726
|
+
await import("./dev-BiPXBOKk.mjs").then((m) => m.runDev(parseDevArgs(rest)));
|
|
8677
8727
|
break;
|
|
8678
8728
|
case "deploy": {
|
|
8679
8729
|
const d = parseDeployArgs(rest);
|
|
8680
|
-
await import("./deploy-
|
|
8730
|
+
await import("./deploy-C4Mi_qwz.mjs").then((m) => m.runDeploy({
|
|
8681
8731
|
worker: d.worker,
|
|
8682
8732
|
env: d.env,
|
|
8683
8733
|
configPath: d.configPath,
|
|
@@ -8686,23 +8736,23 @@ async function main() {
|
|
|
8686
8736
|
break;
|
|
8687
8737
|
}
|
|
8688
8738
|
case "migrate":
|
|
8689
|
-
await import("./migrate-
|
|
8739
|
+
await import("./migrate-36WDEaFz.mjs").then((m) => m.runMigrate(parseMigrateArgs(rest)));
|
|
8690
8740
|
break;
|
|
8691
8741
|
case "types":
|
|
8692
|
-
await import("./types-
|
|
8742
|
+
await import("./types-BQajHdJb.mjs").then((m) => m.runTypes(parseTypesArgs(rest)));
|
|
8693
8743
|
break;
|
|
8694
8744
|
case "status":
|
|
8695
|
-
await import("./status-
|
|
8745
|
+
await import("./status-DaaOPBEf.mjs").then((m) => m.runStatus(parseStatusArgs(rest)));
|
|
8696
8746
|
break;
|
|
8697
8747
|
case "events":
|
|
8698
|
-
await import("./events-
|
|
8748
|
+
await import("./events-D9kQWwH8.mjs").then((m) => m.runEvents(parseEventsArgs(rest)));
|
|
8699
8749
|
break;
|
|
8700
8750
|
case "drift":
|
|
8701
|
-
exitStatus = await import("./drift-
|
|
8751
|
+
exitStatus = await import("./drift-DqMtlwkg.mjs").then((m) => m.runDrift(parseDriftArgs(rest)));
|
|
8702
8752
|
break;
|
|
8703
8753
|
case "plan": {
|
|
8704
8754
|
const p = parsePlanArgs(rest);
|
|
8705
|
-
exitStatus = await import("./plan-
|
|
8755
|
+
exitStatus = await import("./plan-k0jLGYyw.mjs").then((m) => m.runPlan({
|
|
8706
8756
|
env: p.env,
|
|
8707
8757
|
configPath: p.configPath,
|
|
8708
8758
|
json: p.json,
|
|
@@ -8714,14 +8764,14 @@ async function main() {
|
|
|
8714
8764
|
break;
|
|
8715
8765
|
}
|
|
8716
8766
|
case "import":
|
|
8717
|
-
await import("./import-
|
|
8767
|
+
await import("./import-DHmLtue3.mjs").then((m) => m.runImport(parseImportArgs(rest)));
|
|
8718
8768
|
break;
|
|
8719
8769
|
case "doctor":
|
|
8720
|
-
exitStatus = await import("./doctor-
|
|
8770
|
+
exitStatus = await import("./doctor-DDwsA2V6.mjs").then((m) => m.runDoctor(parseDoctorArgs(rest)));
|
|
8721
8771
|
break;
|
|
8722
8772
|
case "provision-tenant": {
|
|
8723
8773
|
const p = parseProvisionTenantArgs(rest);
|
|
8724
|
-
await import("./provision-tenant-
|
|
8774
|
+
await import("./provision-tenant-BjFpVm-y.mjs").then((m) => m.runProvisionTenant({
|
|
8725
8775
|
env: p.env,
|
|
8726
8776
|
product: p.product,
|
|
8727
8777
|
workspace: p.workspace,
|
|
@@ -8738,7 +8788,7 @@ async function main() {
|
|
|
8738
8788
|
}
|
|
8739
8789
|
case "destroy-tenant": {
|
|
8740
8790
|
const t = parseDestroyTenantArgs(rest);
|
|
8741
|
-
await import("./destroy-tenant-
|
|
8791
|
+
await import("./destroy-tenant-DL99EoRZ.mjs").then((m) => m.runDestroyTenant({
|
|
8742
8792
|
env: t.env,
|
|
8743
8793
|
product: t.product,
|
|
8744
8794
|
workspace: t.workspace,
|
|
@@ -8751,7 +8801,7 @@ async function main() {
|
|
|
8751
8801
|
}
|
|
8752
8802
|
case "destroy": {
|
|
8753
8803
|
const d = parseDestroyArgs(rest);
|
|
8754
|
-
await import("./destroy-
|
|
8804
|
+
await import("./destroy-DDVWxl7U.mjs").then((m) => m.runDestroy({
|
|
8755
8805
|
env: d.env,
|
|
8756
8806
|
force: d.force,
|
|
8757
8807
|
skipWorkers: d.skipWorkers,
|
|
@@ -8766,12 +8816,12 @@ async function main() {
|
|
|
8766
8816
|
case "wfp": {
|
|
8767
8817
|
const [sub, ...wfpRest] = rest;
|
|
8768
8818
|
if (sub === "put") {
|
|
8769
|
-
const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-
|
|
8819
|
+
const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-DX_bH-s7.mjs");
|
|
8770
8820
|
await runWfpPut(parseWfpPutArgs(wfpRest));
|
|
8771
8821
|
break;
|
|
8772
8822
|
}
|
|
8773
8823
|
if (sub === "delete") {
|
|
8774
|
-
const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-
|
|
8824
|
+
const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-DsfqSBxt.mjs");
|
|
8775
8825
|
await runWfpDelete(parseWfpDeleteArgs(wfpRest));
|
|
8776
8826
|
break;
|
|
8777
8827
|
}
|
|
@@ -8871,5 +8921,5 @@ Environment variables (same as Wrangler):
|
|
|
8871
8921
|
main();
|
|
8872
8922
|
|
|
8873
8923
|
//#endregion
|
|
8874
|
-
export { rewriteIntraStackServiceTargets as A,
|
|
8924
|
+
export { rewriteIntraStackServiceTargets as A, cloudflareApiTokenFromEnv as B, tamerStateDatabaseName as C, mergedWorkerConfigForEnv as D, mergeWorkerConfigForResourcePick as E, deleteEnvSecretRows as F, loadConfig as H, ensureTamerSecretsDatabase as I, tamerSecretsDatabaseName as L, wranglerConfigCliArgs as M, effectiveDispatchNamespaceName as N, resolveDeployedWorkerName as O, isEphemeralEnv as P, CFApiClient as R, ensureTamerStateDatabase as S, buildIntraStackScriptNameMap as T, getWorkers as V, tenantDispatchScriptName as _, reconcileSecrets as a, createEmptyCfiState as b, vaultReaderFromMap as c, requiredSecretsForWorker as d, fetchStackImports as f, parseTenantShardRoles as g, StateManager as h, pushSecretsForDeploy as i, resolveReferencesInString as j, resolveWorkerConfig as k, createDeploySecretsResources as l, scanConfigForImports as m, parseSecretsArgs as n, secretsDrift as o, importedStackNames as p, runSecrets as r, secretsPlanItems as s, SECRETS_USAGE as t, namingFromConfig as u, tenantShardDatabaseName as v, stackNameForConfig as w, deleteEnvStateRows as x, tenantStateKey as y, cloudflareAccountIdFromEnv as z };
|
|
8875
8925
|
//# sourceMappingURL=tamer.mjs.map
|