@dragonmastery/tamer 0.40.1 → 0.41.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.
Files changed (99) hide show
  1. package/dist/{apply-CV4_3Jv4.mjs → apply-Mk9usR-U.mjs} +14 -14
  2. package/dist/{apply-CV4_3Jv4.mjs.map → apply-Mk9usR-U.mjs.map} +1 -1
  3. package/dist/{applyTarget-B1YPgkb3.mjs → applyTarget-CJSn9DeJ.mjs} +3 -3
  4. package/dist/{applyTarget-B1YPgkb3.mjs.map → applyTarget-CJSn9DeJ.mjs.map} +1 -1
  5. package/dist/{bootstrap-ilkixdmD.mjs → bootstrap-BCy6B-B6.mjs} +3 -3
  6. package/dist/{bootstrap-ilkixdmD.mjs.map → bootstrap-BCy6B-B6.mjs.map} +1 -1
  7. package/dist/{buildDispatchUploadForm-D_fM8JaL.mjs → buildDispatchUploadForm-XO8AxhXJ.mjs} +2 -6
  8. package/dist/buildDispatchUploadForm-XO8AxhXJ.mjs.map +1 -0
  9. package/dist/{cloudflareSnapshot-BAeNVohz.mjs → cloudflareSnapshot-DqP8v_xG.mjs} +4 -4
  10. package/dist/{cloudflareSnapshot-BAeNVohz.mjs.map → cloudflareSnapshot-DqP8v_xG.mjs.map} +1 -1
  11. package/dist/{deploy-BEaNADU6.mjs → deploy-DbXBHpCG.mjs} +9 -9
  12. package/dist/{deploy-BEaNADU6.mjs.map → deploy-DbXBHpCG.mjs.map} +1 -1
  13. package/dist/{destroy-Krf35oqE.mjs → destroy-CesVkyxf.mjs} +10 -10
  14. package/dist/{destroy-Krf35oqE.mjs.map → destroy-CesVkyxf.mjs.map} +1 -1
  15. package/dist/{destroy-tenant-C95ljuon.mjs → destroy-tenant-DMynv_u-.mjs} +1 -1
  16. package/dist/{destroy-tenant-C95ljuon.mjs.map → destroy-tenant-DMynv_u-.mjs.map} +1 -1
  17. package/dist/{dev-C__1rLos.mjs → dev-sk6JGKe4.mjs} +7 -7
  18. package/dist/{dev-C__1rLos.mjs.map → dev-sk6JGKe4.mjs.map} +1 -1
  19. package/dist/{dns-records.resolve-DwBR_1WI.mjs → dns-records.resolve-SPYGYNHa.mjs} +1 -1
  20. package/dist/{dns-records.resolve-DwBR_1WI.mjs.map → dns-records.resolve-SPYGYNHa.mjs.map} +1 -1
  21. package/dist/{dns-records.resolve-C2T0m4NG.mjs → dns-records.resolve-jECsH6N-.mjs} +1 -1
  22. package/dist/{dns-records.sync-Dfwk76J_.mjs → dns-records.sync-BORRvLky.mjs} +2 -2
  23. package/dist/{dns-records.sync-Dfwk76J_.mjs.map → dns-records.sync-BORRvLky.mjs.map} +1 -1
  24. package/dist/{doctor-BIaLEVFR.mjs → doctor-BgqnscIE.mjs} +1 -1
  25. package/dist/{doctor-BIaLEVFR.mjs.map → doctor-BgqnscIE.mjs.map} +1 -1
  26. package/dist/{drift-CLsSBorO.mjs → drift-C5r1cKxV.mjs} +6 -6
  27. package/dist/{drift-CLsSBorO.mjs.map → drift-C5r1cKxV.mjs.map} +1 -1
  28. package/dist/drift-oOUlh0u8.mjs +8 -0
  29. package/dist/{emit-Dh68dvo5.mjs → emit-C7KXAVP0.mjs} +2 -2
  30. package/dist/{emit-Dh68dvo5.mjs.map → emit-C7KXAVP0.mjs.map} +1 -1
  31. package/dist/{env-gc-0vX5Av4i.mjs → env-gc-DE4EV7j7.mjs} +10 -10
  32. package/dist/{env-gc-0vX5Av4i.mjs.map → env-gc-DE4EV7j7.mjs.map} +1 -1
  33. package/dist/{env-list-DYCprcLb.mjs → env-list-DKseThiA.mjs} +1 -1
  34. package/dist/{env-list-DYCprcLb.mjs.map → env-list-DKseThiA.mjs.map} +1 -1
  35. package/dist/{events-CnWvxyX_.mjs → events-CqbN9sbT.mjs} +1 -1
  36. package/dist/{events-CnWvxyX_.mjs.map → events-CqbN9sbT.mjs.map} +1 -1
  37. package/dist/{generator-DAU5K77L.mjs → generator-CbH3UZ3K.mjs} +2 -2
  38. package/dist/{generator-DAU5K77L.mjs.map → generator-CbH3UZ3K.mjs.map} +1 -1
  39. package/dist/{import-BNbHjR9t.mjs → import-leVD9Ryg.mjs} +5 -5
  40. package/dist/{import-BNbHjR9t.mjs.map → import-leVD9Ryg.mjs.map} +1 -1
  41. package/dist/loader-B5iVsP6t.mjs +3 -0
  42. package/dist/{logpush-job-C_6uzGUC.mjs → logpush-job-Dqlt-wEw.mjs} +2 -2
  43. package/dist/{logpush-job-C_6uzGUC.mjs.map → logpush-job-Dqlt-wEw.mjs.map} +1 -1
  44. package/dist/{migrate-EVfFlJOM.mjs → migrate-DyrTw9ep.mjs} +5 -5
  45. package/dist/{migrate-EVfFlJOM.mjs.map → migrate-DyrTw9ep.mjs.map} +1 -1
  46. package/dist/{plan-tnUWkiM1.mjs → plan-D7UyLznb.mjs} +11 -11
  47. package/dist/{plan-tnUWkiM1.mjs.map → plan-D7UyLznb.mjs.map} +1 -1
  48. package/dist/{planFormat-DpA8XhzX.mjs → planFormat-CJw8Kq2s.mjs} +1 -1
  49. package/dist/{planFormat-DpA8XhzX.mjs.map → planFormat-CJw8Kq2s.mjs.map} +1 -1
  50. package/dist/{provision-tenant-R6Xa3IUJ.mjs → provision-tenant-z4DLxYAM.mjs} +20 -20
  51. package/dist/{provision-tenant-R6Xa3IUJ.mjs.map → provision-tenant-z4DLxYAM.mjs.map} +1 -1
  52. package/dist/{r2S3EmptyBucket-CXLmOrYF.mjs → r2S3EmptyBucket-DD81ZWQ7.mjs} +1 -1
  53. package/dist/{r2S3EmptyBucket-CXLmOrYF.mjs.map → r2S3EmptyBucket-DD81ZWQ7.mjs.map} +1 -1
  54. package/dist/{registry-X9dlQxG3.mjs → registry-CTerXUza.mjs} +81 -33
  55. package/dist/registry-CTerXUza.mjs.map +1 -0
  56. package/dist/{resolveTenantBindings-4grVKHIG.mjs → resolveTenantBindings-BypqzcSn.mjs} +18 -11
  57. package/dist/resolveTenantBindings-BypqzcSn.mjs.map +1 -0
  58. package/dist/{stackOutputs-CU2oxjpU.mjs → stackOutputs-BLp-dyzl.mjs} +1 -1
  59. package/dist/{stackOutputs-CU2oxjpU.mjs.map → stackOutputs-BLp-dyzl.mjs.map} +1 -1
  60. package/dist/{status-srUxsBIB.mjs → status-WMG5abrN.mjs} +6 -6
  61. package/dist/{status-srUxsBIB.mjs.map → status-WMG5abrN.mjs.map} +1 -1
  62. package/dist/sync-DSgJGQh1.mjs +7 -0
  63. package/dist/{sync-DfJGkOME.mjs → sync-Dii9n2nJ.mjs} +5 -5
  64. package/dist/{sync-DfJGkOME.mjs.map → sync-Dii9n2nJ.mjs.map} +1 -1
  65. package/dist/tamer.mjs +66 -25
  66. package/dist/tamer.mjs.map +1 -1
  67. package/dist/{tamerArtifactsR2-B9myb-IA.mjs → tamerArtifactsR2-B3X21TGV.mjs} +2 -2
  68. package/dist/{tamerArtifactsR2-B9myb-IA.mjs.map → tamerArtifactsR2-B3X21TGV.mjs.map} +1 -1
  69. package/dist/{tenant-MWIs0esz.mjs → tenant-WNYMWmIe.mjs} +1 -1
  70. package/dist/{tenant-MWIs0esz.mjs.map → tenant-WNYMWmIe.mjs.map} +1 -1
  71. package/dist/{tenant-migrate-BfvYL0HH.mjs → tenant-migrate-DBxTsvJ8.mjs} +15 -17
  72. package/dist/tenant-migrate-DBxTsvJ8.mjs.map +1 -0
  73. package/dist/{types-BPxuutXk.mjs → types-HPpAxgub.mjs} +5 -5
  74. package/dist/{types-BPxuutXk.mjs.map → types-HPpAxgub.mjs.map} +1 -1
  75. package/dist/{verifyPlanFile-CoAOsD3W.mjs → verifyPlanFile-B9VCcFIJ.mjs} +2 -2
  76. package/dist/{verifyPlanFile-CoAOsD3W.mjs.map → verifyPlanFile-B9VCcFIJ.mjs.map} +1 -1
  77. package/dist/{wfp-delete-CwWQFxxj.mjs → wfp-delete-TSVBw9XF.mjs} +1 -1
  78. package/dist/{wfp-delete-CwWQFxxj.mjs.map → wfp-delete-TSVBw9XF.mjs.map} +1 -1
  79. package/dist/{wfp-put-BBitXJep.mjs → wfp-put-5XZ-KC3g.mjs} +2 -2
  80. package/dist/{wfp-put-BBitXJep.mjs.map → wfp-put-5XZ-KC3g.mjs.map} +1 -1
  81. package/dist/{worker-route-CvuUPq1k.mjs → worker-route-BapxsQyX.mjs} +2 -2
  82. package/dist/{worker-route-CvuUPq1k.mjs.map → worker-route-BapxsQyX.mjs.map} +1 -1
  83. package/dist/{workers-DSlrKeNL.mjs → workers-D7ow_joN.mjs} +7 -13
  84. package/dist/{workers-DSlrKeNL.mjs.map → workers-D7ow_joN.mjs.map} +1 -1
  85. package/dist/wranglerSpawn-CfPkFLP3.mjs +3 -0
  86. package/dist/{wranglerSpawn-DWdgrsmQ.mjs → wranglerSpawn-VkSL0gZd.mjs} +1 -1
  87. package/dist/{wranglerSpawn-DWdgrsmQ.mjs.map → wranglerSpawn-VkSL0gZd.mjs.map} +1 -1
  88. package/dist/{zoneResolver-VoxLHM4N.mjs → zoneResolver-CamXJpSB.mjs} +1 -1
  89. package/dist/{zoneResolver-VoxLHM4N.mjs.map → zoneResolver-CamXJpSB.mjs.map} +1 -1
  90. package/package.json +5 -2
  91. package/dist/buildDispatchUploadForm-D_fM8JaL.mjs.map +0 -1
  92. package/dist/drift-08k11FV6.mjs +0 -8
  93. package/dist/registry-X9dlQxG3.mjs.map +0 -1
  94. package/dist/resolveTenantBindings-4grVKHIG.mjs.map +0 -1
  95. package/dist/sync-CfNyelDN.mjs +0 -7
  96. package/dist/tenant-migrate-BfvYL0HH.mjs.map +0 -1
  97. package/dist/wranglerSpawn-aARBLHpA.mjs +0 -3
  98. /package/dist/{secrets-2Hy5LMHs.mjs → secrets-DJ1yUy01.mjs} +0 -0
  99. /package/dist/{wranglerOutFile-f08VsoAj.mjs → wranglerOutFile-DDFKeKwO.mjs} +0 -0
@@ -5,12 +5,13 @@ import { j as resolveReferencesInString } from "./tamer.mjs";
5
5
  /**
6
6
  * Resolve D1 bindings for the tenant dispatch script.
7
7
  * Matches shard roles to `tenant.shardBindings` and produces
8
- * `{ name: binding, id: cfId }` entries for the multipart metadata.
8
+ * unified `bindings[]` entries: `{ type: "d1", name: binding, id: cfId }`.
9
9
  */
10
10
  function resolveTenantD1Bindings(config, shards, naming) {
11
11
  const shardBindings = config.tenant.shardBindings ?? {};
12
12
  return shards.map((shard) => {
13
13
  return {
14
+ type: "d1",
14
15
  name: shardBindings[shard.role]?.binding ?? `DB_${shard.role.toUpperCase().replace(/-/g, "_")}`,
15
16
  id: shard.cfId
16
17
  };
@@ -19,11 +20,11 @@ function resolveTenantD1Bindings(config, shards, naming) {
19
20
  /**
20
21
  * Resolve all dispatch script bindings (D1 + vars + services).
21
22
  * References in vars/services are resolved against state.
23
+ * Uses the unified Cloudflare bindings format.
22
24
  */
23
25
  function resolveTenantBindings(config, shards, naming, state, env, accountId) {
24
- const bindings = {};
25
- const d1Bindings = resolveTenantD1Bindings(config, shards, naming);
26
- if (d1Bindings.length > 0) bindings.d1_databases = d1Bindings;
26
+ const bindings = [];
27
+ bindings.push(...resolveTenantD1Bindings(config, shards, naming));
27
28
  if (config.tenant.dispatchVars) {
28
29
  const refCtx = {
29
30
  config,
@@ -32,9 +33,14 @@ function resolveTenantBindings(config, shards, naming, state, env, accountId) {
32
33
  naming,
33
34
  accountId
34
35
  };
35
- const vars = {};
36
- for (const [key, value] of Object.entries(config.tenant.dispatchVars)) vars[key] = resolveReferencesInString(materializeTamerResolvable(value), refCtx, `tenant.dispatchVars.${key}`);
37
- if (Object.keys(vars).length > 0) bindings.vars = vars;
36
+ for (const [key, value] of Object.entries(config.tenant.dispatchVars)) {
37
+ const text = resolveReferencesInString(materializeTamerResolvable(value), refCtx, `tenant.dispatchVars.${key}`);
38
+ bindings.push({
39
+ type: "plain_text",
40
+ name: key,
41
+ text
42
+ });
43
+ }
38
44
  }
39
45
  if (config.tenant.dispatchServices?.length) {
40
46
  const refCtx = {
@@ -44,15 +50,16 @@ function resolveTenantBindings(config, shards, naming, state, env, accountId) {
44
50
  naming,
45
51
  accountId
46
52
  };
47
- bindings.services = config.tenant.dispatchServices.map((s) => ({
53
+ for (const s of config.tenant.dispatchServices) bindings.push({
54
+ type: "service",
48
55
  name: s.name,
49
56
  service: resolveReferencesInString(materializeTamerResolvable(s.service), refCtx, `tenant.dispatchServices.${s.name}.service`),
50
57
  ...s.environment ? { environment: s.environment } : {}
51
- }));
58
+ });
52
59
  }
53
- return bindings;
60
+ return bindings.length > 0 ? { bindings } : {};
54
61
  }
55
62
 
56
63
  //#endregion
57
64
  export { resolveTenantBindings, resolveTenantD1Bindings };
58
- //# sourceMappingURL=resolveTenantBindings-4grVKHIG.mjs.map
65
+ //# sourceMappingURL=resolveTenantBindings-BypqzcSn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveTenantBindings-BypqzcSn.mjs","names":["bindings: Array<\n | { type: \"d1\"; name: string; id: string }\n | { type: \"plain_text\"; name: string; text: string }\n | { type: \"service\"; name: string; service: string; environment?: string }\n >","refCtx: ReferenceContext"],"sources":["../src/core/tenant/resolveTenantBindings.ts"],"sourcesContent":["/**\n * Resolve dispatch script bindings for a provisioned tenant.\n *\n * D1 bindings derive from `tenant.shardBindings` matched to the tenant's\n * shard roles. Vars and services come from `tenant.dispatchVars` /\n * `tenant.dispatchServices` (resolved against state for `${tamer:...}`\n * references).\n */\nimport type { CfiConfig, TenantD1ShardRef } from \"../../types.js\";\nimport type { StateManager } from \"../../core/state/StateManager.js\";\nimport type { NamingEngine } from \"../../core/naming/NamingEngine.js\";\nimport type { DispatchScriptBindings } from \"../../core/wfp/buildDispatchUploadForm.js\";\nimport { materializeTamerResolvable } from \"../../dx/normalize.js\";\nimport {\n resolveReferencesInString,\n type ReferenceContext,\n} from \"../../core/references/references.js\";\n\n/**\n * Resolve D1 bindings for the tenant dispatch script.\n * Matches shard roles to `tenant.shardBindings` and produces\n * unified `bindings[]` entries: `{ type: \"d1\", name: binding, id: cfId }`.\n */\nexport function resolveTenantD1Bindings(\n config: CfiConfig,\n shards: TenantD1ShardRef[],\n naming: NamingEngine,\n): Array<{ type: \"d1\"; name: string; id: string }> {\n const shardBindings = config.tenant.shardBindings ?? {};\n return shards.map((shard) => {\n const info = shardBindings[shard.role];\n const binding = info?.binding ?? `DB_${shard.role.toUpperCase().replace(/-/g, \"_\")}`;\n return { type: \"d1\", name: binding, id: shard.cfId };\n });\n}\n\n/**\n * Resolve all dispatch script bindings (D1 + vars + services).\n * References in vars/services are resolved against state.\n * Uses the unified Cloudflare bindings format.\n */\nexport function resolveTenantBindings(\n config: CfiConfig,\n shards: TenantD1ShardRef[],\n naming: NamingEngine,\n state: StateManager,\n env: string,\n accountId: string,\n): DispatchScriptBindings {\n const bindings: Array<\n | { type: \"d1\"; name: string; id: string }\n | { type: \"plain_text\"; name: string; text: string }\n | { type: \"service\"; name: string; service: string; environment?: string }\n > = [];\n\n // D1 bindings from shard roles\n bindings.push(...resolveTenantD1Bindings(config, shards, naming));\n\n // Vars from config.tenant.dispatchVars\n if (config.tenant.dispatchVars) {\n const refCtx: ReferenceContext = {\n config,\n env,\n state,\n naming,\n accountId,\n };\n for (const [key, value] of Object.entries(config.tenant.dispatchVars)) {\n const text = resolveReferencesInString(\n materializeTamerResolvable(value),\n refCtx,\n `tenant.dispatchVars.${key}`,\n );\n bindings.push({ type: \"plain_text\", name: key, text });\n }\n }\n\n // Service bindings from config.tenant.dispatchServices\n if (config.tenant.dispatchServices?.length) {\n const refCtx: ReferenceContext = {\n config,\n env,\n state,\n naming,\n accountId,\n };\n for (const s of config.tenant.dispatchServices) {\n bindings.push({\n type: \"service\",\n name: s.name,\n service: resolveReferencesInString(\n materializeTamerResolvable(s.service),\n refCtx,\n `tenant.dispatchServices.${s.name}.service`,\n ),\n ...(s.environment ? { environment: s.environment } : {}),\n });\n }\n }\n\n return bindings.length > 0 ? { bindings } : {};\n}\n"],"mappings":";;;;;;;;;AAuBA,SAAgB,wBACd,QACA,QACA,QACiD;CACjD,MAAM,gBAAgB,OAAO,OAAO,iBAAiB,EAAE;AACvD,QAAO,OAAO,KAAK,UAAU;AAG3B,SAAO;GAAE,MAAM;GAAM,MAFR,cAAc,MAAM,OACX,WAAW,MAAM,MAAM,KAAK,aAAa,CAAC,QAAQ,MAAM,IAAI;GAC9C,IAAI,MAAM;GAAM;GACpD;;;;;;;AAQJ,SAAgB,sBACd,QACA,QACA,QACA,OACA,KACA,WACwB;CACxB,MAAMA,WAIF,EAAE;AAGN,UAAS,KAAK,GAAG,wBAAwB,QAAQ,QAAQ,OAAO,CAAC;AAGjE,KAAI,OAAO,OAAO,cAAc;EAC9B,MAAMC,SAA2B;GAC/B;GACA;GACA;GACA;GACA;GACD;AACD,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,OAAO,aAAa,EAAE;GACrE,MAAM,OAAO,0BACX,2BAA2B,MAAM,EACjC,QACA,uBAAuB,MACxB;AACD,YAAS,KAAK;IAAE,MAAM;IAAc,MAAM;IAAK;IAAM,CAAC;;;AAK1D,KAAI,OAAO,OAAO,kBAAkB,QAAQ;EAC1C,MAAMA,SAA2B;GAC/B;GACA;GACA;GACA;GACA;GACD;AACD,OAAK,MAAM,KAAK,OAAO,OAAO,iBAC5B,UAAS,KAAK;GACZ,MAAM;GACN,MAAM,EAAE;GACR,SAAS,0BACP,2BAA2B,EAAE,QAAQ,EACrC,QACA,2BAA2B,EAAE,KAAK,UACnC;GACD,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,GAAG,EAAE;GACxD,CAAC;;AAIN,QAAO,SAAS,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE"}
@@ -66,4 +66,4 @@ function buildOutputsView(config, state) {
66
66
 
67
67
  //#endregion
68
68
  export { resolveStackOutputs as n, buildOutputsView as t };
69
- //# sourceMappingURL=stackOutputs-CU2oxjpU.mjs.map
69
+ //# sourceMappingURL=stackOutputs-BLp-dyzl.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"stackOutputs-CU2oxjpU.mjs","names":["out: Record<string, CfiStackOutputValue>","rows: StackOutputRow[]","status: StackOutputRow[\"status\"]"],"sources":["../src/core/outputs/stackOutputs.ts"],"sourcesContent":["/**\n * Tamer's CloudFormation `Outputs` analogue.\n *\n * `tamer.config.ts > outputs` declares named exports as Tamer reference\n * strings (e.g. `\"${tamer:d1:users.id}\"`). After a successful `apply` the\n * engine resolves every entry against the just-completed state and persists\n * the literal under {@link CfiState.stackOutputs}. Sibling stacks consume\n * them via `${tamer:import:<stackName>.<outputName>}` (added separately).\n *\n * Resolution is **strict**: any unresolved/unknown reference fails the\n * apply (and rolls back when `--rollback-on-failure` is set). Read-only\n * commands like `status` use {@link buildOutputsView} which is tolerant\n * and shows the placeholder verbatim alongside the persisted value.\n */\nimport type {\n CfiConfig,\n CfiStackOutputValue,\n} from \"../../types.js\";\nimport { materializeTamerResolvable } from \"../../dx/normalize.js\";\nimport type { NamingEngine } from \"../naming/NamingEngine.js\";\nimport type { StateManager } from \"../state/StateManager.js\";\nimport {\n resolveReferencesInString,\n TamerReferenceError,\n} from \"../references/references.js\";\n\n/**\n * Resolve every `outputs:` entry against the current state. Throws\n * {@link TamerReferenceError} on the first unresolved reference so a failed\n * apply can roll back instead of silently persisting half-resolved values.\n *\n * Pass an explicit `now` only from tests — production code should let it\n * default to wall-clock so `resolvedAt` reflects the real persist time.\n */\nexport function resolveStackOutputs(\n config: CfiConfig,\n ctx: {\n env: string;\n state: StateManager;\n naming: NamingEngine;\n /**\n * Outputs from sibling stacks pre-fetched by `fetchStackImports`.\n * An output may chain through an import (e.g.\n * `outputs: { region: \"${tamer:import:net.region}\" }`) — strict\n * resolution requires the sibling row to be hydrated already.\n */\n imports?: Record<string, Record<string, string>>;\n /** Same as wrangler / apply `accountId` (for `${tamer:config:stack.account_id}` in outputs). */\n accountId?: string;\n },\n now: () => string = () => new Date().toISOString(),\n): Record<string, CfiStackOutputValue> {\n const outputs = config.outputs;\n if (!outputs || Object.keys(outputs).length === 0) return {};\n const refCtx = {\n config,\n env: ctx.env,\n state: ctx.state,\n naming: ctx.naming,\n tolerant: false,\n imports: ctx.imports,\n accountId: ctx.accountId,\n };\n const resolvedAt = now();\n const out: Record<string, CfiStackOutputValue> = {};\n for (const [name, source] of Object.entries(outputs)) {\n const sourceStr = materializeTamerResolvable(source);\n const value = resolveReferencesInString(\n sourceStr,\n refCtx,\n `outputs.${name}`,\n );\n out[name] = { value, source: sourceStr, resolvedAt };\n }\n return out;\n}\n\n/**\n * One row in the `tamer status` outputs panel. Combines the *declared*\n * source (from `tamer.config.ts`) with the *persisted* value (from state)\n * so operators can see drift between \"what the config says\" and \"what we\n * last resolved\". `value` is `null` when the output is declared but has\n * never been resolved (no `apply` yet), or when a stale persisted entry\n * exists for an output that has since been removed from config.\n */\nexport interface StackOutputRow {\n name: string;\n /** Live source from `tamer.config.ts > outputs[name]`, if still declared. */\n declaredSource: string | undefined;\n /** Persisted resolved literal, if `apply` has run for this output. */\n value: string | null;\n /** Source string at last persist (drifts vs. `declaredSource` after edits). */\n persistedSource: string | undefined;\n /** ISO timestamp of last persist (undefined when never resolved). */\n resolvedAt: string | undefined;\n /**\n * `\"resolved\"` when persisted matches declared source, `\"stale\"` when\n * source has drifted since persist (re-run apply), `\"orphan\"` when\n * persisted but no longer declared, `\"pending\"` when declared but never\n * resolved.\n */\n status: \"resolved\" | \"stale\" | \"orphan\" | \"pending\";\n}\n\n/**\n * Tolerant union of declared + persisted outputs for `tamer status` and the\n * machine-readable `--json` envelope. Never throws.\n */\nexport function buildOutputsView(\n config: CfiConfig,\n state: StateManager,\n): StackOutputRow[] {\n const declared = config.outputs ?? {};\n const persisted = state.getStackOutputs();\n const names = new Set<string>([\n ...Object.keys(declared),\n ...Object.keys(persisted),\n ]);\n const rows: StackOutputRow[] = [];\n for (const name of [...names].sort()) {\n const rawDeclared = declared[name];\n const declaredSource =\n rawDeclared !== undefined ? materializeTamerResolvable(rawDeclared) : undefined;\n const p = persisted[name];\n let status: StackOutputRow[\"status\"];\n if (declaredSource && !p) status = \"pending\";\n else if (!declaredSource && p) status = \"orphan\";\n else if (declaredSource && p && declaredSource !== p.source) status = \"stale\";\n else status = \"resolved\";\n rows.push({\n name,\n declaredSource,\n value: p?.value ?? null,\n persistedSource: p?.source,\n resolvedAt: p?.resolvedAt,\n status,\n });\n }\n return rows;\n}\n\nexport { TamerReferenceError };\n"],"mappings":";;;;;;;;;;;;AAkCA,SAAgB,oBACd,QACA,KAcA,6BAA0B,IAAI,MAAM,EAAC,aAAa,EACb;CACrC,MAAM,UAAU,OAAO;AACvB,KAAI,CAAC,WAAW,OAAO,KAAK,QAAQ,CAAC,WAAW,EAAG,QAAO,EAAE;CAC5D,MAAM,SAAS;EACb;EACA,KAAK,IAAI;EACT,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,UAAU;EACV,SAAS,IAAI;EACb,WAAW,IAAI;EAChB;CACD,MAAM,aAAa,KAAK;CACxB,MAAMA,MAA2C,EAAE;AACnD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,YAAY,2BAA2B,OAAO;AAMpD,MAAI,QAAQ;GAAE,OALA,0BACZ,WACA,QACA,WAAW,OACZ;GACoB,QAAQ;GAAW;GAAY;;AAEtD,QAAO;;;;;;AAkCT,SAAgB,iBACd,QACA,OACkB;CAClB,MAAM,WAAW,OAAO,WAAW,EAAE;CACrC,MAAM,YAAY,MAAM,iBAAiB;CACzC,MAAM,QAAQ,IAAI,IAAY,CAC5B,GAAG,OAAO,KAAK,SAAS,EACxB,GAAG,OAAO,KAAK,UAAU,CAC1B,CAAC;CACF,MAAMC,OAAyB,EAAE;AACjC,MAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE;EACpC,MAAM,cAAc,SAAS;EAC7B,MAAM,iBACJ,gBAAgB,SAAY,2BAA2B,YAAY,GAAG;EACxE,MAAM,IAAI,UAAU;EACpB,IAAIC;AACJ,MAAI,kBAAkB,CAAC,EAAG,UAAS;WAC1B,CAAC,kBAAkB,EAAG,UAAS;WAC/B,kBAAkB,KAAK,mBAAmB,EAAE,OAAQ,UAAS;MACjE,UAAS;AACd,OAAK,KAAK;GACR;GACA;GACA,OAAO,GAAG,SAAS;GACnB,iBAAiB,GAAG;GACpB,YAAY,GAAG;GACf;GACD,CAAC;;AAEJ,QAAO"}
1
+ {"version":3,"file":"stackOutputs-BLp-dyzl.mjs","names":["out: Record<string, CfiStackOutputValue>","rows: StackOutputRow[]","status: StackOutputRow[\"status\"]"],"sources":["../src/core/outputs/stackOutputs.ts"],"sourcesContent":["/**\n * Tamer's CloudFormation `Outputs` analogue.\n *\n * `tamer.config.ts > outputs` declares named exports as Tamer reference\n * strings (e.g. `\"${tamer:d1:users.id}\"`). After a successful `apply` the\n * engine resolves every entry against the just-completed state and persists\n * the literal under {@link CfiState.stackOutputs}. Sibling stacks consume\n * them via `${tamer:import:<stackName>.<outputName>}` (added separately).\n *\n * Resolution is **strict**: any unresolved/unknown reference fails the\n * apply (and rolls back when `--rollback-on-failure` is set). Read-only\n * commands like `status` use {@link buildOutputsView} which is tolerant\n * and shows the placeholder verbatim alongside the persisted value.\n */\nimport type {\n CfiConfig,\n CfiStackOutputValue,\n} from \"../../types.js\";\nimport { materializeTamerResolvable } from \"../../dx/normalize.js\";\nimport type { NamingEngine } from \"../naming/NamingEngine.js\";\nimport type { StateManager } from \"../state/StateManager.js\";\nimport {\n resolveReferencesInString,\n TamerReferenceError,\n} from \"../references/references.js\";\n\n/**\n * Resolve every `outputs:` entry against the current state. Throws\n * {@link TamerReferenceError} on the first unresolved reference so a failed\n * apply can roll back instead of silently persisting half-resolved values.\n *\n * Pass an explicit `now` only from tests — production code should let it\n * default to wall-clock so `resolvedAt` reflects the real persist time.\n */\nexport function resolveStackOutputs(\n config: CfiConfig,\n ctx: {\n env: string;\n state: StateManager;\n naming: NamingEngine;\n /**\n * Outputs from sibling stacks pre-fetched by `fetchStackImports`.\n * An output may chain through an import (e.g.\n * `outputs: { region: \"${tamer:import:net.region}\" }`) — strict\n * resolution requires the sibling row to be hydrated already.\n */\n imports?: Record<string, Record<string, string>>;\n /** Same as wrangler / apply `accountId` (for `${tamer:config:stack.account_id}` in outputs). */\n accountId?: string;\n },\n now: () => string = () => new Date().toISOString(),\n): Record<string, CfiStackOutputValue> {\n const outputs = config.outputs;\n if (!outputs || Object.keys(outputs).length === 0) return {};\n const refCtx = {\n config,\n env: ctx.env,\n state: ctx.state,\n naming: ctx.naming,\n tolerant: false,\n imports: ctx.imports,\n accountId: ctx.accountId,\n };\n const resolvedAt = now();\n const out: Record<string, CfiStackOutputValue> = {};\n for (const [name, source] of Object.entries(outputs)) {\n const sourceStr = materializeTamerResolvable(source);\n const value = resolveReferencesInString(\n sourceStr,\n refCtx,\n `outputs.${name}`,\n );\n out[name] = { value, source: sourceStr, resolvedAt };\n }\n return out;\n}\n\n/**\n * One row in the `tamer status` outputs panel. Combines the *declared*\n * source (from `tamer.config.ts`) with the *persisted* value (from state)\n * so operators can see drift between \"what the config says\" and \"what we\n * last resolved\". `value` is `null` when the output is declared but has\n * never been resolved (no `apply` yet), or when a stale persisted entry\n * exists for an output that has since been removed from config.\n */\nexport interface StackOutputRow {\n name: string;\n /** Live source from `tamer.config.ts > outputs[name]`, if still declared. */\n declaredSource: string | undefined;\n /** Persisted resolved literal, if `apply` has run for this output. */\n value: string | null;\n /** Source string at last persist (drifts vs. `declaredSource` after edits). */\n persistedSource: string | undefined;\n /** ISO timestamp of last persist (undefined when never resolved). */\n resolvedAt: string | undefined;\n /**\n * `\"resolved\"` when persisted matches declared source, `\"stale\"` when\n * source has drifted since persist (re-run apply), `\"orphan\"` when\n * persisted but no longer declared, `\"pending\"` when declared but never\n * resolved.\n */\n status: \"resolved\" | \"stale\" | \"orphan\" | \"pending\";\n}\n\n/**\n * Tolerant union of declared + persisted outputs for `tamer status` and the\n * machine-readable `--json` envelope. Never throws.\n */\nexport function buildOutputsView(\n config: CfiConfig,\n state: StateManager,\n): StackOutputRow[] {\n const declared = config.outputs ?? {};\n const persisted = state.getStackOutputs();\n const names = new Set<string>([\n ...Object.keys(declared),\n ...Object.keys(persisted),\n ]);\n const rows: StackOutputRow[] = [];\n for (const name of [...names].sort()) {\n const rawDeclared = declared[name];\n const declaredSource =\n rawDeclared !== undefined ? materializeTamerResolvable(rawDeclared) : undefined;\n const p = persisted[name];\n let status: StackOutputRow[\"status\"];\n if (declaredSource && !p) status = \"pending\";\n else if (!declaredSource && p) status = \"orphan\";\n else if (declaredSource && p && declaredSource !== p.source) status = \"stale\";\n else status = \"resolved\";\n rows.push({\n name,\n declaredSource,\n value: p?.value ?? null,\n persistedSource: p?.source,\n resolvedAt: p?.resolvedAt,\n status,\n });\n }\n return rows;\n}\n\nexport { TamerReferenceError };\n"],"mappings":";;;;;;;;;;;;AAkCA,SAAgB,oBACd,QACA,KAcA,6BAA0B,IAAI,MAAM,EAAC,aAAa,EACb;CACrC,MAAM,UAAU,OAAO;AACvB,KAAI,CAAC,WAAW,OAAO,KAAK,QAAQ,CAAC,WAAW,EAAG,QAAO,EAAE;CAC5D,MAAM,SAAS;EACb;EACA,KAAK,IAAI;EACT,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,UAAU;EACV,SAAS,IAAI;EACb,WAAW,IAAI;EAChB;CACD,MAAM,aAAa,KAAK;CACxB,MAAMA,MAA2C,EAAE;AACnD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,YAAY,2BAA2B,OAAO;AAMpD,MAAI,QAAQ;GAAE,OALA,0BACZ,WACA,QACA,WAAW,OACZ;GACoB,QAAQ;GAAW;GAAY;;AAEtD,QAAO;;;;;;AAkCT,SAAgB,iBACd,QACA,OACkB;CAClB,MAAM,WAAW,OAAO,WAAW,EAAE;CACrC,MAAM,YAAY,MAAM,iBAAiB;CACzC,MAAM,QAAQ,IAAI,IAAY,CAC5B,GAAG,OAAO,KAAK,SAAS,EACxB,GAAG,OAAO,KAAK,UAAU,CAC1B,CAAC;CACF,MAAMC,OAAyB,EAAE;AACjC,MAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE;EACpC,MAAM,cAAc,SAAS;EAC7B,MAAM,iBACJ,gBAAgB,SAAY,2BAA2B,YAAY,GAAG;EACxE,MAAM,IAAI,UAAU;EACpB,IAAIC;AACJ,MAAI,kBAAkB,CAAC,EAAG,UAAS;WAC1B,CAAC,kBAAkB,EAAG,UAAS;WAC/B,kBAAkB,KAAK,mBAAmB,EAAE,OAAQ,UAAS;MACjE,UAAS;AACd,OAAK,KAAK;GACR;GACA;GACA,OAAO,GAAG,SAAS;GACnB,iBAAiB,GAAG;GACpB,YAAY,GAAG;GACf;GACD,CAAC;;AAEJ,QAAO"}
@@ -1,10 +1,10 @@
1
1
  import { f as getDispatchNamespaces, m as getLogpushJobs, p as getDnsRecords } from "./normalize-DVSTRZhO.mjs";
2
2
  import { E as mergeWorkerConfigForResourcePick, H as getWorkers, O as resolveDeployedWorkerName, P as effectiveDispatchNamespaceName, R as CFApiClient, U as loadConfig, V as getConfigBaseDir, f as fetchStackImports, h as StateManager, m as scanConfigForImports, u as namingFromConfig, w as stackNameForConfig, y as tenantStateKey, z as cloudflareAccountIdFromEnv } from "./tamer.mjs";
3
- import { n as resourceModules } from "./registry-X9dlQxG3.mjs";
4
- import "./r2S3EmptyBucket-CXLmOrYF.mjs";
5
- import { r as dnsRecordStateKey, t as dnsRecordAppliesToEnv } from "./dns-records.resolve-DwBR_1WI.mjs";
6
- import { t as logpushJobStatus } from "./logpush-job-C_6uzGUC.mjs";
7
- import { t as buildOutputsView } from "./stackOutputs-CU2oxjpU.mjs";
3
+ import { n as resourceModules } from "./registry-CTerXUza.mjs";
4
+ import "./r2S3EmptyBucket-DD81ZWQ7.mjs";
5
+ import { r as dnsRecordStateKey, t as dnsRecordAppliesToEnv } from "./dns-records.resolve-SPYGYNHa.mjs";
6
+ import { t as logpushJobStatus } from "./logpush-job-Dqlt-wEw.mjs";
7
+ import { t as buildOutputsView } from "./stackOutputs-BLp-dyzl.mjs";
8
8
 
9
9
  //#region src/features/dispatch-namespace/dispatch-namespace.status.ts
10
10
  function dispatchNamespaceStatus(resources, env, state, _naming, config) {
@@ -203,4 +203,4 @@ async function runStatus(options) {
203
203
 
204
204
  //#endregion
205
205
  export { runStatus };
206
- //# sourceMappingURL=status-srUxsBIB.mjs.map
206
+ //# sourceMappingURL=status-WMG5abrN.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-srUxsBIB.mjs","names":["results: Array<{\n logicalName: string;\n namespace: string;\n status: ResourceStatus;\n }>","rows: DnsRecordStatusRow[]","meta: string[]","siblingImports: Record<string, Record<string, string>>","logpushLive:\n | Awaited<ReturnType<CFApiClient[\"logpushAccountJobsList\"]>>\n | undefined","hints: string[]"],"sources":["../src/features/dispatch-namespace/dispatch-namespace.status.ts","../src/features/dns-records/dns-records.status.ts","../src/cli/commands/status.ts"],"sourcesContent":["import type { DispatchNamespaceResourceConfig, CfiConfig } from \"../../types.js\";\nimport type { StateManager } from \"../../core/state/StateManager.js\";\nimport type { NamingEngine } from \"../../core/naming/NamingEngine.js\";\nimport type { ResourceStatus } from \"../../types.js\";\nimport { effectiveDispatchNamespaceName } from \"./dispatch-namespace.resolve.js\";\n\nexport function dispatchNamespaceStatus(\n resources: DispatchNamespaceResourceConfig[],\n env: string,\n state: StateManager,\n _naming: NamingEngine,\n config: CfiConfig,\n): Array<{ logicalName: string; namespace: string; status: ResourceStatus }> {\n const results: Array<{\n logicalName: string;\n namespace: string;\n status: ResourceStatus;\n }> = [];\n\n for (const nsConfig of resources) {\n const resolvedName = effectiveDispatchNamespaceName(nsConfig, env, config.tenant);\n const key = `dispatch_ns:${resolvedName}`;\n const entry = state.get(key);\n results.push({\n logicalName: nsConfig.logicalName,\n namespace: resolvedName,\n status:\n entry?.type === \"dispatch_namespace\" ? \"ok\" : \"missing\",\n });\n }\n\n return results;\n}\n","import type { DnsRecordResourceConfig, ResourceStatus } from \"../../types.js\";\nimport type { StateManager } from \"../../core/state/StateManager.js\";\nimport {\n dnsRecordAppliesToEnv,\n dnsRecordStateKey,\n} from \"./dns-records.resolve.js\";\n\nexport interface DnsRecordStatusRow {\n logicalName: string;\n type: string;\n name: string;\n recordId?: string;\n status: ResourceStatus;\n}\n\nexport function dnsRecordStatus(\n resources: DnsRecordResourceConfig[],\n env: string,\n state: StateManager,\n): DnsRecordStatusRow[] {\n const rows: DnsRecordStatusRow[] = [];\n for (const config of resources) {\n if (!dnsRecordAppliesToEnv(config, env)) {\n rows.push({\n logicalName: config.logicalName,\n type: config.type,\n name: config.name,\n status: \"ok\",\n });\n continue;\n }\n const entry = state.get(\n dnsRecordStateKey(config.zoneId, config.type, config.name),\n );\n if (entry?.type === \"dns_record\") {\n rows.push({\n logicalName: config.logicalName,\n type: entry.recordType,\n name: entry.name,\n recordId: entry.recordId,\n status: \"ok\",\n });\n } else {\n rows.push({\n logicalName: config.logicalName,\n type: config.type,\n name: config.name,\n status: \"missing\",\n });\n }\n }\n return rows;\n}\n","import { loadConfig, getWorkers, getConfigBaseDir } from \"../../core/config/loader.js\";\nimport { cloudflareAccountIdFromEnv } from \"../../core/cloudflareEnv.js\";\nimport { namingFromConfig } from \"../../core/config/namingFromConfig.js\";\nimport { StateManager } from \"../../core/state/StateManager.js\";\nimport { stackNameForConfig } from \"../../core/state/stackName.js\";\nimport { CFApiClient } from \"../../core/api/CFApiClient.js\";\nimport { dispatchNamespaceStatus } from \"../../features/dispatch-namespace/index.js\";\nimport { dnsRecordStatus } from \"../../features/dns-records/index.js\";\nimport { getDispatchNamespaces, getDnsRecords, getLogpushJobs } from \"../../types.js\";\nimport { logpushJobStatus } from \"../../features/logpush-job/index.js\";\nimport { tenantStateKey } from \"../../core/tenant/tenantKeys.js\";\nimport { resourceModules } from \"../../core/registry/registry.js\";\nimport {\n resolveDeployedWorkerName,\n mergeWorkerConfigForResourcePick,\n} from \"../../core/config/resolver.js\";\nimport { buildOutputsView } from \"../../core/outputs/stackOutputs.js\";\nimport {\n fetchStackImports,\n scanConfigForImports,\n} from \"../../core/imports/fetchStackImports.js\";\n\nexport async function runStatus(options: {\n env?: string;\n configPath?: string;\n /** `product:workspace` — show only this workspace tenant from state. */\n tenant?: string;\n}): Promise<void> {\n const env = options.env ?? \"local\";\n const configPath = options.configPath;\n\n const config = await loadConfig(configPath, { env });\n const baseDir = getConfigBaseDir();\n const accountId =\n config.account_id ?? cloudflareAccountIdFromEnv();\n if (!accountId) {\n throw new Error(\n \"account_id required in config or CLOUDFLARE_ACCOUNT_ID env var\",\n );\n }\n const naming = namingFromConfig(config);\n const api = new CFApiClient(accountId);\n const state = new StateManager(\n config.tenant.id,\n env,\n stackNameForConfig(config),\n );\n await state.hydrate(api);\n\n const workers = await getWorkers(config, baseDir);\n console.log(\n `\\nStatus for ${config.tenant.name} (${config.tenant.slug}) — env: ${env}\\n`,\n );\n\n if (options.tenant?.trim()) {\n const raw = options.tenant.trim();\n const colon = raw.indexOf(\":\");\n if (colon < 1) {\n throw new Error(\n 'status --tenant expects \"product:workspace\" (e.g. todo:acme)',\n );\n }\n const product = raw.slice(0, colon);\n const workspace = raw.slice(colon + 1);\n const t = state.getTenant(product, workspace);\n console.log(`Workspace tenant ${tenantStateKey(product, workspace)}:`);\n if (!t) {\n console.log(\" (no record in tamer state)\\n\");\n return;\n }\n console.log(` status: ${t.provisioningStatus}`);\n console.log(` dispatch namespace: ${t.dispatchNamespaceName}`);\n console.log(` script: ${t.scriptName}`);\n if (t.d1Shards?.length) {\n console.log(\" D1 shards:\");\n for (const s of t.d1Shards) {\n console.log(` ${s.role}: ${s.derivedName} [${s.cfId}]`);\n }\n }\n console.log();\n return;\n }\n\n const outputRows = buildOutputsView(config, state);\n if (outputRows.length > 0) {\n console.log(\"Stack outputs:\");\n for (const r of outputRows) {\n const valueText =\n r.value === null\n ? \"(unresolved — run apply)\"\n : r.value;\n const meta: string[] = [r.status];\n if (r.status === \"stale\" && r.declaredSource) {\n meta.push(`source drifted → ${r.declaredSource}`);\n }\n console.log(` ${r.name}: ${valueText} [${meta.join(\", \")}]`);\n }\n console.log();\n }\n\n // Inbound imports — show every `${tamer:import:<stack>.<output>}`\n // referenced by config, grouped by source stack. We tolerate fetch\n // failures so `tamer status` still works in offline / partial-cred\n // environments; a missing sibling row just displays \"(unresolved)\".\n const importRefs = scanConfigForImports(config);\n let siblingImports: Record<string, Record<string, string>> = {};\n try {\n siblingImports = await fetchStackImports(api, config, env);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`(could not pre-fetch imported stacks: ${msg})`);\n }\n if (importRefs.length > 0) {\n console.log(\"Stack imports:\");\n const byStack = new Map<string, Set<string>>();\n for (const r of importRefs) {\n if (!byStack.has(r.stack)) byStack.set(r.stack, new Set());\n byStack.get(r.stack)!.add(r.output);\n }\n for (const [stack, outputs] of [...byStack].sort(([a], [b]) =>\n a.localeCompare(b),\n )) {\n console.log(` from stack \"${stack}\":`);\n const stackOutputs = siblingImports[stack] ?? {};\n for (const out of [...outputs].sort()) {\n const v = stackOutputs[out];\n const status = v === undefined ? \"unresolved\" : \"resolved\";\n const value = v ?? \"(missing — run `tamer apply` on that stack)\";\n console.log(` ${out}: ${value} [${status}]`);\n }\n }\n console.log();\n }\n\n const dns = dispatchNamespaceStatus(\n getDispatchNamespaces(config),\n env,\n state,\n naming,\n config,\n );\n if (dns.length > 0) {\n console.log(\"Dispatch namespaces:\");\n for (const r of dns) {\n console.log(` ${r.logicalName} (${r.namespace}) [${r.status}]`);\n }\n console.log();\n }\n\n const tenants = state.listTenants();\n if (tenants.length > 0) {\n console.log(`Tenants (${tenants.length}):`);\n for (const t of tenants.sort((a, b) =>\n `${a.product}:${a.workspace}`.localeCompare(`${b.product}:${b.workspace}`),\n )) {\n const shards = t.d1Shards?.length ?? 0;\n console.log(\n ` ${t.product}:${t.workspace} [${t.provisioningStatus}] ${t.scriptName} (${shards} shard(s))`,\n );\n }\n console.log();\n }\n\n const dnsRows = dnsRecordStatus(getDnsRecords(config), env, state);\n if (dnsRows.length > 0) {\n console.log(\"DNS records:\");\n for (const r of dnsRows) {\n const id = r.recordId ? ` [${r.recordId}]` : \"\";\n console.log(` ${r.logicalName}: ${r.type} ${r.name}${id} [${r.status}]`);\n }\n console.log();\n }\n\n let logpushLive:\n | Awaited<ReturnType<CFApiClient[\"logpushAccountJobsList\"]>>\n | undefined;\n if (env !== \"local\") {\n try {\n logpushLive = await api.logpushAccountJobsList();\n } catch {\n // Token may lack Logpush list; state-only rows still print.\n }\n }\n const logpushRows = logpushJobStatus(\n getLogpushJobs(config),\n config.tenant,\n env,\n state,\n logpushLive,\n );\n if (logpushRows.length > 0) {\n console.log(\"Logpush jobs:\");\n for (const r of logpushRows) {\n const id = r.cfJobId != null ? ` [id ${r.cfJobId}]` : \"\";\n const hints: string[] = [];\n if (r.cfEnabled === false) hints.push(\"disabled on Cloudflare\");\n if (r.cfError) hints.push(`CF error: ${r.cfError}`);\n const hint = hints.length > 0 ? ` — ${hints.join(\"; \")}` : \"\";\n console.log(` ${r.logicalName}: ${r.jobName}${id} [${r.status}]${hint}`);\n }\n console.log();\n }\n\n for (const [workerKey, workerConfig] of workers) {\n console.log(`Worker: ${workerKey}`);\n const deployedName = resolveDeployedWorkerName(\n config,\n workerKey,\n workerConfig,\n env,\n naming,\n );\n const mergedWorker = mergeWorkerConfigForResourcePick(\n config,\n workerKey,\n workerConfig,\n env,\n accountId,\n naming,\n state,\n { referencesMode: \"tolerant\", imports: siblingImports },\n );\n let printedAny = false;\n for (const mod of resourceModules) {\n const resources = mod.pickResources(mergedWorker);\n if (resources.length === 0) continue;\n const rows = mod.status({\n resources,\n env,\n state,\n naming,\n worker: { workerKey, deployedName },\n });\n if (rows.length === 0) continue;\n printedAny = true;\n console.log(` ${mod.label}:`);\n for (const r of rows) {\n console.log(` ${r.binding}: ${r.name} [${r.status}]`);\n }\n }\n if (!printedAny) console.log(\" (no resources)\");\n console.log();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"status-WMG5abrN.mjs","names":["results: Array<{\n logicalName: string;\n namespace: string;\n status: ResourceStatus;\n }>","rows: DnsRecordStatusRow[]","meta: string[]","siblingImports: Record<string, Record<string, string>>","logpushLive:\n | Awaited<ReturnType<CFApiClient[\"logpushAccountJobsList\"]>>\n | undefined","hints: string[]"],"sources":["../src/features/dispatch-namespace/dispatch-namespace.status.ts","../src/features/dns-records/dns-records.status.ts","../src/cli/commands/status.ts"],"sourcesContent":["import type { DispatchNamespaceResourceConfig, CfiConfig } from \"../../types.js\";\nimport type { StateManager } from \"../../core/state/StateManager.js\";\nimport type { NamingEngine } from \"../../core/naming/NamingEngine.js\";\nimport type { ResourceStatus } from \"../../types.js\";\nimport { effectiveDispatchNamespaceName } from \"./dispatch-namespace.resolve.js\";\n\nexport function dispatchNamespaceStatus(\n resources: DispatchNamespaceResourceConfig[],\n env: string,\n state: StateManager,\n _naming: NamingEngine,\n config: CfiConfig,\n): Array<{ logicalName: string; namespace: string; status: ResourceStatus }> {\n const results: Array<{\n logicalName: string;\n namespace: string;\n status: ResourceStatus;\n }> = [];\n\n for (const nsConfig of resources) {\n const resolvedName = effectiveDispatchNamespaceName(nsConfig, env, config.tenant);\n const key = `dispatch_ns:${resolvedName}`;\n const entry = state.get(key);\n results.push({\n logicalName: nsConfig.logicalName,\n namespace: resolvedName,\n status:\n entry?.type === \"dispatch_namespace\" ? \"ok\" : \"missing\",\n });\n }\n\n return results;\n}\n","import type { DnsRecordResourceConfig, ResourceStatus } from \"../../types.js\";\nimport type { StateManager } from \"../../core/state/StateManager.js\";\nimport {\n dnsRecordAppliesToEnv,\n dnsRecordStateKey,\n} from \"./dns-records.resolve.js\";\n\nexport interface DnsRecordStatusRow {\n logicalName: string;\n type: string;\n name: string;\n recordId?: string;\n status: ResourceStatus;\n}\n\nexport function dnsRecordStatus(\n resources: DnsRecordResourceConfig[],\n env: string,\n state: StateManager,\n): DnsRecordStatusRow[] {\n const rows: DnsRecordStatusRow[] = [];\n for (const config of resources) {\n if (!dnsRecordAppliesToEnv(config, env)) {\n rows.push({\n logicalName: config.logicalName,\n type: config.type,\n name: config.name,\n status: \"ok\",\n });\n continue;\n }\n const entry = state.get(\n dnsRecordStateKey(config.zoneId, config.type, config.name),\n );\n if (entry?.type === \"dns_record\") {\n rows.push({\n logicalName: config.logicalName,\n type: entry.recordType,\n name: entry.name,\n recordId: entry.recordId,\n status: \"ok\",\n });\n } else {\n rows.push({\n logicalName: config.logicalName,\n type: config.type,\n name: config.name,\n status: \"missing\",\n });\n }\n }\n return rows;\n}\n","import { loadConfig, getWorkers, getConfigBaseDir } from \"../../core/config/loader.js\";\nimport { cloudflareAccountIdFromEnv } from \"../../core/cloudflareEnv.js\";\nimport { namingFromConfig } from \"../../core/config/namingFromConfig.js\";\nimport { StateManager } from \"../../core/state/StateManager.js\";\nimport { stackNameForConfig } from \"../../core/state/stackName.js\";\nimport { CFApiClient } from \"../../core/api/CFApiClient.js\";\nimport { dispatchNamespaceStatus } from \"../../features/dispatch-namespace/index.js\";\nimport { dnsRecordStatus } from \"../../features/dns-records/index.js\";\nimport { getDispatchNamespaces, getDnsRecords, getLogpushJobs } from \"../../types.js\";\nimport { logpushJobStatus } from \"../../features/logpush-job/index.js\";\nimport { tenantStateKey } from \"../../core/tenant/tenantKeys.js\";\nimport { resourceModules } from \"../../core/registry/registry.js\";\nimport {\n resolveDeployedWorkerName,\n mergeWorkerConfigForResourcePick,\n} from \"../../core/config/resolver.js\";\nimport { buildOutputsView } from \"../../core/outputs/stackOutputs.js\";\nimport {\n fetchStackImports,\n scanConfigForImports,\n} from \"../../core/imports/fetchStackImports.js\";\n\nexport async function runStatus(options: {\n env?: string;\n configPath?: string;\n /** `product:workspace` — show only this workspace tenant from state. */\n tenant?: string;\n}): Promise<void> {\n const env = options.env ?? \"local\";\n const configPath = options.configPath;\n\n const config = await loadConfig(configPath, { env });\n const baseDir = getConfigBaseDir();\n const accountId =\n config.account_id ?? cloudflareAccountIdFromEnv();\n if (!accountId) {\n throw new Error(\n \"account_id required in config or CLOUDFLARE_ACCOUNT_ID env var\",\n );\n }\n const naming = namingFromConfig(config);\n const api = new CFApiClient(accountId);\n const state = new StateManager(\n config.tenant.id,\n env,\n stackNameForConfig(config),\n );\n await state.hydrate(api);\n\n const workers = await getWorkers(config, baseDir);\n console.log(\n `\\nStatus for ${config.tenant.name} (${config.tenant.slug}) — env: ${env}\\n`,\n );\n\n if (options.tenant?.trim()) {\n const raw = options.tenant.trim();\n const colon = raw.indexOf(\":\");\n if (colon < 1) {\n throw new Error(\n 'status --tenant expects \"product:workspace\" (e.g. todo:acme)',\n );\n }\n const product = raw.slice(0, colon);\n const workspace = raw.slice(colon + 1);\n const t = state.getTenant(product, workspace);\n console.log(`Workspace tenant ${tenantStateKey(product, workspace)}:`);\n if (!t) {\n console.log(\" (no record in tamer state)\\n\");\n return;\n }\n console.log(` status: ${t.provisioningStatus}`);\n console.log(` dispatch namespace: ${t.dispatchNamespaceName}`);\n console.log(` script: ${t.scriptName}`);\n if (t.d1Shards?.length) {\n console.log(\" D1 shards:\");\n for (const s of t.d1Shards) {\n console.log(` ${s.role}: ${s.derivedName} [${s.cfId}]`);\n }\n }\n console.log();\n return;\n }\n\n const outputRows = buildOutputsView(config, state);\n if (outputRows.length > 0) {\n console.log(\"Stack outputs:\");\n for (const r of outputRows) {\n const valueText =\n r.value === null\n ? \"(unresolved — run apply)\"\n : r.value;\n const meta: string[] = [r.status];\n if (r.status === \"stale\" && r.declaredSource) {\n meta.push(`source drifted → ${r.declaredSource}`);\n }\n console.log(` ${r.name}: ${valueText} [${meta.join(\", \")}]`);\n }\n console.log();\n }\n\n // Inbound imports — show every `${tamer:import:<stack>.<output>}`\n // referenced by config, grouped by source stack. We tolerate fetch\n // failures so `tamer status` still works in offline / partial-cred\n // environments; a missing sibling row just displays \"(unresolved)\".\n const importRefs = scanConfigForImports(config);\n let siblingImports: Record<string, Record<string, string>> = {};\n try {\n siblingImports = await fetchStackImports(api, config, env);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`(could not pre-fetch imported stacks: ${msg})`);\n }\n if (importRefs.length > 0) {\n console.log(\"Stack imports:\");\n const byStack = new Map<string, Set<string>>();\n for (const r of importRefs) {\n if (!byStack.has(r.stack)) byStack.set(r.stack, new Set());\n byStack.get(r.stack)!.add(r.output);\n }\n for (const [stack, outputs] of [...byStack].sort(([a], [b]) =>\n a.localeCompare(b),\n )) {\n console.log(` from stack \"${stack}\":`);\n const stackOutputs = siblingImports[stack] ?? {};\n for (const out of [...outputs].sort()) {\n const v = stackOutputs[out];\n const status = v === undefined ? \"unresolved\" : \"resolved\";\n const value = v ?? \"(missing — run `tamer apply` on that stack)\";\n console.log(` ${out}: ${value} [${status}]`);\n }\n }\n console.log();\n }\n\n const dns = dispatchNamespaceStatus(\n getDispatchNamespaces(config),\n env,\n state,\n naming,\n config,\n );\n if (dns.length > 0) {\n console.log(\"Dispatch namespaces:\");\n for (const r of dns) {\n console.log(` ${r.logicalName} (${r.namespace}) [${r.status}]`);\n }\n console.log();\n }\n\n const tenants = state.listTenants();\n if (tenants.length > 0) {\n console.log(`Tenants (${tenants.length}):`);\n for (const t of tenants.sort((a, b) =>\n `${a.product}:${a.workspace}`.localeCompare(`${b.product}:${b.workspace}`),\n )) {\n const shards = t.d1Shards?.length ?? 0;\n console.log(\n ` ${t.product}:${t.workspace} [${t.provisioningStatus}] ${t.scriptName} (${shards} shard(s))`,\n );\n }\n console.log();\n }\n\n const dnsRows = dnsRecordStatus(getDnsRecords(config), env, state);\n if (dnsRows.length > 0) {\n console.log(\"DNS records:\");\n for (const r of dnsRows) {\n const id = r.recordId ? ` [${r.recordId}]` : \"\";\n console.log(` ${r.logicalName}: ${r.type} ${r.name}${id} [${r.status}]`);\n }\n console.log();\n }\n\n let logpushLive:\n | Awaited<ReturnType<CFApiClient[\"logpushAccountJobsList\"]>>\n | undefined;\n if (env !== \"local\") {\n try {\n logpushLive = await api.logpushAccountJobsList();\n } catch {\n // Token may lack Logpush list; state-only rows still print.\n }\n }\n const logpushRows = logpushJobStatus(\n getLogpushJobs(config),\n config.tenant,\n env,\n state,\n logpushLive,\n );\n if (logpushRows.length > 0) {\n console.log(\"Logpush jobs:\");\n for (const r of logpushRows) {\n const id = r.cfJobId != null ? ` [id ${r.cfJobId}]` : \"\";\n const hints: string[] = [];\n if (r.cfEnabled === false) hints.push(\"disabled on Cloudflare\");\n if (r.cfError) hints.push(`CF error: ${r.cfError}`);\n const hint = hints.length > 0 ? ` — ${hints.join(\"; \")}` : \"\";\n console.log(` ${r.logicalName}: ${r.jobName}${id} [${r.status}]${hint}`);\n }\n console.log();\n }\n\n for (const [workerKey, workerConfig] of workers) {\n console.log(`Worker: ${workerKey}`);\n const deployedName = resolveDeployedWorkerName(\n config,\n workerKey,\n workerConfig,\n env,\n naming,\n );\n const mergedWorker = mergeWorkerConfigForResourcePick(\n config,\n workerKey,\n workerConfig,\n env,\n accountId,\n naming,\n state,\n { referencesMode: \"tolerant\", imports: siblingImports },\n );\n let printedAny = false;\n for (const mod of resourceModules) {\n const resources = mod.pickResources(mergedWorker);\n if (resources.length === 0) continue;\n const rows = mod.status({\n resources,\n env,\n state,\n naming,\n worker: { workerKey, deployedName },\n });\n if (rows.length === 0) continue;\n printedAny = true;\n console.log(` ${mod.label}:`);\n for (const r of rows) {\n console.log(` ${r.binding}: ${r.name} [${r.status}]`);\n }\n }\n if (!printedAny) console.log(\" (no resources)\");\n console.log();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import "./registry-CTerXUza.mjs";
2
+ import "./r2S3EmptyBucket-DD81ZWQ7.mjs";
3
+ import "./logpush-job-Dqlt-wEw.mjs";
4
+ import "./worker-route-BapxsQyX.mjs";
5
+ import { t as runSync } from "./sync-Dii9n2nJ.mjs";
6
+
7
+ export { runSync };
@@ -1,9 +1,9 @@
1
1
  import { f as getDispatchNamespaces, m as getLogpushJobs, p as getDnsRecords } from "./normalize-DVSTRZhO.mjs";
2
2
  import { E as mergeWorkerConfigForResourcePick, H as getWorkers, R as CFApiClient, U as loadConfig, V as getConfigBaseDir, f as fetchStackImports, h as StateManager, u as namingFromConfig, w as stackNameForConfig, z as cloudflareAccountIdFromEnv } from "./tamer.mjs";
3
- import { n as resourceModules } from "./registry-X9dlQxG3.mjs";
4
- import { n as dispatchNamespaceSync, t as dnsRecordSync } from "./dns-records.sync-Dfwk76J_.mjs";
5
- import { i as logpushJobSync } from "./logpush-job-C_6uzGUC.mjs";
6
- import { i as workerRouteSync } from "./worker-route-CvuUPq1k.mjs";
3
+ import { n as resourceModules } from "./registry-CTerXUza.mjs";
4
+ import { n as dispatchNamespaceSync, t as dnsRecordSync } from "./dns-records.sync-BORRvLky.mjs";
5
+ import { i as logpushJobSync } from "./logpush-job-Dqlt-wEw.mjs";
6
+ import { i as workerRouteSync } from "./worker-route-BapxsQyX.mjs";
7
7
 
8
8
  //#region src/cli/commands/sync.ts
9
9
  async function runSync(options) {
@@ -84,4 +84,4 @@ async function runSync(options) {
84
84
 
85
85
  //#endregion
86
86
  export { runSync as t };
87
- //# sourceMappingURL=sync-DfJGkOME.mjs.map
87
+ //# sourceMappingURL=sync-Dii9n2nJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-DfJGkOME.mjs","names":[],"sources":["../src/cli/commands/sync.ts"],"sourcesContent":["import { loadConfig, getWorkers, getConfigBaseDir } from \"../../core/config/loader.js\";\nimport { cloudflareAccountIdFromEnv } from \"../../core/cloudflareEnv.js\";\nimport { namingFromConfig } from \"../../core/config/namingFromConfig.js\";\nimport { StateManager } from \"../../core/state/StateManager.js\";\nimport { stackNameForConfig } from \"../../core/state/stackName.js\";\nimport { CFApiClient } from \"../../core/api/CFApiClient.js\";\nimport { dispatchNamespaceSync } from \"../../features/dispatch-namespace/index.js\";\nimport { dnsRecordSync } from \"../../features/dns-records/index.js\";\nimport { getDispatchNamespaces, getDnsRecords, getLogpushJobs } from \"../../types.js\";\nimport { logpushJobSync } from \"../../features/logpush-job/index.js\";\nimport { workerRouteSync } from \"../../features/worker-route/index.js\";\nimport { resourceModules } from \"../../core/registry/registry.js\";\nimport { fetchStackImports } from \"../../core/imports/fetchStackImports.js\";\nimport { mergeWorkerConfigForResourcePick } from \"../../core/config/resolver.js\";\n\nexport async function runSync(options: {\n env?: string;\n configPath?: string;\n}): Promise<void> {\n const env = options.env ?? \"local\";\n const configPath = options.configPath;\n\n const config = await loadConfig(configPath, { env });\n const baseDir = getConfigBaseDir();\n const accountId =\n config.account_id ?? cloudflareAccountIdFromEnv();\n if (!accountId) {\n throw new Error(\n \"account_id required in config or CLOUDFLARE_ACCOUNT_ID env var\",\n );\n }\n\n const api = new CFApiClient(accountId);\n const naming = namingFromConfig(config);\n const state = new StateManager(\n config.tenant.id,\n env,\n stackNameForConfig(config),\n );\n await state.hydrate(api);\n // Tolerant pre-fetch: sync runs against existing cloud state, so we\n // pass real import values into worker-route resolution to avoid\n // matching against `${tamer:import:…}` placeholders.\n const imports = await fetchStackImports(api, config, env).catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping cross-stack imports: ${msg}`);\n return {} as Record<string, Record<string, string>>;\n });\n\n async function safeList<T>(\n label: string,\n fn: () => Promise<T[]>,\n ): Promise<T[]> {\n try {\n return await fn();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping ${label}: ${msg}`);\n return [];\n }\n }\n\n const lists = await Promise.all(\n resourceModules.map((m) =>\n safeList(`${m.label} list`, () => m.fetchAll(api)),\n ),\n );\n\n if (getDispatchNamespaces(config).length > 0) {\n try {\n await dispatchNamespaceSync(\n getDispatchNamespaces(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping dispatch namespaces: ${msg}`);\n }\n }\n\n if (getDnsRecords(config).length > 0) {\n try {\n await dnsRecordSync(\n getDnsRecords(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping dns records: ${msg}`);\n }\n }\n\n if (getLogpushJobs(config).length > 0 && env !== \"local\") {\n try {\n await logpushJobSync(\n getLogpushJobs(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping logpush jobs: ${msg}`);\n }\n }\n\n const workers = await getWorkers(config, baseDir);\n for (const [workerKey, workerConfig] of workers) {\n const mergedWorker = mergeWorkerConfigForResourcePick(\n config,\n workerKey,\n workerConfig,\n env,\n accountId,\n naming,\n state,\n { referencesMode: \"tolerant\", imports },\n );\n resourceModules.forEach((mod, i) => {\n const resources = mod.pickResources(mergedWorker);\n if (resources.length === 0) return;\n mod.sync({\n resources,\n all: lists[i],\n tenant: config.tenant,\n env,\n api,\n state,\n naming,\n config,\n baseDir,\n });\n });\n }\n\n try {\n await workerRouteSync(env, config, baseDir, accountId, naming, state, api, {\n imports,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping worker routes: ${msg}`);\n }\n\n await state.persist(api);\n console.log(`Synced state for env: ${env}`);\n}\n"],"mappings":";;;;;;;;AAeA,eAAsB,QAAQ,SAGZ;CAChB,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,aAAa,QAAQ;CAE3B,MAAM,SAAS,MAAM,WAAW,YAAY,EAAE,KAAK,CAAC;CACpD,MAAM,UAAU,kBAAkB;CAClC,MAAM,YACJ,OAAO,cAAc,4BAA4B;AACnD,KAAI,CAAC,UACH,OAAM,IAAI,MACR,iEACD;CAGH,MAAM,MAAM,IAAI,YAAY,UAAU;CACtC,MAAM,SAAS,iBAAiB,OAAO;CACvC,MAAM,QAAQ,IAAI,aAChB,OAAO,OAAO,IACd,KACA,mBAAmB,OAAO,CAC3B;AACD,OAAM,MAAM,QAAQ,IAAI;CAIxB,MAAM,UAAU,MAAM,kBAAkB,KAAK,QAAQ,IAAI,CAAC,OAAO,QAAQ;EACvE,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,wCAAwC,MAAM;AAC3D,SAAO,EAAE;GACT;CAEF,eAAe,SACb,OACA,IACc;AACd,MAAI;AACF,UAAO,MAAM,IAAI;WACV,KAAK;GACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,WAAQ,KAAK,mBAAmB,MAAM,IAAI,MAAM;AAChD,UAAO,EAAE;;;CAIb,MAAM,QAAQ,MAAM,QAAQ,IAC1B,gBAAgB,KAAK,MACnB,SAAS,GAAG,EAAE,MAAM,cAAc,EAAE,SAAS,IAAI,CAAC,CACnD,CACF;AAED,KAAI,sBAAsB,OAAO,CAAC,SAAS,EACzC,KAAI;AACF,QAAM,sBACJ,sBAAsB,OAAO,EAC7B,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,wCAAwC,MAAM;;AAI/D,KAAI,cAAc,OAAO,CAAC,SAAS,EACjC,KAAI;AACF,QAAM,cACJ,cAAc,OAAO,EACrB,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,gCAAgC,MAAM;;AAIvD,KAAI,eAAe,OAAO,CAAC,SAAS,KAAK,QAAQ,QAC/C,KAAI;AACF,QAAM,eACJ,eAAe,OAAO,EACtB,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,iCAAiC,MAAM;;CAIxD,MAAM,UAAU,MAAM,WAAW,QAAQ,QAAQ;AACjD,MAAK,MAAM,CAAC,WAAW,iBAAiB,SAAS;EAC/C,MAAM,eAAe,iCACnB,QACA,WACA,cACA,KACA,WACA,QACA,OACA;GAAE,gBAAgB;GAAY;GAAS,CACxC;AACD,kBAAgB,SAAS,KAAK,MAAM;GAClC,MAAM,YAAY,IAAI,cAAc,aAAa;AACjD,OAAI,UAAU,WAAW,EAAG;AAC5B,OAAI,KAAK;IACP;IACA,KAAK,MAAM;IACX,QAAQ,OAAO;IACf;IACA;IACA;IACA;IACA;IACA;IACD,CAAC;IACF;;AAGJ,KAAI;AACF,QAAM,gBAAgB,KAAK,QAAQ,SAAS,WAAW,QAAQ,OAAO,KAAK,EACzE,SACD,CAAC;UACK,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,kCAAkC,MAAM;;AAGvD,OAAM,MAAM,QAAQ,IAAI;AACxB,SAAQ,IAAI,yBAAyB,MAAM"}
1
+ {"version":3,"file":"sync-Dii9n2nJ.mjs","names":[],"sources":["../src/cli/commands/sync.ts"],"sourcesContent":["import { loadConfig, getWorkers, getConfigBaseDir } from \"../../core/config/loader.js\";\nimport { cloudflareAccountIdFromEnv } from \"../../core/cloudflareEnv.js\";\nimport { namingFromConfig } from \"../../core/config/namingFromConfig.js\";\nimport { StateManager } from \"../../core/state/StateManager.js\";\nimport { stackNameForConfig } from \"../../core/state/stackName.js\";\nimport { CFApiClient } from \"../../core/api/CFApiClient.js\";\nimport { dispatchNamespaceSync } from \"../../features/dispatch-namespace/index.js\";\nimport { dnsRecordSync } from \"../../features/dns-records/index.js\";\nimport { getDispatchNamespaces, getDnsRecords, getLogpushJobs } from \"../../types.js\";\nimport { logpushJobSync } from \"../../features/logpush-job/index.js\";\nimport { workerRouteSync } from \"../../features/worker-route/index.js\";\nimport { resourceModules } from \"../../core/registry/registry.js\";\nimport { fetchStackImports } from \"../../core/imports/fetchStackImports.js\";\nimport { mergeWorkerConfigForResourcePick } from \"../../core/config/resolver.js\";\n\nexport async function runSync(options: {\n env?: string;\n configPath?: string;\n}): Promise<void> {\n const env = options.env ?? \"local\";\n const configPath = options.configPath;\n\n const config = await loadConfig(configPath, { env });\n const baseDir = getConfigBaseDir();\n const accountId =\n config.account_id ?? cloudflareAccountIdFromEnv();\n if (!accountId) {\n throw new Error(\n \"account_id required in config or CLOUDFLARE_ACCOUNT_ID env var\",\n );\n }\n\n const api = new CFApiClient(accountId);\n const naming = namingFromConfig(config);\n const state = new StateManager(\n config.tenant.id,\n env,\n stackNameForConfig(config),\n );\n await state.hydrate(api);\n // Tolerant pre-fetch: sync runs against existing cloud state, so we\n // pass real import values into worker-route resolution to avoid\n // matching against `${tamer:import:…}` placeholders.\n const imports = await fetchStackImports(api, config, env).catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping cross-stack imports: ${msg}`);\n return {} as Record<string, Record<string, string>>;\n });\n\n async function safeList<T>(\n label: string,\n fn: () => Promise<T[]>,\n ): Promise<T[]> {\n try {\n return await fn();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping ${label}: ${msg}`);\n return [];\n }\n }\n\n const lists = await Promise.all(\n resourceModules.map((m) =>\n safeList(`${m.label} list`, () => m.fetchAll(api)),\n ),\n );\n\n if (getDispatchNamespaces(config).length > 0) {\n try {\n await dispatchNamespaceSync(\n getDispatchNamespaces(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping dispatch namespaces: ${msg}`);\n }\n }\n\n if (getDnsRecords(config).length > 0) {\n try {\n await dnsRecordSync(\n getDnsRecords(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping dns records: ${msg}`);\n }\n }\n\n if (getLogpushJobs(config).length > 0 && env !== \"local\") {\n try {\n await logpushJobSync(\n getLogpushJobs(config),\n config.tenant,\n env,\n api,\n state,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping logpush jobs: ${msg}`);\n }\n }\n\n const workers = await getWorkers(config, baseDir);\n for (const [workerKey, workerConfig] of workers) {\n const mergedWorker = mergeWorkerConfigForResourcePick(\n config,\n workerKey,\n workerConfig,\n env,\n accountId,\n naming,\n state,\n { referencesMode: \"tolerant\", imports },\n );\n resourceModules.forEach((mod, i) => {\n const resources = mod.pickResources(mergedWorker);\n if (resources.length === 0) return;\n mod.sync({\n resources,\n all: lists[i],\n tenant: config.tenant,\n env,\n api,\n state,\n naming,\n config,\n baseDir,\n });\n });\n }\n\n try {\n await workerRouteSync(env, config, baseDir, accountId, naming, state, api, {\n imports,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`[sync] skipping worker routes: ${msg}`);\n }\n\n await state.persist(api);\n console.log(`Synced state for env: ${env}`);\n}\n"],"mappings":";;;;;;;;AAeA,eAAsB,QAAQ,SAGZ;CAChB,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,aAAa,QAAQ;CAE3B,MAAM,SAAS,MAAM,WAAW,YAAY,EAAE,KAAK,CAAC;CACpD,MAAM,UAAU,kBAAkB;CAClC,MAAM,YACJ,OAAO,cAAc,4BAA4B;AACnD,KAAI,CAAC,UACH,OAAM,IAAI,MACR,iEACD;CAGH,MAAM,MAAM,IAAI,YAAY,UAAU;CACtC,MAAM,SAAS,iBAAiB,OAAO;CACvC,MAAM,QAAQ,IAAI,aAChB,OAAO,OAAO,IACd,KACA,mBAAmB,OAAO,CAC3B;AACD,OAAM,MAAM,QAAQ,IAAI;CAIxB,MAAM,UAAU,MAAM,kBAAkB,KAAK,QAAQ,IAAI,CAAC,OAAO,QAAQ;EACvE,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,wCAAwC,MAAM;AAC3D,SAAO,EAAE;GACT;CAEF,eAAe,SACb,OACA,IACc;AACd,MAAI;AACF,UAAO,MAAM,IAAI;WACV,KAAK;GACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,WAAQ,KAAK,mBAAmB,MAAM,IAAI,MAAM;AAChD,UAAO,EAAE;;;CAIb,MAAM,QAAQ,MAAM,QAAQ,IAC1B,gBAAgB,KAAK,MACnB,SAAS,GAAG,EAAE,MAAM,cAAc,EAAE,SAAS,IAAI,CAAC,CACnD,CACF;AAED,KAAI,sBAAsB,OAAO,CAAC,SAAS,EACzC,KAAI;AACF,QAAM,sBACJ,sBAAsB,OAAO,EAC7B,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,wCAAwC,MAAM;;AAI/D,KAAI,cAAc,OAAO,CAAC,SAAS,EACjC,KAAI;AACF,QAAM,cACJ,cAAc,OAAO,EACrB,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,gCAAgC,MAAM;;AAIvD,KAAI,eAAe,OAAO,CAAC,SAAS,KAAK,QAAQ,QAC/C,KAAI;AACF,QAAM,eACJ,eAAe,OAAO,EACtB,OAAO,QACP,KACA,KACA,MACD;UACM,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,iCAAiC,MAAM;;CAIxD,MAAM,UAAU,MAAM,WAAW,QAAQ,QAAQ;AACjD,MAAK,MAAM,CAAC,WAAW,iBAAiB,SAAS;EAC/C,MAAM,eAAe,iCACnB,QACA,WACA,cACA,KACA,WACA,QACA,OACA;GAAE,gBAAgB;GAAY;GAAS,CACxC;AACD,kBAAgB,SAAS,KAAK,MAAM;GAClC,MAAM,YAAY,IAAI,cAAc,aAAa;AACjD,OAAI,UAAU,WAAW,EAAG;AAC5B,OAAI,KAAK;IACP;IACA,KAAK,MAAM;IACX,QAAQ,OAAO;IACf;IACA;IACA;IACA;IACA;IACA;IACD,CAAC;IACF;;AAGJ,KAAI;AACF,QAAM,gBAAgB,KAAK,QAAQ,SAAS,WAAW,QAAQ,OAAO,KAAK,EACzE,SACD,CAAC;UACK,KAAK;EACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,UAAQ,KAAK,kCAAkC,MAAM;;AAGvD,OAAM,MAAM,QAAQ,IAAI;AACxB,SAAQ,IAAI,yBAAyB,MAAM"}
package/dist/tamer.mjs CHANGED
@@ -4290,6 +4290,11 @@ const TenantMetaSchema = object({
4290
4290
  name: string().min(1),
4291
4291
  slug: string().min(1),
4292
4292
  d1Shards: array(string().min(1).refine((s) => TENANT_SHARD_ROLE_RE.test(s), { error: "tenant.d1Shards entries must be lowercase ASCII (letters, digits, `_`, `-`) and start with a letter" })).optional().refine((arr) => !arr || new Set(arr).size === arr.length, "tenant.d1Shards must not contain duplicate roles"),
4293
+ shardBindings: record(string(), object({
4294
+ binding: string().min(1),
4295
+ migrationsDir: string().min(1),
4296
+ migrationsTable: string().optional()
4297
+ })).optional(),
4293
4298
  protectedEnvs: array(string().min(1)).optional(),
4294
4299
  ephemeralEnvPattern: string().min(1).optional().refine((s) => {
4295
4300
  if (s == null) return true;
@@ -4299,7 +4304,13 @@ const TenantMetaSchema = object({
4299
4304
  } catch {
4300
4305
  return false;
4301
4306
  }
4302
- }, "tenant.ephemeralEnvPattern must be a valid JavaScript RegExp source string")
4307
+ }, "tenant.ephemeralEnvPattern must be a valid JavaScript RegExp source string"),
4308
+ dispatchVars: record(string(), union([string(), any()])).optional(),
4309
+ dispatchServices: array(object({
4310
+ name: string().min(1),
4311
+ service: union([string(), any()]),
4312
+ environment: string().optional()
4313
+ })).optional()
4303
4314
  });
4304
4315
  const CloudflareNameFnSchema = custom((v) => v === void 0 || typeof v === "function").optional();
4305
4316
  const D1ResourceConfigSchema = object({
@@ -4733,6 +4744,23 @@ var CFApiClient = class {
4733
4744
  return data.result;
4734
4745
  }
4735
4746
  /**
4747
+ * Delete a Worker script via the CF API.
4748
+ * @see https://developers.cloudflare.com/api/resources/workers/subresources/scripts/methods/delete/
4749
+ */
4750
+ async workersScriptDelete(scriptName) {
4751
+ const url = `${CF_API_BASE}/accounts/${this.accountId}/workers/scripts/${encodeURIComponent(scriptName)}`;
4752
+ const res = await fetch(url, {
4753
+ method: "DELETE",
4754
+ headers: { Authorization: `Bearer ${this.apiToken}` }
4755
+ });
4756
+ if (res.status === 404) return false;
4757
+ if (!res.ok) {
4758
+ const msg = (await res.json())?.errors?.map((e) => e.message).join("; ") ?? res.statusText;
4759
+ throw new Error(`CF API error (workers script delete): ${msg}`);
4760
+ }
4761
+ return true;
4762
+ }
4763
+ /**
4736
4764
  * Upsert a plain-text secret binding on a Worker script.
4737
4765
  * @see https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/secrets/methods/update/
4738
4766
  */
@@ -4874,6 +4902,19 @@ var CFApiClient = class {
4874
4902
  await this.request(`/accounts/${this.accountId}/r2/buckets/${bucketName}`, { method: "DELETE" });
4875
4903
  }
4876
4904
  /**
4905
+ * Set lifecycle rules on an R2 bucket via CF REST API.
4906
+ * Used by R2 destroy to abort incomplete multipart uploads and delete
4907
+ * all objects before bucket deletion — no S3 credentials needed.
4908
+ *
4909
+ * @see https://developers.cloudflare.com/api/resources/r2/subresources/buckets/subresources/lifecycle/
4910
+ */
4911
+ async r2PutLifecycleRules(bucketName, rules) {
4912
+ await this.request(`/accounts/${this.accountId}/r2/buckets/${encodeURIComponent(bucketName)}/lifecycle`, {
4913
+ method: "PUT",
4914
+ body: JSON.stringify({ rules })
4915
+ });
4916
+ }
4917
+ /**
4877
4918
  * List objects in an R2 bucket via the CF REST API (not S3).
4878
4919
  * Uses the existing CLOUDFLARE_API_TOKEN — no separate S3 keys needed.
4879
4920
  */
@@ -8899,14 +8940,14 @@ async function main() {
8899
8940
  try {
8900
8941
  switch (command) {
8901
8942
  case "bootstrap":
8902
- await import("./bootstrap-ilkixdmD.mjs").then((m) => m.runBootstrap(parseBootstrapArgs(rest)));
8943
+ await import("./bootstrap-BCy6B-B6.mjs").then((m) => m.runBootstrap(parseBootstrapArgs(rest)));
8903
8944
  break;
8904
8945
  case "sync":
8905
- await import("./sync-CfNyelDN.mjs").then((m) => m.runSync(parseSyncArgs(rest)));
8946
+ await import("./sync-DSgJGQh1.mjs").then((m) => m.runSync(parseSyncArgs(rest)));
8906
8947
  break;
8907
8948
  case "apply": {
8908
8949
  const a = parseApplyArgs(rest);
8909
- await import("./apply-CV4_3Jv4.mjs").then((m) => m.runApply({
8950
+ await import("./apply-Mk9usR-U.mjs").then((m) => m.runApply({
8910
8951
  env: a.env,
8911
8952
  addShard: a.addShard,
8912
8953
  configPath: a.configPath,
@@ -8918,11 +8959,11 @@ async function main() {
8918
8959
  break;
8919
8960
  }
8920
8961
  case "dev":
8921
- await import("./dev-C__1rLos.mjs").then((m) => m.runDev(parseDevArgs(rest)));
8962
+ await import("./dev-sk6JGKe4.mjs").then((m) => m.runDev(parseDevArgs(rest)));
8922
8963
  break;
8923
8964
  case "deploy": {
8924
8965
  const d = parseDeployArgs(rest);
8925
- await import("./deploy-BEaNADU6.mjs").then((m) => m.runDeploy({
8966
+ await import("./deploy-DbXBHpCG.mjs").then((m) => m.runDeploy({
8926
8967
  worker: d.worker,
8927
8968
  env: d.env,
8928
8969
  configPath: d.configPath,
@@ -8931,23 +8972,23 @@ async function main() {
8931
8972
  break;
8932
8973
  }
8933
8974
  case "migrate":
8934
- await import("./migrate-EVfFlJOM.mjs").then((m) => m.runMigrate(parseMigrateArgs(rest)));
8975
+ await import("./migrate-DyrTw9ep.mjs").then((m) => m.runMigrate(parseMigrateArgs(rest)));
8935
8976
  break;
8936
8977
  case "types":
8937
- await import("./types-BPxuutXk.mjs").then((m) => m.runTypes(parseTypesArgs(rest)));
8978
+ await import("./types-HPpAxgub.mjs").then((m) => m.runTypes(parseTypesArgs(rest)));
8938
8979
  break;
8939
8980
  case "status":
8940
- await import("./status-srUxsBIB.mjs").then((m) => m.runStatus(parseStatusArgs(rest)));
8981
+ await import("./status-WMG5abrN.mjs").then((m) => m.runStatus(parseStatusArgs(rest)));
8941
8982
  break;
8942
8983
  case "events":
8943
- await import("./events-CnWvxyX_.mjs").then((m) => m.runEvents(parseEventsArgs(rest)));
8984
+ await import("./events-CqbN9sbT.mjs").then((m) => m.runEvents(parseEventsArgs(rest)));
8944
8985
  break;
8945
8986
  case "drift":
8946
- exitStatus = await import("./drift-08k11FV6.mjs").then((m) => m.runDrift(parseDriftArgs(rest)));
8987
+ exitStatus = await import("./drift-oOUlh0u8.mjs").then((m) => m.runDrift(parseDriftArgs(rest)));
8947
8988
  break;
8948
8989
  case "plan": {
8949
8990
  const p = parsePlanArgs(rest);
8950
- exitStatus = await import("./plan-tnUWkiM1.mjs").then((m) => m.runPlan({
8991
+ exitStatus = await import("./plan-D7UyLznb.mjs").then((m) => m.runPlan({
8951
8992
  env: p.env,
8952
8993
  configPath: p.configPath,
8953
8994
  json: p.json,
@@ -8959,14 +9000,14 @@ async function main() {
8959
9000
  break;
8960
9001
  }
8961
9002
  case "import":
8962
- await import("./import-BNbHjR9t.mjs").then((m) => m.runImport(parseImportArgs(rest)));
9003
+ await import("./import-leVD9Ryg.mjs").then((m) => m.runImport(parseImportArgs(rest)));
8963
9004
  break;
8964
9005
  case "doctor":
8965
- exitStatus = await import("./doctor-BIaLEVFR.mjs").then((m) => m.runDoctor(parseDoctorArgs(rest)));
9006
+ exitStatus = await import("./doctor-BgqnscIE.mjs").then((m) => m.runDoctor(parseDoctorArgs(rest)));
8966
9007
  break;
8967
9008
  case "destroy": {
8968
9009
  const d = parseDestroyArgs(rest);
8969
- await import("./destroy-Krf35oqE.mjs").then((m) => m.runDestroy({
9010
+ await import("./destroy-CesVkyxf.mjs").then((m) => m.runDestroy({
8970
9011
  env: d.env,
8971
9012
  force: d.force,
8972
9013
  skipWorkers: d.skipWorkers,
@@ -8981,12 +9022,12 @@ async function main() {
8981
9022
  case "wfp": {
8982
9023
  const [sub, ...wfpRest] = rest;
8983
9024
  if (sub === "put") {
8984
- const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-BBitXJep.mjs");
9025
+ const { parseWfpPutArgs, runWfpPut } = await import("./wfp-put-5XZ-KC3g.mjs");
8985
9026
  await runWfpPut(parseWfpPutArgs(wfpRest));
8986
9027
  break;
8987
9028
  }
8988
9029
  if (sub === "delete") {
8989
- const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-CwWQFxxj.mjs");
9030
+ const { parseWfpDeleteArgs, runWfpDelete } = await import("./wfp-delete-TSVBw9XF.mjs");
8990
9031
  await runWfpDelete(parseWfpDeleteArgs(wfpRest));
8991
9032
  break;
8992
9033
  }
@@ -8994,7 +9035,7 @@ async function main() {
8994
9035
  const tenantSub = wfpRest[0];
8995
9036
  const tenantRest = wfpRest.slice(1);
8996
9037
  if (tenantSub === "list") {
8997
- await import("./tenant-MWIs0esz.mjs").then((m) => m.runTenantList({
9038
+ await import("./tenant-WNYMWmIe.mjs").then((m) => m.runTenantList({
8998
9039
  env: parseStringFlag(wfpRest, "--env"),
8999
9040
  configPath: parseStringFlag(wfpRest, "--config"),
9000
9041
  json: wfpRest.includes("--json")
@@ -9002,7 +9043,7 @@ async function main() {
9002
9043
  break;
9003
9044
  }
9004
9045
  if (tenantSub === "status") {
9005
- await import("./tenant-MWIs0esz.mjs").then((m) => m.runTenantStatus({
9046
+ await import("./tenant-WNYMWmIe.mjs").then((m) => m.runTenantStatus({
9006
9047
  env: parseStringFlag(wfpRest, "--env"),
9007
9048
  product: parseStringFlag(wfpRest, "--product") ?? "",
9008
9049
  workspace: parseStringFlag(wfpRest, "--workspace") ?? "",
@@ -9011,15 +9052,15 @@ async function main() {
9011
9052
  break;
9012
9053
  }
9013
9054
  if (tenantSub === "provision") {
9014
- await import("./provision-tenant-R6Xa3IUJ.mjs").then((m) => m.runProvisionTenant(parseProvisionTenantArgs(tenantRest)));
9055
+ await import("./provision-tenant-z4DLxYAM.mjs").then((m) => m.runProvisionTenant(parseProvisionTenantArgs(tenantRest)));
9015
9056
  break;
9016
9057
  }
9017
9058
  if (tenantSub === "destroy") {
9018
- await import("./destroy-tenant-C95ljuon.mjs").then((m) => m.runDestroyTenant(parseDestroyTenantArgs(tenantRest)));
9059
+ await import("./destroy-tenant-DMynv_u-.mjs").then((m) => m.runDestroyTenant(parseDestroyTenantArgs(tenantRest)));
9019
9060
  break;
9020
9061
  }
9021
9062
  if (tenantSub === "migrate") {
9022
- await import("./tenant-migrate-BfvYL0HH.mjs").then((m) => m.runTenantMigrate({
9063
+ await import("./tenant-migrate-DBxTsvJ8.mjs").then((m) => m.runTenantMigrate({
9023
9064
  env: parseStringFlag(wfpRest, "--env"),
9024
9065
  product: parseStringFlag(wfpRest, "--product") ?? "",
9025
9066
  workspace: parseStringFlag(wfpRest, "--workspace") ?? "",
@@ -9034,14 +9075,14 @@ async function main() {
9034
9075
  process.exit(1);
9035
9076
  }
9036
9077
  case "secrets":
9037
- exitStatus = await import("./secrets-2Hy5LMHs.mjs").then((m) => m.runSecrets(rest));
9078
+ exitStatus = await import("./secrets-DJ1yUy01.mjs").then((m) => m.runSecrets(rest));
9038
9079
  break;
9039
9080
  case "env":
9040
- if (rest[0] === "list") await import("./env-list-DYCprcLb.mjs").then((m) => m.runEnvList({
9081
+ if (rest[0] === "list") await import("./env-list-DKseThiA.mjs").then((m) => m.runEnvList({
9041
9082
  configPath: parseStringFlag(rest, "--config"),
9042
9083
  json: rest.includes("--json")
9043
9084
  }));
9044
- else if (rest[0] === "gc") await import("./env-gc-0vX5Av4i.mjs").then((m) => m.runEnvGc({
9085
+ else if (rest[0] === "gc") await import("./env-gc-DE4EV7j7.mjs").then((m) => m.runEnvGc({
9045
9086
  maxAge: parseStringFlag(rest, "--max-age") ?? "72h",
9046
9087
  force: rest.includes("--force"),
9047
9088
  dryRun: rest.includes("--dry-run"),