@geekmidas/cli 10.0.0-alpha.74 → 10.0.0-alpha.75

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/dist/{LegacyStateStore-D_78eaHM.cjs → LegacyStateStore-BFnXUFlx.cjs} +2 -2
  2. package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-BFnXUFlx.cjs.map} +1 -1
  3. package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-cpt3K1vx.mjs} +2 -2
  4. package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-cpt3K1vx.mjs.map} +1 -1
  5. package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-RH9F2ZEy.mjs} +2 -2
  6. package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-RH9F2ZEy.mjs.map} +1 -1
  7. package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-zQGZ9b4J.cjs} +2 -2
  8. package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-zQGZ9b4J.cjs.map} +1 -1
  9. package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-CT-ZMlQY.cjs} +2 -2
  10. package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-CT-ZMlQY.cjs.map} +1 -1
  11. package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-DBeBc0c0.mjs} +2 -2
  12. package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-DBeBc0c0.mjs.map} +1 -1
  13. package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-HmsH3c4v.cjs} +2 -2
  14. package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-HmsH3c4v.cjs.map} +1 -1
  15. package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-rnzNfOaV.mjs} +2 -2
  16. package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-rnzNfOaV.mjs.map} +1 -1
  17. package/dist/{add-Djrr12Xc.cjs → add-CHBin8TF.cjs} +2 -2
  18. package/dist/{add-Djrr12Xc.cjs.map → add-CHBin8TF.cjs.map} +1 -1
  19. package/dist/{add-BTH7WaH3.mjs → add-Cvzdw8cf.mjs} +2 -2
  20. package/dist/{add-BTH7WaH3.mjs.map → add-Cvzdw8cf.mjs.map} +1 -1
  21. package/dist/{bundler-utHuESvL.cjs → bundler-_8AEZhrs.cjs} +5 -5
  22. package/dist/{bundler-utHuESvL.cjs.map → bundler-_8AEZhrs.cjs.map} +1 -1
  23. package/dist/{bundler-BUojOkof.mjs → bundler-xjp5RwRS.mjs} +5 -5
  24. package/dist/{bundler-BUojOkof.mjs.map → bundler-xjp5RwRS.mjs.map} +1 -1
  25. package/dist/{cli-Bx0sUzxH.cjs → cli-B4ktxAsM.cjs} +3 -3
  26. package/dist/{cli-Bx0sUzxH.cjs.map → cli-B4ktxAsM.cjs.map} +1 -1
  27. package/dist/{cli-CyYceKTS.mjs → cli-BTGfA0B7.mjs} +3 -3
  28. package/dist/{cli-CyYceKTS.mjs.map → cli-BTGfA0B7.mjs.map} +1 -1
  29. package/dist/{compose-DZp8DJ0A.mjs → compose-DdH2JQJD.mjs} +219 -152
  30. package/dist/compose-DdH2JQJD.mjs.map +1 -0
  31. package/dist/{compose-iuw8wfHk.cjs → compose-UKyv_1yU.cjs} +241 -150
  32. package/dist/compose-UKyv_1yU.cjs.map +1 -0
  33. package/dist/deploy/public.cjs +7 -6
  34. package/dist/deploy/public.d.cts +11 -0
  35. package/dist/deploy/public.d.cts.map +1 -1
  36. package/dist/deploy/public.d.mts +11 -0
  37. package/dist/deploy/public.d.mts.map +1 -1
  38. package/dist/deploy/public.mjs +7 -7
  39. package/dist/{deploy-C17K7Imy.mjs → deploy-CuSsiFIc.mjs} +21 -5
  40. package/dist/deploy-CuSsiFIc.mjs.map +1 -0
  41. package/dist/{deploy-eWorhvQp.cjs → deploy-XUZoA1us.cjs} +26 -4
  42. package/dist/deploy-XUZoA1us.cjs.map +1 -0
  43. package/dist/{dokploy-DKzcI-RL.cjs → dokploy-Cvgg_pID.cjs} +2 -2
  44. package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-Cvgg_pID.cjs.map} +1 -1
  45. package/dist/{dokploy-DKa49Nqm.mjs → dokploy-DZXTQX10.mjs} +2 -2
  46. package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-DZXTQX10.mjs.map} +1 -1
  47. package/dist/{encryption-sTMz3aWi.mjs → encryption-JkeMPugf.mjs} +2 -2
  48. package/dist/{encryption-sTMz3aWi.mjs.map → encryption-JkeMPugf.mjs.map} +1 -1
  49. package/dist/{encryption-DSkJdoyk.cjs → encryption-w-Ehh9DW.cjs} +2 -2
  50. package/dist/{encryption-DSkJdoyk.cjs.map → encryption-w-Ehh9DW.cjs.map} +1 -1
  51. package/dist/{engine-B1b4I34Z.mjs → engine-CmozkHxq.mjs} +192 -4
  52. package/dist/engine-CmozkHxq.mjs.map +1 -0
  53. package/dist/{engine-Bh76sAHy.cjs → engine-zpWBMsQq.cjs} +195 -7
  54. package/dist/engine-zpWBMsQq.cjs.map +1 -0
  55. package/dist/{github-BvN3CfxM.cjs → github-BGdJ-Lnm.cjs} +2 -2
  56. package/dist/{github-BvN3CfxM.cjs.map → github-BGdJ-Lnm.cjs.map} +1 -1
  57. package/dist/{github-C9ODoyZU.mjs → github-BNngHoId.mjs} +2 -2
  58. package/dist/{github-C9ODoyZU.mjs.map → github-BNngHoId.mjs.map} +1 -1
  59. package/dist/index.cjs +70 -45
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.mjs +69 -44
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/{migrate-CTtJhGV9.mjs → migrate-BLL1RTAj.mjs} +2 -2
  64. package/dist/{migrate-CTtJhGV9.mjs.map → migrate-BLL1RTAj.mjs.map} +1 -1
  65. package/dist/{migrate-B0FCZNkp.cjs → migrate-CgjlYeun.cjs} +2 -2
  66. package/dist/{migrate-B0FCZNkp.cjs.map → migrate-CgjlYeun.cjs.map} +1 -1
  67. package/dist/{resolve-DSAXj_47.mjs → resolve-DZNx7rLy.mjs} +3 -3
  68. package/dist/{resolve-DSAXj_47.mjs.map → resolve-DZNx7rLy.mjs.map} +1 -1
  69. package/dist/{resolve-D_BU-wKA.cjs → resolve-fevXn-wZ.cjs} +3 -3
  70. package/dist/{resolve-D_BU-wKA.cjs.map → resolve-fevXn-wZ.cjs.map} +1 -1
  71. package/dist/{rollback-CWYTUhfW.mjs → rollback-CLi5Pln_.mjs} +4 -4
  72. package/dist/{rollback-CWYTUhfW.mjs.map → rollback-CLi5Pln_.mjs.map} +1 -1
  73. package/dist/{rollback-DJy3t696.cjs → rollback-Dw-FW3X2.cjs} +4 -4
  74. package/dist/{rollback-DJy3t696.cjs.map → rollback-Dw-FW3X2.cjs.map} +1 -1
  75. package/dist/{sniffer-BFmdZpZ2.mjs → sniffer-BmCvVyhq.mjs} +59 -7
  76. package/dist/sniffer-BmCvVyhq.mjs.map +1 -0
  77. package/dist/{sniffer-C-T7dSMN.cjs → sniffer-bMzrX4cO.cjs} +75 -5
  78. package/dist/{sniffer-C-T7dSMN.cjs.map → sniffer-bMzrX4cO.cjs.map} +1 -1
  79. package/dist/{state-DpkxSwzI.mjs → state-BrWIOce_.mjs} +46 -284
  80. package/dist/state-BrWIOce_.mjs.map +1 -0
  81. package/dist/{state-DCwRWyh-.cjs → state-kA4Fkufx.cjs} +56 -312
  82. package/dist/state-kA4Fkufx.cjs.map +1 -0
  83. package/dist/target/public.cjs +1 -1
  84. package/dist/target/public.mjs +1 -1
  85. package/package.json +17 -17
  86. package/dist/compose-DZp8DJ0A.mjs.map +0 -1
  87. package/dist/compose-iuw8wfHk.cjs.map +0 -1
  88. package/dist/deploy-C17K7Imy.mjs.map +0 -1
  89. package/dist/deploy-eWorhvQp.cjs.map +0 -1
  90. package/dist/engine-B1b4I34Z.mjs.map +0 -1
  91. package/dist/engine-Bh76sAHy.cjs.map +0 -1
  92. package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
  93. package/dist/state-DCwRWyh-.cjs.map +0 -1
  94. package/dist/state-DpkxSwzI.mjs.map +0 -1
@@ -1,16 +1,16 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { a as runOutput, i as run$1, s as gkmHome } from "./run-BJLIerMM.mjs";
2
+ import { i as run$1, s as gkmHome } from "./run-BJLIerMM.mjs";
3
3
  import { d as output, r as discover, u as ConstructGenerator } from "./discover-BPelzeGW.mjs";
4
4
  import { t as appKey } from "./derive-B4vDpzgP.mjs";
5
5
  import { O as TEST_STAGE, h as getPublicEnvPrefix, n as allConstructGlobs } from "./workspace-C7NqCsQF.mjs";
6
6
  import { ConfigNotFound, NotInAnApp, loadWorkspaceAppInfo, loadWorkspaceConfig } from "./config.mjs";
7
7
  import { n as runtimeFor, r as generateTelemetryModule } from "./EndpointGenerator-DftalLYg.mjs";
8
- import { c as runtimeOf } from "./resolve-DSAXj_47.mjs";
8
+ import { c as runtimeOf } from "./resolve-DZNx7rLy.mjs";
9
9
  import { a as DEFAULT_STORAGE, i as DEFAULT_EVENTS$1, n as readFakes, o as holdsEveryCache, r as DEFAULT_CACHE, t as SubscriberGenerator } from "./SubscriberGenerator-5looQ3gB.mjs";
10
10
  import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
11
11
  import { constants, existsSync, readFileSync } from "node:fs";
12
- import { appendFile, chmod, copyFile, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises";
13
- import { homedir, networkInterfaces, tmpdir } from "node:os";
12
+ import { appendFile, chmod, copyFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
13
+ import { homedir, networkInterfaces } from "node:os";
14
14
  import { promisify } from "node:util";
15
15
  import { Cron } from "@geekmidas/constructs/crons";
16
16
  import { Queue } from "@geekmidas/constructs/queue";
@@ -274,7 +274,7 @@ function applicationName(identity, app) {
274
274
  * old file stays, so an older CLI on the same machine keeps working.
275
275
  */
276
276
  /** Key length for AES-256 encryption */
277
- const KEY_LENGTH$1 = 32;
277
+ const KEY_LENGTH = 32;
278
278
  /** A keystore project key that is not `<namespace>/<project>`. */
279
279
  var KeystoreProjectInvalid = class extends Error {
280
280
  key;
@@ -367,7 +367,7 @@ async function generateKey(stage, project, flag = "w") {
367
367
  recursive: true,
368
368
  mode: 448
369
369
  });
370
- const key = randomBytes(KEY_LENGTH$1).toString("hex");
370
+ const key = randomBytes(KEY_LENGTH).toString("hex");
371
371
  await writeFile(keyPath, key, {
372
372
  mode: 384,
373
373
  encoding: "utf-8",
@@ -436,8 +436,8 @@ async function getOrCreateKey(stage, project) {
436
436
  /** Where the files live, relative to the project root. */
437
437
  const SECRETS_DIR = ".gkm/secrets";
438
438
  /** AES-256-GCM configuration */
439
- const ALGORITHM$1 = "aes-256-gcm";
440
- const IV_LENGTH$1 = 12;
439
+ const ALGORITHM = "aes-256-gcm";
440
+ const IV_LENGTH = 12;
441
441
  /**
442
442
  * A stage's secrets as an encrypted file on this machine:
443
443
  * `.gkm/secrets/<stage>.json`, with its key in the CLI's home at
@@ -505,8 +505,8 @@ function packageName$1(root) {
505
505
  }
506
506
  function encrypt(secrets, keyHex) {
507
507
  const key = Buffer.from(keyHex, "hex");
508
- const iv = randomBytes(IV_LENGTH$1);
509
- const cipher = createCipheriv(ALGORITHM$1, key, iv);
508
+ const iv = randomBytes(IV_LENGTH);
509
+ const cipher = createCipheriv(ALGORITHM, key, iv);
510
510
  const ciphertext = Buffer.concat([cipher.update(JSON.stringify(secrets), "utf-8"), cipher.final()]);
511
511
  return {
512
512
  version: 1,
@@ -517,7 +517,7 @@ function encrypt(secrets, keyHex) {
517
517
  function decrypt(data, keyHex) {
518
518
  const key = Buffer.from(keyHex, "hex");
519
519
  const combined = Buffer.from(data.encrypted, "base64");
520
- const decipher = createDecipheriv(ALGORITHM$1, key, Buffer.from(data.iv, "hex"));
520
+ const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(data.iv, "hex"));
521
521
  decipher.setAuthTag(combined.subarray(-16));
522
522
  const plaintext = Buffer.concat([decipher.update(combined.subarray(0, -16)), decipher.final()]);
523
523
  return JSON.parse(plaintext.toString("utf-8"));
@@ -554,7 +554,7 @@ function isRemoteStore(workspace, stage) {
554
554
  }
555
555
  //#endregion
556
556
  //#region src/credentials/index.ts
557
- const logger$2 = console;
557
+ const logger$1 = console;
558
558
  /**
559
559
  * Load environment files
560
560
  * @internal Exported for testing
@@ -605,7 +605,7 @@ async function findAvailablePort(preferredPort, maxAttempts = 10) {
605
605
  for (let i = 0; i < maxAttempts; i++) {
606
606
  const port = preferredPort + i;
607
607
  if (await isPortAvailable(port)) return port;
608
- logger$2.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
608
+ logger$1.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
609
609
  }
610
610
  throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
611
611
  }
@@ -640,7 +640,7 @@ async function loadSecretsForApp(store, stage, appName) {
640
640
  let secrets = {};
641
641
  const stageSecrets = await store.read(stage);
642
642
  if (stageSecrets) {
643
- logger$2.log(`🔐 Loading secrets from stage: ${stage}`);
643
+ logger$1.log(`🔐 Loading secrets from stage: ${stage}`);
644
644
  secrets = toEmbeddableSecrets(stageSecrets);
645
645
  }
646
646
  if (Object.keys(secrets).length === 0) return {};
@@ -746,7 +746,7 @@ async function prepareEntryCredentials(options) {
746
746
  free: isPortAvailable,
747
747
  holder: holderOf
748
748
  });
749
- for (const { app, from, to, holder } of assigned.moved) logger$2.log(`↪️ ${app}: ${from} is held by ${describeHolder(holder)}, which is not this workspace's — using ${to}`);
749
+ for (const { app, from, to, holder } of assigned.moved) logger$1.log(`↪️ ${app}: ${from} is held by ${describeHolder(holder)}, which is not this workspace's — using ${to}`);
750
750
  workspace = withAppPorts(workspace, assigned.ports);
751
751
  workspaceAppPort = assigned.ports[appName] ?? workspaceAppPort;
752
752
  }
@@ -770,7 +770,7 @@ async function prepareEntryCredentials(options) {
770
770
  });
771
771
  Object.assign(credentials, reconciled.env);
772
772
  declaredKeys.push(...Object.keys(reconciled.env));
773
- if (Object.keys(reconciled.env).length > 0) logger$2.log(`🔌 Resolved ${Object.keys(reconciled.env).length} declared URL(s)`);
773
+ if (Object.keys(reconciled.env).length > 0) logger$1.log(`🔌 Resolved ${Object.keys(reconciled.env).length} declared URL(s)`);
774
774
  }
775
775
  const secretsDir = join(secretsRoot, ".gkm");
776
776
  await mkdir(secretsDir, { recursive: true });
@@ -1279,23 +1279,22 @@ RUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\
1279
1279
  *
1280
1280
  * Nothing built on the host reaches the image — `.dockerignore` keeps every
1281
1281
  * `dist` out — so a workspace package (a CLI that is a sibling package) is
1282
- * built here: the root's `build` script if it has one, then turbo's build of
1283
- * the app's dependencies (`^build`).
1282
+ * built here: turbo's build of the app's dependencies (`^build`) and nothing
1283
+ * else. The root's own `build` script is never run: the slice holds one app,
1284
+ * and a root `build` that is `gkm build` (what `gkm init` scaffolds) builds
1285
+ * every app the workspace declares, most of which are not in it. The app
1286
+ * itself is built after this, by `gkm build` or its framework.
1284
1287
  */
1285
1288
  function builderStage(options, extra = {}) {
1286
- const { pm, turbo, monorepo } = layout(options);
1289
+ const { turbo, monorepo } = layout(options);
1287
1290
  const args = extra.args ?? [];
1288
1291
  const argLines = args.length ? `\n# Build-time args: public values the bundler inlines\n${args.map((a) => `ARG ${a}=""`).join("\n")}\n${args.map((a) => `ENV ${a}=$${a}`).join("\n")}\n` : "";
1289
1292
  const scopes = [options.turboPackage, ...options.prunePackages ?? []];
1290
- const dependencies = monorepo ? `\nRUN ${turbo} run build ${scopes.map((s) => `--filter='${s}^...'`).join(" ")}` : "";
1291
1293
  return `# Stage 3: Build
1292
1294
  FROM deps AS builder
1293
1295
  WORKDIR /app
1294
1296
  ${argLines}
1295
- COPY --from=pruner /app/out/full/ ./
1296
-
1297
- # The workspace packages the app depends on, built from source.
1298
- RUN ${pm.run} --if-present build${dependencies}`;
1297
+ COPY --from=pruner /app/out/full/ ./${monorepo ? `\n# The workspace packages the app depends on, built from source.\nRUN ${turbo} run build ${scopes.map((s) => `--filter='${s}^...'`).join(" ")}` : ""}`;
1299
1298
  }
1300
1299
  /**
1301
1300
  * The PATH a command in the app's directory runs with: the app's binaries,
@@ -5291,58 +5290,6 @@ logger.info({ port }, 'Worker started');
5291
5290
  `;
5292
5291
  }
5293
5292
  //#endregion
5294
- //#region src/secrets/encryption.ts
5295
- var encryption_exports = /* @__PURE__ */ __exportAll({
5296
- encryptSecrets: () => encryptSecrets,
5297
- generateDefineOptions: () => generateDefineOptions,
5298
- keyFingerprint: () => keyFingerprint
5299
- });
5300
- /** AES-256-GCM configuration */
5301
- const ALGORITHM = "aes-256-gcm";
5302
- const KEY_LENGTH = 32;
5303
- const IV_LENGTH = 12;
5304
- /**
5305
- * Encrypt secrets for embedding in a bundle.
5306
- * Uses AES-256-GCM with a randomly generated ephemeral key.
5307
- *
5308
- * @param secrets - Key-value pairs to encrypt
5309
- * @returns Encrypted payload with ephemeral master key
5310
- */
5311
- function encryptSecrets(secrets) {
5312
- const masterKey = randomBytes(KEY_LENGTH);
5313
- const iv = randomBytes(IV_LENGTH);
5314
- const plaintext = JSON.stringify(secrets);
5315
- const cipher = createCipheriv(ALGORITHM, masterKey, iv);
5316
- const ciphertext = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
5317
- const authTag = cipher.getAuthTag();
5318
- return {
5319
- encrypted: Buffer.concat([ciphertext, authTag]).toString("base64"),
5320
- iv: iv.toString("hex"),
5321
- masterKey: masterKey.toString("hex")
5322
- };
5323
- }
5324
- /**
5325
- * Generate the define options for tsdown/esbuild.
5326
- * These will be injected at build time.
5327
- */
5328
- function generateDefineOptions(payload) {
5329
- return {
5330
- __GKM_ENCRYPTED_CREDENTIALS__: JSON.stringify(payload.encrypted),
5331
- __GKM_CREDENTIALS_IV__: JSON.stringify(payload.iv)
5332
- };
5333
- }
5334
- /**
5335
- * A short, one-way name for a master key: the first 8 hex characters of its
5336
- * SHA-256.
5337
- *
5338
- * Printed where the key itself used to be, so a person can tell which key a
5339
- * build used — and match it against the one they hold — without the output
5340
- * carrying a value that decrypts every secret of the stage.
5341
- */
5342
- function keyFingerprint(masterKey) {
5343
- return createHash("sha256").update(masterKey).digest("hex").slice(0, 8);
5344
- }
5345
- //#endregion
5346
5293
  //#region src/build/workers.ts
5347
5294
  /** A worker with background work and no backend app to build it from. */
5348
5295
  var WorkerHasNoApp = class extends Error {
@@ -5830,7 +5777,7 @@ function validateImageRef(ref) {
5830
5777
  }
5831
5778
  //#endregion
5832
5779
  //#region src/docker/index.ts
5833
- const logger$1 = output;
5780
+ const logger = output;
5834
5781
  /** `docker build` failed; what docker printed above says why. */
5835
5782
  var DockerBuildFailed = class extends Error {
5836
5783
  imageRef;
@@ -5881,7 +5828,7 @@ async function buildDockerImage(app, buildRoot, options) {
5881
5828
  const tag = options.tag ?? "latest";
5882
5829
  const registry = options.registry;
5883
5830
  const fullImageName = validateImageRef(registry ? `${registry}/${app.imageName}:${tag}` : `${app.imageName}:${tag}`);
5884
- logger$1.log(`\n🐳 Building Docker image: ${fullImageName}`);
5831
+ logger.log(`\n🐳 Building Docker image: ${fullImageName}`);
5885
5832
  try {
5886
5833
  await run$1("docker", [
5887
5834
  "build",
@@ -5895,7 +5842,7 @@ async function buildDockerImage(app, buildRoot, options) {
5895
5842
  DOCKER_BUILDKIT: "1"
5896
5843
  }
5897
5844
  });
5898
- logger$1.log(`✅ Docker image built: ${fullImageName}`);
5845
+ logger.log(`✅ Docker image built: ${fullImageName}`);
5899
5846
  } catch (error) {
5900
5847
  throw new DockerBuildFailed(fullImageName, error);
5901
5848
  }
@@ -5908,10 +5855,10 @@ async function pushDockerImage(imageName, options, cwd) {
5908
5855
  const registry = options.registry;
5909
5856
  if (!registry) throw new PushNeedsRegistry(imageName);
5910
5857
  const fullImageName = validateImageRef(`${registry}/${imageName}:${tag}`);
5911
- logger$1.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
5858
+ logger.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
5912
5859
  try {
5913
5860
  await run$1("docker", ["push", fullImageName], { cwd });
5914
- logger$1.log(`✅ Docker image pushed: ${fullImageName}`);
5861
+ logger.log(`✅ Docker image pushed: ${fullImageName}`);
5915
5862
  } catch (error) {
5916
5863
  throw new DockerPushFailed(fullImageName, error);
5917
5864
  }
@@ -5923,16 +5870,16 @@ async function pushDockerImage(imageName, options, cwd) {
5923
5870
  async function workspaceDockerCommand(workspace, manifest, imageNames = {}, background = {}) {
5924
5871
  const results = [];
5925
5872
  const layout = imageLayout(workspace);
5926
- logger$1.log(`\n🐳 Generating Dockerfiles for workspace: ${workspace.name}`);
5927
- logger$1.log(` Build root: ${layout.buildRoot}`);
5928
- logger$1.log(` Package manager: ${layout.tools.packageManager}${layout.tools.packageManagerVersion ? `@${layout.tools.packageManagerVersion}` : ""}, turbo@${layout.tools.turboVersion}`);
5873
+ logger.log(`\n🐳 Generating Dockerfiles for workspace: ${workspace.name}`);
5874
+ logger.log(` Build root: ${layout.buildRoot}`);
5875
+ logger.log(` Package manager: ${layout.tools.packageManager}${layout.tools.packageManagerVersion ? `@${layout.tools.packageManagerVersion}` : ""}, turbo@${layout.tools.turboVersion}`);
5929
5876
  for (const [appName, app] of Object.entries(workspace.apps)) {
5930
5877
  if (app.type === "mobile") {
5931
- logger$1.log(`\n 📱 Skipping Docker for ${appName} (mobile app — deploy via framework toolchain)`);
5878
+ logger.log(`\n 📱 Skipping Docker for ${appName} (mobile app — deploy via framework toolchain)`);
5932
5879
  continue;
5933
5880
  }
5934
5881
  const buildType = app.entry ? "entry" : app.type;
5935
- logger$1.log(`\n 📄 Generating Dockerfile for ${appName} (${buildType})`);
5882
+ logger.log(`\n 📄 Generating Dockerfile for ${appName} (${buildType})`);
5936
5883
  const dockerfile = appDockerfile(appName, app, {
5937
5884
  layout,
5938
5885
  workspaceRoot: workspace.root,
@@ -5942,7 +5889,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
5942
5889
  const dockerfilePath = join(workspace.root, path);
5943
5890
  await mkdir(dirname(dockerfilePath), { recursive: true });
5944
5891
  await writeFile(dockerfilePath, dockerfile);
5945
- logger$1.log(` Generated: ${path}`);
5892
+ logger.log(` Generated: ${path}`);
5946
5893
  results.push({
5947
5894
  appName,
5948
5895
  type: app.type,
@@ -5951,7 +5898,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
5951
5898
  });
5952
5899
  }
5953
5900
  for (const worker of manifest ? workerUnits(workspace, manifest, background) : []) {
5954
- logger$1.log(`\n 📄 Generating Dockerfile for ${worker.name} (worker ${worker.id}, built from ${worker.app})`);
5901
+ logger.log(`\n 📄 Generating Dockerfile for ${worker.name} (worker ${worker.id}, built from ${worker.app})`);
5955
5902
  const dockerfile = workerDockerfile(worker, workspace.apps[worker.app], {
5956
5903
  layout,
5957
5904
  workspaceRoot: workspace.root
@@ -5960,7 +5907,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
5960
5907
  const dockerfilePath = join(workspace.root, path);
5961
5908
  await mkdir(dirname(dockerfilePath), { recursive: true });
5962
5909
  await writeFile(dockerfilePath, dockerfile);
5963
- logger$1.log(` Generated: ${path}`);
5910
+ logger.log(` Generated: ${path}`);
5964
5911
  results.push({
5965
5912
  appName: worker.name,
5966
5913
  type: "backend",
@@ -5969,13 +5916,13 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
5969
5916
  });
5970
5917
  }
5971
5918
  const dockerignorePath = await ensureDockerignore(layout.buildRoot);
5972
- logger$1.log(`\n Ensured: ${dockerignorePath}`);
5919
+ logger.log(`\n Ensured: ${dockerignorePath}`);
5973
5920
  const composePath = await writeConstructsCompose(workspace);
5974
- logger$1.log(`\n✅ Generated ${results.length} Dockerfile(s) + ${COMPOSE_PATH}`);
5975
- logger$1.log(`\n📋 Build commands (from ${layout.buildRoot}):`);
5921
+ logger.log(`\n✅ Generated ${results.length} Dockerfile(s) + ${COMPOSE_PATH}`);
5922
+ logger.log(`\n📋 Build commands (from ${layout.buildRoot}):`);
5976
5923
  for (const result of results) {
5977
5924
  const icon = result.type === "backend" ? "⚙️" : result.type === "mobile" ? "📱" : "🌐";
5978
- logger$1.log(` ${icon} docker build -f ${relative(layout.buildRoot, result.dockerfile)} -t ${result.imageName} .`);
5925
+ logger.log(` ${icon} docker build -f ${relative(layout.buildRoot, result.dockerfile)} -t ${result.imageName} .`);
5979
5926
  }
5980
5927
  printRunInstructions(workspace);
5981
5928
  return {
@@ -6094,199 +6041,14 @@ async function writeConstructsCompose(workspace) {
6094
6041
  stage: workspace.stages.local,
6095
6042
  start: false
6096
6043
  });
6097
- logger$1.log(` Generated: ${COMPOSE_PATH} (project root)`);
6044
+ logger.log(` Generated: ${COMPOSE_PATH} (project root)`);
6098
6045
  return join(workspace.root, COMPOSE_PATH);
6099
6046
  }
6100
6047
  function printRunInstructions(workspace) {
6101
6048
  const project = existsSync(join(workspace.root, "docker-compose.yml")) ? " -f docker-compose.yml" : "";
6102
- logger$1.log("\n📋 Run everything (the apps sit behind the \"apps\" profile):");
6103
- logger$1.log(" gkm setup # starts the containers and creates what they hold");
6104
- logger$1.log(` docker compose -f ${COMPOSE_PATH}${project} --profile apps up --build`);
6105
- }
6106
- //#endregion
6107
- //#region src/deploy/docker.ts
6108
- const logger = output;
6109
- /**
6110
- * The id the Dockerfile templates mount the encrypted credentials under:
6111
- * `RUN --mount=type=secret,id=gkm_credentials`.
6112
- */
6113
- const CREDENTIALS_SECRET_ID = "gkm_credentials";
6114
- /**
6115
- * Get the full image reference
6116
- */
6117
- function getImageRef(registry, imageName, tag) {
6118
- if (registry) return `${registry}/${imageName}:${tag}`;
6119
- return `${imageName}:${tag}`;
6120
- }
6121
- /**
6122
- * The `docker build` argv for an image.
6123
- *
6124
- * One element per value, so nothing in a ref or a build arg is read by a
6125
- * shell, and `--opt=value` rather than `--opt value`, so a value that starts
6126
- * with `-` cannot be taken for one of docker's own flags.
6127
- *
6128
- * @internal Exported for testing
6129
- */
6130
- function dockerBuildArgs(options) {
6131
- const { dockerfilePath, imageRef, buildArgs = [], credentialsFile } = options;
6132
- return [
6133
- "build",
6134
- "--platform=linux/amd64",
6135
- `--file=${dockerfilePath}`,
6136
- `--tag=${imageRef}`,
6137
- ...buildArgs.map((arg) => `--build-arg=${arg}`),
6138
- ...credentialsFile ? [`--secret=id=${CREDENTIALS_SECRET_ID},src=${credentialsFile}`] : [],
6139
- "."
6140
- ];
6141
- }
6142
- /**
6143
- * The build arg that names which credentials an image embeds: a hash of the
6144
- * ciphertext, which is not a secret. A BuildKit secret is no part of the
6145
- * build cache's key, so without it a rebuild with credentials encrypted under
6146
- * a new key would reuse the layer that embedded the old ones.
6147
- */
6148
- function credentialsBuildArg(credentials) {
6149
- return `GKM_CIPHERTEXT_HASH=${createHash("sha256").update(`${credentials.encrypted}\n${credentials.iv}`).digest("hex").slice(0, 16)}`;
6150
- }
6151
- /** The secret file's content: ciphertext, then IV, one per line. */
6152
- function credentialsFileContent(credentials) {
6153
- return `${credentials.encrypted}\n${credentials.iv}\n`;
6154
- }
6155
- /**
6156
- * Write the encrypted credentials where `docker build --secret` reads them.
6157
- *
6158
- * Two lines — ciphertext, then IV — so a template can split them with `sed`
6159
- * in any base image. Owner-only, in a directory of its own, and the returned
6160
- * cleanup removes both whatever the build did.
6161
- *
6162
- * @internal Exported for testing
6163
- */
6164
- async function writeCredentialsFile(credentials) {
6165
- const dir = await mkdtemp(join(tmpdir(), "gkm-credentials-"));
6166
- const path = join(dir, CREDENTIALS_SECRET_ID);
6167
- await writeFile(path, credentialsFileContent(credentials), { mode: 384 });
6168
- await chmod(path, 384);
6169
- return {
6170
- path,
6171
- cleanup: () => rm(dir, {
6172
- recursive: true,
6173
- force: true
6174
- })
6175
- };
6176
- }
6177
- /**
6178
- * Build Docker image
6179
- * @param imageRef - Full image reference (registry/name:tag)
6180
- * @param buildArgs - Build arguments to pass to docker build
6181
- * @param credentials - Encrypted credentials, passed as a build secret
6182
- */
6183
- async function buildImage(imageRef, buildArgs, credentials, { cwd, dockerfile, signal, stdio }) {
6184
- logger.log(`\n🔨 Building Docker image: ${imageRef}`);
6185
- logger.log(" Generating Dockerfile...");
6186
- const { buildRoot } = await dockerCommand({ cwd });
6187
- const dockerfilePath = relative(buildRoot, dockerfile);
6188
- const secret = credentials ? await writeCredentialsFile(credentials) : void 0;
6189
- try {
6190
- await run$1("docker", dockerBuildArgs({
6191
- dockerfilePath,
6192
- imageRef,
6193
- buildArgs: [...buildArgs ?? [], ...credentials ? [credentialsBuildArg(credentials)] : []],
6194
- credentialsFile: secret?.path
6195
- }), {
6196
- cwd: buildRoot,
6197
- env: {
6198
- ...process.env,
6199
- DOCKER_BUILDKIT: "1"
6200
- },
6201
- ...signal ? { signal } : {},
6202
- ...stdio ? { stdio } : {}
6203
- });
6204
- logger.log(`✅ Image built: ${imageRef}`);
6205
- } catch (error) {
6206
- throw new DockerBuildFailed(imageRef, error);
6207
- } finally {
6208
- await secret?.cleanup();
6209
- }
6210
- }
6211
- /**
6212
- * Push Docker image to registry
6213
- */
6214
- async function pushImage(imageRef, { cwd, signal, stdio }) {
6215
- logger.log(`\n☁️ Pushing image: ${imageRef}`);
6216
- try {
6217
- await run$1("docker", ["push", imageRef], {
6218
- cwd,
6219
- ...signal ? { signal } : {},
6220
- ...stdio ? { stdio } : {}
6221
- });
6222
- logger.log(`✅ Image pushed: ${imageRef}`);
6223
- } catch (error) {
6224
- throw new DockerPushFailed(imageRef, error);
6225
- }
6226
- }
6227
- /**
6228
- * The digest the registry gave a pushed image, `sha256:…`.
6229
- *
6230
- * A tag can be pushed over — by the next deploy, or by anything else that
6231
- * shares the repository — and the digest is what says which image a stage
6232
- * actually ran. `RepoDigests` has one entry per repository the image was
6233
- * pushed to, so the one for this ref's repository is picked by name.
6234
- *
6235
- * @internal Exported for testing
6236
- */
6237
- async function pushedDigest(imageRef, { cwd, signal } = { cwd: process.cwd() }) {
6238
- const repository = imageRef.split("@")[0].replace(/:[\w][\w.-]*$/, "");
6239
- const output = await runOutput("docker", [
6240
- "image",
6241
- "inspect",
6242
- "--format={{json .RepoDigests}}",
6243
- imageRef
6244
- ], {
6245
- cwd,
6246
- ...signal ? { signal } : {}
6247
- });
6248
- let digests;
6249
- try {
6250
- digests = JSON.parse(output.trim() || "[]");
6251
- } catch {
6252
- return;
6253
- }
6254
- if (!Array.isArray(digests)) return void 0;
6255
- return digests.find((entry) => typeof entry === "string" && entry.startsWith(`${repository}@`))?.slice(repository.length + 1);
6256
- }
6257
- /**
6258
- * Deploy using Docker (build and optionally push image)
6259
- */
6260
- async function deployDocker(options) {
6261
- const { stage, tag, skipPush, masterKey, config, buildArgs, credentials } = options;
6262
- const imageName = config.imageName;
6263
- const imageRef = validateImageRef(getImageRef(config.registry, imageName, tag));
6264
- const cwd = options.cwd ?? process.cwd();
6265
- const docker = {
6266
- cwd,
6267
- dockerfile: join(cwd, options.dockerfile ?? dockerfileOf(config.appName ?? imageName, options.appPath ?? ".")),
6268
- ...options.signal ? { signal: options.signal } : {},
6269
- ...options.stdio ? { stdio: options.stdio } : {}
6270
- };
6271
- await buildImage(imageRef, buildArgs, credentials, docker);
6272
- let digest;
6273
- if (!skipPush) {
6274
- if (!config.registry) logger.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
6275
- else {
6276
- await pushImage(imageRef, docker);
6277
- digest = await pushedDigest(imageRef, docker);
6278
- }
6279
- }
6280
- logger.log("\n✅ Docker deployment ready!");
6281
- logger.log(`\n📋 Deployment details:`);
6282
- logger.log(` Image: ${imageRef}`);
6283
- logger.log(` Stage: ${stage}`);
6284
- if (masterKey) logger.log(`\n🔐 Run the container with GKM_MASTER_KEY set to the key with fingerprint ${keyFingerprint(masterKey)}.`);
6285
- return {
6286
- imageRef,
6287
- ...digest ? { digest } : {},
6288
- masterKey
6289
- };
6049
+ logger.log("\n📋 Run everything (the apps sit behind the \"apps\" profile):");
6050
+ logger.log(" gkm setup # starts the containers and creates what they hold");
6051
+ logger.log(` docker compose -f ${COMPOSE_PATH}${project} --profile apps up --build`);
6290
6052
  }
6291
6053
  //#endregion
6292
6054
  //#region src/deploy/generated.ts
@@ -6590,6 +6352,6 @@ function setPostgresBackupId(state, backupId) {
6590
6352
  if (state.backups) state.backups.postgresBackupId = backupId;
6591
6353
  }
6592
6354
  //#endregion
6593
- export { constructGlobs as $, applicationName as $t, DevServicesNeedServerTarget as A, eventsBackendFor as At, requiredStageKeys as B, findAvailablePort as Bt, validateImageRef as C, composeBuildPaths as Ct, isOtlpDestination as D, detectPackageManager as Dt, resolveHost as E, WORKER_PORT as Et, devServicesUsed as F, fakeKey as Ft, keyFingerprint as G, isRemoteStore as Gt, workerUnits as H, loadEnvFiles as Ht, externalServices as I, portKeys as It, workerEntryDir as J, FileSecretsStore as Jt, WorkerGenerator as K, secretsStoreFor as Kt, manifestServiceDeclarations as L, primaryPortKey as Lt, STORAGE_KEY_PAIR as M, storageBackendFor as Mt, UnknownDevService as N, DEFAULT_IMAGES as Nt, otelEnv as O, findBuildRoot as Ot, assertExternalServices as P, describeServices as Pt, backendsOf as Q, readKey as Qt, parseDevServices as R, createCredentialsPreload as Rt, workerDockerfileOf as S, hostFor as St, isMainFrontendApp as T, TURBO_VERSION as Tt, encryptSecrets as U, loadSecretsForApp as Ut, suppliedOnly as V, isPortAvailable as Vt, encryption_exports as W, prepareEntryCredentials as Wt, CronGenerator as X, keystoreProject as Xt, QueueGenerator as Y, getKeyPath as Yt, FAKE_ENV as Z, projectKey as Zt, deployDocker as _, workerEnvKeys as _t, recordRelease as a, ownershipMarker as an, applyBuckets as at, ensureDockerignore as b, planFor as bt, setBackupState as c, maskPassword as cn, bucketPolicies as ct, setGeneratedSecret as d, withCustomSecret as dn, quoteIdentifier as dt, deployIdentity as en, derivedContainers as et, setPostgresBackupId as f, composeFor as ft, credentialsFileContent as g, networkEnv as gt, credentialsBuildArg as h, appEnvKeys as ht, isDnsVerified as i, markerOf as in, forgetState as it, ExternalServicesNotConfigured as j, providerOf as jt, DEV_SERVICES as k, cacheBackendFor as kt, setDnsRecord as l, storage_exports as ln, postgresDatabaseNames as lt, withGeneratedSecrets as m, pgClient as mt, getBackupState as n, imageRef as nn, workspace_exports as nt, recordRollback as o, projectName as on, applyPolicies as ot, DeployJournal as p, bucketClient as pt, workerBundleName as q, store_exports as qt, getGeneratedSecret as r, isOwnedBy as rn, LOCAL_CA_PATH as rt, setApplicationId as s, initStageSecrets as sn, applyPostgres as st, createEmptyState as t, imageName as tn, reconcileWorkspace as tt, setDnsVerification as u, toEmbeddableSecrets as un, postgresStatements as ut, appDockerfile as v, envFor as vt, NoDomainForStage as w, imageLayout as wt, workerDockerfile as x, resourceName as xt, dockerCommand as y, localRolePassword as yt, reportDevServices as z, createEntryWrapper as zt };
6355
+ export { LOCAL_CA_PATH as $, imageRef as $t, ExternalServicesNotConfigured as A, DEFAULT_IMAGES as At, suppliedOnly as B, loadSecretsForApp as Bt, NoDomainForStage as C, WORKER_PORT as Ct, otelEnv as D, eventsBackendFor as Dt, isOtlpDestination as E, cacheBackendFor as Et, externalServices as F, createCredentialsPreload as Ft, QueueGenerator as G, FileSecretsStore as Gt, WorkerGenerator as H, isRemoteStore as Ht, manifestServiceDeclarations as I, createEntryWrapper as It, backendsOf as J, projectKey as Jt, CronGenerator as K, getKeyPath as Kt, parseDevServices as L, findAvailablePort as Lt, UnknownDevService as M, fakeKey as Mt, assertExternalServices as N, portKeys as Nt, DEV_SERVICES as O, providerOf as Ot, devServicesUsed as P, primaryPortKey as Pt, workspace_exports as Q, imageName as Qt, reportDevServices as R, isPortAvailable as Rt, validateImageRef as S, TURBO_VERSION as St, resolveHost as T, findBuildRoot as Tt, workerBundleName as U, secretsStoreFor as Ut, workerUnits as V, prepareEntryCredentials as Vt, workerEntryDir as W, store_exports as Wt, derivedContainers as X, applicationName as Xt, constructGlobs as Y, readKey as Yt, reconcileWorkspace as Z, deployIdentity as Zt, appDockerfile as _, planFor as _t, recordRelease as a, maskPassword as an, postgresDatabaseNames as at, workerDockerfile as b, composeBuildPaths as bt, setBackupState as c, withCustomSecret as cn, composeFor as ct, setGeneratedSecret as d, appEnvKeys as dt, isOwnedBy as en, forgetState as et, setPostgresBackupId as f, dockerfileOf as ft, DockerPushFailed as g, localRolePassword as gt, DockerBuildFailed as h, envFor as ht, isDnsVerified as i, initStageSecrets as in, bucketPolicies as it, STORAGE_KEY_PAIR as j, describeServices as jt, DevServicesNeedServerTarget as k, storageBackendFor as kt, setDnsRecord as l, bucketClient as lt, withGeneratedSecrets as m, workerEnvKeys as mt, getBackupState as n, ownershipMarker as nn, applyPolicies as nt, recordRollback as o, storage_exports as on, postgresStatements as ot, DeployJournal as p, networkEnv as pt, FAKE_ENV as q, keystoreProject as qt, getGeneratedSecret as r, projectName as rn, applyPostgres as rt, setApplicationId as s, toEmbeddableSecrets as sn, quoteIdentifier as st, createEmptyState as t, markerOf as tn, applyBuckets as tt, setDnsVerification as u, pgClient as ut, dockerCommand as v, resourceName as vt, isMainFrontendApp as w, detectPackageManager as wt, workerDockerfileOf as x, imageLayout as xt, ensureDockerignore as y, hostFor as yt, requiredStageKeys as z, loadEnvFiles as zt };
6594
6356
 
6595
- //# sourceMappingURL=state-DpkxSwzI.mjs.map
6357
+ //# sourceMappingURL=state-BrWIOce_.mjs.map