@geekmidas/cli 1.10.30 → 1.10.31

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 (135) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/{CachedStateProvider-37pG1HBx.cjs → CachedStateProvider-3couMAQk.cjs} +1 -1
  3. package/dist/CachedStateProvider-C4QqvlPE.mjs +3 -0
  4. package/dist/{CachedStateProvider-C8A-cCm5.mjs → CachedStateProvider-CQr31ups.mjs} +1 -1
  5. package/dist/{CachedStateProvider-C8A-cCm5.mjs.map → CachedStateProvider-CQr31ups.mjs.map} +1 -1
  6. package/dist/{CachedStateProvider-CxsXOKkg.cjs → CachedStateProvider-Cyn17x3x.cjs} +1 -1
  7. package/dist/{CachedStateProvider-CxsXOKkg.cjs.map → CachedStateProvider-Cyn17x3x.cjs.map} +1 -1
  8. package/dist/{HostingerProvider-5KYmwoK2.cjs → HostingerProvider-C5oLa7N7.cjs} +1 -1
  9. package/dist/{HostingerProvider-5KYmwoK2.cjs.map → HostingerProvider-C5oLa7N7.cjs.map} +1 -1
  10. package/dist/{HostingerProvider-ANWchdiK.mjs → HostingerProvider-YvCg3Mus.mjs} +1 -1
  11. package/dist/{HostingerProvider-ANWchdiK.mjs.map → HostingerProvider-YvCg3Mus.mjs.map} +1 -1
  12. package/dist/{LocalStateProvider-Dp0KkRcw.mjs → LocalStateProvider-BciOhGR0.mjs} +1 -1
  13. package/dist/{LocalStateProvider-Dp0KkRcw.mjs.map → LocalStateProvider-BciOhGR0.mjs.map} +1 -1
  14. package/dist/{LocalStateProvider-CLifRC0Y.cjs → LocalStateProvider-DI6n11UM.cjs} +1 -1
  15. package/dist/{LocalStateProvider-CLifRC0Y.cjs.map → LocalStateProvider-DI6n11UM.cjs.map} +1 -1
  16. package/dist/{Route53Provider-QoPgcXxn.mjs → Route53Provider-CYlDOrYO.mjs} +1 -1
  17. package/dist/{Route53Provider-QoPgcXxn.mjs.map → Route53Provider-CYlDOrYO.mjs.map} +1 -1
  18. package/dist/{Route53Provider-owQQ4pn6.cjs → Route53Provider-DISZ6E8f.cjs} +1 -1
  19. package/dist/{Route53Provider-owQQ4pn6.cjs.map → Route53Provider-DISZ6E8f.cjs.map} +1 -1
  20. package/dist/{SSMStateProvider-CT8tjl9o.cjs → SSMStateProvider-BljH5efc.cjs} +1 -1
  21. package/dist/{SSMStateProvider-CT8tjl9o.cjs.map → SSMStateProvider-BljH5efc.cjs.map} +1 -1
  22. package/dist/{SSMStateProvider-CksOTB8M.mjs → SSMStateProvider-DXT1dIdI.mjs} +1 -1
  23. package/dist/{SSMStateProvider-CksOTB8M.mjs.map → SSMStateProvider-DXT1dIdI.mjs.map} +1 -1
  24. package/dist/{backup-provisioner-BEXoHTuC.mjs → backup-provisioner-CCUcj28C.mjs} +1 -1
  25. package/dist/{backup-provisioner-BEXoHTuC.mjs.map → backup-provisioner-CCUcj28C.mjs.map} +1 -1
  26. package/dist/{backup-provisioner-C4noe75O.cjs → backup-provisioner-CpirEvO1.cjs} +1 -1
  27. package/dist/{backup-provisioner-C4noe75O.cjs.map → backup-provisioner-CpirEvO1.cjs.map} +1 -1
  28. package/dist/{bundler-BG6P249p.cjs → bundler-CLOenWgi.cjs} +2 -2
  29. package/dist/{bundler-BG6P249p.cjs.map → bundler-CLOenWgi.cjs.map} +1 -1
  30. package/dist/{bundler-c6QvGUBM.mjs → bundler-E5VcXsPH.mjs} +2 -2
  31. package/dist/{bundler-c6QvGUBM.mjs.map → bundler-E5VcXsPH.mjs.map} +1 -1
  32. package/dist/client-generator-CUVVtAOo.mjs +23 -0
  33. package/dist/client-generator-CUVVtAOo.mjs.map +1 -0
  34. package/dist/client-generator-D-T4ypQo.cjs +35 -0
  35. package/dist/client-generator-D-T4ypQo.cjs.map +1 -0
  36. package/dist/{config-jsRYHOHU.mjs → config-B62g483e.mjs} +2 -2
  37. package/dist/{config-jsRYHOHU.mjs.map → config-B62g483e.mjs.map} +1 -1
  38. package/dist/{config-D3ORuiUs.cjs → config-Cuo8vFsp.cjs} +2 -2
  39. package/dist/{config-D3ORuiUs.cjs.map → config-Cuo8vFsp.cjs.map} +1 -1
  40. package/dist/config.cjs +2 -2
  41. package/dist/config.d.cts +1 -1
  42. package/dist/config.d.mts +2 -2
  43. package/dist/config.mjs +2 -2
  44. package/dist/deploy/sniffer-worker.cjs +2 -0
  45. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  46. package/dist/deploy/sniffer-worker.mjs +2 -0
  47. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  48. package/dist/dokploy-api-BPYkG-ZZ.cjs +3 -0
  49. package/dist/dokploy-api-BiSzWM4v.mjs +3 -0
  50. package/dist/{dokploy-api-Dvyq-LsM.cjs → dokploy-api-CqOIKHme.cjs} +1 -1
  51. package/dist/{dokploy-api-Dvyq-LsM.cjs.map → dokploy-api-CqOIKHme.cjs.map} +1 -1
  52. package/dist/{dokploy-api-BIT0683o.mjs → dokploy-api-sfZFlWuE.mjs} +1 -1
  53. package/dist/{dokploy-api-BIT0683o.mjs.map → dokploy-api-sfZFlWuE.mjs.map} +1 -1
  54. package/dist/{encryption-CipsS0KW.cjs → encryption-BVS7Vmzs.cjs} +1 -1
  55. package/dist/encryption-Bd_m4q3g.mjs +3 -0
  56. package/dist/{encryption-DSkIlEZ6.mjs → encryption-CO5Q4Bhf.mjs} +1 -1
  57. package/dist/{encryption-DSkIlEZ6.mjs.map → encryption-CO5Q4Bhf.mjs.map} +1 -1
  58. package/dist/{encryption-DgKS-Dv9.cjs → encryption-MfXAiFTm.cjs} +1 -1
  59. package/dist/{encryption-DgKS-Dv9.cjs.map → encryption-MfXAiFTm.cjs.map} +1 -1
  60. package/dist/{index-CY-ieuRp.d.mts → index-C-_rW4KF.d.mts} +3 -33
  61. package/dist/index-C-_rW4KF.d.mts.map +1 -0
  62. package/dist/{index-BkibYzso.d.cts → index-C3t5VL4R.d.cts} +2 -32
  63. package/dist/index-C3t5VL4R.d.cts.map +1 -0
  64. package/dist/index.cjs +94 -379
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.mjs +70 -355
  67. package/dist/index.mjs.map +1 -1
  68. package/dist/{openapi-CTARkkkn.mjs → openapi-DHq5r17U.mjs} +6 -41
  69. package/dist/openapi-DHq5r17U.mjs.map +1 -0
  70. package/dist/{openapi-react-query-C4UdILaI.mjs → openapi-react-query-COpH7Mmz.mjs} +1 -1
  71. package/dist/{openapi-react-query-C4UdILaI.mjs.map → openapi-react-query-COpH7Mmz.mjs.map} +1 -1
  72. package/dist/{openapi-react-query-DYbBq-WJ.cjs → openapi-react-query-CxyQTTdF.cjs} +1 -1
  73. package/dist/{openapi-react-query-DYbBq-WJ.cjs.map → openapi-react-query-CxyQTTdF.cjs.map} +1 -1
  74. package/dist/openapi-react-query.cjs +1 -1
  75. package/dist/openapi-react-query.mjs +1 -1
  76. package/dist/{openapi-ClA8lIhO.cjs → openapi-w-_smBTO.cjs} +6 -53
  77. package/dist/openapi-w-_smBTO.cjs.map +1 -0
  78. package/dist/openapi.cjs +4 -3
  79. package/dist/openapi.d.mts +1 -1
  80. package/dist/openapi.mjs +4 -3
  81. package/dist/{reconcile-CZtzdrnc.cjs → reconcile-C8KIy4Uy.cjs} +1 -1
  82. package/dist/{reconcile-CZtzdrnc.cjs.map → reconcile-C8KIy4Uy.cjs.map} +1 -1
  83. package/dist/{reconcile-DAAKa0YR.mjs → reconcile-D423q2QW.mjs} +1 -1
  84. package/dist/{reconcile-DAAKa0YR.mjs.map → reconcile-D423q2QW.mjs.map} +1 -1
  85. package/dist/sniffer-BqSVVrWA.mjs +356 -0
  86. package/dist/sniffer-BqSVVrWA.mjs.map +1 -0
  87. package/dist/sniffer-CBhzByiY.cjs +386 -0
  88. package/dist/sniffer-CBhzByiY.cjs.map +1 -0
  89. package/dist/sniffer-Cpq_cbyz.mjs +4 -0
  90. package/dist/sniffer-eZ13G10M.cjs +4 -0
  91. package/dist/sync-B2CN_KS5.cjs +4 -0
  92. package/dist/{sync-DGXXSk2v.cjs → sync-BWY6yoUG.cjs} +1 -1
  93. package/dist/{sync-DGXXSk2v.cjs.map → sync-BWY6yoUG.cjs.map} +1 -1
  94. package/dist/{sync-D_NowTkZ.mjs → sync-Dc-QA4Mx.mjs} +1 -1
  95. package/dist/{sync-D_NowTkZ.mjs.map → sync-Dc-QA4Mx.mjs.map} +1 -1
  96. package/dist/{sync-COnAugP-.mjs → sync-fzT5WX_y.mjs} +1 -1
  97. package/dist/{types-OszPdw9m.d.mts → types-BqAbYt5a.d.mts} +1 -1
  98. package/dist/{types-OszPdw9m.d.mts.map → types-BqAbYt5a.d.mts.map} +1 -1
  99. package/dist/workspace/index.cjs +1 -1
  100. package/dist/workspace/index.d.cts +2 -2
  101. package/dist/workspace/index.d.mts +3 -3
  102. package/dist/workspace/index.mjs +1 -1
  103. package/dist/{workspace-D4z4A4cq.mjs → workspace-Bi4X7Yzy.mjs} +1 -6
  104. package/dist/{workspace-D4z4A4cq.mjs.map → workspace-Bi4X7Yzy.mjs.map} +1 -1
  105. package/dist/{workspace-4SP3Gx4Y.cjs → workspace-CGYykWfn.cjs} +1 -6
  106. package/dist/{workspace-4SP3Gx4Y.cjs.map → workspace-CGYykWfn.cjs.map} +1 -1
  107. package/package.json +2 -2
  108. package/src/__tests__/openapi.spec.ts +0 -315
  109. package/src/build/__tests__/manifests.spec.ts +66 -0
  110. package/src/build/index.ts +54 -1
  111. package/src/deploy/__tests__/__fixtures__/env-parsers/optional-env-parser.ts +21 -0
  112. package/src/deploy/__tests__/sniffer.spec.ts +123 -0
  113. package/src/deploy/sniffer-worker.ts +2 -1
  114. package/src/deploy/sniffer.ts +86 -12
  115. package/src/docker/compose.ts +2 -0
  116. package/src/index.ts +8 -0
  117. package/src/init/generators/monorepo.ts +15 -1
  118. package/src/init/index.ts +2 -4
  119. package/src/init/versions.ts +1 -1
  120. package/src/openapi.ts +1 -35
  121. package/src/types.ts +7 -0
  122. package/src/workspace/__tests__/client-generator.spec.ts +1 -485
  123. package/src/workspace/client-generator.ts +1 -145
  124. package/src/workspace/index.ts +0 -1
  125. package/src/workspace/schema.ts +0 -9
  126. package/src/workspace/types.ts +0 -29
  127. package/dist/CachedStateProvider-CC0DyO09.mjs +0 -3
  128. package/dist/dokploy-api-BOx71j6F.cjs +0 -3
  129. package/dist/dokploy-api-BZGk-lkD.mjs +0 -3
  130. package/dist/encryption-Db2zvGqM.mjs +0 -3
  131. package/dist/index-BkibYzso.d.cts.map +0 -1
  132. package/dist/index-CY-ieuRp.d.mts.map +0 -1
  133. package/dist/openapi-CTARkkkn.mjs.map +0 -1
  134. package/dist/openapi-ClA8lIhO.cjs.map +0 -1
  135. package/dist/sync-D1Pa30oV.cjs +0 -4
package/dist/index.cjs CHANGED
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env -S npx tsx
2
2
  const require_chunk = require('./chunk-CUT6urMc.cjs');
3
- const require_workspace = require('./workspace-4SP3Gx4Y.cjs');
4
- const require_config = require('./config-D3ORuiUs.cjs');
3
+ const require_workspace = require('./workspace-CGYykWfn.cjs');
4
+ const require_config = require('./config-Cuo8vFsp.cjs');
5
5
  const require_credentials = require('./credentials-C8DWtnMY.cjs');
6
6
  const require_fullstack_secrets = require('./fullstack-secrets-Bchl2MDd.cjs');
7
7
  const require_storage = require('./storage-B1wvztiJ.cjs');
8
- const require_openapi = require('./openapi-ClA8lIhO.cjs');
9
- const require_dokploy_api = require('./dokploy-api-Dvyq-LsM.cjs');
10
- const require_encryption = require('./encryption-DgKS-Dv9.cjs');
11
- const require_CachedStateProvider = require('./CachedStateProvider-CxsXOKkg.cjs');
12
- const require_openapi_react_query = require('./openapi-react-query-DYbBq-WJ.cjs');
13
- const require_sync = require('./sync-DGXXSk2v.cjs');
8
+ const require_client_generator = require('./client-generator-D-T4ypQo.cjs');
9
+ const require_openapi = require('./openapi-w-_smBTO.cjs');
10
+ const require_dokploy_api = require('./dokploy-api-CqOIKHme.cjs');
11
+ const require_encryption = require('./encryption-MfXAiFTm.cjs');
12
+ const require_sniffer = require('./sniffer-CBhzByiY.cjs');
13
+ const require_CachedStateProvider = require('./CachedStateProvider-Cyn17x3x.cjs');
14
+ const require_openapi_react_query = require('./openapi-react-query-CxyQTTdF.cjs');
15
+ const require_sync = require('./sync-BWY6yoUG.cjs');
14
16
  const node_fs = require_chunk.__toESM(require("node:fs"));
15
17
  const node_path = require_chunk.__toESM(require("node:path"));
16
18
  const commander = require_chunk.__toESM(require("commander"));
@@ -30,12 +32,11 @@ const __geekmidas_constructs_subscribers = require_chunk.__toESM(require("@geekm
30
32
  const pg = require_chunk.__toESM(require("pg"));
31
33
  const node_dns_promises = require_chunk.__toESM(require("node:dns/promises"));
32
34
  const node_module = require_chunk.__toESM(require("node:module"));
33
- const node_url = require_chunk.__toESM(require("node:url"));
34
35
  const prompts = require_chunk.__toESM(require("prompts"));
35
36
 
36
37
  //#region package.json
37
38
  var name = "@geekmidas/cli";
38
- var version = "1.10.29";
39
+ var version = "1.10.30";
39
40
  var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
40
41
  var private$1 = false;
41
42
  var type = "module";
@@ -138,7 +139,7 @@ const logger$14 = console;
138
139
  * Validate Dokploy token by making a test API call
139
140
  */
140
141
  async function validateDokployToken(endpoint, token) {
141
- const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-BOx71j6F.cjs"));
142
+ const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-BPYkG-ZZ.cjs"));
142
143
  const api = new DokployApi$1({
143
144
  baseUrl: endpoint,
144
145
  token
@@ -152,7 +153,7 @@ async function prompt$1(message, hidden = false) {
152
153
  if (!process.stdin.isTTY) throw new Error("Interactive input required. Please provide --token option.");
153
154
  if (hidden) {
154
155
  process.stdout.write(message);
155
- return new Promise((resolve$4, reject) => {
156
+ return new Promise((resolve$3, reject) => {
156
157
  let value = "";
157
158
  const cleanup = () => {
158
159
  process.stdin.setRawMode(false);
@@ -169,7 +170,7 @@ async function prompt$1(message, hidden = false) {
169
170
  if (c === "\n" || c === "\r") {
170
171
  cleanup();
171
172
  process.stdout.write("\n");
172
- resolve$4(value);
173
+ resolve$3(value);
173
174
  } else if (c === "") {
174
175
  cleanup();
175
176
  process.stdout.write("\n");
@@ -374,15 +375,15 @@ function loadEnvFiles(envConfig, cwd = process.cwd()) {
374
375
  * @internal Exported for testing
375
376
  */
376
377
  async function isPortAvailable(port) {
377
- return new Promise((resolve$4) => {
378
+ return new Promise((resolve$3) => {
378
379
  const server = (0, node_net.createServer)();
379
380
  server.once("error", (err) => {
380
- if (err.code === "EADDRINUSE") resolve$4(false);
381
- else resolve$4(false);
381
+ if (err.code === "EADDRINUSE") resolve$3(false);
382
+ else resolve$3(false);
382
383
  });
383
384
  server.once("listening", () => {
384
385
  server.close();
385
- resolve$4(true);
386
+ resolve$3(true);
386
387
  });
387
388
  server.listen(port);
388
389
  });
@@ -1140,11 +1141,11 @@ async function execCommand(commandArgs, options = {}) {
1140
1141
  NODE_OPTIONS: nodeOptions
1141
1142
  }
1142
1143
  });
1143
- const exitCode = await new Promise((resolve$4) => {
1144
- child.on("close", (code) => resolve$4(code ?? 0));
1144
+ const exitCode = await new Promise((resolve$3) => {
1145
+ child.on("close", (code) => resolve$3(code ?? 0));
1145
1146
  child.on("error", (error) => {
1146
1147
  logger$12.error(`Failed to run command: ${error.message}`);
1147
- resolve$4(1);
1148
+ resolve$3(1);
1148
1149
  });
1149
1150
  });
1150
1151
  if (exitCode !== 0) process.exit(exitCode);
@@ -1646,14 +1647,14 @@ async function workspaceDevCommand(workspace, options) {
1646
1647
  };
1647
1648
  process.on("SIGINT", shutdown);
1648
1649
  process.on("SIGTERM", shutdown);
1649
- return new Promise((resolve$4, reject) => {
1650
+ return new Promise((resolve$3, reject) => {
1650
1651
  turboProcess.on("error", (error) => {
1651
1652
  logger$11.error("❌ Turbo error:", error);
1652
1653
  reject(error);
1653
1654
  });
1654
1655
  turboProcess.on("exit", (code) => {
1655
1656
  if (code !== null && code !== 0) reject(new Error(`Turbo exited with code ${code}`));
1656
- else resolve$4();
1657
+ else resolve$3();
1657
1658
  });
1658
1659
  });
1659
1660
  }
@@ -1765,7 +1766,7 @@ var EntryRunner = class {
1765
1766
  if (code !== null && code !== 0 && code !== 143) logger$11.error(`❌ Process exited with code ${code}`);
1766
1767
  this.isRunning = false;
1767
1768
  });
1768
- await new Promise((resolve$4) => setTimeout(resolve$4, 500));
1769
+ await new Promise((resolve$3) => setTimeout(resolve$3, 500));
1769
1770
  if (this.isRunning) {
1770
1771
  logger$11.log("");
1771
1772
  logger$11.log(` \x1b[32m✓ Ready\x1b[0m at \x1b[36mhttp://localhost:${this.port}\x1b[0m`);
@@ -1774,7 +1775,7 @@ var EntryRunner = class {
1774
1775
  }
1775
1776
  async restart() {
1776
1777
  this.stopProcess();
1777
- await new Promise((resolve$4) => setTimeout(resolve$4, 500));
1778
+ await new Promise((resolve$3) => setTimeout(resolve$3, 500));
1778
1779
  await this.runProcess();
1779
1780
  }
1780
1781
  stop() {
@@ -1909,7 +1910,7 @@ var DevServer = class {
1909
1910
  if (code !== null && code !== 0 && signal !== "SIGTERM") logger$11.error(`❌ Server exited with code ${code}`);
1910
1911
  this.isRunning = false;
1911
1912
  });
1912
- await new Promise((resolve$4) => setTimeout(resolve$4, 1e3));
1913
+ await new Promise((resolve$3) => setTimeout(resolve$3, 1e3));
1913
1914
  if (this.isRunning) {
1914
1915
  const base = `http://localhost:${this.actualPort}`;
1915
1916
  const lines = [` Local: ${base}`];
@@ -1955,7 +1956,7 @@ var DevServer = class {
1955
1956
  let attempts = 0;
1956
1957
  while (attempts < 30) {
1957
1958
  if (await isPortAvailable(portToReuse)) break;
1958
- await new Promise((resolve$4) => setTimeout(resolve$4, 100));
1959
+ await new Promise((resolve$3) => setTimeout(resolve$3, 100));
1959
1960
  attempts++;
1960
1961
  }
1961
1962
  this.requestedPort = portToReuse;
@@ -2202,18 +2203,25 @@ async function buildCommand(options) {
2202
2203
  }
2203
2204
  const rootOutputDir = (0, node_path.join)(process.cwd(), ".gkm");
2204
2205
  await (0, node_fs_promises.mkdir)(rootOutputDir, { recursive: true });
2206
+ let optionalVarSet;
2207
+ if (options.markOptional && config.envParser) try {
2208
+ const { _sniffEnvParser } = await Promise.resolve().then(() => require("./sniffer-eZ13G10M.cjs"));
2209
+ const sniffed = await _sniffEnvParser(config.envParser, process.cwd(), process.cwd());
2210
+ if (sniffed.optionalEnvVars.length > 0) optionalVarSet = new Set(sniffed.optionalEnvVars);
2211
+ } catch {}
2205
2212
  let result = {};
2206
2213
  for (const provider of resolved.providers) {
2207
- const providerResult = await buildForProvider(provider, buildContext, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, resolved.enableOpenApi, options.skipBundle ?? false, options.stage);
2214
+ const providerResult = await buildForProvider(provider, buildContext, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, resolved.enableOpenApi, options.skipBundle ?? false, options.stage, optionalVarSet);
2208
2215
  if (providerResult.masterKey) result = providerResult;
2209
2216
  }
2217
+ await require_openapi.generateOpenApi(config, { bustCache: true });
2210
2218
  return result;
2211
2219
  }
2212
- async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage) {
2220
+ async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage, optionalVarSet) {
2213
2221
  const outputDir = (0, node_path.join)(process.cwd(), ".gkm", provider);
2214
2222
  await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
2215
2223
  logger$9.log(`\nGenerating handlers for provider: ${provider}`);
2216
- const [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all([
2224
+ const [rawRoutes, rawFunctions, rawCrons, rawSubscribers] = await Promise.all([
2217
2225
  endpointGenerator.build(context, endpoints, outputDir, {
2218
2226
  provider,
2219
2227
  enableOpenApi
@@ -2222,6 +2230,23 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2222
2230
  cronGenerator.build(context, crons, outputDir, { provider }),
2223
2231
  subscriberGenerator.build(context, subscribers, outputDir, { provider })
2224
2232
  ]);
2233
+ const markEnv = optionalVarSet ? (vars) => vars?.map((v) => optionalVarSet.has(v) ? `${v}?` : v) : (vars) => vars;
2234
+ const routes = rawRoutes.map((r) => ({
2235
+ ...r,
2236
+ environment: markEnv(r.environment)
2237
+ }));
2238
+ const functionInfos = rawFunctions.map((f) => ({
2239
+ ...f,
2240
+ environment: markEnv(f.environment)
2241
+ }));
2242
+ const cronInfos = rawCrons.map((c) => ({
2243
+ ...c,
2244
+ environment: markEnv(c.environment)
2245
+ }));
2246
+ const subscriberInfos = rawSubscribers.map((s) => ({
2247
+ ...s,
2248
+ environment: markEnv(s.environment)
2249
+ }));
2225
2250
  logger$9.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`);
2226
2251
  const manifestRoutes = assembleManifestField(routes, endpoints);
2227
2252
  const manifestFunctions = assembleManifestField(functionInfos, functions);
@@ -2243,7 +2268,7 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2243
2268
  let masterKey;
2244
2269
  if (context.production?.bundle && !skipBundle) {
2245
2270
  logger$9.log(`\n📦 Bundling production server...`);
2246
- const { bundleServer } = await Promise.resolve().then(() => require("./bundler-BG6P249p.cjs"));
2271
+ const { bundleServer } = await Promise.resolve().then(() => require("./bundler-CLOenWgi.cjs"));
2247
2272
  const allConstructs = [
2248
2273
  ...endpoints.map((e) => e.construct),
2249
2274
  ...functions.map((f) => f.construct),
@@ -2313,7 +2338,7 @@ async function workspaceBuildCommand(workspace, options) {
2313
2338
  try {
2314
2339
  const turboCommand = getTurboCommand(pm);
2315
2340
  logger$9.log(`Running: ${turboCommand}`);
2316
- await new Promise((resolve$4, reject) => {
2341
+ await new Promise((resolve$3, reject) => {
2317
2342
  const child = (0, node_child_process.spawn)(turboCommand, {
2318
2343
  shell: true,
2319
2344
  cwd: workspace.root,
@@ -2324,7 +2349,7 @@ async function workspaceBuildCommand(workspace, options) {
2324
2349
  }
2325
2350
  });
2326
2351
  child.on("close", (code) => {
2327
- if (code === 0) resolve$4();
2352
+ if (code === 0) resolve$3();
2328
2353
  else reject(new Error(`Turbo build failed with exit code ${code}`));
2329
2354
  });
2330
2355
  child.on("error", (err) => {
@@ -2341,6 +2366,7 @@ async function workspaceBuildCommand(workspace, options) {
2341
2366
  });
2342
2367
  }
2343
2368
  logger$9.log(`\n✅ Workspace build complete!`);
2369
+ await require_openapi.openapiCommand({ cwd: workspace.root });
2344
2370
  logger$9.log(`\n📋 Build Summary:`);
2345
2371
  for (const result of results) {
2346
2372
  const icon = result.type === "backend" ? "⚙️" : "🌐";
@@ -2371,7 +2397,7 @@ function getAppOutputPath(workspace, _appName, app) {
2371
2397
  * Format routes for logging, handling PartitionedRoutes.
2372
2398
  */
2373
2399
  function formatRoutes(routes) {
2374
- if (require_openapi.isPartitionedRoutes(routes)) {
2400
+ if (require_client_generator.isPartitionedRoutes(routes)) {
2375
2401
  const paths = Array.isArray(routes.paths) ? routes.paths.join(", ") : routes.paths;
2376
2402
  return `${paths} (partitioned)`;
2377
2403
  }
@@ -2569,11 +2595,11 @@ async function createDnsProvider(options) {
2569
2595
  if (isDnsProvider(config.provider)) return config.provider;
2570
2596
  const provider = config.provider;
2571
2597
  if (provider === "hostinger") {
2572
- const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-5KYmwoK2.cjs"));
2598
+ const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-C5oLa7N7.cjs"));
2573
2599
  return new HostingerProvider();
2574
2600
  }
2575
2601
  if (provider === "route53") {
2576
- const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-owQQ4pn6.cjs"));
2602
+ const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-DISZ6E8f.cjs"));
2577
2603
  const route53Config = config;
2578
2604
  return new Route53Provider({
2579
2605
  region: route53Config.region,
@@ -3123,6 +3149,7 @@ services:
3123
3149
  restart: unless-stopped
3124
3150
  environment:
3125
3151
  MP_SMTP_AUTH: \${SMTP_USER:-${imageName}}:\${SMTP_PASS:-${imageName}}
3152
+ MP_SMTP_AUTH_ALLOW_INSECURE: true
3126
3153
  ports:
3127
3154
  - "\${MAILPIT_PORT:-8025}:8025" # Web UI / API
3128
3155
  - "\${SMTP_PORT:-1025}:1025" # SMTP
@@ -3287,6 +3314,7 @@ services:
3287
3314
  restart: unless-stopped
3288
3315
  environment:
3289
3316
  MP_SMTP_AUTH: \${SMTP_USER:-${workspace.name}}:\${SMTP_PASS:-${workspace.name}}
3317
+ MP_SMTP_AUTH_ALLOW_INSECURE: true
3290
3318
  ports:
3291
3319
  - "\${MAILPIT_PORT:-8025}:8025" # Web UI / API
3292
3320
  - "\${SMTP_PORT:-1025}:1025" # SMTP
@@ -5042,20 +5070,20 @@ function isStateProvider(value) {
5042
5070
  async function createStateProvider(options) {
5043
5071
  const { config, workspaceRoot, workspaceName } = options;
5044
5072
  if (!config) {
5045
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
5073
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-DI6n11UM.cjs"));
5046
5074
  return new LocalStateProvider(workspaceRoot);
5047
5075
  }
5048
5076
  if (isStateProvider(config.provider)) return config.provider;
5049
5077
  const provider = config.provider;
5050
5078
  if (provider === "local") {
5051
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
5079
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-DI6n11UM.cjs"));
5052
5080
  return new LocalStateProvider(workspaceRoot);
5053
5081
  }
5054
5082
  if (provider === "ssm") {
5055
5083
  if (!workspaceName) throw new Error("Workspace name is required for SSM state provider. Set \"name\" in gkm.config.ts.");
5056
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
5057
- const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-CT8tjl9o.cjs"));
5058
- const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-37pG1HBx.cjs"));
5084
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-DI6n11UM.cjs"));
5085
+ const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-BljH5efc.cjs"));
5086
+ const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-3couMAQk.cjs"));
5059
5087
  const ssmConfig = config;
5060
5088
  const local = new LocalStateProvider(workspaceRoot);
5061
5089
  const ssm = SSMStateProvider.create({
@@ -5165,326 +5193,6 @@ function generateSecretsReport(encryptedApps, sniffedApps) {
5165
5193
  };
5166
5194
  }
5167
5195
 
5168
- //#endregion
5169
- //#region src/deploy/sniffer.ts
5170
- const __filename$1 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
5171
- const __dirname$1 = (0, node_path.dirname)(__filename$1);
5172
- /**
5173
- * Resolve the tsx package path from the CLI package's dependencies.
5174
- * This ensures tsx is available regardless of whether the target project has it installed.
5175
- */
5176
- function resolveTsxPath() {
5177
- const require$2 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
5178
- return require$2.resolve("tsx");
5179
- }
5180
- /**
5181
- * Resolve the path to a sniffer helper file.
5182
- * Handles both dev (.ts with tsx) and production (.mjs from dist).
5183
- *
5184
- * In production: sniffer.ts is bundled into dist/index.mjs, but sniffer helper
5185
- * files are output to dist/deploy/ as standalone modules for subprocess loading.
5186
- *
5187
- * In development: All files are in src/deploy/ and loaded via tsx.
5188
- */
5189
- function resolveSnifferFile(baseName) {
5190
- const deployMjsPath = (0, node_path.resolve)(__dirname$1, "deploy", `${baseName}.mjs`);
5191
- if ((0, node_fs.existsSync)(deployMjsPath)) return deployMjsPath;
5192
- const mjsPath = (0, node_path.resolve)(__dirname$1, `${baseName}.mjs`);
5193
- if ((0, node_fs.existsSync)(mjsPath)) return mjsPath;
5194
- const tsPath = (0, node_path.resolve)(__dirname$1, `${baseName}.ts`);
5195
- if ((0, node_fs.existsSync)(tsPath)) return tsPath;
5196
- return tsPath;
5197
- }
5198
- /**
5199
- * Get required environment variables for an app.
5200
- *
5201
- * Detection strategy (in order):
5202
- * 1. Frontend apps: Returns empty (no server secrets)
5203
- * 2. Apps with `requiredEnv`: Uses explicit list from config
5204
- * 3. Entry apps: Imports entry file in subprocess to capture config.parse() calls
5205
- * 4. Route-based apps: Loads route files and calls getEnvironment() on each construct
5206
- * 5. Apps with `envParser` (no routes): Runs SnifferEnvironmentParser to detect usage
5207
- * 6. Apps with neither: Returns empty
5208
- *
5209
- * This function handles "fire and forget" async operations gracefully,
5210
- * capturing errors and unhandled rejections without failing the build.
5211
- *
5212
- * @param app - The normalized app configuration
5213
- * @param appName - The name of the app
5214
- * @param workspacePath - Absolute path to the workspace root
5215
- * @param options - Optional configuration for sniffing behavior
5216
- * @returns The sniffed environment with required variables
5217
- */
5218
- async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5219
- const { logWarnings = true } = options;
5220
- if (app.type === "frontend") {
5221
- const depVars = (app.dependencies ?? []).map((dep) => `NEXT_PUBLIC_${dep.toUpperCase()}_URL`);
5222
- if (app.config) {
5223
- const sniffedVars = [];
5224
- const configPaths = [];
5225
- if (app.config.client) configPaths.push(app.config.client);
5226
- if (app.config.server) configPaths.push(app.config.server);
5227
- for (const configPath of configPaths) {
5228
- const result = await sniffEntryFile(configPath, app.path, workspacePath);
5229
- if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Config file "${configPath}" threw error during sniffing (env vars still captured): ${result.error.message}`);
5230
- sniffedVars.push(...result.envVars);
5231
- }
5232
- const allVars = [...new Set([...depVars, ...sniffedVars])];
5233
- return {
5234
- appName,
5235
- requiredEnvVars: allVars
5236
- };
5237
- }
5238
- return {
5239
- appName,
5240
- requiredEnvVars: depVars
5241
- };
5242
- }
5243
- if (app.entry) {
5244
- const result = await sniffEntryFile(app.entry, app.path, workspacePath);
5245
- if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Entry file threw error during sniffing (env vars still captured): ${result.error.message}`);
5246
- return {
5247
- appName,
5248
- requiredEnvVars: result.envVars
5249
- };
5250
- }
5251
- if (app.routes) {
5252
- const result = await sniffRouteFiles(require_openapi.normalizeRoutes(app.routes), app.path, workspacePath);
5253
- if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Route sniffing threw error (env vars still captured): ${result.error.message}`);
5254
- return {
5255
- appName,
5256
- requiredEnvVars: result.envVars
5257
- };
5258
- }
5259
- if (app.envParser) {
5260
- const result = await sniffEnvParser(app.envParser, app.path, workspacePath);
5261
- if (logWarnings) {
5262
- if (result.error) console.warn(`[sniffer] ${appName}: envParser threw error during sniffing (env vars still captured): ${result.error.message}`);
5263
- if (result.unhandledRejections.length > 0) console.warn(`[sniffer] ${appName}: Fire-and-forget rejections during sniffing (suppressed): ${result.unhandledRejections.map((e) => e.message).join(", ")}`);
5264
- }
5265
- return {
5266
- appName,
5267
- requiredEnvVars: result.envVars
5268
- };
5269
- }
5270
- return {
5271
- appName,
5272
- requiredEnvVars: []
5273
- };
5274
- }
5275
- /**
5276
- * Sniff an entry file by importing it in a subprocess.
5277
- *
5278
- * Entry apps call `config.parse()` at module load time. To capture which
5279
- * env vars are accessed, we:
5280
- * 1. Spawn a subprocess with a module loader hook
5281
- * 2. The loader intercepts `@geekmidas/envkit` and replaces EnvironmentParser
5282
- * with SnifferEnvironmentParser
5283
- * 3. Import the entry file (triggers config.parse())
5284
- * 4. Capture and return the accessed env var names
5285
- *
5286
- * This approach provides process isolation - each app is sniffed in its own
5287
- * subprocess, preventing module cache pollution.
5288
- *
5289
- * @param entryPath - Relative path to the entry file (e.g., './src/index.ts')
5290
- * @param appPath - The app's path relative to workspace (e.g., 'apps/auth')
5291
- * @param workspacePath - Absolute path to workspace root
5292
- * @returns EntrySniffResult with env vars and optional error
5293
- */
5294
- async function sniffEntryFile(entryPath, appPath, workspacePath) {
5295
- const fullEntryPath = (0, node_path.resolve)(workspacePath, appPath, entryPath);
5296
- const loaderPath = resolveSnifferFile("sniffer-loader");
5297
- const workerPath = resolveSnifferFile("sniffer-worker");
5298
- return new Promise((resolvePromise) => {
5299
- const child = (0, node_child_process.spawn)("node", [
5300
- "--import",
5301
- loaderPath,
5302
- workerPath,
5303
- fullEntryPath
5304
- ], {
5305
- cwd: (0, node_path.resolve)(workspacePath, appPath),
5306
- stdio: [
5307
- "ignore",
5308
- "pipe",
5309
- "pipe"
5310
- ],
5311
- env: {
5312
- ...process.env,
5313
- NODE_OPTIONS: "--import=tsx"
5314
- }
5315
- });
5316
- let stdout = "";
5317
- let stderr = "";
5318
- child.stdout.on("data", (data) => {
5319
- stdout += data.toString();
5320
- });
5321
- child.stderr.on("data", (data) => {
5322
- stderr += data.toString();
5323
- });
5324
- child.on("close", (code) => {
5325
- try {
5326
- const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
5327
- if (jsonMatch) {
5328
- const result = JSON.parse(jsonMatch[0]);
5329
- resolvePromise({
5330
- envVars: result.envVars || [],
5331
- error: result.error ? new Error(result.error) : void 0
5332
- });
5333
- return;
5334
- }
5335
- } catch {}
5336
- resolvePromise({
5337
- envVars: [],
5338
- error: new Error(`Failed to sniff entry file (exit code ${code}): ${stderr || stdout || "No output"}`)
5339
- });
5340
- });
5341
- child.on("error", (err) => {
5342
- resolvePromise({
5343
- envVars: [],
5344
- error: err
5345
- });
5346
- });
5347
- });
5348
- }
5349
- /**
5350
- * Sniff route files by loading constructs and calling getEnvironment().
5351
- *
5352
- * Route-based apps have endpoints, functions, crons, and subscribers that
5353
- * use services. Each service's register() method accesses environment variables.
5354
- *
5355
- * This runs in a subprocess with tsx loader to properly handle TypeScript
5356
- * compilation and path alias resolution (e.g., `src/...` imports).
5357
- *
5358
- * @param routes - Glob pattern(s) for route files
5359
- * @param appPath - The app's path relative to workspace (e.g., 'apps/api')
5360
- * @param workspacePath - Absolute path to workspace root
5361
- * @returns EntrySniffResult with env vars and optional error
5362
- */
5363
- async function sniffRouteFiles(routes, appPath, workspacePath) {
5364
- const fullAppPath = (0, node_path.resolve)(workspacePath, appPath);
5365
- const workerPath = resolveSnifferFile("sniffer-routes-worker");
5366
- const tsxPath = resolveTsxPath();
5367
- const routesArray = Array.isArray(routes) ? routes : [routes];
5368
- const pattern = routesArray[0];
5369
- if (!pattern) return {
5370
- envVars: [],
5371
- error: new Error("No route patterns provided")
5372
- };
5373
- return new Promise((resolvePromise) => {
5374
- const child = (0, node_child_process.spawn)("node", [
5375
- "--import",
5376
- tsxPath,
5377
- workerPath,
5378
- fullAppPath,
5379
- pattern
5380
- ], {
5381
- cwd: fullAppPath,
5382
- stdio: [
5383
- "ignore",
5384
- "pipe",
5385
- "pipe"
5386
- ],
5387
- env: { ...process.env }
5388
- });
5389
- let stdout = "";
5390
- let stderr = "";
5391
- child.stdout.on("data", (data) => {
5392
- stdout += data.toString();
5393
- });
5394
- child.stderr.on("data", (data) => {
5395
- stderr += data.toString();
5396
- });
5397
- child.on("close", (code) => {
5398
- if (stderr) stderr.split("\n").filter((line) => line.trim()).forEach((line) => console.warn(line));
5399
- try {
5400
- const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
5401
- if (jsonMatch) {
5402
- const result = JSON.parse(jsonMatch[0]);
5403
- resolvePromise({
5404
- envVars: result.envVars || [],
5405
- error: result.error ? new Error(result.error) : void 0
5406
- });
5407
- return;
5408
- }
5409
- } catch {}
5410
- resolvePromise({
5411
- envVars: [],
5412
- error: new Error(`Failed to sniff route files (exit code ${code}): ${stderr || stdout || "No output"}`)
5413
- });
5414
- });
5415
- child.on("error", (err) => {
5416
- resolvePromise({
5417
- envVars: [],
5418
- error: err
5419
- });
5420
- });
5421
- });
5422
- }
5423
- /**
5424
- * Run the SnifferEnvironmentParser on an envParser module to detect
5425
- * which environment variables it accesses.
5426
- *
5427
- * This function handles "fire and forget" async operations by using
5428
- * the shared sniffWithFireAndForget utility from @geekmidas/envkit.
5429
- *
5430
- * @param envParserPath - The envParser config (e.g., './src/config/env#envParser')
5431
- * @param appPath - The app's path relative to workspace
5432
- * @param workspacePath - Absolute path to workspace root
5433
- * @returns SniffResult with env vars and any errors encountered
5434
- */
5435
- async function sniffEnvParser(envParserPath, appPath, workspacePath) {
5436
- const [modulePath, exportName = "default"] = envParserPath.split("#");
5437
- if (!modulePath) return {
5438
- envVars: [],
5439
- unhandledRejections: []
5440
- };
5441
- const fullPath = (0, node_path.resolve)(workspacePath, appPath, modulePath);
5442
- let SnifferEnvironmentParser;
5443
- let sniffWithFireAndForget;
5444
- try {
5445
- const envkitModule = await import("@geekmidas/envkit/sniffer");
5446
- SnifferEnvironmentParser = envkitModule.SnifferEnvironmentParser;
5447
- sniffWithFireAndForget = envkitModule.sniffWithFireAndForget;
5448
- } catch (error) {
5449
- const message = error instanceof Error ? error.message : String(error);
5450
- console.warn(`[sniffer] Failed to import SnifferEnvironmentParser: ${message}`);
5451
- return {
5452
- envVars: [],
5453
- unhandledRejections: []
5454
- };
5455
- }
5456
- const sniffer = new SnifferEnvironmentParser();
5457
- return sniffWithFireAndForget(sniffer, async () => {
5458
- const moduleUrl = (0, node_url.pathToFileURL)(fullPath).href;
5459
- const module$1 = await import(moduleUrl);
5460
- const envParser = module$1[exportName];
5461
- if (typeof envParser !== "function") {
5462
- console.warn(`[sniffer] Export "${exportName}" from "${modulePath}" is not a function`);
5463
- return;
5464
- }
5465
- const result = envParser(sniffer);
5466
- if (result && typeof result.parse === "function") try {
5467
- result.parse();
5468
- } catch {}
5469
- });
5470
- }
5471
- /**
5472
- * Sniff environment requirements for multiple apps.
5473
- *
5474
- * @param apps - Map of app name to app config
5475
- * @param workspacePath - Absolute path to workspace root
5476
- * @param options - Optional configuration for sniffing behavior
5477
- * @returns Map of app name to sniffed environment
5478
- */
5479
- async function sniffAllApps(apps, workspacePath, options = {}) {
5480
- const results = /* @__PURE__ */ new Map();
5481
- for (const [appName, app] of Object.entries(apps)) {
5482
- const sniffed = await sniffAppEnvironment(app, appName, workspacePath, options);
5483
- results.set(appName, sniffed);
5484
- }
5485
- return results;
5486
- }
5487
-
5488
5196
  //#endregion
5489
5197
  //#region src/deploy/index.ts
5490
5198
  const logger$3 = console;
@@ -5495,7 +5203,7 @@ async function prompt(message, hidden = false) {
5495
5203
  if (!process.stdin.isTTY) throw new Error("Interactive input required. Please configure manually.");
5496
5204
  if (hidden) {
5497
5205
  process.stdout.write(message);
5498
- return new Promise((resolve$4) => {
5206
+ return new Promise((resolve$3) => {
5499
5207
  let value = "";
5500
5208
  const onData = (char) => {
5501
5209
  const c = char.toString();
@@ -5504,7 +5212,7 @@ async function prompt(message, hidden = false) {
5504
5212
  process.stdin.pause();
5505
5213
  process.stdin.removeListener("data", onData);
5506
5214
  process.stdout.write("\n");
5507
- resolve$4(value);
5215
+ resolve$3(value);
5508
5216
  } else if (c === "") {
5509
5217
  process.stdin.setRawMode(false);
5510
5218
  process.stdin.pause();
@@ -5979,7 +5687,7 @@ async function workspaceDeployCommand(workspace, options) {
5979
5687
  logger$3.log(` ⚠️ No secrets found for stage "${stage}"`);
5980
5688
  logger$3.log(` Run "gkm secrets:init --stage ${stage}" to create secrets`);
5981
5689
  }
5982
- const sniffedApps = await sniffAllApps(workspace.apps, workspace.root);
5690
+ const sniffedApps = await require_sniffer.sniffAllApps(workspace.apps, workspace.root);
5983
5691
  const encryptedSecrets = stageSecrets ? prepareSecretsForAllApps(stageSecrets, sniffedApps) : /* @__PURE__ */ new Map();
5984
5692
  if (stageSecrets) {
5985
5693
  const report = generateSecretsReport(encryptedSecrets, sniffedApps);
@@ -6154,7 +5862,7 @@ async function workspaceDeployCommand(workspace, options) {
6154
5862
  }
6155
5863
  if (workspace.deploy?.backups && provisionedPostgres) {
6156
5864
  logger$3.log("\n💾 Provisioning backup destination...");
6157
- const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-C4noe75O.cjs"));
5865
+ const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-CpirEvO1.cjs"));
6158
5866
  const backupState = await provisionBackupDestination({
6159
5867
  api,
6160
5868
  projectId: project.projectId,
@@ -6806,7 +6514,7 @@ const GEEKMIDAS_VERSIONS = {
6806
6514
  "@geekmidas/cache": "~1.1.0",
6807
6515
  "@geekmidas/client": "~4.0.4",
6808
6516
  "@geekmidas/cloud": "~1.0.0",
6809
- "@geekmidas/constructs": "~3.0.6",
6517
+ "@geekmidas/constructs": "~3.0.7",
6810
6518
  "@geekmidas/db": "~1.0.1",
6811
6519
  "@geekmidas/emailkit": "~1.0.0",
6812
6520
  "@geekmidas/envkit": "~1.0.4",
@@ -8068,7 +7776,7 @@ export default defineWorkspace({
8068
7776
  schema: 'zod',
8069
7777
  },
8070
7778
  },`;
8071
- if (services.db || services.cache || services.mail) {
7779
+ if (services.db || services.cache || services.mail || services.storage || services.events) {
8072
7780
  config += `
8073
7781
  services: {`;
8074
7782
  if (services.db) config += `
@@ -8077,6 +7785,10 @@ export default defineWorkspace({
8077
7785
  cache: true,`;
8078
7786
  if (services.mail) config += `
8079
7787
  mail: true,`;
7788
+ if (services.storage) config += `
7789
+ storage: true,`;
7790
+ if (services.events) config += `
7791
+ events: '${services.events}',`;
8080
7792
  config += `
8081
7793
  },`;
8082
7794
  }
@@ -11306,7 +11018,7 @@ async function initCommand(projectName, options = {}) {
11306
11018
  "mail",
11307
11019
  "storage"
11308
11020
  ] : answers.services || [];
11309
- const eventsBackend = options.yes ? isFullstack ? "pgboss" : void 0 : answers.eventsBackend;
11021
+ const eventsBackend = options.yes ? "pgboss" : answers.eventsBackend;
11310
11022
  const services = {
11311
11023
  db: servicesArray.includes("db"),
11312
11024
  cache: servicesArray.includes("cache"),
@@ -11995,7 +11707,7 @@ async function testCommand(options = {}) {
11995
11707
  });
11996
11708
  let finalCredentials = { ...result.credentials };
11997
11709
  if (result.appInfo) {
11998
- const sniffed = await sniffAppEnvironment(result.appInfo.app, result.appInfo.appName, result.appInfo.workspaceRoot, { logWarnings: false });
11710
+ const sniffed = await require_sniffer.sniffAppEnvironment(result.appInfo.app, result.appInfo.appName, result.appInfo.workspaceRoot, { logWarnings: false });
11999
11711
  if (sniffed.requiredEnvVars.length > 0) {
12000
11712
  const needed = new Set(sniffed.requiredEnvVars);
12001
11713
  const filtered = {};
@@ -12034,9 +11746,9 @@ async function testCommand(options = {}) {
12034
11746
  NODE_OPTIONS: nodeOptions
12035
11747
  }
12036
11748
  });
12037
- return new Promise((resolve$4, reject) => {
11749
+ return new Promise((resolve$3, reject) => {
12038
11750
  vitestProcess.on("close", (code) => {
12039
- if (code === 0) resolve$4();
11751
+ if (code === 0) resolve$3();
12040
11752
  else reject(new Error(`Tests failed with exit code ${code}`));
12041
11753
  });
12042
11754
  vitestProcess.on("error", (error) => {
@@ -12235,7 +11947,7 @@ program.command("setup").description("Setup development environment (secrets, Do
12235
11947
  process.exit(1);
12236
11948
  }
12237
11949
  });
12238
- program.command("build").description("Build handlers from endpoints, functions, and crons").option("--provider <provider>", "Target provider for generated handlers (aws, server)").option("--providers <providers>", "[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)").option("--enable-openapi", "Enable OpenAPI documentation generation for server builds").option("--production", "Build for production (no dev tools, bundled output)").option("--skip-bundle", "Skip bundling step in production build").option("--stage <stage>", "Inject encrypted secrets for deployment stage").action(async (options) => {
11950
+ program.command("build").description("Build handlers from endpoints, functions, and crons").option("--provider <provider>", "Target provider for generated handlers (aws, server)").option("--providers <providers>", "[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)").option("--enable-openapi", "Enable OpenAPI documentation generation for server builds").option("--production", "Build for production (no dev tools, bundled output)").option("--skip-bundle", "Skip bundling step in production build").option("--stage <stage>", "Inject encrypted secrets for deployment stage").option("--mark-optional", "Suffix optional env vars with ? in manifest envVars field (e.g. PORT?)").action(async (options) => {
12239
11951
  try {
12240
11952
  const globalOptions = program.opts();
12241
11953
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -12246,7 +11958,8 @@ program.command("build").description("Build handlers from endpoints, functions,
12246
11958
  enableOpenApi: options.enableOpenapi || false,
12247
11959
  production: options.production || false,
12248
11960
  skipBundle: options.skipBundle || false,
12249
- stage: options.stage
11961
+ stage: options.stage,
11962
+ markOptional: options.markOptional || false
12250
11963
  });
12251
11964
  } else if (options.providers) {
12252
11965
  const providerList = [...new Set(options.providers.split(",").map((p) => p.trim()))];
@@ -12255,13 +11968,15 @@ program.command("build").description("Build handlers from endpoints, functions,
12255
11968
  enableOpenApi: options.enableOpenapi || false,
12256
11969
  production: options.production || false,
12257
11970
  skipBundle: options.skipBundle || false,
12258
- stage: options.stage
11971
+ stage: options.stage,
11972
+ markOptional: options.markOptional || false
12259
11973
  });
12260
11974
  } else await buildCommand({
12261
11975
  enableOpenApi: options.enableOpenapi || false,
12262
11976
  production: options.production || false,
12263
11977
  skipBundle: options.skipBundle || false,
12264
- stage: options.stage
11978
+ stage: options.stage,
11979
+ markOptional: options.markOptional || false
12265
11980
  });
12266
11981
  } catch (error) {
12267
11982
  console.error(formatError(error));
@@ -12436,8 +12151,8 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
12436
12151
  const globalOptions = program.opts();
12437
12152
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12438
12153
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
12439
- const { pushSecrets: pushSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
12440
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
12154
+ const { pushSecrets: pushSecrets$1 } = await Promise.resolve().then(() => require("./sync-B2CN_KS5.cjs"));
12155
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-C8KIy4Uy.cjs"));
12441
12156
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
12442
12157
  const { workspace } = await loadWorkspaceConfig$1();
12443
12158
  const secrets = await readStageSecrets$1(options.stage, workspace.root);
@@ -12461,9 +12176,9 @@ program.command("secrets:pull").description("Pull secrets from remote provider (
12461
12176
  const globalOptions = program.opts();
12462
12177
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12463
12178
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
12464
- const { pullSecrets: pullSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
12179
+ const { pullSecrets: pullSecrets$1 } = await Promise.resolve().then(() => require("./sync-B2CN_KS5.cjs"));
12465
12180
  const { writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
12466
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
12181
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-C8KIy4Uy.cjs"));
12467
12182
  const { workspace } = await loadWorkspaceConfig$1();
12468
12183
  let secrets = await pullSecrets$1(options.stage, workspace);
12469
12184
  if (!secrets) {
@@ -12488,7 +12203,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
12488
12203
  const globalOptions = program.opts();
12489
12204
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12490
12205
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
12491
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
12206
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-C8KIy4Uy.cjs"));
12492
12207
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
12493
12208
  const { workspace } = await loadWorkspaceConfig$1();
12494
12209
  const secrets = await readStageSecrets$1(options.stage, workspace.root);