@geekmidas/cli 1.10.29 → 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 (138) hide show
  1. package/CHANGELOG.md +18 -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 +102 -380
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.mjs +78 -356
  67. package/dist/index.mjs.map +1 -1
  68. package/dist/{openapi-CQCoLuzh.mjs → openapi-DHq5r17U.mjs} +7 -42
  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-CBU4TEi-.cjs → openapi-w-_smBTO.cjs} +7 -54
  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 +3 -3
  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/generators/EndpointGenerator.ts +1 -1
  117. package/src/index.ts +8 -0
  118. package/src/init/generators/monorepo.ts +15 -1
  119. package/src/init/generators/package.ts +2 -0
  120. package/src/init/index.ts +2 -4
  121. package/src/init/templates/index.ts +5 -0
  122. package/src/init/versions.ts +1 -1
  123. package/src/openapi.ts +1 -35
  124. package/src/types.ts +7 -0
  125. package/src/workspace/__tests__/client-generator.spec.ts +1 -485
  126. package/src/workspace/client-generator.ts +1 -145
  127. package/src/workspace/index.ts +0 -1
  128. package/src/workspace/schema.ts +0 -9
  129. package/src/workspace/types.ts +0 -29
  130. package/dist/CachedStateProvider-CC0DyO09.mjs +0 -3
  131. package/dist/dokploy-api-BOx71j6F.cjs +0 -3
  132. package/dist/dokploy-api-BZGk-lkD.mjs +0 -3
  133. package/dist/encryption-Db2zvGqM.mjs +0 -3
  134. package/dist/index-BkibYzso.d.cts.map +0 -1
  135. package/dist/index-CY-ieuRp.d.mts.map +0 -1
  136. package/dist/openapi-CBU4TEi-.cjs.map +0 -1
  137. package/dist/openapi-CQCoLuzh.mjs.map +0 -1
  138. package/dist/sync-D1Pa30oV.cjs +0 -4
package/dist/index.mjs CHANGED
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env -S npx tsx
2
2
  import { __require } from "./chunk-Duj1WY3L.mjs";
3
- import { getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-D4z4A4cq.mjs";
4
- import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, parseModuleConfig } from "./config-jsRYHOHU.mjs";
3
+ import { getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-Bi4X7Yzy.mjs";
4
+ import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, parseModuleConfig } from "./config-B62g483e.mjs";
5
5
  import { getCredentialsPath, getDokployCredentials, getDokployRegistryId, getDokployToken, removeDokployCredentials, storeDokployCredentials, storeDokployRegistryId } from "./credentials-s1kLcIzK.mjs";
6
6
  import { createStageSecrets, generateConnectionUrls, generateDbPassword, generateDbUrl, generateFullstackCustomSecrets, generateLocalStackCredentials, generatePgBossUrl, generateSecurePassword, generateServiceCredentials, rotateServicePassword, writeDockerEnvFromSecrets } from "./fullstack-secrets-P84v8zWn.mjs";
7
7
  import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-dbb9RyBl.mjs";
8
- import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, isPartitionedRoutes, normalizeRoutes, openapiCommand, resolveOpenApiConfig } from "./openapi-CQCoLuzh.mjs";
9
- import { DokployApi } from "./dokploy-api-BIT0683o.mjs";
10
- import { encryptSecrets } from "./encryption-DSkIlEZ6.mjs";
11
- import { CachedStateProvider } from "./CachedStateProvider-C8A-cCm5.mjs";
12
- import { generateReactQueryCommand } from "./openapi-react-query-C4UdILaI.mjs";
13
- import { isSSMConfigured, pullSecrets, pushSecrets } from "./sync-D_NowTkZ.mjs";
8
+ import { isPartitionedRoutes } from "./client-generator-CUVVtAOo.mjs";
9
+ import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-DHq5r17U.mjs";
10
+ import { DokployApi } from "./dokploy-api-sfZFlWuE.mjs";
11
+ import { encryptSecrets } from "./encryption-CO5Q4Bhf.mjs";
12
+ import { sniffAllApps, sniffAppEnvironment } from "./sniffer-BqSVVrWA.mjs";
13
+ import { CachedStateProvider } from "./CachedStateProvider-CQr31ups.mjs";
14
+ import { generateReactQueryCommand } from "./openapi-react-query-COpH7Mmz.mjs";
15
+ import { isSSMConfigured, pullSecrets, pushSecrets } from "./sync-Dc-QA4Mx.mjs";
14
16
  import { createRequire } from "node:module";
15
17
  import { copyFileSync, existsSync, readFileSync, unlinkSync } from "node:fs";
16
18
  import { basename, dirname, join, parse, relative, resolve } from "node:path";
@@ -30,12 +32,11 @@ import { Function } from "@geekmidas/constructs/functions";
30
32
  import { Subscriber } from "@geekmidas/constructs/subscribers";
31
33
  import { Client } from "pg";
32
34
  import { lookup } from "node:dns/promises";
33
- import { fileURLToPath, pathToFileURL } from "node:url";
34
35
  import prompts from "prompts";
35
36
 
36
37
  //#region package.json
37
38
  var name = "@geekmidas/cli";
38
- var version = "1.10.28";
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 import("./dokploy-api-BZGk-lkD.mjs");
142
+ const { DokployApi: DokployApi$1 } = await import("./dokploy-api-BiSzWM4v.mjs");
142
143
  const api = new DokployApi$1({
143
144
  baseUrl: endpoint,
144
145
  token
@@ -2202,18 +2203,25 @@ async function buildCommand(options) {
2202
2203
  }
2203
2204
  const rootOutputDir = join(process.cwd(), ".gkm");
2204
2205
  await mkdir(rootOutputDir, { recursive: true });
2206
+ let optionalVarSet;
2207
+ if (options.markOptional && config$1.envParser) try {
2208
+ const { _sniffEnvParser } = await import("./sniffer-Cpq_cbyz.mjs");
2209
+ const sniffed = await _sniffEnvParser(config$1.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 generateOpenApi(config$1, { 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 = join(process.cwd(), ".gkm", provider);
2214
2222
  await 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 import("./bundler-c6QvGUBM.mjs");
2271
+ const { bundleServer } = await import("./bundler-E5VcXsPH.mjs");
2247
2272
  const allConstructs = [
2248
2273
  ...endpoints.map((e) => e.construct),
2249
2274
  ...functions.map((f) => f.construct),
@@ -2341,6 +2366,7 @@ async function workspaceBuildCommand(workspace, options) {
2341
2366
  });
2342
2367
  }
2343
2368
  logger$9.log(`\n✅ Workspace build complete!`);
2369
+ await 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" ? "⚙️" : "🌐";
@@ -2569,11 +2595,11 @@ async function createDnsProvider(options) {
2569
2595
  if (isDnsProvider(config$1.provider)) return config$1.provider;
2570
2596
  const provider = config$1.provider;
2571
2597
  if (provider === "hostinger") {
2572
- const { HostingerProvider } = await import("./HostingerProvider-ANWchdiK.mjs");
2598
+ const { HostingerProvider } = await import("./HostingerProvider-YvCg3Mus.mjs");
2573
2599
  return new HostingerProvider();
2574
2600
  }
2575
2601
  if (provider === "route53") {
2576
- const { Route53Provider } = await import("./Route53Provider-QoPgcXxn.mjs");
2602
+ const { Route53Provider } = await import("./Route53Provider-CYlDOrYO.mjs");
2577
2603
  const route53Config = config$1;
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: config$1, workspaceRoot, workspaceName } = options;
5044
5072
  if (!config$1) {
5045
- const { LocalStateProvider } = await import("./LocalStateProvider-Dp0KkRcw.mjs");
5073
+ const { LocalStateProvider } = await import("./LocalStateProvider-BciOhGR0.mjs");
5046
5074
  return new LocalStateProvider(workspaceRoot);
5047
5075
  }
5048
5076
  if (isStateProvider(config$1.provider)) return config$1.provider;
5049
5077
  const provider = config$1.provider;
5050
5078
  if (provider === "local") {
5051
- const { LocalStateProvider } = await import("./LocalStateProvider-Dp0KkRcw.mjs");
5079
+ const { LocalStateProvider } = await import("./LocalStateProvider-BciOhGR0.mjs");
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 import("./LocalStateProvider-Dp0KkRcw.mjs");
5057
- const { SSMStateProvider } = await import("./SSMStateProvider-CksOTB8M.mjs");
5058
- const { CachedStateProvider: CachedStateProvider$1 } = await import("./CachedStateProvider-CC0DyO09.mjs");
5084
+ const { LocalStateProvider } = await import("./LocalStateProvider-BciOhGR0.mjs");
5085
+ const { SSMStateProvider } = await import("./SSMStateProvider-DXT1dIdI.mjs");
5086
+ const { CachedStateProvider: CachedStateProvider$1 } = await import("./CachedStateProvider-C4QqvlPE.mjs");
5059
5087
  const ssmConfig = config$1;
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 = fileURLToPath(import.meta.url);
5171
- const __dirname = dirname(__filename);
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 = createRequire(import.meta.url);
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 = resolve(__dirname, "deploy", `${baseName}.mjs`);
5191
- if (existsSync(deployMjsPath)) return deployMjsPath;
5192
- const mjsPath = resolve(__dirname, `${baseName}.mjs`);
5193
- if (existsSync(mjsPath)) return mjsPath;
5194
- const tsPath = resolve(__dirname, `${baseName}.ts`);
5195
- if (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(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 = resolve(workspacePath, appPath, entryPath);
5296
- const loaderPath = resolveSnifferFile("sniffer-loader");
5297
- const workerPath = resolveSnifferFile("sniffer-worker");
5298
- return new Promise((resolvePromise) => {
5299
- const child = spawn("node", [
5300
- "--import",
5301
- loaderPath,
5302
- workerPath,
5303
- fullEntryPath
5304
- ], {
5305
- cwd: 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$1 = "";
5317
- let stderr = "";
5318
- child.stdout.on("data", (data) => {
5319
- stdout$1 += 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$1.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$1 || "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 = 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 = 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$1 = "";
5390
- let stderr = "";
5391
- child.stdout.on("data", (data) => {
5392
- stdout$1 += 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$1.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$1 || "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 = 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 = pathToFileURL(fullPath).href;
5459
- const module = await import(moduleUrl);
5460
- const envParser = module[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;
@@ -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 import("./backup-provisioner-BEXoHTuC.mjs");
5865
+ const { provisionBackupDestination } = await import("./backup-provisioner-CCUcj28C.mjs");
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.5",
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$1 += `
8073
7781
  services: {`;
8074
7782
  if (services.db) config$1 += `
@@ -8077,6 +7785,10 @@ export default defineWorkspace({
8077
7785
  cache: true,`;
8078
7786
  if (services.mail) config$1 += `
8079
7787
  mail: true,`;
7788
+ if (services.storage) config$1 += `
7789
+ storage: true,`;
7790
+ if (services.events) config$1 += `
7791
+ events: '${services.events}',`;
8080
7792
  config$1 += `
8081
7793
  },`;
8082
7794
  }
@@ -8933,6 +8645,10 @@ export const telescope = new Telescope({
8933
8645
  */
8934
8646
  const OPENAPI_OUTPUT_PATH$1 = "./.gkm/openapi.ts";
8935
8647
  /**
8648
+ * Endpoints output path (generated by gkm dev/build)
8649
+ */
8650
+ const ENDPOINTS_OUTPUT_PATH = "./.gkm/server/endpoints.ts";
8651
+ /**
8936
8652
  * All available templates
8937
8653
  */
8938
8654
  const templates = {
@@ -9132,7 +8848,10 @@ function generatePackageJson(options, template) {
9132
8848
  version: "0.0.1",
9133
8849
  private: true,
9134
8850
  type: "module",
9135
- exports: { "./client": OPENAPI_OUTPUT_PATH$1 },
8851
+ exports: {
8852
+ "./client": OPENAPI_OUTPUT_PATH$1,
8853
+ "./endpoints": ENDPOINTS_OUTPUT_PATH
8854
+ },
9136
8855
  scripts: scripts$1,
9137
8856
  dependencies: sortObject(dependencies$1),
9138
8857
  devDependencies: sortObject(devDependencies$1)
@@ -11299,7 +11018,7 @@ async function initCommand(projectName, options = {}) {
11299
11018
  "mail",
11300
11019
  "storage"
11301
11020
  ] : answers.services || [];
11302
- const eventsBackend = options.yes ? isFullstack ? "pgboss" : void 0 : answers.eventsBackend;
11021
+ const eventsBackend = options.yes ? "pgboss" : answers.eventsBackend;
11303
11022
  const services = {
11304
11023
  db: servicesArray.includes("db"),
11305
11024
  cache: servicesArray.includes("cache"),
@@ -12228,7 +11947,7 @@ program.command("setup").description("Setup development environment (secrets, Do
12228
11947
  process.exit(1);
12229
11948
  }
12230
11949
  });
12231
- 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) => {
12232
11951
  try {
12233
11952
  const globalOptions = program.opts();
12234
11953
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -12239,7 +11958,8 @@ program.command("build").description("Build handlers from endpoints, functions,
12239
11958
  enableOpenApi: options.enableOpenapi || false,
12240
11959
  production: options.production || false,
12241
11960
  skipBundle: options.skipBundle || false,
12242
- stage: options.stage
11961
+ stage: options.stage,
11962
+ markOptional: options.markOptional || false
12243
11963
  });
12244
11964
  } else if (options.providers) {
12245
11965
  const providerList = [...new Set(options.providers.split(",").map((p) => p.trim()))];
@@ -12248,13 +11968,15 @@ program.command("build").description("Build handlers from endpoints, functions,
12248
11968
  enableOpenApi: options.enableOpenapi || false,
12249
11969
  production: options.production || false,
12250
11970
  skipBundle: options.skipBundle || false,
12251
- stage: options.stage
11971
+ stage: options.stage,
11972
+ markOptional: options.markOptional || false
12252
11973
  });
12253
11974
  } else await buildCommand({
12254
11975
  enableOpenApi: options.enableOpenapi || false,
12255
11976
  production: options.production || false,
12256
11977
  skipBundle: options.skipBundle || false,
12257
- stage: options.stage
11978
+ stage: options.stage,
11979
+ markOptional: options.markOptional || false
12258
11980
  });
12259
11981
  } catch (error) {
12260
11982
  console.error(formatError(error));
@@ -12429,8 +12151,8 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
12429
12151
  const globalOptions = program.opts();
12430
12152
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12431
12153
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
12432
- const { pushSecrets: pushSecrets$1 } = await import("./sync-COnAugP-.mjs");
12433
- const { reconcileMissingSecrets } = await import("./reconcile-DAAKa0YR.mjs");
12154
+ const { pushSecrets: pushSecrets$1 } = await import("./sync-fzT5WX_y.mjs");
12155
+ const { reconcileMissingSecrets } = await import("./reconcile-D423q2QW.mjs");
12434
12156
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
12435
12157
  const { workspace } = await loadWorkspaceConfig$1();
12436
12158
  const secrets = await readStageSecrets$1(options.stage, workspace.root);
@@ -12454,9 +12176,9 @@ program.command("secrets:pull").description("Pull secrets from remote provider (
12454
12176
  const globalOptions = program.opts();
12455
12177
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12456
12178
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
12457
- const { pullSecrets: pullSecrets$1 } = await import("./sync-COnAugP-.mjs");
12179
+ const { pullSecrets: pullSecrets$1 } = await import("./sync-fzT5WX_y.mjs");
12458
12180
  const { writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
12459
- const { reconcileMissingSecrets } = await import("./reconcile-DAAKa0YR.mjs");
12181
+ const { reconcileMissingSecrets } = await import("./reconcile-D423q2QW.mjs");
12460
12182
  const { workspace } = await loadWorkspaceConfig$1();
12461
12183
  let secrets = await pullSecrets$1(options.stage, workspace);
12462
12184
  if (!secrets) {
@@ -12481,7 +12203,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
12481
12203
  const globalOptions = program.opts();
12482
12204
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
12483
12205
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
12484
- const { reconcileMissingSecrets } = await import("./reconcile-DAAKa0YR.mjs");
12206
+ const { reconcileMissingSecrets } = await import("./reconcile-D423q2QW.mjs");
12485
12207
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
12486
12208
  const { workspace } = await loadWorkspaceConfig$1();
12487
12209
  const secrets = await readStageSecrets$1(options.stage, workspace.root);