@geekmidas/cli 10.0.0-alpha.62 → 10.0.0-alpha.63

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 (170) hide show
  1. package/README.md +2 -0
  2. package/dist/{HostingerProvider-B92qH4dC.mjs → HostingerProvider-DBBwpDjn.mjs} +2 -2
  3. package/dist/{HostingerProvider-B92qH4dC.mjs.map → HostingerProvider-DBBwpDjn.mjs.map} +1 -1
  4. package/dist/{HostingerProvider-DyD1Hin8.cjs → HostingerProvider-mJ7YruxH.cjs} +2 -2
  5. package/dist/{HostingerProvider-DyD1Hin8.cjs.map → HostingerProvider-mJ7YruxH.cjs.map} +1 -1
  6. package/dist/{LegacyStateStore-UHJEBLdn.cjs → LegacyStateStore-CP7SZwTP.cjs} +2 -2
  7. package/dist/{LegacyStateStore-UHJEBLdn.cjs.map → LegacyStateStore-CP7SZwTP.cjs.map} +1 -1
  8. package/dist/{LegacyStateStore-A8d2GdT7.mjs → LegacyStateStore-Q3GmKOdw.mjs} +2 -2
  9. package/dist/{LegacyStateStore-A8d2GdT7.mjs.map → LegacyStateStore-Q3GmKOdw.mjs.map} +1 -1
  10. package/dist/{LocalStateStore-B51rnfgn.mjs → LocalStateStore-BGIXcrvX.mjs} +2 -2
  11. package/dist/{LocalStateStore-B51rnfgn.mjs.map → LocalStateStore-BGIXcrvX.mjs.map} +1 -1
  12. package/dist/{LocalStateStore-COW3Ldwa.cjs → LocalStateStore-sS8mvLeq.cjs} +2 -2
  13. package/dist/{LocalStateStore-COW3Ldwa.cjs.map → LocalStateStore-sS8mvLeq.cjs.map} +1 -1
  14. package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs → OpenApiTsGenerator-CjHWFRDd.cjs} +2 -2
  15. package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs.map → OpenApiTsGenerator-CjHWFRDd.cjs.map} +1 -1
  16. package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs → OpenApiTsGenerator-CnAwhGxi.mjs} +2 -2
  17. package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs.map → OpenApiTsGenerator-CnAwhGxi.mjs.map} +1 -1
  18. package/dist/{S3StateStore-WUJGdRNL.cjs → S3StateStore-6jqITH2F.cjs} +2 -2
  19. package/dist/{S3StateStore-WUJGdRNL.cjs.map → S3StateStore-6jqITH2F.cjs.map} +1 -1
  20. package/dist/{S3StateStore-CJewPhgz.mjs → S3StateStore-D7l_lWJ3.mjs} +2 -2
  21. package/dist/{S3StateStore-CJewPhgz.mjs.map → S3StateStore-D7l_lWJ3.mjs.map} +1 -1
  22. package/dist/{SSMStateStore-Zejt42V8.cjs → SSMStateStore-B__F7IJa.cjs} +2 -2
  23. package/dist/{SSMStateStore-Zejt42V8.cjs.map → SSMStateStore-B__F7IJa.cjs.map} +1 -1
  24. package/dist/{SSMStateStore-iK5UKp9d.mjs → SSMStateStore-CAQDVpoc.mjs} +2 -2
  25. package/dist/{SSMStateStore-iK5UKp9d.mjs.map → SSMStateStore-CAQDVpoc.mjs.map} +1 -1
  26. package/dist/{bundler-CfH9frOS.cjs → bundler-DLfOn0ls.cjs} +3 -3
  27. package/dist/{bundler-CfH9frOS.cjs.map → bundler-DLfOn0ls.cjs.map} +1 -1
  28. package/dist/{bundler-DN5r4x5b.mjs → bundler-DyWI41Iy.mjs} +2 -2
  29. package/dist/{bundler-DN5r4x5b.mjs.map → bundler-DyWI41Iy.mjs.map} +1 -1
  30. package/dist/{cli-DOAUp80L.cjs → cli-D-ZM-X2s.cjs} +4 -4
  31. package/dist/{cli-DOAUp80L.cjs.map → cli-D-ZM-X2s.cjs.map} +1 -1
  32. package/dist/{cli-DYwxmfsW.mjs → cli-PkVF28LM.mjs} +4 -4
  33. package/dist/{cli-DYwxmfsW.mjs.map → cli-PkVF28LM.mjs.map} +1 -1
  34. package/dist/{config-BYh9S0cZ.cjs → config-BEJYKd4s.cjs} +132 -18
  35. package/dist/config-BEJYKd4s.cjs.map +1 -0
  36. package/dist/config-C2BUosLm.d.mts +256 -0
  37. package/dist/config-C2BUosLm.d.mts.map +1 -0
  38. package/dist/config-CemHVcIr.d.cts +256 -0
  39. package/dist/config-CemHVcIr.d.cts.map +1 -0
  40. package/dist/{config-Bf4-bROQ.mjs → config-LKKCVCnC.mjs} +109 -19
  41. package/dist/config-LKKCVCnC.mjs.map +1 -0
  42. package/dist/config.cjs +6 -2
  43. package/dist/config.d.cts +3 -210
  44. package/dist/config.d.mts +3 -210
  45. package/dist/config.mjs +3 -3
  46. package/dist/deploy/public.cjs +151 -5
  47. package/dist/deploy/public.cjs.map +1 -0
  48. package/dist/deploy/public.d.cts +186 -1
  49. package/dist/deploy/public.d.cts.map +1 -1
  50. package/dist/deploy/public.d.mts +186 -1
  51. package/dist/deploy/public.d.mts.map +1 -1
  52. package/dist/deploy/public.mjs +134 -6
  53. package/dist/deploy/public.mjs.map +1 -0
  54. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  55. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  56. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  57. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  58. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  59. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  60. package/dist/{deploy-DSaCYvcO.cjs → deploy-ABBI0lf1.cjs} +7 -7
  61. package/dist/{deploy-DSaCYvcO.cjs.map → deploy-ABBI0lf1.cjs.map} +1 -1
  62. package/dist/{deploy-D8Qr-Xto.cjs → deploy-BiMrP9i7.cjs} +11 -9
  63. package/dist/deploy-BiMrP9i7.cjs.map +1 -0
  64. package/dist/{deploy-B7jvUORo.mjs → deploy-CG8bfFij.mjs} +7 -7
  65. package/dist/{deploy-B7jvUORo.mjs.map → deploy-CG8bfFij.mjs.map} +1 -1
  66. package/dist/{deploy-Cg9fae7a.mjs → deploy-CGW-QY9D.mjs} +11 -9
  67. package/dist/deploy-CGW-QY9D.mjs.map +1 -0
  68. package/dist/discover-B6yPpvRV.d.mts +99 -0
  69. package/dist/discover-B6yPpvRV.d.mts.map +1 -0
  70. package/dist/discover-B_IkPukx.d.cts +99 -0
  71. package/dist/discover-B_IkPukx.d.cts.map +1 -0
  72. package/dist/discover-BaT6bpnA.mjs +614 -0
  73. package/dist/discover-BaT6bpnA.mjs.map +1 -0
  74. package/dist/discover-C_6COHEv.cjs +729 -0
  75. package/dist/discover-C_6COHEv.cjs.map +1 -0
  76. package/dist/{dokploy-CD9PY-3D.mjs → dokploy-CwdmlyQL.mjs} +2 -2
  77. package/dist/{dokploy-CD9PY-3D.mjs.map → dokploy-CwdmlyQL.mjs.map} +1 -1
  78. package/dist/{dokploy-Ey2foJLv.cjs → dokploy-QJxMhxdf.cjs} +2 -2
  79. package/dist/{dokploy-Ey2foJLv.cjs.map → dokploy-QJxMhxdf.cjs.map} +1 -1
  80. package/dist/{encryption-CVwvGbsL.mjs → encryption-CbQG_ayW.mjs} +4 -4
  81. package/dist/{encryption-CVwvGbsL.mjs.map → encryption-CbQG_ayW.mjs.map} +1 -1
  82. package/dist/{encryption-ChBk3hTj.cjs → encryption-DXw3jj0c.cjs} +4 -4
  83. package/dist/{encryption-ChBk3hTj.cjs.map → encryption-DXw3jj0c.cjs.map} +1 -1
  84. package/dist/fakes-C9RiT6XG.mjs.map +1 -1
  85. package/dist/fakes-zW-jNAbQ.cjs.map +1 -1
  86. package/dist/{github-OUgPDlqg.cjs → github-BH_mETav.cjs} +3 -3
  87. package/dist/{github-OUgPDlqg.cjs.map → github-BH_mETav.cjs.map} +1 -1
  88. package/dist/{github-BCB3_LBX.mjs → github-ciwbIwVa.mjs} +3 -3
  89. package/dist/{github-BCB3_LBX.mjs.map → github-ciwbIwVa.mjs.map} +1 -1
  90. package/dist/index.cjs +55 -48
  91. package/dist/index.cjs.map +1 -1
  92. package/dist/index.mjs +52 -45
  93. package/dist/index.mjs.map +1 -1
  94. package/dist/{migrate-dnaFMvOm.cjs → migrate-6oa9y_f2.cjs} +5 -5
  95. package/dist/{migrate-dnaFMvOm.cjs.map → migrate-6oa9y_f2.cjs.map} +1 -1
  96. package/dist/{migrate-BoHMqdCu.mjs → migrate-ImBKTBcW.mjs} +5 -5
  97. package/dist/{migrate-BoHMqdCu.mjs.map → migrate-ImBKTBcW.mjs.map} +1 -1
  98. package/dist/openapi.cjs +3 -3
  99. package/dist/openapi.mjs +3 -3
  100. package/dist/{ready-XlNx-Gbo.cjs → ready-BiG0rt4h.cjs} +3 -3
  101. package/dist/{ready-XlNx-Gbo.cjs.map → ready-BiG0rt4h.cjs.map} +1 -1
  102. package/dist/{ready-DQIy21W5.mjs → ready-Bpdnn2ON.mjs} +3 -3
  103. package/dist/{ready-DQIy21W5.mjs.map → ready-Bpdnn2ON.mjs.map} +1 -1
  104. package/dist/reconcile/public.cjs +1 -1
  105. package/dist/reconcile/public.d.cts +3 -76
  106. package/dist/reconcile/public.d.cts.map +1 -1
  107. package/dist/reconcile/public.d.mts +3 -76
  108. package/dist/reconcile/public.d.mts.map +1 -1
  109. package/dist/reconcile/public.mjs +1 -1
  110. package/dist/{resolve-CFCIkm7m.mjs → resolve-B1T0hUaR.mjs} +2 -2
  111. package/dist/{resolve-CFCIkm7m.mjs.map → resolve-B1T0hUaR.mjs.map} +1 -1
  112. package/dist/{resolve-wbv66HjD.cjs → resolve-xytBTtG4.cjs} +2 -2
  113. package/dist/{resolve-wbv66HjD.cjs.map → resolve-xytBTtG4.cjs.map} +1 -1
  114. package/dist/sandbox/config-worker.cjs +43 -0
  115. package/dist/sandbox/config-worker.cjs.map +1 -0
  116. package/dist/sandbox/config-worker.d.cts +1 -0
  117. package/dist/sandbox/config-worker.d.mts +1 -0
  118. package/dist/sandbox/config-worker.mjs +44 -0
  119. package/dist/sandbox/config-worker.mjs.map +1 -0
  120. package/dist/sandbox/discover-worker.cjs +44 -0
  121. package/dist/sandbox/discover-worker.cjs.map +1 -0
  122. package/dist/sandbox/discover-worker.d.cts +1 -0
  123. package/dist/sandbox/discover-worker.d.mts +1 -0
  124. package/dist/sandbox/discover-worker.mjs +45 -0
  125. package/dist/sandbox/discover-worker.mjs.map +1 -0
  126. package/dist/sandbox-M8UnLhXE.d.cts +126 -0
  127. package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
  128. package/dist/sandbox-M8UnLhXE.d.mts +126 -0
  129. package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
  130. package/dist/{workspace-BFe57es7.mjs → schemas-Ckm_aBnF.cjs} +71 -982
  131. package/dist/schemas-Ckm_aBnF.cjs.map +1 -0
  132. package/dist/{workspace-B6zQO6RY.cjs → schemas-D2LCF689.mjs} +2 -1168
  133. package/dist/schemas-D2LCF689.mjs.map +1 -0
  134. package/dist/{sniffer-BsfPa-GA.cjs → sniffer-D_SYc_pO.cjs} +369 -207
  135. package/dist/sniffer-D_SYc_pO.cjs.map +1 -0
  136. package/dist/{sniffer-DHE2Nafd.mjs → sniffer-aO_-s5vq.mjs} +336 -204
  137. package/dist/sniffer-aO_-s5vq.mjs.map +1 -0
  138. package/dist/target/public.cjs +1 -1
  139. package/dist/target/public.mjs +1 -1
  140. package/dist/{terminal-6oL0vANs.cjs → terminal-D0f1u0LG.cjs} +6 -6
  141. package/dist/{terminal-6oL0vANs.cjs.map → terminal-D0f1u0LG.cjs.map} +1 -1
  142. package/dist/{terminal-ByZNjuig.mjs → terminal-gMxAo9Dj.mjs} +6 -6
  143. package/dist/{terminal-ByZNjuig.mjs.map → terminal-gMxAo9Dj.mjs.map} +1 -1
  144. package/dist/vitest.cjs +2 -2
  145. package/dist/vitest.mjs +2 -2
  146. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  147. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  148. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  149. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  150. package/dist/workspace/index.cjs +1 -1
  151. package/dist/workspace/index.mjs +1 -1
  152. package/dist/workspace-Dh7rr7l4.mjs +1024 -0
  153. package/dist/workspace-Dh7rr7l4.mjs.map +1 -0
  154. package/dist/workspace-Kl4NG9IH.cjs +1196 -0
  155. package/dist/workspace-Kl4NG9IH.cjs.map +1 -0
  156. package/package.json +13 -13
  157. package/dist/config-BYh9S0cZ.cjs.map +0 -1
  158. package/dist/config-Bf4-bROQ.mjs.map +0 -1
  159. package/dist/config.d.cts.map +0 -1
  160. package/dist/config.d.mts.map +0 -1
  161. package/dist/deploy-Cg9fae7a.mjs.map +0 -1
  162. package/dist/deploy-D8Qr-Xto.cjs.map +0 -1
  163. package/dist/discover-Bc-4eA_p.cjs +0 -299
  164. package/dist/discover-Bc-4eA_p.cjs.map +0 -1
  165. package/dist/discover-FrYvzkeC.mjs +0 -262
  166. package/dist/discover-FrYvzkeC.mjs.map +0 -1
  167. package/dist/sniffer-BsfPa-GA.cjs.map +0 -1
  168. package/dist/sniffer-DHE2Nafd.mjs.map +0 -1
  169. package/dist/workspace-B6zQO6RY.cjs.map +0 -1
  170. package/dist/workspace-BFe57es7.mjs.map +0 -1
@@ -1,26 +1,25 @@
1
1
  import { n as __require, t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { n as gkmHome } from "./home-GI7pJl1M.mjs";
3
- import { a as output, t as discover } from "./discover-FrYvzkeC.mjs";
4
- import { c as loadWorkspaceAppInfo, f as appKey, l as loadWorkspaceConfig, r as NotInAnApp, s as loadConfig, t as ConfigNotFound } from "./config-Bf4-bROQ.mjs";
5
- import { E as TEST_STAGE, p as getPublicEnvPrefix, t as allConstructGlobs } from "./workspace-BFe57es7.mjs";
3
+ import { h as confineCwd, m as assertSecretNames, p as activeSandbox, r as discover, s as nodeWithTsx, u as SECRETS_DIR_ENV, v as output } from "./discover-BaT6bpnA.mjs";
4
+ import { d as loadConfig, f as loadWorkspaceAppInfo, g as appKey, o as NotInAnApp, p as loadWorkspaceConfig, r as ConfigNotFound } from "./config-LKKCVCnC.mjs";
5
+ import { E as TEST_STAGE, p as getPublicEnvPrefix, t as allConstructGlobs } from "./workspace-Dh7rr7l4.mjs";
6
6
  import { i as toEmbeddableSecrets } from "./storage-BzaUxmqe.mjs";
7
7
  import { i as FileSecretsStore, n as secretsStoreFor } from "./store-BS8A7NcA.mjs";
8
8
  import { r as runtimeOf } from "./runtime-DbakJS8u.mjs";
9
9
  import { i as DEFAULT_STORAGE, n as DEFAULT_CACHE, r as DEFAULT_EVENTS$1, t as readFakes } from "./fakes-C9RiT6XG.mjs";
10
- import { createRequire } from "node:module";
11
10
  import { basename, dirname, join, parse, resolve } from "node:path";
12
11
  import { stdin, stdout } from "node:process";
13
12
  import * as readline from "node:readline/promises";
14
13
  import { copyFileSync, existsSync, mkdirSync, readFileSync, unlinkSync } from "node:fs";
15
- import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
16
- import { hostname, networkInterfaces, userInfo } from "node:os";
14
+ import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises";
15
+ import { hostname, networkInterfaces, tmpdir, userInfo } from "node:os";
17
16
  import { promisify } from "node:util";
18
17
  import { DEFAULT_POSTGRES_VERSION, cacheTable, cookieDomain, dependenciesOf, dependentsOf, externalApiUrl, kebabCase, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase } from "@geekmidas/manifest";
18
+ import { fileURLToPath } from "node:url";
19
19
  import { execFile, spawn } from "node:child_process";
20
20
  import { createServer } from "node:net";
21
21
  import { config } from "dotenv";
22
22
  import { createCipheriv, createHash, randomBytes, randomUUID } from "node:crypto";
23
- import { fileURLToPath, pathToFileURL } from "node:url";
24
23
  import { formatKeyring, generateKeyring } from "@geekmidas/constructs/encryption";
25
24
  import { ownerRole, readerRole, roleStatements } from "@geekmidas/db/pg/roles";
26
25
  import * as snsUrl from "@geekmidas/events/sns/url";
@@ -585,45 +584,6 @@ function normalizeRoutes(routes) {
585
584
  return Array.isArray(routes) ? routes : [routes];
586
585
  }
587
586
  //#endregion
588
- //#region src/owningTsconfigJsx.ts
589
- const REGISTER = "owning-tsconfig-jsx-register.mjs";
590
- /** The CLI's `bin/` was not found above the module looking for it. */
591
- var OwningTsconfigJsxHookMissing = class extends Error {
592
- from;
593
- constructor(from) {
594
- super(`Could not find bin/${REGISTER} in any directory above '${from}'. It ships with @geekmidas/cli beside bin/gkm.mjs; reinstall the package if it is missing.`);
595
- this.from = from;
596
- this.name = "OwningTsconfigJsxHookMissing";
597
- }
598
- };
599
- /**
600
- * The CLI's `bin/owning-tsconfig-jsx-register.mjs`, as a file URL. Searched
601
- * upward because this module runs from `src/` in the repo and from a chunk in
602
- * `dist/` once built, and `bin/` sits beside both.
603
- */
604
- function registerUrl() {
605
- const from = dirname(fileURLToPath(import.meta.url));
606
- for (let dir = from;; dir = dirname(dir)) {
607
- const candidate = join(dir, "bin", REGISTER);
608
- if (existsSync(candidate)) return pathToFileURL(candidate).href;
609
- if (dirname(dir) === dir) throw new OwningTsconfigJsxHookMissing(from);
610
- }
611
- }
612
- /**
613
- * `NODE_OPTIONS` for a process that runs app code through tsx, with the hook
614
- * that compiles each `.tsx` with its own tsconfig's JSX settings (see
615
- * `bin/owning-tsconfig-jsx.mjs`) put in front of every other `--import`, so it
616
- * is registered before tsx and reads the source on tsx's behalf.
617
- *
618
- * `bin/gkm.mjs` already starts the CLI this way, and its children inherit it;
619
- * this is for those that set `NODE_OPTIONS` themselves, or whose CLI was
620
- * started with tsx already imported.
621
- */
622
- function withOwningTsconfigJsx(nodeOptions = "") {
623
- if (nodeOptions.includes(REGISTER)) return nodeOptions;
624
- return [`--import=${registerUrl()}`, nodeOptions].filter(Boolean).join(" ");
625
- }
626
- //#endregion
627
587
  //#region src/reconcile/containers.ts
628
588
  /**
629
589
  * What gkm knows about each container it can derive.
@@ -3533,7 +3493,7 @@ function localAddress(port) {
3533
3493
  /** Long enough for a cold image build; short enough that a hung one ends. */
3534
3494
  const DEFAULT_TIMEOUT_MS = 18e5;
3535
3495
  /** How long a timed-out child has to exit on SIGTERM before it is killed. */
3536
- const KILL_GRACE_MS = 5e3;
3496
+ const KILL_GRACE_MS$1 = 5e3;
3537
3497
  /** The command line as a person would read it — for messages, never to run. */
3538
3498
  function display(command, args) {
3539
3499
  return [command, ...args].join(" ");
@@ -3606,7 +3566,7 @@ function spawnChild(command, args, options, capture) {
3606
3566
  const timer = setTimeout(() => {
3607
3567
  timedOut = true;
3608
3568
  child.kill("SIGTERM");
3609
- killer = setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS);
3569
+ killer = setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS$1);
3610
3570
  killer.unref?.();
3611
3571
  }, timeoutMs);
3612
3572
  timer.unref?.();
@@ -3628,6 +3588,221 @@ function spawnChild(command, args, options, capture) {
3628
3588
  });
3629
3589
  }
3630
3590
  //#endregion
3591
+ //#region src/sandbox/env.ts
3592
+ /**
3593
+ * What of the host's environment a local sandbox passes on.
3594
+ *
3595
+ * An allowlist, not a denylist: a credential's variable has any name its
3596
+ * owner chose (`DOKPLOY_TOKEN`, `AWS_SECRET_ACCESS_KEY`, `MY_VAULT_TOKEN`), so
3597
+ * the only safe default is to name what a program needs to *run* and pass
3598
+ * nothing else.
3599
+ */
3600
+ /**
3601
+ * Variables a command needs to find programs, write temp files, print in the
3602
+ * user's locale and reach the network through the host's proxy — and nothing
3603
+ * that authenticates as anyone.
3604
+ *
3605
+ * Deliberately left out:
3606
+ * - `NODE_OPTIONS`: it can `--require` or `--import` code into every node
3607
+ * process, and CI often holds `--import tsx` there. A step that needs a
3608
+ * loader passes its own.
3609
+ * - `NODE_AUTH_TOKEN`, `NPM_TOKEN`, `npm_config_*`: registry tokens
3610
+ * (`actions/setup-node` writes `NODE_AUTH_TOKEN`), which is why there is no
3611
+ * `NODE_*` wildcard.
3612
+ * - `AWS_*`, `DOCKER_*`, `DOKPLOY_*`, `GITHUB_TOKEN`, `TURBO_TOKEN`, `GKM_*`:
3613
+ * credentials, or where the deploy keeps them.
3614
+ * - `SHELL`, `EDITOR` and the rest of a login session: nothing here starts a
3615
+ * shell.
3616
+ *
3617
+ * Proxies are passed: behind one, nothing installs or builds without it. A
3618
+ * proxy URL with a password in it reaches the command too — a host that keeps
3619
+ * one there and builds code it does not trust should pass a sandbox of its
3620
+ * own.
3621
+ */
3622
+ const SANDBOX_ENV_ALLOWLIST = [
3623
+ "PATH",
3624
+ "HOME",
3625
+ "USER",
3626
+ "LOGNAME",
3627
+ "TMPDIR",
3628
+ "TMP",
3629
+ "TEMP",
3630
+ "LANG",
3631
+ "LANGUAGE",
3632
+ "TZ",
3633
+ /^LC_[A-Z]+$/,
3634
+ "TERM",
3635
+ "COLORTERM",
3636
+ "NO_COLOR",
3637
+ "FORCE_COLOR",
3638
+ "CI",
3639
+ "NODE_ENV",
3640
+ "NODE_EXTRA_CA_CERTS",
3641
+ "COREPACK_HOME",
3642
+ "PNPM_HOME",
3643
+ "XDG_CACHE_HOME",
3644
+ "XDG_DATA_HOME",
3645
+ "HTTP_PROXY",
3646
+ "HTTPS_PROXY",
3647
+ "NO_PROXY",
3648
+ "http_proxy",
3649
+ "https_proxy",
3650
+ "no_proxy",
3651
+ "SystemRoot",
3652
+ "SYSTEMROOT",
3653
+ "windir",
3654
+ "WINDIR",
3655
+ "ComSpec",
3656
+ "COMSPEC",
3657
+ "PATHEXT",
3658
+ "USERPROFILE",
3659
+ "APPDATA",
3660
+ "LOCALAPPDATA"
3661
+ ];
3662
+ function allowed(name) {
3663
+ return SANDBOX_ENV_ALLOWLIST.some((entry) => typeof entry === "string" ? entry === name : entry.test(name));
3664
+ }
3665
+ /**
3666
+ * The allowlisted part of `source`, plus each of `extra` the host chose to
3667
+ * pass on by name.
3668
+ */
3669
+ function allowlistedEnv(source = process.env, extra = []) {
3670
+ const env = {};
3671
+ for (const [name, value] of Object.entries(source)) {
3672
+ if (value === void 0) continue;
3673
+ if (allowed(name) || extra.includes(name)) env[name] = value;
3674
+ }
3675
+ return env;
3676
+ }
3677
+ //#endregion
3678
+ //#region src/sandbox/local.ts
3679
+ /** How long a timed-out command has to exit on SIGTERM before SIGKILL. */
3680
+ const KILL_GRACE_MS = 5e3;
3681
+ /** Where `output` sends a child's streams. */
3682
+ const STDIO = {
3683
+ capture: [
3684
+ "ignore",
3685
+ "pipe",
3686
+ "pipe"
3687
+ ],
3688
+ inherit: "inherit",
3689
+ stderr: [
3690
+ "ignore",
3691
+ 2,
3692
+ 2
3693
+ ],
3694
+ ignore: "ignore"
3695
+ };
3696
+ /**
3697
+ * A child process on this machine, as this user, with an allowlisted
3698
+ * environment.
3699
+ *
3700
+ * What it withholds from the command: the host's environment beyond
3701
+ * {@link SANDBOX_ENV_ALLOWLIST}, a shell, a working directory outside the
3702
+ * project, and any time past the timeout. What it does not: the host's
3703
+ * filesystem, which the command can read and write as the user running the
3704
+ * deploy. So it is not `isolating`, and it is the default for projects the
3705
+ * host already trusts — the developer's own, a team's own CI. Code nobody
3706
+ * vetted belongs in a sandbox that is.
3707
+ *
3708
+ * A timed-out command is sent SIGTERM, then SIGKILL; processes it started
3709
+ * itself are its to stop.
3710
+ */
3711
+ var LocalSandbox = class {
3712
+ root;
3713
+ isolating = false;
3714
+ env;
3715
+ constructor(options) {
3716
+ this.root = resolve(options.root);
3717
+ this.env = {
3718
+ ...allowlistedEnv(options.hostEnv ?? process.env, options.passEnv),
3719
+ ...options.home ? {
3720
+ HOME: options.home,
3721
+ USERPROFILE: options.home
3722
+ } : {}
3723
+ };
3724
+ }
3725
+ async exec(command, args, options) {
3726
+ const cwd = confineCwd(this.root, options.cwd);
3727
+ assertSecretNames(options.secrets);
3728
+ options.signal?.throwIfAborted();
3729
+ const secretsDir = await mountSecrets(options.secrets);
3730
+ try {
3731
+ return await spawnConfined(command, args, {
3732
+ ...options,
3733
+ cwd,
3734
+ env: secretsDir ? {
3735
+ ...options.env,
3736
+ [SECRETS_DIR_ENV]: secretsDir
3737
+ } : options.env
3738
+ });
3739
+ } finally {
3740
+ if (secretsDir) await rm(secretsDir, {
3741
+ recursive: true,
3742
+ force: true
3743
+ });
3744
+ }
3745
+ }
3746
+ };
3747
+ /**
3748
+ * Each secret as a 0600 file in a fresh 0700 directory outside the project —
3749
+ * where nothing the build writes, packs or commits will pick it up.
3750
+ */
3751
+ async function mountSecrets(secrets) {
3752
+ if (!secrets || Object.keys(secrets).length === 0) return void 0;
3753
+ const dir = await mkdtemp(join(tmpdir(), "gkm-secrets-"));
3754
+ for (const [name, value] of Object.entries(secrets)) await writeFile(join(dir, name), value, { mode: 384 });
3755
+ return dir;
3756
+ }
3757
+ function spawnConfined(command, args, options) {
3758
+ const { output = "capture", signal, timeoutMs } = options;
3759
+ return new Promise((resolvePromise, reject) => {
3760
+ const child = spawn(command, [...args], {
3761
+ cwd: options.cwd,
3762
+ env: { ...options.env },
3763
+ stdio: STDIO[output],
3764
+ shell: false,
3765
+ ...signal ? { signal } : {}
3766
+ });
3767
+ let stdout = "";
3768
+ let stderr = "";
3769
+ child.stdout?.on("data", (chunk) => {
3770
+ stdout += chunk.toString();
3771
+ });
3772
+ child.stderr?.on("data", (chunk) => {
3773
+ stderr += chunk.toString();
3774
+ });
3775
+ let timedOut = false;
3776
+ let killer;
3777
+ const timer = setTimeout(() => {
3778
+ timedOut = true;
3779
+ child.kill("SIGTERM");
3780
+ killer = setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS);
3781
+ killer.unref?.();
3782
+ }, timeoutMs);
3783
+ timer.unref?.();
3784
+ const settle = () => {
3785
+ clearTimeout(timer);
3786
+ if (killer) clearTimeout(killer);
3787
+ };
3788
+ child.on("error", (error) => {
3789
+ settle();
3790
+ reject(signal?.aborted ? signal.reason : error);
3791
+ });
3792
+ child.on("close", (code, killedBy) => {
3793
+ settle();
3794
+ if (signal?.aborted) reject(signal.reason);
3795
+ else if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));
3796
+ else resolvePromise({
3797
+ exitCode: code,
3798
+ signal: killedBy ?? null,
3799
+ stdout,
3800
+ stderr
3801
+ });
3802
+ });
3803
+ });
3804
+ }
3805
+ //#endregion
3631
3806
  //#region src/secrets/encryption.ts
3632
3807
  var encryption_exports = /* @__PURE__ */ __exportAll({
3633
3808
  encryptSecrets: () => encryptSecrets,
@@ -4052,17 +4227,17 @@ function isStateStore(value) {
4052
4227
  async function createStateStore(options) {
4053
4228
  const { config, workspaceRoot, workspaceName } = options;
4054
4229
  if (!config || config.provider === "local") {
4055
- const { LocalStateStore } = await import("./LocalStateStore-B51rnfgn.mjs").then((n) => n.n);
4230
+ const { LocalStateStore } = await import("./LocalStateStore-BGIXcrvX.mjs").then((n) => n.n);
4056
4231
  return new LocalStateStore(workspaceRoot);
4057
4232
  }
4058
4233
  if (isStateStore(config.provider)) return config.provider;
4059
4234
  if (isStateProvider(config.provider)) {
4060
- const { LegacyStateStore } = await import("./LegacyStateStore-A8d2GdT7.mjs");
4235
+ const { LegacyStateStore } = await import("./LegacyStateStore-Q3GmKOdw.mjs");
4061
4236
  return new LegacyStateStore(config.provider, { warn: options.warn });
4062
4237
  }
4063
4238
  if (config.provider === "ssm") {
4064
4239
  if (!workspaceName) throw new StateStoreNeedsWorkspaceName("ssm");
4065
- const { SSMStateStore } = await import("./SSMStateStore-iK5UKp9d.mjs");
4240
+ const { SSMStateStore } = await import("./SSMStateStore-CAQDVpoc.mjs");
4066
4241
  const ssm = config;
4067
4242
  return SSMStateStore.create({
4068
4243
  workspaceName,
@@ -4072,7 +4247,7 @@ async function createStateStore(options) {
4072
4247
  }
4073
4248
  if (config.provider === "s3") {
4074
4249
  if (!workspaceName) throw new StateStoreNeedsWorkspaceName("s3");
4075
- const { S3StateStore } = await import("./S3StateStore-CJewPhgz.mjs");
4250
+ const { S3StateStore } = await import("./S3StateStore-D7l_lWJ3.mjs");
4076
4251
  const s3 = config;
4077
4252
  return S3StateStore.create({
4078
4253
  workspaceName,
@@ -6221,13 +6396,6 @@ var DokployApi = class {
6221
6396
  const __filename = fileURLToPath(import.meta.url);
6222
6397
  const __dirname = dirname(__filename);
6223
6398
  /**
6224
- * Resolve the tsx package path from the CLI package's dependencies.
6225
- * This ensures tsx is available regardless of whether the target project has it installed.
6226
- */
6227
- function resolveTsxPath() {
6228
- return createRequire(import.meta.url).resolve("tsx");
6229
- }
6230
- /**
6231
6399
  * Resolve the path to a sniffer helper file.
6232
6400
  * Handles both dev (.ts with tsx) and production (.mjs from dist).
6233
6401
  *
@@ -6246,6 +6414,39 @@ function resolveSnifferFile(baseName) {
6246
6414
  return tsPath;
6247
6415
  }
6248
6416
  /**
6417
+ * Run a sniffer worker in the sandbox, with the sandbox's environment and
6418
+ * nothing of the deploy's: the deploy's Dokploy token, registry login and AWS
6419
+ * keys stay where they are. A worker that outlives the timeout is killed, and
6420
+ * comes back as the error the caller reports.
6421
+ */
6422
+ async function runSniffer(run, workspacePath, cwd, nodeArgs) {
6423
+ const sandbox = run.sandbox ?? activeSandbox() ?? new LocalSandbox({ root: resolve(workspacePath) });
6424
+ try {
6425
+ const result = await sandbox.exec("node", nodeArgs, {
6426
+ cwd,
6427
+ env: { ...sandbox.env },
6428
+ timeoutMs: run.timeoutMs ?? 3e4,
6429
+ output: "capture"
6430
+ });
6431
+ return {
6432
+ stdout: result.stdout,
6433
+ stderr: result.stderr,
6434
+ code: result.exitCode
6435
+ };
6436
+ } catch (error) {
6437
+ return { error: error instanceof Error ? error : new Error(String(error)) };
6438
+ }
6439
+ }
6440
+ /** The worker's JSON answer: the last object on stdout naming `envVars`. */
6441
+ function snifferAnswer(stdout) {
6442
+ try {
6443
+ const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
6444
+ return jsonMatch ? JSON.parse(jsonMatch[0]) : void 0;
6445
+ } catch {
6446
+ return;
6447
+ }
6448
+ }
6449
+ /**
6249
6450
  * Get required environment variables for an app.
6250
6451
  *
6251
6452
  * Detection strategy (in order):
@@ -6267,6 +6468,10 @@ function resolveSnifferFile(baseName) {
6267
6468
  */
6268
6469
  async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
6269
6470
  const { logWarnings = true, markOptional = false } = options;
6471
+ const run = {
6472
+ ...options.sandbox ? { sandbox: options.sandbox } : {},
6473
+ ...options.timeoutMs ? { timeoutMs: options.timeoutMs } : {}
6474
+ };
6270
6475
  if (app.type === "web" || app.type === "mobile") {
6271
6476
  const publicPrefix = getPublicEnvPrefix(app.framework);
6272
6477
  const depVars = publicPrefix ? (app.dependencies ?? []).map((dep) => `${publicPrefix}${dep.toUpperCase()}_URL`) : [];
@@ -6277,7 +6482,7 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
6277
6482
  if (app.config.client) configPaths.push(app.config.client);
6278
6483
  if (app.config.server) configPaths.push(app.config.server);
6279
6484
  for (const configPath of configPaths) {
6280
- const result = await sniffEntryFile(configPath, app.path, workspacePath);
6485
+ const result = await sniffEntryFile(configPath, app.path, workspacePath, run);
6281
6486
  if (logWarnings && result.error) output.warn(`[sniffer] ${appName}: Config file "${configPath}" threw error during sniffing (env vars still captured): ${result.error.message}`);
6282
6487
  sniffedVars.push(...result.envVars);
6283
6488
  sniffedOptional.push(...result.optionalEnvVars);
@@ -6296,7 +6501,7 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
6296
6501
  };
6297
6502
  }
6298
6503
  if (app.entry) {
6299
- const result = await sniffEntryFile(app.entry, app.path, workspacePath);
6504
+ const result = await sniffEntryFile(app.entry, app.path, workspacePath, run);
6300
6505
  if (logWarnings && result.error) output.warn(`[sniffer] ${appName}: Entry file threw error during sniffing (env vars still captured): ${result.error.message}`);
6301
6506
  return {
6302
6507
  appName,
@@ -6305,7 +6510,7 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
6305
6510
  };
6306
6511
  }
6307
6512
  if (app.routes) {
6308
- const result = await sniffRouteFiles(normalizeRoutes(app.routes), app.path, workspacePath);
6513
+ const result = await sniffRouteFiles(normalizeRoutes(app.routes), app.path, workspacePath, run);
6309
6514
  if (logWarnings && result.error) output.warn(`[sniffer] ${appName}: Route sniffing threw error (env vars still captured): ${result.error.message}`);
6310
6515
  return {
6311
6516
  appName,
@@ -6314,7 +6519,7 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
6314
6519
  };
6315
6520
  }
6316
6521
  if (app.envParser) {
6317
- const result = await sniffEnvParser(app.envParser, app.path, workspacePath);
6522
+ const result = await sniffEnvParser(app.envParser, app.path, workspacePath, run);
6318
6523
  if (logWarnings) {
6319
6524
  if (result.error) output.warn(`[sniffer] ${appName}: envParser threw error during sniffing (env vars still captured): ${result.error.message}`);
6320
6525
  if (result.unhandledRejections.length > 0) output.warn(`[sniffer] ${appName}: Fire-and-forget rejections during sniffing (suppressed): ${result.unhandledRejections.map((e) => e.message).join(", ")}`);
@@ -6359,63 +6564,27 @@ function applyMarkOptional(envVars, optionalEnvVars, markOptional) {
6359
6564
  * @param workspacePath - Absolute path to workspace root
6360
6565
  * @returns EntrySniffResult with env vars and optional error
6361
6566
  */
6362
- async function sniffEntryFile(entryPath, appPath, workspacePath) {
6567
+ async function sniffEntryFile(entryPath, appPath, workspacePath, run = {}) {
6363
6568
  const fullEntryPath = resolve(workspacePath, appPath, entryPath);
6364
6569
  const loaderPath = resolveSnifferFile("sniffer-loader");
6365
6570
  const workerPath = resolveSnifferFile("sniffer-worker");
6366
- return new Promise((resolvePromise) => {
6367
- const child = spawn("node", [
6368
- "--import",
6369
- loaderPath,
6370
- workerPath,
6371
- fullEntryPath
6372
- ], {
6373
- cwd: resolve(workspacePath, appPath),
6374
- stdio: [
6375
- "ignore",
6376
- "pipe",
6377
- "pipe"
6378
- ],
6379
- env: {
6380
- ...process.env,
6381
- NODE_OPTIONS: withOwningTsconfigJsx("--import=tsx")
6382
- }
6383
- });
6384
- let stdout = "";
6385
- let stderr = "";
6386
- child.stdout.on("data", (data) => {
6387
- stdout += data.toString();
6388
- });
6389
- child.stderr.on("data", (data) => {
6390
- stderr += data.toString();
6391
- });
6392
- child.on("close", (code) => {
6393
- try {
6394
- const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
6395
- if (jsonMatch) {
6396
- const result = JSON.parse(jsonMatch[0]);
6397
- resolvePromise({
6398
- envVars: result.envVars || [],
6399
- optionalEnvVars: result.optionalEnvVars || [],
6400
- error: result.error ? new Error(result.error) : void 0
6401
- });
6402
- return;
6403
- }
6404
- } catch {}
6405
- resolvePromise({
6406
- envVars: [],
6407
- optionalEnvVars: [],
6408
- error: /* @__PURE__ */ new Error(`Failed to sniff entry file (exit code ${code}): ${stderr || stdout || "No output"}`)
6409
- });
6410
- });
6411
- child.on("error", (err) => {
6412
- resolvePromise({
6413
- envVars: [],
6414
- optionalEnvVars: [],
6415
- error: err
6416
- });
6417
- });
6418
- });
6571
+ const ran = await runSniffer(run, workspacePath, resolve(workspacePath, appPath), nodeWithTsx(workerPath, [fullEntryPath], [loaderPath]));
6572
+ if ("error" in ran) return {
6573
+ envVars: [],
6574
+ optionalEnvVars: [],
6575
+ error: ran.error
6576
+ };
6577
+ const answer = snifferAnswer(ran.stdout);
6578
+ if (answer) return {
6579
+ envVars: answer.envVars || [],
6580
+ optionalEnvVars: answer.optionalEnvVars || [],
6581
+ error: answer.error ? new Error(answer.error) : void 0
6582
+ };
6583
+ return {
6584
+ envVars: [],
6585
+ optionalEnvVars: [],
6586
+ error: /* @__PURE__ */ new Error(`Failed to sniff entry file (exit code ${ran.code}): ${ran.stderr || ran.stdout || "No output"}`)
6587
+ };
6419
6588
  }
6420
6589
  /**
6421
6590
  * Sniff route files by loading constructs and calling getEnvironment().
@@ -6431,116 +6600,79 @@ async function sniffEntryFile(entryPath, appPath, workspacePath) {
6431
6600
  * @param workspacePath - Absolute path to workspace root
6432
6601
  * @returns EntrySniffResult with env vars and optional error
6433
6602
  */
6434
- async function sniffRouteFiles(routes, appPath, workspacePath) {
6603
+ async function sniffRouteFiles(routes, appPath, workspacePath, run = {}) {
6435
6604
  const fullAppPath = resolve(workspacePath, appPath);
6436
6605
  const workerPath = resolveSnifferFile("sniffer-routes-worker");
6437
- const tsxPath = resolveTsxPath();
6438
6606
  const pattern = (Array.isArray(routes) ? routes : [routes])[0];
6439
6607
  if (!pattern) return {
6440
6608
  envVars: [],
6441
6609
  optionalEnvVars: [],
6442
6610
  error: /* @__PURE__ */ new Error("No route patterns provided")
6443
6611
  };
6444
- return new Promise((resolvePromise) => {
6445
- const child = spawn("node", [
6446
- "--import",
6447
- tsxPath,
6448
- workerPath,
6449
- fullAppPath,
6450
- pattern
6451
- ], {
6452
- cwd: fullAppPath,
6453
- stdio: [
6454
- "ignore",
6455
- "pipe",
6456
- "pipe"
6457
- ],
6458
- env: { ...process.env }
6459
- });
6460
- let stdout = "";
6461
- let stderr = "";
6462
- child.stdout.on("data", (data) => {
6463
- stdout += data.toString();
6464
- });
6465
- child.stderr.on("data", (data) => {
6466
- stderr += data.toString();
6467
- });
6468
- child.on("close", (code) => {
6469
- if (stderr) stderr.split("\n").filter((line) => line.trim()).forEach((line) => output.warn(line));
6470
- try {
6471
- const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
6472
- if (jsonMatch) {
6473
- const result = JSON.parse(jsonMatch[0]);
6474
- resolvePromise({
6475
- envVars: result.envVars || [],
6476
- optionalEnvVars: result.optionalEnvVars || [],
6477
- error: result.error ? new Error(result.error) : void 0
6478
- });
6479
- return;
6480
- }
6481
- } catch {}
6482
- resolvePromise({
6483
- envVars: [],
6484
- optionalEnvVars: [],
6485
- error: /* @__PURE__ */ new Error(`Failed to sniff route files (exit code ${code}): ${stderr || stdout || "No output"}`)
6486
- });
6487
- });
6488
- child.on("error", (err) => {
6489
- resolvePromise({
6490
- envVars: [],
6491
- optionalEnvVars: [],
6492
- error: err
6493
- });
6494
- });
6495
- });
6612
+ const ran = await runSniffer(run, workspacePath, fullAppPath, nodeWithTsx(workerPath, [fullAppPath, pattern]));
6613
+ if ("error" in ran) return {
6614
+ envVars: [],
6615
+ optionalEnvVars: [],
6616
+ error: ran.error
6617
+ };
6618
+ if (ran.stderr) ran.stderr.split("\n").filter((line) => line.trim()).forEach((line) => output.warn(line));
6619
+ const answer = snifferAnswer(ran.stdout);
6620
+ if (answer) return {
6621
+ envVars: answer.envVars || [],
6622
+ optionalEnvVars: answer.optionalEnvVars || [],
6623
+ error: answer.error ? new Error(answer.error) : void 0
6624
+ };
6625
+ return {
6626
+ envVars: [],
6627
+ optionalEnvVars: [],
6628
+ error: /* @__PURE__ */ new Error(`Failed to sniff route files (exit code ${ran.code}): ${ran.stderr || ran.stdout || "No output"}`)
6629
+ };
6496
6630
  }
6497
6631
  /**
6498
6632
  * Run the SnifferEnvironmentParser on an envParser module to detect
6499
6633
  * which environment variables it accesses.
6500
6634
  *
6501
- * This function handles "fire and forget" async operations by using
6502
- * the shared sniffWithFireAndForget utility from @geekmidas/envkit.
6635
+ * In a subprocess, like the entry and route sniffers: the module is the
6636
+ * project's code, and it was imported into the deploy itself before — with
6637
+ * every credential the deploy held in reach. Fire-and-forget rejections are
6638
+ * collected there with the shared `sniffWithFireAndForget`.
6503
6639
  *
6504
6640
  * @param envParserPath - The envParser config (e.g., './src/config/env#envParser')
6505
6641
  * @param appPath - The app's path relative to workspace
6506
6642
  * @param workspacePath - Absolute path to workspace root
6507
6643
  * @returns SniffResult with env vars and any errors encountered
6508
6644
  */
6509
- async function sniffEnvParser(envParserPath, appPath, workspacePath) {
6645
+ async function sniffEnvParser(envParserPath, appPath, workspacePath, run = {}) {
6510
6646
  const [modulePath, exportName = "default"] = envParserPath.split("#");
6511
6647
  if (!modulePath) return {
6512
6648
  envVars: [],
6513
6649
  optionalEnvVars: [],
6514
6650
  unhandledRejections: []
6515
6651
  };
6516
- const fullPath = resolve(workspacePath, appPath, modulePath);
6517
- let SnifferEnvironmentParser;
6518
- let sniffWithFireAndForget;
6519
- try {
6520
- const envkitModule = await import("@geekmidas/envkit/sniffer");
6521
- SnifferEnvironmentParser = envkitModule.SnifferEnvironmentParser;
6522
- sniffWithFireAndForget = envkitModule.sniffWithFireAndForget;
6523
- } catch (error) {
6524
- const message = error instanceof Error ? error.message : String(error);
6525
- output.warn(`[sniffer] Failed to import SnifferEnvironmentParser: ${message}`);
6526
- return {
6527
- envVars: [],
6528
- optionalEnvVars: [],
6529
- unhandledRejections: []
6530
- };
6531
- }
6532
- const sniffer = new SnifferEnvironmentParser();
6533
- return sniffWithFireAndForget(sniffer, async () => {
6534
- const envParser = (await import(pathToFileURL(fullPath).href))[exportName];
6535
- if (typeof envParser !== "function") {
6536
- output.warn(`[sniffer] Export "${exportName}" from "${modulePath}" is not a function`);
6537
- return;
6538
- }
6539
- const result = envParser(sniffer);
6540
- if (result && typeof result.parse === "function") try {
6541
- result.parse();
6542
- } catch {}
6543
- });
6652
+ const appRoot = resolve(workspacePath, appPath);
6653
+ const fullPath = resolve(appRoot, modulePath);
6654
+ const workerPath = resolveSnifferFile("sniffer-envparser-worker");
6655
+ const ran = await runSniffer(run, workspacePath, appRoot, nodeWithTsx(workerPath, [fullPath, exportName]));
6656
+ if ("error" in ran) return {
6657
+ envVars: [],
6658
+ optionalEnvVars: [],
6659
+ unhandledRejections: [],
6660
+ error: ran.error
6661
+ };
6662
+ const answer = snifferAnswer(ran.stdout);
6663
+ if (!answer) return {
6664
+ envVars: [],
6665
+ optionalEnvVars: [],
6666
+ unhandledRejections: [],
6667
+ error: /* @__PURE__ */ new Error(`Failed to sniff envParser (exit code ${ran.code}): ${ran.stderr || ran.stdout || "No output"}`)
6668
+ };
6669
+ for (const warning of answer.warnings ?? []) output.warn(warning);
6670
+ return {
6671
+ envVars: answer.envVars ?? [],
6672
+ optionalEnvVars: answer.optionalEnvVars ?? [],
6673
+ unhandledRejections: (answer.unhandledRejections ?? []).map((message) => new Error(message)),
6674
+ ...answer.error ? { error: new Error(answer.error) } : {}
6675
+ };
6544
6676
  }
6545
6677
  /**
6546
6678
  * Sniff environment requirements for multiple apps.
@@ -6559,6 +6691,6 @@ async function sniffAllApps(apps, workspacePath, options = {}) {
6559
6691
  return results;
6560
6692
  }
6561
6693
  //#endregion
6562
- export { quoteIdentifier as $, StateStoreBusy as A, getDokployCredentials as At, run as B, setDnsRecord as C, loadEnvFiles as Ct, DocumentStateStore as D, logoutCommand as Dt, setPostgresBackupId as E, loginCommand as Et, newLockHolder as F, storeDokployCredentials as Ft, derivedContainers as G, FAKE_ENV as H, withGeneratedSecrets as I, canPrompt as It, LOCAL_CA_PATH as J, reconcileWorkspace as K, encryptSecrets as L, prompt as Lt, StateVersionConflict as M, getDokployToken as Mt, contentVersion as N, getHostingerToken as Nt, StageStateMissing as O, validateDokployToken as Ot, createStateStore as P, readCredentials as Pt, postgresStatements as Q, encryption_exports as R, setDeployedImage as S, isPortAvailable as St, setGeneratedSecret as T, prepareEntryCredentials as Tt, backendsOf as U, runOutput as V, constructGlobs as W, applyPostgres as X, forgetState as Y, postgresDatabaseNames as Z, getBackupState as _, primaryPortKey as _t, DockerBuildFailed as a, localRolePassword as at, setApplicationId as b, createEntryWrapper as bt, dockerCommand as c, hostFor as ct, generateDockerignore as d, providerOf as dt, composeFor as et, generateSlimDockerfile as f, storageBackendFor as ft, createEmptyState as g, portKeys as gt, resolveHost as h, fakeKey as ht, DokployApiError as i, envFor as it, StateStoreWithoutLocking as j, getDokployRegistryId as jt, StateLocked as k, whoamiCommand as kt, siteDockerfile as l, cacheBackendFor as lt, isMainFrontendApp as m, describeServices as mt, sniffAppEnvironment as n, appEnvKeys as nt, DockerPushFailed as o, planFor as ot, validateImageRef as p, DEFAULT_IMAGES as pt, workspace_exports as q, DokployApi as r, networkEnv as rt, appPackageName as s, resourceName as st, sniffAllApps as t, pgClient as tt, detectPackageManager as u, eventsBackendFor as ut, getGeneratedSecret as v, withOwningTsconfigJsx as vt, setDnsVerification as w, loadSecretsForApp as wt, setBackupState as x, findAvailablePort as xt, isDnsVerified as y, createCredentialsPreload as yt, keyFingerprint as z };
6694
+ export { workspace_exports as $, StateStoreBusy as A, prepareEntryCredentials as At, LocalSandbox as B, storeDokployCredentials as Bt, setDnsRecord as C, primaryPortKey as Ct, DocumentStateStore as D, isPortAvailable as Dt, setPostgresBackupId as E, findAvailablePort as Et, newLockHolder as F, getDokployCredentials as Ft, DEFAULT_TIMEOUT_MS as G, allowlistedEnv as H, prompt as Ht, withGeneratedSecrets as I, getDokployRegistryId as It, FAKE_ENV as J, run as K, encryptSecrets as L, getDokployToken as Lt, StateVersionConflict as M, logoutCommand as Mt, contentVersion as N, validateDokployToken as Nt, StageStateMissing as O, loadEnvFiles as Ot, createStateStore as P, whoamiCommand as Pt, reconcileWorkspace as Q, encryption_exports as R, getHostingerToken as Rt, setDeployedImage as S, portKeys as St, setGeneratedSecret as T, createEntryWrapper as Tt, CommandFailed as U, SANDBOX_ENV_ALLOWLIST as V, canPrompt as Vt, CommandTimedOut as W, constructGlobs as X, backendsOf as Y, derivedContainers as Z, getBackupState as _, providerOf as _t, DockerBuildFailed as a, quoteIdentifier as at, setApplicationId as b, describeServices as bt, dockerCommand as c, appEnvKeys as ct, generateDockerignore as d, localRolePassword as dt, LOCAL_CA_PATH as et, generateSlimDockerfile as f, planFor as ft, createEmptyState as g, eventsBackendFor as gt, resolveHost as h, cacheBackendFor as ht, DokployApiError as i, postgresStatements as it, StateStoreWithoutLocking as j, loginCommand as jt, StateLocked as k, loadSecretsForApp as kt, siteDockerfile as l, networkEnv as lt, isMainFrontendApp as m, hostFor as mt, sniffAppEnvironment as n, applyPostgres as nt, DockerPushFailed as o, composeFor as ot, validateImageRef as p, resourceName as pt, runOutput as q, DokployApi as r, postgresDatabaseNames as rt, appPackageName as s, pgClient as st, sniffAllApps as t, forgetState as tt, detectPackageManager as u, envFor as ut, getGeneratedSecret as v, storageBackendFor as vt, setDnsVerification as w, createCredentialsPreload as wt, setBackupState as x, fakeKey as xt, isDnsVerified as y, DEFAULT_IMAGES as yt, keyFingerprint as z, readCredentials as zt };
6563
6695
 
6564
- //# sourceMappingURL=sniffer-DHE2Nafd.mjs.map
6696
+ //# sourceMappingURL=sniffer-aO_-s5vq.mjs.map