@dragonmastery/tamer 0.34.1 → 0.35.1
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-Cz1lxAOp.mjs} +11 -11
- package/dist/{apply-BsVQ9cbK.mjs.map → apply-Cz1lxAOp.mjs.map} +1 -1
- package/dist/{applyTarget-BJlVrED9.mjs → applyTarget-BI6QAVwA.mjs} +2 -2
- package/dist/{applyTarget-BJlVrED9.mjs.map → applyTarget-BI6QAVwA.mjs.map} +1 -1
- package/dist/bootstrap-CsL4IT9Z.mjs +34 -0
- package/dist/bootstrap-CsL4IT9Z.mjs.map +1 -0
- package/dist/{cloudflareSnapshot-CMbPQIsN.mjs → cloudflareSnapshot-CpNFH4zd.mjs} +4 -4
- package/dist/{cloudflareSnapshot-CMbPQIsN.mjs.map → cloudflareSnapshot-CpNFH4zd.mjs.map} +1 -1
- package/dist/{deploy-dNygCucr.mjs → deploy-D2tQrtN9.mjs} +7 -7
- package/dist/{deploy-dNygCucr.mjs.map → deploy-D2tQrtN9.mjs.map} +1 -1
- package/dist/{destroy-C0cKkpWe.mjs → destroy-CEv14T0X.mjs} +18 -12
- package/dist/destroy-CEv14T0X.mjs.map +1 -0
- package/dist/{destroy-tenant-hyEb1gEz.mjs → destroy-tenant-Ugu7Y1EH.mjs} +2 -2
- package/dist/{destroy-tenant-hyEb1gEz.mjs.map → destroy-tenant-Ugu7Y1EH.mjs.map} +1 -1
- package/dist/{dev-Bug5l5OZ.mjs → dev-vGQIP7tD.mjs} +6 -6
- package/dist/{dev-Bug5l5OZ.mjs.map → dev-vGQIP7tD.mjs.map} +1 -1
- package/dist/{dns-records.sync-FyzKl-Ph.mjs → dns-records.sync-PoahWQjY.mjs} +2 -2
- package/dist/{dns-records.sync-FyzKl-Ph.mjs.map → dns-records.sync-PoahWQjY.mjs.map} +1 -1
- package/dist/{doctor-BwuEPYM6.mjs → doctor-BnsOxqnA.mjs} +2 -2
- package/dist/{doctor-BwuEPYM6.mjs.map → doctor-BnsOxqnA.mjs.map} +1 -1
- package/dist/{drift-DENAf1Oe.mjs → drift-C3wIrNyg.mjs} +4 -4
- package/dist/{drift-B5y9LF5X.mjs → drift-C7pgj4Iw.mjs} +5 -5
- package/dist/{drift-B5y9LF5X.mjs.map → drift-C7pgj4Iw.mjs.map} +1 -1
- package/dist/{emit-DTpaIMkn.mjs → emit-vpibELHm.mjs} +3 -3
- package/dist/{emit-DTpaIMkn.mjs.map → emit-vpibELHm.mjs.map} +1 -1
- package/dist/{events-B7Lencm8.mjs → events-yk4J3l0M.mjs} +2 -2
- package/dist/{events-B7Lencm8.mjs.map → events-yk4J3l0M.mjs.map} +1 -1
- package/dist/{generator-ZTEeHlft.mjs → generator-7b97QsuM.mjs} +2 -2
- package/dist/{generator-ZTEeHlft.mjs.map → generator-7b97QsuM.mjs.map} +1 -1
- package/dist/{import-Ciq9MN3v.mjs → import-CZ6509_t.mjs} +3 -3
- package/dist/{import-Ciq9MN3v.mjs.map → import-CZ6509_t.mjs.map} +1 -1
- package/dist/{migrate-DWyUVN1I.mjs → migrate-DDBMzPtR.mjs} +4 -4
- package/dist/{migrate-DWyUVN1I.mjs.map → migrate-DDBMzPtR.mjs.map} +1 -1
- package/dist/{plan-Blxn-yKr.mjs → plan-Dot2VV7R.mjs} +8 -8
- package/dist/{plan-Blxn-yKr.mjs.map → plan-Dot2VV7R.mjs.map} +1 -1
- package/dist/{provision-tenant-BHDWTC2U.mjs → provision-tenant-C2EL79oz.mjs} +6 -5
- package/dist/provision-tenant-C2EL79oz.mjs.map +1 -0
- package/dist/{registry-BlHEOKlN.mjs → registry-D-vo1TTV.mjs} +2 -2
- package/dist/{registry-BlHEOKlN.mjs.map → registry-D-vo1TTV.mjs.map} +1 -1
- package/dist/{stackOutputs-CkpNSng8.mjs → stackOutputs-CuLa76D4.mjs} +2 -2
- package/dist/{stackOutputs-CkpNSng8.mjs.map → stackOutputs-CuLa76D4.mjs.map} +1 -1
- package/dist/{status-PlMHsDzT.mjs → status-_k3a77Fw.mjs} +4 -4
- package/dist/{status-PlMHsDzT.mjs.map → status-_k3a77Fw.mjs.map} +1 -1
- package/dist/{sync-YKZ5HD8v.mjs → sync-C5RjLfgk.mjs} +5 -5
- package/dist/{sync-YKZ5HD8v.mjs.map → sync-C5RjLfgk.mjs.map} +1 -1
- package/dist/tamer.mjs +141 -93
- 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-CqmFeIBf.mjs} +4 -4
- package/dist/{types-CADr4Kck.mjs.map → types-CqmFeIBf.mjs.map} +1 -1
- package/dist/{verifyPlanFile-BBAwWzUo.mjs → verifyPlanFile-DSO-yS64.mjs} +2 -2
- package/dist/{verifyPlanFile-BBAwWzUo.mjs.map → verifyPlanFile-DSO-yS64.mjs.map} +1 -1
- package/dist/{wfp-delete-CQc9tveU.mjs → wfp-delete-C-1pIY3Z.mjs} +2 -2
- package/dist/{wfp-delete-CQc9tveU.mjs.map → wfp-delete-C-1pIY3Z.mjs.map} +1 -1
- package/dist/{wfp-put-CVw8cloM.mjs → wfp-put-D0tDs0J5.mjs} +2 -2
- package/dist/{wfp-put-CVw8cloM.mjs.map → wfp-put-D0tDs0J5.mjs.map} +1 -1
- package/dist/{worker-route-CqBDvjgo.mjs → worker-route-RexL6xCk.mjs} +2 -2
- package/dist/{worker-route-CqBDvjgo.mjs.map → worker-route-RexL6xCk.mjs.map} +1 -1
- package/dist/{workers-y9RTOzbC.mjs → workers-CS0tlbdk.mjs} +2 -2
- package/dist/{workers-y9RTOzbC.mjs.map → workers-CS0tlbdk.mjs.map} +1 -1
- package/package.json +6 -2
- package/dist/bootstrap-CV6OT-c9.mjs +0 -33
- 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
|
|
@@ -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,28 @@ 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
|
-
*
|
|
6597
|
-
*
|
|
6598
|
-
*
|
|
6626
|
+
* Create `tamer-state` (account-scoped) if missing, ensure `tamer_kv` table.
|
|
6627
|
+
* When `env` is provided, also seeds an initial empty
|
|
6628
|
+
* `cfi_state:{env}:{stackName}` row for that stack. When `env` is omitted
|
|
6629
|
+
* (e.g. from `tamer bootstrap`), only creates the D1 + table — the first
|
|
6630
|
+
* `tamer apply` will seed the row automatically via the StateManager.
|
|
6631
|
+
*
|
|
6632
|
+
* Idempotent — re-running is always safe.
|
|
6599
6633
|
*/
|
|
6600
6634
|
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(
|
|
6635
|
+
let uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6636
|
+
if (!uuid$1) uuid$1 = (await api.d1Create(tamerStateDatabaseName())).uuid;
|
|
6603
6637
|
await api.d1Query(uuid$1, `CREATE TABLE IF NOT EXISTS tamer_kv (
|
|
6604
6638
|
k TEXT PRIMARY KEY,
|
|
6605
6639
|
v TEXT NOT NULL
|
|
6606
6640
|
)`);
|
|
6607
|
-
|
|
6641
|
+
if (!env) return uuid$1;
|
|
6642
|
+
const rowKey = stateRowKey(env, stackName);
|
|
6608
6643
|
const { rows } = await api.d1Query(uuid$1, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6609
6644
|
if (rows.length === 0) {
|
|
6610
6645
|
const initial = createEmptyCfiState(tenantId, env);
|
|
@@ -6619,10 +6654,19 @@ function parseCfiStateJson(json) {
|
|
|
6619
6654
|
if (!result.success) throw new Error(`Invalid tamer state JSON: ${result.error.message}`);
|
|
6620
6655
|
return result.data;
|
|
6621
6656
|
}
|
|
6622
|
-
|
|
6623
|
-
|
|
6657
|
+
/**
|
|
6658
|
+
* Delete all state rows for a specific env from the shared account-scoped D1.
|
|
6659
|
+
* Used by `tamer destroy --wipe-metadata` to clean up an env's state without
|
|
6660
|
+
* affecting other envs that share the same `tamer-state` database.
|
|
6661
|
+
*
|
|
6662
|
+
* Note: this does NOT delete the D1 database itself — the shared `tamer-state`
|
|
6663
|
+
* database persists for other envs. To remove Tamer entirely from an account,
|
|
6664
|
+
* delete the D1/R2 resources manually via the Cloudflare dashboard.
|
|
6665
|
+
*/
|
|
6666
|
+
async function deleteEnvStateRows(api, env) {
|
|
6667
|
+
const uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6624
6668
|
if (!uuid$1) return false;
|
|
6625
|
-
await api.
|
|
6669
|
+
await api.d1Query(uuid$1, `DELETE FROM tamer_kv WHERE k LIKE ?`, [`cfi_state:${env}:%`]);
|
|
6626
6670
|
return true;
|
|
6627
6671
|
}
|
|
6628
6672
|
|
|
@@ -6705,15 +6749,13 @@ var StateConflictError = class extends Error {
|
|
|
6705
6749
|
|
|
6706
6750
|
//#endregion
|
|
6707
6751
|
//#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
6752
|
const OPERATION_HISTORY_CAP = 50;
|
|
6713
6753
|
/**
|
|
6714
6754
|
* Authoritative deployment state for an env.
|
|
6715
6755
|
*
|
|
6716
|
-
* - **Non-local:** stored as JSON in Cloudflare D1 (`tamer-state
|
|
6756
|
+
* - **Non-local:** stored as JSON in Cloudflare D1 (`tamer-state`,
|
|
6757
|
+
* account-scoped). Each env's state is isolated by row key:
|
|
6758
|
+
* `cfi_state:{env}:{stackName}`.
|
|
6717
6759
|
* Call {@link hydrate} before {@link load}, then {@link persist} after mutations.
|
|
6718
6760
|
* - **local:** in-memory only (no persistence).
|
|
6719
6761
|
*/
|
|
@@ -6730,14 +6772,13 @@ var StateManager = class {
|
|
|
6730
6772
|
/**
|
|
6731
6773
|
* @param tenantId `config.tenant.id` — recorded on the state row for
|
|
6732
6774
|
* diagnostics; not part of the row key.
|
|
6733
|
-
* @param env Cloudflare environment name;
|
|
6734
|
-
* `
|
|
6775
|
+
* @param env Cloudflare environment name; included in the D1 row key
|
|
6776
|
+
* (`cfi_state:{env}:{stackName}`) for isolation within the
|
|
6777
|
+
* shared account-scoped `tamer-state` database.
|
|
6735
6778
|
* @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.
|
|
6779
|
+
* Combined with env to form the D1 row key, so multiple
|
|
6780
|
+
* stacks and multiple envs coexist in one D1 without
|
|
6781
|
+
* clobbering each other. Defaults to `"default"`.
|
|
6741
6782
|
*/
|
|
6742
6783
|
constructor(tenantId, env, stackName = DEFAULT_STACK_NAME) {
|
|
6743
6784
|
this.tenantId = tenantId;
|
|
@@ -6755,11 +6796,10 @@ var StateManager = class {
|
|
|
6755
6796
|
this.baselineRevision = this.state.revision ?? 0;
|
|
6756
6797
|
return;
|
|
6757
6798
|
}
|
|
6758
|
-
const
|
|
6759
|
-
|
|
6760
|
-
if (!uuid$1) throw new Error(`Tamer state database "${name}" not found. Run: tamer bootstrap --env ${this.env}`);
|
|
6799
|
+
const uuid$1 = await findTamerStateDatabaseUuid(api);
|
|
6800
|
+
if (!uuid$1) throw new Error(`Tamer state database "tamer-state" not found. Run: tamer bootstrap --env ${this.env}`);
|
|
6761
6801
|
this.tamerStateDbUuid = uuid$1;
|
|
6762
|
-
const rowKey = stateRowKey(this.stackName);
|
|
6802
|
+
const rowKey = stateRowKey(this.env, this.stackName);
|
|
6763
6803
|
const { rows } = await api.d1Query(uuid$1, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6764
6804
|
if (rows.length === 0) {
|
|
6765
6805
|
this.state = createEmptyCfiState(this.tenantId, this.env);
|
|
@@ -6951,7 +6991,7 @@ var StateManager = class {
|
|
|
6951
6991
|
return;
|
|
6952
6992
|
}
|
|
6953
6993
|
if (!this.dirty || !this.state || !this.tamerStateDbUuid) return;
|
|
6954
|
-
const rowKey = stateRowKey(this.stackName);
|
|
6994
|
+
const rowKey = stateRowKey(this.env, this.stackName);
|
|
6955
6995
|
const { rows } = await api.d1Query(this.tamerStateDbUuid, `SELECT v FROM tamer_kv WHERE k = ?`, [rowKey]);
|
|
6956
6996
|
let remoteRev = 0;
|
|
6957
6997
|
if (rows.length > 0) {
|
|
@@ -7333,7 +7373,8 @@ function namingFromConfig(config$1) {
|
|
|
7333
7373
|
//#endregion
|
|
7334
7374
|
//#region src/core/secrets/SecretsVault.ts
|
|
7335
7375
|
/**
|
|
7336
|
-
* Encrypted secrets vault backed by `tamer-secrets
|
|
7376
|
+
* Encrypted secrets vault backed by account-scoped `tamer-secrets` D1.
|
|
7377
|
+
* Each env's secrets are isolated by row key: `{env}:{secretName}`.
|
|
7337
7378
|
* Stores ciphertext only — never plaintext.
|
|
7338
7379
|
*/
|
|
7339
7380
|
var SecretsVault = class {
|
|
@@ -7343,10 +7384,19 @@ var SecretsVault = class {
|
|
|
7343
7384
|
this.env = env;
|
|
7344
7385
|
this.databaseId = databaseId;
|
|
7345
7386
|
}
|
|
7387
|
+
/** Convert a logical secret name to its D1 row key: `{env}:{name}`. */
|
|
7388
|
+
key(name) {
|
|
7389
|
+
return secretRowKey(this.env, name);
|
|
7390
|
+
}
|
|
7391
|
+
/** Reverse: strip the `{env}:` prefix from a D1 row key. */
|
|
7392
|
+
unkey(rowKey) {
|
|
7393
|
+
const prefix = `${this.env}:`;
|
|
7394
|
+
return rowKey.startsWith(prefix) ? rowKey.slice(prefix.length) : rowKey;
|
|
7395
|
+
}
|
|
7346
7396
|
async dbId() {
|
|
7347
7397
|
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
|
|
7398
|
+
const uuid$1 = await findTamerSecretsDatabaseUuid(this.api);
|
|
7399
|
+
if (!uuid$1) throw new Error(`secrets vault not provisioned (expected D1 "tamer-secrets"); run tamer bootstrap`);
|
|
7350
7400
|
this.databaseId = uuid$1;
|
|
7351
7401
|
return uuid$1;
|
|
7352
7402
|
}
|
|
@@ -7354,6 +7404,7 @@ var SecretsVault = class {
|
|
|
7354
7404
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7355
7405
|
const updatedBy = options?.updatedBy;
|
|
7356
7406
|
const db = await this.dbId();
|
|
7407
|
+
const key = this.key(name);
|
|
7357
7408
|
await this.api.d1Query(db, `INSERT INTO secrets (
|
|
7358
7409
|
name, ciphertext, iv, wrapped_dek, dek_iv, value_hash, updated_at, updated_by
|
|
7359
7410
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -7365,7 +7416,7 @@ var SecretsVault = class {
|
|
|
7365
7416
|
value_hash = excluded.value_hash,
|
|
7366
7417
|
updated_at = excluded.updated_at,
|
|
7367
7418
|
updated_by = excluded.updated_by`, [
|
|
7368
|
-
|
|
7419
|
+
key,
|
|
7369
7420
|
blobParam(encrypted.ciphertext),
|
|
7370
7421
|
blobParam(encrypted.iv),
|
|
7371
7422
|
blobParam(encrypted.wrappedDek),
|
|
@@ -7376,7 +7427,7 @@ var SecretsVault = class {
|
|
|
7376
7427
|
]);
|
|
7377
7428
|
await this.api.d1Query(db, `INSERT INTO secret_history (name, value_hash, updated_at, updated_by)
|
|
7378
7429
|
VALUES (?, ?, ?, ?)`, [
|
|
7379
|
-
|
|
7430
|
+
key,
|
|
7380
7431
|
valueHash,
|
|
7381
7432
|
updatedAt,
|
|
7382
7433
|
updatedBy ?? null
|
|
@@ -7391,24 +7442,24 @@ var SecretsVault = class {
|
|
|
7391
7442
|
LIMIT -1 OFFSET ?
|
|
7392
7443
|
)
|
|
7393
7444
|
)`, [
|
|
7394
|
-
|
|
7395
|
-
|
|
7445
|
+
key,
|
|
7446
|
+
key,
|
|
7396
7447
|
SECRET_HISTORY_CAP
|
|
7397
7448
|
]);
|
|
7398
7449
|
}
|
|
7399
7450
|
async get(name) {
|
|
7400
7451
|
const db = await this.dbId();
|
|
7401
7452
|
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]);
|
|
7453
|
+
FROM secrets WHERE name = ?`, [this.key(name)]);
|
|
7403
7454
|
if (rows.length === 0) return void 0;
|
|
7404
|
-
return rowToVaultSecret(rows[0]);
|
|
7455
|
+
return rowToVaultSecret(rows[0], this.env);
|
|
7405
7456
|
}
|
|
7406
7457
|
async list() {
|
|
7407
7458
|
const db = await this.dbId();
|
|
7408
7459
|
const { rows } = await this.api.d1Query(db, `SELECT name, value_hash, updated_at, updated_by
|
|
7409
|
-
FROM secrets ORDER BY name
|
|
7460
|
+
FROM secrets WHERE name LIKE ? ORDER BY name`, [`${this.env}:%`]);
|
|
7410
7461
|
return rows.map((row) => ({
|
|
7411
|
-
name: String(row.name),
|
|
7462
|
+
name: this.unkey(String(row.name)),
|
|
7412
7463
|
valueHash: row.value_hash,
|
|
7413
7464
|
updatedAt: String(row.updated_at),
|
|
7414
7465
|
updatedBy: row.updated_by != null ? String(row.updated_by) : void 0
|
|
@@ -7416,7 +7467,7 @@ var SecretsVault = class {
|
|
|
7416
7467
|
}
|
|
7417
7468
|
async delete(name) {
|
|
7418
7469
|
const db = await this.dbId();
|
|
7419
|
-
const { rows } = await this.api.d1Query(db, `DELETE FROM secrets WHERE name = ? RETURNING name`, [name]);
|
|
7470
|
+
const { rows } = await this.api.d1Query(db, `DELETE FROM secrets WHERE name = ? RETURNING name`, [this.key(name)]);
|
|
7420
7471
|
return rows.length > 0;
|
|
7421
7472
|
}
|
|
7422
7473
|
/** Append an audit row (e.g. after `secrets get`) without changing the secret. */
|
|
@@ -7426,9 +7477,10 @@ var SecretsVault = class {
|
|
|
7426
7477
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7427
7478
|
const updatedBy = options?.updatedBy;
|
|
7428
7479
|
const db = await this.dbId();
|
|
7480
|
+
const key = this.key(name);
|
|
7429
7481
|
await this.api.d1Query(db, `INSERT INTO secret_history (name, value_hash, updated_at, updated_by)
|
|
7430
7482
|
VALUES (?, ?, ?, ?)`, [
|
|
7431
|
-
|
|
7483
|
+
key,
|
|
7432
7484
|
record$1.valueHash,
|
|
7433
7485
|
updatedAt,
|
|
7434
7486
|
updatedBy ?? null
|
|
@@ -7443,8 +7495,8 @@ var SecretsVault = class {
|
|
|
7443
7495
|
LIMIT -1 OFFSET ?
|
|
7444
7496
|
)
|
|
7445
7497
|
)`, [
|
|
7446
|
-
|
|
7447
|
-
|
|
7498
|
+
key,
|
|
7499
|
+
key,
|
|
7448
7500
|
SECRET_HISTORY_CAP
|
|
7449
7501
|
]);
|
|
7450
7502
|
}
|
|
@@ -7453,18 +7505,20 @@ var SecretsVault = class {
|
|
|
7453
7505
|
const { rows } = await this.api.d1Query(db, `SELECT name, value_hash, updated_at, updated_by
|
|
7454
7506
|
FROM secret_history
|
|
7455
7507
|
WHERE name = ?
|
|
7456
|
-
ORDER BY updated_at DESC`, [name]);
|
|
7508
|
+
ORDER BY updated_at DESC`, [this.key(name)]);
|
|
7457
7509
|
return rows.map((row) => ({
|
|
7458
|
-
name: String(row.name),
|
|
7510
|
+
name: this.unkey(String(row.name)),
|
|
7459
7511
|
valueHash: row.value_hash,
|
|
7460
7512
|
updatedAt: String(row.updated_at),
|
|
7461
7513
|
updatedBy: row.updated_by != null ? String(row.updated_by) : void 0
|
|
7462
7514
|
}));
|
|
7463
7515
|
}
|
|
7464
7516
|
};
|
|
7465
|
-
function rowToVaultSecret(row) {
|
|
7517
|
+
function rowToVaultSecret(row, env) {
|
|
7518
|
+
const rawName = String(row.name);
|
|
7519
|
+
const prefix = `${env}:`;
|
|
7466
7520
|
return {
|
|
7467
|
-
name:
|
|
7521
|
+
name: rawName.startsWith(prefix) ? rawName.slice(prefix.length) : rawName,
|
|
7468
7522
|
ciphertext: blobFromRow(row.ciphertext),
|
|
7469
7523
|
iv: blobFromRow(row.iv),
|
|
7470
7524
|
wrappedDek: blobFromRow(row.wrapped_dek),
|
|
@@ -7512,7 +7566,7 @@ async function createSecretsContext(options) {
|
|
|
7512
7566
|
const accountId = config$1.account_id ?? cloudflareAccountIdFromEnv();
|
|
7513
7567
|
if (!accountId) throw new Error("account_id required in config or CLOUDFLARE_ACCOUNT_ID env var");
|
|
7514
7568
|
const api = new CFApiClient(accountId);
|
|
7515
|
-
const vault = new SecretsVault(api, env, await ensureTamerSecretsDatabase(api
|
|
7569
|
+
const vault = new SecretsVault(api, env, await ensureTamerSecretsDatabase(api));
|
|
7516
7570
|
const state = new StateManager(config$1.tenant.id, env, stackNameForConfig(config$1));
|
|
7517
7571
|
await state.hydrate(api);
|
|
7518
7572
|
const masterKey = readMasterKeyFromEnv(env);
|
|
@@ -7593,7 +7647,7 @@ function displayPathFromCwd(absOrRel) {
|
|
|
7593
7647
|
async function createDeploySecretsResources(api, env) {
|
|
7594
7648
|
const resolvedEnv = resolveSecretsEnv(env);
|
|
7595
7649
|
return {
|
|
7596
|
-
vault: new SecretsVault(api, resolvedEnv, await ensureTamerSecretsDatabase(api
|
|
7650
|
+
vault: new SecretsVault(api, resolvedEnv, await ensureTamerSecretsDatabase(api)),
|
|
7597
7651
|
masterKey: readMasterKeyFromEnv(resolvedEnv)
|
|
7598
7652
|
};
|
|
7599
7653
|
}
|
|
@@ -7606,8 +7660,8 @@ async function runSecretsInit(options) {
|
|
|
7606
7660
|
if (!accountId) throw new Error("account_id required in config or CLOUDFLARE_ACCOUNT_ID env var");
|
|
7607
7661
|
const masterKey = generateMasterKey();
|
|
7608
7662
|
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(
|
|
7663
|
+
const uuid$1 = await ensureTamerSecretsDatabase(new CFApiClient(accountId));
|
|
7664
|
+
console.log(`Secrets vault ready: D1 uuid=${uuid$1} name=${tamerSecretsDatabaseName()}`);
|
|
7611
7665
|
console.log("");
|
|
7612
7666
|
console.log(`Generated master key for env "${env}" (store in two durable places — CI + password manager):`);
|
|
7613
7667
|
console.log("");
|
|
@@ -8377,10 +8431,7 @@ const DestroyArgsSchema = BaseArgsSchema.extend({
|
|
|
8377
8431
|
plan: string().optional(),
|
|
8378
8432
|
allow_stale: boolean().optional()
|
|
8379
8433
|
});
|
|
8380
|
-
const BootstrapArgsSchema = object({
|
|
8381
|
-
env: string().min(1, { error: "env is required for bootstrap" }),
|
|
8382
|
-
config: string().optional()
|
|
8383
|
-
});
|
|
8434
|
+
const BootstrapArgsSchema = object({ config: string().optional() });
|
|
8384
8435
|
const DriftArgsSchema = BaseArgsSchema.extend({ json: boolean().optional() });
|
|
8385
8436
|
const PlanArgsSchema = BaseArgsSchema.extend({
|
|
8386
8437
|
json: boolean().optional(),
|
|
@@ -8638,10 +8689,7 @@ function parseImportArgs(argv) {
|
|
|
8638
8689
|
function parseBootstrapArgs(argv) {
|
|
8639
8690
|
const parsed = BootstrapArgsSchema.safeParse(toOpts(parseArgs(argv)));
|
|
8640
8691
|
if (!parsed.success) throw new Error(`Invalid arguments: ${formatZodError(parsed.error)}`);
|
|
8641
|
-
return {
|
|
8642
|
-
env: parsed.data.env,
|
|
8643
|
-
configPath: parsed.data.config
|
|
8644
|
-
};
|
|
8692
|
+
return { configPath: parsed.data.config };
|
|
8645
8693
|
}
|
|
8646
8694
|
|
|
8647
8695
|
//#endregion
|
|
@@ -8654,14 +8702,14 @@ async function main() {
|
|
|
8654
8702
|
try {
|
|
8655
8703
|
switch (command) {
|
|
8656
8704
|
case "bootstrap":
|
|
8657
|
-
await import("./bootstrap-
|
|
8705
|
+
await import("./bootstrap-CsL4IT9Z.mjs").then((m) => m.runBootstrap(parseBootstrapArgs(rest)));
|
|
8658
8706
|
break;
|
|
8659
8707
|
case "sync":
|
|
8660
|
-
await import("./sync-
|
|
8708
|
+
await import("./sync-C5RjLfgk.mjs").then((m) => m.runSync(parseSyncArgs(rest)));
|
|
8661
8709
|
break;
|
|
8662
8710
|
case "apply": {
|
|
8663
8711
|
const a = parseApplyArgs(rest);
|
|
8664
|
-
await import("./apply-
|
|
8712
|
+
await import("./apply-Cz1lxAOp.mjs").then((m) => m.runApply({
|
|
8665
8713
|
env: a.env,
|
|
8666
8714
|
addShard: a.addShard,
|
|
8667
8715
|
configPath: a.configPath,
|
|
@@ -8673,11 +8721,11 @@ async function main() {
|
|
|
8673
8721
|
break;
|
|
8674
8722
|
}
|
|
8675
8723
|
case "dev":
|
|
8676
|
-
await import("./dev-
|
|
8724
|
+
await import("./dev-vGQIP7tD.mjs").then((m) => m.runDev(parseDevArgs(rest)));
|
|
8677
8725
|
break;
|
|
8678
8726
|
case "deploy": {
|
|
8679
8727
|
const d = parseDeployArgs(rest);
|
|
8680
|
-
await import("./deploy-
|
|
8728
|
+
await import("./deploy-D2tQrtN9.mjs").then((m) => m.runDeploy({
|
|
8681
8729
|
worker: d.worker,
|
|
8682
8730
|
env: d.env,
|
|
8683
8731
|
configPath: d.configPath,
|
|
@@ -8686,23 +8734,23 @@ async function main() {
|
|
|
8686
8734
|
break;
|
|
8687
8735
|
}
|
|
8688
8736
|
case "migrate":
|
|
8689
|
-
await import("./migrate-
|
|
8737
|
+
await import("./migrate-DDBMzPtR.mjs").then((m) => m.runMigrate(parseMigrateArgs(rest)));
|
|
8690
8738
|
break;
|
|
8691
8739
|
case "types":
|
|
8692
|
-
await import("./types-
|
|
8740
|
+
await import("./types-CqmFeIBf.mjs").then((m) => m.runTypes(parseTypesArgs(rest)));
|
|
8693
8741
|
break;
|
|
8694
8742
|
case "status":
|
|
8695
|
-
await import("./status-
|
|
8743
|
+
await import("./status-_k3a77Fw.mjs").then((m) => m.runStatus(parseStatusArgs(rest)));
|
|
8696
8744
|
break;
|
|
8697
8745
|
case "events":
|
|
8698
|
-
await import("./events-
|
|
8746
|
+
await import("./events-yk4J3l0M.mjs").then((m) => m.runEvents(parseEventsArgs(rest)));
|
|
8699
8747
|
break;
|
|
8700
8748
|
case "drift":
|
|
8701
|
-
exitStatus = await import("./drift-
|
|
8749
|
+
exitStatus = await import("./drift-C3wIrNyg.mjs").then((m) => m.runDrift(parseDriftArgs(rest)));
|
|
8702
8750
|
break;
|
|
8703
8751
|
case "plan": {
|
|
8704
8752
|
const p = parsePlanArgs(rest);
|
|
8705
|
-
exitStatus = await import("./plan-
|
|
8753
|
+
exitStatus = await import("./plan-Dot2VV7R.mjs").then((m) => m.runPlan({
|
|
8706
8754
|
env: p.env,
|
|
8707
8755
|
configPath: p.configPath,
|
|
8708
8756
|
json: p.json,
|
|
@@ -8714,14 +8762,14 @@ async function main() {
|
|
|
8714
8762
|
break;
|
|
8715
8763
|
}
|
|
8716
8764
|
case "import":
|
|
8717
|
-
await import("./import-
|
|
8765
|
+
await import("./import-CZ6509_t.mjs").then((m) => m.runImport(parseImportArgs(rest)));
|
|
8718
8766
|
break;
|
|
8719
8767
|
case "doctor":
|
|
8720
|
-
exitStatus = await import("./doctor-
|
|
8768
|
+
exitStatus = await import("./doctor-BnsOxqnA.mjs").then((m) => m.runDoctor(parseDoctorArgs(rest)));
|
|
8721
8769
|
break;
|
|
8722
8770
|
case "provision-tenant": {
|
|
8723
8771
|
const p = parseProvisionTenantArgs(rest);
|
|
8724
|
-
await import("./provision-tenant-
|
|
8772
|
+
await import("./provision-tenant-C2EL79oz.mjs").then((m) => m.runProvisionTenant({
|
|
8725
8773
|
env: p.env,
|
|
8726
8774
|
product: p.product,
|
|
8727
8775
|
workspace: p.workspace,
|
|
@@ -8738,7 +8786,7 @@ async function main() {
|
|
|
8738
8786
|
}
|
|
8739
8787
|
case "destroy-tenant": {
|
|
8740
8788
|
const t = parseDestroyTenantArgs(rest);
|
|
8741
|
-
await import("./destroy-tenant-
|
|
8789
|
+
await import("./destroy-tenant-Ugu7Y1EH.mjs").then((m) => m.runDestroyTenant({
|
|
8742
8790
|
env: t.env,
|
|
8743
8791
|
product: t.product,
|
|
8744
8792
|
workspace: t.workspace,
|
|
@@ -8751,7 +8799,7 @@ async function main() {
|
|
|
8751
8799
|
}
|
|
8752
8800
|
case "destroy": {
|
|
8753
8801
|
const d = parseDestroyArgs(rest);
|
|
8754
|
-
await import("./destroy-
|
|
8802
|
+
await import("./destroy-CEv14T0X.mjs").then((m) => m.runDestroy({
|
|
8755
8803
|
env: d.env,
|
|
8756
8804
|
force: d.force,
|
|
8757
8805
|
skipWorkers: d.skipWorkers,
|
|
@@ -8766,12 +8814,12 @@ async function main() {
|
|
|
8766
8814
|
case "wfp": {
|
|
8767
8815
|
const [sub, ...wfpRest] = rest;
|
|
8768
8816
|
if (sub === "put") {
|
|
8769
|
-
const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-
|
|
8817
|
+
const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-D0tDs0J5.mjs");
|
|
8770
8818
|
await runWfpPut(parseWfpPutArgs(wfpRest));
|
|
8771
8819
|
break;
|
|
8772
8820
|
}
|
|
8773
8821
|
if (sub === "delete") {
|
|
8774
|
-
const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-
|
|
8822
|
+
const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-C-1pIY3Z.mjs");
|
|
8775
8823
|
await runWfpDelete(parseWfpDeleteArgs(wfpRest));
|
|
8776
8824
|
break;
|
|
8777
8825
|
}
|
|
@@ -8791,7 +8839,7 @@ tamer — Cloudflare Workers infrastructure manager
|
|
|
8791
8839
|
Usage: tamer <command> [options]
|
|
8792
8840
|
|
|
8793
8841
|
Commands:
|
|
8794
|
-
bootstrap Create
|
|
8842
|
+
bootstrap Create account-scoped Tamer metadata: tamer-state (D1), tamer-artifacts (R2), tamer-secrets (D1). Run once per account.
|
|
8795
8843
|
sync Sync state from Cloudflare API
|
|
8796
8844
|
apply Provision missing resources
|
|
8797
8845
|
dev Start wrangler dev (use --all for every worker)
|
|
@@ -8871,5 +8919,5 @@ Environment variables (same as Wrangler):
|
|
|
8871
8919
|
main();
|
|
8872
8920
|
|
|
8873
8921
|
//#endregion
|
|
8874
|
-
export {
|
|
8922
|
+
export { resolveReferencesInString as A, loadConfig as B, stackNameForConfig as C, resolveDeployedWorkerName as D, mergedWorkerConfigForEnv as E, ensureTamerSecretsDatabase as F, CFApiClient as I, cloudflareAccountIdFromEnv as L, effectiveDispatchNamespaceName as M, isEphemeralEnv as N, resolveWorkerConfig as O, deleteEnvSecretRows as P, cloudflareApiTokenFromEnv as R, ensureTamerStateDatabase as S, mergeWorkerConfigForResourcePick as T, 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, wranglerConfigCliArgs as j, rewriteIntraStackServiceTargets 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, buildIntraStackScriptNameMap as w, deleteEnvStateRows as x, tenantStateKey as y, getWorkers as z };
|
|
8875
8923
|
//# sourceMappingURL=tamer.mjs.map
|