@geekmidas/cli 10.0.0-alpha.64 → 10.0.0-alpha.65

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 (175) hide show
  1. package/README.md +1 -1
  2. package/dist/{HostingerProvider-Bx2lHHvu.cjs → HostingerProvider-Dlmbfass.cjs} +3 -3
  3. package/dist/{HostingerProvider-Bx2lHHvu.cjs.map → HostingerProvider-Dlmbfass.cjs.map} +1 -1
  4. package/dist/{HostingerProvider-Cd4aS5Kj.mjs → HostingerProvider-x9gQTAGZ.mjs} +2 -2
  5. package/dist/{HostingerProvider-Cd4aS5Kj.mjs.map → HostingerProvider-x9gQTAGZ.mjs.map} +1 -1
  6. package/dist/{LegacyStateStore-C2abV49N.cjs → LegacyStateStore-BGoo__sO.cjs} +2 -2
  7. package/dist/{LegacyStateStore-C2abV49N.cjs.map → LegacyStateStore-BGoo__sO.cjs.map} +1 -1
  8. package/dist/{LegacyStateStore-DIgkGaUP.mjs → LegacyStateStore-BUu1nQ5u.mjs} +2 -2
  9. package/dist/{LegacyStateStore-DIgkGaUP.mjs.map → LegacyStateStore-BUu1nQ5u.mjs.map} +1 -1
  10. package/dist/{LocalStateStore-DiJqKyPy.cjs → LocalStateStore-93urXyQe.cjs} +2 -2
  11. package/dist/{LocalStateStore-DiJqKyPy.cjs.map → LocalStateStore-93urXyQe.cjs.map} +1 -1
  12. package/dist/{LocalStateStore-Cy1ZBW7U.mjs → LocalStateStore-BRhMQRuy.mjs} +2 -2
  13. package/dist/{LocalStateStore-Cy1ZBW7U.mjs.map → LocalStateStore-BRhMQRuy.mjs.map} +1 -1
  14. package/dist/{S3StateStore-Ds0V1Lgm.cjs → S3StateStore-F4dxw6kS.cjs} +2 -2
  15. package/dist/{S3StateStore-Ds0V1Lgm.cjs.map → S3StateStore-F4dxw6kS.cjs.map} +1 -1
  16. package/dist/{S3StateStore-D3x6ivBL.mjs → S3StateStore-pw1GhWwt.mjs} +2 -2
  17. package/dist/{S3StateStore-D3x6ivBL.mjs.map → S3StateStore-pw1GhWwt.mjs.map} +1 -1
  18. package/dist/{SSMStateStore-CLipvx47.cjs → SSMStateStore-Bt9acuAF.cjs} +2 -2
  19. package/dist/{SSMStateStore-CLipvx47.cjs.map → SSMStateStore-Bt9acuAF.cjs.map} +1 -1
  20. package/dist/{SSMStateStore-DfF174xQ.mjs → SSMStateStore-Dmj7zzFO.mjs} +2 -2
  21. package/dist/{SSMStateStore-DfF174xQ.mjs.map → SSMStateStore-Dmj7zzFO.mjs.map} +1 -1
  22. package/dist/{bundler-C8uJf324.cjs → bundler-D6MlIfBT.cjs} +3 -3
  23. package/dist/{bundler-C8uJf324.cjs.map → bundler-D6MlIfBT.cjs.map} +1 -1
  24. package/dist/{bundler-DYgm9xsd.mjs → bundler-D_14JLZF.mjs} +3 -3
  25. package/dist/{bundler-DYgm9xsd.mjs.map → bundler-D_14JLZF.mjs.map} +1 -1
  26. package/dist/{cli-D3jofJ6j.cjs → cli-BfH1deAT.cjs} +6 -6
  27. package/dist/{cli-D3jofJ6j.cjs.map → cli-BfH1deAT.cjs.map} +1 -1
  28. package/dist/{cli-Bogz-zEj.mjs → cli-P56vvrDQ.mjs} +5 -5
  29. package/dist/{cli-Bogz-zEj.mjs.map → cli-P56vvrDQ.mjs.map} +1 -1
  30. package/dist/compose-391oEKj1.cjs +1982 -0
  31. package/dist/compose-391oEKj1.cjs.map +1 -0
  32. package/dist/compose-DprE3ASm.mjs +1862 -0
  33. package/dist/compose-DprE3ASm.mjs.map +1 -0
  34. package/dist/{config-DqNRiQOp.d.mts → config-BonvTW8p.d.mts} +3 -3
  35. package/dist/{config-Be-4_I6H.d.cts.map → config-BonvTW8p.d.mts.map} +1 -1
  36. package/dist/{config-Be-4_I6H.d.cts → config-V_X_BMpm.d.cts} +3 -3
  37. package/dist/{config-DqNRiQOp.d.mts.map → config-V_X_BMpm.d.cts.map} +1 -1
  38. package/dist/config.cjs +1 -1
  39. package/dist/config.d.cts +3 -3
  40. package/dist/config.d.mts +3 -3
  41. package/dist/config.mjs +1 -1
  42. package/dist/{credentials-B70vmLcm.cjs → credentials-Bzbg23n8.cjs} +176 -3
  43. package/dist/credentials-Bzbg23n8.cjs.map +1 -0
  44. package/dist/{credentials-s0wMeZBU.mjs → credentials-Dq1MnWQf.mjs} +128 -3
  45. package/dist/credentials-Dq1MnWQf.mjs.map +1 -0
  46. package/dist/{define-CYs0PEfZ.mjs → define-DR8xGYfL.mjs} +5 -1
  47. package/dist/define-DR8xGYfL.mjs.map +1 -0
  48. package/dist/{define-zUsP72ym.cjs → define-DzRz8FgH.cjs} +5 -1
  49. package/dist/define-DzRz8FgH.cjs.map +1 -0
  50. package/dist/deploy/public.cjs +18 -18
  51. package/dist/deploy/public.cjs.map +1 -1
  52. package/dist/deploy/public.d.cts +7 -4
  53. package/dist/deploy/public.d.cts.map +1 -1
  54. package/dist/deploy/public.d.mts +7 -4
  55. package/dist/deploy/public.d.mts.map +1 -1
  56. package/dist/deploy/public.mjs +11 -11
  57. package/dist/{deploy-Dc2LBJaK.mjs → deploy-9MBG_QLd.mjs} +8 -7
  58. package/dist/deploy-9MBG_QLd.mjs.map +1 -0
  59. package/dist/{deploy-yUcR2OlW.cjs → deploy-B80idPUZ.cjs} +11 -10
  60. package/dist/deploy-B80idPUZ.cjs.map +1 -0
  61. package/dist/{deploy-ZRXIPp1c.mjs → deploy-CZ5nlpsu.mjs} +13 -119
  62. package/dist/deploy-CZ5nlpsu.mjs.map +1 -0
  63. package/dist/{deploy-55rJkdKz.cjs → deploy-Cy8igpQF.cjs} +39 -145
  64. package/dist/deploy-Cy8igpQF.cjs.map +1 -0
  65. package/dist/{dokploy-CepdXuMl.mjs → dokploy-BdtBePjp.mjs} +3 -3
  66. package/dist/{dokploy-CepdXuMl.mjs.map → dokploy-BdtBePjp.mjs.map} +1 -1
  67. package/dist/{dokploy-D1d37rvM.cjs → dokploy-iFY8MY-L.cjs} +3 -3
  68. package/dist/{dokploy-D1d37rvM.cjs.map → dokploy-iFY8MY-L.cjs.map} +1 -1
  69. package/dist/{encryption-C9X98u2F.cjs → encryption-B1wJwgae.cjs} +5 -5
  70. package/dist/{encryption-C9X98u2F.cjs.map → encryption-B1wJwgae.cjs.map} +1 -1
  71. package/dist/{encryption-CKHjMpCr.mjs → encryption-DF_hgIpl.mjs} +4 -4
  72. package/dist/{encryption-CKHjMpCr.mjs.map → encryption-DF_hgIpl.mjs.map} +1 -1
  73. package/dist/{github-D-byNI7T.mjs → github-B0YYE98x.mjs} +3 -3
  74. package/dist/{github-D-byNI7T.mjs.map → github-B0YYE98x.mjs.map} +1 -1
  75. package/dist/{github-Dd3tMa1u.cjs → github-CYcmTdFs.cjs} +3 -3
  76. package/dist/{github-Dd3tMa1u.cjs.map → github-CYcmTdFs.cjs.map} +1 -1
  77. package/dist/{index-CfE9Y885.d.cts → index-DPUAGJaK.d.cts} +16 -3
  78. package/dist/index-DPUAGJaK.d.cts.map +1 -0
  79. package/dist/{index-CJ2qsSpp.d.mts → index-DwKD_8lt.d.mts} +16 -3
  80. package/dist/index-DwKD_8lt.d.mts.map +1 -0
  81. package/dist/index.cjs +233 -1667
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.mjs +196 -1614
  84. package/dist/index.mjs.map +1 -1
  85. package/dist/{local-C7wnrcYK.cjs → local-BdH4XN0E.cjs} +1 -178
  86. package/dist/local-BdH4XN0E.cjs.map +1 -0
  87. package/dist/{local-Cd8ZYQG3.mjs → local-CWR4Y_kW.mjs} +3 -126
  88. package/dist/local-CWR4Y_kW.mjs.map +1 -0
  89. package/dist/{migrate-B4gngTLe.mjs → migrate-B2qL5wj4.mjs} +6 -5
  90. package/dist/{migrate-B4gngTLe.mjs.map → migrate-B2qL5wj4.mjs.map} +1 -1
  91. package/dist/{migrate-tx9-P9uz.cjs → migrate-q4pPAXtO.cjs} +19 -18
  92. package/dist/{migrate-tx9-P9uz.cjs.map → migrate-q4pPAXtO.cjs.map} +1 -1
  93. package/dist/openapi.d.cts +1 -1
  94. package/dist/openapi.d.mts +1 -1
  95. package/dist/provider-C9_-45d5.cjs +56 -0
  96. package/dist/provider-C9_-45d5.cjs.map +1 -0
  97. package/dist/provider-q4lsYzYG.mjs +45 -0
  98. package/dist/provider-q4lsYzYG.mjs.map +1 -0
  99. package/dist/reconcile/public.d.cts +1 -1
  100. package/dist/reconcile/public.d.mts +1 -1
  101. package/dist/resolve-DLkIXTct.mjs +262 -0
  102. package/dist/resolve-DLkIXTct.mjs.map +1 -0
  103. package/dist/resolve-N_i4XNd-.cjs +315 -0
  104. package/dist/resolve-N_i4XNd-.cjs.map +1 -0
  105. package/dist/{runtime-CJEYK4Gz.d.mts → runtime-BnD7Nn96.d.cts} +2 -2
  106. package/dist/{runtime-CJEYK4Gz.d.mts.map → runtime-BnD7Nn96.d.cts.map} +1 -1
  107. package/dist/{runtime-Cjq1jlVX.d.cts → runtime-j-tmFL65.d.mts} +2 -2
  108. package/dist/{runtime-Cjq1jlVX.d.cts.map → runtime-j-tmFL65.d.mts.map} +1 -1
  109. package/dist/sniffer-BSwaL-dX.cjs +2236 -0
  110. package/dist/sniffer-BSwaL-dX.cjs.map +1 -0
  111. package/dist/sniffer-BZ-OJO4Y.mjs +2068 -0
  112. package/dist/sniffer-BZ-OJO4Y.mjs.map +1 -0
  113. package/dist/{sst-Cper040I.mjs → sst-B2HbrDR3.mjs} +4 -4
  114. package/dist/{sst-Cper040I.mjs.map → sst-B2HbrDR3.mjs.map} +1 -1
  115. package/dist/{sst-BdALKEas.cjs → sst-DcfsVH6x.cjs} +4 -4
  116. package/dist/{sst-BdALKEas.cjs.map → sst-DcfsVH6x.cjs.map} +1 -1
  117. package/dist/{sniffer-49KPbDgq.mjs → state-B8YwmUZU.mjs} +878 -2465
  118. package/dist/state-B8YwmUZU.mjs.map +1 -0
  119. package/dist/{sniffer-ByhbEW5A.cjs → state-DF26e_lo.cjs} +811 -2525
  120. package/dist/state-DF26e_lo.cjs.map +1 -0
  121. package/dist/{store-D_2ByRtW.cjs → store-CJF1Tqkq.cjs} +2 -2
  122. package/dist/{store-D_2ByRtW.cjs.map → store-CJF1Tqkq.cjs.map} +1 -1
  123. package/dist/{store-BaaonhkJ.mjs → store-CLiHnqOY.mjs} +2 -2
  124. package/dist/{store-BaaonhkJ.mjs.map → store-CLiHnqOY.mjs.map} +1 -1
  125. package/dist/target/public.cjs +6 -6
  126. package/dist/target/public.d.cts +2 -2
  127. package/dist/target/public.d.mts +2 -2
  128. package/dist/target/public.mjs +3 -3
  129. package/dist/terminal-Bs5E1oxm.cjs +88 -0
  130. package/dist/terminal-Bs5E1oxm.cjs.map +1 -0
  131. package/dist/terminal-CfbiYUbZ.mjs +84 -0
  132. package/dist/terminal-CfbiYUbZ.mjs.map +1 -0
  133. package/dist/{types-B_bEQvb9.d.mts → types-BCzMWBb6.d.mts} +43 -11
  134. package/dist/types-BCzMWBb6.d.mts.map +1 -0
  135. package/dist/{types-DkrDOMxw.d.cts → types-ByMWkXKP.d.cts} +43 -11
  136. package/dist/types-ByMWkXKP.d.cts.map +1 -0
  137. package/dist/workspace/index.cjs +3 -1
  138. package/dist/workspace/index.d.cts +3 -3
  139. package/dist/workspace/index.d.mts +3 -3
  140. package/dist/workspace/index.mjs +2 -2
  141. package/dist/{workspace-BwgWJK7h.cjs → workspace-BewAHZIo.cjs} +38 -3
  142. package/dist/workspace-BewAHZIo.cjs.map +1 -0
  143. package/dist/{workspace-Bwit4q9O.mjs → workspace-C06_pW4g.mjs} +27 -4
  144. package/dist/workspace-C06_pW4g.mjs.map +1 -0
  145. package/package.json +13 -13
  146. package/dist/credentials-B70vmLcm.cjs.map +0 -1
  147. package/dist/credentials-s0wMeZBU.mjs.map +0 -1
  148. package/dist/define-CYs0PEfZ.mjs.map +0 -1
  149. package/dist/define-zUsP72ym.cjs.map +0 -1
  150. package/dist/deploy-55rJkdKz.cjs.map +0 -1
  151. package/dist/deploy-Dc2LBJaK.mjs.map +0 -1
  152. package/dist/deploy-ZRXIPp1c.mjs.map +0 -1
  153. package/dist/deploy-yUcR2OlW.cjs.map +0 -1
  154. package/dist/index-CJ2qsSpp.d.mts.map +0 -1
  155. package/dist/index-CfE9Y885.d.cts.map +0 -1
  156. package/dist/local-C7wnrcYK.cjs.map +0 -1
  157. package/dist/local-Cd8ZYQG3.mjs.map +0 -1
  158. package/dist/resolve-BXsNQjMR.cjs +0 -220
  159. package/dist/resolve-BXsNQjMR.cjs.map +0 -1
  160. package/dist/resolve-DZ2IJ0qY.mjs +0 -173
  161. package/dist/resolve-DZ2IJ0qY.mjs.map +0 -1
  162. package/dist/runtime-BGNDrHzh.cjs +0 -163
  163. package/dist/runtime-BGNDrHzh.cjs.map +0 -1
  164. package/dist/runtime-Cmn-FeYO.mjs +0 -134
  165. package/dist/runtime-Cmn-FeYO.mjs.map +0 -1
  166. package/dist/sniffer-49KPbDgq.mjs.map +0 -1
  167. package/dist/sniffer-ByhbEW5A.cjs.map +0 -1
  168. package/dist/terminal-Bdv--jhY.cjs +0 -481
  169. package/dist/terminal-Bdv--jhY.cjs.map +0 -1
  170. package/dist/terminal-D7Ntz6WE.mjs +0 -440
  171. package/dist/terminal-D7Ntz6WE.mjs.map +0 -1
  172. package/dist/types-B_bEQvb9.d.mts.map +0 -1
  173. package/dist/types-DkrDOMxw.d.cts.map +0 -1
  174. package/dist/workspace-BwgWJK7h.cjs.map +0 -1
  175. package/dist/workspace-Bwit4q9O.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy-yUcR2OlW.cjs","names":["Redactor","storedCredentials","gkmHome","withOutput","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","runDeploy","eventError","loadWorkspaceConfig"],"sources":["../src/deploy/deploy.ts"],"sourcesContent":["/**\n * `deploy()`: a deploy as a library call.\n *\n * `gkm deploy` could only be driven from an interactive terminal: it prompted\n * for what it lacked and exited the process on failure, worked out of\n * `process.cwd()`, and reported progress by printing. Here the caller says\n * where the project is, hands over the credentials and a signal, and gets back\n * a run — events to iterate while it goes, and a structured result at the end.\n * Nothing below this asks a person anything or ends the process; `gkm deploy`\n * is a thin wrapper that does both.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../config';\nimport { gkmHome } from '../home';\nimport { type OutputLevel, withOutput } from '../output';\nimport { LocalSandbox } from '../sandbox/local';\nimport { type Sandbox, withSandbox } from '../sandbox/sandbox';\nimport { Redactor } from '../target/secrets';\nimport type { AnyDeployTarget } from '../target/types';\nimport { assertDeployedStage } from '../workspace/stages.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport { type CredentialProvider, storedCredentials } from './credentials';\nimport { type DeployEvent, eventError } from './events';\nimport { type DeployContext, runDeploy } from './orchestrate';\nimport type { DeployResult } from './types';\n\n/**\n * Where a run's progress lines go, besides its events. `@geekmidas/logger`'s\n * `Logger` is one.\n */\nexport interface DeployLogger {\n\tinfo(message: string): void;\n\twarn(message: string): void;\n\terror?(message: string): void;\n}\n\nexport interface DeployInput {\n\t/**\n\t * The project to deploy: the directory holding `gkm.config.ts`, or any\n\t * directory inside it. Never assumed to be `process.cwd()`.\n\t */\n\tcwd: string;\n\t/** The stage to deploy — one of the config's deployed stages. */\n\tstage: string;\n\t/**\n\t * The target to deploy through, by name. Defaults to `deploy.default`,\n\t * else `dokploy`.\n\t */\n\ttarget?: string;\n\t/**\n\t * The host's own targets, by name. Consulted before the built-ins and the\n\t * config's `deploy.targets`, so a host can deploy through an\n\t * implementation of its own — `{ dokploy: myDokploy }` included.\n\t */\n\ttargets?: Record<string, AnyDeployTarget>;\n\t/** The image tag. Defaults to `<stage>-<timestamp>`. */\n\ttag?: string;\n\t/** Deploy only these apps (in dependency order). Defaults to all. */\n\tapps?: string[];\n\t/**\n\t * Look everything up and report what would happen — as `resource.planned`\n\t * events — without taking the lock, writing state, generating secrets,\n\t * changing Dokploy or building and pushing images.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Where credentials come from. Defaults to the environment, then the\n\t * logins `gkm login` stored. A credential no provider has stops the run\n\t * with `MissingCredential`; nothing prompts.\n\t */\n\tcredentials?: CredentialProvider;\n\t/** Receives each progress line as it is written. Defaults to none. */\n\tlogger?: DeployLogger;\n\t/**\n\t * Stops the run: in-flight Dokploy requests and docker children are\n\t * cancelled, the stage's lock is released, and `result` rejects with the\n\t * signal's reason.\n\t */\n\tsignal?: AbortSignal;\n\t/**\n\t * The CLI's home: stage keys and stored logins. Defaults to `GKM_HOME`,\n\t * else `~/.gkm`.\n\t */\n\thome?: string;\n\t/**\n\t * Where docker's own output goes: the host's terminal (`inherit`, the\n\t * default), its stderr, or nowhere.\n\t */\n\tchildOutput?: 'inherit' | 'stderr' | 'ignore';\n\t/**\n\t * Where the project's own code runs: loading `gkm.config.ts`, discovering\n\t * its constructs, sniffing each app's environment. Defaults to a\n\t * `LocalSandbox` on the project — a child process here with an\n\t * allowlisted environment, for a project the host trusts.\n\t *\n\t * A host deploying repositories it does not trust passes one that\n\t * isolates — a container per build — and the config then reaches the\n\t * deploy only as data. Credentials never enter a sandbox: they go from\n\t * `credentials` to the steps that provision, push and release.\n\t */\n\tsandbox?: Sandbox;\n}\n\n/** A deploy in progress. */\nexport interface DeployRun extends AsyncIterable<DeployEvent> {\n\t/**\n\t * What the deploy did, once it is done. Rejects with the error that\n\t * stopped it — `MissingCredential`, `StateLocked`, `ProjectNotOwned`, … —\n\t * after a `deploy.failed` event carrying the same.\n\t */\n\treadonly result: Promise<DeployResult>;\n}\n\n/**\n * Every event a run emits, kept so that each iteration — however late it\n * starts — sees the run from its first event to its last.\n */\nclass EventLog {\n\tprivate readonly events: DeployEvent[] = [];\n\tprivate closed = false;\n\tprivate waiting: (() => void)[] = [];\n\n\tpush(event: DeployEvent): void {\n\t\tthis.events.push(event);\n\t\tthis.wake();\n\t}\n\n\tclose(): void {\n\t\tthis.closed = true;\n\t\tthis.wake();\n\t}\n\n\tprivate wake(): void {\n\t\tconst waiting = this.waiting;\n\t\tthis.waiting = [];\n\t\tfor (const resume of waiting) resume();\n\t}\n\n\tasync *iterate(): AsyncGenerator<DeployEvent> {\n\t\tlet next = 0;\n\t\twhile (true) {\n\t\t\tif (next < this.events.length) {\n\t\t\t\tyield this.events[next++]!;\n\t\t\t} else if (this.closed) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tawait new Promise<void>((resume) => this.waiting.push(resume));\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction forward(\n\tlogger: DeployLogger | undefined,\n\tlevel: OutputLevel,\n\tmessage: string,\n): void {\n\tif (!logger) return;\n\tif (level === 'info') logger.info(message);\n\telse if (level === 'error' && logger.error) logger.error(message);\n\telse logger.warn(message);\n}\n\n/**\n * Deploy a project's stage.\n *\n * ```ts\n * import { deploy } from '@geekmidas/cli/deploy';\n *\n * const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });\n * for await (const event of run) {\n * if (event.type === 'app.deployed') console.log(event.app, event.url);\n * }\n * const result = await run.result;\n * ```\n *\n * The run starts at once; iterating it is optional, and an iteration started\n * late still sees every event from the first.\n */\nexport function deploy(input: DeployInput): DeployRun {\n\tconst log = new EventLog();\n\t// Every secret the run reads is masked in every line it reports — in the\n\t// events and in what the logger is handed.\n\tconst redactor = new Redactor();\n\tconst emit = (event: DeployEvent) => {\n\t\tconst masked =\n\t\t\tevent.type === 'log'\n\t\t\t\t? { ...event, message: redactor.redact(event.message) }\n\t\t\t\t: event;\n\t\tlog.push(masked);\n\t\tif (masked.type === 'log') {\n\t\t\tforward(input.logger, masked.level, masked.message);\n\t\t}\n\t};\n\n\tconst ctx: DeployContext = {\n\t\temit,\n\t\tcredentials:\n\t\t\tinput.credentials ?? storedCredentials({ home: input.home ?? gkmHome() }),\n\t\tdryRun: input.dryRun ?? false,\n\t\thome: input.home ?? gkmHome(),\n\t\tredactor,\n\t\t...(input.signal ? { signal: input.signal } : {}),\n\t\t...(input.childOutput ? { childOutput: input.childOutput } : {}),\n\t\t...(input.targets ? { targets: input.targets } : {}),\n\t};\n\n\t// Every line anything in the run writes through `output` — the deploy's\n\t// own, the Dockerfile generator's, discovery's warnings — becomes an event\n\t// of this run, and of no other.\n\tconst result = withOutput(\n\t\t(level, message) => emit({ type: 'log', level, message }),\n\t\tasync () => {\n\t\t\ttry {\n\t\t\t\tinput.signal?.throwIfAborted();\n\t\t\t\tconst sandbox =\n\t\t\t\t\tinput.sandbox ??\n\t\t\t\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\t\t\t\t// Every step of the run that executes the project's code — the\n\t\t\t\t// engine's own discoveries and sniffs included — runs in it.\n\t\t\t\tconst deployed = await withSandbox(sandbox, () =>\n\t\t\t\t\trunDeploy(\n\t\t\t\t\t\t() => load(input, sandbox),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstage: input.stage,\n\t\t\t\t\t\t\t...(input.target ? { target: input.target } : {}),\n\t\t\t\t\t\t\t...(input.tag ? { tag: input.tag } : {}),\n\t\t\t\t\t\t\t...(input.apps ? { apps: input.apps } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tctx,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\temit({ type: 'deploy.finished', result: deployed });\n\t\t\t\treturn deployed;\n\t\t\t} catch (error) {\n\t\t\t\temit({ type: 'deploy.failed', error: eventError(error) });\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tlog.close();\n\t\t\t}\n\t\t},\n\t);\n\n\t// A caller that only iterates still learns of the failure from the\n\t// `deploy.failed` event; the rejection must not also crash its process as\n\t// unhandled. Awaiting `result` still rejects.\n\tresult.catch(() => {});\n\n\treturn {\n\t\tresult,\n\t\t[Symbol.asyncIterator]: () => log.iterate(),\n\t};\n}\n\n/** The workspace at `input.cwd`, refusing a stage it does not deploy. */\nasync function load(\n\tinput: DeployInput,\n\tsandbox: Sandbox,\n): Promise<NormalizedWorkspace> {\n\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\tsandbox,\n\t});\n\n\t// Before anything is provisioned: a typo'd stage would otherwise create a\n\t// whole second environment under the wrong name.\n\tassertDeployedStage(workspace.stages, input.stage);\n\treturn workspace;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CJ2qsSpp.d.mts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"mappings":";;;;;;;;;cASa;;;;;;;;;;;;;;;iBAoBG,mBAAmB,YAAY;;;;;iBAoB/B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC2ElB,sBAAsB,cAAc,YACnD,QAAQ,eAAe,SACrB,wBAAwB;;;;iBA8BX,mBACf,QAAQ,iBACR,cACE;;;;;iBAgDa,yBACf,QAAQ,WACR,cACE;;;;;iBAuDa,cACf,QAAQ,YAAY,iBACpB,cACE;;;;;;;iBA6Ba,wBACf,WAAW;;;;;;;;;;;;iBAkBI,kBACf,WAAW,qBACX;;;;;;;iBAsBe,kBAAkB,WAAW;;iBAa7B,kBAAkB,QAAQ;;;;;iBAS1B,gBACf,WAAW,qBACX,kBACE;;;;;iBAgCa,iBAAiB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoD5B,oBACf;EACK;EAAmB,YAAY;eAEpC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CfE9Y885.d.cts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"mappings":";;;;;;;;;cASa;;;;;;;;;;;;;;;iBAoBG,mBAAmB,YAAY;;;;;iBAoB/B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC2ElB,sBAAsB,cAAc,YACnD,QAAQ,eAAe,SACrB,wBAAwB;;;;iBA8BX,mBACf,QAAQ,iBACR,cACE;;;;;iBAgDa,yBACf,QAAQ,WACR,cACE;;;;;iBAuDa,cACf,QAAQ,YAAY,iBACpB,cACE;;;;;;;iBA6Ba,wBACf,WAAW;;;;;;;;;;;;iBAkBI,kBACf,WAAW,qBACX;;;;;;;iBAsBe,kBAAkB,WAAW;;iBAa7B,kBAAkB,QAAQ;;;;;iBAS1B,gBACf,WAAW,qBACX,kBACE;;;;;iBAgCa,iBAAiB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoD5B,oBACf;EACK;EAAmB,YAAY;eAEpC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"local-C7wnrcYK.cjs","names":["resolve","join","homedir","join","existsSync","readFile","writeFile","KILL_GRACE_MS","spawn","resolve","confineCwd","SECRETS_DIR_ENV","rm","mkdtemp","join","tmpdir","writeFile","spawn"],"sources":["../src/home.ts","../src/auth/credentials.ts","../src/run.ts","../src/sandbox/env.ts","../src/sandbox/local.ts"],"sourcesContent":["/**\n * Where the CLI keeps what belongs to a person rather than a project: stage\n * keys and stored provider credentials.\n *\n * `GKM_HOME` names it, so a CI job, a shared build runner or a test can give\n * every run its own instead of reaching into whoever's home directory the\n * process happens to have. Unset, it is `~/.gkm`, where it has always been.\n */\n\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\n/** The environment variable that moves the CLI's home. */\nexport const GKM_HOME_ENV = 'GKM_HOME';\n\n/** The CLI's home: `GKM_HOME` if set, else `~/.gkm`. */\nexport function gkmHome(env: NodeJS.ProcessEnv = process.env): string {\n\tconst configured = env[GKM_HOME_ENV];\n\treturn configured ? resolve(configured) : join(homedir(), '.gkm');\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { gkmHome } from '../home';\n\n/**\n * Stored credentials for various services\n */\nexport interface StoredCredentials {\n\tdokploy?: {\n\t\t/** API token */\n\t\ttoken: string;\n\t\t/** Dokploy endpoint URL */\n\t\tendpoint: string;\n\t\t/** Registry ID in Dokploy (for Docker image pulls) */\n\t\tregistryId?: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n\thostinger?: {\n\t\t/** API token from hpanel.hostinger.com/profile/api */\n\t\ttoken: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n}\n\n/**\n * Options for credential operations\n */\nexport interface CredentialOptions {\n\t/**\n\t * A directory whose `.gkm` holds the credentials. Default: the CLI's home\n\t * (`GKM_HOME`, else `~/.gkm`).\n\t */\n\troot?: string;\n\t/** The CLI's home itself, holding `credentials.json`. Wins over `root`. */\n\thome?: string;\n}\n\n/**\n * Get the path to the credentials directory\n */\nexport function getCredentialsDir(options?: CredentialOptions): string {\n\tif (options?.home) return options.home;\n\treturn options?.root ? join(options.root, '.gkm') : gkmHome();\n}\n\n/**\n * Get the path to the credentials file\n */\nexport function getCredentialsPath(options?: CredentialOptions): string {\n\treturn join(getCredentialsDir(options), 'credentials.json');\n}\n\n/**\n * Ensure the credentials directory exists\n */\nfunction ensureCredentialsDir(options?: CredentialOptions): void {\n\tconst dir = getCredentialsDir(options);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Read stored credentials from disk\n */\nexport async function readCredentials(\n\toptions?: CredentialOptions,\n): Promise<StoredCredentials> {\n\tconst path = getCredentialsPath(options);\n\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = await readFile(path, 'utf-8');\n\t\treturn JSON.parse(content) as StoredCredentials;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/**\n * Write credentials to disk\n */\nexport async function writeCredentials(\n\tcredentials: StoredCredentials,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tensureCredentialsDir(options);\n\tconst path = getCredentialsPath(options);\n\n\tawait writeFile(path, JSON.stringify(credentials, null, 2), {\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n/**\n * Store Dokploy credentials\n */\nexport async function storeDokployCredentials(\n\ttoken: string,\n\tendpoint: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.dokploy = {\n\t\ttoken,\n\t\tendpoint,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Dokploy credentials\n */\nexport async function getDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<{\n\ttoken: string;\n\tendpoint: string;\n\tregistryId?: string;\n} | null> {\n\tconst credentials = await readCredentials(options);\n\n\t// The environment first, and each half independently.\n\t//\n\t// `getDokployToken` has always read `DOKPLOY_API_TOKEN` while this — the\n\t// function the deploy path actually calls — read only the file. So a CI job\n\t// given the token as a secret had a token and nowhere to send it, and the\n\t// only way through was committing a credentials file or running an\n\t// interactive login on the runner.\n\t//\n\t// Read separately rather than as a pair because they arrive separately: a\n\t// token is a secret and belongs in the environment, while an endpoint is\n\t// configuration and usually belongs in `deploy.dokploy.endpoint`. Requiring\n\t// both from the same place is what made either one useless alone.\n\tconst token = process.env.DOKPLOY_API_TOKEN ?? credentials.dokploy?.token;\n\tconst endpoint =\n\t\tprocess.env.DOKPLOY_ENDPOINT ?? credentials.dokploy?.endpoint;\n\n\tif (!token || !endpoint) return null;\n\n\treturn {\n\t\ttoken,\n\t\tendpoint: endpoint.replace(/\\/$/, ''),\n\t\t...(credentials.dokploy?.registryId\n\t\t\t? { registryId: credentials.dokploy.registryId }\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Remove Dokploy credentials\n */\nexport async function removeDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.dokploy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n/**\n * Remove all stored credentials\n */\nexport async function removeAllCredentials(\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst path = getCredentialsPath(options);\n\n\tif (existsSync(path)) {\n\t\tawait unlink(path);\n\t}\n}\n\n/**\n * Get Dokploy API token, checking stored credentials first, then environment\n */\nexport async function getDokployToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.DOKPLOY_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst stored = await getDokployCredentials(options);\n\tif (stored) {\n\t\treturn stored.token;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get Dokploy endpoint from stored credentials\n */\nexport async function getDokployEndpoint(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.endpoint ?? null;\n}\n\n/**\n * Store Dokploy registry ID\n */\nexport async function storeDokployRegistryId(\n\tregistryId: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found. Run \"gkm login --service dokploy\" first.',\n\t\t);\n\t}\n\n\tcredentials.dokploy.registryId = registryId;\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get Dokploy registry ID from stored credentials\n */\nexport async function getDokployRegistryId(\n\toptions?: CredentialOptions,\n): Promise<string | undefined> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.registryId ?? undefined;\n}\n\n// ============================================\n// Hostinger credentials\n// ============================================\n\n/**\n * Store Hostinger API token\n *\n * @param token - API token from hpanel.hostinger.com/profile/api\n */\nexport async function storeHostingerToken(\n\ttoken: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.hostinger = {\n\t\ttoken,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Hostinger API token\n *\n * Checks environment variable first (HOSTINGER_API_TOKEN),\n * then falls back to stored credentials.\n */\nexport async function getHostingerToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.HOSTINGER_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst credentials = await readCredentials(options);\n\treturn credentials.hostinger?.token ?? null;\n}\n\n/**\n * Remove Hostinger credentials\n */\nexport async function removeHostingerCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.hostinger) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.hostinger;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n","/**\n * Start a program with an argument array, never a shell string.\n *\n * `gkm build`, `gkm docker` and `gkm deploy` pass values that come from the\n * workspace — image refs, tags, build args, package names — to `docker` and\n * `turbo`. Joined into a string and handed to a shell, a package named\n * `x;curl …|sh` or a tag holding `$(…)` became part of the command line, which\n * matters most where the CLI builds a repository it didn't write: a CI job for a\n * fork, a shared build runner. Here every value reaches the program as one\n * `argv` element, whatever it contains.\n */\n\nimport { type SpawnOptions, spawn } from 'node:child_process';\n\n/** Long enough for a cold image build; short enough that a hung one ends. */\nexport const DEFAULT_TIMEOUT_MS = 30 * 60_000;\n\n/** How long a timed-out child has to exit on SIGTERM before it is killed. */\nconst KILL_GRACE_MS = 5_000;\n\nexport interface RunOptions {\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tstdio?: SpawnOptions['stdio'];\n\t/** Kill the child after this long. Defaults to {@link DEFAULT_TIMEOUT_MS}. */\n\ttimeoutMs?: number;\n\t/**\n\t * Kills the child when aborted, and rejects with the signal's reason — the\n\t * same as a stopped deploy's other calls.\n\t */\n\tsignal?: AbortSignal;\n}\n\n/** The command line as a person would read it — for messages, never to run. */\nfunction display(command: string, args: readonly string[]): string {\n\treturn [command, ...args].join(' ');\n}\n\n/** The program ran and exited unsuccessfully; its own output said why. */\nexport class CommandFailed extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly exitCode: number | null,\n\t\treadonly signal: NodeJS.Signals | null,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` ${exitCode === null ? `was stopped by ${signal ?? 'a signal'}` : `exited with code ${exitCode}`}. Its output above says why; run it by hand to see it again.`,\n\t\t);\n\t\tthis.name = 'CommandFailed';\n\t}\n}\n\n/** The program ran past its timeout and was killed. */\nexport class CommandTimedOut extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly timeoutMs: number,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` was still running after ${Math.round(timeoutMs / 1000)}s and was stopped. Check what it was waiting on — a registry, the Docker daemon, a prompt — and run it again.`,\n\t\t);\n\t\tthis.name = 'CommandTimedOut';\n\t}\n}\n\n/**\n * Run `command` with `args`, resolving when it exits 0.\n *\n * Rejects with {@link CommandFailed} on any other exit, {@link CommandTimedOut}\n * once `timeoutMs` passes (after the child is gone), and with the spawn error\n * itself when the program cannot be started at all — `ENOENT` already names it.\n */\nexport async function run(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions = {},\n): Promise<void> {\n\tawait spawnChild(command, args, options, false);\n}\n\n/**\n * {@link run}, resolving with what the program wrote to stdout — for a value\n * the CLI reads back, such as the digest `docker inspect` reports. stderr still\n * reaches the terminal, so a failure explains itself the same way.\n */\nexport function runOutput(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: Omit<RunOptions, 'stdio'> = {},\n): Promise<string> {\n\treturn spawnChild(command, args, options, true);\n}\n\nfunction spawnChild(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions,\n\tcapture: boolean,\n): Promise<string> {\n\tconst { timeoutMs = DEFAULT_TIMEOUT_MS, ...spawnOptions } = options;\n\n\treturn new Promise<string>((resolve, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tstdio: 'inherit',\n\t\t\t...spawnOptions,\n\t\t\t...(capture ? { stdio: ['ignore', 'pipe', 'inherit'] } : {}),\n\t\t\tshell: false,\n\t\t});\n\n\t\tlet stdout = '';\n\t\tchild.stdout?.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tlet killer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\t// A child that ignores SIGTERM would hold the deploy open forever.\n\t\t\tkiller = setTimeout(() => child.kill('SIGKILL'), KILL_GRACE_MS);\n\t\t\tkiller.unref?.();\n\t\t}, timeoutMs);\n\t\ttimer.unref?.();\n\n\t\tconst settle = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tif (killer) clearTimeout(killer);\n\t\t};\n\n\t\tchild.on('error', (error) => {\n\t\t\tsettle();\n\t\t\t// Node reports an abort as its own `AbortError`; the caller asked\n\t\t\t// with a reason, and that is what it should get back.\n\t\t\treject(spawnOptions.signal?.aborted ? spawnOptions.signal.reason : error);\n\t\t});\n\n\t\tchild.on('close', (code: number | null, signal: NodeJS.Signals | null) => {\n\t\t\tsettle();\n\t\t\tif (spawnOptions.signal?.aborted) reject(spawnOptions.signal.reason);\n\t\t\telse if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));\n\t\t\telse if (code === 0) resolve(stdout);\n\t\t\telse reject(new CommandFailed(command, args, code, signal));\n\t\t});\n\t});\n}\n","/**\n * What of the host's environment a local sandbox passes on.\n *\n * An allowlist, not a denylist: a credential's variable has any name its\n * owner chose (`DOKPLOY_TOKEN`, `AWS_SECRET_ACCESS_KEY`, `MY_VAULT_TOKEN`), so\n * the only safe default is to name what a program needs to *run* and pass\n * nothing else.\n */\n\n/**\n * Variables a command needs to find programs, write temp files, print in the\n * user's locale and reach the network through the host's proxy — and nothing\n * that authenticates as anyone.\n *\n * Deliberately left out:\n * - `NODE_OPTIONS`: it can `--require` or `--import` code into every node\n * process, and CI often holds `--import tsx` there. A step that needs a\n * loader passes its own.\n * - `NODE_AUTH_TOKEN`, `NPM_TOKEN`, `npm_config_*`: registry tokens\n * (`actions/setup-node` writes `NODE_AUTH_TOKEN`), which is why there is no\n * `NODE_*` wildcard.\n * - `AWS_*`, `DOCKER_*`, `DOKPLOY_*`, `GITHUB_TOKEN`, `TURBO_TOKEN`, `GKM_*`:\n * credentials, or where the deploy keeps them.\n * - `SHELL`, `EDITOR` and the rest of a login session: nothing here starts a\n * shell.\n *\n * Proxies are passed: behind one, nothing installs or builds without it. A\n * proxy URL with a password in it reaches the command too — a host that keeps\n * one there and builds code it does not trust should pass a sandbox of its\n * own.\n */\nexport const SANDBOX_ENV_ALLOWLIST: readonly (string | RegExp)[] = [\n\t// Finding programs and a home to cache in.\n\t'PATH',\n\t'HOME',\n\t'USER',\n\t'LOGNAME',\n\t'TMPDIR',\n\t'TMP',\n\t'TEMP',\n\t// Locale and terminal: output a person reads should look the same.\n\t'LANG',\n\t'LANGUAGE',\n\t'TZ',\n\t/^LC_[A-Z]+$/,\n\t'TERM',\n\t'COLORTERM',\n\t'NO_COLOR',\n\t'FORCE_COLOR',\n\t'CI',\n\t// Node: the mode a build runs in, and the CAs a corporate network adds.\n\t'NODE_ENV',\n\t'NODE_EXTRA_CA_CERTS',\n\t// Package managers' own homes, so a build reuses the host's store.\n\t'COREPACK_HOME',\n\t'PNPM_HOME',\n\t'XDG_CACHE_HOME',\n\t'XDG_DATA_HOME',\n\t// The network, through the host's proxy.\n\t'HTTP_PROXY',\n\t'HTTPS_PROXY',\n\t'NO_PROXY',\n\t'http_proxy',\n\t'https_proxy',\n\t'no_proxy',\n\t// Windows: without these, nothing starts.\n\t'SystemRoot',\n\t'SYSTEMROOT',\n\t'windir',\n\t'WINDIR',\n\t'ComSpec',\n\t'COMSPEC',\n\t'PATHEXT',\n\t'USERPROFILE',\n\t'APPDATA',\n\t'LOCALAPPDATA',\n];\n\nfunction allowed(name: string): boolean {\n\treturn SANDBOX_ENV_ALLOWLIST.some((entry) =>\n\t\ttypeof entry === 'string' ? entry === name : entry.test(name),\n\t);\n}\n\n/**\n * The allowlisted part of `source`, plus each of `extra` the host chose to\n * pass on by name.\n */\nexport function allowlistedEnv(\n\tsource: NodeJS.ProcessEnv = process.env,\n\textra: readonly string[] = [],\n): Record<string, string> {\n\tconst env: Record<string, string> = {};\n\tfor (const [name, value] of Object.entries(source)) {\n\t\tif (value === undefined) continue;\n\t\tif (allowed(name) || extra.includes(name)) env[name] = value;\n\t}\n\treturn env;\n}\n","import { type SpawnOptions, spawn } from 'node:child_process';\nimport { mkdtemp, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { CommandTimedOut } from '../run';\nimport { allowlistedEnv } from './env';\nimport {\n\tassertSecretNames,\n\tconfineCwd,\n\ttype Sandbox,\n\ttype SandboxExecOptions,\n\ttype SandboxOutput,\n\ttype SandboxResult,\n\tSECRETS_DIR_ENV,\n} from './sandbox';\n\n/** How long a timed-out command has to exit on SIGTERM before SIGKILL. */\nconst KILL_GRACE_MS = 5_000;\n\nexport interface LocalSandboxOptions {\n\t/** The project. Every command runs at or below it. */\n\troot: string;\n\t/**\n\t * `HOME` for every command. Defaults to the host's, because a build\n\t * reuses the caches kept there — the pnpm store, corepack's package\n\t * managers, turbo's cache — and a cold one re-downloads all of them.\n\t * Point it at an empty directory to keep `~/.aws`, `~/.npmrc` and\n\t * `~/.docker` out of reach of an SDK's default lookup — though, sharing\n\t * the host's filesystem, a command that goes looking still finds them.\n\t */\n\thome?: string;\n\t/**\n\t * Host variables to pass on beyond the allowlist, by name — a remote\n\t * cache's `TURBO_TOKEN`, for a build the host trusts with it.\n\t */\n\tpassEnv?: readonly string[];\n\t/** Where the allowlisted variables are read from. Defaults to `process.env`. */\n\thostEnv?: NodeJS.ProcessEnv;\n}\n\n/** Where `output` sends a child's streams. */\nconst STDIO: Record<SandboxOutput, SpawnOptions['stdio']> = {\n\tcapture: ['ignore', 'pipe', 'pipe'],\n\tinherit: 'inherit',\n\tstderr: ['ignore', 2, 2],\n\tignore: 'ignore',\n};\n\n/**\n * A child process on this machine, as this user, with an allowlisted\n * environment.\n *\n * What it withholds from the command: the host's environment beyond\n * {@link SANDBOX_ENV_ALLOWLIST}, a shell, a working directory outside the\n * project, and any time past the timeout. What it does not: the host's\n * filesystem, which the command can read and write as the user running the\n * deploy. So it is not `isolating`, and it is the default for projects the\n * host already trusts — the developer's own, a team's own CI. Code nobody\n * vetted belongs in a sandbox that is.\n *\n * A timed-out command is sent SIGTERM, then SIGKILL; processes it started\n * itself are its to stop.\n */\nexport class LocalSandbox implements Sandbox {\n\treadonly root: string;\n\treadonly isolating = false;\n\treadonly env: Readonly<Record<string, string>>;\n\n\tconstructor(options: LocalSandboxOptions) {\n\t\tthis.root = resolve(options.root);\n\t\tthis.env = {\n\t\t\t...allowlistedEnv(options.hostEnv ?? process.env, options.passEnv),\n\t\t\t...(options.home\n\t\t\t\t? { HOME: options.home, USERPROFILE: options.home }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions: SandboxExecOptions,\n\t): Promise<SandboxResult> {\n\t\tconst cwd = confineCwd(this.root, options.cwd);\n\t\tassertSecretNames(options.secrets);\n\t\toptions.signal?.throwIfAborted();\n\n\t\tconst secretsDir = await mountSecrets(options.secrets);\n\t\ttry {\n\t\t\treturn await spawnConfined(command, args, {\n\t\t\t\t...options,\n\t\t\t\tcwd,\n\t\t\t\tenv: secretsDir\n\t\t\t\t\t? { ...options.env, [SECRETS_DIR_ENV]: secretsDir }\n\t\t\t\t\t: options.env,\n\t\t\t});\n\t\t} finally {\n\t\t\tif (secretsDir) await rm(secretsDir, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/**\n * Each secret as a 0600 file in a fresh 0700 directory outside the project —\n * where nothing the build writes, packs or commits will pick it up.\n */\nasync function mountSecrets(\n\tsecrets: Readonly<Record<string, string>> | undefined,\n): Promise<string | undefined> {\n\tif (!secrets || Object.keys(secrets).length === 0) return undefined;\n\n\tconst dir = await mkdtemp(join(tmpdir(), 'gkm-secrets-'));\n\tfor (const [name, value] of Object.entries(secrets)) {\n\t\tawait writeFile(join(dir, name), value, { mode: 0o600 });\n\t}\n\treturn dir;\n}\n\nfunction spawnConfined(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: SandboxExecOptions,\n): Promise<SandboxResult> {\n\tconst { output = 'capture', signal, timeoutMs } = options;\n\n\treturn new Promise<SandboxResult>((resolvePromise, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tcwd: options.cwd,\n\t\t\t// The whole environment, as given. `spawn` reads `process.env` only\n\t\t\t// when this is left out.\n\t\t\tenv: { ...options.env },\n\t\t\tstdio: STDIO[output],\n\t\t\tshell: false,\n\t\t\t...(signal ? { signal } : {}),\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tchild.stdout?.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\t\tchild.stderr?.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tlet killer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\t// A command that ignores SIGTERM would otherwise outlive its timeout.\n\t\t\tkiller = setTimeout(() => child.kill('SIGKILL'), KILL_GRACE_MS);\n\t\t\tkiller.unref?.();\n\t\t}, timeoutMs);\n\t\ttimer.unref?.();\n\n\t\tconst settle = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tif (killer) clearTimeout(killer);\n\t\t};\n\n\t\tchild.on('error', (error) => {\n\t\t\tsettle();\n\t\t\t// Node reports an abort as its own `AbortError`; the caller asked\n\t\t\t// with a reason, and that is what it gets back.\n\t\t\treject(signal?.aborted ? signal.reason : error);\n\t\t});\n\n\t\tchild.on('close', (code: number | null, killedBy: string | null) => {\n\t\t\tsettle();\n\t\t\tif (signal?.aborted) reject(signal.reason);\n\t\t\telse if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));\n\t\t\telse\n\t\t\t\tresolvePromise({\n\t\t\t\t\texitCode: code,\n\t\t\t\t\tsignal: killedBy ?? null,\n\t\t\t\t\tstdout,\n\t\t\t\t\tstderr,\n\t\t\t\t});\n\t\t});\n\t});\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"local-Cd8ZYQG3.mjs","names":["KILL_GRACE_MS"],"sources":["../src/home.ts","../src/auth/credentials.ts","../src/run.ts","../src/sandbox/env.ts","../src/sandbox/local.ts"],"sourcesContent":["/**\n * Where the CLI keeps what belongs to a person rather than a project: stage\n * keys and stored provider credentials.\n *\n * `GKM_HOME` names it, so a CI job, a shared build runner or a test can give\n * every run its own instead of reaching into whoever's home directory the\n * process happens to have. Unset, it is `~/.gkm`, where it has always been.\n */\n\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\n/** The environment variable that moves the CLI's home. */\nexport const GKM_HOME_ENV = 'GKM_HOME';\n\n/** The CLI's home: `GKM_HOME` if set, else `~/.gkm`. */\nexport function gkmHome(env: NodeJS.ProcessEnv = process.env): string {\n\tconst configured = env[GKM_HOME_ENV];\n\treturn configured ? resolve(configured) : join(homedir(), '.gkm');\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { gkmHome } from '../home';\n\n/**\n * Stored credentials for various services\n */\nexport interface StoredCredentials {\n\tdokploy?: {\n\t\t/** API token */\n\t\ttoken: string;\n\t\t/** Dokploy endpoint URL */\n\t\tendpoint: string;\n\t\t/** Registry ID in Dokploy (for Docker image pulls) */\n\t\tregistryId?: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n\thostinger?: {\n\t\t/** API token from hpanel.hostinger.com/profile/api */\n\t\ttoken: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n}\n\n/**\n * Options for credential operations\n */\nexport interface CredentialOptions {\n\t/**\n\t * A directory whose `.gkm` holds the credentials. Default: the CLI's home\n\t * (`GKM_HOME`, else `~/.gkm`).\n\t */\n\troot?: string;\n\t/** The CLI's home itself, holding `credentials.json`. Wins over `root`. */\n\thome?: string;\n}\n\n/**\n * Get the path to the credentials directory\n */\nexport function getCredentialsDir(options?: CredentialOptions): string {\n\tif (options?.home) return options.home;\n\treturn options?.root ? join(options.root, '.gkm') : gkmHome();\n}\n\n/**\n * Get the path to the credentials file\n */\nexport function getCredentialsPath(options?: CredentialOptions): string {\n\treturn join(getCredentialsDir(options), 'credentials.json');\n}\n\n/**\n * Ensure the credentials directory exists\n */\nfunction ensureCredentialsDir(options?: CredentialOptions): void {\n\tconst dir = getCredentialsDir(options);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Read stored credentials from disk\n */\nexport async function readCredentials(\n\toptions?: CredentialOptions,\n): Promise<StoredCredentials> {\n\tconst path = getCredentialsPath(options);\n\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = await readFile(path, 'utf-8');\n\t\treturn JSON.parse(content) as StoredCredentials;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/**\n * Write credentials to disk\n */\nexport async function writeCredentials(\n\tcredentials: StoredCredentials,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tensureCredentialsDir(options);\n\tconst path = getCredentialsPath(options);\n\n\tawait writeFile(path, JSON.stringify(credentials, null, 2), {\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n/**\n * Store Dokploy credentials\n */\nexport async function storeDokployCredentials(\n\ttoken: string,\n\tendpoint: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.dokploy = {\n\t\ttoken,\n\t\tendpoint,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Dokploy credentials\n */\nexport async function getDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<{\n\ttoken: string;\n\tendpoint: string;\n\tregistryId?: string;\n} | null> {\n\tconst credentials = await readCredentials(options);\n\n\t// The environment first, and each half independently.\n\t//\n\t// `getDokployToken` has always read `DOKPLOY_API_TOKEN` while this — the\n\t// function the deploy path actually calls — read only the file. So a CI job\n\t// given the token as a secret had a token and nowhere to send it, and the\n\t// only way through was committing a credentials file or running an\n\t// interactive login on the runner.\n\t//\n\t// Read separately rather than as a pair because they arrive separately: a\n\t// token is a secret and belongs in the environment, while an endpoint is\n\t// configuration and usually belongs in `deploy.dokploy.endpoint`. Requiring\n\t// both from the same place is what made either one useless alone.\n\tconst token = process.env.DOKPLOY_API_TOKEN ?? credentials.dokploy?.token;\n\tconst endpoint =\n\t\tprocess.env.DOKPLOY_ENDPOINT ?? credentials.dokploy?.endpoint;\n\n\tif (!token || !endpoint) return null;\n\n\treturn {\n\t\ttoken,\n\t\tendpoint: endpoint.replace(/\\/$/, ''),\n\t\t...(credentials.dokploy?.registryId\n\t\t\t? { registryId: credentials.dokploy.registryId }\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Remove Dokploy credentials\n */\nexport async function removeDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.dokploy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n/**\n * Remove all stored credentials\n */\nexport async function removeAllCredentials(\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst path = getCredentialsPath(options);\n\n\tif (existsSync(path)) {\n\t\tawait unlink(path);\n\t}\n}\n\n/**\n * Get Dokploy API token, checking stored credentials first, then environment\n */\nexport async function getDokployToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.DOKPLOY_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst stored = await getDokployCredentials(options);\n\tif (stored) {\n\t\treturn stored.token;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get Dokploy endpoint from stored credentials\n */\nexport async function getDokployEndpoint(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.endpoint ?? null;\n}\n\n/**\n * Store Dokploy registry ID\n */\nexport async function storeDokployRegistryId(\n\tregistryId: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found. Run \"gkm login --service dokploy\" first.',\n\t\t);\n\t}\n\n\tcredentials.dokploy.registryId = registryId;\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get Dokploy registry ID from stored credentials\n */\nexport async function getDokployRegistryId(\n\toptions?: CredentialOptions,\n): Promise<string | undefined> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.registryId ?? undefined;\n}\n\n// ============================================\n// Hostinger credentials\n// ============================================\n\n/**\n * Store Hostinger API token\n *\n * @param token - API token from hpanel.hostinger.com/profile/api\n */\nexport async function storeHostingerToken(\n\ttoken: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.hostinger = {\n\t\ttoken,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Hostinger API token\n *\n * Checks environment variable first (HOSTINGER_API_TOKEN),\n * then falls back to stored credentials.\n */\nexport async function getHostingerToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.HOSTINGER_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst credentials = await readCredentials(options);\n\treturn credentials.hostinger?.token ?? null;\n}\n\n/**\n * Remove Hostinger credentials\n */\nexport async function removeHostingerCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.hostinger) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.hostinger;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n","/**\n * Start a program with an argument array, never a shell string.\n *\n * `gkm build`, `gkm docker` and `gkm deploy` pass values that come from the\n * workspace — image refs, tags, build args, package names — to `docker` and\n * `turbo`. Joined into a string and handed to a shell, a package named\n * `x;curl …|sh` or a tag holding `$(…)` became part of the command line, which\n * matters most where the CLI builds a repository it didn't write: a CI job for a\n * fork, a shared build runner. Here every value reaches the program as one\n * `argv` element, whatever it contains.\n */\n\nimport { type SpawnOptions, spawn } from 'node:child_process';\n\n/** Long enough for a cold image build; short enough that a hung one ends. */\nexport const DEFAULT_TIMEOUT_MS = 30 * 60_000;\n\n/** How long a timed-out child has to exit on SIGTERM before it is killed. */\nconst KILL_GRACE_MS = 5_000;\n\nexport interface RunOptions {\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tstdio?: SpawnOptions['stdio'];\n\t/** Kill the child after this long. Defaults to {@link DEFAULT_TIMEOUT_MS}. */\n\ttimeoutMs?: number;\n\t/**\n\t * Kills the child when aborted, and rejects with the signal's reason — the\n\t * same as a stopped deploy's other calls.\n\t */\n\tsignal?: AbortSignal;\n}\n\n/** The command line as a person would read it — for messages, never to run. */\nfunction display(command: string, args: readonly string[]): string {\n\treturn [command, ...args].join(' ');\n}\n\n/** The program ran and exited unsuccessfully; its own output said why. */\nexport class CommandFailed extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly exitCode: number | null,\n\t\treadonly signal: NodeJS.Signals | null,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` ${exitCode === null ? `was stopped by ${signal ?? 'a signal'}` : `exited with code ${exitCode}`}. Its output above says why; run it by hand to see it again.`,\n\t\t);\n\t\tthis.name = 'CommandFailed';\n\t}\n}\n\n/** The program ran past its timeout and was killed. */\nexport class CommandTimedOut extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly timeoutMs: number,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` was still running after ${Math.round(timeoutMs / 1000)}s and was stopped. Check what it was waiting on — a registry, the Docker daemon, a prompt — and run it again.`,\n\t\t);\n\t\tthis.name = 'CommandTimedOut';\n\t}\n}\n\n/**\n * Run `command` with `args`, resolving when it exits 0.\n *\n * Rejects with {@link CommandFailed} on any other exit, {@link CommandTimedOut}\n * once `timeoutMs` passes (after the child is gone), and with the spawn error\n * itself when the program cannot be started at all — `ENOENT` already names it.\n */\nexport async function run(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions = {},\n): Promise<void> {\n\tawait spawnChild(command, args, options, false);\n}\n\n/**\n * {@link run}, resolving with what the program wrote to stdout — for a value\n * the CLI reads back, such as the digest `docker inspect` reports. stderr still\n * reaches the terminal, so a failure explains itself the same way.\n */\nexport function runOutput(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: Omit<RunOptions, 'stdio'> = {},\n): Promise<string> {\n\treturn spawnChild(command, args, options, true);\n}\n\nfunction spawnChild(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions,\n\tcapture: boolean,\n): Promise<string> {\n\tconst { timeoutMs = DEFAULT_TIMEOUT_MS, ...spawnOptions } = options;\n\n\treturn new Promise<string>((resolve, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tstdio: 'inherit',\n\t\t\t...spawnOptions,\n\t\t\t...(capture ? { stdio: ['ignore', 'pipe', 'inherit'] } : {}),\n\t\t\tshell: false,\n\t\t});\n\n\t\tlet stdout = '';\n\t\tchild.stdout?.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tlet killer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\t// A child that ignores SIGTERM would hold the deploy open forever.\n\t\t\tkiller = setTimeout(() => child.kill('SIGKILL'), KILL_GRACE_MS);\n\t\t\tkiller.unref?.();\n\t\t}, timeoutMs);\n\t\ttimer.unref?.();\n\n\t\tconst settle = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tif (killer) clearTimeout(killer);\n\t\t};\n\n\t\tchild.on('error', (error) => {\n\t\t\tsettle();\n\t\t\t// Node reports an abort as its own `AbortError`; the caller asked\n\t\t\t// with a reason, and that is what it should get back.\n\t\t\treject(spawnOptions.signal?.aborted ? spawnOptions.signal.reason : error);\n\t\t});\n\n\t\tchild.on('close', (code: number | null, signal: NodeJS.Signals | null) => {\n\t\t\tsettle();\n\t\t\tif (spawnOptions.signal?.aborted) reject(spawnOptions.signal.reason);\n\t\t\telse if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));\n\t\t\telse if (code === 0) resolve(stdout);\n\t\t\telse reject(new CommandFailed(command, args, code, signal));\n\t\t});\n\t});\n}\n","/**\n * What of the host's environment a local sandbox passes on.\n *\n * An allowlist, not a denylist: a credential's variable has any name its\n * owner chose (`DOKPLOY_TOKEN`, `AWS_SECRET_ACCESS_KEY`, `MY_VAULT_TOKEN`), so\n * the only safe default is to name what a program needs to *run* and pass\n * nothing else.\n */\n\n/**\n * Variables a command needs to find programs, write temp files, print in the\n * user's locale and reach the network through the host's proxy — and nothing\n * that authenticates as anyone.\n *\n * Deliberately left out:\n * - `NODE_OPTIONS`: it can `--require` or `--import` code into every node\n * process, and CI often holds `--import tsx` there. A step that needs a\n * loader passes its own.\n * - `NODE_AUTH_TOKEN`, `NPM_TOKEN`, `npm_config_*`: registry tokens\n * (`actions/setup-node` writes `NODE_AUTH_TOKEN`), which is why there is no\n * `NODE_*` wildcard.\n * - `AWS_*`, `DOCKER_*`, `DOKPLOY_*`, `GITHUB_TOKEN`, `TURBO_TOKEN`, `GKM_*`:\n * credentials, or where the deploy keeps them.\n * - `SHELL`, `EDITOR` and the rest of a login session: nothing here starts a\n * shell.\n *\n * Proxies are passed: behind one, nothing installs or builds without it. A\n * proxy URL with a password in it reaches the command too — a host that keeps\n * one there and builds code it does not trust should pass a sandbox of its\n * own.\n */\nexport const SANDBOX_ENV_ALLOWLIST: readonly (string | RegExp)[] = [\n\t// Finding programs and a home to cache in.\n\t'PATH',\n\t'HOME',\n\t'USER',\n\t'LOGNAME',\n\t'TMPDIR',\n\t'TMP',\n\t'TEMP',\n\t// Locale and terminal: output a person reads should look the same.\n\t'LANG',\n\t'LANGUAGE',\n\t'TZ',\n\t/^LC_[A-Z]+$/,\n\t'TERM',\n\t'COLORTERM',\n\t'NO_COLOR',\n\t'FORCE_COLOR',\n\t'CI',\n\t// Node: the mode a build runs in, and the CAs a corporate network adds.\n\t'NODE_ENV',\n\t'NODE_EXTRA_CA_CERTS',\n\t// Package managers' own homes, so a build reuses the host's store.\n\t'COREPACK_HOME',\n\t'PNPM_HOME',\n\t'XDG_CACHE_HOME',\n\t'XDG_DATA_HOME',\n\t// The network, through the host's proxy.\n\t'HTTP_PROXY',\n\t'HTTPS_PROXY',\n\t'NO_PROXY',\n\t'http_proxy',\n\t'https_proxy',\n\t'no_proxy',\n\t// Windows: without these, nothing starts.\n\t'SystemRoot',\n\t'SYSTEMROOT',\n\t'windir',\n\t'WINDIR',\n\t'ComSpec',\n\t'COMSPEC',\n\t'PATHEXT',\n\t'USERPROFILE',\n\t'APPDATA',\n\t'LOCALAPPDATA',\n];\n\nfunction allowed(name: string): boolean {\n\treturn SANDBOX_ENV_ALLOWLIST.some((entry) =>\n\t\ttypeof entry === 'string' ? entry === name : entry.test(name),\n\t);\n}\n\n/**\n * The allowlisted part of `source`, plus each of `extra` the host chose to\n * pass on by name.\n */\nexport function allowlistedEnv(\n\tsource: NodeJS.ProcessEnv = process.env,\n\textra: readonly string[] = [],\n): Record<string, string> {\n\tconst env: Record<string, string> = {};\n\tfor (const [name, value] of Object.entries(source)) {\n\t\tif (value === undefined) continue;\n\t\tif (allowed(name) || extra.includes(name)) env[name] = value;\n\t}\n\treturn env;\n}\n","import { type SpawnOptions, spawn } from 'node:child_process';\nimport { mkdtemp, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { CommandTimedOut } from '../run';\nimport { allowlistedEnv } from './env';\nimport {\n\tassertSecretNames,\n\tconfineCwd,\n\ttype Sandbox,\n\ttype SandboxExecOptions,\n\ttype SandboxOutput,\n\ttype SandboxResult,\n\tSECRETS_DIR_ENV,\n} from './sandbox';\n\n/** How long a timed-out command has to exit on SIGTERM before SIGKILL. */\nconst KILL_GRACE_MS = 5_000;\n\nexport interface LocalSandboxOptions {\n\t/** The project. Every command runs at or below it. */\n\troot: string;\n\t/**\n\t * `HOME` for every command. Defaults to the host's, because a build\n\t * reuses the caches kept there — the pnpm store, corepack's package\n\t * managers, turbo's cache — and a cold one re-downloads all of them.\n\t * Point it at an empty directory to keep `~/.aws`, `~/.npmrc` and\n\t * `~/.docker` out of reach of an SDK's default lookup — though, sharing\n\t * the host's filesystem, a command that goes looking still finds them.\n\t */\n\thome?: string;\n\t/**\n\t * Host variables to pass on beyond the allowlist, by name — a remote\n\t * cache's `TURBO_TOKEN`, for a build the host trusts with it.\n\t */\n\tpassEnv?: readonly string[];\n\t/** Where the allowlisted variables are read from. Defaults to `process.env`. */\n\thostEnv?: NodeJS.ProcessEnv;\n}\n\n/** Where `output` sends a child's streams. */\nconst STDIO: Record<SandboxOutput, SpawnOptions['stdio']> = {\n\tcapture: ['ignore', 'pipe', 'pipe'],\n\tinherit: 'inherit',\n\tstderr: ['ignore', 2, 2],\n\tignore: 'ignore',\n};\n\n/**\n * A child process on this machine, as this user, with an allowlisted\n * environment.\n *\n * What it withholds from the command: the host's environment beyond\n * {@link SANDBOX_ENV_ALLOWLIST}, a shell, a working directory outside the\n * project, and any time past the timeout. What it does not: the host's\n * filesystem, which the command can read and write as the user running the\n * deploy. So it is not `isolating`, and it is the default for projects the\n * host already trusts — the developer's own, a team's own CI. Code nobody\n * vetted belongs in a sandbox that is.\n *\n * A timed-out command is sent SIGTERM, then SIGKILL; processes it started\n * itself are its to stop.\n */\nexport class LocalSandbox implements Sandbox {\n\treadonly root: string;\n\treadonly isolating = false;\n\treadonly env: Readonly<Record<string, string>>;\n\n\tconstructor(options: LocalSandboxOptions) {\n\t\tthis.root = resolve(options.root);\n\t\tthis.env = {\n\t\t\t...allowlistedEnv(options.hostEnv ?? process.env, options.passEnv),\n\t\t\t...(options.home\n\t\t\t\t? { HOME: options.home, USERPROFILE: options.home }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tasync exec(\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions: SandboxExecOptions,\n\t): Promise<SandboxResult> {\n\t\tconst cwd = confineCwd(this.root, options.cwd);\n\t\tassertSecretNames(options.secrets);\n\t\toptions.signal?.throwIfAborted();\n\n\t\tconst secretsDir = await mountSecrets(options.secrets);\n\t\ttry {\n\t\t\treturn await spawnConfined(command, args, {\n\t\t\t\t...options,\n\t\t\t\tcwd,\n\t\t\t\tenv: secretsDir\n\t\t\t\t\t? { ...options.env, [SECRETS_DIR_ENV]: secretsDir }\n\t\t\t\t\t: options.env,\n\t\t\t});\n\t\t} finally {\n\t\t\tif (secretsDir) await rm(secretsDir, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/**\n * Each secret as a 0600 file in a fresh 0700 directory outside the project —\n * where nothing the build writes, packs or commits will pick it up.\n */\nasync function mountSecrets(\n\tsecrets: Readonly<Record<string, string>> | undefined,\n): Promise<string | undefined> {\n\tif (!secrets || Object.keys(secrets).length === 0) return undefined;\n\n\tconst dir = await mkdtemp(join(tmpdir(), 'gkm-secrets-'));\n\tfor (const [name, value] of Object.entries(secrets)) {\n\t\tawait writeFile(join(dir, name), value, { mode: 0o600 });\n\t}\n\treturn dir;\n}\n\nfunction spawnConfined(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: SandboxExecOptions,\n): Promise<SandboxResult> {\n\tconst { output = 'capture', signal, timeoutMs } = options;\n\n\treturn new Promise<SandboxResult>((resolvePromise, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tcwd: options.cwd,\n\t\t\t// The whole environment, as given. `spawn` reads `process.env` only\n\t\t\t// when this is left out.\n\t\t\tenv: { ...options.env },\n\t\t\tstdio: STDIO[output],\n\t\t\tshell: false,\n\t\t\t...(signal ? { signal } : {}),\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tchild.stdout?.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\t\tchild.stderr?.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tlet killer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\t// A command that ignores SIGTERM would otherwise outlive its timeout.\n\t\t\tkiller = setTimeout(() => child.kill('SIGKILL'), KILL_GRACE_MS);\n\t\t\tkiller.unref?.();\n\t\t}, timeoutMs);\n\t\ttimer.unref?.();\n\n\t\tconst settle = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tif (killer) clearTimeout(killer);\n\t\t};\n\n\t\tchild.on('error', (error) => {\n\t\t\tsettle();\n\t\t\t// Node reports an abort as its own `AbortError`; the caller asked\n\t\t\t// with a reason, and that is what it gets back.\n\t\t\treject(signal?.aborted ? signal.reason : error);\n\t\t});\n\n\t\tchild.on('close', (code: number | null, killedBy: string | null) => {\n\t\t\tsettle();\n\t\t\tif (signal?.aborted) reject(signal.reason);\n\t\t\telse if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));\n\t\t\telse\n\t\t\t\tresolvePromise({\n\t\t\t\t\texitCode: code,\n\t\t\t\t\tsignal: killedBy ?? null,\n\t\t\t\t\tstdout,\n\t\t\t\t\tstderr,\n\t\t\t\t});\n\t\t});\n\t});\n}\n"],"mappings":"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"}
@@ -1,220 +0,0 @@
1
- const require_define = require("./define-zUsP72ym.cjs");
2
- const require_runtime = require("./runtime-BGNDrHzh.cjs");
3
- //#region src/target/provider.ts
4
- /**
5
- * `gkm deploy --provider`, from before there were targets.
6
- *
7
- * It named three things, and only one of them ever deployed a workspace:
8
- * `dokploy` is now the target of that name; `docker` and `aws-lambda` were
9
- * accepted and always failed, so they are gone with a pointer to what does
10
- * the job.
11
- */
12
- /** What each removed provider's job is done with now. */
13
- const REMOVED = {
14
- docker: "Build images with `gkm docker`, or run the stage as one Docker Compose stack with `gkm compose`",
15
- "aws-lambda": "Deploy to AWS with SST: set deploy: { default: 'sst' } and run `gkm deploy --stage <stage>`, which runs `sst deploy`"
16
- };
17
- /** A `--provider` that no longer exists. */
18
- var ProviderRemoved = class extends Error {
19
- provider;
20
- instead;
21
- constructor(provider, instead) {
22
- super(`--provider ${provider} has been removed. ${instead}.`);
23
- this.provider = provider;
24
- this.instead = instead;
25
- this.name = "ProviderRemoved";
26
- }
27
- };
28
- /** The deprecation `--provider` prints when it still means something. */
29
- function providerDeprecation(provider) {
30
- return `--provider is deprecated; use --target ${provider}.`;
31
- }
32
- /**
33
- * The target a `--provider` value means. `warn` hears the deprecation; a
34
- * provider that is gone, or a target not deployable yet, throws.
35
- */
36
- function targetForProvider(provider, warn) {
37
- const removed = REMOVED[provider];
38
- if (removed) throw new ProviderRemoved(provider, removed);
39
- if (provider === "vercel" || provider === "cloudflare") throw new require_define.DeployTargetNotYetSupported(provider);
40
- warn(providerDeprecation(provider));
41
- return provider;
42
- }
43
- //#endregion
44
- //#region src/target/resolve.ts
45
- /**
46
- * From a target's name to the target.
47
- *
48
- * In this order, the first that has the name wins:
49
- *
50
- * 1. the host's own targets — what a program calling `deploy()` passes
51
- * 2. the built-ins — `dokploy`, `sst`
52
- * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either
53
- * with options
54
- *
55
- * Built-ins come before the config so that a dependency cannot take over
56
- * `dokploy` by being listed under its name. A name nothing has is
57
- * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a
58
- * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody
59
- * has claimed can be claimed by anyone, and a deploy would then run their
60
- * code with the stage's credentials. A target is installed and named.
61
- */
62
- /** A target package whose default export is not a target. */
63
- var TargetPackageInvalid = class extends Error {
64
- target;
65
- packageName;
66
- constructor(target, packageName) {
67
- super(`deploy.targets.${target} names "${packageName}", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`);
68
- this.target = target;
69
- this.packageName = packageName;
70
- this.name = "TargetPackageInvalid";
71
- }
72
- };
73
- /** A `deploy.targets` entry that is not a target, a package name or a pair. */
74
- var TargetEntryInvalid = class extends Error {
75
- target;
76
- constructor(target) {
77
- super(`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`);
78
- this.target = target;
79
- this.name = "TargetEntryInvalid";
80
- }
81
- };
82
- /** A target whose `runtime` is not the one its package declares. */
83
- var TargetRuntimeMismatch = class extends Error {
84
- target;
85
- packageName;
86
- declared;
87
- actual;
88
- constructor(target, packageName, declared, actual) {
89
- super(`The deploy target "${target}" runs on "${actual}", but ${packageName}'s package.json declares gkm.runtime "${declared}". gkm dev and gkm build chose backends for "${declared}", so the two must agree — fix the package.`);
90
- this.target = target;
91
- this.packageName = packageName;
92
- this.declared = declared;
93
- this.actual = actual;
94
- this.name = "TargetRuntimeMismatch";
95
- }
96
- };
97
- /** Options a target's schema rejected. */
98
- var InvalidTargetOptions = class extends Error {
99
- target;
100
- issues;
101
- constructor(target, issues) {
102
- const lines = issues.map((issue) => {
103
- const path = (issue.path ?? []).map((segment) => typeof segment === "object" ? String(segment.key) : String(segment)).join(".");
104
- return ` - ${path ? `${path}: ` : ""}${issue.message}`;
105
- });
106
- super(`The options for deploy target "${target}" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\n${lines.join("\n")}`);
107
- this.target = target;
108
- this.issues = issues;
109
- this.name = "InvalidTargetOptions";
110
- }
111
- };
112
- /** The built-ins `gkm deploy` deploys through, loaded only when used. */
113
- const BUILTIN_LOADERS = {
114
- dokploy: async () => (await Promise.resolve().then(() => require("./dokploy-D1d37rvM.cjs"))).dokployTarget,
115
- sst: async () => (await Promise.resolve().then(() => require("./sst-BdALKEas.cjs")).then((n) => n.sst_exports)).sstTarget
116
- };
117
- /** The target `name` means, in this workspace, for this host. */
118
- async function resolveTarget(name, { workspace, host, stage }) {
119
- if (host && Object.hasOwn(host, name)) return {
120
- name,
121
- target: host[name],
122
- source: "host",
123
- options: void 0
124
- };
125
- const builtin = require_define.builtinTarget(name);
126
- if (builtin) {
127
- const load = BUILTIN_LOADERS[name];
128
- if (builtin.status !== "available" || !load) throw new require_define.DeployTargetNotYetSupported(name, builtin.instead?.(stage));
129
- return {
130
- name,
131
- target: await load(),
132
- source: "builtin",
133
- options: void 0
134
- };
135
- }
136
- const entry = require_define.configuredTarget(workspace.deploy, name);
137
- if (entry === void 0) throw new require_define.UnknownDeployTarget(name, [...require_define.configurableBuiltins(), ...Object.keys(workspace.deploy?.targets ?? {})]);
138
- const [implementation, options] = Array.isArray(entry) ? entry : [entry, void 0];
139
- if (typeof implementation === "string") {
140
- const declared = require_runtime.declaredRuntime(name, implementation, workspace.root);
141
- const target = (await require_runtime.importPackage(name, implementation, workspace.root)).default;
142
- if (!require_define.isDeployTarget(target)) throw new TargetPackageInvalid(name, implementation);
143
- if (target.runtime !== declared) throw new TargetRuntimeMismatch(name, implementation, declared, target.runtime);
144
- return {
145
- name,
146
- target,
147
- source: "config",
148
- options
149
- };
150
- }
151
- if (!require_define.isDeployTarget(implementation)) throw new TargetEntryInvalid(name);
152
- return {
153
- name,
154
- target: implementation,
155
- source: "config",
156
- options
157
- };
158
- }
159
- /** The target's options, parsed by its schema. */
160
- async function parseTargetOptions(resolved) {
161
- const { name, target, options } = resolved;
162
- if (!target.options) {
163
- if (options !== void 0) throw new InvalidTargetOptions(name, [{ message: "this target takes no options" }]);
164
- return;
165
- }
166
- const result = await target.options["~standard"].validate(options);
167
- if (result.issues) throw new InvalidTargetOptions(name, result.issues);
168
- return result.value;
169
- }
170
- //#endregion
171
- Object.defineProperty(exports, "InvalidTargetOptions", {
172
- enumerable: true,
173
- get: function() {
174
- return InvalidTargetOptions;
175
- }
176
- });
177
- Object.defineProperty(exports, "ProviderRemoved", {
178
- enumerable: true,
179
- get: function() {
180
- return ProviderRemoved;
181
- }
182
- });
183
- Object.defineProperty(exports, "TargetEntryInvalid", {
184
- enumerable: true,
185
- get: function() {
186
- return TargetEntryInvalid;
187
- }
188
- });
189
- Object.defineProperty(exports, "TargetPackageInvalid", {
190
- enumerable: true,
191
- get: function() {
192
- return TargetPackageInvalid;
193
- }
194
- });
195
- Object.defineProperty(exports, "TargetRuntimeMismatch", {
196
- enumerable: true,
197
- get: function() {
198
- return TargetRuntimeMismatch;
199
- }
200
- });
201
- Object.defineProperty(exports, "parseTargetOptions", {
202
- enumerable: true,
203
- get: function() {
204
- return parseTargetOptions;
205
- }
206
- });
207
- Object.defineProperty(exports, "resolveTarget", {
208
- enumerable: true,
209
- get: function() {
210
- return resolveTarget;
211
- }
212
- });
213
- Object.defineProperty(exports, "targetForProvider", {
214
- enumerable: true,
215
- get: function() {
216
- return targetForProvider;
217
- }
218
- });
219
-
220
- //# sourceMappingURL=resolve-BXsNQjMR.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolve-BXsNQjMR.cjs","names":["DeployTargetNotYetSupported","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","declaredRuntime","importPackage","isDeployTarget"],"sources":["../src/target/provider.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * `gkm deploy --provider`, from before there were targets.\n *\n * It named three things, and only one of them ever deployed a workspace:\n * `dokploy` is now the target of that name; `docker` and `aws-lambda` were\n * accepted and always failed, so they are gone with a pointer to what does\n * the job.\n */\n\nimport { DeployTargetNotYetSupported } from './builtins';\n\n/** What each removed provider's job is done with now. */\nconst REMOVED: Record<string, string> = {\n\tdocker:\n\t\t'Build images with `gkm docker`, or run the stage as one Docker Compose stack with `gkm compose`',\n\t'aws-lambda':\n\t\t\"Deploy to AWS with SST: set deploy: { default: 'sst' } and run `gkm deploy --stage <stage>`, which runs `sst deploy`\",\n};\n\n/** A `--provider` that no longer exists. */\nexport class ProviderRemoved extends Error {\n\tconstructor(\n\t\treadonly provider: string,\n\t\t/** What to use instead. */\n\t\treadonly instead: string,\n\t) {\n\t\tsuper(`--provider ${provider} has been removed. ${instead}.`);\n\t\tthis.name = 'ProviderRemoved';\n\t}\n}\n\n/** The deprecation `--provider` prints when it still means something. */\nexport function providerDeprecation(provider: string): string {\n\treturn `--provider is deprecated; use --target ${provider}.`;\n}\n\n/**\n * The target a `--provider` value means. `warn` hears the deprecation; a\n * provider that is gone, or a target not deployable yet, throws.\n */\nexport function targetForProvider(\n\tprovider: string,\n\twarn: (message: string) => void,\n): string {\n\tconst removed = REMOVED[provider];\n\tif (removed) throw new ProviderRemoved(provider, removed);\n\tif (provider === 'vercel' || provider === 'cloudflare') {\n\t\tthrow new DeployTargetNotYetSupported(provider);\n\t}\n\twarn(providerDeprecation(provider));\n\treturn provider;\n}\n","/**\n * From a target's name to the target.\n *\n * In this order, the first that has the name wins:\n *\n * 1. the host's own targets — what a program calling `deploy()` passes\n * 2. the built-ins — `dokploy`, `sst`\n * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either\n * with options\n *\n * Built-ins come before the config so that a dependency cannot take over\n * `dokploy` by being listed under its name. A name nothing has is\n * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a\n * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody\n * has claimed can be claimed by anyone, and a deploy would then run their\n * code with the stage's credentials. A target is installed and named.\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tDeployTargetNotYetSupported,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { isDeployTarget } from './define';\nimport { importPackage } from './package';\nimport { declaredRuntime } from './runtime';\nimport type {\n\tAnyDeployTarget,\n\tDeployRuntime,\n\tDeployTargetEntry,\n\tTargetOptionsIssue,\n} from './types';\n\n/** Where a target came from. */\nexport type TargetSourceKind = 'host' | 'builtin' | 'config';\n\nexport interface ResolvedTarget {\n\t/** The name it was asked for by. */\n\tname: string;\n\ttarget: AnyDeployTarget;\n\tsource: TargetSourceKind;\n\t/** Its options as written in the config, before its schema parsed them. */\n\toptions: unknown;\n}\n\nexport interface ResolveTargetOptions {\n\t/** The workspace whose `deploy.targets` is consulted. */\n\tworkspace: {\n\t\troot: string;\n\t\tdeploy?: { targets?: Record<string, DeployTargetEntry> } | undefined;\n\t};\n\t/** The host's targets, consulted first. */\n\thost?: Record<string, AnyDeployTarget>;\n\t/** The stage being deployed, for what to do instead of a refused target. */\n\tstage: string;\n}\n\n/** A target package whose default export is not a target. */\nexport class TargetPackageInvalid extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names \"${packageName}\", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`,\n\t\t);\n\t\tthis.name = 'TargetPackageInvalid';\n\t}\n}\n\n/** A `deploy.targets` entry that is not a target, a package name or a pair. */\nexport class TargetEntryInvalid extends Error {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`,\n\t\t);\n\t\tthis.name = 'TargetEntryInvalid';\n\t}\n}\n\n/** A target whose `runtime` is not the one its package declares. */\nexport class TargetRuntimeMismatch extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly declared: DeployRuntime,\n\t\treadonly actual: DeployRuntime,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" runs on \"${actual}\", but ${packageName}'s package.json declares gkm.runtime \"${declared}\". gkm dev and gkm build chose backends for \"${declared}\", so the two must agree — fix the package.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeMismatch';\n\t}\n}\n\n/** Options a target's schema rejected. */\nexport class InvalidTargetOptions extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly issues: readonly TargetOptionsIssue[],\n\t) {\n\t\tconst lines = issues.map((issue) => {\n\t\t\tconst path = (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.');\n\t\t\treturn ` - ${path ? `${path}: ` : ''}${issue.message}`;\n\t\t});\n\t\tsuper(\n\t\t\t`The options for deploy target \"${target}\" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\\n${lines.join('\\n')}`,\n\t\t);\n\t\tthis.name = 'InvalidTargetOptions';\n\t}\n}\n\n/** The built-ins `gkm deploy` deploys through, loaded only when used. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<AnyDeployTarget>> = {\n\tdokploy: async () => (await import('./dokploy')).dokployTarget,\n\tsst: async () => (await import('./sst/index')).sstTarget,\n};\n\n/** The target `name` means, in this workspace, for this host. */\nexport async function resolveTarget(\n\tname: string,\n\t{ workspace, host, stage }: ResolveTargetOptions,\n): Promise<ResolvedTarget> {\n\tif (host && Object.hasOwn(host, name)) {\n\t\treturn { name, target: host[name]!, source: 'host', options: undefined };\n\t}\n\n\tconst builtin = builtinTarget(name);\n\tif (builtin) {\n\t\tconst load = BUILTIN_LOADERS[name];\n\t\tif (builtin.status !== 'available' || !load) {\n\t\t\tthrow new DeployTargetNotYetSupported(name, builtin.instead?.(stage));\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\ttarget: await load(),\n\t\t\tsource: 'builtin',\n\t\t\toptions: undefined,\n\t\t};\n\t}\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst [implementation, options] = Array.isArray(entry)\n\t\t? (entry as readonly [unknown, unknown])\n\t\t: [entry, undefined];\n\n\tif (typeof implementation === 'string') {\n\t\t// Before the import: a package that does not say where it runs is\n\t\t// refused without running any of its code.\n\t\tconst declared = declaredRuntime(name, implementation, workspace.root);\n\t\tconst loaded = await importPackage(name, implementation, workspace.root);\n\t\tconst target = loaded.default;\n\t\tif (!isDeployTarget(target)) {\n\t\t\tthrow new TargetPackageInvalid(name, implementation);\n\t\t}\n\t\tif (target.runtime !== declared) {\n\t\t\tthrow new TargetRuntimeMismatch(\n\t\t\t\tname,\n\t\t\t\timplementation,\n\t\t\t\tdeclared,\n\t\t\t\ttarget.runtime,\n\t\t\t);\n\t\t}\n\t\treturn { name, target, source: 'config', options };\n\t}\n\n\tif (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);\n\treturn { name, target: implementation, source: 'config', options };\n}\n\n/** The target's options, parsed by its schema. */\nexport async function parseTargetOptions(\n\tresolved: ResolvedTarget,\n): Promise<unknown> {\n\tconst { name, target, options } = resolved;\n\tif (!target.options) {\n\t\tif (options !== undefined) {\n\t\t\tthrow new InvalidTargetOptions(name, [\n\t\t\t\t{ message: 'this target takes no options' },\n\t\t\t]);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst result = await target.options['~standard'].validate(options);\n\tif (result.issues) throw new InvalidTargetOptions(name, result.issues);\n\treturn result.value;\n}\n"],"mappings":"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"}
@@ -1,173 +0,0 @@
1
- import { a as UnknownDeployTarget, c as configuredTarget, i as DeployTargetNotYetSupported, n as isDeployTarget, o as builtinTarget, s as configurableBuiltins } from "./define-CYs0PEfZ.mjs";
2
- import { a as importPackage, n as declaredRuntime } from "./runtime-Cmn-FeYO.mjs";
3
- //#region src/target/provider.ts
4
- /**
5
- * `gkm deploy --provider`, from before there were targets.
6
- *
7
- * It named three things, and only one of them ever deployed a workspace:
8
- * `dokploy` is now the target of that name; `docker` and `aws-lambda` were
9
- * accepted and always failed, so they are gone with a pointer to what does
10
- * the job.
11
- */
12
- /** What each removed provider's job is done with now. */
13
- const REMOVED = {
14
- docker: "Build images with `gkm docker`, or run the stage as one Docker Compose stack with `gkm compose`",
15
- "aws-lambda": "Deploy to AWS with SST: set deploy: { default: 'sst' } and run `gkm deploy --stage <stage>`, which runs `sst deploy`"
16
- };
17
- /** A `--provider` that no longer exists. */
18
- var ProviderRemoved = class extends Error {
19
- provider;
20
- instead;
21
- constructor(provider, instead) {
22
- super(`--provider ${provider} has been removed. ${instead}.`);
23
- this.provider = provider;
24
- this.instead = instead;
25
- this.name = "ProviderRemoved";
26
- }
27
- };
28
- /** The deprecation `--provider` prints when it still means something. */
29
- function providerDeprecation(provider) {
30
- return `--provider is deprecated; use --target ${provider}.`;
31
- }
32
- /**
33
- * The target a `--provider` value means. `warn` hears the deprecation; a
34
- * provider that is gone, or a target not deployable yet, throws.
35
- */
36
- function targetForProvider(provider, warn) {
37
- const removed = REMOVED[provider];
38
- if (removed) throw new ProviderRemoved(provider, removed);
39
- if (provider === "vercel" || provider === "cloudflare") throw new DeployTargetNotYetSupported(provider);
40
- warn(providerDeprecation(provider));
41
- return provider;
42
- }
43
- //#endregion
44
- //#region src/target/resolve.ts
45
- /**
46
- * From a target's name to the target.
47
- *
48
- * In this order, the first that has the name wins:
49
- *
50
- * 1. the host's own targets — what a program calling `deploy()` passes
51
- * 2. the built-ins — `dokploy`, `sst`
52
- * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either
53
- * with options
54
- *
55
- * Built-ins come before the config so that a dependency cannot take over
56
- * `dokploy` by being listed under its name. A name nothing has is
57
- * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a
58
- * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody
59
- * has claimed can be claimed by anyone, and a deploy would then run their
60
- * code with the stage's credentials. A target is installed and named.
61
- */
62
- /** A target package whose default export is not a target. */
63
- var TargetPackageInvalid = class extends Error {
64
- target;
65
- packageName;
66
- constructor(target, packageName) {
67
- super(`deploy.targets.${target} names "${packageName}", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`);
68
- this.target = target;
69
- this.packageName = packageName;
70
- this.name = "TargetPackageInvalid";
71
- }
72
- };
73
- /** A `deploy.targets` entry that is not a target, a package name or a pair. */
74
- var TargetEntryInvalid = class extends Error {
75
- target;
76
- constructor(target) {
77
- super(`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`);
78
- this.target = target;
79
- this.name = "TargetEntryInvalid";
80
- }
81
- };
82
- /** A target whose `runtime` is not the one its package declares. */
83
- var TargetRuntimeMismatch = class extends Error {
84
- target;
85
- packageName;
86
- declared;
87
- actual;
88
- constructor(target, packageName, declared, actual) {
89
- super(`The deploy target "${target}" runs on "${actual}", but ${packageName}'s package.json declares gkm.runtime "${declared}". gkm dev and gkm build chose backends for "${declared}", so the two must agree — fix the package.`);
90
- this.target = target;
91
- this.packageName = packageName;
92
- this.declared = declared;
93
- this.actual = actual;
94
- this.name = "TargetRuntimeMismatch";
95
- }
96
- };
97
- /** Options a target's schema rejected. */
98
- var InvalidTargetOptions = class extends Error {
99
- target;
100
- issues;
101
- constructor(target, issues) {
102
- const lines = issues.map((issue) => {
103
- const path = (issue.path ?? []).map((segment) => typeof segment === "object" ? String(segment.key) : String(segment)).join(".");
104
- return ` - ${path ? `${path}: ` : ""}${issue.message}`;
105
- });
106
- super(`The options for deploy target "${target}" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\n${lines.join("\n")}`);
107
- this.target = target;
108
- this.issues = issues;
109
- this.name = "InvalidTargetOptions";
110
- }
111
- };
112
- /** The built-ins `gkm deploy` deploys through, loaded only when used. */
113
- const BUILTIN_LOADERS = {
114
- dokploy: async () => (await import("./dokploy-CepdXuMl.mjs")).dokployTarget,
115
- sst: async () => (await import("./sst-Cper040I.mjs").then((n) => n.n)).sstTarget
116
- };
117
- /** The target `name` means, in this workspace, for this host. */
118
- async function resolveTarget(name, { workspace, host, stage }) {
119
- if (host && Object.hasOwn(host, name)) return {
120
- name,
121
- target: host[name],
122
- source: "host",
123
- options: void 0
124
- };
125
- const builtin = builtinTarget(name);
126
- if (builtin) {
127
- const load = BUILTIN_LOADERS[name];
128
- if (builtin.status !== "available" || !load) throw new DeployTargetNotYetSupported(name, builtin.instead?.(stage));
129
- return {
130
- name,
131
- target: await load(),
132
- source: "builtin",
133
- options: void 0
134
- };
135
- }
136
- const entry = configuredTarget(workspace.deploy, name);
137
- if (entry === void 0) throw new UnknownDeployTarget(name, [...configurableBuiltins(), ...Object.keys(workspace.deploy?.targets ?? {})]);
138
- const [implementation, options] = Array.isArray(entry) ? entry : [entry, void 0];
139
- if (typeof implementation === "string") {
140
- const declared = declaredRuntime(name, implementation, workspace.root);
141
- const target = (await importPackage(name, implementation, workspace.root)).default;
142
- if (!isDeployTarget(target)) throw new TargetPackageInvalid(name, implementation);
143
- if (target.runtime !== declared) throw new TargetRuntimeMismatch(name, implementation, declared, target.runtime);
144
- return {
145
- name,
146
- target,
147
- source: "config",
148
- options
149
- };
150
- }
151
- if (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);
152
- return {
153
- name,
154
- target: implementation,
155
- source: "config",
156
- options
157
- };
158
- }
159
- /** The target's options, parsed by its schema. */
160
- async function parseTargetOptions(resolved) {
161
- const { name, target, options } = resolved;
162
- if (!target.options) {
163
- if (options !== void 0) throw new InvalidTargetOptions(name, [{ message: "this target takes no options" }]);
164
- return;
165
- }
166
- const result = await target.options["~standard"].validate(options);
167
- if (result.issues) throw new InvalidTargetOptions(name, result.issues);
168
- return result.value;
169
- }
170
- //#endregion
171
- export { parseTargetOptions as a, targetForProvider as c, TargetRuntimeMismatch as i, TargetEntryInvalid as n, resolveTarget as o, TargetPackageInvalid as r, ProviderRemoved as s, InvalidTargetOptions as t };
172
-
173
- //# sourceMappingURL=resolve-DZ2IJ0qY.mjs.map