@geekmidas/cli 1.10.41 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +14 -0
  3. package/dist/{CachedStateProvider-37pG1HBx.cjs → CachedStateProvider-BdX7klRc.cjs} +1 -1
  4. package/dist/{CachedStateProvider-C8A-cCm5.mjs → CachedStateProvider-CzyFct42.mjs} +1 -1
  5. package/dist/{CachedStateProvider-C8A-cCm5.mjs.map → CachedStateProvider-CzyFct42.mjs.map} +1 -1
  6. package/dist/CachedStateProvider-GcGziXh1.mjs +3 -0
  7. package/dist/{CachedStateProvider-CxsXOKkg.cjs → CachedStateProvider-klLWZXWF.cjs} +1 -1
  8. package/dist/{CachedStateProvider-CxsXOKkg.cjs.map → CachedStateProvider-klLWZXWF.cjs.map} +1 -1
  9. package/dist/{HostingerProvider-ANWchdiK.mjs → HostingerProvider-B2ZYz7Yc.mjs} +1 -1
  10. package/dist/{HostingerProvider-ANWchdiK.mjs.map → HostingerProvider-B2ZYz7Yc.mjs.map} +1 -1
  11. package/dist/{HostingerProvider-5KYmwoK2.cjs → HostingerProvider-CrHfsgz9.cjs} +1 -1
  12. package/dist/{HostingerProvider-5KYmwoK2.cjs.map → HostingerProvider-CrHfsgz9.cjs.map} +1 -1
  13. package/dist/{LocalStateProvider-Dp0KkRcw.mjs → LocalStateProvider-CP49rjzt.mjs} +1 -1
  14. package/dist/{LocalStateProvider-Dp0KkRcw.mjs.map → LocalStateProvider-CP49rjzt.mjs.map} +1 -1
  15. package/dist/{LocalStateProvider-CLifRC0Y.cjs → LocalStateProvider-CalzNfNA.cjs} +1 -1
  16. package/dist/{LocalStateProvider-CLifRC0Y.cjs.map → LocalStateProvider-CalzNfNA.cjs.map} +1 -1
  17. package/dist/{Route53Provider-owQQ4pn6.cjs → Route53Provider-DwgXiLxt.cjs} +1 -1
  18. package/dist/{Route53Provider-owQQ4pn6.cjs.map → Route53Provider-DwgXiLxt.cjs.map} +1 -1
  19. package/dist/{Route53Provider-QoPgcXxn.mjs → Route53Provider-tlgBzrRQ.mjs} +1 -1
  20. package/dist/{Route53Provider-QoPgcXxn.mjs.map → Route53Provider-tlgBzrRQ.mjs.map} +1 -1
  21. package/dist/{SSMStateProvider-CksOTB8M.mjs → SSMStateProvider-BlrTiV5m.mjs} +1 -1
  22. package/dist/{SSMStateProvider-CksOTB8M.mjs.map → SSMStateProvider-BlrTiV5m.mjs.map} +1 -1
  23. package/dist/{SSMStateProvider-CT8tjl9o.cjs → SSMStateProvider-Bt6r8CTL.cjs} +1 -1
  24. package/dist/{SSMStateProvider-CT8tjl9o.cjs.map → SSMStateProvider-Bt6r8CTL.cjs.map} +1 -1
  25. package/dist/{backup-provisioner-C4noe75O.cjs → backup-provisioner-B3HBN-2k.cjs} +1 -1
  26. package/dist/{backup-provisioner-C4noe75O.cjs.map → backup-provisioner-B3HBN-2k.cjs.map} +1 -1
  27. package/dist/{backup-provisioner-BEXoHTuC.mjs → backup-provisioner-Xunq-p_8.mjs} +1 -1
  28. package/dist/{backup-provisioner-BEXoHTuC.mjs.map → backup-provisioner-Xunq-p_8.mjs.map} +1 -1
  29. package/dist/{bundler-c6QvGUBM.mjs → bundler-DkA4qzUD.mjs} +2 -2
  30. package/dist/{bundler-c6QvGUBM.mjs.map → bundler-DkA4qzUD.mjs.map} +1 -1
  31. package/dist/{bundler-BG6P249p.cjs → bundler-Dufq3uvI.cjs} +2 -2
  32. package/dist/{bundler-BG6P249p.cjs.map → bundler-Dufq3uvI.cjs.map} +1 -1
  33. package/dist/config.d.mts +2 -2
  34. package/dist/dokploy-api-BPYkG-ZZ.cjs +3 -0
  35. package/dist/dokploy-api-BiSzWM4v.mjs +3 -0
  36. package/dist/{dokploy-api-Dvyq-LsM.cjs → dokploy-api-CqOIKHme.cjs} +1 -1
  37. package/dist/{dokploy-api-Dvyq-LsM.cjs.map → dokploy-api-CqOIKHme.cjs.map} +1 -1
  38. package/dist/{dokploy-api-BIT0683o.mjs → dokploy-api-sfZFlWuE.mjs} +1 -1
  39. package/dist/{dokploy-api-BIT0683o.mjs.map → dokploy-api-sfZFlWuE.mjs.map} +1 -1
  40. package/dist/{encryption-CipsS0KW.cjs → encryption-BVS7Vmzs.cjs} +1 -1
  41. package/dist/encryption-Bd_m4q3g.mjs +3 -0
  42. package/dist/{encryption-DSkIlEZ6.mjs → encryption-CO5Q4Bhf.mjs} +1 -1
  43. package/dist/{encryption-DSkIlEZ6.mjs.map → encryption-CO5Q4Bhf.mjs.map} +1 -1
  44. package/dist/{encryption-DgKS-Dv9.cjs → encryption-MfXAiFTm.cjs} +1 -1
  45. package/dist/{encryption-DgKS-Dv9.cjs.map → encryption-MfXAiFTm.cjs.map} +1 -1
  46. package/dist/{index-BBvGMG_A.d.mts → index-Dx9Kk5bR.d.mts} +2 -2
  47. package/dist/{index-BBvGMG_A.d.mts.map → index-Dx9Kk5bR.d.mts.map} +1 -1
  48. package/dist/index.cjs +596 -1314
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.mjs +725 -1443
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/{openapi-DHp49UJV.cjs → openapi-CG1LBk7s.cjs} +1 -1
  53. package/dist/{openapi-DHp49UJV.cjs.map → openapi-CG1LBk7s.cjs.map} +1 -1
  54. package/dist/{openapi-DF9GyhyZ.mjs → openapi-CtRVU6RD.mjs} +1 -1
  55. package/dist/{openapi-DF9GyhyZ.mjs.map → openapi-CtRVU6RD.mjs.map} +1 -1
  56. package/dist/{openapi-react-query-C4UdILaI.mjs → openapi-react-query-C4iIvpPf.mjs} +1 -1
  57. package/dist/{openapi-react-query-C4UdILaI.mjs.map → openapi-react-query-C4iIvpPf.mjs.map} +1 -1
  58. package/dist/{openapi-react-query-DYbBq-WJ.cjs → openapi-react-query-CYWik72n.cjs} +1 -1
  59. package/dist/{openapi-react-query-DYbBq-WJ.cjs.map → openapi-react-query-CYWik72n.cjs.map} +1 -1
  60. package/dist/openapi-react-query.cjs +1 -1
  61. package/dist/openapi-react-query.mjs +1 -1
  62. package/dist/openapi.cjs +1 -1
  63. package/dist/openapi.d.mts +1 -1
  64. package/dist/openapi.mjs +1 -1
  65. package/dist/{reconcile-CYGmqXvq.mjs → reconcile-B2FoJE0a.mjs} +1 -1
  66. package/dist/{reconcile-CYGmqXvq.mjs.map → reconcile-B2FoJE0a.mjs.map} +1 -1
  67. package/dist/{reconcile-D93YG7G5.cjs → reconcile-BzqKJ2Rt.cjs} +1 -1
  68. package/dist/{reconcile-D93YG7G5.cjs.map → reconcile-BzqKJ2Rt.cjs.map} +1 -1
  69. package/dist/setup-DDXUXzzl.mjs +765 -0
  70. package/dist/setup-DDXUXzzl.mjs.map +1 -0
  71. package/dist/setup-DLwhfyt-.cjs +8 -0
  72. package/dist/setup-Dh-B7YTX.mjs +8 -0
  73. package/dist/setup-WZ-xqAQO.cjs +849 -0
  74. package/dist/setup-WZ-xqAQO.cjs.map +1 -0
  75. package/dist/{sync-COnAugP-.mjs → sync-B5UHXwRM.mjs} +1 -1
  76. package/dist/sync-BLA94rgC.cjs +4 -0
  77. package/dist/{sync-D_NowTkZ.mjs → sync-CSooqRQ8.mjs} +1 -1
  78. package/dist/{sync-D_NowTkZ.mjs.map → sync-CSooqRQ8.mjs.map} +1 -1
  79. package/dist/{sync-DGXXSk2v.cjs → sync-o_CtEbvR.cjs} +1 -1
  80. package/dist/{sync-DGXXSk2v.cjs.map → sync-o_CtEbvR.cjs.map} +1 -1
  81. package/dist/{types-OszPdw9m.d.mts → types-CqfhdmRi.d.mts} +1 -1
  82. package/dist/{types-OszPdw9m.d.mts.map → types-CqfhdmRi.d.mts.map} +1 -1
  83. package/dist/workspace/index.d.mts +2 -2
  84. package/package.json +4 -4
  85. package/src/index.ts +4 -0
  86. package/src/init/versions.ts +5 -5
  87. package/src/setup/__tests__/auto-setup.spec.ts +147 -0
  88. package/src/setup/index.ts +46 -6
  89. package/src/test/index.ts +17 -0
  90. package/dist/CachedStateProvider-CC0DyO09.mjs +0 -3
  91. package/dist/dokploy-api-BOx71j6F.cjs +0 -3
  92. package/dist/dokploy-api-BZGk-lkD.mjs +0 -3
  93. package/dist/encryption-Db2zvGqM.mjs +0 -3
  94. package/dist/sync-D1Pa30oV.cjs +0 -4
package/dist/index.cjs CHANGED
@@ -5,12 +5,13 @@ const require_config = require('./config-DujV8DbR.cjs');
5
5
  const require_credentials = require('./credentials-C8DWtnMY.cjs');
6
6
  const require_fullstack_secrets = require('./fullstack-secrets-BYzi6Hwl.cjs');
7
7
  const require_storage = require('./storage-B1wvztiJ.cjs');
8
- const require_openapi = require('./openapi-DHp49UJV.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_setup = require('./setup-WZ-xqAQO.cjs');
9
+ const require_openapi = require('./openapi-CG1LBk7s.cjs');
10
+ const require_dokploy_api = require('./dokploy-api-CqOIKHme.cjs');
11
+ const require_encryption = require('./encryption-MfXAiFTm.cjs');
12
+ const require_CachedStateProvider = require('./CachedStateProvider-klLWZXWF.cjs');
13
+ const require_openapi_react_query = require('./openapi-react-query-CYWik72n.cjs');
14
+ require('./sync-o_CtEbvR.cjs');
14
15
  const node_fs = require_chunk.__toESM(require("node:fs"));
15
16
  const node_path = require_chunk.__toESM(require("node:path"));
16
17
  const commander = require_chunk.__toESM(require("commander"));
@@ -20,8 +21,6 @@ const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
20
21
  const node_child_process = require_chunk.__toESM(require("node:child_process"));
21
22
  const chokidar = require_chunk.__toESM(require("chokidar"));
22
23
  const fast_glob = require_chunk.__toESM(require("fast-glob"));
23
- const node_net = require_chunk.__toESM(require("node:net"));
24
- const dotenv = require_chunk.__toESM(require("dotenv"));
25
24
  const yaml = require_chunk.__toESM(require("yaml"));
26
25
  const node_crypto = require_chunk.__toESM(require("node:crypto"));
27
26
  const __geekmidas_constructs_crons = require_chunk.__toESM(require("@geekmidas/constructs/crons"));
@@ -35,7 +34,7 @@ const prompts = require_chunk.__toESM(require("prompts"));
35
34
 
36
35
  //#region package.json
37
36
  var name = "@geekmidas/cli";
38
- var version = "1.10.40";
37
+ var version = "1.10.41";
39
38
  var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
40
39
  var private$1 = false;
41
40
  var type = "module";
@@ -158,12 +157,12 @@ var package_default = {
158
157
 
159
158
  //#endregion
160
159
  //#region src/auth/index.ts
161
- const logger$14 = console;
160
+ const logger$12 = console;
162
161
  /**
163
162
  * Validate Dokploy token by making a test API call
164
163
  */
165
164
  async function validateDokployToken(endpoint, token) {
166
- const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-BOx71j6F.cjs"));
165
+ const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-BPYkG-ZZ.cjs"));
167
166
  const api = new DokployApi$1({
168
167
  baseUrl: endpoint,
169
168
  token
@@ -177,7 +176,7 @@ async function prompt$1(message, hidden = false) {
177
176
  if (!process.stdin.isTTY) throw new Error("Interactive input required. Please provide --token option.");
178
177
  if (hidden) {
179
178
  process.stdout.write(message);
180
- return new Promise((resolve$4, reject) => {
179
+ return new Promise((resolve$3, reject) => {
181
180
  let value = "";
182
181
  const cleanup = () => {
183
182
  process.stdin.setRawMode(false);
@@ -194,7 +193,7 @@ async function prompt$1(message, hidden = false) {
194
193
  if (c === "\n" || c === "\r") {
195
194
  cleanup();
196
195
  process.stdout.write("\n");
197
- resolve$4(value);
196
+ resolve$3(value);
198
197
  } else if (c === "") {
199
198
  cleanup();
200
199
  process.stdout.write("\n");
@@ -226,36 +225,36 @@ async function prompt$1(message, hidden = false) {
226
225
  async function loginCommand(options) {
227
226
  const { service, token: providedToken, endpoint: providedEndpoint } = options;
228
227
  if (service === "dokploy") {
229
- logger$14.log("\n🔐 Logging in to Dokploy...\n");
228
+ logger$12.log("\n🔐 Logging in to Dokploy...\n");
230
229
  let endpoint = providedEndpoint;
231
230
  if (!endpoint) endpoint = await prompt$1("Dokploy URL (e.g., https://dokploy.example.com): ");
232
231
  endpoint = endpoint.replace(/\/$/, "");
233
232
  try {
234
233
  new URL(endpoint);
235
234
  } catch {
236
- logger$14.error("Invalid URL format");
235
+ logger$12.error("Invalid URL format");
237
236
  process.exit(1);
238
237
  }
239
238
  let token = providedToken;
240
239
  if (!token) {
241
- logger$14.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
240
+ logger$12.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
242
241
  token = await prompt$1("API Token: ", true);
243
242
  }
244
243
  if (!token) {
245
- logger$14.error("Token is required");
244
+ logger$12.error("Token is required");
246
245
  process.exit(1);
247
246
  }
248
- logger$14.log("\nValidating credentials...");
247
+ logger$12.log("\nValidating credentials...");
249
248
  const isValid = await validateDokployToken(endpoint, token);
250
249
  if (!isValid) {
251
- logger$14.error("\n✗ Invalid credentials. Please check your token and try again.");
250
+ logger$12.error("\n✗ Invalid credentials. Please check your token and try again.");
252
251
  process.exit(1);
253
252
  }
254
253
  await require_credentials.storeDokployCredentials(token, endpoint);
255
- logger$14.log("\n✓ Successfully logged in to Dokploy!");
256
- logger$14.log(` Endpoint: ${endpoint}`);
257
- logger$14.log(` Credentials stored in: ${require_credentials.getCredentialsPath()}`);
258
- logger$14.log("\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.");
254
+ logger$12.log("\n✓ Successfully logged in to Dokploy!");
255
+ logger$12.log(` Endpoint: ${endpoint}`);
256
+ logger$12.log(` Credentials stored in: ${require_credentials.getCredentialsPath()}`);
257
+ logger$12.log("\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.");
259
258
  }
260
259
  }
261
260
  /**
@@ -265,28 +264,28 @@ async function logoutCommand(options) {
265
264
  const { service = "dokploy" } = options;
266
265
  if (service === "all") {
267
266
  const dokployRemoved = await require_credentials.removeDokployCredentials();
268
- if (dokployRemoved) logger$14.log("\n✓ Logged out from all services");
269
- else logger$14.log("\nNo stored credentials found");
267
+ if (dokployRemoved) logger$12.log("\n✓ Logged out from all services");
268
+ else logger$12.log("\nNo stored credentials found");
270
269
  return;
271
270
  }
272
271
  if (service === "dokploy") {
273
272
  const removed = await require_credentials.removeDokployCredentials();
274
- if (removed) logger$14.log("\n✓ Logged out from Dokploy");
275
- else logger$14.log("\nNo Dokploy credentials found");
273
+ if (removed) logger$12.log("\n✓ Logged out from Dokploy");
274
+ else logger$12.log("\nNo Dokploy credentials found");
276
275
  }
277
276
  }
278
277
  /**
279
278
  * Show current login status
280
279
  */
281
280
  async function whoamiCommand() {
282
- logger$14.log("\n📋 Current credentials:\n");
281
+ logger$12.log("\n📋 Current credentials:\n");
283
282
  const dokploy = await require_credentials.getDokployCredentials();
284
283
  if (dokploy) {
285
- logger$14.log(" Dokploy:");
286
- logger$14.log(` Endpoint: ${dokploy.endpoint}`);
287
- logger$14.log(` Token: ${maskToken(dokploy.token)}`);
288
- } else logger$14.log(" Dokploy: Not logged in");
289
- logger$14.log(`\n Credentials file: ${require_credentials.getCredentialsPath()}`);
284
+ logger$12.log(" Dokploy:");
285
+ logger$12.log(` Endpoint: ${dokploy.endpoint}`);
286
+ logger$12.log(` Token: ${maskToken(dokploy.token)}`);
287
+ } else logger$12.log(" Dokploy: Not logged in");
288
+ logger$12.log(`\n Credentials file: ${require_credentials.getCredentialsPath()}`);
290
289
  }
291
290
  /**
292
291
  * Mask a token for display
@@ -367,477 +366,12 @@ function isEnabled(config) {
367
366
  return config.enabled !== false;
368
367
  }
369
368
 
370
- //#endregion
371
- //#region src/credentials/index.ts
372
- const logger$13 = console;
373
- /**
374
- * Load environment files
375
- * @internal Exported for testing
376
- */
377
- function loadEnvFiles(envConfig, cwd = process.cwd()) {
378
- const loaded = [];
379
- const missing = [];
380
- const envFiles = envConfig ? Array.isArray(envConfig) ? envConfig : [envConfig] : [".env"];
381
- for (const envFile of envFiles) {
382
- const envPath = (0, node_path.resolve)(cwd, envFile);
383
- if ((0, node_fs.existsSync)(envPath)) {
384
- (0, dotenv.config)({
385
- path: envPath,
386
- override: true,
387
- quiet: true
388
- });
389
- loaded.push(envFile);
390
- } else if (envConfig) missing.push(envFile);
391
- }
392
- return {
393
- loaded,
394
- missing
395
- };
396
- }
397
- /**
398
- * Check if a port is available
399
- * @internal Exported for testing
400
- */
401
- async function isPortAvailable(port) {
402
- return new Promise((resolve$4) => {
403
- const server = (0, node_net.createServer)();
404
- server.once("error", (err) => {
405
- if (err.code === "EADDRINUSE") resolve$4(false);
406
- else resolve$4(false);
407
- });
408
- server.once("listening", () => {
409
- server.close();
410
- resolve$4(true);
411
- });
412
- server.listen(port);
413
- });
414
- }
415
- /**
416
- * Find an available port starting from the preferred port
417
- * @internal Exported for testing
418
- */
419
- async function findAvailablePort(preferredPort, maxAttempts = 10) {
420
- for (let i = 0; i < maxAttempts; i++) {
421
- const port = preferredPort + i;
422
- if (await isPortAvailable(port)) return port;
423
- logger$13.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
424
- }
425
- throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
426
- }
427
- const PORT_STATE_PATH = ".gkm/ports.json";
428
- /**
429
- * Parse docker-compose.yml and extract all port mappings that use env var interpolation.
430
- * Entries like `'${POSTGRES_HOST_PORT:-5432}:5432'` are captured.
431
- * Fixed port mappings like `'5050:80'` are skipped.
432
- * @internal Exported for testing
433
- */
434
- function parseComposePortMappings(composePath) {
435
- if (!(0, node_fs.existsSync)(composePath)) return [];
436
- const content = (0, node_fs.readFileSync)(composePath, "utf-8");
437
- const compose = (0, yaml.parse)(content);
438
- if (!compose?.services) return [];
439
- const results = [];
440
- for (const [serviceName, serviceConfig] of Object.entries(compose.services)) for (const portMapping of serviceConfig?.ports ?? []) {
441
- const match = String(portMapping).match(/\$\{(\w+):-(\d+)\}:(\d+)/);
442
- if (match?.[1] && match[2] && match[3]) results.push({
443
- service: serviceName,
444
- envVar: match[1],
445
- defaultPort: Number(match[2]),
446
- containerPort: Number(match[3])
447
- });
448
- }
449
- return results;
450
- }
451
- /**
452
- * Load saved port state from .gkm/ports.json.
453
- * @internal Exported for testing
454
- */
455
- async function loadPortState(workspaceRoot) {
456
- try {
457
- const raw = await (0, node_fs_promises.readFile)((0, node_path.join)(workspaceRoot, PORT_STATE_PATH), "utf-8");
458
- return JSON.parse(raw);
459
- } catch {
460
- return {};
461
- }
462
- }
463
- /**
464
- * Save port state to .gkm/ports.json.
465
- * @internal Exported for testing
466
- */
467
- async function savePortState(workspaceRoot, ports) {
468
- const dir = (0, node_path.join)(workspaceRoot, ".gkm");
469
- await (0, node_fs_promises.mkdir)(dir, { recursive: true });
470
- await (0, node_fs_promises.writeFile)((0, node_path.join)(workspaceRoot, PORT_STATE_PATH), `${JSON.stringify(ports, null, 2)}\n`);
471
- }
472
- /**
473
- * Check if a project's own Docker container is running and return its host port.
474
- * Uses `docker compose port` scoped to the project's compose file.
475
- * @internal Exported for testing
476
- */
477
- function getContainerHostPort(workspaceRoot, service, containerPort) {
478
- try {
479
- const result = (0, node_child_process.execSync)(`docker compose port ${service} ${containerPort}`, {
480
- cwd: workspaceRoot,
481
- stdio: "pipe"
482
- }).toString().trim();
483
- const match = result.match(/:(\d+)$/);
484
- return match ? Number(match[1]) : null;
485
- } catch {
486
- return null;
487
- }
488
- }
489
- /**
490
- * Resolve host ports for Docker services by parsing docker-compose.yml.
491
- * Priority: running container → saved state → find available port.
492
- * Persists resolved ports to .gkm/ports.json.
493
- * @internal Exported for testing
494
- */
495
- async function resolveServicePorts(workspaceRoot) {
496
- const composePath = (0, node_path.join)(workspaceRoot, "docker-compose.yml");
497
- const mappings = parseComposePortMappings(composePath);
498
- if (mappings.length === 0) return {
499
- dockerEnv: {},
500
- ports: {},
501
- mappings: []
502
- };
503
- const savedState = await loadPortState(workspaceRoot);
504
- const dockerEnv = {};
505
- const ports = {};
506
- const assignedPorts = /* @__PURE__ */ new Set();
507
- logger$13.log("\n🔌 Resolving service ports...");
508
- for (const mapping of mappings) {
509
- const containerPort = getContainerHostPort(workspaceRoot, mapping.service, mapping.containerPort);
510
- if (containerPort !== null) {
511
- ports[mapping.envVar] = containerPort;
512
- dockerEnv[mapping.envVar] = String(containerPort);
513
- assignedPorts.add(containerPort);
514
- logger$13.log(` 🔄 ${mapping.service}:${mapping.containerPort}: reusing existing container on port ${containerPort}`);
515
- continue;
516
- }
517
- const savedPort = savedState[mapping.envVar];
518
- if (savedPort && !assignedPorts.has(savedPort) && await isPortAvailable(savedPort)) {
519
- ports[mapping.envVar] = savedPort;
520
- dockerEnv[mapping.envVar] = String(savedPort);
521
- assignedPorts.add(savedPort);
522
- logger$13.log(` 💾 ${mapping.service}:${mapping.containerPort}: using saved port ${savedPort}`);
523
- continue;
524
- }
525
- let resolvedPort = await findAvailablePort(mapping.defaultPort);
526
- while (assignedPorts.has(resolvedPort)) resolvedPort = await findAvailablePort(resolvedPort + 1);
527
- ports[mapping.envVar] = resolvedPort;
528
- dockerEnv[mapping.envVar] = String(resolvedPort);
529
- assignedPorts.add(resolvedPort);
530
- if (resolvedPort !== mapping.defaultPort) logger$13.log(` ⚡ ${mapping.service}:${mapping.containerPort}: port ${mapping.defaultPort} occupied, using port ${resolvedPort}`);
531
- else logger$13.log(` ✅ ${mapping.service}:${mapping.containerPort}: using default port ${resolvedPort}`);
532
- }
533
- await savePortState(workspaceRoot, ports);
534
- return {
535
- dockerEnv,
536
- ports,
537
- mappings
538
- };
539
- }
540
- /**
541
- * Replace a port in a URL string.
542
- * Handles both `hostname:port` and `localhost:port` patterns.
543
- * @internal Exported for testing
544
- */
545
- function replacePortInUrl(url, oldPort, newPort) {
546
- if (oldPort === newPort) return url;
547
- let result = url.replace(new RegExp(`:${oldPort}(?=[/?#]|$)`, "g"), `:${newPort}`);
548
- result = result.replace(new RegExp(`%3A${oldPort}(?=[%/?#&]|$)`, "gi"), `%3A${newPort}`);
549
- return result;
550
- }
551
- /**
552
- * Rewrite connection URLs and port vars in secrets with resolved ports.
553
- * Uses the parsed compose mappings to determine which default ports to replace.
554
- * Pure transform — does not modify secrets on disk.
555
- * @internal Exported for testing
556
- */
557
- function rewriteUrlsWithPorts(secrets, resolvedPorts) {
558
- const { ports, mappings } = resolvedPorts;
559
- const result = { ...secrets };
560
- const portReplacements = [];
561
- const serviceNames = /* @__PURE__ */ new Set();
562
- for (const mapping of mappings) {
563
- serviceNames.add(mapping.service);
564
- const resolved = ports[mapping.envVar];
565
- if (resolved !== void 0) portReplacements.push({
566
- defaultPort: mapping.defaultPort,
567
- resolvedPort: resolved
568
- });
569
- }
570
- for (const [key, value] of Object.entries(result)) {
571
- if (!key.endsWith("_HOST")) continue;
572
- if (serviceNames.has(value)) result[key] = "localhost";
573
- }
574
- for (const [key, value] of Object.entries(result)) {
575
- if (!key.endsWith("_PORT")) continue;
576
- for (const { defaultPort, resolvedPort } of portReplacements) if (value === String(defaultPort)) result[key] = String(resolvedPort);
577
- }
578
- for (const [key, value] of Object.entries(result)) {
579
- if (!key.endsWith("_URL") && !key.endsWith("_ENDPOINT") && !key.endsWith("_CONNECTION_STRING") && key !== "DATABASE_URL") continue;
580
- let rewritten = value;
581
- for (const name$1 of serviceNames) rewritten = rewritten.replace(new RegExp(`@${name$1}:`, "g"), "@localhost:");
582
- for (const { defaultPort, resolvedPort } of portReplacements) rewritten = replacePortInUrl(rewritten, defaultPort, resolvedPort);
583
- result[key] = rewritten;
584
- }
585
- return result;
586
- }
587
- /**
588
- * Build the environment variables to pass to `docker compose up`.
589
- * Merges process.env, secrets, and port mappings so that Docker Compose
590
- * can interpolate variables like ${POSTGRES_USER} correctly.
591
- * @internal Exported for testing
592
- */
593
- function buildDockerComposeEnv(secretsEnv, portEnv) {
594
- return {
595
- ...process.env,
596
- ...secretsEnv,
597
- ...portEnv
598
- };
599
- }
600
- /**
601
- * Parse all service names from a docker-compose.yml file.
602
- * @internal Exported for testing
603
- */
604
- function parseComposeServiceNames(composePath) {
605
- if (!(0, node_fs.existsSync)(composePath)) return [];
606
- const content = (0, node_fs.readFileSync)(composePath, "utf-8");
607
- const compose = (0, yaml.parse)(content);
608
- return Object.keys(compose?.services ?? {});
609
- }
610
- /**
611
- * Start docker-compose services for a single-app project (no workspace config).
612
- * Starts all services defined in docker-compose.yml.
613
- */
614
- async function startComposeServices(cwd, portEnv, secretsEnv) {
615
- const composeFile = (0, node_path.join)(cwd, "docker-compose.yml");
616
- if (!(0, node_fs.existsSync)(composeFile)) return;
617
- const servicesToStart = parseComposeServiceNames(composeFile);
618
- if (servicesToStart.length === 0) return;
619
- logger$13.log(`🐳 Starting services: ${servicesToStart.join(", ")}`);
620
- try {
621
- (0, node_child_process.execSync)(`docker compose up -d ${servicesToStart.join(" ")}`, {
622
- cwd,
623
- stdio: "inherit",
624
- env: buildDockerComposeEnv(secretsEnv, portEnv)
625
- });
626
- logger$13.log("✅ Services started");
627
- } catch (error) {
628
- logger$13.error("❌ Failed to start services:", error.message);
629
- throw error;
630
- }
631
- }
632
- /**
633
- * Start docker-compose services for a workspace.
634
- * Discovers all services from docker-compose.yml and starts everything
635
- * except app services (which are managed by turbo).
636
- * @internal Exported for testing
637
- */
638
- async function startWorkspaceServices(workspace, portEnv, secretsEnv) {
639
- const composeFile = (0, node_path.join)(workspace.root, "docker-compose.yml");
640
- if (!(0, node_fs.existsSync)(composeFile)) return;
641
- const allServices = parseComposeServiceNames(composeFile);
642
- const appNames = new Set(Object.keys(workspace.apps));
643
- const servicesToStart = allServices.filter((name$1) => !appNames.has(name$1));
644
- if (servicesToStart.length === 0) return;
645
- logger$13.log(`🐳 Starting services: ${servicesToStart.join(", ")}`);
646
- try {
647
- (0, node_child_process.execSync)(`docker compose up -d ${servicesToStart.join(" ")}`, {
648
- cwd: workspace.root,
649
- stdio: "inherit",
650
- env: buildDockerComposeEnv(secretsEnv, portEnv)
651
- });
652
- logger$13.log("✅ Services started");
653
- } catch (error) {
654
- logger$13.error("❌ Failed to start services:", error.message);
655
- throw error;
656
- }
657
- }
658
- /**
659
- * Load and flatten secrets for an app from encrypted storage.
660
- * For workspace app: maps {APP}_DATABASE_URL → DATABASE_URL.
661
- * @internal Exported for testing
662
- */
663
- async function loadSecretsForApp(secretsRoot, appName, stages = ["dev", "development"]) {
664
- let secrets = {};
665
- for (const stage of stages) if (require_storage.secretsExist(stage, secretsRoot)) {
666
- const stageSecrets = await require_storage.readStageSecrets(stage, secretsRoot);
667
- if (stageSecrets) {
668
- logger$13.log(`🔐 Loading secrets from stage: ${stage}`);
669
- secrets = require_storage.toEmbeddableSecrets(stageSecrets);
670
- break;
671
- }
672
- }
673
- if (Object.keys(secrets).length === 0) return {};
674
- if (!appName) return secrets;
675
- const prefix = appName.toUpperCase();
676
- const mapped = { ...secrets };
677
- const appDbUrl = secrets[`${prefix}_DATABASE_URL`];
678
- if (appDbUrl) mapped.DATABASE_URL = appDbUrl;
679
- return mapped;
680
- }
681
- /**
682
- * Walk up the directory tree to find the root containing .gkm/secrets/.
683
- * @internal Exported for testing
684
- */
685
- function findSecretsRoot(startDir) {
686
- let dir = startDir;
687
- while (dir !== "/") {
688
- if ((0, node_fs.existsSync)((0, node_path.join)(dir, ".gkm", "secrets"))) return dir;
689
- const parent = (0, node_path.dirname)(dir);
690
- if (parent === dir) break;
691
- dir = parent;
692
- }
693
- return startDir;
694
- }
695
- /**
696
- * Generate the credentials injection code snippet.
697
- * This is the common logic used by both entry wrapper and exec preload.
698
- * @internal
699
- */
700
- function generateCredentialsInjection(secretsJsonPath) {
701
- return `import { existsSync, readFileSync } from 'node:fs';
702
-
703
- // Inject dev secrets via globalThis and process.env
704
- // Using globalThis.__gkm_credentials__ avoids CJS/ESM interop issues where
705
- // Object.assign on the Credentials export only mutates one module copy.
706
- const secretsPath = '${secretsJsonPath}';
707
- if (existsSync(secretsPath)) {
708
- const secrets = JSON.parse(readFileSync(secretsPath, 'utf-8'));
709
- globalThis.__gkm_credentials__ = secrets;
710
- Object.assign(process.env, secrets);
711
- }
712
- `;
713
- }
714
- /**
715
- * Create a preload script that injects secrets into Credentials.
716
- * Used by `gkm exec` to inject secrets before running any command.
717
- * @internal Exported for testing
718
- */
719
- async function createCredentialsPreload(preloadPath, secretsJsonPath) {
720
- const content = `/**
721
- * Credentials preload generated by 'gkm exec'
722
- * This file is loaded via NODE_OPTIONS="--import <path>"
723
- */
724
- ${generateCredentialsInjection(secretsJsonPath)}`;
725
- await (0, node_fs_promises.writeFile)(preloadPath, content);
726
- }
727
- /**
728
- * Create a wrapper script that injects secrets before importing the entry file.
729
- * @internal Exported for testing
730
- */
731
- async function createEntryWrapper(wrapperPath, entryPath, secretsJsonPath) {
732
- const credentialsInjection = secretsJsonPath ? `${generateCredentialsInjection(secretsJsonPath)}
733
- ` : "";
734
- const content = `#!/usr/bin/env node
735
- /**
736
- * Entry wrapper generated by 'gkm dev --entry'
737
- */
738
- ${credentialsInjection}// Import and run the user's entry file (dynamic import ensures secrets load first)
739
- await import('${entryPath}');
740
- `;
741
- await (0, node_fs_promises.writeFile)(wrapperPath, content);
742
- }
743
- /**
744
- * Prepare credentials for dev/exec/test modes.
745
- * Loads workspace config, secrets, resolves Docker ports, rewrites URLs,
746
- * injects PORT, dependency URLs, and writes credentials JSON.
747
- *
748
- * @param options.resolveDockerPorts - How to resolve Docker ports:
749
- * - `'full'` (default): probe running containers, saved state, then find available ports. Used by dev/test.
750
- * - `'readonly'`: check running containers and saved state only, never probe for new ports. Used by exec.
751
- * @param options.stages - Secret stages to try, in order. Default: ['dev', 'development'].
752
- * @param options.startDocker - Start Docker Compose services after port resolution. Default: false.
753
- * @param options.secretsFileName - Custom secrets JSON filename. Default: 'dev-secrets-{appName}.json' or 'dev-secrets.json'.
754
- * @internal Exported for testing
755
- */
756
- async function prepareEntryCredentials(options) {
757
- const cwd = options.cwd ?? process.cwd();
758
- const portMode = options.resolveDockerPorts ?? "full";
759
- let workspaceAppPort;
760
- let secretsRoot = cwd;
761
- let appName;
762
- let appInfo;
763
- try {
764
- appInfo = await require_config.loadWorkspaceAppInfo(cwd);
765
- workspaceAppPort = appInfo.app.port;
766
- secretsRoot = appInfo.workspaceRoot;
767
- appName = appInfo.appName;
768
- } catch {
769
- secretsRoot = findSecretsRoot(cwd);
770
- appName = require_config.getAppNameFromCwd(cwd) ?? void 0;
771
- }
772
- const resolvedPort = options.explicitPort ?? workspaceAppPort ?? 3e3;
773
- const credentials = await loadSecretsForApp(secretsRoot, appName, options.stages);
774
- credentials.PORT = String(resolvedPort);
775
- const composePath = (0, node_path.join)(secretsRoot, "docker-compose.yml");
776
- const mappings = parseComposePortMappings(composePath);
777
- if (mappings.length > 0) {
778
- let resolvedPorts;
779
- if (portMode === "full") resolvedPorts = await resolveServicePorts(secretsRoot);
780
- else {
781
- const savedPorts = await loadPortState(secretsRoot);
782
- const ports = {};
783
- for (const mapping of mappings) {
784
- const containerPort = getContainerHostPort(secretsRoot, mapping.service, mapping.containerPort);
785
- if (containerPort !== null) ports[mapping.envVar] = containerPort;
786
- else {
787
- const saved = savedPorts[mapping.envVar];
788
- if (saved !== void 0) ports[mapping.envVar] = saved;
789
- }
790
- }
791
- resolvedPorts = {
792
- dockerEnv: {},
793
- ports,
794
- mappings
795
- };
796
- }
797
- if (options.startDocker) if (appInfo) await startWorkspaceServices(appInfo.workspace, resolvedPorts.dockerEnv, credentials);
798
- else await startComposeServices(secretsRoot, resolvedPorts.dockerEnv, credentials);
799
- if (Object.keys(resolvedPorts.ports).length > 0) {
800
- const rewritten = rewriteUrlsWithPorts(credentials, resolvedPorts);
801
- Object.assign(credentials, rewritten);
802
- logger$13.log(`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`);
803
- }
804
- }
805
- if (appInfo?.appName) {
806
- const depEnv = require_workspace.getDependencyEnvVars(appInfo.workspace, appInfo.appName);
807
- Object.assign(credentials, depEnv);
808
- }
809
- if (!credentials.EVENT_PUBLISHER_CONNECTION_STRING && !credentials.EVENT_SUBSCRIBER_CONNECTION_STRING && credentials.PGBOSS_DB_USER) {
810
- const pgbossUrl = require_fullstack_secrets.generatePgBossUrl({
811
- username: credentials.PGBOSS_DB_USER,
812
- password: credentials.PGBOSS_DB_PASSWORD ?? "",
813
- host: credentials.POSTGRES_HOST ?? "localhost",
814
- port: Number(credentials.POSTGRES_PORT ?? "5432"),
815
- database: credentials.POSTGRES_DB ?? "app"
816
- });
817
- credentials.EVENT_PUBLISHER_CONNECTION_STRING = pgbossUrl;
818
- credentials.EVENT_SUBSCRIBER_CONNECTION_STRING = pgbossUrl;
819
- }
820
- const secretsDir = (0, node_path.join)(secretsRoot, ".gkm");
821
- await (0, node_fs_promises.mkdir)(secretsDir, { recursive: true });
822
- const secretsFileName = options.secretsFileName ?? (appName ? `dev-secrets-${appName}.json` : "dev-secrets.json");
823
- const secretsJsonPath = (0, node_path.join)(secretsDir, secretsFileName);
824
- await (0, node_fs_promises.writeFile)(secretsJsonPath, JSON.stringify(credentials, null, 2));
825
- return {
826
- credentials,
827
- resolvedPort,
828
- secretsJsonPath,
829
- appName,
830
- secretsRoot,
831
- appInfo
832
- };
833
- }
834
-
835
369
  //#endregion
836
370
  //#region src/generators/CronGenerator.ts
837
371
  var CronGenerator = class extends require_openapi.ConstructGenerator {
838
372
  async build(context, constructs, outputDir, options) {
839
373
  const provider = options?.provider || "aws-lambda";
840
- const logger$15 = console;
374
+ const logger$13 = console;
841
375
  const cronInfos = [];
842
376
  if (constructs.length === 0 || provider !== "aws-lambda") return cronInfos;
843
377
  const cronsDir = (0, node_path.join)(outputDir, "crons");
@@ -852,7 +386,7 @@ var CronGenerator = class extends require_openapi.ConstructGenerator {
852
386
  memorySize: construct.memorySize,
853
387
  environment: await construct.getEnvironment({ markOptional: context.markOptional })
854
388
  });
855
- logger$15.log(`Generated cron handler: ${key}`);
389
+ logger$13.log(`Generated cron handler: ${key}`);
856
390
  }
857
391
  return cronInfos;
858
392
  }
@@ -888,7 +422,7 @@ var FunctionGenerator = class extends require_openapi.ConstructGenerator {
888
422
  }
889
423
  async build(context, constructs, outputDir, options) {
890
424
  const provider = options?.provider || "aws-lambda";
891
- const logger$15 = console;
425
+ const logger$13 = console;
892
426
  const functionInfos = [];
893
427
  if (constructs.length === 0 || provider !== "aws-lambda") return functionInfos;
894
428
  const functionsDir = (0, node_path.join)(outputDir, "functions");
@@ -902,7 +436,7 @@ var FunctionGenerator = class extends require_openapi.ConstructGenerator {
902
436
  memorySize: construct.memorySize,
903
437
  environment: await construct.getEnvironment({ markOptional: context.markOptional })
904
438
  });
905
- logger$15.log(`Generated function handler: ${key}`);
439
+ logger$13.log(`Generated function handler: ${key}`);
906
440
  }
907
441
  return functionInfos;
908
442
  }
@@ -935,11 +469,11 @@ var SubscriberGenerator = class extends require_openapi.ConstructGenerator {
935
469
  }
936
470
  async build(context, constructs, outputDir, options) {
937
471
  const provider = options?.provider || "aws-lambda";
938
- const logger$15 = console;
472
+ const logger$13 = console;
939
473
  const subscriberInfos = [];
940
474
  if (provider === "server") {
941
475
  await this.generateServerSubscribersFile(outputDir, constructs);
942
- logger$15.log(`Generated server subscribers file with ${constructs.length} subscribers (polling mode)`);
476
+ logger$13.log(`Generated server subscribers file with ${constructs.length} subscribers (polling mode)`);
943
477
  return subscriberInfos;
944
478
  }
945
479
  if (constructs.length === 0) return subscriberInfos;
@@ -956,7 +490,7 @@ var SubscriberGenerator = class extends require_openapi.ConstructGenerator {
956
490
  memorySize: construct.memorySize,
957
491
  environment: await construct.getEnvironment({ markOptional: context.markOptional })
958
492
  });
959
- logger$15.log(`Generated subscriber handler: ${key}`);
493
+ logger$13.log(`Generated subscriber handler: ${key}`);
960
494
  }
961
495
  return subscriberInfos;
962
496
  }
@@ -1122,7 +656,7 @@ export async function setupSubscribers(
1122
656
 
1123
657
  //#endregion
1124
658
  //#region src/exec/index.ts
1125
- const logger$12 = console;
659
+ const logger$11 = console;
1126
660
  /**
1127
661
  * Run a command with secrets injected into Credentials.
1128
662
  * Uses Node's --import flag to preload a script that populates Credentials
@@ -1137,22 +671,22 @@ const logger$12 = console;
1137
671
  async function execCommand(commandArgs, options = {}) {
1138
672
  const cwd = options.cwd ?? process.cwd();
1139
673
  if (commandArgs.length === 0) throw new Error("No command specified. Usage: gkm exec -- <command>");
1140
- const defaultEnv = loadEnvFiles(".env");
1141
- if (defaultEnv.loaded.length > 0) logger$12.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
1142
- const { credentials, secretsJsonPath, appName } = await prepareEntryCredentials({
674
+ const defaultEnv = require_setup.loadEnvFiles(".env");
675
+ if (defaultEnv.loaded.length > 0) logger$11.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
676
+ const { credentials, secretsJsonPath, appName } = await require_setup.prepareEntryCredentials({
1143
677
  cwd,
1144
678
  resolveDockerPorts: "readonly"
1145
679
  });
1146
- if (appName) logger$12.log(`📦 App: ${appName}`);
680
+ if (appName) logger$11.log(`📦 App: ${appName}`);
1147
681
  const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
1148
- if (secretCount > 0) logger$12.log(`🔐 Loaded ${secretCount} secret(s)`);
682
+ if (secretCount > 0) logger$11.log(`🔐 Loaded ${secretCount} secret(s)`);
1149
683
  const preloadDir = (0, node_path.join)(cwd, ".gkm");
1150
684
  await (0, node_fs_promises.mkdir)(preloadDir, { recursive: true });
1151
685
  const preloadPath = (0, node_path.join)(preloadDir, "credentials-preload.mjs");
1152
- await createCredentialsPreload(preloadPath, secretsJsonPath);
686
+ await require_setup.createCredentialsPreload(preloadPath, secretsJsonPath);
1153
687
  const [cmd, ...args] = commandArgs;
1154
688
  if (!cmd) throw new Error("No command specified");
1155
- logger$12.log(`🚀 Running: ${[cmd, ...args].join(" ")}`);
689
+ logger$11.log(`🚀 Running: ${[cmd, ...args].join(" ")}`);
1156
690
  const existingNodeOptions = (process.env.NODE_OPTIONS ?? "").replace(/--import[= ]\S+/g, "").trim();
1157
691
  const preloadImport = `--import=${preloadPath}`;
1158
692
  const nodeOptions = [existingNodeOptions, preloadImport].filter(Boolean).join(" ");
@@ -1165,11 +699,11 @@ async function execCommand(commandArgs, options = {}) {
1165
699
  NODE_OPTIONS: nodeOptions
1166
700
  }
1167
701
  });
1168
- const exitCode = await new Promise((resolve$4) => {
1169
- child.on("close", (code) => resolve$4(code ?? 0));
702
+ const exitCode = await new Promise((resolve$3) => {
703
+ child.on("close", (code) => resolve$3(code ?? 0));
1170
704
  child.on("error", (error) => {
1171
- logger$12.error(`Failed to run command: ${error.message}`);
1172
- resolve$4(1);
705
+ logger$11.error(`Failed to run command: ${error.message}`);
706
+ resolve$3(1);
1173
707
  });
1174
708
  });
1175
709
  if (exitCode !== 0) process.exit(exitCode);
@@ -1177,7 +711,7 @@ async function execCommand(commandArgs, options = {}) {
1177
711
 
1178
712
  //#endregion
1179
713
  //#region src/dev/index.ts
1180
- const logger$11 = console;
714
+ const logger$10 = console;
1181
715
  /**
1182
716
  * Normalize telescope configuration
1183
717
  * @internal Exported for testing
@@ -1274,8 +808,8 @@ function getProductionConfigFromGkm(config) {
1274
808
  }
1275
809
  async function devCommand(options) {
1276
810
  if (options.entry) return entryDevCommand(options);
1277
- const defaultEnv = loadEnvFiles(".env");
1278
- if (defaultEnv.loaded.length > 0) logger$11.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
811
+ const defaultEnv = require_setup.loadEnvFiles(".env");
812
+ if (defaultEnv.loaded.length > 0) logger$10.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
1279
813
  const appName = require_config.getAppNameFromCwd();
1280
814
  let config;
1281
815
  let appRoot = process.cwd();
@@ -1291,9 +825,9 @@ async function devCommand(options) {
1291
825
  workspaceAppName = appConfig.appName;
1292
826
  workspaceAppPort = appConfig.app.port;
1293
827
  workspace = appConfig.workspace;
1294
- logger$11.log(`📦 Running app: ${appConfig.appName} on port ${workspaceAppPort}`);
828
+ logger$10.log(`📦 Running app: ${appConfig.appName} on port ${workspaceAppPort}`);
1295
829
  if (appConfig.app.entry) {
1296
- logger$11.log(`📄 Using entry point: ${appConfig.app.entry}`);
830
+ logger$10.log(`📄 Using entry point: ${appConfig.app.entry}`);
1297
831
  return entryDevCommand({
1298
832
  ...options,
1299
833
  entry: appConfig.app.entry,
@@ -1304,7 +838,7 @@ async function devCommand(options) {
1304
838
  } catch {
1305
839
  const loadedConfig = await require_config.loadWorkspaceConfig();
1306
840
  if (loadedConfig.type === "workspace") {
1307
- logger$11.log("📦 Detected workspace configuration");
841
+ logger$10.log("📦 Detected workspace configuration");
1308
842
  return workspaceDevCommand(loadedConfig.workspace, options);
1309
843
  }
1310
844
  config = loadedConfig.raw;
@@ -1312,34 +846,34 @@ async function devCommand(options) {
1312
846
  else {
1313
847
  const loadedConfig = await require_config.loadWorkspaceConfig();
1314
848
  if (loadedConfig.type === "workspace") {
1315
- logger$11.log("📦 Detected workspace configuration");
849
+ logger$10.log("📦 Detected workspace configuration");
1316
850
  return workspaceDevCommand(loadedConfig.workspace, options);
1317
851
  }
1318
852
  config = loadedConfig.raw;
1319
853
  }
1320
854
  if (config.env) {
1321
- const { loaded, missing } = loadEnvFiles(config.env, appRoot);
1322
- if (loaded.length > 0) logger$11.log(`📦 Loaded env: ${loaded.join(", ")}`);
1323
- if (missing.length > 0) logger$11.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
855
+ const { loaded, missing } = require_setup.loadEnvFiles(config.env, appRoot);
856
+ if (loaded.length > 0) logger$10.log(`📦 Loaded env: ${loaded.join(", ")}`);
857
+ if (missing.length > 0) logger$10.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
1324
858
  }
1325
859
  const resolved = resolveProviders(config, { provider: "server" });
1326
- logger$11.log("🚀 Starting development server...");
1327
- logger$11.log(`Loading routes from: ${config.routes}`);
1328
- if (config.functions) logger$11.log(`Loading functions from: ${config.functions}`);
1329
- if (config.crons) logger$11.log(`Loading crons from: ${config.crons}`);
1330
- if (config.subscribers) logger$11.log(`Loading subscribers from: ${config.subscribers}`);
1331
- logger$11.log(`Using envParser: ${config.envParser}`);
860
+ logger$10.log("🚀 Starting development server...");
861
+ logger$10.log(`Loading routes from: ${config.routes}`);
862
+ if (config.functions) logger$10.log(`Loading functions from: ${config.functions}`);
863
+ if (config.crons) logger$10.log(`Loading crons from: ${config.crons}`);
864
+ if (config.subscribers) logger$10.log(`Loading subscribers from: ${config.subscribers}`);
865
+ logger$10.log(`Using envParser: ${config.envParser}`);
1332
866
  const { path: envParserPath, importPattern: envParserImportPattern } = require_config.parseModuleConfig(config.envParser, "envParser");
1333
867
  const { path: loggerPath, importPattern: loggerImportPattern } = require_config.parseModuleConfig(config.logger, "logger");
1334
868
  const telescope = normalizeTelescopeConfig(config.telescope);
1335
- if (telescope) logger$11.log(`🔭 Telescope enabled at ${telescope.path}`);
869
+ if (telescope) logger$10.log(`🔭 Telescope enabled at ${telescope.path}`);
1336
870
  const studio = normalizeStudioConfig(config.studio);
1337
- if (studio) logger$11.log(`🗄️ Studio enabled at ${studio.path}`);
871
+ if (studio) logger$10.log(`🗄️ Studio enabled at ${studio.path}`);
1338
872
  const hooks = normalizeHooksConfig(config.hooks, appRoot);
1339
- if (hooks) logger$11.log(`🪝 Server hooks enabled from ${config.hooks?.server}`);
873
+ if (hooks) logger$10.log(`🪝 Server hooks enabled from ${config.hooks?.server}`);
1340
874
  const openApiConfig = require_openapi.resolveOpenApiConfig(config);
1341
875
  const enableOpenApi = openApiConfig.enabled || resolved.enableOpenApi;
1342
- if (enableOpenApi) logger$11.log(`📄 OpenAPI output: ${require_openapi.OPENAPI_OUTPUT_PATH}`);
876
+ if (enableOpenApi) logger$10.log(`📄 OpenAPI output: ${require_openapi.OPENAPI_OUTPUT_PATH}`);
1343
877
  const buildContext = {
1344
878
  envParserPath,
1345
879
  envParserImportPattern,
@@ -1353,12 +887,12 @@ async function devCommand(options) {
1353
887
  if (enableOpenApi) await require_openapi.generateOpenApi(config);
1354
888
  const runtime = config.runtime ?? "node";
1355
889
  let secretsJsonPath;
1356
- const appSecrets = await loadSecretsForApp(secretsRoot, workspaceAppName);
1357
- const resolvedPorts = await resolveServicePorts(secretsRoot);
890
+ const appSecrets = await require_setup.loadSecretsForApp(secretsRoot, workspaceAppName);
891
+ const resolvedPorts = await require_setup.resolveServicePorts(secretsRoot);
1358
892
  if (Object.keys(resolvedPorts.ports).length > 0) {
1359
- const rewritten = rewriteUrlsWithPorts(appSecrets, resolvedPorts);
893
+ const rewritten = require_setup.rewriteUrlsWithPorts(appSecrets, resolvedPorts);
1360
894
  Object.assign(appSecrets, rewritten);
1361
- logger$11.log(`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`);
895
+ logger$10.log(`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`);
1362
896
  }
1363
897
  if (workspace && workspaceAppName) {
1364
898
  const depEnv = require_workspace.getDependencyEnvVars(workspace, workspaceAppName);
@@ -1370,7 +904,7 @@ async function devCommand(options) {
1370
904
  const secretsFileName = workspaceAppName ? `dev-secrets-${workspaceAppName}.json` : "dev-secrets.json";
1371
905
  secretsJsonPath = (0, node_path.join)(secretsDir, secretsFileName);
1372
906
  await (0, node_fs_promises.writeFile)(secretsJsonPath, JSON.stringify(appSecrets, null, 2));
1373
- logger$11.log(`🔐 Loaded ${Object.keys(appSecrets).length} secret(s)`);
907
+ logger$10.log(`🔐 Loaded ${Object.keys(appSecrets).length} secret(s)`);
1374
908
  }
1375
909
  const devServer = new DevServer(resolved.providers[0], options.port ?? workspaceAppPort ?? 3e3, options.portExplicit ?? false, enableOpenApi, telescope, studio, runtime, appRoot, secretsJsonPath);
1376
910
  await devServer.start();
@@ -1388,7 +922,7 @@ async function devCommand(options) {
1388
922
  ...hooksFile ? [hooksFile.endsWith(".ts") ? hooksFile : `${hooksFile}.ts`] : []
1389
923
  ].flat().filter((p) => typeof p === "string");
1390
924
  const normalizedPatterns = watchPatterns.map((p) => p.startsWith("./") ? p.slice(2) : p);
1391
- logger$11.log(`👀 Watching for changes in: ${normalizedPatterns.join(", ")}`);
925
+ logger$10.log(`👀 Watching for changes in: ${normalizedPatterns.join(", ")}`);
1392
926
  const resolvedFiles = await (0, fast_glob.default)(normalizedPatterns, {
1393
927
  cwd: appRoot,
1394
928
  absolute: false,
@@ -1398,7 +932,7 @@ async function devCommand(options) {
1398
932
  const parts = f.split("/");
1399
933
  return parts.slice(0, -1).join("/");
1400
934
  }))];
1401
- logger$11.log(`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`);
935
+ logger$10.log(`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`);
1402
936
  const watcher = chokidar.default.watch([...resolvedFiles, ...dirsToWatch], {
1403
937
  ignored: /(^|[/\\])\../,
1404
938
  persistent: true,
@@ -1406,29 +940,29 @@ async function devCommand(options) {
1406
940
  cwd: appRoot
1407
941
  });
1408
942
  watcher.on("ready", () => {
1409
- logger$11.log("🔍 File watcher ready");
943
+ logger$10.log("🔍 File watcher ready");
1410
944
  });
1411
945
  watcher.on("error", (error) => {
1412
- logger$11.error("❌ Watcher error:", error);
946
+ logger$10.error("❌ Watcher error:", error);
1413
947
  });
1414
948
  let rebuildTimeout = null;
1415
949
  watcher.on("change", async (path) => {
1416
- logger$11.log(`📝 File changed: ${path}`);
950
+ logger$10.log(`📝 File changed: ${path}`);
1417
951
  if (rebuildTimeout) clearTimeout(rebuildTimeout);
1418
952
  rebuildTimeout = setTimeout(async () => {
1419
953
  try {
1420
- logger$11.log("🔄 Rebuilding...");
954
+ logger$10.log("🔄 Rebuilding...");
1421
955
  await buildServer(config, buildContext, resolved.providers[0], enableOpenApi, appRoot, true);
1422
956
  if (enableOpenApi) await require_openapi.generateOpenApi(config, {
1423
957
  silent: true,
1424
958
  bustCache: true
1425
959
  });
1426
- logger$11.log("✅ Rebuild complete, restarting server...");
960
+ logger$10.log("✅ Rebuild complete, restarting server...");
1427
961
  await devServer.restart();
1428
962
  } catch (error) {
1429
963
  const err = error;
1430
- logger$11.error(`❌ Rebuild failed: ${err.message}`);
1431
- if (err.stack) logger$11.error(err.stack);
964
+ logger$10.error(`❌ Rebuild failed: ${err.message}`);
965
+ if (err.stack) logger$10.error(err.stack);
1432
966
  }
1433
967
  }, 300);
1434
968
  });
@@ -1436,9 +970,9 @@ async function devCommand(options) {
1436
970
  const shutdown = () => {
1437
971
  if (isShuttingDown) return;
1438
972
  isShuttingDown = true;
1439
- logger$11.log("\n🛑 Shutting down...");
973
+ logger$10.log("\n🛑 Shutting down...");
1440
974
  Promise.all([watcher.close(), devServer.stop()]).catch((err) => {
1441
- logger$11.error("Error during shutdown:", err);
975
+ logger$10.error("Error during shutdown:", err);
1442
976
  }).finally(() => {
1443
977
  process.exit(0);
1444
978
  });
@@ -1637,11 +1171,11 @@ async function loadDevSecrets(workspace) {
1637
1171
  for (const stage of stages) if (require_storage.secretsExist(stage, workspace.root)) {
1638
1172
  const secrets = await require_storage.readStageSecrets(stage, workspace.root);
1639
1173
  if (secrets) {
1640
- logger$11.log(`🔐 Loading secrets from stage: ${stage}`);
1174
+ logger$10.log(`🔐 Loading secrets from stage: ${stage}`);
1641
1175
  return require_storage.toEmbeddableSecrets(secrets);
1642
1176
  }
1643
1177
  }
1644
- logger$11.warn("⚠️ Secrets enabled but no dev/development secrets found. Run \"gkm setup\" to initialize your development environment");
1178
+ logger$10.warn("⚠️ Secrets enabled but no dev/development secrets found. Run \"gkm setup\" to initialize your development environment");
1645
1179
  return {};
1646
1180
  }
1647
1181
  /**
@@ -1658,39 +1192,39 @@ async function workspaceDevCommand(workspace, options) {
1658
1192
  const backendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "backend");
1659
1193
  const frontendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "web");
1660
1194
  const mobileApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "mobile");
1661
- logger$11.log(`\n🚀 Starting workspace: ${workspace.name}`);
1195
+ logger$10.log(`\n🚀 Starting workspace: ${workspace.name}`);
1662
1196
  const counts = [`${backendApps.length} backend`, `${frontendApps.length} web`];
1663
1197
  if (mobileApps.length > 0) counts.push(`${mobileApps.length} mobile`);
1664
- logger$11.log(` ${counts.join(", ")} app(s)`);
1198
+ logger$10.log(` ${counts.join(", ")} app(s)`);
1665
1199
  const conflicts = checkPortConflicts(workspace);
1666
1200
  if (conflicts.length > 0) {
1667
- for (const conflict of conflicts) logger$11.error(`❌ Port conflict: Apps "${conflict.app1}" and "${conflict.app2}" both use port ${conflict.port}`);
1201
+ for (const conflict of conflicts) logger$10.error(`❌ Port conflict: Apps "${conflict.app1}" and "${conflict.app2}" both use port ${conflict.port}`);
1668
1202
  throw new Error("Port conflicts detected. Please assign unique ports to each app.");
1669
1203
  }
1670
1204
  if (frontendApps.length > 0) {
1671
- logger$11.log("\n🔍 Validating frontend apps...");
1205
+ logger$10.log("\n🔍 Validating frontend apps...");
1672
1206
  const validationResults = await validateFrontendApps(workspace);
1673
1207
  let hasErrors = false;
1674
1208
  for (const result of validationResults) {
1675
1209
  if (!result.valid) {
1676
1210
  hasErrors = true;
1677
- logger$11.error(`\n❌ Frontend app "${result.appName}" validation failed:`);
1678
- for (const error of result.errors) logger$11.error(` • ${error}`);
1211
+ logger$10.error(`\n❌ Frontend app "${result.appName}" validation failed:`);
1212
+ for (const error of result.errors) logger$10.error(` • ${error}`);
1679
1213
  }
1680
- for (const warning of result.warnings) logger$11.warn(` ⚠️ ${result.appName}: ${warning}`);
1214
+ for (const warning of result.warnings) logger$10.warn(` ⚠️ ${result.appName}: ${warning}`);
1681
1215
  }
1682
1216
  if (hasErrors) throw new Error("Frontend app validation failed. Fix the issues above and try again.");
1683
- logger$11.log("✅ Frontend apps validated");
1217
+ logger$10.log("✅ Frontend apps validated");
1684
1218
  }
1685
- const resolvedPorts = await resolveServicePorts(workspace.root);
1219
+ const resolvedPorts = await require_setup.resolveServicePorts(workspace.root);
1686
1220
  const rawSecrets = await loadDevSecrets(workspace);
1687
- await startWorkspaceServices(workspace, resolvedPorts.dockerEnv, rawSecrets);
1688
- const secretsEnv = rewriteUrlsWithPorts(rawSecrets, resolvedPorts);
1689
- if (Object.keys(secretsEnv).length > 0) logger$11.log(` Loaded ${Object.keys(secretsEnv).length} secret(s)`);
1221
+ await require_setup.startWorkspaceServices(workspace, resolvedPorts.dockerEnv, rawSecrets);
1222
+ const secretsEnv = require_setup.rewriteUrlsWithPorts(rawSecrets, resolvedPorts);
1223
+ if (Object.keys(secretsEnv).length > 0) logger$10.log(` Loaded ${Object.keys(secretsEnv).length} secret(s)`);
1690
1224
  const dependencyEnv = generateAllDependencyEnvVars(workspace);
1691
1225
  if (Object.keys(dependencyEnv).length > 0) {
1692
- logger$11.log("📡 Dependency URLs:");
1693
- for (const [key, value] of Object.entries(dependencyEnv)) logger$11.log(` ${key}=${value}`);
1226
+ logger$10.log("📡 Dependency URLs:");
1227
+ for (const [key, value] of Object.entries(dependencyEnv)) logger$10.log(` ${key}=${value}`);
1694
1228
  }
1695
1229
  let turboFilter = [];
1696
1230
  if (options.app) {
@@ -1699,19 +1233,19 @@ async function workspaceDevCommand(workspace, options) {
1699
1233
  throw new Error(`App "${options.app}" not found. Available apps: ${appNames}`);
1700
1234
  }
1701
1235
  turboFilter = ["--filter", options.app];
1702
- logger$11.log(`\n🎯 Running single app: ${options.app}`);
1236
+ logger$10.log(`\n🎯 Running single app: ${options.app}`);
1703
1237
  } else if (options.filter) {
1704
1238
  turboFilter = ["--filter", options.filter];
1705
- logger$11.log(`\n🔍 Using filter: ${options.filter}`);
1706
- } else logger$11.log(`\n🎯 Running all ${appCount} apps`);
1239
+ logger$10.log(`\n🔍 Using filter: ${options.filter}`);
1240
+ } else logger$10.log(`\n🎯 Running all ${appCount} apps`);
1707
1241
  const buildOrder = require_workspace.getAppBuildOrder(workspace);
1708
- logger$11.log("\n📋 Apps (in dependency order):");
1242
+ logger$10.log("\n📋 Apps (in dependency order):");
1709
1243
  for (const appName of buildOrder) {
1710
1244
  const app = workspace.apps[appName];
1711
1245
  if (!app) continue;
1712
1246
  const deps = app.dependencies.length > 0 ? ` (depends on: ${app.dependencies.join(", ")})` : "";
1713
1247
  const icon = app.type === "backend" ? "🔧" : app.type === "mobile" ? "📱" : "🌐";
1714
- logger$11.log(` ${icon} ${appName} → http://localhost:${app.port}${deps}`);
1248
+ logger$10.log(` ${icon} ${appName} → http://localhost:${app.port}${deps}`);
1715
1249
  }
1716
1250
  const configFiles = [
1717
1251
  "gkm.config.ts",
@@ -1733,7 +1267,7 @@ async function workspaceDevCommand(workspace, options) {
1733
1267
  NODE_ENV: "development",
1734
1268
  ...configPath ? { GKM_CONFIG_PATH: configPath } : {}
1735
1269
  };
1736
- logger$11.log("\n🏃 Starting turbo run dev...\n");
1270
+ logger$10.log("\n🏃 Starting turbo run dev...\n");
1737
1271
  const turboProcess = (0, node_child_process.spawn)("pnpm", [
1738
1272
  "turbo",
1739
1273
  "run",
@@ -1749,7 +1283,7 @@ async function workspaceDevCommand(workspace, options) {
1749
1283
  const shutdown = () => {
1750
1284
  if (isShuttingDown) return;
1751
1285
  isShuttingDown = true;
1752
- logger$11.log("\n🛑 Shutting down workspace...");
1286
+ logger$10.log("\n🛑 Shutting down workspace...");
1753
1287
  const pid = turboProcess.pid;
1754
1288
  if (pid) try {
1755
1289
  process.kill(-pid, "SIGTERM");
@@ -1771,14 +1305,14 @@ async function workspaceDevCommand(workspace, options) {
1771
1305
  };
1772
1306
  process.on("SIGINT", shutdown);
1773
1307
  process.on("SIGTERM", shutdown);
1774
- return new Promise((resolve$4, reject) => {
1308
+ return new Promise((resolve$3, reject) => {
1775
1309
  turboProcess.on("error", (error) => {
1776
- logger$11.error("❌ Turbo error:", error);
1310
+ logger$10.error("❌ Turbo error:", error);
1777
1311
  reject(error);
1778
1312
  });
1779
1313
  turboProcess.on("exit", (code) => {
1780
1314
  if (code !== null && code !== 0) reject(new Error(`Turbo exited with code ${code}`));
1781
- else resolve$4();
1315
+ else resolve$3();
1782
1316
  });
1783
1317
  });
1784
1318
  }
@@ -1814,23 +1348,23 @@ async function entryDevCommand(options) {
1814
1348
  if (!entry) throw new Error("--entry requires a file path");
1815
1349
  const entryPath = (0, node_path.resolve)(process.cwd(), entry);
1816
1350
  if (!(0, node_fs.existsSync)(entryPath)) throw new Error(`Entry file not found: ${entryPath}`);
1817
- const defaultEnv = loadEnvFiles(".env");
1818
- if (defaultEnv.loaded.length > 0) logger$11.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
1819
- const { credentials, resolvedPort, secretsJsonPath, appName } = await prepareEntryCredentials({ explicitPort: options.portExplicit ? options.port : void 0 });
1820
- if (appName) logger$11.log(`📦 App: ${appName} (port ${resolvedPort})`);
1821
- logger$11.log(`🚀 Starting entry file: ${entry} on port ${resolvedPort}`);
1822
- if (Object.keys(credentials).length > 1) logger$11.log(`🔐 Loaded ${Object.keys(credentials).length - 1} secret(s) + PORT`);
1351
+ const defaultEnv = require_setup.loadEnvFiles(".env");
1352
+ if (defaultEnv.loaded.length > 0) logger$10.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
1353
+ const { credentials, resolvedPort, secretsJsonPath, appName } = await require_setup.prepareEntryCredentials({ explicitPort: options.portExplicit ? options.port : void 0 });
1354
+ if (appName) logger$10.log(`📦 App: ${appName} (port ${resolvedPort})`);
1355
+ logger$10.log(`🚀 Starting entry file: ${entry} on port ${resolvedPort}`);
1356
+ if (Object.keys(credentials).length > 1) logger$10.log(`🔐 Loaded ${Object.keys(credentials).length - 1} secret(s) + PORT`);
1823
1357
  const wrapperDir = (0, node_path.join)(process.cwd(), ".gkm");
1824
1358
  await (0, node_fs_promises.mkdir)(wrapperDir, { recursive: true });
1825
1359
  const wrapperPath = (0, node_path.join)(wrapperDir, "entry-wrapper.ts");
1826
- await createEntryWrapper(wrapperPath, entryPath, secretsJsonPath);
1360
+ await require_setup.createEntryWrapper(wrapperPath, entryPath, secretsJsonPath);
1827
1361
  const runner = new EntryRunner(wrapperPath, entryPath, watch, resolvedPort);
1828
1362
  await runner.start();
1829
1363
  let isShuttingDown = false;
1830
1364
  const shutdown = () => {
1831
1365
  if (isShuttingDown) return;
1832
1366
  isShuttingDown = true;
1833
- logger$11.log("\n🛑 Shutting down...");
1367
+ logger$10.log("\n🛑 Shutting down...");
1834
1368
  runner.stop();
1835
1369
  process.exit(0);
1836
1370
  };
@@ -1862,14 +1396,14 @@ var EntryRunner = class {
1862
1396
  });
1863
1397
  let restartTimeout = null;
1864
1398
  this.watcher.on("change", (path) => {
1865
- logger$11.log(`📝 File changed: ${path}`);
1399
+ logger$10.log(`📝 File changed: ${path}`);
1866
1400
  if (restartTimeout) clearTimeout(restartTimeout);
1867
1401
  restartTimeout = setTimeout(async () => {
1868
- logger$11.log("🔄 Restarting...");
1402
+ logger$10.log("🔄 Restarting...");
1869
1403
  await this.restart();
1870
1404
  }, 300);
1871
1405
  });
1872
- logger$11.log(`👀 Watching for changes in: ${watchDir}`);
1406
+ logger$10.log(`👀 Watching for changes in: ${watchDir}`);
1873
1407
  }
1874
1408
  }
1875
1409
  async runProcess() {
@@ -1884,22 +1418,22 @@ var EntryRunner = class {
1884
1418
  });
1885
1419
  this.isRunning = true;
1886
1420
  this.childProcess.on("error", (error) => {
1887
- logger$11.error("❌ Process error:", error);
1421
+ logger$10.error("❌ Process error:", error);
1888
1422
  });
1889
1423
  this.childProcess.on("exit", (code) => {
1890
- if (code !== null && code !== 0 && code !== 143) logger$11.error(`❌ Process exited with code ${code}`);
1424
+ if (code !== null && code !== 0 && code !== 143) logger$10.error(`❌ Process exited with code ${code}`);
1891
1425
  this.isRunning = false;
1892
1426
  });
1893
- await new Promise((resolve$4) => setTimeout(resolve$4, 500));
1427
+ await new Promise((resolve$3) => setTimeout(resolve$3, 500));
1894
1428
  if (this.isRunning) {
1895
- logger$11.log("");
1896
- logger$11.log(` \x1b[32m✓ Ready\x1b[0m at \x1b[36mhttp://localhost:${this.port}\x1b[0m`);
1897
- logger$11.log("");
1429
+ logger$10.log("");
1430
+ logger$10.log(` \x1b[32m✓ Ready\x1b[0m at \x1b[36mhttp://localhost:${this.port}\x1b[0m`);
1431
+ logger$10.log("");
1898
1432
  }
1899
1433
  }
1900
1434
  async restart() {
1901
1435
  this.stopProcess();
1902
- await new Promise((resolve$4) => setTimeout(resolve$4, 500));
1436
+ await new Promise((resolve$3) => setTimeout(resolve$3, 500));
1903
1437
  await this.runProcess();
1904
1438
  }
1905
1439
  stop() {
@@ -2003,16 +1537,16 @@ var DevServer = class {
2003
1537
  this.startTime = Date.now();
2004
1538
  if (this.isRunning) await this.stop();
2005
1539
  if (this.portExplicit) {
2006
- const available = await isPortAvailable(this.requestedPort);
1540
+ const available = await require_setup.isPortAvailable(this.requestedPort);
2007
1541
  if (!available) throw new Error(`Port ${this.requestedPort} is already in use. Either stop the process using that port or omit -p/--port to auto-select an available port.`);
2008
1542
  this.actualPort = this.requestedPort;
2009
1543
  } else {
2010
- this.actualPort = await findAvailablePort(this.requestedPort);
2011
- if (this.actualPort !== this.requestedPort) logger$11.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
1544
+ this.actualPort = await require_setup.findAvailablePort(this.requestedPort);
1545
+ if (this.actualPort !== this.requestedPort) logger$10.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
2012
1546
  }
2013
1547
  const serverEntryPath = (0, node_path.join)(this.appRoot, ".gkm", this.provider, "server.ts");
2014
1548
  await this.createServerEntry();
2015
- logger$11.log(`\n⏳ Starting server...`);
1549
+ logger$10.log(`\n⏳ Starting server...`);
2016
1550
  this.serverProcess = (0, node_child_process.spawn)("npx", [
2017
1551
  "tsx",
2018
1552
  serverEntryPath,
@@ -2028,13 +1562,13 @@ var DevServer = class {
2028
1562
  });
2029
1563
  this.isRunning = true;
2030
1564
  this.serverProcess.on("error", (error) => {
2031
- logger$11.error("❌ Server error:", error);
1565
+ logger$10.error("❌ Server error:", error);
2032
1566
  });
2033
1567
  this.serverProcess.on("exit", (code, signal) => {
2034
- if (code !== null && code !== 0 && signal !== "SIGTERM") logger$11.error(`❌ Server exited with code ${code}`);
1568
+ if (code !== null && code !== 0 && signal !== "SIGTERM") logger$10.error(`❌ Server exited with code ${code}`);
2035
1569
  this.isRunning = false;
2036
1570
  });
2037
- await new Promise((resolve$4) => setTimeout(resolve$4, 1e3));
1571
+ await new Promise((resolve$3) => setTimeout(resolve$3, 1e3));
2038
1572
  if (this.isRunning) {
2039
1573
  const base = `http://localhost:${this.actualPort}`;
2040
1574
  const lines = [` Local: ${base}`];
@@ -2044,13 +1578,13 @@ var DevServer = class {
2044
1578
  const maxLen = Math.max(...lines.map((l) => l.length));
2045
1579
  const pad = (s) => s.padEnd(maxLen);
2046
1580
  const border = "─".repeat(maxLen + 2);
2047
- logger$11.log("");
2048
- logger$11.log(` \x1b[32m✓ Ready\x1b[0m in ${((Date.now() - this.startTime) / 1e3).toFixed(1)}s`);
2049
- logger$11.log("");
2050
- logger$11.log(` ┌${border}┐`);
2051
- for (const line of lines) logger$11.log(` │ ${pad(line)} │`);
2052
- logger$11.log(` └${border}┘`);
2053
- logger$11.log("");
1581
+ logger$10.log("");
1582
+ logger$10.log(` \x1b[32m✓ Ready\x1b[0m in ${((Date.now() - this.startTime) / 1e3).toFixed(1)}s`);
1583
+ logger$10.log("");
1584
+ logger$10.log(` ┌${border}┐`);
1585
+ for (const line of lines) logger$10.log(` │ ${pad(line)} │`);
1586
+ logger$10.log(` └${border}┘`);
1587
+ logger$10.log("");
2054
1588
  }
2055
1589
  }
2056
1590
  async stop() {
@@ -2079,8 +1613,8 @@ var DevServer = class {
2079
1613
  await this.stop();
2080
1614
  let attempts = 0;
2081
1615
  while (attempts < 30) {
2082
- if (await isPortAvailable(portToReuse)) break;
2083
- await new Promise((resolve$4) => setTimeout(resolve$4, 100));
1616
+ if (await require_setup.isPortAvailable(portToReuse)) break;
1617
+ await new Promise((resolve$3) => setTimeout(resolve$3, 100));
2084
1618
  attempts++;
2085
1619
  }
2086
1620
  this.requestedPort = portToReuse;
@@ -2100,7 +1634,7 @@ var DevServer = class {
2100
1634
 
2101
1635
  //#endregion
2102
1636
  //#region src/build/manifests.ts
2103
- const logger$10 = console;
1637
+ const logger$9 = console;
2104
1638
  function isPartitioned(field) {
2105
1639
  return !Array.isArray(field);
2106
1640
  }
@@ -2161,8 +1695,8 @@ export type RoutePath = Route['path'];
2161
1695
  `;
2162
1696
  const manifestPath = (0, node_path.join)(manifestDir, "aws.ts");
2163
1697
  await (0, node_fs_promises.writeFile)(manifestPath, content);
2164
- logger$10.log(`Generated AWS manifest with ${countItems(awsRoutes)} routes, ${countItems(functions)} functions, ${countItems(crons)} crons, ${countItems(subscribers)} subscribers`);
2165
- logger$10.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
1698
+ logger$9.log(`Generated AWS manifest with ${countItems(awsRoutes)} routes, ${countItems(functions)} functions, ${countItems(crons)} crons, ${countItems(subscribers)} subscribers`);
1699
+ logger$9.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
2166
1700
  }
2167
1701
  async function generateServerManifest(outputDir, appInfo, routes, subscribers) {
2168
1702
  const manifestDir = (0, node_path.join)(outputDir, "manifest");
@@ -2188,8 +1722,8 @@ export type RoutePath = Route['path'];
2188
1722
  `;
2189
1723
  const manifestPath = (0, node_path.join)(manifestDir, "server.ts");
2190
1724
  await (0, node_fs_promises.writeFile)(manifestPath, content);
2191
- logger$10.log(`Generated server manifest with ${countItems(serverRoutes)} routes, ${countItems(serverSubscribers)} subscribers`);
2192
- logger$10.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
1725
+ logger$9.log(`Generated server manifest with ${countItems(serverRoutes)} routes, ${countItems(serverSubscribers)} subscribers`);
1726
+ logger$9.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
2193
1727
  }
2194
1728
  /**
2195
1729
  * Filter out 'ALL' method routes from a manifest field (flat or partitioned).
@@ -2255,7 +1789,7 @@ function groupInfosByPartition(infos, constructs) {
2255
1789
 
2256
1790
  //#endregion
2257
1791
  //#region src/build/index.ts
2258
- const logger$9 = console;
1792
+ const logger$8 = console;
2259
1793
  async function buildCommand(options) {
2260
1794
  const loadedConfig = await require_config.loadWorkspaceConfig();
2261
1795
  if (loadedConfig.type === "workspace") {
@@ -2263,7 +1797,7 @@ async function buildCommand(options) {
2263
1797
  const workspaceRoot = (0, node_path.resolve)(loadedConfig.workspace.root);
2264
1798
  const isAtWorkspaceRoot = cwd === workspaceRoot;
2265
1799
  if (isAtWorkspaceRoot) {
2266
- logger$9.log("📦 Detected workspace configuration");
1800
+ logger$8.log("📦 Detected workspace configuration");
2267
1801
  return workspaceBuildCommand(loadedConfig.workspace, options);
2268
1802
  }
2269
1803
  }
@@ -2271,21 +1805,21 @@ async function buildCommand(options) {
2271
1805
  const resolved = resolveProviders(config, options);
2272
1806
  const productionConfigFromGkm = getProductionConfigFromGkm(config);
2273
1807
  const production = normalizeProductionConfig(options.production ?? false, productionConfigFromGkm);
2274
- if (production) logger$9.log(`🏭 Building for PRODUCTION`);
2275
- logger$9.log(`Building with providers: ${resolved.providers.join(", ")}`);
2276
- logger$9.log(`Loading routes from: ${formatRoutes(config.routes)}`);
2277
- if (config.functions) logger$9.log(`Loading functions from: ${formatRoutes(config.functions)}`);
2278
- if (config.crons) logger$9.log(`Loading crons from: ${formatRoutes(config.crons)}`);
2279
- if (config.subscribers) logger$9.log(`Loading subscribers from: ${formatRoutes(config.subscribers)}`);
2280
- logger$9.log(`Using envParser: ${config.envParser}`);
1808
+ if (production) logger$8.log(`🏭 Building for PRODUCTION`);
1809
+ logger$8.log(`Building with providers: ${resolved.providers.join(", ")}`);
1810
+ logger$8.log(`Loading routes from: ${formatRoutes(config.routes)}`);
1811
+ if (config.functions) logger$8.log(`Loading functions from: ${formatRoutes(config.functions)}`);
1812
+ if (config.crons) logger$8.log(`Loading crons from: ${formatRoutes(config.crons)}`);
1813
+ if (config.subscribers) logger$8.log(`Loading subscribers from: ${formatRoutes(config.subscribers)}`);
1814
+ logger$8.log(`Using envParser: ${config.envParser}`);
2281
1815
  const { path: envParserPath, importPattern: envParserImportPattern } = require_config.parseModuleConfig(config.envParser, "envParser");
2282
1816
  const { path: loggerPath, importPattern: loggerImportPattern } = require_config.parseModuleConfig(config.logger, "logger");
2283
1817
  const telescope = production ? void 0 : normalizeTelescopeConfig(config.telescope);
2284
- if (telescope) logger$9.log(`🔭 Telescope enabled at ${telescope.path}`);
1818
+ if (telescope) logger$8.log(`🔭 Telescope enabled at ${telescope.path}`);
2285
1819
  const studio = production ? void 0 : normalizeStudioConfig(config.studio);
2286
- if (studio) logger$9.log(`🗄️ Studio enabled at ${studio.path}`);
1820
+ if (studio) logger$8.log(`🗄️ Studio enabled at ${studio.path}`);
2287
1821
  const hooks = normalizeHooksConfig(config.hooks);
2288
- if (hooks) logger$9.log(`🪝 Server hooks enabled`);
1822
+ if (hooks) logger$8.log(`🪝 Server hooks enabled`);
2289
1823
  const services = config.docker?.compose?.services;
2290
1824
  const dockerServices = services ? Array.isArray(services) ? {
2291
1825
  postgres: services.includes("postgres"),
@@ -2318,12 +1852,12 @@ async function buildCommand(options) {
2318
1852
  config.crons ? cronGenerator.load(config.crons) : [],
2319
1853
  config.subscribers ? subscriberGenerator.load(config.subscribers) : []
2320
1854
  ]);
2321
- logger$9.log(`Found ${allEndpoints.length} endpoints`);
2322
- logger$9.log(`Found ${allFunctions.length} functions`);
2323
- logger$9.log(`Found ${allCrons.length} crons`);
2324
- logger$9.log(`Found ${allSubscribers.length} subscribers`);
1855
+ logger$8.log(`Found ${allEndpoints.length} endpoints`);
1856
+ logger$8.log(`Found ${allFunctions.length} functions`);
1857
+ logger$8.log(`Found ${allCrons.length} crons`);
1858
+ logger$8.log(`Found ${allSubscribers.length} subscribers`);
2325
1859
  if (allEndpoints.length === 0 && allFunctions.length === 0 && allCrons.length === 0 && allSubscribers.length === 0) {
2326
- logger$9.log("No endpoints, functions, crons, or subscribers found to process");
1860
+ logger$8.log("No endpoints, functions, crons, or subscribers found to process");
2327
1861
  return {};
2328
1862
  }
2329
1863
  const rootOutputDir = (0, node_path.join)(process.cwd(), ".gkm");
@@ -2339,7 +1873,7 @@ async function buildCommand(options) {
2339
1873
  async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage) {
2340
1874
  const outputDir = (0, node_path.join)(process.cwd(), ".gkm", provider);
2341
1875
  await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
2342
- logger$9.log(`\nGenerating handlers for provider: ${provider}`);
1876
+ logger$8.log(`\nGenerating handlers for provider: ${provider}`);
2343
1877
  const [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all([
2344
1878
  endpointGenerator.build(context, endpoints, outputDir, {
2345
1879
  provider,
@@ -2349,7 +1883,7 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2349
1883
  cronGenerator.build(context, crons, outputDir, { provider }),
2350
1884
  subscriberGenerator.build(context, subscribers, outputDir, { provider })
2351
1885
  ]);
2352
- logger$9.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`);
1886
+ logger$8.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`);
2353
1887
  const manifestRoutes = assembleManifestField(routes, endpoints);
2354
1888
  const manifestFunctions = assembleManifestField(functionInfos, functions);
2355
1889
  const manifestCrons = assembleManifestField(cronInfos, crons);
@@ -2369,8 +1903,8 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2369
1903
  await generateServerManifest(rootOutputDir, appInfo, serverRouteField, manifestSubscribers);
2370
1904
  let masterKey;
2371
1905
  if (context.production?.bundle && !skipBundle) {
2372
- logger$9.log(`\n📦 Bundling production server...`);
2373
- const { bundleServer } = await Promise.resolve().then(() => require("./bundler-BG6P249p.cjs"));
1906
+ logger$8.log(`\n📦 Bundling production server...`);
1907
+ const { bundleServer } = await Promise.resolve().then(() => require("./bundler-Dufq3uvI.cjs"));
2374
1908
  const allConstructs = [
2375
1909
  ...endpoints.map((e) => e.construct),
2376
1910
  ...functions.map((f) => f.construct),
@@ -2389,10 +1923,10 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2389
1923
  dockerServices
2390
1924
  });
2391
1925
  masterKey = bundleResult.masterKey;
2392
- logger$9.log(`✅ Bundle complete: .gkm/server/dist/server.mjs`);
1926
+ logger$8.log(`✅ Bundle complete: .gkm/server/dist/server.mjs`);
2393
1927
  if (masterKey) {
2394
- logger$9.log(`\n🔐 Secrets encrypted for deployment`);
2395
- logger$9.log(` Deploy with: GKM_MASTER_KEY=${masterKey}`);
1928
+ logger$8.log(`\n🔐 Secrets encrypted for deployment`);
1929
+ logger$8.log(` Deploy with: GKM_MASTER_KEY=${masterKey}`);
2396
1930
  }
2397
1931
  }
2398
1932
  return { masterKey };
@@ -2429,18 +1963,18 @@ async function workspaceBuildCommand(workspace, options) {
2429
1963
  const apps = Object.entries(workspace.apps);
2430
1964
  const backendApps = apps.filter(([, app]) => app.type === "backend");
2431
1965
  const frontendApps = apps.filter(([, app]) => app.type === "web");
2432
- logger$9.log(`\n🏗️ Building workspace: ${workspace.name}`);
2433
- logger$9.log(` Backend apps: ${backendApps.map(([name$1]) => name$1).join(", ") || "none"}`);
2434
- logger$9.log(` Frontend apps: ${frontendApps.map(([name$1]) => name$1).join(", ") || "none"}`);
2435
- if (options.production) logger$9.log(` 🏭 Production mode enabled`);
1966
+ logger$8.log(`\n🏗️ Building workspace: ${workspace.name}`);
1967
+ logger$8.log(` Backend apps: ${backendApps.map(([name$1]) => name$1).join(", ") || "none"}`);
1968
+ logger$8.log(` Frontend apps: ${frontendApps.map(([name$1]) => name$1).join(", ") || "none"}`);
1969
+ if (options.production) logger$8.log(` 🏭 Production mode enabled`);
2436
1970
  const buildOrder = require_workspace.getAppBuildOrder(workspace);
2437
- logger$9.log(` Build order: ${buildOrder.join(" → ")}`);
1971
+ logger$8.log(` Build order: ${buildOrder.join(" → ")}`);
2438
1972
  const pm = detectPackageManager$2();
2439
- logger$9.log(`\n📦 Using ${pm} with Turbo for parallel builds...\n`);
1973
+ logger$8.log(`\n📦 Using ${pm} with Turbo for parallel builds...\n`);
2440
1974
  try {
2441
1975
  const turboCommand = getTurboCommand(pm);
2442
- logger$9.log(`Running: ${turboCommand}`);
2443
- await new Promise((resolve$4, reject) => {
1976
+ logger$8.log(`Running: ${turboCommand}`);
1977
+ await new Promise((resolve$3, reject) => {
2444
1978
  const child = (0, node_child_process.spawn)(turboCommand, {
2445
1979
  shell: true,
2446
1980
  cwd: workspace.root,
@@ -2451,7 +1985,7 @@ async function workspaceBuildCommand(workspace, options) {
2451
1985
  }
2452
1986
  });
2453
1987
  child.on("close", (code) => {
2454
- if (code === 0) resolve$4();
1988
+ if (code === 0) resolve$3();
2455
1989
  else reject(new Error(`Turbo build failed with exit code ${code}`));
2456
1990
  });
2457
1991
  child.on("error", (err) => {
@@ -2467,16 +2001,16 @@ async function workspaceBuildCommand(workspace, options) {
2467
2001
  outputPath
2468
2002
  });
2469
2003
  }
2470
- logger$9.log(`\n✅ Workspace build complete!`);
2004
+ logger$8.log(`\n✅ Workspace build complete!`);
2471
2005
  await require_openapi.openapiCommand({ cwd: workspace.root });
2472
- logger$9.log(`\n📋 Build Summary:`);
2006
+ logger$8.log(`\n📋 Build Summary:`);
2473
2007
  for (const result of results) {
2474
2008
  const icon = result.type === "backend" ? "⚙️" : result.type === "mobile" ? "📱" : "🌐";
2475
- logger$9.log(` ${icon} ${result.appName}: ${result.outputPath || "built"}`);
2009
+ logger$8.log(` ${icon} ${result.appName}: ${result.outputPath || "built"}`);
2476
2010
  }
2477
2011
  } catch (error) {
2478
2012
  const errorMessage = error instanceof Error ? error.message : "Build failed";
2479
- logger$9.log(`\n❌ Build failed: ${errorMessage}`);
2013
+ logger$8.log(`\n❌ Build failed: ${errorMessage}`);
2480
2014
  for (const [appName, app] of apps) results.push({
2481
2015
  appName,
2482
2016
  type: app.type,
@@ -2703,11 +2237,11 @@ async function createDnsProvider(options) {
2703
2237
  if (isDnsProvider(config.provider)) return config.provider;
2704
2238
  const provider = config.provider;
2705
2239
  if (provider === "hostinger") {
2706
- const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-5KYmwoK2.cjs"));
2240
+ const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-CrHfsgz9.cjs"));
2707
2241
  return new HostingerProvider();
2708
2242
  }
2709
2243
  if (provider === "route53") {
2710
- const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-owQQ4pn6.cjs"));
2244
+ const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-DwgXiLxt.cjs"));
2711
2245
  const route53Config = config;
2712
2246
  return new Route53Provider({
2713
2247
  region: route53Config.region,
@@ -2721,7 +2255,7 @@ async function createDnsProvider(options) {
2721
2255
 
2722
2256
  //#endregion
2723
2257
  //#region src/deploy/dns/index.ts
2724
- const logger$8 = console;
2258
+ const logger$7 = console;
2725
2259
  /**
2726
2260
  * Check if DNS config is legacy format (single domain with `domain` property)
2727
2261
  */
@@ -2758,7 +2292,7 @@ function groupHostnamesByDomain(appHostnames, dnsConfig) {
2758
2292
  for (const [appName, hostname] of appHostnames) {
2759
2293
  const rootDomain = findRootDomain(hostname, dnsConfig);
2760
2294
  if (!rootDomain) {
2761
- logger$8.log(` ⚠ No DNS config found for hostname: ${hostname}`);
2295
+ logger$7.log(` ⚠ No DNS config found for hostname: ${hostname}`);
2762
2296
  continue;
2763
2297
  }
2764
2298
  if (!grouped.has(rootDomain)) grouped.set(rootDomain, /* @__PURE__ */ new Map());
@@ -2810,10 +2344,10 @@ function generateRequiredRecords(appHostnames, rootDomain, serverIp) {
2810
2344
  * Print DNS records table
2811
2345
  */
2812
2346
  function printDnsRecordsTable(records, rootDomain) {
2813
- logger$8.log(`\n 📋 DNS Records for ${rootDomain}:`);
2814
- logger$8.log(" ┌─────────────────────────────────────┬──────┬─────────────────┬────────┐");
2815
- logger$8.log(" │ Subdomain │ Type │ Value │ Status │");
2816
- logger$8.log(" ├─────────────────────────────────────┼──────┼─────────────────┼────────┤");
2347
+ logger$7.log(`\n 📋 DNS Records for ${rootDomain}:`);
2348
+ logger$7.log(" ┌─────────────────────────────────────┬──────┬─────────────────┬────────┐");
2349
+ logger$7.log(" │ Subdomain │ Type │ Value │ Status │");
2350
+ logger$7.log(" ├─────────────────────────────────────┼──────┼─────────────────┼────────┤");
2817
2351
  for (const record of records) {
2818
2352
  const subdomain = record.subdomain.padEnd(35);
2819
2353
  const type$1 = record.type.padEnd(4);
@@ -2823,18 +2357,18 @@ function printDnsRecordsTable(records, rootDomain) {
2823
2357
  else if (record.created) status = "✓ new";
2824
2358
  else if (record.existed) status = "✓";
2825
2359
  else status = "?";
2826
- logger$8.log(` │ ${subdomain} │ ${type$1} │ ${value} │ ${status.padEnd(6)} │`);
2360
+ logger$7.log(` │ ${subdomain} │ ${type$1} │ ${value} │ ${status.padEnd(6)} │`);
2827
2361
  }
2828
- logger$8.log(" └─────────────────────────────────────┴──────┴─────────────────┴────────┘");
2362
+ logger$7.log(" └─────────────────────────────────────┴──────┴─────────────────┴────────┘");
2829
2363
  }
2830
2364
  /**
2831
2365
  * Print DNS records in a simple format for manual setup
2832
2366
  */
2833
2367
  function printDnsRecordsSimple(records, rootDomain) {
2834
- logger$8.log("\n 📋 Required DNS Records:");
2835
- logger$8.log(` Add these A records to your DNS provider (${rootDomain}):\n`);
2836
- for (const record of records) logger$8.log(` ${record.subdomain} → ${record.value} (A record)`);
2837
- logger$8.log("");
2368
+ logger$7.log("\n 📋 Required DNS Records:");
2369
+ logger$7.log(` Add these A records to your DNS provider (${rootDomain}):\n`);
2370
+ for (const record of records) logger$7.log(` ${record.subdomain} → ${record.value} (A record)`);
2371
+ logger$7.log("");
2838
2372
  }
2839
2373
  /**
2840
2374
  * Create DNS records for a single domain using its configured provider
@@ -2846,7 +2380,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
2846
2380
  provider = await createDnsProvider({ config: providerConfig });
2847
2381
  } catch (error) {
2848
2382
  const message = error instanceof Error ? error.message : "Unknown error";
2849
- logger$8.log(` ⚠ Failed to create DNS provider for ${rootDomain}: ${message}`);
2383
+ logger$7.log(` ⚠ Failed to create DNS provider for ${rootDomain}: ${message}`);
2850
2384
  return records.map((r) => ({
2851
2385
  ...r,
2852
2386
  error: message
@@ -2900,7 +2434,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
2900
2434
  }
2901
2435
  } catch (error) {
2902
2436
  const message = error instanceof Error ? error.message : "Unknown error";
2903
- logger$8.log(` ⚠ Failed to create DNS records for ${rootDomain}: ${message}`);
2437
+ logger$7.log(` ⚠ Failed to create DNS records for ${rootDomain}: ${message}`);
2904
2438
  return records.map((r) => ({
2905
2439
  hostname: r.hostname,
2906
2440
  subdomain: r.subdomain,
@@ -2927,20 +2461,20 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
2927
2461
  async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
2928
2462
  if (!dnsConfig) return null;
2929
2463
  const normalizedConfig = normalizeDnsConfig(dnsConfig);
2930
- logger$8.log("\n🌐 Setting up DNS records...");
2464
+ logger$7.log("\n🌐 Setting up DNS records...");
2931
2465
  let serverIp;
2932
2466
  try {
2933
2467
  const endpointUrl = new URL(dokployEndpoint);
2934
2468
  serverIp = await resolveHostnameToIp(endpointUrl.hostname);
2935
- logger$8.log(` Server IP: ${serverIp} (from ${endpointUrl.hostname})`);
2469
+ logger$7.log(` Server IP: ${serverIp} (from ${endpointUrl.hostname})`);
2936
2470
  } catch (error) {
2937
2471
  const message = error instanceof Error ? error.message : "Unknown error";
2938
- logger$8.log(` ⚠ Failed to resolve server IP: ${message}`);
2472
+ logger$7.log(` ⚠ Failed to resolve server IP: ${message}`);
2939
2473
  return null;
2940
2474
  }
2941
2475
  const groupedHostnames = groupHostnamesByDomain(appHostnames, normalizedConfig);
2942
2476
  if (groupedHostnames.size === 0) {
2943
- logger$8.log(" No DNS records needed (no hostnames match configured domains)");
2477
+ logger$7.log(" No DNS records needed (no hostnames match configured domains)");
2944
2478
  return {
2945
2479
  records: [],
2946
2480
  success: true,
@@ -2952,22 +2486,22 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
2952
2486
  for (const [rootDomain, domainHostnames] of groupedHostnames) {
2953
2487
  const providerConfig = normalizedConfig[rootDomain];
2954
2488
  if (!providerConfig) {
2955
- logger$8.log(` ⚠ No provider config for ${rootDomain}`);
2489
+ logger$7.log(` ⚠ No provider config for ${rootDomain}`);
2956
2490
  continue;
2957
2491
  }
2958
2492
  const providerName = typeof providerConfig.provider === "string" ? providerConfig.provider : "custom";
2959
2493
  const requiredRecords = generateRequiredRecords(domainHostnames, rootDomain, serverIp);
2960
2494
  if (requiredRecords.length === 0) continue;
2961
- logger$8.log(` Creating DNS records for ${rootDomain} (${providerName})...`);
2495
+ logger$7.log(` Creating DNS records for ${rootDomain} (${providerName})...`);
2962
2496
  const domainRecords = await createDnsRecordsForDomain(requiredRecords, rootDomain, providerConfig);
2963
2497
  allRecords.push(...domainRecords);
2964
2498
  const created = domainRecords.filter((r) => r.created).length;
2965
2499
  const existed = domainRecords.filter((r) => r.existed).length;
2966
2500
  const failed = domainRecords.filter((r) => r.error).length;
2967
- if (created > 0) logger$8.log(` ✓ Created ${created} DNS record(s) for ${rootDomain}`);
2968
- if (existed > 0) logger$8.log(` ✓ ${existed} record(s) already exist for ${rootDomain}`);
2501
+ if (created > 0) logger$7.log(` ✓ Created ${created} DNS record(s) for ${rootDomain}`);
2502
+ if (existed > 0) logger$7.log(` ✓ ${existed} record(s) already exist for ${rootDomain}`);
2969
2503
  if (failed > 0) {
2970
- logger$8.log(` ⚠ ${failed} record(s) failed for ${rootDomain}`);
2504
+ logger$7.log(` ⚠ ${failed} record(s) failed for ${rootDomain}`);
2971
2505
  hasFailures = true;
2972
2506
  }
2973
2507
  if (state) {
@@ -3004,10 +2538,10 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
3004
2538
  */
3005
2539
  async function verifyDnsRecords(appHostnames, serverIp, state) {
3006
2540
  const results = [];
3007
- logger$8.log("\n🔍 Verifying DNS records...");
2541
+ logger$7.log("\n🔍 Verifying DNS records...");
3008
2542
  for (const [appName, hostname] of appHostnames) {
3009
2543
  if (isDnsVerified(state, hostname, serverIp)) {
3010
- logger$8.log(` ✓ ${hostname} (previously verified)`);
2544
+ logger$7.log(` ✓ ${hostname} (previously verified)`);
3011
2545
  results.push({
3012
2546
  hostname,
3013
2547
  appName,
@@ -3021,7 +2555,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
3021
2555
  const resolvedIp = await resolveHostnameToIp(hostname);
3022
2556
  if (resolvedIp === serverIp) {
3023
2557
  setDnsVerification(state, hostname, serverIp);
3024
- logger$8.log(` ✓ ${hostname} → ${resolvedIp}`);
2558
+ logger$7.log(` ✓ ${hostname} → ${resolvedIp}`);
3025
2559
  results.push({
3026
2560
  hostname,
3027
2561
  appName,
@@ -3030,7 +2564,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
3030
2564
  expectedIp: serverIp
3031
2565
  });
3032
2566
  } else {
3033
- logger$8.log(` ⚠ ${hostname} resolves to ${resolvedIp}, expected ${serverIp}`);
2567
+ logger$7.log(` ⚠ ${hostname} resolves to ${resolvedIp}, expected ${serverIp}`);
3034
2568
  results.push({
3035
2569
  hostname,
3036
2570
  appName,
@@ -3041,7 +2575,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
3041
2575
  }
3042
2576
  } catch (error) {
3043
2577
  const message = error instanceof Error ? error.message : "Unknown error";
3044
- logger$8.log(` ⚠ ${hostname} DNS not propagated (${message})`);
2578
+ logger$7.log(` ⚠ ${hostname} DNS not propagated (${message})`);
3045
2579
  results.push({
3046
2580
  hostname,
3047
2581
  appName,
@@ -3055,9 +2589,9 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
3055
2589
  const skipped = results.filter((r) => r.skipped).length;
3056
2590
  const pending = results.filter((r) => !r.verified).length;
3057
2591
  if (pending > 0) {
3058
- logger$8.log(`\n ${verified} verified, ${pending} pending propagation`);
3059
- logger$8.log(" DNS changes may take 5-30 minutes to propagate");
3060
- } else if (skipped > 0) logger$8.log(` ${verified} verified (${skipped} from cache)`);
2592
+ logger$7.log(`\n ${verified} verified, ${pending} pending propagation`);
2593
+ logger$7.log(" DNS changes may take 5-30 minutes to propagate");
2594
+ } else if (skipped > 0) logger$7.log(` ${verified} verified (${skipped} from cache)`);
3061
2595
  return results;
3062
2596
  }
3063
2597
 
@@ -4528,7 +4062,7 @@ CMD ["nginx", "-g", "daemon off;"]
4528
4062
 
4529
4063
  //#endregion
4530
4064
  //#region src/docker/index.ts
4531
- const logger$7 = console;
4065
+ const logger$6 = console;
4532
4066
  /**
4533
4067
  * Docker command implementation
4534
4068
  * Generates Dockerfile, docker-compose.yml, and related files
@@ -4539,7 +4073,7 @@ const logger$7 = console;
4539
4073
  async function dockerCommand(options) {
4540
4074
  const loadedConfig = await require_config.loadWorkspaceConfig();
4541
4075
  if (loadedConfig.type === "workspace") {
4542
- logger$7.log("📦 Detected workspace configuration");
4076
+ logger$6.log("📦 Detected workspace configuration");
4543
4077
  return workspaceDockerCommand(loadedConfig.workspace, options);
4544
4078
  }
4545
4079
  const config = await require_config.loadConfig();
@@ -4560,14 +4094,14 @@ async function dockerCommand(options) {
4560
4094
  let useTurbo = options.turbo ?? false;
4561
4095
  if (inMonorepo && !useSlim) if (hasTurbo) {
4562
4096
  useTurbo = true;
4563
- logger$7.log(" Detected monorepo with turbo.json - using turbo prune");
4097
+ logger$6.log(" Detected monorepo with turbo.json - using turbo prune");
4564
4098
  } else throw new Error("Monorepo detected but turbo.json not found.\n\nDocker builds in monorepos require Turborepo for proper dependency isolation.\n\nTo fix this:\n 1. Install turbo: pnpm add -Dw turbo\n 2. Create turbo.json in your monorepo root\n 3. Run this command again\n\nSee: https://turbo.build/repo/docs/guides/tools/docker");
4565
4099
  let turboPackage = options.turboPackage ?? dockerConfig.imageName;
4566
4100
  if (useTurbo && !options.turboPackage) try {
4567
4101
  const pkg$1 = require(`${process.cwd()}/package.json`);
4568
4102
  if (pkg$1.name) {
4569
4103
  turboPackage = pkg$1.name;
4570
- logger$7.log(` Turbo package: ${turboPackage}`);
4104
+ logger$6.log(` Turbo package: ${turboPackage}`);
4571
4105
  }
4572
4106
  } catch {}
4573
4107
  const templateOptions = {
@@ -4584,7 +4118,7 @@ async function dockerCommand(options) {
4584
4118
  const dockerMode = useSlim ? "slim" : useTurbo ? "turbo" : "multi-stage";
4585
4119
  const dockerfilePath = (0, node_path.join)(dockerDir, "Dockerfile");
4586
4120
  await (0, node_fs_promises.writeFile)(dockerfilePath, dockerfile);
4587
- logger$7.log(`Generated: .gkm/docker/Dockerfile (${dockerMode}, ${packageManager})`);
4121
+ logger$6.log(`Generated: .gkm/docker/Dockerfile (${dockerMode}, ${packageManager})`);
4588
4122
  const composeOptions = {
4589
4123
  imageName: dockerConfig.imageName,
4590
4124
  registry: options.registry ?? dockerConfig.registry,
@@ -4596,15 +4130,15 @@ async function dockerCommand(options) {
4596
4130
  const dockerCompose = hasServices ? generateDockerCompose(composeOptions) : generateMinimalDockerCompose(composeOptions);
4597
4131
  const composePath = (0, node_path.join)(dockerDir, "docker-compose.yml");
4598
4132
  await (0, node_fs_promises.writeFile)(composePath, dockerCompose);
4599
- logger$7.log("Generated: .gkm/docker/docker-compose.yml");
4133
+ logger$6.log("Generated: .gkm/docker/docker-compose.yml");
4600
4134
  const dockerignore = generateDockerignore();
4601
4135
  const dockerignorePath = (0, node_path.join)(process.cwd(), ".dockerignore");
4602
4136
  await (0, node_fs_promises.writeFile)(dockerignorePath, dockerignore);
4603
- logger$7.log("Generated: .dockerignore (project root)");
4137
+ logger$6.log("Generated: .dockerignore (project root)");
4604
4138
  const entrypoint = generateDockerEntrypoint();
4605
4139
  const entrypointPath = (0, node_path.join)(dockerDir, "docker-entrypoint.sh");
4606
4140
  await (0, node_fs_promises.writeFile)(entrypointPath, entrypoint);
4607
- logger$7.log("Generated: .gkm/docker/docker-entrypoint.sh");
4141
+ logger$6.log("Generated: .gkm/docker/docker-entrypoint.sh");
4608
4142
  const result = {
4609
4143
  dockerfile: dockerfilePath,
4610
4144
  dockerCompose: composePath,
@@ -4623,13 +4157,13 @@ async function dockerCommand(options) {
4623
4157
  function ensureLockfile(cwd) {
4624
4158
  const lockfilePath = findLockfilePath(cwd);
4625
4159
  if (!lockfilePath) {
4626
- logger$7.warn("\n⚠️ No lockfile found. Docker build may fail or use stale dependencies.");
4160
+ logger$6.warn("\n⚠️ No lockfile found. Docker build may fail or use stale dependencies.");
4627
4161
  return null;
4628
4162
  }
4629
4163
  const lockfileName = (0, node_path.basename)(lockfilePath);
4630
4164
  const localLockfile = (0, node_path.join)(cwd, lockfileName);
4631
4165
  if (lockfilePath === localLockfile) return null;
4632
- logger$7.log(` Copying ${lockfileName} from monorepo root...`);
4166
+ logger$6.log(` Copying ${lockfileName} from monorepo root...`);
4633
4167
  (0, node_fs.copyFileSync)(lockfilePath, localLockfile);
4634
4168
  return () => {
4635
4169
  try {
@@ -4645,7 +4179,7 @@ async function buildDockerImage(imageName, options) {
4645
4179
  const tag = options.tag ?? "latest";
4646
4180
  const registry = options.registry;
4647
4181
  const fullImageName = registry ? `${registry}/${imageName}:${tag}` : `${imageName}:${tag}`;
4648
- logger$7.log(`\n🐳 Building Docker image: ${fullImageName}`);
4182
+ logger$6.log(`\n🐳 Building Docker image: ${fullImageName}`);
4649
4183
  const cwd = process.cwd();
4650
4184
  const cleanup = ensureLockfile(cwd);
4651
4185
  try {
@@ -4657,7 +4191,7 @@ async function buildDockerImage(imageName, options) {
4657
4191
  DOCKER_BUILDKIT: "1"
4658
4192
  }
4659
4193
  });
4660
- logger$7.log(`✅ Docker image built: ${fullImageName}`);
4194
+ logger$6.log(`✅ Docker image built: ${fullImageName}`);
4661
4195
  } catch (error) {
4662
4196
  throw new Error(`Failed to build Docker image: ${error instanceof Error ? error.message : "Unknown error"}`);
4663
4197
  } finally {
@@ -4672,13 +4206,13 @@ async function pushDockerImage(imageName, options) {
4672
4206
  const registry = options.registry;
4673
4207
  if (!registry) throw new Error("Registry is required to push Docker image. Use --registry or configure docker.registry in gkm.config.ts");
4674
4208
  const fullImageName = `${registry}/${imageName}:${tag}`;
4675
- logger$7.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
4209
+ logger$6.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
4676
4210
  try {
4677
4211
  (0, node_child_process.execSync)(`docker push ${fullImageName}`, {
4678
4212
  cwd: process.cwd(),
4679
4213
  stdio: "inherit"
4680
4214
  });
4681
- logger$7.log(`✅ Docker image pushed: ${fullImageName}`);
4215
+ logger$6.log(`✅ Docker image pushed: ${fullImageName}`);
4682
4216
  } catch (error) {
4683
4217
  throw new Error(`Failed to push Docker image: ${error instanceof Error ? error.message : "Unknown error"}`);
4684
4218
  }
@@ -4704,14 +4238,14 @@ function getAppPackageName(appPath) {
4704
4238
  async function workspaceDockerCommand(workspace, options) {
4705
4239
  const results = [];
4706
4240
  const apps = Object.entries(workspace.apps);
4707
- logger$7.log(`\n🐳 Generating Dockerfiles for workspace: ${workspace.name}`);
4241
+ logger$6.log(`\n🐳 Generating Dockerfiles for workspace: ${workspace.name}`);
4708
4242
  const dockerDir = (0, node_path.join)(workspace.root, ".gkm", "docker");
4709
4243
  await (0, node_fs_promises.mkdir)(dockerDir, { recursive: true });
4710
4244
  const packageManager = detectPackageManager$1(workspace.root);
4711
- logger$7.log(` Package manager: ${packageManager}`);
4245
+ logger$6.log(` Package manager: ${packageManager}`);
4712
4246
  for (const [appName, app] of apps) {
4713
4247
  if (app.type === "mobile") {
4714
- logger$7.log(`\n 📱 Skipping Docker for ${appName} (mobile app — deploy via framework toolchain)`);
4248
+ logger$6.log(`\n 📱 Skipping Docker for ${appName} (mobile app — deploy via framework toolchain)`);
4715
4249
  continue;
4716
4250
  }
4717
4251
  const appPath = app.path;
@@ -4720,7 +4254,7 @@ async function workspaceDockerCommand(workspace, options) {
4720
4254
  const imageName = appName;
4721
4255
  const hasEntry = !!app.entry;
4722
4256
  const buildType = hasEntry ? "entry" : app.type;
4723
- logger$7.log(`\n 📄 Generating Dockerfile for ${appName} (${buildType})`);
4257
+ logger$6.log(`\n 📄 Generating Dockerfile for ${appName} (${buildType})`);
4724
4258
  let dockerfile;
4725
4259
  if (app.type === "web") {
4726
4260
  const publicUrlArgs = getPublicUrlArgNames(app);
@@ -4764,7 +4298,7 @@ async function workspaceDockerCommand(workspace, options) {
4764
4298
  });
4765
4299
  const dockerfilePath = (0, node_path.join)(dockerDir, `Dockerfile.${appName}`);
4766
4300
  await (0, node_fs_promises.writeFile)(dockerfilePath, dockerfile);
4767
- logger$7.log(` Generated: .gkm/docker/Dockerfile.${appName}`);
4301
+ logger$6.log(` Generated: .gkm/docker/Dockerfile.${appName}`);
4768
4302
  results.push({
4769
4303
  appName,
4770
4304
  type: app.type,
@@ -4775,19 +4309,19 @@ async function workspaceDockerCommand(workspace, options) {
4775
4309
  const dockerignore = generateDockerignore();
4776
4310
  const dockerignorePath = (0, node_path.join)(workspace.root, ".dockerignore");
4777
4311
  await (0, node_fs_promises.writeFile)(dockerignorePath, dockerignore);
4778
- logger$7.log(`\n Generated: .dockerignore (workspace root)`);
4312
+ logger$6.log(`\n Generated: .dockerignore (workspace root)`);
4779
4313
  const dockerCompose = generateWorkspaceCompose(workspace, { registry: options.registry });
4780
4314
  const composePath = (0, node_path.join)(dockerDir, "docker-compose.yml");
4781
4315
  await (0, node_fs_promises.writeFile)(composePath, dockerCompose);
4782
- logger$7.log(` Generated: .gkm/docker/docker-compose.yml`);
4783
- logger$7.log(`\n✅ Generated ${results.length} Dockerfile(s) + docker-compose.yml`);
4784
- logger$7.log("\n📋 Build commands:");
4316
+ logger$6.log(` Generated: .gkm/docker/docker-compose.yml`);
4317
+ logger$6.log(`\n✅ Generated ${results.length} Dockerfile(s) + docker-compose.yml`);
4318
+ logger$6.log("\n📋 Build commands:");
4785
4319
  for (const result of results) {
4786
4320
  const icon = result.type === "backend" ? "⚙️" : result.type === "mobile" ? "📱" : "🌐";
4787
- logger$7.log(` ${icon} docker build -f .gkm/docker/Dockerfile.${result.appName} -t ${result.imageName} .`);
4321
+ logger$6.log(` ${icon} docker build -f .gkm/docker/Dockerfile.${result.appName} -t ${result.imageName} .`);
4788
4322
  }
4789
- logger$7.log("\n📋 Run all services:");
4790
- logger$7.log(" docker compose -f .gkm/docker/docker-compose.yml up --build");
4323
+ logger$6.log("\n📋 Run all services:");
4324
+ logger$6.log(" docker compose -f .gkm/docker/docker-compose.yml up --build");
4791
4325
  return {
4792
4326
  apps: results,
4793
4327
  dockerCompose: composePath,
@@ -4827,7 +4361,7 @@ function getAppNameFromPackageJson() {
4827
4361
  } catch {}
4828
4362
  return void 0;
4829
4363
  }
4830
- const logger$6 = console;
4364
+ const logger$5 = console;
4831
4365
  /**
4832
4366
  * Get the full image reference
4833
4367
  */
@@ -4842,18 +4376,18 @@ function getImageRef(registry, imageName, tag) {
4842
4376
  * @param buildArgs - Build arguments to pass to docker build
4843
4377
  */
4844
4378
  async function buildImage(imageRef, appName, buildArgs) {
4845
- logger$6.log(`\n🔨 Building Docker image: ${imageRef}`);
4379
+ logger$5.log(`\n🔨 Building Docker image: ${imageRef}`);
4846
4380
  const cwd = process.cwd();
4847
4381
  const lockfilePath = findLockfilePath(cwd);
4848
4382
  const lockfileDir = lockfilePath ? (0, node_path.dirname)(lockfilePath) : cwd;
4849
4383
  const inMonorepo = lockfileDir !== cwd;
4850
- if (appName || inMonorepo) logger$6.log(" Generating Dockerfile for monorepo (turbo prune)...");
4851
- else logger$6.log(" Generating Dockerfile...");
4384
+ if (appName || inMonorepo) logger$5.log(" Generating Dockerfile for monorepo (turbo prune)...");
4385
+ else logger$5.log(" Generating Dockerfile...");
4852
4386
  await dockerCommand({});
4853
4387
  const dockerfileSuffix = appName ? `.${appName}` : "";
4854
4388
  const dockerfilePath = `.gkm/docker/Dockerfile${dockerfileSuffix}`;
4855
4389
  const buildCwd = lockfilePath && (inMonorepo || appName) ? lockfileDir : cwd;
4856
- if (buildCwd !== cwd) logger$6.log(` Building from workspace root: ${buildCwd}`);
4390
+ if (buildCwd !== cwd) logger$5.log(` Building from workspace root: ${buildCwd}`);
4857
4391
  const buildArgsString = buildArgs && buildArgs.length > 0 ? buildArgs.map((arg) => `--build-arg "${arg}"`).join(" ") : "";
4858
4392
  try {
4859
4393
  const cmd = [
@@ -4872,7 +4406,7 @@ async function buildImage(imageRef, appName, buildArgs) {
4872
4406
  DOCKER_BUILDKIT: "1"
4873
4407
  }
4874
4408
  });
4875
- logger$6.log(`✅ Image built: ${imageRef}`);
4409
+ logger$5.log(`✅ Image built: ${imageRef}`);
4876
4410
  } catch (error) {
4877
4411
  throw new Error(`Failed to build Docker image: ${error instanceof Error ? error.message : "Unknown error"}`);
4878
4412
  }
@@ -4881,13 +4415,13 @@ async function buildImage(imageRef, appName, buildArgs) {
4881
4415
  * Push Docker image to registry
4882
4416
  */
4883
4417
  async function pushImage(imageRef) {
4884
- logger$6.log(`\n☁️ Pushing image: ${imageRef}`);
4418
+ logger$5.log(`\n☁️ Pushing image: ${imageRef}`);
4885
4419
  try {
4886
4420
  (0, node_child_process.execSync)(`docker push ${imageRef}`, {
4887
4421
  cwd: process.cwd(),
4888
4422
  stdio: "inherit"
4889
4423
  });
4890
- logger$6.log(`✅ Image pushed: ${imageRef}`);
4424
+ logger$5.log(`✅ Image pushed: ${imageRef}`);
4891
4425
  } catch (error) {
4892
4426
  throw new Error(`Failed to push Docker image: ${error instanceof Error ? error.message : "Unknown error"}`);
4893
4427
  }
@@ -4900,17 +4434,17 @@ async function deployDocker(options) {
4900
4434
  const imageName = config.imageName;
4901
4435
  const imageRef = getImageRef(config.registry, imageName, tag);
4902
4436
  await buildImage(imageRef, config.appName, buildArgs);
4903
- if (!skipPush) if (!config.registry) logger$6.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
4437
+ if (!skipPush) if (!config.registry) logger$5.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
4904
4438
  else await pushImage(imageRef);
4905
- logger$6.log("\n✅ Docker deployment ready!");
4906
- logger$6.log(`\n📋 Deployment details:`);
4907
- logger$6.log(` Image: ${imageRef}`);
4908
- logger$6.log(` Stage: ${stage}`);
4439
+ logger$5.log("\n✅ Docker deployment ready!");
4440
+ logger$5.log(`\n📋 Deployment details:`);
4441
+ logger$5.log(` Image: ${imageRef}`);
4442
+ logger$5.log(` Stage: ${stage}`);
4909
4443
  if (masterKey) {
4910
- logger$6.log(`\n🔐 Deploy with this environment variable:`);
4911
- logger$6.log(` GKM_MASTER_KEY=${masterKey}`);
4912
- logger$6.log("\n Example docker run:");
4913
- logger$6.log(` docker run -e GKM_MASTER_KEY=${masterKey} ${imageRef}`);
4444
+ logger$5.log(`\n🔐 Deploy with this environment variable:`);
4445
+ logger$5.log(` GKM_MASTER_KEY=${masterKey}`);
4446
+ logger$5.log("\n Example docker run:");
4447
+ logger$5.log(` docker run -e GKM_MASTER_KEY=${masterKey} ${imageRef}`);
4914
4448
  }
4915
4449
  return {
4916
4450
  imageRef,
@@ -4937,7 +4471,7 @@ function resolveDockerConfig(config) {
4937
4471
 
4938
4472
  //#endregion
4939
4473
  //#region src/deploy/dokploy.ts
4940
- const logger$5 = console;
4474
+ const logger$4 = console;
4941
4475
  /**
4942
4476
  * Get the Dokploy API token from stored credentials or environment
4943
4477
  */
@@ -4961,25 +4495,25 @@ async function createApi$1(endpoint) {
4961
4495
  */
4962
4496
  async function deployDokploy(options) {
4963
4497
  const { stage, imageRef, masterKey, config } = options;
4964
- logger$5.log(`\n🎯 Deploying to Dokploy...`);
4965
- logger$5.log(` Endpoint: ${config.endpoint}`);
4966
- logger$5.log(` Application: ${config.applicationId}`);
4498
+ logger$4.log(`\n🎯 Deploying to Dokploy...`);
4499
+ logger$4.log(` Endpoint: ${config.endpoint}`);
4500
+ logger$4.log(` Application: ${config.applicationId}`);
4967
4501
  const api = await createApi$1(config.endpoint);
4968
- logger$5.log(` Configuring Docker image: ${imageRef}`);
4502
+ logger$4.log(` Configuring Docker image: ${imageRef}`);
4969
4503
  const registryOptions = {};
4970
4504
  if (config.registryId) {
4971
4505
  registryOptions.registryId = config.registryId;
4972
- logger$5.log(` Using Dokploy registry: ${config.registryId}`);
4506
+ logger$4.log(` Using Dokploy registry: ${config.registryId}`);
4973
4507
  } else {
4974
4508
  const storedRegistryId = await require_credentials.getDokployRegistryId();
4975
4509
  if (storedRegistryId) {
4976
4510
  registryOptions.registryId = storedRegistryId;
4977
- logger$5.log(` Using stored Dokploy registry: ${storedRegistryId}`);
4511
+ logger$4.log(` Using stored Dokploy registry: ${storedRegistryId}`);
4978
4512
  } else if (config.registryCredentials) {
4979
4513
  registryOptions.username = config.registryCredentials.username;
4980
4514
  registryOptions.password = config.registryCredentials.password;
4981
4515
  registryOptions.registryUrl = config.registryCredentials.registryUrl;
4982
- logger$5.log(` Using registry credentials for: ${config.registryCredentials.registryUrl}`);
4516
+ logger$4.log(` Using registry credentials for: ${config.registryCredentials.registryUrl}`);
4983
4517
  } else {
4984
4518
  const username = process.env.DOCKER_REGISTRY_USERNAME;
4985
4519
  const password = process.env.DOCKER_REGISTRY_PASSWORD;
@@ -4988,31 +4522,31 @@ async function deployDokploy(options) {
4988
4522
  registryOptions.username = username;
4989
4523
  registryOptions.password = password;
4990
4524
  registryOptions.registryUrl = registryUrl;
4991
- logger$5.log(` Using registry credentials from environment`);
4525
+ logger$4.log(` Using registry credentials from environment`);
4992
4526
  }
4993
4527
  }
4994
4528
  }
4995
4529
  await api.saveDockerProvider(config.applicationId, imageRef, registryOptions);
4996
- logger$5.log(" ✓ Docker provider configured");
4530
+ logger$4.log(" ✓ Docker provider configured");
4997
4531
  const envVars = {};
4998
4532
  if (masterKey) envVars.GKM_MASTER_KEY = masterKey;
4999
4533
  if (Object.keys(envVars).length > 0) {
5000
- logger$5.log(" Updating environment variables...");
4534
+ logger$4.log(" Updating environment variables...");
5001
4535
  const envString = Object.entries(envVars).map(([key, value]) => `${key}=${value}`).join("\n");
5002
4536
  await api.saveApplicationEnv(config.applicationId, envString);
5003
- logger$5.log(" ✓ Environment variables updated");
4537
+ logger$4.log(" ✓ Environment variables updated");
5004
4538
  }
5005
- logger$5.log(" Triggering deployment...");
4539
+ logger$4.log(" Triggering deployment...");
5006
4540
  await api.deployApplication(config.applicationId);
5007
- logger$5.log(" ✓ Deployment triggered");
5008
- logger$5.log("\n✅ Dokploy deployment initiated!");
5009
- logger$5.log(`\n📋 Deployment details:`);
5010
- logger$5.log(` Image: ${imageRef}`);
5011
- logger$5.log(` Stage: ${stage}`);
5012
- logger$5.log(` Application ID: ${config.applicationId}`);
5013
- if (masterKey) logger$5.log(`\n🔐 GKM_MASTER_KEY has been set in Dokploy environment`);
4541
+ logger$4.log(" ✓ Deployment triggered");
4542
+ logger$4.log("\n✅ Dokploy deployment initiated!");
4543
+ logger$4.log(`\n📋 Deployment details:`);
4544
+ logger$4.log(` Image: ${imageRef}`);
4545
+ logger$4.log(` Stage: ${stage}`);
4546
+ logger$4.log(` Application ID: ${config.applicationId}`);
4547
+ if (masterKey) logger$4.log(`\n🔐 GKM_MASTER_KEY has been set in Dokploy environment`);
5014
4548
  const deploymentUrl = `${config.endpoint}/project/${config.projectId}`;
5015
- logger$5.log(`\n🔗 View deployment: ${deploymentUrl}`);
4549
+ logger$4.log(`\n🔗 View deployment: ${deploymentUrl}`);
5016
4550
  return {
5017
4551
  imageRef,
5018
4552
  masterKey,
@@ -5129,7 +4663,7 @@ function validateEnvVars(requiredVars, context) {
5129
4663
 
5130
4664
  //#endregion
5131
4665
  //#region src/deploy/init.ts
5132
- const logger$4 = console;
4666
+ const logger$3 = console;
5133
4667
  /**
5134
4668
  * Get the Dokploy API token from stored credentials or environment
5135
4669
  */
@@ -5163,20 +4697,20 @@ async function createApi(endpoint) {
5163
4697
  async function updateConfig(config, cwd = process.cwd()) {
5164
4698
  const configPath = (0, node_path.join)(cwd, "gkm.config.ts");
5165
4699
  if (!(0, node_fs.existsSync)(configPath)) {
5166
- logger$4.warn("\n gkm.config.ts not found. Add this configuration manually:\n");
5167
- logger$4.log(` providers: {`);
5168
- logger$4.log(` dokploy: {`);
5169
- logger$4.log(` endpoint: '${config.endpoint}',`);
5170
- logger$4.log(` projectId: '${config.projectId}',`);
5171
- logger$4.log(` applicationId: '${config.applicationId}',`);
5172
- logger$4.log(` },`);
5173
- logger$4.log(` },`);
4700
+ logger$3.warn("\n gkm.config.ts not found. Add this configuration manually:\n");
4701
+ logger$3.log(` providers: {`);
4702
+ logger$3.log(` dokploy: {`);
4703
+ logger$3.log(` endpoint: '${config.endpoint}',`);
4704
+ logger$3.log(` projectId: '${config.projectId}',`);
4705
+ logger$3.log(` applicationId: '${config.applicationId}',`);
4706
+ logger$3.log(` },`);
4707
+ logger$3.log(` },`);
5174
4708
  return;
5175
4709
  }
5176
4710
  const content = await (0, node_fs_promises.readFile)(configPath, "utf-8");
5177
4711
  if (content.includes("dokploy:") && content.includes("applicationId:")) {
5178
- logger$4.log("\n Dokploy config already exists in gkm.config.ts");
5179
- logger$4.log(" Updating with new values...");
4712
+ logger$3.log("\n Dokploy config already exists in gkm.config.ts");
4713
+ logger$3.log(" Updating with new values...");
5180
4714
  }
5181
4715
  const registryLine = config.registryId ? `\n\t\t\tregistryId: '${config.registryId}',` : "";
5182
4716
  const dokployConfigStr = `dokploy: {
@@ -5193,7 +4727,7 @@ async function updateConfig(config, cwd = process.cwd()) {
5193
4727
  },
5194
4728
  });`);
5195
4729
  await (0, node_fs_promises.writeFile)(configPath, newContent);
5196
- logger$4.log("\n ✓ Updated gkm.config.ts with Dokploy configuration");
4730
+ logger$3.log("\n ✓ Updated gkm.config.ts with Dokploy configuration");
5197
4731
  }
5198
4732
  /**
5199
4733
  * Initialize Dokploy deployment configuration
@@ -5202,24 +4736,24 @@ async function deployInitCommand(options) {
5202
4736
  const { projectName, appName, projectId: existingProjectId, registryId } = options;
5203
4737
  const endpoint = await getEndpoint(options.endpoint);
5204
4738
  const api = await createApi(endpoint);
5205
- logger$4.log(`\n🚀 Initializing Dokploy deployment...`);
5206
- logger$4.log(` Endpoint: ${endpoint}`);
4739
+ logger$3.log(`\n🚀 Initializing Dokploy deployment...`);
4740
+ logger$3.log(` Endpoint: ${endpoint}`);
5207
4741
  let projectId;
5208
4742
  if (existingProjectId) {
5209
4743
  projectId = existingProjectId;
5210
- logger$4.log(`\n📁 Using existing project: ${projectId}`);
4744
+ logger$3.log(`\n📁 Using existing project: ${projectId}`);
5211
4745
  } else {
5212
- logger$4.log(`\n📁 Looking for project: ${projectName}`);
4746
+ logger$3.log(`\n📁 Looking for project: ${projectName}`);
5213
4747
  const projects = await api.listProjects();
5214
4748
  const existingProject = projects.find((p) => p.name.toLowerCase() === projectName.toLowerCase());
5215
4749
  if (existingProject) {
5216
4750
  projectId = existingProject.projectId;
5217
- logger$4.log(` Found existing project: ${projectId}`);
4751
+ logger$3.log(` Found existing project: ${projectId}`);
5218
4752
  } else {
5219
- logger$4.log(` Creating new project...`);
4753
+ logger$3.log(` Creating new project...`);
5220
4754
  const result = await api.createProject(projectName);
5221
4755
  projectId = result.project.projectId;
5222
- logger$4.log(` ✓ Created project: ${projectId}`);
4756
+ logger$3.log(` ✓ Created project: ${projectId}`);
5223
4757
  }
5224
4758
  }
5225
4759
  const project = await api.getProject(projectId);
@@ -5227,23 +4761,23 @@ async function deployInitCommand(options) {
5227
4761
  const firstEnv = project.environments?.[0];
5228
4762
  if (firstEnv) environmentId = firstEnv.environmentId;
5229
4763
  else {
5230
- logger$4.log(` Creating production environment...`);
4764
+ logger$3.log(` Creating production environment...`);
5231
4765
  const env = await api.createEnvironment(projectId, "production");
5232
4766
  environmentId = env.environmentId;
5233
4767
  }
5234
- logger$4.log(`\n📦 Creating application: ${appName}`);
4768
+ logger$3.log(`\n📦 Creating application: ${appName}`);
5235
4769
  const application = await api.createApplication(appName, projectId, environmentId);
5236
- logger$4.log(` ✓ Created application: ${application.applicationId}`);
4770
+ logger$3.log(` ✓ Created application: ${application.applicationId}`);
5237
4771
  if (registryId) {
5238
- logger$4.log(`\n🔧 Configuring registry: ${registryId}`);
4772
+ logger$3.log(`\n🔧 Configuring registry: ${registryId}`);
5239
4773
  await api.updateApplication(application.applicationId, { registryId });
5240
- logger$4.log(` ✓ Registry configured`);
4774
+ logger$3.log(` ✓ Registry configured`);
5241
4775
  } else try {
5242
4776
  const registries = await api.listRegistries();
5243
4777
  if (registries.length > 0) {
5244
- logger$4.log(`\n📋 Available registries:`);
5245
- for (const reg of registries) logger$4.log(` - ${reg.registryName}: ${reg.registryUrl} (${reg.registryId})`);
5246
- logger$4.log(`\n To use a registry, run with --registry-id <id>`);
4778
+ logger$3.log(`\n📋 Available registries:`);
4779
+ for (const reg of registries) logger$3.log(` - ${reg.registryName}: ${reg.registryUrl} (${reg.registryId})`);
4780
+ logger$3.log(`\n To use a registry, run with --registry-id <id>`);
5247
4781
  }
5248
4782
  } catch {}
5249
4783
  const config = {
@@ -5252,14 +4786,14 @@ async function deployInitCommand(options) {
5252
4786
  applicationId: application.applicationId
5253
4787
  };
5254
4788
  await updateConfig(config);
5255
- logger$4.log(`\n✅ Dokploy deployment initialized!`);
5256
- logger$4.log(`\n📋 Configuration:`);
5257
- logger$4.log(` Project ID: ${projectId}`);
5258
- logger$4.log(` Application ID: ${application.applicationId}`);
5259
- logger$4.log(`\n🔗 View in Dokploy: ${endpoint}/project/${projectId}`);
5260
- logger$4.log(`\n📝 Next steps:`);
5261
- logger$4.log(` 1. Initialize secrets: gkm secrets:init --stage production`);
5262
- logger$4.log(` 2. Deploy: gkm deploy --provider dokploy --stage production`);
4789
+ logger$3.log(`\n✅ Dokploy deployment initialized!`);
4790
+ logger$3.log(`\n📋 Configuration:`);
4791
+ logger$3.log(` Project ID: ${projectId}`);
4792
+ logger$3.log(` Application ID: ${application.applicationId}`);
4793
+ logger$3.log(`\n🔗 View in Dokploy: ${endpoint}/project/${projectId}`);
4794
+ logger$3.log(`\n📝 Next steps:`);
4795
+ logger$3.log(` 1. Initialize secrets: gkm secrets:init --stage production`);
4796
+ logger$3.log(` 2. Deploy: gkm deploy --provider dokploy --stage production`);
5263
4797
  return config;
5264
4798
  }
5265
4799
  /**
@@ -5270,32 +4804,32 @@ async function deployListCommand(options) {
5270
4804
  const api = await createApi(endpoint);
5271
4805
  const { resource } = options;
5272
4806
  if (resource === "projects") {
5273
- logger$4.log(`\n📁 Projects in ${endpoint}:`);
4807
+ logger$3.log(`\n📁 Projects in ${endpoint}:`);
5274
4808
  const projects = await api.listProjects();
5275
4809
  if (projects.length === 0) {
5276
- logger$4.log(" No projects found");
4810
+ logger$3.log(" No projects found");
5277
4811
  return;
5278
4812
  }
5279
4813
  for (const project of projects) {
5280
- logger$4.log(`\n ${project.name} (${project.projectId})`);
5281
- if (project.description) logger$4.log(` ${project.description}`);
4814
+ logger$3.log(`\n ${project.name} (${project.projectId})`);
4815
+ if (project.description) logger$3.log(` ${project.description}`);
5282
4816
  }
5283
4817
  } else if (resource === "registries") {
5284
- logger$4.log(`\n🐳 Registries in ${endpoint}:`);
4818
+ logger$3.log(`\n🐳 Registries in ${endpoint}:`);
5285
4819
  const registries = await api.listRegistries();
5286
4820
  if (registries.length === 0) {
5287
- logger$4.log(" No registries configured");
5288
- logger$4.log(" Run \"gkm registry:setup\" to configure a registry");
4821
+ logger$3.log(" No registries configured");
4822
+ logger$3.log(" Run \"gkm registry:setup\" to configure a registry");
5289
4823
  return;
5290
4824
  }
5291
4825
  const storedRegistryId = await require_credentials.getDokployRegistryId();
5292
4826
  for (const registry of registries) {
5293
4827
  const isDefault = registry.registryId === storedRegistryId;
5294
4828
  const marker = isDefault ? " (default)" : "";
5295
- logger$4.log(`\n ${registry.registryName}${marker} (${registry.registryId})`);
5296
- logger$4.log(` URL: ${registry.registryUrl}`);
5297
- logger$4.log(` Username: ${registry.username}`);
5298
- if (registry.imagePrefix) logger$4.log(` Prefix: ${registry.imagePrefix}`);
4829
+ logger$3.log(`\n ${registry.registryName}${marker} (${registry.registryId})`);
4830
+ logger$3.log(` URL: ${registry.registryUrl}`);
4831
+ logger$3.log(` Username: ${registry.username}`);
4832
+ if (registry.imagePrefix) logger$3.log(` Prefix: ${registry.imagePrefix}`);
5299
4833
  }
5300
4834
  }
5301
4835
  }
@@ -5318,20 +4852,20 @@ function isStateProvider(value) {
5318
4852
  async function createStateProvider(options) {
5319
4853
  const { config, workspaceRoot, workspaceName } = options;
5320
4854
  if (!config) {
5321
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
4855
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CalzNfNA.cjs"));
5322
4856
  return new LocalStateProvider(workspaceRoot);
5323
4857
  }
5324
4858
  if (isStateProvider(config.provider)) return config.provider;
5325
4859
  const provider = config.provider;
5326
4860
  if (provider === "local") {
5327
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
4861
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CalzNfNA.cjs"));
5328
4862
  return new LocalStateProvider(workspaceRoot);
5329
4863
  }
5330
4864
  if (provider === "ssm") {
5331
4865
  if (!workspaceName) throw new Error("Workspace name is required for SSM state provider. Set \"name\" in gkm.config.ts.");
5332
- const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
5333
- const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-CT8tjl9o.cjs"));
5334
- const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-37pG1HBx.cjs"));
4866
+ const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CalzNfNA.cjs"));
4867
+ const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-Bt6r8CTL.cjs"));
4868
+ const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-BdX7klRc.cjs"));
5335
4869
  const ssmConfig = config;
5336
4870
  const local = new LocalStateProvider(workspaceRoot);
5337
4871
  const ssm = SSMStateProvider.create({
@@ -5791,7 +5325,7 @@ async function sniffAllApps(apps, workspacePath, options = {}) {
5791
5325
 
5792
5326
  //#endregion
5793
5327
  //#region src/deploy/index.ts
5794
- const logger$3 = console;
5328
+ const logger$2 = console;
5795
5329
  /**
5796
5330
  * Prompt for input
5797
5331
  */
@@ -5799,7 +5333,7 @@ async function prompt(message, hidden = false) {
5799
5333
  if (!process.stdin.isTTY) throw new Error("Interactive input required. Please configure manually.");
5800
5334
  if (hidden) {
5801
5335
  process.stdout.write(message);
5802
- return new Promise((resolve$4) => {
5336
+ return new Promise((resolve$3) => {
5803
5337
  let value = "";
5804
5338
  const onData = (char) => {
5805
5339
  const c = char.toString();
@@ -5808,7 +5342,7 @@ async function prompt(message, hidden = false) {
5808
5342
  process.stdin.pause();
5809
5343
  process.stdin.removeListener("data", onData);
5810
5344
  process.stdout.write("\n");
5811
- resolve$4(value);
5345
+ resolve$3(value);
5812
5346
  } else if (c === "") {
5813
5347
  process.stdin.setRawMode(false);
5814
5348
  process.stdin.pause();
@@ -5863,7 +5397,7 @@ async function waitForPostgres(host, port, user, password, database, maxRetries
5863
5397
  return;
5864
5398
  } catch {
5865
5399
  if (i < maxRetries - 1) {
5866
- logger$3.log(` Waiting for Postgres... (${i + 1}/${maxRetries})`);
5400
+ logger$2.log(` Waiting for Postgres... (${i + 1}/${maxRetries})`);
5867
5401
  await new Promise((r) => setTimeout(r, retryIntervalMs));
5868
5402
  }
5869
5403
  }
@@ -5898,12 +5432,12 @@ async function waitForPostgres(host, port, user, password, database, maxRetries
5898
5432
  * ```
5899
5433
  */
5900
5434
  async function initializePostgresUsers(api, postgres, serverHostname, users) {
5901
- logger$3.log("\n🔧 Initializing database users...");
5435
+ logger$2.log("\n🔧 Initializing database users...");
5902
5436
  const externalPort = 5432;
5903
- logger$3.log(` Enabling external port ${externalPort}...`);
5437
+ logger$2.log(` Enabling external port ${externalPort}...`);
5904
5438
  await api.savePostgresExternalPort(postgres.postgresId, externalPort);
5905
5439
  await api.deployPostgres(postgres.postgresId);
5906
- logger$3.log(` Waiting for Postgres to be accessible at ${serverHostname}:${externalPort}...`);
5440
+ logger$2.log(` Waiting for Postgres to be accessible at ${serverHostname}:${externalPort}...`);
5907
5441
  await waitForPostgres(serverHostname, externalPort, postgres.databaseUser, postgres.databasePassword, postgres.databaseName);
5908
5442
  const client = new pg.Client({
5909
5443
  host: serverHostname,
@@ -5916,7 +5450,7 @@ async function initializePostgresUsers(api, postgres, serverHostname, users) {
5916
5450
  await client.connect();
5917
5451
  for (const user of users) {
5918
5452
  const schemaName = user.usePublicSchema ? "public" : user.name;
5919
- logger$3.log(` Creating user "${user.name}" with schema "${schemaName}"...`);
5453
+ logger$2.log(` Creating user "${user.name}" with schema "${schemaName}"...`);
5920
5454
  if (user.usePublicSchema) {
5921
5455
  await client.query(`
5922
5456
  DO $$ BEGIN
@@ -5951,15 +5485,15 @@ async function initializePostgresUsers(api, postgres, serverHostname, users) {
5951
5485
  ALTER DEFAULT PRIVILEGES IN SCHEMA "${schemaName}" GRANT ALL ON TABLES TO "${user.name}";
5952
5486
  `);
5953
5487
  }
5954
- logger$3.log(` ✓ User "${user.name}" configured`);
5488
+ logger$2.log(` ✓ User "${user.name}" configured`);
5955
5489
  }
5956
5490
  } finally {
5957
5491
  await client.end();
5958
5492
  }
5959
- logger$3.log(" Disabling external port...");
5493
+ logger$2.log(" Disabling external port...");
5960
5494
  await api.savePostgresExternalPort(postgres.postgresId, null);
5961
5495
  await api.deployPostgres(postgres.postgresId);
5962
- logger$3.log(" ✓ Database users initialized");
5496
+ logger$2.log(" ✓ Database users initialized");
5963
5497
  }
5964
5498
  /**
5965
5499
  * Get the server hostname from the Dokploy endpoint URL
@@ -5973,24 +5507,24 @@ function getServerHostname(endpoint) {
5973
5507
  * @internal Exported for testing
5974
5508
  */
5975
5509
  async function provisionServices(api, projectId, environmentId, projectName, services, existingServiceIds) {
5976
- logger$3.log(`\n🔍 provisionServices called: services=${JSON.stringify(services)}, envId=${environmentId}`);
5510
+ logger$2.log(`\n🔍 provisionServices called: services=${JSON.stringify(services)}, envId=${environmentId}`);
5977
5511
  if (!services || !environmentId) {
5978
- logger$3.log(" Skipping: no services or no environmentId");
5512
+ logger$2.log(" Skipping: no services or no environmentId");
5979
5513
  return void 0;
5980
5514
  }
5981
5515
  const serviceUrls = {};
5982
5516
  const serviceIds = {};
5983
5517
  if (services.postgres) {
5984
- logger$3.log("\n🐘 Checking PostgreSQL...");
5518
+ logger$2.log("\n🐘 Checking PostgreSQL...");
5985
5519
  const postgresName = "db";
5986
5520
  try {
5987
5521
  let postgres = null;
5988
5522
  let created = false;
5989
5523
  if (existingServiceIds?.postgresId) {
5990
- logger$3.log(` Using cached ID: ${existingServiceIds.postgresId}`);
5524
+ logger$2.log(` Using cached ID: ${existingServiceIds.postgresId}`);
5991
5525
  postgres = await api.getPostgres(existingServiceIds.postgresId);
5992
- if (postgres) logger$3.log(` ✓ PostgreSQL found: ${postgres.postgresId}`);
5993
- else logger$3.log(` ⚠ Cached ID invalid, will create new`);
5526
+ if (postgres) logger$2.log(` ✓ PostgreSQL found: ${postgres.postgresId}`);
5527
+ else logger$2.log(` ⚠ Cached ID invalid, will create new`);
5994
5528
  }
5995
5529
  if (!postgres) {
5996
5530
  const databasePassword = (0, node_crypto.randomBytes)(16).toString("hex");
@@ -6002,10 +5536,10 @@ async function provisionServices(api, projectId, environmentId, projectName, ser
6002
5536
  postgres = result.postgres;
6003
5537
  created = result.created;
6004
5538
  if (created) {
6005
- logger$3.log(` ✓ Created PostgreSQL: ${postgres.postgresId}`);
5539
+ logger$2.log(` ✓ Created PostgreSQL: ${postgres.postgresId}`);
6006
5540
  await api.deployPostgres(postgres.postgresId);
6007
- logger$3.log(" ✓ PostgreSQL deployed");
6008
- } else logger$3.log(` ✓ PostgreSQL already exists: ${postgres.postgresId}`);
5541
+ logger$2.log(" ✓ PostgreSQL deployed");
5542
+ } else logger$2.log(` ✓ PostgreSQL already exists: ${postgres.postgresId}`);
6009
5543
  }
6010
5544
  serviceIds.postgresId = postgres.postgresId;
6011
5545
  serviceUrls.DATABASE_HOST = postgres.appName;
@@ -6014,23 +5548,23 @@ async function provisionServices(api, projectId, environmentId, projectName, ser
6014
5548
  serviceUrls.DATABASE_USER = postgres.databaseUser;
6015
5549
  serviceUrls.DATABASE_PASSWORD = postgres.databasePassword;
6016
5550
  serviceUrls.DATABASE_URL = `postgresql://${postgres.databaseUser}:${postgres.databasePassword}@${postgres.appName}:5432/${postgres.databaseName}`;
6017
- logger$3.log(` ✓ Database credentials configured`);
5551
+ logger$2.log(` ✓ Database credentials configured`);
6018
5552
  } catch (error) {
6019
5553
  const message = error instanceof Error ? error.message : "Unknown error";
6020
- logger$3.log(` ⚠ Failed to provision PostgreSQL: ${message}`);
5554
+ logger$2.log(` ⚠ Failed to provision PostgreSQL: ${message}`);
6021
5555
  }
6022
5556
  }
6023
5557
  if (services.redis) {
6024
- logger$3.log("\n🔴 Checking Redis...");
5558
+ logger$2.log("\n🔴 Checking Redis...");
6025
5559
  const redisName = "cache";
6026
5560
  try {
6027
5561
  let redis = null;
6028
5562
  let created = false;
6029
5563
  if (existingServiceIds?.redisId) {
6030
- logger$3.log(` Using cached ID: ${existingServiceIds.redisId}`);
5564
+ logger$2.log(` Using cached ID: ${existingServiceIds.redisId}`);
6031
5565
  redis = await api.getRedis(existingServiceIds.redisId);
6032
- if (redis) logger$3.log(` ✓ Redis found: ${redis.redisId}`);
6033
- else logger$3.log(` ⚠ Cached ID invalid, will create new`);
5566
+ if (redis) logger$2.log(` ✓ Redis found: ${redis.redisId}`);
5567
+ else logger$2.log(` ⚠ Cached ID invalid, will create new`);
6034
5568
  }
6035
5569
  if (!redis) {
6036
5570
  const { randomBytes: randomBytes$2 } = await import("node:crypto");
@@ -6039,10 +5573,10 @@ async function provisionServices(api, projectId, environmentId, projectName, ser
6039
5573
  redis = result.redis;
6040
5574
  created = result.created;
6041
5575
  if (created) {
6042
- logger$3.log(` ✓ Created Redis: ${redis.redisId}`);
5576
+ logger$2.log(` ✓ Created Redis: ${redis.redisId}`);
6043
5577
  await api.deployRedis(redis.redisId);
6044
- logger$3.log(" ✓ Redis deployed");
6045
- } else logger$3.log(` ✓ Redis already exists: ${redis.redisId}`);
5578
+ logger$2.log(" ✓ Redis deployed");
5579
+ } else logger$2.log(` ✓ Redis already exists: ${redis.redisId}`);
6046
5580
  }
6047
5581
  serviceIds.redisId = redis.redisId;
6048
5582
  serviceUrls.REDIS_HOST = redis.appName;
@@ -6050,10 +5584,10 @@ async function provisionServices(api, projectId, environmentId, projectName, ser
6050
5584
  if (redis.databasePassword) serviceUrls.REDIS_PASSWORD = redis.databasePassword;
6051
5585
  const password = redis.databasePassword ? `:${redis.databasePassword}@` : "";
6052
5586
  serviceUrls.REDIS_URL = `redis://${password}${redis.appName}:6379`;
6053
- logger$3.log(` ✓ Redis credentials configured`);
5587
+ logger$2.log(` ✓ Redis credentials configured`);
6054
5588
  } catch (error) {
6055
5589
  const message = error instanceof Error ? error.message : "Unknown error";
6056
- logger$3.log(` ⚠ Failed to provision Redis: ${message}`);
5590
+ logger$2.log(` ⚠ Failed to provision Redis: ${message}`);
6057
5591
  }
6058
5592
  }
6059
5593
  return Object.keys(serviceUrls).length > 0 ? {
@@ -6065,10 +5599,10 @@ async function provisionServices(api, projectId, environmentId, projectName, ser
6065
5599
  * Ensure Dokploy is fully configured, recovering/creating resources as needed
6066
5600
  */
6067
5601
  async function ensureDokploySetup(config, dockerConfig, stage, services) {
6068
- logger$3.log("\n🔧 Checking Dokploy setup...");
5602
+ logger$2.log("\n🔧 Checking Dokploy setup...");
6069
5603
  let creds = await require_credentials.getDokployCredentials();
6070
5604
  if (!creds) {
6071
- logger$3.log("\n📋 Dokploy credentials not found. Let's set them up.");
5605
+ logger$2.log("\n📋 Dokploy credentials not found. Let's set them up.");
6072
5606
  const endpoint = await prompt("Dokploy URL (e.g., https://dokploy.example.com): ");
6073
5607
  const normalizedEndpoint = endpoint.replace(/\/$/, "");
6074
5608
  try {
@@ -6076,9 +5610,9 @@ async function ensureDokploySetup(config, dockerConfig, stage, services) {
6076
5610
  } catch {
6077
5611
  throw new Error("Invalid URL format");
6078
5612
  }
6079
- logger$3.log(`\nGenerate a token at: ${normalizedEndpoint}/settings/profile\n`);
5613
+ logger$2.log(`\nGenerate a token at: ${normalizedEndpoint}/settings/profile\n`);
6080
5614
  const token = await prompt("API Token: ", true);
6081
- logger$3.log("\nValidating credentials...");
5615
+ logger$2.log("\nValidating credentials...");
6082
5616
  const isValid = await validateDokployToken(normalizedEndpoint, token);
6083
5617
  if (!isValid) throw new Error("Invalid credentials. Please check your token.");
6084
5618
  await require_credentials.storeDokployCredentials(token, normalizedEndpoint);
@@ -6086,7 +5620,7 @@ async function ensureDokploySetup(config, dockerConfig, stage, services) {
6086
5620
  token,
6087
5621
  endpoint: normalizedEndpoint
6088
5622
  };
6089
- logger$3.log("✓ Credentials saved");
5623
+ logger$2.log("✓ Credentials saved");
6090
5624
  }
6091
5625
  const api = new require_dokploy_api.DokployApi({
6092
5626
  baseUrl: creds.endpoint,
@@ -6094,20 +5628,20 @@ async function ensureDokploySetup(config, dockerConfig, stage, services) {
6094
5628
  });
6095
5629
  const existingConfig = config.providers?.dokploy;
6096
5630
  if (existingConfig && typeof existingConfig !== "boolean" && existingConfig.applicationId && existingConfig.projectId) {
6097
- logger$3.log("✓ Dokploy config found in gkm.config.ts");
5631
+ logger$2.log("✓ Dokploy config found in gkm.config.ts");
6098
5632
  try {
6099
5633
  const projectDetails = await api.getProject(existingConfig.projectId);
6100
- logger$3.log("✓ Project verified");
5634
+ logger$2.log("✓ Project verified");
6101
5635
  const storedRegistryId = existingConfig.registryId ?? await require_credentials.getDokployRegistryId();
6102
5636
  const environments = projectDetails.environments ?? [];
6103
5637
  let environment = environments.find((e) => e.name.toLowerCase() === stage.toLowerCase());
6104
5638
  if (!environment) {
6105
- logger$3.log(` Creating "${stage}" environment...`);
5639
+ logger$2.log(` Creating "${stage}" environment...`);
6106
5640
  environment = await api.createEnvironment(existingConfig.projectId, stage);
6107
- logger$3.log(` ✓ Created environment: ${environment.environmentId}`);
5641
+ logger$2.log(` ✓ Created environment: ${environment.environmentId}`);
6108
5642
  }
6109
5643
  const environmentId$1 = environment.environmentId;
6110
- logger$3.log(` Services config: ${JSON.stringify(services)}, envId: ${environmentId$1}`);
5644
+ logger$2.log(` Services config: ${JSON.stringify(services)}, envId: ${environmentId$1}`);
6111
5645
  const provisionResult$1 = await provisionServices(api, existingConfig.projectId, environmentId$1, dockerConfig.appName, services, void 0);
6112
5646
  return {
6113
5647
  config: {
@@ -6120,97 +5654,97 @@ async function ensureDokploySetup(config, dockerConfig, stage, services) {
6120
5654
  serviceUrls: provisionResult$1?.serviceUrls
6121
5655
  };
6122
5656
  } catch {
6123
- logger$3.log("⚠ Project not found, will recover...");
5657
+ logger$2.log("⚠ Project not found, will recover...");
6124
5658
  }
6125
5659
  }
6126
- logger$3.log("\n📁 Looking for project...");
5660
+ logger$2.log("\n📁 Looking for project...");
6127
5661
  const projectName = dockerConfig.projectName;
6128
5662
  const projects = await api.listProjects();
6129
5663
  let project = projects.find((p) => p.name.toLowerCase() === projectName.toLowerCase());
6130
5664
  let environmentId;
6131
5665
  if (project) {
6132
- logger$3.log(` Found existing project: ${project.name} (${project.projectId})`);
5666
+ logger$2.log(` Found existing project: ${project.name} (${project.projectId})`);
6133
5667
  const projectDetails = await api.getProject(project.projectId);
6134
5668
  const environments = projectDetails.environments ?? [];
6135
5669
  const matchingEnv = environments.find((e) => e.name.toLowerCase() === stage.toLowerCase());
6136
5670
  if (matchingEnv) {
6137
5671
  environmentId = matchingEnv.environmentId;
6138
- logger$3.log(` Using environment: ${matchingEnv.name}`);
5672
+ logger$2.log(` Using environment: ${matchingEnv.name}`);
6139
5673
  } else {
6140
- logger$3.log(` Creating "${stage}" environment...`);
5674
+ logger$2.log(` Creating "${stage}" environment...`);
6141
5675
  const env = await api.createEnvironment(project.projectId, stage);
6142
5676
  environmentId = env.environmentId;
6143
- logger$3.log(` ✓ Created environment: ${stage}`);
5677
+ logger$2.log(` ✓ Created environment: ${stage}`);
6144
5678
  }
6145
5679
  } else {
6146
- logger$3.log(` Creating project: ${projectName}`);
5680
+ logger$2.log(` Creating project: ${projectName}`);
6147
5681
  const result = await api.createProject(projectName);
6148
5682
  project = result.project;
6149
5683
  if (result.environment.name.toLowerCase() !== stage.toLowerCase()) {
6150
- logger$3.log(` Creating "${stage}" environment...`);
5684
+ logger$2.log(` Creating "${stage}" environment...`);
6151
5685
  const env = await api.createEnvironment(project.projectId, stage);
6152
5686
  environmentId = env.environmentId;
6153
5687
  } else environmentId = result.environment.environmentId;
6154
- logger$3.log(` ✓ Created project: ${project.projectId}`);
6155
- logger$3.log(` ✓ Using environment: ${stage}`);
5688
+ logger$2.log(` ✓ Created project: ${project.projectId}`);
5689
+ logger$2.log(` ✓ Using environment: ${stage}`);
6156
5690
  }
6157
- logger$3.log("\n📦 Looking for application...");
5691
+ logger$2.log("\n📦 Looking for application...");
6158
5692
  const appName = dockerConfig.appName;
6159
5693
  let applicationId;
6160
5694
  if (existingConfig && typeof existingConfig !== "boolean" && existingConfig.applicationId) {
6161
5695
  applicationId = existingConfig.applicationId;
6162
- logger$3.log(` Using application from config: ${applicationId}`);
5696
+ logger$2.log(` Using application from config: ${applicationId}`);
6163
5697
  } else {
6164
- logger$3.log(` Creating application: ${appName}`);
5698
+ logger$2.log(` Creating application: ${appName}`);
6165
5699
  const app = await api.createApplication(appName, project.projectId, environmentId);
6166
5700
  applicationId = app.applicationId;
6167
- logger$3.log(` ✓ Created application: ${applicationId}`);
5701
+ logger$2.log(` ✓ Created application: ${applicationId}`);
6168
5702
  }
6169
- logger$3.log("\n🐳 Checking registry...");
5703
+ logger$2.log("\n🐳 Checking registry...");
6170
5704
  let registryId = await require_credentials.getDokployRegistryId();
6171
5705
  if (registryId) try {
6172
5706
  const registry = await api.getRegistry(registryId);
6173
- logger$3.log(` Using registry: ${registry.registryName}`);
5707
+ logger$2.log(` Using registry: ${registry.registryName}`);
6174
5708
  } catch {
6175
- logger$3.log(" ⚠ Stored registry not found, clearing...");
5709
+ logger$2.log(" ⚠ Stored registry not found, clearing...");
6176
5710
  registryId = void 0;
6177
5711
  await require_credentials.storeDokployRegistryId("");
6178
5712
  }
6179
5713
  if (!registryId) {
6180
5714
  const registries = await api.listRegistries();
6181
5715
  if (registries.length === 0) if (dockerConfig.registry) {
6182
- logger$3.log(" No registries found in Dokploy. Let's create one.");
6183
- logger$3.log(` Registry URL: ${dockerConfig.registry}`);
5716
+ logger$2.log(" No registries found in Dokploy. Let's create one.");
5717
+ logger$2.log(` Registry URL: ${dockerConfig.registry}`);
6184
5718
  const username = await prompt("Registry username: ");
6185
5719
  const password = await prompt("Registry password/token: ", true);
6186
5720
  const registry = await api.createRegistry("Default Registry", dockerConfig.registry, username, password);
6187
5721
  registryId = registry.registryId;
6188
5722
  await require_credentials.storeDokployRegistryId(registryId);
6189
- logger$3.log(` ✓ Registry created: ${registryId}`);
6190
- } else logger$3.log(" ⚠ No registry configured. Set docker.registry in gkm.config.ts");
5723
+ logger$2.log(` ✓ Registry created: ${registryId}`);
5724
+ } else logger$2.log(" ⚠ No registry configured. Set docker.registry in gkm.config.ts");
6191
5725
  else {
6192
- logger$3.log(" Available registries:");
5726
+ logger$2.log(" Available registries:");
6193
5727
  registries.forEach((reg, i) => {
6194
- logger$3.log(` ${i + 1}. ${reg.registryName} (${reg.registryUrl})`);
5728
+ logger$2.log(` ${i + 1}. ${reg.registryName} (${reg.registryUrl})`);
6195
5729
  });
6196
- if (dockerConfig.registry) logger$3.log(` ${registries.length + 1}. Create new registry`);
5730
+ if (dockerConfig.registry) logger$2.log(` ${registries.length + 1}. Create new registry`);
6197
5731
  const maxOption = dockerConfig.registry ? registries.length + 1 : registries.length;
6198
5732
  const selection = await prompt(` Select registry (1-${maxOption}): `);
6199
5733
  const index = parseInt(selection, 10) - 1;
6200
5734
  if (index >= 0 && index < registries.length) {
6201
5735
  registryId = registries[index].registryId;
6202
5736
  await require_credentials.storeDokployRegistryId(registryId);
6203
- logger$3.log(` ✓ Selected: ${registries[index].registryName}`);
5737
+ logger$2.log(` ✓ Selected: ${registries[index].registryName}`);
6204
5738
  } else if (dockerConfig.registry && index === registries.length) {
6205
- logger$3.log(`\n Creating new registry...`);
6206
- logger$3.log(` Registry URL: ${dockerConfig.registry}`);
5739
+ logger$2.log(`\n Creating new registry...`);
5740
+ logger$2.log(` Registry URL: ${dockerConfig.registry}`);
6207
5741
  const username = await prompt(" Registry username: ");
6208
5742
  const password = await prompt(" Registry password/token: ", true);
6209
5743
  const registry = await api.createRegistry(dockerConfig.registry.replace(/^https?:\/\//, ""), dockerConfig.registry, username, password);
6210
5744
  registryId = registry.registryId;
6211
5745
  await require_credentials.storeDokployRegistryId(registryId);
6212
- logger$3.log(` ✓ Registry created: ${registryId}`);
6213
- } else logger$3.log(" ⚠ Invalid selection, skipping registry setup");
5746
+ logger$2.log(` ✓ Registry created: ${registryId}`);
5747
+ } else logger$2.log(" ⚠ Invalid selection, skipping registry setup");
6214
5748
  }
6215
5749
  }
6216
5750
  const dokployConfig = {
@@ -6220,10 +5754,10 @@ async function ensureDokploySetup(config, dockerConfig, stage, services) {
6220
5754
  registryId: registryId ?? void 0
6221
5755
  };
6222
5756
  await updateConfig(dokployConfig);
6223
- logger$3.log("\n✅ Dokploy setup complete!");
6224
- logger$3.log(` Project: ${project.projectId}`);
6225
- logger$3.log(` Application: ${applicationId}`);
6226
- if (registryId) logger$3.log(` Registry: ${registryId}`);
5757
+ logger$2.log("\n✅ Dokploy setup complete!");
5758
+ logger$2.log(` Project: ${project.projectId}`);
5759
+ logger$2.log(` Application: ${applicationId}`);
5760
+ if (registryId) logger$2.log(` Registry: ${registryId}`);
6227
5761
  const provisionResult = await provisionServices(api, project.projectId, environmentId, dockerConfig.appName, services, void 0);
6228
5762
  return {
6229
5763
  config: dokployConfig,
@@ -6254,45 +5788,45 @@ function generateTag(stage) {
6254
5788
  async function workspaceDeployCommand(workspace, options) {
6255
5789
  const { provider, stage, tag, apps: selectedApps } = options;
6256
5790
  if (provider !== "dokploy") throw new Error(`Workspace deployment only supports Dokploy. Got: ${provider}`);
6257
- logger$3.log(`\n🚀 Deploying workspace "${workspace.name}" to Dokploy...`);
6258
- logger$3.log(` Stage: ${stage}`);
5791
+ logger$2.log(`\n🚀 Deploying workspace "${workspace.name}" to Dokploy...`);
5792
+ logger$2.log(` Stage: ${stage}`);
6259
5793
  const imageTag = tag ?? generateTag(stage);
6260
- logger$3.log(` Tag: ${imageTag}`);
5794
+ logger$2.log(` Tag: ${imageTag}`);
6261
5795
  const buildOrder = require_workspace.getAppBuildOrder(workspace);
6262
5796
  let appsToDeployNames = buildOrder;
6263
5797
  if (selectedApps && selectedApps.length > 0) {
6264
5798
  const invalidApps = selectedApps.filter((name$1) => !workspace.apps[name$1]);
6265
5799
  if (invalidApps.length > 0) throw new Error(`Unknown apps: ${invalidApps.join(", ")}\nAvailable apps: ${Object.keys(workspace.apps).join(", ")}`);
6266
5800
  appsToDeployNames = buildOrder.filter((name$1) => selectedApps.includes(name$1));
6267
- logger$3.log(` Deploying apps: ${appsToDeployNames.join(", ")}`);
6268
- } else logger$3.log(` Deploying all apps: ${appsToDeployNames.join(", ")}`);
5801
+ logger$2.log(` Deploying apps: ${appsToDeployNames.join(", ")}`);
5802
+ } else logger$2.log(` Deploying all apps: ${appsToDeployNames.join(", ")}`);
6269
5803
  const dokployApps = appsToDeployNames.filter((name$1) => {
6270
5804
  const app = workspace.apps[name$1];
6271
5805
  const target = app.resolvedDeployTarget;
6272
5806
  if (!require_workspace.isDeployTargetSupported(target)) {
6273
- logger$3.log(` ⚠️ Skipping ${name$1}: ${require_workspace.getDeployTargetError(target, name$1)}`);
5807
+ logger$2.log(` ⚠️ Skipping ${name$1}: ${require_workspace.getDeployTargetError(target, name$1)}`);
6274
5808
  return false;
6275
5809
  }
6276
5810
  return true;
6277
5811
  });
6278
5812
  if (dokployApps.length === 0) throw new Error("No apps to deploy. All selected apps have unsupported deploy targets.");
6279
5813
  appsToDeployNames = dokployApps;
6280
- logger$3.log("\n🔐 Loading secrets and analyzing environment requirements...");
5814
+ logger$2.log("\n🔐 Loading secrets and analyzing environment requirements...");
6281
5815
  const stageSecrets = await require_storage.readStageSecrets(stage, workspace.root);
6282
5816
  if (!stageSecrets) {
6283
- logger$3.log(` ⚠️ No secrets found for stage "${stage}"`);
6284
- logger$3.log(` Run "gkm secrets:init --stage ${stage}" to create secrets`);
5817
+ logger$2.log(` ⚠️ No secrets found for stage "${stage}"`);
5818
+ logger$2.log(` Run "gkm secrets:init --stage ${stage}" to create secrets`);
6285
5819
  }
6286
5820
  const sniffedApps = await sniffAllApps(workspace.apps, workspace.root);
6287
5821
  const encryptedSecrets = stageSecrets ? prepareSecretsForAllApps(stageSecrets, sniffedApps) : /* @__PURE__ */ new Map();
6288
5822
  if (stageSecrets) {
6289
5823
  const report = generateSecretsReport(encryptedSecrets, sniffedApps);
6290
- if (report.appsWithSecrets.length > 0) logger$3.log(` ✓ Encrypted secrets for: ${report.appsWithSecrets.join(", ")}`);
6291
- if (report.appsWithMissingSecrets.length > 0) for (const { appName, missing } of report.appsWithMissingSecrets) logger$3.log(` ⚠️ ${appName}: Missing secrets: ${missing.join(", ")}`);
5824
+ if (report.appsWithSecrets.length > 0) logger$2.log(` ✓ Encrypted secrets for: ${report.appsWithSecrets.join(", ")}`);
5825
+ if (report.appsWithMissingSecrets.length > 0) for (const { appName, missing } of report.appsWithMissingSecrets) logger$2.log(` ⚠️ ${appName}: Missing secrets: ${missing.join(", ")}`);
6292
5826
  }
6293
5827
  let creds = await require_credentials.getDokployCredentials();
6294
5828
  if (!creds) {
6295
- logger$3.log("\n📋 Dokploy credentials not found. Let's set them up.");
5829
+ logger$2.log("\n📋 Dokploy credentials not found. Let's set them up.");
6296
5830
  const endpoint = await prompt("Dokploy URL (e.g., https://dokploy.example.com): ");
6297
5831
  const normalizedEndpoint = endpoint.replace(/\/$/, "");
6298
5832
  try {
@@ -6300,9 +5834,9 @@ async function workspaceDeployCommand(workspace, options) {
6300
5834
  } catch {
6301
5835
  throw new Error("Invalid URL format");
6302
5836
  }
6303
- logger$3.log(`\nGenerate a token at: ${normalizedEndpoint}/settings/profile\n`);
5837
+ logger$2.log(`\nGenerate a token at: ${normalizedEndpoint}/settings/profile\n`);
6304
5838
  const token = await prompt("API Token: ", true);
6305
- logger$3.log("\nValidating credentials...");
5839
+ logger$2.log("\nValidating credentials...");
6306
5840
  const isValid = await validateDokployToken(normalizedEndpoint, token);
6307
5841
  if (!isValid) throw new Error("Invalid credentials. Please check your token.");
6308
5842
  await require_credentials.storeDokployCredentials(token, normalizedEndpoint);
@@ -6310,43 +5844,43 @@ async function workspaceDeployCommand(workspace, options) {
6310
5844
  token,
6311
5845
  endpoint: normalizedEndpoint
6312
5846
  };
6313
- logger$3.log("✓ Credentials saved");
5847
+ logger$2.log("✓ Credentials saved");
6314
5848
  }
6315
5849
  const api = new require_dokploy_api.DokployApi({
6316
5850
  baseUrl: creds.endpoint,
6317
5851
  token: creds.token
6318
5852
  });
6319
- logger$3.log("\n📁 Setting up Dokploy project...");
5853
+ logger$2.log("\n📁 Setting up Dokploy project...");
6320
5854
  const projectName = workspace.name;
6321
5855
  const projects = await api.listProjects();
6322
5856
  let project = projects.find((p) => p.name.toLowerCase() === projectName.toLowerCase());
6323
5857
  let environmentId;
6324
5858
  if (project) {
6325
- logger$3.log(` Found existing project: ${project.name}`);
5859
+ logger$2.log(` Found existing project: ${project.name}`);
6326
5860
  const projectDetails = await api.getProject(project.projectId);
6327
5861
  const environments = projectDetails.environments ?? [];
6328
5862
  const matchingEnv = environments.find((e) => e.name.toLowerCase() === stage.toLowerCase());
6329
5863
  if (matchingEnv) {
6330
5864
  environmentId = matchingEnv.environmentId;
6331
- logger$3.log(` Using environment: ${matchingEnv.name}`);
5865
+ logger$2.log(` Using environment: ${matchingEnv.name}`);
6332
5866
  } else {
6333
- logger$3.log(` Creating "${stage}" environment...`);
5867
+ logger$2.log(` Creating "${stage}" environment...`);
6334
5868
  const env = await api.createEnvironment(project.projectId, stage);
6335
5869
  environmentId = env.environmentId;
6336
- logger$3.log(` ✓ Created environment: ${stage}`);
5870
+ logger$2.log(` ✓ Created environment: ${stage}`);
6337
5871
  }
6338
5872
  } else {
6339
- logger$3.log(` Creating project: ${projectName}`);
5873
+ logger$2.log(` Creating project: ${projectName}`);
6340
5874
  const result = await api.createProject(projectName);
6341
5875
  project = result.project;
6342
5876
  if (result.environment.name.toLowerCase() !== stage.toLowerCase()) {
6343
- logger$3.log(` Creating "${stage}" environment...`);
5877
+ logger$2.log(` Creating "${stage}" environment...`);
6344
5878
  const env = await api.createEnvironment(project.projectId, stage);
6345
5879
  environmentId = env.environmentId;
6346
5880
  } else environmentId = result.environment.environmentId;
6347
- logger$3.log(` ✓ Created project: ${project.projectId}`);
5881
+ logger$2.log(` ✓ Created project: ${project.projectId}`);
6348
5882
  }
6349
- logger$3.log("\n📋 Loading deploy state...");
5883
+ logger$2.log("\n📋 Loading deploy state...");
6350
5884
  const stateProvider = await createStateProvider({
6351
5885
  config: workspace.state,
6352
5886
  workspaceRoot: workspace.root,
@@ -6354,27 +5888,27 @@ async function workspaceDeployCommand(workspace, options) {
6354
5888
  });
6355
5889
  let state = await stateProvider.read(stage);
6356
5890
  if (state) {
6357
- logger$3.log(` Found existing state for stage "${stage}"`);
5891
+ logger$2.log(` Found existing state for stage "${stage}"`);
6358
5892
  if (state.projectId !== project.projectId) {
6359
- logger$3.log(` ⚠ Project ID changed, updating state`);
5893
+ logger$2.log(` ⚠ Project ID changed, updating state`);
6360
5894
  state.projectId = project.projectId;
6361
5895
  }
6362
5896
  if (state.environmentId !== environmentId) {
6363
- logger$3.log(` ⚠ Environment ID changed, updating state`);
5897
+ logger$2.log(` ⚠ Environment ID changed, updating state`);
6364
5898
  state.environmentId = environmentId;
6365
5899
  }
6366
5900
  } else {
6367
- logger$3.log(` Creating new state for stage "${stage}"`);
5901
+ logger$2.log(` Creating new state for stage "${stage}"`);
6368
5902
  state = createEmptyState(stage, project.projectId, environmentId);
6369
5903
  }
6370
- logger$3.log("\n🐳 Checking registry...");
5904
+ logger$2.log("\n🐳 Checking registry...");
6371
5905
  let registryId = await require_credentials.getDokployRegistryId();
6372
5906
  const registry = workspace.deploy.dokploy?.registry;
6373
5907
  if (registryId) try {
6374
5908
  const reg = await api.getRegistry(registryId);
6375
- logger$3.log(` Using registry: ${reg.registryName}`);
5909
+ logger$2.log(` Using registry: ${reg.registryName}`);
6376
5910
  } catch {
6377
- logger$3.log(" ⚠ Stored registry not found, clearing...");
5911
+ logger$2.log(" ⚠ Stored registry not found, clearing...");
6378
5912
  registryId = void 0;
6379
5913
  await require_credentials.storeDokployRegistryId("");
6380
5914
  }
@@ -6383,17 +5917,17 @@ async function workspaceDeployCommand(workspace, options) {
6383
5917
  if (registries.length > 0) {
6384
5918
  registryId = registries[0].registryId;
6385
5919
  await require_credentials.storeDokployRegistryId(registryId);
6386
- logger$3.log(` Using registry: ${registries[0].registryName}`);
5920
+ logger$2.log(` Using registry: ${registries[0].registryName}`);
6387
5921
  } else if (registry) {
6388
- logger$3.log(" No registries found in Dokploy. Let's create one.");
6389
- logger$3.log(` Registry URL: ${registry}`);
5922
+ logger$2.log(" No registries found in Dokploy. Let's create one.");
5923
+ logger$2.log(` Registry URL: ${registry}`);
6390
5924
  const username = await prompt("Registry username: ");
6391
5925
  const password = await prompt("Registry password/token: ", true);
6392
5926
  const reg = await api.createRegistry("Default Registry", registry, username, password);
6393
5927
  registryId = reg.registryId;
6394
5928
  await require_credentials.storeDokployRegistryId(registryId);
6395
- logger$3.log(` ✓ Registry created: ${registryId}`);
6396
- } else logger$3.log(" ⚠ No registry configured. Set deploy.dokploy.registry in workspace config");
5929
+ logger$2.log(` ✓ Registry created: ${registryId}`);
5930
+ } else logger$2.log(" ⚠ No registry configured. Set deploy.dokploy.registry in workspace config");
6397
5931
  }
6398
5932
  const services = workspace.services;
6399
5933
  const dockerServices = {
@@ -6403,7 +5937,7 @@ async function workspaceDeployCommand(workspace, options) {
6403
5937
  let provisionedPostgres = null;
6404
5938
  let provisionedRedis = null;
6405
5939
  if (dockerServices.postgres || dockerServices.redis) {
6406
- logger$3.log("\n🔧 Provisioning infrastructure services...");
5940
+ logger$2.log("\n🔧 Provisioning infrastructure services...");
6407
5941
  const existingServiceIds = {
6408
5942
  postgresId: getPostgresId(state),
6409
5943
  redisId: getRedisId(state)
@@ -6421,7 +5955,7 @@ async function workspaceDeployCommand(workspace, options) {
6421
5955
  }
6422
5956
  }
6423
5957
  const skippedMobileApps = appsToDeployNames.filter((name$1) => workspace.apps[name$1].type === "mobile");
6424
- if (skippedMobileApps.length > 0) logger$3.log(`\n📱 Skipping ${skippedMobileApps.length} mobile app(s) — deploy via framework toolchain: ${skippedMobileApps.join(", ")}`);
5958
+ if (skippedMobileApps.length > 0) logger$2.log(`\n📱 Skipping ${skippedMobileApps.length} mobile app(s) — deploy via framework toolchain: ${skippedMobileApps.join(", ")}`);
6425
5959
  const backendApps = appsToDeployNames.filter((name$1) => workspace.apps[name$1].type === "backend");
6426
5960
  const frontendApps = appsToDeployNames.filter((name$1) => workspace.apps[name$1].type === "web");
6427
5961
  const perAppDbCredentials = /* @__PURE__ */ new Map();
@@ -6431,13 +5965,13 @@ async function workspaceDeployCommand(workspace, options) {
6431
5965
  return requirements?.requiredEnvVars.includes("DATABASE_URL");
6432
5966
  });
6433
5967
  if (appsNeedingDb.length > 0) {
6434
- logger$3.log(`\n🔐 Setting up per-app database credentials...`);
6435
- logger$3.log(` Apps needing DATABASE_URL: ${appsNeedingDb.join(", ")}`);
5968
+ logger$2.log(`\n🔐 Setting up per-app database credentials...`);
5969
+ logger$2.log(` Apps needing DATABASE_URL: ${appsNeedingDb.join(", ")}`);
6436
5970
  const existingCredentials = getAllAppCredentials(state);
6437
5971
  const usersToCreate = [];
6438
5972
  for (const appName of appsNeedingDb) {
6439
5973
  let credentials = existingCredentials[appName];
6440
- if (credentials) logger$3.log(` ${appName}: Using existing credentials from state`);
5974
+ if (credentials) logger$2.log(` ${appName}: Using existing credentials from state`);
6441
5975
  else {
6442
5976
  const password = (0, node_crypto.randomBytes)(16).toString("hex");
6443
5977
  credentials = {
@@ -6445,7 +5979,7 @@ async function workspaceDeployCommand(workspace, options) {
6445
5979
  dbPassword: password
6446
5980
  };
6447
5981
  setAppCredentials(state, appName, credentials);
6448
- logger$3.log(` ${appName}: Generated new credentials`);
5982
+ logger$2.log(` ${appName}: Generated new credentials`);
6449
5983
  }
6450
5984
  perAppDbCredentials.set(appName, credentials);
6451
5985
  usersToCreate.push({
@@ -6459,8 +5993,8 @@ async function workspaceDeployCommand(workspace, options) {
6459
5993
  }
6460
5994
  }
6461
5995
  if (workspace.deploy?.backups && provisionedPostgres) {
6462
- logger$3.log("\n💾 Provisioning backup destination...");
6463
- const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-C4noe75O.cjs"));
5996
+ logger$2.log("\n💾 Provisioning backup destination...");
5997
+ const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-B3HBN-2k.cjs"));
6464
5998
  const backupState = await provisionBackupDestination({
6465
5999
  api,
6466
6000
  projectId: project.projectId,
@@ -6468,13 +6002,13 @@ async function workspaceDeployCommand(workspace, options) {
6468
6002
  stage,
6469
6003
  config: workspace.deploy.backups,
6470
6004
  existingState: getBackupState(state),
6471
- logger: logger$3
6005
+ logger: logger$2
6472
6006
  });
6473
6007
  setBackupState(state, backupState);
6474
6008
  if (!backupState.postgresBackupId) {
6475
6009
  const backupSchedule = workspace.deploy.backups.schedule ?? "0 2 * * *";
6476
6010
  const backupRetention = workspace.deploy.backups.retention ?? 30;
6477
- logger$3.log(" Creating postgres backup schedule...");
6011
+ logger$2.log(" Creating postgres backup schedule...");
6478
6012
  const backup = await api.createPostgresBackup({
6479
6013
  schedule: backupSchedule,
6480
6014
  prefix: `${stage}/postgres`,
@@ -6485,8 +6019,8 @@ async function workspaceDeployCommand(workspace, options) {
6485
6019
  keepLatestCount: backupRetention
6486
6020
  });
6487
6021
  setPostgresBackupId(state, backup.backupId);
6488
- logger$3.log(` ✓ Postgres backup schedule created (${backupSchedule})`);
6489
- } else logger$3.log(" ✓ Using existing postgres backup schedule");
6022
+ logger$2.log(` ✓ Postgres backup schedule created (${backupSchedule})`);
6023
+ } else logger$2.log(" ✓ Using existing postgres backup schedule");
6490
6024
  }
6491
6025
  const publicUrls = {};
6492
6026
  const results = [];
@@ -6501,25 +6035,25 @@ async function workspaceDeployCommand(workspace, options) {
6501
6035
  frontendUrls.push(`https://${hostname}`);
6502
6036
  }
6503
6037
  if (backendApps.length > 0) {
6504
- logger$3.log("\n📦 PHASE 1: Deploying backend applications...");
6038
+ logger$2.log("\n📦 PHASE 1: Deploying backend applications...");
6505
6039
  for (const appName of backendApps) {
6506
6040
  const app = workspace.apps[appName];
6507
- logger$3.log(`\n ⚙️ Deploying ${appName}...`);
6041
+ logger$2.log(`\n ⚙️ Deploying ${appName}...`);
6508
6042
  try {
6509
6043
  const dokployAppName = appName;
6510
6044
  let application = null;
6511
6045
  const cachedAppId = getApplicationId(state, appName);
6512
6046
  if (cachedAppId) {
6513
- logger$3.log(` Using cached ID: ${cachedAppId}`);
6047
+ logger$2.log(` Using cached ID: ${cachedAppId}`);
6514
6048
  application = await api.getApplication(cachedAppId);
6515
- if (application) logger$3.log(` ✓ Application found: ${application.applicationId}`);
6516
- else logger$3.log(` ⚠ Cached ID invalid, will create new`);
6049
+ if (application) logger$2.log(` ✓ Application found: ${application.applicationId}`);
6050
+ else logger$2.log(` ⚠ Cached ID invalid, will create new`);
6517
6051
  }
6518
6052
  if (!application) {
6519
6053
  const result = await api.findOrCreateApplication(dokployAppName, project.projectId, environmentId);
6520
6054
  application = result.application;
6521
- if (result.created) logger$3.log(` Created application: ${application.applicationId}`);
6522
- else logger$3.log(` Found existing application: ${application.applicationId}`);
6055
+ if (result.created) logger$2.log(` Created application: ${application.applicationId}`);
6056
+ else logger$2.log(` Found existing application: ${application.applicationId}`);
6523
6057
  }
6524
6058
  setApplicationId(state, appName, application.applicationId);
6525
6059
  const appSecrets = encryptedSecrets.get(appName);
@@ -6527,11 +6061,11 @@ async function workspaceDeployCommand(workspace, options) {
6527
6061
  if (appSecrets && appSecrets.secretCount > 0) {
6528
6062
  buildArgs.push(`GKM_ENCRYPTED_CREDENTIALS=${appSecrets.payload.encrypted}`);
6529
6063
  buildArgs.push(`GKM_CREDENTIALS_IV=${appSecrets.payload.iv}`);
6530
- logger$3.log(` Encrypted ${appSecrets.secretCount} secrets`);
6064
+ logger$2.log(` Encrypted ${appSecrets.secretCount} secrets`);
6531
6065
  }
6532
6066
  const imageName = `${workspace.name}-${appName}`;
6533
6067
  const imageRef = registry ? `${registry}/${imageName}:${imageTag}` : `${imageName}:${imageTag}`;
6534
- logger$3.log(` Building Docker image: ${imageRef}`);
6068
+ logger$2.log(` Building Docker image: ${imageRef}`);
6535
6069
  await deployDocker({
6536
6070
  stage,
6537
6071
  tag: imageTag,
@@ -6581,10 +6115,10 @@ async function workspaceDeployCommand(workspace, options) {
6581
6115
  const { valid, missing, resolved } = validateEnvVars(requiredVars, envContext);
6582
6116
  if (!valid) throw new Error(formatMissingVarsError(appName, missing, stage));
6583
6117
  const envVars = Object.entries(resolved).map(([key, value]) => `${key}=${value}`);
6584
- if (Object.keys(resolved).length > 0) logger$3.log(` Resolved ${Object.keys(resolved).length} env vars: ${Object.keys(resolved).join(", ")}`);
6118
+ if (Object.keys(resolved).length > 0) logger$2.log(` Resolved ${Object.keys(resolved).length} env vars: ${Object.keys(resolved).join(", ")}`);
6585
6119
  await api.saveDockerProvider(application.applicationId, imageRef, { registryId });
6586
6120
  await api.saveApplicationEnv(application.applicationId, envVars.join("\n"));
6587
- logger$3.log(` Deploying to Dokploy...`);
6121
+ logger$2.log(` Deploying to Dokploy...`);
6588
6122
  await api.deployApplication(application.applicationId);
6589
6123
  const existingDomains = await api.getDomainsByApplicationId(application.applicationId);
6590
6124
  const existingDomain = existingDomains.find((d) => d.host === backendHost);
@@ -6592,7 +6126,7 @@ async function workspaceDeployCommand(workspace, options) {
6592
6126
  appHostnames.set(appName, backendHost);
6593
6127
  appDomainIds.set(appName, existingDomain.domainId);
6594
6128
  publicUrls[appName] = `https://${backendHost}`;
6595
- logger$3.log(` ✓ Domain: https://${backendHost} (existing)`);
6129
+ logger$2.log(` ✓ Domain: https://${backendHost} (existing)`);
6596
6130
  } else try {
6597
6131
  const domain = await api.createDomain({
6598
6132
  host: backendHost,
@@ -6604,10 +6138,10 @@ async function workspaceDeployCommand(workspace, options) {
6604
6138
  appHostnames.set(appName, backendHost);
6605
6139
  appDomainIds.set(appName, domain.domainId);
6606
6140
  publicUrls[appName] = `https://${backendHost}`;
6607
- logger$3.log(` ✓ Domain: https://${backendHost} (created)`);
6141
+ logger$2.log(` ✓ Domain: https://${backendHost} (created)`);
6608
6142
  } catch (domainError) {
6609
6143
  const message = domainError instanceof Error ? domainError.message : "Unknown error";
6610
- logger$3.log(` ⚠ Domain creation failed: ${message}`);
6144
+ logger$2.log(` ⚠ Domain creation failed: ${message}`);
6611
6145
  appHostnames.set(appName, backendHost);
6612
6146
  publicUrls[appName] = `https://${backendHost}`;
6613
6147
  }
@@ -6618,10 +6152,10 @@ async function workspaceDeployCommand(workspace, options) {
6618
6152
  applicationId: application.applicationId,
6619
6153
  imageRef
6620
6154
  });
6621
- logger$3.log(` ✓ ${appName} deployed successfully`);
6155
+ logger$2.log(` ✓ ${appName} deployed successfully`);
6622
6156
  } catch (error) {
6623
6157
  const message = error instanceof Error ? error.message : "Unknown error";
6624
- logger$3.log(` ✗ Failed to deploy ${appName}: ${message}`);
6158
+ logger$2.log(` ✗ Failed to deploy ${appName}: ${message}`);
6625
6159
  results.push({
6626
6160
  appName,
6627
6161
  type: app.type,
@@ -6633,25 +6167,25 @@ async function workspaceDeployCommand(workspace, options) {
6633
6167
  }
6634
6168
  }
6635
6169
  if (frontendApps.length > 0) {
6636
- logger$3.log("\n🌐 PHASE 2: Deploying frontend applications...");
6170
+ logger$2.log("\n🌐 PHASE 2: Deploying frontend applications...");
6637
6171
  for (const appName of frontendApps) {
6638
6172
  const app = workspace.apps[appName];
6639
- logger$3.log(`\n 🌐 Deploying ${appName}...`);
6173
+ logger$2.log(`\n 🌐 Deploying ${appName}...`);
6640
6174
  try {
6641
6175
  const dokployAppName = appName;
6642
6176
  let application = null;
6643
6177
  const cachedAppId = getApplicationId(state, appName);
6644
6178
  if (cachedAppId) {
6645
- logger$3.log(` Using cached ID: ${cachedAppId}`);
6179
+ logger$2.log(` Using cached ID: ${cachedAppId}`);
6646
6180
  application = await api.getApplication(cachedAppId);
6647
- if (application) logger$3.log(` ✓ Application found: ${application.applicationId}`);
6648
- else logger$3.log(` ⚠ Cached ID invalid, will create new`);
6181
+ if (application) logger$2.log(` ✓ Application found: ${application.applicationId}`);
6182
+ else logger$2.log(` ⚠ Cached ID invalid, will create new`);
6649
6183
  }
6650
6184
  if (!application) {
6651
6185
  const result = await api.findOrCreateApplication(dokployAppName, project.projectId, environmentId);
6652
6186
  application = result.application;
6653
- if (result.created) logger$3.log(` Created application: ${application.applicationId}`);
6654
- else logger$3.log(` Found existing application: ${application.applicationId}`);
6187
+ if (result.created) logger$2.log(` Created application: ${application.applicationId}`);
6188
+ else logger$2.log(` Found existing application: ${application.applicationId}`);
6655
6189
  }
6656
6190
  setApplicationId(state, appName, application.applicationId);
6657
6191
  const dependencyUrls = {};
@@ -6673,7 +6207,7 @@ async function workspaceDeployCommand(workspace, options) {
6673
6207
  const sniffedVars = sniffedApps.get(appName)?.requiredEnvVars ?? [];
6674
6208
  const { valid, missing, resolved } = validateEnvVars(sniffedVars, envContext);
6675
6209
  if (!valid) throw new Error(formatMissingVarsError(appName, missing, stage));
6676
- if (Object.keys(resolved).length > 0) logger$3.log(` Resolved ${Object.keys(resolved).length} env vars: ${Object.keys(resolved).join(", ")}`);
6210
+ if (Object.keys(resolved).length > 0) logger$2.log(` Resolved ${Object.keys(resolved).length} env vars: ${Object.keys(resolved).join(", ")}`);
6677
6211
  const publicPrefix = require_workspace.getPublicEnvPrefix(app.framework);
6678
6212
  const buildArgs = [];
6679
6213
  const publicUrlArgNames = [];
@@ -6683,10 +6217,10 @@ async function workspaceDeployCommand(workspace, options) {
6683
6217
  publicUrlArgNames.push(key);
6684
6218
  }
6685
6219
  }
6686
- if (buildArgs.length > 0) logger$3.log(` Build args: ${publicUrlArgNames.join(", ")}`);
6220
+ if (buildArgs.length > 0) logger$2.log(` Build args: ${publicUrlArgNames.join(", ")}`);
6687
6221
  const imageName = `${workspace.name}-${appName}`;
6688
6222
  const imageRef = registry ? `${registry}/${imageName}:${imageTag}` : `${imageName}:${imageTag}`;
6689
- logger$3.log(` Building Docker image: ${imageRef}`);
6223
+ logger$2.log(` Building Docker image: ${imageRef}`);
6690
6224
  await deployDocker({
6691
6225
  stage,
6692
6226
  tag: imageTag,
@@ -6707,7 +6241,7 @@ async function workspaceDeployCommand(workspace, options) {
6707
6241
  for (const [key, value] of Object.entries(resolved)) envVars.push(`${key}=${value}`);
6708
6242
  await api.saveDockerProvider(application.applicationId, imageRef, { registryId });
6709
6243
  await api.saveApplicationEnv(application.applicationId, envVars.join("\n"));
6710
- logger$3.log(` Deploying to Dokploy...`);
6244
+ logger$2.log(` Deploying to Dokploy...`);
6711
6245
  await api.deployApplication(application.applicationId);
6712
6246
  const existingFrontendDomains = await api.getDomainsByApplicationId(application.applicationId);
6713
6247
  const existingFrontendDomain = existingFrontendDomains.find((d) => d.host === frontendHost);
@@ -6715,7 +6249,7 @@ async function workspaceDeployCommand(workspace, options) {
6715
6249
  appHostnames.set(appName, frontendHost);
6716
6250
  appDomainIds.set(appName, existingFrontendDomain.domainId);
6717
6251
  publicUrls[appName] = `https://${frontendHost}`;
6718
- logger$3.log(` ✓ Domain: https://${frontendHost} (existing)`);
6252
+ logger$2.log(` ✓ Domain: https://${frontendHost} (existing)`);
6719
6253
  } else try {
6720
6254
  const domain = await api.createDomain({
6721
6255
  host: frontendHost,
@@ -6727,10 +6261,10 @@ async function workspaceDeployCommand(workspace, options) {
6727
6261
  appHostnames.set(appName, frontendHost);
6728
6262
  appDomainIds.set(appName, domain.domainId);
6729
6263
  publicUrls[appName] = `https://${frontendHost}`;
6730
- logger$3.log(` ✓ Domain: https://${frontendHost} (created)`);
6264
+ logger$2.log(` ✓ Domain: https://${frontendHost} (created)`);
6731
6265
  } catch (domainError) {
6732
6266
  const message = domainError instanceof Error ? domainError.message : "Unknown error";
6733
- logger$3.log(` ⚠ Domain creation failed: ${message}`);
6267
+ logger$2.log(` ⚠ Domain creation failed: ${message}`);
6734
6268
  appHostnames.set(appName, frontendHost);
6735
6269
  publicUrls[appName] = `https://${frontendHost}`;
6736
6270
  }
@@ -6741,10 +6275,10 @@ async function workspaceDeployCommand(workspace, options) {
6741
6275
  applicationId: application.applicationId,
6742
6276
  imageRef
6743
6277
  });
6744
- logger$3.log(` ✓ ${appName} deployed successfully`);
6278
+ logger$2.log(` ✓ ${appName} deployed successfully`);
6745
6279
  } catch (error) {
6746
6280
  const message = error instanceof Error ? error.message : "Unknown error";
6747
- logger$3.log(` ✗ Failed to deploy ${appName}: ${message}`);
6281
+ logger$2.log(` ✗ Failed to deploy ${appName}: ${message}`);
6748
6282
  results.push({
6749
6283
  appName,
6750
6284
  type: app.type,
@@ -6754,9 +6288,9 @@ async function workspaceDeployCommand(workspace, options) {
6754
6288
  }
6755
6289
  }
6756
6290
  }
6757
- logger$3.log("\n📋 Saving deploy state...");
6291
+ logger$2.log("\n📋 Saving deploy state...");
6758
6292
  await stateProvider.write(stage, state);
6759
- logger$3.log(" ✓ State saved");
6293
+ logger$2.log(" ✓ State saved");
6760
6294
  const dnsConfig = workspace.deploy.dns;
6761
6295
  if (dnsConfig && appHostnames.size > 0) {
6762
6296
  const dnsResult = await orchestrateDns(appHostnames, dnsConfig, creds.endpoint);
@@ -6765,27 +6299,27 @@ async function workspaceDeployCommand(workspace, options) {
6765
6299
  await stateProvider.write(stage, state);
6766
6300
  }
6767
6301
  if (dnsResult?.success && appHostnames.size > 0) {
6768
- logger$3.log("\n🔒 Validating domains for SSL certificates...");
6302
+ logger$2.log("\n🔒 Validating domains for SSL certificates...");
6769
6303
  for (const [appName, hostname] of appHostnames) try {
6770
6304
  const result = await api.validateDomain(hostname);
6771
- if (result.isValid) logger$3.log(` ✓ ${appName}: ${hostname} → ${result.resolvedIp}`);
6772
- else logger$3.log(` ⚠ ${appName}: ${hostname} not valid`);
6305
+ if (result.isValid) logger$2.log(` ✓ ${appName}: ${hostname} → ${result.resolvedIp}`);
6306
+ else logger$2.log(` ⚠ ${appName}: ${hostname} not valid`);
6773
6307
  } catch (validationError) {
6774
6308
  const message = validationError instanceof Error ? validationError.message : "Unknown error";
6775
- logger$3.log(` ⚠ ${appName}: validation failed - ${message}`);
6309
+ logger$2.log(` ⚠ ${appName}: validation failed - ${message}`);
6776
6310
  }
6777
6311
  }
6778
6312
  }
6779
6313
  const successCount = results.filter((r) => r.success).length;
6780
6314
  const failedCount = results.filter((r) => !r.success).length;
6781
- logger$3.log(`\n${"─".repeat(50)}`);
6782
- logger$3.log(`\n✅ Workspace deployment complete!`);
6783
- logger$3.log(` Project: ${project.projectId}`);
6784
- logger$3.log(` Successful: ${successCount}`);
6785
- if (failedCount > 0) logger$3.log(` Failed: ${failedCount}`);
6315
+ logger$2.log(`\n${"─".repeat(50)}`);
6316
+ logger$2.log(`\n✅ Workspace deployment complete!`);
6317
+ logger$2.log(` Project: ${project.projectId}`);
6318
+ logger$2.log(` Successful: ${successCount}`);
6319
+ if (failedCount > 0) logger$2.log(` Failed: ${failedCount}`);
6786
6320
  if (Object.keys(publicUrls).length > 0) {
6787
- logger$3.log("\n 📡 Deployed URLs:");
6788
- for (const [name$1, url] of Object.entries(publicUrls)) logger$3.log(` ${name$1}: ${url}`);
6321
+ logger$2.log("\n 📡 Deployed URLs:");
6322
+ for (const [name$1, url] of Object.entries(publicUrls)) logger$2.log(` ${name$1}: ${url}`);
6789
6323
  }
6790
6324
  return {
6791
6325
  apps: results,
@@ -6801,14 +6335,14 @@ async function deployCommand(options) {
6801
6335
  const { provider, stage, tag, skipPush, skipBuild } = options;
6802
6336
  const loadedConfig = await require_config.loadWorkspaceConfig();
6803
6337
  if (loadedConfig.type === "workspace") {
6804
- logger$3.log("📦 Detected workspace configuration");
6338
+ logger$2.log("📦 Detected workspace configuration");
6805
6339
  return workspaceDeployCommand(loadedConfig.workspace, options);
6806
6340
  }
6807
- logger$3.log(`\n🚀 Deploying to ${provider}...`);
6808
- logger$3.log(` Stage: ${stage}`);
6341
+ logger$2.log(`\n🚀 Deploying to ${provider}...`);
6342
+ logger$2.log(` Stage: ${stage}`);
6809
6343
  const config = await require_config.loadConfig();
6810
6344
  const imageTag = tag ?? generateTag(stage);
6811
- logger$3.log(` Tag: ${imageTag}`);
6345
+ logger$2.log(` Tag: ${imageTag}`);
6812
6346
  const dockerConfig = resolveDockerConfig(config);
6813
6347
  const imageName = dockerConfig.imageName;
6814
6348
  const registry = dockerConfig.registry;
@@ -6817,7 +6351,7 @@ async function deployCommand(options) {
6817
6351
  let finalRegistry = registry;
6818
6352
  if (provider === "dokploy") {
6819
6353
  const composeServices = config.docker?.compose?.services;
6820
- logger$3.log(`\n🔍 Docker compose config: ${JSON.stringify(config.docker?.compose)}`);
6354
+ logger$2.log(`\n🔍 Docker compose config: ${JSON.stringify(config.docker?.compose)}`);
6821
6355
  const dockerServices = composeServices ? Array.isArray(composeServices) ? {
6822
6356
  postgres: composeServices.includes("postgres"),
6823
6357
  redis: composeServices.includes("redis"),
@@ -6834,7 +6368,7 @@ async function deployCommand(options) {
6834
6368
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1, initStageSecrets } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
6835
6369
  let secrets = await readStageSecrets$1(stage);
6836
6370
  if (!secrets) {
6837
- logger$3.log(` Creating secrets file for stage "${stage}"...`);
6371
+ logger$2.log(` Creating secrets file for stage "${stage}"...`);
6838
6372
  secrets = initStageSecrets(stage);
6839
6373
  }
6840
6374
  let updated = false;
@@ -6849,12 +6383,12 @@ async function deployCommand(options) {
6849
6383
  const urlKey = key;
6850
6384
  if (!secrets.urls[urlKey]) {
6851
6385
  secrets.urls[urlKey] = value;
6852
- logger$3.log(` Saved ${key} to secrets.urls`);
6386
+ logger$2.log(` Saved ${key} to secrets.urls`);
6853
6387
  updated = true;
6854
6388
  }
6855
6389
  } else if (!secrets.custom[key]) {
6856
6390
  secrets.custom[key] = value;
6857
- logger$3.log(` Saved ${key} to secrets.custom`);
6391
+ logger$2.log(` Saved ${key} to secrets.custom`);
6858
6392
  updated = true;
6859
6393
  }
6860
6394
  }
@@ -6863,14 +6397,14 @@ async function deployCommand(options) {
6863
6397
  }
6864
6398
  let masterKey;
6865
6399
  if (!skipBuild) {
6866
- logger$3.log(`\n📦 Building for production...`);
6400
+ logger$2.log(`\n📦 Building for production...`);
6867
6401
  const buildResult = await buildCommand({
6868
6402
  provider: "server",
6869
6403
  production: true,
6870
6404
  stage
6871
6405
  });
6872
6406
  masterKey = buildResult.masterKey;
6873
- } else logger$3.log(`\n⏭️ Skipping build (--skip-build)`);
6407
+ } else logger$2.log(`\n⏭️ Skipping build (--skip-build)`);
6874
6408
  let result;
6875
6409
  switch (provider) {
6876
6410
  case "docker": {
@@ -6906,8 +6440,8 @@ async function deployCommand(options) {
6906
6440
  break;
6907
6441
  }
6908
6442
  case "aws-lambda": {
6909
- logger$3.log("\n⚠️ AWS Lambda deployment is not yet implemented.");
6910
- logger$3.log(" Use SST or AWS CDK for Lambda deployments.");
6443
+ logger$2.log("\n⚠️ AWS Lambda deployment is not yet implemented.");
6444
+ logger$2.log(" Use SST or AWS CDK for Lambda deployments.");
6911
6445
  result = {
6912
6446
  imageRef,
6913
6447
  masterKey
@@ -6916,7 +6450,7 @@ async function deployCommand(options) {
6916
6450
  }
6917
6451
  default: throw new Error(`Unknown deploy provider: ${provider}\nSupported providers: docker, dokploy, aws-lambda`);
6918
6452
  }
6919
- logger$3.log("\n✅ Deployment complete!");
6453
+ logger$2.log("\n✅ Deployment complete!");
6920
6454
  return result;
6921
6455
  }
6922
6456
 
@@ -7113,22 +6647,22 @@ const GEEKMIDAS_VERSIONS = {
7113
6647
  "@geekmidas/audit": "~2.0.1",
7114
6648
  "@geekmidas/auth": "~2.0.1",
7115
6649
  "@geekmidas/cache": "~1.1.1",
7116
- "@geekmidas/client": "~5.0.0",
6650
+ "@geekmidas/client": "~6.0.0",
7117
6651
  "@geekmidas/cloud": "~1.0.1",
7118
- "@geekmidas/constructs": "~3.1.0",
6652
+ "@geekmidas/constructs": "~4.0.0",
7119
6653
  "@geekmidas/db": "~1.0.2",
7120
6654
  "@geekmidas/emailkit": "~1.0.1",
7121
6655
  "@geekmidas/envkit": "~1.0.7",
7122
6656
  "@geekmidas/errors": "~1.0.1",
7123
6657
  "@geekmidas/events": "~1.1.4",
7124
6658
  "@geekmidas/logger": "~1.0.2",
7125
- "@geekmidas/rate-limit": "~2.0.1",
6659
+ "@geekmidas/rate-limit": "~3.0.0",
7126
6660
  "@geekmidas/schema": "~1.0.2",
7127
- "@geekmidas/services": "~1.0.4",
6661
+ "@geekmidas/services": "~1.1.1",
7128
6662
  "@geekmidas/storage": "~2.0.3",
7129
6663
  "@geekmidas/studio": "~1.0.1",
7130
6664
  "@geekmidas/telescope": "~1.0.1",
7131
- "@geekmidas/testkit": "~1.0.9",
6665
+ "@geekmidas/testkit": "~2.0.0",
7132
6666
  "@geekmidas/cli": CLI_VERSION
7133
6667
  };
7134
6668
 
@@ -12868,7 +12402,7 @@ function printNextSteps(projectName, options, pkgManager) {
12868
12402
 
12869
12403
  //#endregion
12870
12404
  //#region src/secrets/index.ts
12871
- const logger$2 = console;
12405
+ const logger$1 = console;
12872
12406
  /**
12873
12407
  * Extract service names from compose config.
12874
12408
  */
@@ -12884,12 +12418,12 @@ function getServicesFromConfig(services) {
12884
12418
  async function secretsInitCommand(options) {
12885
12419
  const { stage, force } = options;
12886
12420
  if (!force && require_storage.secretsExist(stage)) {
12887
- logger$2.error(`Secrets already exist for stage "${stage}". Use --force to overwrite.`);
12421
+ logger$1.error(`Secrets already exist for stage "${stage}". Use --force to overwrite.`);
12888
12422
  process.exit(1);
12889
12423
  }
12890
12424
  const config = await require_config.loadConfig();
12891
12425
  const services = getServicesFromConfig(config.docker?.compose?.services);
12892
- if (services.length === 0) logger$2.warn("No services configured in docker.compose.services. Creating secrets with empty services.");
12426
+ if (services.length === 0) logger$1.warn("No services configured in docker.compose.services. Creating secrets with empty services.");
12893
12427
  let projectName;
12894
12428
  let workspaceSecrets;
12895
12429
  try {
@@ -12898,23 +12432,23 @@ async function secretsInitCommand(options) {
12898
12432
  const isMultiApp = Object.keys(loaded.workspace.apps).length > 1;
12899
12433
  if (isMultiApp) {
12900
12434
  workspaceSecrets = require_fullstack_secrets.generateFullstackCustomSecrets(loaded.workspace);
12901
- logger$2.log(" Detected workspace mode — generating per-app secrets");
12435
+ logger$1.log(" Detected workspace mode — generating per-app secrets");
12902
12436
  }
12903
12437
  } catch {}
12904
12438
  const secrets = require_fullstack_secrets.createStageSecrets(stage, services, { projectName });
12905
12439
  if (workspaceSecrets) secrets.custom = workspaceSecrets;
12906
12440
  await require_storage.writeStageSecrets(secrets);
12907
- logger$2.log(`\n✓ Secrets initialized for stage "${stage}"`);
12908
- logger$2.log(` Location: .gkm/secrets/${stage}.json`);
12909
- logger$2.log("\n Generated credentials for:");
12910
- for (const service of services) logger$2.log(` - ${service}`);
12911
- if (secrets.urls.DATABASE_URL) logger$2.log(`\n DATABASE_URL: ${maskUrl(secrets.urls.DATABASE_URL)}`);
12912
- if (secrets.urls.REDIS_URL) logger$2.log(` REDIS_URL: ${maskUrl(secrets.urls.REDIS_URL)}`);
12913
- if (secrets.urls.RABBITMQ_URL) logger$2.log(` RABBITMQ_URL: ${maskUrl(secrets.urls.RABBITMQ_URL)}`);
12914
- if (secrets.urls.STORAGE_ENDPOINT) logger$2.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
12915
- if (Object.keys(secrets.custom).length > 0) logger$2.log(`\n Custom secrets: ${Object.keys(secrets.custom).length}`);
12916
- logger$2.log(`\n Use "gkm secrets:show --stage ${stage}" to view secrets`);
12917
- logger$2.log(" Use \"gkm secrets:set <KEY> <VALUE> --stage " + stage + "\" to add custom secrets");
12441
+ logger$1.log(`\n✓ Secrets initialized for stage "${stage}"`);
12442
+ logger$1.log(` Location: .gkm/secrets/${stage}.json`);
12443
+ logger$1.log("\n Generated credentials for:");
12444
+ for (const service of services) logger$1.log(` - ${service}`);
12445
+ if (secrets.urls.DATABASE_URL) logger$1.log(`\n DATABASE_URL: ${maskUrl(secrets.urls.DATABASE_URL)}`);
12446
+ if (secrets.urls.REDIS_URL) logger$1.log(` REDIS_URL: ${maskUrl(secrets.urls.REDIS_URL)}`);
12447
+ if (secrets.urls.RABBITMQ_URL) logger$1.log(` RABBITMQ_URL: ${maskUrl(secrets.urls.RABBITMQ_URL)}`);
12448
+ if (secrets.urls.STORAGE_ENDPOINT) logger$1.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
12449
+ if (Object.keys(secrets.custom).length > 0) logger$1.log(`\n Custom secrets: ${Object.keys(secrets.custom).length}`);
12450
+ logger$1.log(`\n Use "gkm secrets:show --stage ${stage}" to view secrets`);
12451
+ logger$1.log(" Use \"gkm secrets:set <KEY> <VALUE> --stage " + stage + "\" to add custom secrets");
12918
12452
  }
12919
12453
  /**
12920
12454
  * Read all data from stdin.
@@ -12933,21 +12467,21 @@ async function secretsSetCommand(key, value, options) {
12933
12467
  let secretValue = value;
12934
12468
  if (!secretValue) {
12935
12469
  if (process.stdin.isTTY) {
12936
- logger$2.error("No value provided. Use: gkm secrets:set KEY VALUE --stage <stage>");
12937
- logger$2.error("Or pipe from stdin: echo \"value\" | gkm secrets:set KEY --stage <stage>");
12470
+ logger$1.error("No value provided. Use: gkm secrets:set KEY VALUE --stage <stage>");
12471
+ logger$1.error("Or pipe from stdin: echo \"value\" | gkm secrets:set KEY --stage <stage>");
12938
12472
  process.exit(1);
12939
12473
  }
12940
12474
  secretValue = await readStdin();
12941
12475
  if (!secretValue) {
12942
- logger$2.error("No value received from stdin");
12476
+ logger$1.error("No value received from stdin");
12943
12477
  process.exit(1);
12944
12478
  }
12945
12479
  }
12946
12480
  try {
12947
12481
  await require_storage.setCustomSecret(stage, key, secretValue);
12948
- logger$2.log(`\n✓ Secret "${key}" set for stage "${stage}"`);
12482
+ logger$1.log(`\n✓ Secret "${key}" set for stage "${stage}"`);
12949
12483
  } catch (error) {
12950
- logger$2.error(error instanceof Error ? error.message : "Failed to set secret");
12484
+ logger$1.error(error instanceof Error ? error.message : "Failed to set secret");
12951
12485
  process.exit(1);
12952
12486
  }
12953
12487
  }
@@ -12958,34 +12492,34 @@ async function secretsShowCommand(options) {
12958
12492
  const { stage, reveal } = options;
12959
12493
  const secrets = await require_storage.readStageSecrets(stage);
12960
12494
  if (!secrets) {
12961
- logger$2.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
12495
+ logger$1.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
12962
12496
  process.exit(1);
12963
12497
  }
12964
- logger$2.log(`\nSecrets for stage "${stage}":`);
12965
- logger$2.log(` Created: ${secrets.createdAt}`);
12966
- logger$2.log(` Updated: ${secrets.updatedAt}`);
12967
- logger$2.log("\nService Credentials:");
12498
+ logger$1.log(`\nSecrets for stage "${stage}":`);
12499
+ logger$1.log(` Created: ${secrets.createdAt}`);
12500
+ logger$1.log(` Updated: ${secrets.updatedAt}`);
12501
+ logger$1.log("\nService Credentials:");
12968
12502
  for (const [service, creds] of Object.entries(secrets.services)) if (creds) {
12969
- logger$2.log(`\n ${service}:`);
12970
- logger$2.log(` host: ${creds.host}`);
12971
- logger$2.log(` port: ${creds.port}`);
12972
- logger$2.log(` username: ${creds.username}`);
12973
- logger$2.log(` password: ${reveal ? creds.password : require_storage.maskPassword(creds.password)}`);
12974
- if (creds.database) logger$2.log(` database: ${creds.database}`);
12975
- if (creds.vhost) logger$2.log(` vhost: ${creds.vhost}`);
12976
- if (creds.bucket) logger$2.log(` bucket: ${creds.bucket}`);
12977
- }
12978
- logger$2.log("\nConnection URLs:");
12979
- if (secrets.urls.DATABASE_URL) logger$2.log(` DATABASE_URL: ${reveal ? secrets.urls.DATABASE_URL : maskUrl(secrets.urls.DATABASE_URL)}`);
12980
- if (secrets.urls.REDIS_URL) logger$2.log(` REDIS_URL: ${reveal ? secrets.urls.REDIS_URL : maskUrl(secrets.urls.REDIS_URL)}`);
12981
- if (secrets.urls.RABBITMQ_URL) logger$2.log(` RABBITMQ_URL: ${reveal ? secrets.urls.RABBITMQ_URL : maskUrl(secrets.urls.RABBITMQ_URL)}`);
12982
- if (secrets.urls.STORAGE_ENDPOINT) logger$2.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
12503
+ logger$1.log(`\n ${service}:`);
12504
+ logger$1.log(` host: ${creds.host}`);
12505
+ logger$1.log(` port: ${creds.port}`);
12506
+ logger$1.log(` username: ${creds.username}`);
12507
+ logger$1.log(` password: ${reveal ? creds.password : require_storage.maskPassword(creds.password)}`);
12508
+ if (creds.database) logger$1.log(` database: ${creds.database}`);
12509
+ if (creds.vhost) logger$1.log(` vhost: ${creds.vhost}`);
12510
+ if (creds.bucket) logger$1.log(` bucket: ${creds.bucket}`);
12511
+ }
12512
+ logger$1.log("\nConnection URLs:");
12513
+ if (secrets.urls.DATABASE_URL) logger$1.log(` DATABASE_URL: ${reveal ? secrets.urls.DATABASE_URL : maskUrl(secrets.urls.DATABASE_URL)}`);
12514
+ if (secrets.urls.REDIS_URL) logger$1.log(` REDIS_URL: ${reveal ? secrets.urls.REDIS_URL : maskUrl(secrets.urls.REDIS_URL)}`);
12515
+ if (secrets.urls.RABBITMQ_URL) logger$1.log(` RABBITMQ_URL: ${reveal ? secrets.urls.RABBITMQ_URL : maskUrl(secrets.urls.RABBITMQ_URL)}`);
12516
+ if (secrets.urls.STORAGE_ENDPOINT) logger$1.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
12983
12517
  const customKeys = Object.keys(secrets.custom);
12984
12518
  if (customKeys.length > 0) {
12985
- logger$2.log("\nCustom Secrets:");
12986
- for (const [key, value] of Object.entries(secrets.custom)) logger$2.log(` ${key}: ${reveal ? value : require_storage.maskPassword(value)}`);
12519
+ logger$1.log("\nCustom Secrets:");
12520
+ for (const [key, value] of Object.entries(secrets.custom)) logger$1.log(` ${key}: ${reveal ? value : require_storage.maskPassword(value)}`);
12987
12521
  }
12988
- if (!reveal) logger$2.log("\nUse --reveal to show actual values");
12522
+ if (!reveal) logger$1.log("\nUse --reveal to show actual values");
12989
12523
  }
12990
12524
  /**
12991
12525
  * Rotate passwords for services.
@@ -12994,25 +12528,25 @@ async function secretsRotateCommand(options) {
12994
12528
  const { stage, service } = options;
12995
12529
  const secrets = await require_storage.readStageSecrets(stage);
12996
12530
  if (!secrets) {
12997
- logger$2.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
12531
+ logger$1.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
12998
12532
  process.exit(1);
12999
12533
  }
13000
12534
  if (service) {
13001
12535
  if (!secrets.services[service]) {
13002
- logger$2.error(`Service "${service}" not configured in stage "${stage}"`);
12536
+ logger$1.error(`Service "${service}" not configured in stage "${stage}"`);
13003
12537
  process.exit(1);
13004
12538
  }
13005
12539
  const updated = require_fullstack_secrets.rotateServicePassword(secrets, service);
13006
12540
  await require_storage.writeStageSecrets(updated);
13007
- logger$2.log(`\n✓ Password rotated for ${service} in stage "${stage}"`);
12541
+ logger$1.log(`\n✓ Password rotated for ${service} in stage "${stage}"`);
13008
12542
  } else {
13009
12543
  let updated = secrets;
13010
12544
  const services = Object.keys(secrets.services);
13011
12545
  for (const svc of services) updated = require_fullstack_secrets.rotateServicePassword(updated, svc);
13012
12546
  await require_storage.writeStageSecrets(updated);
13013
- logger$2.log(`\n✓ Passwords rotated for all services in stage "${stage}": ${services.join(", ")}`);
12547
+ logger$1.log(`\n✓ Passwords rotated for all services in stage "${stage}": ${services.join(", ")}`);
13014
12548
  }
13015
- logger$2.log(`\nUse "gkm secrets:show --stage ${stage}" to view new values`);
12549
+ logger$1.log(`\nUse "gkm secrets:show --stage ${stage}" to view new values`);
13016
12550
  }
13017
12551
  /**
13018
12552
  * Import secrets from a JSON file.
@@ -13020,7 +12554,7 @@ async function secretsRotateCommand(options) {
13020
12554
  async function secretsImportCommand(file, options) {
13021
12555
  const { stage, merge = true } = options;
13022
12556
  if (!(0, node_fs.existsSync)(file)) {
13023
- logger$2.error(`File not found: ${file}`);
12557
+ logger$1.error(`File not found: ${file}`);
13024
12558
  process.exit(1);
13025
12559
  }
13026
12560
  let importedSecrets;
@@ -13030,12 +12564,12 @@ async function secretsImportCommand(file, options) {
13030
12564
  if (typeof importedSecrets !== "object" || importedSecrets === null) throw new Error("JSON must be an object");
13031
12565
  for (const [key, value] of Object.entries(importedSecrets)) if (typeof value !== "string") throw new Error(`Value for "${key}" must be a string, got ${typeof value}`);
13032
12566
  } catch (error) {
13033
- logger$2.error(`Failed to parse JSON file: ${error instanceof Error ? error.message : "Invalid JSON"}`);
12567
+ logger$1.error(`Failed to parse JSON file: ${error instanceof Error ? error.message : "Invalid JSON"}`);
13034
12568
  process.exit(1);
13035
12569
  }
13036
12570
  const secrets = await require_storage.readStageSecrets(stage);
13037
12571
  if (!secrets) {
13038
- logger$2.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
12572
+ logger$1.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
13039
12573
  process.exit(1);
13040
12574
  }
13041
12575
  const updatedCustom = merge ? {
@@ -13050,10 +12584,10 @@ async function secretsImportCommand(file, options) {
13050
12584
  await require_storage.writeStageSecrets(updated);
13051
12585
  const importedCount = Object.keys(importedSecrets).length;
13052
12586
  const totalCount = Object.keys(updatedCustom).length;
13053
- logger$2.log(`\n✓ Imported ${importedCount} secrets for stage "${stage}"`);
13054
- if (merge && totalCount > importedCount) logger$2.log(` Total custom secrets: ${totalCount}`);
13055
- logger$2.log("\n Imported keys:");
13056
- for (const key of Object.keys(importedSecrets)) logger$2.log(` - ${key}`);
12587
+ logger$1.log(`\n✓ Imported ${importedCount} secrets for stage "${stage}"`);
12588
+ if (merge && totalCount > importedCount) logger$1.log(` Total custom secrets: ${totalCount}`);
12589
+ logger$1.log("\n Imported keys:");
12590
+ for (const key of Object.keys(importedSecrets)) logger$1.log(` - ${key}`);
13057
12591
  }
13058
12592
  /**
13059
12593
  * Mask password in a URL for display.
@@ -13068,264 +12602,6 @@ function maskUrl(url) {
13068
12602
  }
13069
12603
  }
13070
12604
 
13071
- //#endregion
13072
- //#region src/setup/index.ts
13073
- const logger$1 = console;
13074
- /**
13075
- * Setup development environment.
13076
- *
13077
- * Orchestrates:
13078
- * 1. Load workspace config
13079
- * 2. Resolve secrets (local → SSM → generate fresh)
13080
- * 3. Write docker/.env from secrets
13081
- * 4. Start Docker services
13082
- */
13083
- async function setupCommand(options = {}) {
13084
- const stage = options.stage ?? "development";
13085
- logger$1.log("\n🔧 Setting up development environment...\n");
13086
- let loadedConfig;
13087
- try {
13088
- loadedConfig = await require_config.loadWorkspaceConfig();
13089
- } catch {
13090
- logger$1.error("❌ No gkm.config.ts found. Run this command from a workspace root.");
13091
- process.exit(1);
13092
- }
13093
- const { workspace } = loadedConfig;
13094
- const isMultiApp = Object.keys(workspace.apps).length > 1;
13095
- logger$1.log(`📦 Workspace: ${workspace.name}`);
13096
- logger$1.log(`📱 Apps: ${Object.keys(workspace.apps).join(", ")}`);
13097
- logger$1.log(`🔑 Stage: ${stage}\n`);
13098
- const secrets = await resolveSecrets(stage, workspace, options);
13099
- if (!secrets) {
13100
- logger$1.error("❌ Failed to resolve secrets. Exiting.");
13101
- process.exit(1);
13102
- }
13103
- if (isMultiApp && workspace.services.db) {
13104
- await require_fullstack_secrets.writeDockerEnvFromSecrets(secrets, workspace.root);
13105
- logger$1.log("📄 Generated docker/.env with database passwords");
13106
- }
13107
- if (!options.skipDocker) {
13108
- const composeFile = (0, node_path.join)(workspace.root, "docker-compose.yml");
13109
- if ((0, node_fs.existsSync)(composeFile)) {
13110
- logger$1.log("");
13111
- const resolvedPorts = await resolveServicePorts(workspace.root);
13112
- await startWorkspaceServices(workspace, resolvedPorts.dockerEnv);
13113
- } else logger$1.log("⚠️ No docker-compose.yml found. Skipping Docker services.");
13114
- }
13115
- printSummary(workspace, stage);
13116
- }
13117
- /**
13118
- * Resolve secrets with priority:
13119
- * 1. Local secrets exist → use them (preserves manual additions)
13120
- * 2. SSM configured and has secrets → pull and use
13121
- * 3. Neither → generate fresh secrets
13122
- *
13123
- * --force skips checks 1 and 2 and always regenerates.
13124
- */
13125
- async function resolveSecrets(stage, workspace, options) {
13126
- if (options.force) {
13127
- logger$1.log("🔐 Generating fresh secrets (--force)...");
13128
- return generateFreshSecrets(stage, workspace, options);
13129
- }
13130
- if (require_storage.secretsExist(stage, workspace.root)) {
13131
- logger$1.log("🔐 Using existing local secrets");
13132
- const secrets = await require_storage.readStageSecrets(stage, workspace.root);
13133
- if (secrets) {
13134
- const reconciled = reconcileSecrets(secrets, workspace);
13135
- if (reconciled) await require_storage.writeStageSecrets(reconciled, workspace.root);
13136
- return reconciled ?? secrets;
13137
- }
13138
- }
13139
- if (require_sync.isSSMConfigured(workspace)) {
13140
- logger$1.log("☁️ Checking for remote secrets in SSM...");
13141
- try {
13142
- const remoteSecrets = await require_sync.pullSecrets(stage, workspace);
13143
- if (remoteSecrets) {
13144
- logger$1.log("✅ Pulled secrets from SSM");
13145
- await require_storage.writeStageSecrets(remoteSecrets, workspace.root);
13146
- return remoteSecrets;
13147
- }
13148
- logger$1.log(" No remote secrets found");
13149
- } catch (error) {
13150
- logger$1.warn(`⚠️ Failed to pull from SSM: ${error.message}`);
13151
- }
13152
- }
13153
- logger$1.log("🔐 Generating fresh development secrets...");
13154
- return generateFreshSecrets(stage, workspace, options);
13155
- }
13156
- /**
13157
- * Reconcile existing secrets with expected workspace-derived keys.
13158
- * Adds missing keys (e.g. BETTER_AUTH_*) without overwriting existing values.
13159
- * Returns the updated secrets if changes were made, or null if no changes needed.
13160
- * @internal Exported for testing
13161
- */
13162
- function reconcileSecrets(secrets, workspace) {
13163
- let changed = false;
13164
- let result = { ...secrets };
13165
- const serviceMap = [
13166
- {
13167
- key: "db",
13168
- name: "postgres"
13169
- },
13170
- {
13171
- key: "cache",
13172
- name: "redis"
13173
- },
13174
- {
13175
- key: "storage",
13176
- name: "minio"
13177
- },
13178
- {
13179
- key: "mail",
13180
- name: "mailpit"
13181
- }
13182
- ];
13183
- for (const { key, name: name$1 } of serviceMap) if (workspace.services[key] && !result.services[name$1]) {
13184
- const creds = require_fullstack_secrets.generateServiceCredentials(name$1);
13185
- if (name$1 === "minio") {
13186
- creds.bucket = workspace.name;
13187
- creds.username = workspace.name;
13188
- }
13189
- result = {
13190
- ...result,
13191
- services: {
13192
- ...result.services,
13193
- [name$1]: creds
13194
- }
13195
- };
13196
- result.urls = require_fullstack_secrets.generateConnectionUrls(result.services, result.eventsBackend);
13197
- logger$1.log(` 🔄 Adding missing service credentials: ${name$1}`);
13198
- changed = true;
13199
- }
13200
- if (result.services.postgres && !result.services.pgboss) {
13201
- result = {
13202
- ...result,
13203
- services: {
13204
- ...result.services,
13205
- pgboss: {
13206
- host: result.services.postgres.host,
13207
- port: result.services.postgres.port,
13208
- username: "pgboss",
13209
- password: require_fullstack_secrets.generateSecurePassword(),
13210
- database: result.services.postgres.database ?? "app"
13211
- }
13212
- }
13213
- };
13214
- result.urls = require_fullstack_secrets.generateConnectionUrls(result.services, result.eventsBackend);
13215
- logger$1.log(" 🔄 Adding missing service credentials: pgboss");
13216
- changed = true;
13217
- }
13218
- const eventsBackend = workspace.services.events;
13219
- if (eventsBackend && result.eventsBackend !== eventsBackend) {
13220
- result.eventsBackend = eventsBackend;
13221
- if (eventsBackend === "sns" && !result.services.localstack) {
13222
- result = {
13223
- ...result,
13224
- services: {
13225
- ...result.services,
13226
- localstack: require_fullstack_secrets.generateLocalStackCredentials()
13227
- }
13228
- };
13229
- logger$1.log(" 🔄 Adding missing service credentials: localstack");
13230
- changed = true;
13231
- }
13232
- if (eventsBackend === "rabbitmq" && !result.services.rabbitmq) {
13233
- result = {
13234
- ...result,
13235
- services: {
13236
- ...result.services,
13237
- rabbitmq: require_fullstack_secrets.generateServiceCredentials("rabbitmq")
13238
- }
13239
- };
13240
- logger$1.log(" 🔄 Adding missing service credentials: rabbitmq");
13241
- changed = true;
13242
- }
13243
- result.urls = require_fullstack_secrets.generateConnectionUrls(result.services, eventsBackend);
13244
- changed = true;
13245
- }
13246
- const isMultiApp = Object.keys(workspace.apps).length > 1;
13247
- if (isMultiApp) {
13248
- const expected = require_fullstack_secrets.generateFullstackCustomSecrets(workspace);
13249
- const missing = {};
13250
- for (const [key, value] of Object.entries(expected)) if (!(key in result.custom)) missing[key] = value;
13251
- if (Object.keys(missing).length > 0) {
13252
- logger$1.log(` 🔄 Adding missing secrets: ${Object.keys(missing).join(", ")}`);
13253
- result = {
13254
- ...result,
13255
- custom: {
13256
- ...result.custom,
13257
- ...missing
13258
- }
13259
- };
13260
- changed = true;
13261
- }
13262
- }
13263
- if (!changed) return null;
13264
- return {
13265
- ...result,
13266
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
13267
- };
13268
- }
13269
- /**
13270
- * Generate fresh secrets for the workspace.
13271
- */
13272
- async function generateFreshSecrets(stage, workspace, options) {
13273
- const serviceNames = [];
13274
- if (workspace.services.db) serviceNames.push("postgres");
13275
- if (workspace.services.cache) serviceNames.push("redis");
13276
- if (workspace.services.storage) serviceNames.push("minio");
13277
- if (workspace.services.mail) serviceNames.push("mailpit");
13278
- if (workspace.services.events === "sns") serviceNames.push("localstack");
13279
- if (workspace.services.events === "rabbitmq") serviceNames.push("rabbitmq");
13280
- const secrets = require_fullstack_secrets.createStageSecrets(stage, serviceNames, {
13281
- projectName: workspace.name,
13282
- eventsBackend: workspace.services.events
13283
- });
13284
- const isMultiApp = Object.keys(workspace.apps).length > 1;
13285
- if (isMultiApp) {
13286
- const customSecrets = require_fullstack_secrets.generateFullstackCustomSecrets(workspace);
13287
- secrets.custom = customSecrets;
13288
- } else secrets.custom = {
13289
- NODE_ENV: "development",
13290
- PORT: "3000",
13291
- LOG_LEVEL: "debug",
13292
- JWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`
13293
- };
13294
- await require_storage.writeStageSecrets(secrets, workspace.root);
13295
- logger$1.log(` Secrets written to .gkm/secrets/${stage}.json`);
13296
- if (require_sync.isSSMConfigured(workspace) && !options.yes) {
13297
- const { shouldPush } = await (0, prompts.default)({
13298
- type: "confirm",
13299
- name: "shouldPush",
13300
- message: "Push secrets to SSM for team sharing?",
13301
- initial: true
13302
- });
13303
- if (shouldPush) try {
13304
- await require_sync.pushSecrets(stage, workspace);
13305
- logger$1.log("☁️ Secrets pushed to SSM");
13306
- } catch (error) {
13307
- logger$1.warn(`⚠️ Failed to push to SSM: ${error.message}`);
13308
- }
13309
- }
13310
- return secrets;
13311
- }
13312
- /**
13313
- * Print setup summary with next steps.
13314
- */
13315
- function printSummary(workspace, stage) {
13316
- logger$1.log(`\n${"─".repeat(50)}`);
13317
- logger$1.log("\n✅ Development environment ready!\n");
13318
- logger$1.log("📋 Apps:");
13319
- for (const [name$1, app] of Object.entries(workspace.apps)) {
13320
- const icon = app.type === "web" ? "🌐" : app.type === "mobile" ? "📱" : "🔧";
13321
- logger$1.log(` ${icon} ${name$1} → http://localhost:${app.port}`);
13322
- }
13323
- logger$1.log("\n🚀 Next steps:");
13324
- logger$1.log(" gkm dev # Start all apps");
13325
- logger$1.log(` gkm secrets:show --stage ${stage} # View secrets`);
13326
- logger$1.log("");
13327
- }
13328
-
13329
12605
  //#endregion
13330
12606
  //#region src/test/index.ts
13331
12607
  /**
@@ -13336,9 +12612,15 @@ async function testCommand(options = {}) {
13336
12612
  const stage = options.stage ?? "development";
13337
12613
  const cwd = process.cwd();
13338
12614
  console.log(`\n🧪 Running tests with ${stage} environment...\n`);
13339
- const defaultEnv = loadEnvFiles(".env");
12615
+ const autoSetup = options.autoSetup || Boolean(process.env.GKM_AUTO_SETUP);
12616
+ if (autoSetup) {
12617
+ const { ensureStageSecrets } = await Promise.resolve().then(() => require("./setup-DLwhfyt-.cjs"));
12618
+ const generated = await ensureStageSecrets(stage, cwd);
12619
+ if (generated) console.log(` 🔐 Generated fresh ${stage} secrets (auto-setup)`);
12620
+ }
12621
+ const defaultEnv = require_setup.loadEnvFiles(".env");
13340
12622
  if (defaultEnv.loaded.length > 0) console.log(` 📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
13341
- const result = await prepareEntryCredentials({
12623
+ const result = await require_setup.prepareEntryCredentials({
13342
12624
  stages: [stage],
13343
12625
  startDocker: true,
13344
12626
  secretsFileName: "test-secrets.json",
@@ -13360,7 +12642,7 @@ async function testCommand(options = {}) {
13360
12642
  await (0, node_fs_promises.writeFile)(result.secretsJsonPath, JSON.stringify(finalCredentials, null, 2));
13361
12643
  const gkmDir = (0, node_path.join)(cwd, ".gkm");
13362
12644
  const preloadPath = (0, node_path.join)(gkmDir, "test-credentials-preload.ts");
13363
- await createCredentialsPreload(preloadPath, result.secretsJsonPath);
12645
+ await require_setup.createCredentialsPreload(preloadPath, result.secretsJsonPath);
13364
12646
  const existingNodeOptions = process.env.NODE_OPTIONS ?? "";
13365
12647
  const tsxImport = "--import=tsx";
13366
12648
  const preloadImport = `--import=${preloadPath}`;
@@ -13385,9 +12667,9 @@ async function testCommand(options = {}) {
13385
12667
  NODE_OPTIONS: nodeOptions
13386
12668
  }
13387
12669
  });
13388
- return new Promise((resolve$4, reject) => {
12670
+ return new Promise((resolve$3, reject) => {
13389
12671
  vitestProcess.on("close", (code) => {
13390
- if (code === 0) resolve$4();
12672
+ if (code === 0) resolve$3();
13391
12673
  else reject(new Error(`Tests failed with exit code ${code}`));
13392
12674
  });
13393
12675
  vitestProcess.on("error", (error) => {
@@ -13580,7 +12862,7 @@ program.command("setup").description("Setup development environment (secrets, Do
13580
12862
  try {
13581
12863
  const globalOptions = program.opts();
13582
12864
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
13583
- await setupCommand(options);
12865
+ await require_setup.setupCommand(options);
13584
12866
  } catch (error) {
13585
12867
  console.error(formatError(error));
13586
12868
  process.exit(1);
@@ -13648,7 +12930,7 @@ program.command("exec").description("Run a command with secrets injected into Cr
13648
12930
  process.exit(1);
13649
12931
  }
13650
12932
  });
13651
- program.command("test").description("Run tests with secrets loaded from environment").option("--stage <stage>", "Stage to load secrets from", "development").option("--run", "Run tests once without watch mode").option("--watch", "Enable watch mode").option("--coverage", "Generate coverage report").option("--ui", "Open Vitest UI").argument("[pattern]", "Pattern to filter tests").action(async (pattern, options) => {
12933
+ program.command("test").description("Run tests with secrets loaded from environment").option("--stage <stage>", "Stage to load secrets from", "development").option("--run", "Run tests once without watch mode").option("--watch", "Enable watch mode").option("--coverage", "Generate coverage report").option("--ui", "Open Vitest UI").option("--auto-setup", "Generate a fresh stage (secrets + key) from the workspace config when none exists (for CI; also via GKM_AUTO_SETUP)").argument("[pattern]", "Pattern to filter tests").action(async (pattern, options) => {
13652
12934
  try {
13653
12935
  const globalOptions = program.opts();
13654
12936
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -13790,8 +13072,8 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
13790
13072
  const globalOptions = program.opts();
13791
13073
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
13792
13074
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
13793
- const { pushSecrets: pushSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
13794
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-D93YG7G5.cjs"));
13075
+ const { pushSecrets } = await Promise.resolve().then(() => require("./sync-BLA94rgC.cjs"));
13076
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-BzqKJ2Rt.cjs"));
13795
13077
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
13796
13078
  const { workspace } = await loadWorkspaceConfig$1();
13797
13079
  const secrets = await readStageSecrets$1(options.stage, workspace.root);
@@ -13803,7 +13085,7 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
13803
13085
  for (const key of result.addedKeys) console.log(` + ${key}`);
13804
13086
  }
13805
13087
  }
13806
- await pushSecrets$1(options.stage, workspace);
13088
+ await pushSecrets(options.stage, workspace);
13807
13089
  console.log(`\n✓ Secrets pushed for stage "${options.stage}"`);
13808
13090
  } catch (error) {
13809
13091
  console.error(formatError(error));
@@ -13815,11 +13097,11 @@ program.command("secrets:pull").description("Pull secrets from remote provider (
13815
13097
  const globalOptions = program.opts();
13816
13098
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
13817
13099
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
13818
- const { pullSecrets: pullSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
13100
+ const { pullSecrets } = await Promise.resolve().then(() => require("./sync-BLA94rgC.cjs"));
13819
13101
  const { writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
13820
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-D93YG7G5.cjs"));
13102
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-BzqKJ2Rt.cjs"));
13821
13103
  const { workspace } = await loadWorkspaceConfig$1();
13822
- let secrets = await pullSecrets$1(options.stage, workspace);
13104
+ let secrets = await pullSecrets(options.stage, workspace);
13823
13105
  if (!secrets) {
13824
13106
  console.error(`No remote secrets found for stage "${options.stage}".`);
13825
13107
  process.exit(1);
@@ -13842,7 +13124,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
13842
13124
  const globalOptions = program.opts();
13843
13125
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
13844
13126
  const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
13845
- const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-D93YG7G5.cjs"));
13127
+ const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-BzqKJ2Rt.cjs"));
13846
13128
  const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
13847
13129
  const { workspace } = await loadWorkspaceConfig$1();
13848
13130
  const secrets = await readStageSecrets$1(options.stage, workspace.root);