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

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 (161) hide show
  1. package/dist/{LegacyStateStore-D_78eaHM.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
  2. package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
  3. package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
  4. package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
  5. package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
  6. package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
  7. package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
  8. package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
  9. package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
  10. package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
  11. package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
  12. package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
  13. package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
  14. package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
  15. package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
  16. package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
  17. package/dist/{add-BTH7WaH3.mjs → add-B7IMXzou.mjs} +3 -3
  18. package/dist/{add-BTH7WaH3.mjs.map → add-B7IMXzou.mjs.map} +1 -1
  19. package/dist/{add-Djrr12Xc.cjs → add-j2yI3cbS.cjs} +3 -3
  20. package/dist/{add-Djrr12Xc.cjs.map → add-j2yI3cbS.cjs.map} +1 -1
  21. package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
  22. package/dist/aws-Bja4zGSs.mjs.map +1 -0
  23. package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
  24. package/dist/aws-CQAuluiu.cjs.map +1 -0
  25. package/dist/awsStore-7VmS_cZR.cjs +54 -0
  26. package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
  27. package/dist/awsStore-B529csle.mjs +43 -0
  28. package/dist/awsStore-B529csle.mjs.map +1 -0
  29. package/dist/{bundler-utHuESvL.cjs → bundler-Cf6OgaOe.cjs} +5 -5
  30. package/dist/bundler-Cf6OgaOe.cjs.map +1 -0
  31. package/dist/{bundler-BUojOkof.mjs → bundler-DO6bHhnb.mjs} +5 -5
  32. package/dist/bundler-DO6bHhnb.mjs.map +1 -0
  33. package/dist/{cli-CyYceKTS.mjs → cli-BCPOHmg9.mjs} +3 -3
  34. package/dist/{cli-CyYceKTS.mjs.map → cli-BCPOHmg9.mjs.map} +1 -1
  35. package/dist/{cli-Bx0sUzxH.cjs → cli-CNanUB7a.cjs} +3 -3
  36. package/dist/{cli-Bx0sUzxH.cjs.map → cli-CNanUB7a.cjs.map} +1 -1
  37. package/dist/{compose-DZp8DJ0A.mjs → compose-Dq4VCtu5.mjs} +221 -153
  38. package/dist/compose-Dq4VCtu5.mjs.map +1 -0
  39. package/dist/{compose-iuw8wfHk.cjs → compose-h_6oNnHC.cjs} +243 -151
  40. package/dist/compose-h_6oNnHC.cjs.map +1 -0
  41. package/dist/{config-B38YWicj.d.cts → config-CWyhLSY1.d.cts} +3 -3
  42. package/dist/{config-B38YWicj.d.cts.map → config-CWyhLSY1.d.cts.map} +1 -1
  43. package/dist/{config-DA0kRTQe.d.mts → config-CqAvPP-f.d.mts} +3 -3
  44. package/dist/{config-DA0kRTQe.d.mts.map → config-CqAvPP-f.d.mts.map} +1 -1
  45. package/dist/config.cjs +1 -1
  46. package/dist/config.d.cts +3 -3
  47. package/dist/config.d.mts +3 -3
  48. package/dist/config.mjs +1 -1
  49. package/dist/deploy/public.cjs +7 -6
  50. package/dist/deploy/public.d.cts +14 -3
  51. package/dist/deploy/public.d.cts.map +1 -1
  52. package/dist/deploy/public.d.mts +14 -3
  53. package/dist/deploy/public.d.mts.map +1 -1
  54. package/dist/deploy/public.mjs +7 -7
  55. package/dist/{deploy-eWorhvQp.cjs → deploy-CT3R9de9.cjs} +27 -5
  56. package/dist/deploy-CT3R9de9.cjs.map +1 -0
  57. package/dist/{deploy-C17K7Imy.mjs → deploy-CVXEx7Nm.mjs} +22 -6
  58. package/dist/deploy-CVXEx7Nm.mjs.map +1 -0
  59. package/dist/{dokploy-DKa49Nqm.mjs → dokploy-CYm2ozFs.mjs} +2 -2
  60. package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-CYm2ozFs.mjs.map} +1 -1
  61. package/dist/{dokploy-DKzcI-RL.cjs → dokploy-eSGmlhhj.cjs} +2 -2
  62. package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-eSGmlhhj.cjs.map} +1 -1
  63. package/dist/{encryption-sTMz3aWi.mjs → encryption-DC0rsR1W.mjs} +3 -3
  64. package/dist/{encryption-sTMz3aWi.mjs.map → encryption-DC0rsR1W.mjs.map} +1 -1
  65. package/dist/{encryption-DSkJdoyk.cjs → encryption-vS3Qzw73.cjs} +3 -3
  66. package/dist/{encryption-DSkJdoyk.cjs.map → encryption-vS3Qzw73.cjs.map} +1 -1
  67. package/dist/{engine-B1b4I34Z.mjs → engine-BOO5TWZd.mjs} +193 -5
  68. package/dist/engine-BOO5TWZd.mjs.map +1 -0
  69. package/dist/{engine-Bh76sAHy.cjs → engine-C0N2d1i5.cjs} +196 -8
  70. package/dist/engine-C0N2d1i5.cjs.map +1 -0
  71. package/dist/{github-C9ODoyZU.mjs → github-CEaFDL6t.mjs} +6 -6
  72. package/dist/github-CEaFDL6t.mjs.map +1 -0
  73. package/dist/{github-BvN3CfxM.cjs → github-ClkdCOL9.cjs} +6 -6
  74. package/dist/github-ClkdCOL9.cjs.map +1 -0
  75. package/dist/{index-B-1lLGzy.d.mts → index-Ccu0f_2m.d.cts} +2 -2
  76. package/dist/{index-B-1lLGzy.d.mts.map → index-Ccu0f_2m.d.cts.map} +1 -1
  77. package/dist/{index-vMidfqhU.d.cts → index-DOxmDKqv.d.mts} +2 -2
  78. package/dist/{index-vMidfqhU.d.cts.map → index-DOxmDKqv.d.mts.map} +1 -1
  79. package/dist/index.cjs +106 -52
  80. package/dist/index.cjs.map +1 -1
  81. package/dist/index.mjs +105 -51
  82. package/dist/index.mjs.map +1 -1
  83. package/dist/migrate-BRbYtFXG.cjs +93 -0
  84. package/dist/migrate-BRbYtFXG.cjs.map +1 -0
  85. package/dist/migrate-D3NAT7Ns.mjs +93 -0
  86. package/dist/migrate-D3NAT7Ns.mjs.map +1 -0
  87. package/dist/{migrate-B0FCZNkp.cjs → migrate-D5_-ylI1.cjs} +3 -3
  88. package/dist/{migrate-B0FCZNkp.cjs.map → migrate-D5_-ylI1.cjs.map} +1 -1
  89. package/dist/{migrate-CTtJhGV9.mjs → migrate-DrO2p9Rl.mjs} +3 -3
  90. package/dist/{migrate-CTtJhGV9.mjs.map → migrate-DrO2p9Rl.mjs.map} +1 -1
  91. package/dist/openapi.cjs +16 -6
  92. package/dist/openapi.cjs.map +1 -1
  93. package/dist/openapi.d.cts +1 -1
  94. package/dist/openapi.d.cts.map +1 -1
  95. package/dist/openapi.d.mts +1 -1
  96. package/dist/openapi.d.mts.map +1 -1
  97. package/dist/openapi.mjs +16 -6
  98. package/dist/openapi.mjs.map +1 -1
  99. package/dist/reconcile/public.d.cts +1 -1
  100. package/dist/reconcile/public.d.mts +1 -1
  101. package/dist/{resolve-DSAXj_47.mjs → resolve-C1muFos5.mjs} +3 -3
  102. package/dist/{resolve-DSAXj_47.mjs.map → resolve-C1muFos5.mjs.map} +1 -1
  103. package/dist/{resolve-D_BU-wKA.cjs → resolve-Fa1Ii0BK.cjs} +3 -3
  104. package/dist/{resolve-D_BU-wKA.cjs.map → resolve-Fa1Ii0BK.cjs.map} +1 -1
  105. package/dist/{rollback-DJy3t696.cjs → rollback-C9N5lKVf.cjs} +5 -5
  106. package/dist/{rollback-DJy3t696.cjs.map → rollback-C9N5lKVf.cjs.map} +1 -1
  107. package/dist/{rollback-CWYTUhfW.mjs → rollback-DeQzbRqM.mjs} +5 -5
  108. package/dist/{rollback-CWYTUhfW.mjs.map → rollback-DeQzbRqM.mjs.map} +1 -1
  109. package/dist/{runtime-BzZD5HHi.d.cts → runtime-BSvzPqXW.d.mts} +2 -2
  110. package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-BSvzPqXW.d.mts.map} +1 -1
  111. package/dist/{runtime-Cm6J6L7n.d.mts → runtime-Cm7QA53H.d.cts} +2 -2
  112. package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-Cm7QA53H.d.cts.map} +1 -1
  113. package/dist/secretsManager-DUXW3fQt.cjs +70 -0
  114. package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
  115. package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
  116. package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
  117. package/dist/{sniffer-BFmdZpZ2.mjs → sniffer-DR8AlRCk.mjs} +67 -15
  118. package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
  119. package/dist/{sniffer-C-T7dSMN.cjs → sniffer-Y6GQOCXB.cjs} +83 -13
  120. package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
  121. package/dist/{state-DCwRWyh-.cjs → state-C2qi0iQw.cjs} +241 -334
  122. package/dist/state-C2qi0iQw.cjs.map +1 -0
  123. package/dist/{state-DpkxSwzI.mjs → state-CUecOCNJ.mjs} +213 -306
  124. package/dist/state-CUecOCNJ.mjs.map +1 -0
  125. package/dist/target/public.cjs +1 -1
  126. package/dist/target/public.d.cts +2 -2
  127. package/dist/target/public.d.mts +2 -2
  128. package/dist/target/public.mjs +1 -1
  129. package/dist/{types-TzCChNrA.d.cts → types-BdptGBFS.d.cts} +59 -6
  130. package/dist/types-BdptGBFS.d.cts.map +1 -0
  131. package/dist/{types-Dp9lgx_S.d.mts → types-OxE0OAn2.d.mts} +59 -6
  132. package/dist/types-OxE0OAn2.d.mts.map +1 -0
  133. package/dist/workspace/index.cjs +1 -1
  134. package/dist/workspace/index.d.cts +2 -2
  135. package/dist/workspace/index.d.mts +2 -2
  136. package/dist/workspace/index.mjs +1 -1
  137. package/dist/{workspace-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
  138. package/dist/workspace-DOm81oUo.cjs.map +1 -0
  139. package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
  140. package/dist/workspace-QUTqYmVy.mjs.map +1 -0
  141. package/package.json +18 -17
  142. package/dist/aws-DkHdTV-p.cjs.map +0 -1
  143. package/dist/aws-DojzQnLd.mjs.map +0 -1
  144. package/dist/bundler-BUojOkof.mjs.map +0 -1
  145. package/dist/bundler-utHuESvL.cjs.map +0 -1
  146. package/dist/compose-DZp8DJ0A.mjs.map +0 -1
  147. package/dist/compose-iuw8wfHk.cjs.map +0 -1
  148. package/dist/deploy-C17K7Imy.mjs.map +0 -1
  149. package/dist/deploy-eWorhvQp.cjs.map +0 -1
  150. package/dist/engine-B1b4I34Z.mjs.map +0 -1
  151. package/dist/engine-Bh76sAHy.cjs.map +0 -1
  152. package/dist/github-BvN3CfxM.cjs.map +0 -1
  153. package/dist/github-C9ODoyZU.mjs.map +0 -1
  154. package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
  155. package/dist/sniffer-C-T7dSMN.cjs.map +0 -1
  156. package/dist/state-DCwRWyh-.cjs.map +0 -1
  157. package/dist/state-DpkxSwzI.mjs.map +0 -1
  158. package/dist/types-Dp9lgx_S.d.mts.map +0 -1
  159. package/dist/types-TzCChNrA.d.cts.map +0 -1
  160. package/dist/workspace-C7NqCsQF.mjs.map +0 -1
  161. package/dist/workspace-vdrcRI-m.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as Routes, i as OpenApiConfig } from "./types-Dp9lgx_S.mjs";
1
+ import { a as Routes, i as OpenApiConfig } from "./types-OxE0OAn2.mjs";
2
2
  import { Endpoint } from "@geekmidas/constructs/endpoints";
3
3
  //#region src/openapi.d.ts
4
4
  interface OpenAPIOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.mts","names":[],"sources":["../src/openapi.ts"],"mappings":";;;UAeU;EACT;;;;;;;EAOA;;;;;;;;;;wBAWe,eAAe;;;;wBAOf,qBAAqB;EACpC,oBAAoB;IACjB;EAAkB;;;iBA0BL;;EAEhB;;EAEA;;EAEA;;;;;;;;;wBAUqB,oBACrB,QAAQ,QACR;EACC,oBAAoB;EACpB;EACA;EACA;IAEC,QAAQ;;;;;;;;;;;;wBAwBW,gBACrB,oBAAoB,qCACpB;EACC,oBAAoB;EACpB;;;;;;;EAOA;IAEC,QAAQ;wBAoEW,eACrB,UAAS,iBACP"}
1
+ {"version":3,"file":"openapi.d.mts","names":[],"sources":["../src/openapi.ts"],"mappings":";;;UAmBU;EACT;;;;;;;EAOA;;;;;;;;;;wBAWe,eAAe;;;;wBAOf,qBAAqB;EACpC,oBAAoB;IACjB;EAAkB;;;iBA0BL;;EAEhB;;EAEA;;EAEA;;;;;;;;;wBAUqB,oBACrB,QAAQ,QACR;EACC,oBAAoB;EACpB;EACA;EACA;IAEC,QAAQ;;;;;;;;;;;;wBAwBW,gBACrB,oBAAoB,qCACpB;EACC,oBAAoB;EACpB;;;;;;;EAOA;IAEC,QAAQ;wBAoEW,eACrB,UAAS,iBACP"}
package/dist/openapi.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env -S npx tsx
2
+ import { t as appKey } from "./derive-B4vDpzgP.mjs";
3
+ import { r as appConstructGlobs } from "./workspace-QUTqYmVy.mjs";
2
4
  import { loadWorkspaceConfig } from "./config.mjs";
3
5
  import { t as EndpointGenerator } from "./EndpointGenerator-DftalLYg.mjs";
4
6
  import { t as OpenApiTsGenerator } from "./OpenApiTsGenerator-nu1r1NgB.mjs";
@@ -124,14 +126,14 @@ async function openapiCommand(options = {}) {
124
126
  const entry = backendApps.find(([name]) => name === options.app);
125
127
  if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
126
128
  const [appName, app] = entry;
127
- const result = await generateOpenApiForApp(workspaceRoot, appName, app);
129
+ const result = await generateOpenApiForApp(workspace, appName, app);
128
130
  if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
129
131
  return;
130
132
  }
131
133
  for (const [appName, app] of backendApps) {
132
134
  const appPath = join(workspaceRoot, app.path);
133
135
  if (resolve(appPath) === resolve(workspaceRoot)) {
134
- const result = await generateOpenApiForApp(workspaceRoot, appName, app, false);
136
+ const result = await generateOpenApiForApp(workspace, appName, app, false);
135
137
  if (result) logger.log(`Found ${result.endpointCount} endpoints`);
136
138
  continue;
137
139
  }
@@ -146,14 +148,22 @@ async function openapiCommand(options = {}) {
146
148
  * Generate OpenAPI for a single named app within a workspace.
147
149
  * Runs in-process. The caller is responsible for ensuring `process.cwd()`
148
150
  * is the app's directory so tsx loads the app's tsconfig path aliases.
151
+ *
152
+ * The endpoints are found the way the app's build finds them — through the
153
+ * workspace's constructs globs — never by importing every `.ts` under the app,
154
+ * which loaded its tests and gkm's own generated files with them.
149
155
  */
150
- async function generateOpenApiForApp(workspaceRoot, _appName, app, silent = true) {
156
+ async function generateOpenApiForApp(workspace, appName, app, silent = true) {
151
157
  if (app.type !== "backend") return null;
152
- const appPath = join(workspaceRoot, app.path);
153
- return generateOpenApiFrom([join(appPath, "**/*.ts")], {
158
+ return generateOpenApi((await new EndpointGenerator().load(appConstructGlobs(workspace, appName))).map(({ construct }) => construct).filter((endpoint) => {
159
+ const owner = endpoint.owner ?? endpoint.surface?.id;
160
+ if (!owner) return false;
161
+ const key = appKey(owner);
162
+ return key === appName || !workspace.apps[key];
163
+ }), {
154
164
  openapi: app.openapi ?? { enabled: true },
155
165
  silent,
156
- root: workspaceRoot
166
+ root: workspace.root
157
167
  });
158
168
  }
159
169
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.mjs","names":["relative","relativePath"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { spawn } from 'node:child_process';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative as relativePath, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Endpoint } from '@geekmidas/constructs/endpoints';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { loadWorkspaceConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig, Routes } from './types.js';\nimport { normalizeRoutes } from './workspace/client-generator.js';\nimport type { NormalizedAppConfig } from './workspace/types.js';\n\ninterface OpenAPIOptions {\n\tcwd?: string;\n\t/**\n\t * Workspace mode: generate for a single named backend app. When set,\n\t * generation runs in-process against the current CWD. When unset,\n\t * workspace mode spawns one subprocess per backend app so each gets a\n\t * fresh tsx that loads the app's own tsconfig (path aliases included).\n\t */\n\tapp?: string;\n}\n\n/**\n * Where a surface's generated client lands, under the workspace root.\n *\n * Named from the surface, so `new RestApi('Webhooks')` writes\n * `.gkm/client/webhooks.ts` — the same kebab form that gives it its container\n * name and its `WEBHOOKS_URL` — and a site imports it as\n * `@<name>/client/webhooks`, through the alias its tsconfig maps.\n */\nexport function openApiPathFor(surfaceId: string): string {\n\treturn `./.gkm/client/${kebabCase(surfaceId)}.ts`;\n}\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(config: {\n\topenapi?: boolean | OpenApiConfig;\n}): OpenApiConfig & { enabled: boolean } {\n\tif (config.openapi === false) {\n\t\treturn { enabled: false };\n\t}\n\n\tif (config.openapi === true || config.openapi === undefined) {\n\t\t// Enable by default when not explicitly set (undefined) or explicitly true\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\ttitle: 'API Documentation',\n\t\t\tversion: '1.0.0',\n\t\t\tdescription: 'Auto-generated API documentation from endpoints',\n\t\t};\n\t}\n\n\treturn {\n\t\tenabled: config.openapi.enabled !== false,\n\t\ttitle: config.openapi.title || 'API Documentation',\n\t\tversion: config.openapi.version || '1.0.0',\n\t\tdescription:\n\t\t\tconfig.openapi.description ||\n\t\t\t'Auto-generated API documentation from endpoints',\n\t};\n}\n\n/** What a generation run wrote. */\nexport interface OpenApiResult {\n\t/** The first spec written — kept so existing callers still compile. */\n\toutputPath: string;\n\t/** Every spec written, one per surface. */\n\toutputPaths: string[];\n\t/** Endpoints across all of them. */\n\tendpointCount: number;\n}\n\n/**\n * Load endpoints from a glob, then generate.\n *\n * For the callers that have no endpoints in hand — `gkm openapi`, and `gkm dev`\n * regenerating on reload. The glob is the app's derived one — the conventional\n * directories under it — not a `routes` field anybody wrote.\n */\nexport async function generateOpenApiFrom(\n\troutes: Routes,\n\toptions: {\n\t\topenapi?: boolean | OpenApiConfig;\n\t\tsilent?: boolean;\n\t\tbustCache?: boolean;\n\t\troot?: string;\n\t} = {},\n): Promise<OpenApiResult | null> {\n\tconst loaded = await new EndpointGenerator().load(\n\t\troutes,\n\t\tundefined,\n\t\toptions.bustCache,\n\t);\n\n\treturn generateOpenApi(\n\t\tloaded.map(({ construct }) => construct),\n\t\toptions,\n\t);\n}\n\n/**\n * Generate an OpenAPI spec for each surface these endpoints name.\n *\n * Takes the endpoints, not a glob to find them with. The build has already\n * loaded every one of them to generate handlers, so globbing again was a second\n * discovery pass over the same files — and the reason this function needed a\n * `routes` to be told where to look, which is how a retired config field stayed\n * load-bearing.\n *\n * @returns What was written, or null if disabled or there were none\n */\nexport async function generateOpenApi(\n\tendpoints: readonly Endpoint<any, any, any, any, any>[],\n\toptions: {\n\t\topenapi?: boolean | OpenApiConfig;\n\t\tsilent?: boolean;\n\t\t/**\n\t\t * The workspace root, whose `.gkm/client/` holds every surface's client.\n\t\t * The client is the application's, like its manifest — a site reaches it\n\t\t * as `@<name>/client/<surface>` — so it is written there whichever\n\t\t * directory the build happened to run in.\n\t\t */\n\t\troot?: string;\n\t} = {},\n): Promise<OpenApiResult | null> {\n\tconst root = options.root ?? process.cwd();\n\tconst logger = options.silent ? { log: () => {} } : console;\n\tconst openApiConfig = resolveOpenApiConfig({ openapi: options.openapi });\n\n\tif (!openApiConfig.enabled) {\n\t\treturn null;\n\t}\n\n\tif (endpoints.length === 0) {\n\t\tlogger.log('No valid endpoints found for OpenAPI generation');\n\t\treturn null;\n\t}\n\n\t// One spec per surface, not one per glob.\n\t//\n\t// The glob is a directory, and a directory is not a surface: two `RestApi`s\n\t// whose endpoints live side by side produced a single spec describing both,\n\t// under a filename that named neither. Every endpoint carries the surface\n\t// that serves it, so that is what the spec is cut along — `Api` becomes\n\t// `api.ts`, `Webhooks` becomes `webhooks.ts`, by the same kebab rule that\n\t// gives the surface its container name and its environment keys.\n\tconst bySurface = new Map<string, Endpoint<any, any, any, any, any>[]>();\n\tfor (const endpoint of endpoints) {\n\t\tconst owner = endpoint.owner ?? endpoint.surface?.id;\n\t\tif (!owner) continue;\n\t\tconst existing = bySurface.get(owner);\n\t\tif (existing) existing.push(endpoint);\n\t\telse bySurface.set(owner, [endpoint]);\n\t}\n\n\tif (bySurface.size === 0) {\n\t\tlogger.log('No endpoints named a surface, so no OpenAPI was generated');\n\t\treturn null;\n\t}\n\n\tconst tsGenerator = new OpenApiTsGenerator();\n\tconst written: string[] = [];\n\n\tfor (const [surfaceId, surfaceEndpoints] of bySurface) {\n\t\tconst relative = openApiPathFor(surfaceId);\n\t\tconst outputPath = join(root, relative);\n\n\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\n\t\tconst tsContent = await tsGenerator.generate(surfaceEndpoints, {\n\t\t\t// The surface's own name, so a spec says which API it describes\n\t\t\t// rather than repeating one title across all of them.\n\t\t\ttitle: openApiConfig.title ?? surfaceId,\n\t\t\tversion: openApiConfig.version!,\n\t\t\tdescription: openApiConfig.description!,\n\t\t});\n\n\t\tawait writeFile(outputPath, tsContent);\n\t\twritten.push(relative);\n\t\tlogger.log(\n\t\t\t`📄 OpenAPI client generated: ${relativePath(process.cwd(), outputPath)} (${surfaceEndpoints.length} endpoints)`,\n\t\t);\n\t}\n\n\treturn {\n\t\t// The first, for a caller that wants one path. `outputPaths` has them all.\n\t\toutputPath: join(root, written[0]!),\n\t\toutputPaths: written.map((r) => join(root, r)),\n\t\tendpointCount: endpoints.length,\n\t};\n}\n\nexport async function openapiCommand(\n\toptions: OpenAPIOptions = {},\n): Promise<void> {\n\tconst logger = console;\n\n\ttry {\n\t\tconst loadedConfig = await loadWorkspaceConfig(options.cwd);\n\n\t\tif (loadedConfig.type === 'single') {\n\t\t\t// Single-app config - use existing behavior\n\t\t\tconst config = loadedConfig.raw as GkmConfig;\n\n\t\t\t// Enable openapi if not configured\n\t\t\tif (!config.openapi) {\n\t\t\t\tconfig.openapi = { enabled: true };\n\t\t\t}\n\n\t\t\tconst result = await generateOpenApiFrom(config.constructs, {\n\t\t\t\topenapi: config.openapi,\n\t\t\t\troot: loadedConfig.workspace.root,\n\t\t\t});\n\n\t\t\tif (result) {\n\t\t\t\tlogger.log(`Found ${result.endpointCount} endpoints`);\n\t\t\t}\n\t\t} else {\n\t\t\t// Workspace config - generate for each backend app\n\t\t\tconst { workspace } = loadedConfig;\n\t\t\t// Always derive the workspace root from the loaded config rather than\n\t\t\t// CWD. Subprocesses run with CWD set to an app directory, and falling\n\t\t\t// back to CWD there causes `join(workspaceRoot, app.path)` to point at\n\t\t\t// a non-existent nested path (e.g. `apps/api/apps/api`).\n\t\t\tconst workspaceRoot = workspace.root;\n\n\t\t\t// Backend apps with openapi enabled — which is all of them that have\n\t\t\t// routes, unless one says otherwise.\n\t\t\t//\n\t\t\t// This used to require `openapi: true` written out, while the app's\n\t\t\t// own build generated a spec regardless. Two paths disagreeing about\n\t\t\t// the same flag: the app emitted `.gkm/openapi.ts` and this pass,\n\t\t\t// finding nothing \"enabled\", skipped copying it to the frontends that\n\t\t\t// consume it. A surface whose routes are declared rather than\n\t\t\t// discovered has no spec to generate, so it is not a candidate.\n\t\t\tconst backendApps = Object.entries(workspace.apps).filter(\n\t\t\t\t([_, app]) =>\n\t\t\t\t\tapp.type === 'backend' &&\n\t\t\t\t\tapp.openapi !== false &&\n\t\t\t\t\t(typeof app.openapi !== 'object' || app.openapi.enabled !== false),\n\t\t\t);\n\n\t\t\tif (backendApps.length === 0) {\n\t\t\t\tlogger.log('No backend apps with OpenAPI enabled found');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Single-app mode: generate in-process. The caller is expected to\n\t\t\t// have CWD set to the app's directory (e.g., when invoked as a\n\t\t\t// subprocess), so tsx picks up the app's tsconfig path aliases.\n\t\t\tif (options.app) {\n\t\t\t\tconst entry = backendApps.find(([name]) => name === options.app);\n\t\t\t\tif (!entry) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`App \"${options.app}\" not found or has OpenAPI disabled`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst [appName, app] = entry;\n\t\t\t\tconst result = await generateOpenApiForApp(workspaceRoot, appName, app);\n\t\t\t\tif (result) {\n\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Multi-app mode: spawn a subprocess per backend app. Each\n\t\t\t// subprocess starts with CWD at the app's directory so that\n\t\t\t// tsx's tsconfig discovery picks up the app's `paths` aliases\n\t\t\t// (e.g., `~/*`) instead of the workspace root's tsconfig.\n\t\t\tfor (const [appName, app] of backendApps) {\n\t\t\t\t// No `app.routes` check any more: the per-kind globs are gone, and\n\t\t\t\t// an app's code is found by one glob rather than by a field naming\n\t\t\t\t// endpoints. Guarding on `routes` here meant every app was skipped\n\t\t\t\t// the moment that field stopped existing — silently, because a loop\n\t\t\t\t// that runs zero times looks exactly like one with nothing to do.\n\t\t\t\tconst appPath = join(workspaceRoot, app.path);\n\n\t\t\t\t// A subprocess exists to put CWD inside the app, so tsx picks up\n\t\t\t\t// that app's tsconfig aliases instead of the workspace root's. When\n\t\t\t\t// the app *is* the root there is nothing to change: spawning would\n\t\t\t\t// re-enter the same directory, having paid for a process and a\n\t\t\t\t// module graph, and needing `tsx` resolvable from it.\n\t\t\t\tif (resolve(appPath) === resolve(workspaceRoot)) {\n\t\t\t\t\t// Not silent: silence is for a subprocess whose output the\n\t\t\t\t\t// parent relays, and there is no parent here to relay it. The\n\t\t\t\t\t// per-surface lines come from the generator; the count is this\n\t\t\t\t\t// command's own summary, as in the single-app path.\n\t\t\t\t\tconst result = await generateOpenApiForApp(\n\t\t\t\t\t\tworkspaceRoot,\n\t\t\t\t\t\tappName,\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tlogger.log(`Found ${result.endpointCount} endpoints`);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait runOpenApiInSubprocess(appPath, appName);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Generate OpenAPI for a single named app within a workspace.\n * Runs in-process. The caller is responsible for ensuring `process.cwd()`\n * is the app's directory so tsx loads the app's tsconfig path aliases.\n */\nasync function generateOpenApiForApp(\n\tworkspaceRoot: string,\n\t_appName: string,\n\tapp: NormalizedAppConfig,\n\t/**\n\t * Quiet by default, because the usual caller is a subprocess whose output\n\t * the parent relays. Generating in-process there is no parent to relay to,\n\t * and silence would swallow the only report of what happened.\n\t */\n\tsilent = true,\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n\t// A backend app, and everything under it.\n\t//\n\t// It used to gate on `app.routes` and glob that; derive no longer sets it,\n\t// because an app has one glob and which kind a module exports is decided by\n\t// the value. A surface is an app, so an app's own directory contains exactly\n\t// its own surface's endpoints — and the split inside is by surface anyway.\n\tif (app.type !== 'backend') {\n\t\treturn null;\n\t}\n\n\tconst appPath = join(workspaceRoot, app.path);\n\tconst globs = [join(appPath, '**/*.ts')];\n\n\treturn generateOpenApiFrom(globs, {\n\t\t// Absent means enabled, which is what the caller's filter already decided\n\t\t// when it kept this app: it skips one that says `openapi: false` and keeps\n\t\t// every other. Passing `undefined` through let `resolveOpenApiConfig`\n\t\t// default it to *disabled*, so an app selected for generation generated\n\t\t// nothing and said nothing — two places disagreeing about one flag, which\n\t\t// is the failure the filter above was written to describe.\n\t\topenapi: app.openapi ?? { enabled: true },\n\t\tsilent,\n\t\troot: workspaceRoot,\n\t});\n}\n\n/**\n * Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var\n * to avoid depending on the built dist.\n */\nfunction resolveGkmBinPath(): string {\n\tif (process.env.GKM_BIN_PATH) {\n\t\treturn process.env.GKM_BIN_PATH;\n\t}\n\treturn fileURLToPath(new URL('../bin/gkm.mjs', import.meta.url));\n}\n\n/**\n * Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to\n * the app's directory. Inherits `NODE_OPTIONS` (which already contains\n * `--import tsx`), so the child gets a fresh tsx instance whose tsconfig\n * discovery picks up the app's tsconfig path aliases.\n */\nasync function runOpenApiInSubprocess(\n\tappCwd: string,\n\tappName: string,\n): Promise<void> {\n\tconst binPath = resolveGkmBinPath();\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\n\t\t\tprocess.execPath,\n\t\t\t[binPath, 'openapi', '--app', appName],\n\t\t\t{\n\t\t\t\tcwd: appCwd,\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: process.env,\n\t\t\t},\n\t\t);\n\n\t\tchild.on('error', reject);\n\t\tchild.on('close', (code) => {\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`OpenAPI generation for app \"${appName}\" exited with code ${code}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"openapi.mjs","names":["relative","relativePath"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { spawn } from 'node:child_process';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative as relativePath, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Endpoint } from '@geekmidas/constructs/endpoints';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { loadWorkspaceConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig, Routes } from './types.js';\nimport { appKey } from './workspace/derive.js';\nimport { appConstructGlobs } from './workspace/index.js';\nimport type {\n\tNormalizedAppConfig,\n\tNormalizedWorkspace,\n} from './workspace/types.js';\n\ninterface OpenAPIOptions {\n\tcwd?: string;\n\t/**\n\t * Workspace mode: generate for a single named backend app. When set,\n\t * generation runs in-process against the current CWD. When unset,\n\t * workspace mode spawns one subprocess per backend app so each gets a\n\t * fresh tsx that loads the app's own tsconfig (path aliases included).\n\t */\n\tapp?: string;\n}\n\n/**\n * Where a surface's generated client lands, under the workspace root.\n *\n * Named from the surface, so `new RestApi('Webhooks')` writes\n * `.gkm/client/webhooks.ts` — the same kebab form that gives it its container\n * name and its `WEBHOOKS_URL` — and a site imports it as\n * `@<name>/client/webhooks`, through the alias its tsconfig maps.\n */\nexport function openApiPathFor(surfaceId: string): string {\n\treturn `./.gkm/client/${kebabCase(surfaceId)}.ts`;\n}\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(config: {\n\topenapi?: boolean | OpenApiConfig;\n}): OpenApiConfig & { enabled: boolean } {\n\tif (config.openapi === false) {\n\t\treturn { enabled: false };\n\t}\n\n\tif (config.openapi === true || config.openapi === undefined) {\n\t\t// Enable by default when not explicitly set (undefined) or explicitly true\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\ttitle: 'API Documentation',\n\t\t\tversion: '1.0.0',\n\t\t\tdescription: 'Auto-generated API documentation from endpoints',\n\t\t};\n\t}\n\n\treturn {\n\t\tenabled: config.openapi.enabled !== false,\n\t\ttitle: config.openapi.title || 'API Documentation',\n\t\tversion: config.openapi.version || '1.0.0',\n\t\tdescription:\n\t\t\tconfig.openapi.description ||\n\t\t\t'Auto-generated API documentation from endpoints',\n\t};\n}\n\n/** What a generation run wrote. */\nexport interface OpenApiResult {\n\t/** The first spec written — kept so existing callers still compile. */\n\toutputPath: string;\n\t/** Every spec written, one per surface. */\n\toutputPaths: string[];\n\t/** Endpoints across all of them. */\n\tendpointCount: number;\n}\n\n/**\n * Load endpoints from a glob, then generate.\n *\n * For the callers that have no endpoints in hand — `gkm openapi`, and `gkm dev`\n * regenerating on reload. The glob is the app's derived one — the conventional\n * directories under it — not a `routes` field anybody wrote.\n */\nexport async function generateOpenApiFrom(\n\troutes: Routes,\n\toptions: {\n\t\topenapi?: boolean | OpenApiConfig;\n\t\tsilent?: boolean;\n\t\tbustCache?: boolean;\n\t\troot?: string;\n\t} = {},\n): Promise<OpenApiResult | null> {\n\tconst loaded = await new EndpointGenerator().load(\n\t\troutes,\n\t\tundefined,\n\t\toptions.bustCache,\n\t);\n\n\treturn generateOpenApi(\n\t\tloaded.map(({ construct }) => construct),\n\t\toptions,\n\t);\n}\n\n/**\n * Generate an OpenAPI spec for each surface these endpoints name.\n *\n * Takes the endpoints, not a glob to find them with. The build has already\n * loaded every one of them to generate handlers, so globbing again was a second\n * discovery pass over the same files — and the reason this function needed a\n * `routes` to be told where to look, which is how a retired config field stayed\n * load-bearing.\n *\n * @returns What was written, or null if disabled or there were none\n */\nexport async function generateOpenApi(\n\tendpoints: readonly Endpoint<any, any, any, any, any>[],\n\toptions: {\n\t\topenapi?: boolean | OpenApiConfig;\n\t\tsilent?: boolean;\n\t\t/**\n\t\t * The workspace root, whose `.gkm/client/` holds every surface's client.\n\t\t * The client is the application's, like its manifest — a site reaches it\n\t\t * as `@<name>/client/<surface>` — so it is written there whichever\n\t\t * directory the build happened to run in.\n\t\t */\n\t\troot?: string;\n\t} = {},\n): Promise<OpenApiResult | null> {\n\tconst root = options.root ?? process.cwd();\n\tconst logger = options.silent ? { log: () => {} } : console;\n\tconst openApiConfig = resolveOpenApiConfig({ openapi: options.openapi });\n\n\tif (!openApiConfig.enabled) {\n\t\treturn null;\n\t}\n\n\tif (endpoints.length === 0) {\n\t\tlogger.log('No valid endpoints found for OpenAPI generation');\n\t\treturn null;\n\t}\n\n\t// One spec per surface, not one per glob.\n\t//\n\t// The glob is a directory, and a directory is not a surface: two `RestApi`s\n\t// whose endpoints live side by side produced a single spec describing both,\n\t// under a filename that named neither. Every endpoint carries the surface\n\t// that serves it, so that is what the spec is cut along — `Api` becomes\n\t// `api.ts`, `Webhooks` becomes `webhooks.ts`, by the same kebab rule that\n\t// gives the surface its container name and its environment keys.\n\tconst bySurface = new Map<string, Endpoint<any, any, any, any, any>[]>();\n\tfor (const endpoint of endpoints) {\n\t\tconst owner = endpoint.owner ?? endpoint.surface?.id;\n\t\tif (!owner) continue;\n\t\tconst existing = bySurface.get(owner);\n\t\tif (existing) existing.push(endpoint);\n\t\telse bySurface.set(owner, [endpoint]);\n\t}\n\n\tif (bySurface.size === 0) {\n\t\tlogger.log('No endpoints named a surface, so no OpenAPI was generated');\n\t\treturn null;\n\t}\n\n\tconst tsGenerator = new OpenApiTsGenerator();\n\tconst written: string[] = [];\n\n\tfor (const [surfaceId, surfaceEndpoints] of bySurface) {\n\t\tconst relative = openApiPathFor(surfaceId);\n\t\tconst outputPath = join(root, relative);\n\n\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\n\t\tconst tsContent = await tsGenerator.generate(surfaceEndpoints, {\n\t\t\t// The surface's own name, so a spec says which API it describes\n\t\t\t// rather than repeating one title across all of them.\n\t\t\ttitle: openApiConfig.title ?? surfaceId,\n\t\t\tversion: openApiConfig.version!,\n\t\t\tdescription: openApiConfig.description!,\n\t\t});\n\n\t\tawait writeFile(outputPath, tsContent);\n\t\twritten.push(relative);\n\t\tlogger.log(\n\t\t\t`📄 OpenAPI client generated: ${relativePath(process.cwd(), outputPath)} (${surfaceEndpoints.length} endpoints)`,\n\t\t);\n\t}\n\n\treturn {\n\t\t// The first, for a caller that wants one path. `outputPaths` has them all.\n\t\toutputPath: join(root, written[0]!),\n\t\toutputPaths: written.map((r) => join(root, r)),\n\t\tendpointCount: endpoints.length,\n\t};\n}\n\nexport async function openapiCommand(\n\toptions: OpenAPIOptions = {},\n): Promise<void> {\n\tconst logger = console;\n\n\ttry {\n\t\tconst loadedConfig = await loadWorkspaceConfig(options.cwd);\n\n\t\tif (loadedConfig.type === 'single') {\n\t\t\t// Single-app config - use existing behavior\n\t\t\tconst config = loadedConfig.raw as GkmConfig;\n\n\t\t\t// Enable openapi if not configured\n\t\t\tif (!config.openapi) {\n\t\t\t\tconfig.openapi = { enabled: true };\n\t\t\t}\n\n\t\t\tconst result = await generateOpenApiFrom(config.constructs, {\n\t\t\t\topenapi: config.openapi,\n\t\t\t\troot: loadedConfig.workspace.root,\n\t\t\t});\n\n\t\t\tif (result) {\n\t\t\t\tlogger.log(`Found ${result.endpointCount} endpoints`);\n\t\t\t}\n\t\t} else {\n\t\t\t// Workspace config - generate for each backend app\n\t\t\tconst { workspace } = loadedConfig;\n\t\t\t// Always derive the workspace root from the loaded config rather than\n\t\t\t// CWD. Subprocesses run with CWD set to an app directory, and falling\n\t\t\t// back to CWD there causes `join(workspaceRoot, app.path)` to point at\n\t\t\t// a non-existent nested path (e.g. `apps/api/apps/api`).\n\t\t\tconst workspaceRoot = workspace.root;\n\n\t\t\t// Backend apps with openapi enabled — which is all of them that have\n\t\t\t// routes, unless one says otherwise.\n\t\t\t//\n\t\t\t// This used to require `openapi: true` written out, while the app's\n\t\t\t// own build generated a spec regardless. Two paths disagreeing about\n\t\t\t// the same flag: the app emitted `.gkm/openapi.ts` and this pass,\n\t\t\t// finding nothing \"enabled\", skipped copying it to the frontends that\n\t\t\t// consume it. A surface whose routes are declared rather than\n\t\t\t// discovered has no spec to generate, so it is not a candidate.\n\t\t\tconst backendApps = Object.entries(workspace.apps).filter(\n\t\t\t\t([_, app]) =>\n\t\t\t\t\tapp.type === 'backend' &&\n\t\t\t\t\tapp.openapi !== false &&\n\t\t\t\t\t(typeof app.openapi !== 'object' || app.openapi.enabled !== false),\n\t\t\t);\n\n\t\t\tif (backendApps.length === 0) {\n\t\t\t\tlogger.log('No backend apps with OpenAPI enabled found');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Single-app mode: generate in-process. The caller is expected to\n\t\t\t// have CWD set to the app's directory (e.g., when invoked as a\n\t\t\t// subprocess), so tsx picks up the app's tsconfig path aliases.\n\t\t\tif (options.app) {\n\t\t\t\tconst entry = backendApps.find(([name]) => name === options.app);\n\t\t\t\tif (!entry) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`App \"${options.app}\" not found or has OpenAPI disabled`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst [appName, app] = entry;\n\t\t\t\tconst result = await generateOpenApiForApp(workspace, appName, app);\n\t\t\t\tif (result) {\n\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Multi-app mode: spawn a subprocess per backend app. Each\n\t\t\t// subprocess starts with CWD at the app's directory so that\n\t\t\t// tsx's tsconfig discovery picks up the app's `paths` aliases\n\t\t\t// (e.g., `~/*`) instead of the workspace root's tsconfig.\n\t\t\tfor (const [appName, app] of backendApps) {\n\t\t\t\t// No `app.routes` check any more: the per-kind globs are gone, and\n\t\t\t\t// an app's code is found by one glob rather than by a field naming\n\t\t\t\t// endpoints. Guarding on `routes` here meant every app was skipped\n\t\t\t\t// the moment that field stopped existing — silently, because a loop\n\t\t\t\t// that runs zero times looks exactly like one with nothing to do.\n\t\t\t\tconst appPath = join(workspaceRoot, app.path);\n\n\t\t\t\t// A subprocess exists to put CWD inside the app, so tsx picks up\n\t\t\t\t// that app's tsconfig aliases instead of the workspace root's. When\n\t\t\t\t// the app *is* the root there is nothing to change: spawning would\n\t\t\t\t// re-enter the same directory, having paid for a process and a\n\t\t\t\t// module graph, and needing `tsx` resolvable from it.\n\t\t\t\tif (resolve(appPath) === resolve(workspaceRoot)) {\n\t\t\t\t\t// Not silent: silence is for a subprocess whose output the\n\t\t\t\t\t// parent relays, and there is no parent here to relay it. The\n\t\t\t\t\t// per-surface lines come from the generator; the count is this\n\t\t\t\t\t// command's own summary, as in the single-app path.\n\t\t\t\t\tconst result = await generateOpenApiForApp(\n\t\t\t\t\t\tworkspace,\n\t\t\t\t\t\tappName,\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tlogger.log(`Found ${result.endpointCount} endpoints`);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait runOpenApiInSubprocess(appPath, appName);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Generate OpenAPI for a single named app within a workspace.\n * Runs in-process. The caller is responsible for ensuring `process.cwd()`\n * is the app's directory so tsx loads the app's tsconfig path aliases.\n *\n * The endpoints are found the way the app's build finds them — through the\n * workspace's constructs globs — never by importing every `.ts` under the app,\n * which loaded its tests and gkm's own generated files with them.\n */\nasync function generateOpenApiForApp(\n\tworkspace: NormalizedWorkspace,\n\tappName: string,\n\tapp: NormalizedAppConfig,\n\t/**\n\t * Quiet by default, because the usual caller is a subprocess whose output\n\t * the parent relays. Generating in-process there is no parent to relay to,\n\t * and silence would swallow the only report of what happened.\n\t */\n\tsilent = true,\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n\tif (app.type !== 'backend') {\n\t\treturn null;\n\t}\n\n\tconst loaded = await new EndpointGenerator().load(\n\t\tappConstructGlobs(workspace, appName),\n\t);\n\n\t// The workspace's globs reach every app's code, so each app writes its own\n\t// surfaces' clients and no other's. An endpoint whose surface is no app of\n\t// this workspace's has nowhere else to go, and stays.\n\tconst endpoints = loaded\n\t\t.map(({ construct }) => construct)\n\t\t.filter((endpoint) => {\n\t\t\tconst owner = endpoint.owner ?? endpoint.surface?.id;\n\t\t\tif (!owner) return false;\n\t\t\tconst key = appKey(owner);\n\t\t\treturn key === appName || !workspace.apps[key];\n\t\t});\n\n\treturn generateOpenApi(endpoints, {\n\t\t// Absent means enabled, which is what the caller's filter already decided\n\t\t// when it kept this app: it skips one that says `openapi: false` and keeps\n\t\t// every other. Passing `undefined` through let `resolveOpenApiConfig`\n\t\t// default it to *disabled*, so an app selected for generation generated\n\t\t// nothing and said nothing — two places disagreeing about one flag, which\n\t\t// is the failure the filter above was written to describe.\n\t\topenapi: app.openapi ?? { enabled: true },\n\t\tsilent,\n\t\troot: workspace.root,\n\t});\n}\n\n/**\n * Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var\n * to avoid depending on the built dist.\n */\nfunction resolveGkmBinPath(): string {\n\tif (process.env.GKM_BIN_PATH) {\n\t\treturn process.env.GKM_BIN_PATH;\n\t}\n\treturn fileURLToPath(new URL('../bin/gkm.mjs', import.meta.url));\n}\n\n/**\n * Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to\n * the app's directory. Inherits `NODE_OPTIONS` (which already contains\n * `--import tsx`), so the child gets a fresh tsx instance whose tsconfig\n * discovery picks up the app's tsconfig path aliases.\n */\nasync function runOpenApiInSubprocess(\n\tappCwd: string,\n\tappName: string,\n): Promise<void> {\n\tconst binPath = resolveGkmBinPath();\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\n\t\t\tprocess.execPath,\n\t\t\t[binPath, 'openapi', '--app', appName],\n\t\t\t{\n\t\t\t\tcwd: appCwd,\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: process.env,\n\t\t\t},\n\t\t);\n\n\t\tchild.on('error', reject);\n\t\tchild.on('close', (code) => {\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`OpenAPI generation for app \"${appName}\" exited with code ${code}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t});\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { n as EmailBackend, t as CacheBackend } from "../types-TzCChNrA.cjs";
1
+ import { n as EmailBackend, t as CacheBackend } from "../types-BdptGBFS.cjs";
2
2
  import { a as isDeclarable, i as discover, r as DiscoverOptions } from "../discover-CU0paUyH.cjs";
3
3
  import { ConstructManifest, RouteInfo } from "@geekmidas/manifest";
4
4
  //#region src/reconcile/emit.d.ts
@@ -1,4 +1,4 @@
1
- import { n as EmailBackend, t as CacheBackend } from "../types-Dp9lgx_S.mjs";
1
+ import { n as EmailBackend, t as CacheBackend } from "../types-OxE0OAn2.mjs";
2
2
  import { a as isDeclarable, i as discover, r as DiscoverOptions } from "../discover-DFiJxwfv.mjs";
3
3
  import { ConstructManifest, RouteInfo } from "@geekmidas/manifest";
4
4
  //#region src/reconcile/emit.d.ts
@@ -199,8 +199,8 @@ var InvalidTargetOptions = class extends Error {
199
199
  };
200
200
  /** The built-ins `gkm deploy` deploys through, loaded only when used. */
201
201
  const BUILTIN_LOADERS = {
202
- dokploy: async () => (await import("./dokploy-DKa49Nqm.mjs")).dokployTarget,
203
- compose: async () => (await import("./compose-DZp8DJ0A.mjs").then((n) => n.n)).composeTarget(),
202
+ dokploy: async () => (await import("./dokploy-CYm2ozFs.mjs")).dokployTarget,
203
+ compose: async () => (await import("./compose-Dq4VCtu5.mjs").then((n) => n.n)).composeTarget(),
204
204
  sst: async () => (await import("./sst-DRi3H5TB.mjs").then((n) => n.n)).sstTarget
205
205
  };
206
206
  /** The target `name` means, in this workspace, for this host. */
@@ -259,4 +259,4 @@ async function parseTargetOptions(resolved) {
259
259
  //#endregion
260
260
  export { parseTargetOptions as a, runtimeOf as c, TargetRuntimeMismatch as i, TargetPackageNotFound as l, TargetEntryInvalid as n, resolveTarget as o, TargetPackageInvalid as r, TargetRuntimeUndeclared as s, InvalidTargetOptions as t };
261
261
 
262
- //# sourceMappingURL=resolve-DSAXj_47.mjs.map
262
+ //# sourceMappingURL=resolve-C1muFos5.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-DSAXj_47.mjs","names":[],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\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 = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\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`, `compose`, `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\tcompose: async () => (await import('./compose/index')).composeTarget(),\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
+ {"version":3,"file":"resolve-C1muFos5.mjs","names":[],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\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 = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\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`, `compose`, `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\tcompose: async () => (await import('./compose/index')).composeTarget(),\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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"}
@@ -199,8 +199,8 @@ var InvalidTargetOptions = class extends Error {
199
199
  };
200
200
  /** The built-ins `gkm deploy` deploys through, loaded only when used. */
201
201
  const BUILTIN_LOADERS = {
202
- dokploy: async () => (await Promise.resolve().then(() => require("./dokploy-DKzcI-RL.cjs"))).dokployTarget,
203
- compose: async () => (await Promise.resolve().then(() => require("./compose-iuw8wfHk.cjs")).then((n) => n.compose_exports)).composeTarget(),
202
+ dokploy: async () => (await Promise.resolve().then(() => require("./dokploy-eSGmlhhj.cjs"))).dokployTarget,
203
+ compose: async () => (await Promise.resolve().then(() => require("./compose-h_6oNnHC.cjs")).then((n) => n.compose_exports)).composeTarget(),
204
204
  sst: async () => (await Promise.resolve().then(() => require("./sst-hBrKouBy.cjs")).then((n) => n.sst_exports)).sstTarget
205
205
  };
206
206
  /** The target `name` means, in this workspace, for this host. */
@@ -312,4 +312,4 @@ Object.defineProperty(exports, "runtimeOf", {
312
312
  }
313
313
  });
314
314
 
315
- //# sourceMappingURL=resolve-D_BU-wKA.cjs.map
315
+ //# sourceMappingURL=resolve-Fa1Ii0BK.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-D_BU-wKA.cjs","names":["join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\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 = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\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`, `compose`, `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\tcompose: async () => (await import('./compose/index')).composeTarget(),\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
+ {"version":3,"file":"resolve-Fa1Ii0BK.cjs","names":["join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\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 = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\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`, `compose`, `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\tcompose: async () => (await import('./compose/index')).composeTarget(),\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,11 +1,11 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_credentials = require("./credentials-BVs7mrtw.cjs");
3
3
  const require_sandbox = require("./sandbox-CL--ZDui.cjs");
4
- const require_workspace = require("./workspace-vdrcRI-m.cjs");
4
+ const require_workspace = require("./workspace-DOm81oUo.cjs");
5
5
  const require_config = require("./config.cjs");
6
- const require_state = require("./state-DCwRWyh-.cjs");
7
- const require_sniffer = require("./sniffer-C-T7dSMN.cjs");
8
- const require_engine = require("./engine-Bh76sAHy.cjs");
6
+ const require_state = require("./state-C2qi0iQw.cjs");
7
+ const require_sniffer = require("./sniffer-Y6GQOCXB.cjs");
8
+ const require_engine = require("./engine-C0N2d1i5.cjs");
9
9
  let node_path = require("node:path");
10
10
  //#region src/target/dokploy/rollback.ts
11
11
  /**
@@ -158,4 +158,4 @@ Object.defineProperty(exports, "rollback_exports", {
158
158
  }
159
159
  });
160
160
 
161
- //# sourceMappingURL=rollback-DJy3t696.cjs.map
161
+ //# sourceMappingURL=rollback-C9N5lKVf.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-DJy3t696.cjs","names":["storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-C9N5lKVf.cjs","names":["storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,mBAAb,cAAsC,MAAM;CAEjC;CAEA;CAHV,YACC,OAEA,MACC;EACD,MACC,oDAAoD,KAAK,KAAK,IAAI,KAAK,8BAA8B,mCACnE,MAAM,YACzC;EAPS,KAAA,QAAA;EAEA,KAAA,OAAA;EAMT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,oBAAb,cAAuC,MAAM;CAElC;CACA;CAFV,YACC,OACA,KACC;EACD,MACC,IAAI,IAAI,+BAA+B,MAAM,oIAE9C;EANS,KAAA,QAAA;EACA,KAAA,MAAA;EAMT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,qBAAb,cAAwC,MAAM;CACxB;CAArB,YAAY,OAAwB;EACnC,MACC,IAAI,MAAM,6JAEX;EAJoB,KAAA,QAAA;EAKpB,KAAK,OAAO;CACb;AACD;;;;;AAMA,eAAsB,cACrB,OACwB;CACxB,MAAM,SAAS,MAAM,UAAU,IAAI,gBAAgB,CAAC,CAAC;CACrD,MAAM,MAAM,MAAM,cAAc,CAAC;CACjC,MAAM,cAAc,MAAM,eAAeA,oBAAAA,kBAAkB;CAC3D,MAAM,UACL,MAAM,WACN,IAAIC,oBAAAA,aAAa,EAAE,MAAMC,eAAAA,mBAAAA,GAAkBC,UAAAA,QAAAA,CAAQ,MAAM,GAAG,CAAC,EAAE,CAAC;CAEjE,OAAOC,gBAAAA,YAAY,SAAS,YAAY;EACvC,MAAM,EAAE,cAAc,MAAMC,eAAAA,qBAAAA,GAAoBF,UAAAA,QAAAA,CAAQ,MAAM,GAAG,GAAG,EACnE,QACD,CAAC;EACD,kBAAA,oBAAoB,UAAU,QAAQ,MAAM,KAAK;EAEjD,MAAM,QAAQ,MAAMG,gBAAAA,iBAAiB;GACpC,QAAQ,UAAU;GAClB,eAAe,UAAU;GACzB,eAAe,UAAU;EAC1B,CAAC;EACD,IAAI,CAAE,MAAM,MAAM,KAAK,MAAM,KAAK,GACjC,MAAM,IAAI,mBAAmB,MAAM,KAAK;EAGzC,MAAM,OAAO,MAAM,MAAM,KAAK,MAAM,OAAO,EAAE,WAAW,WAAW,CAAC;EACpE,IAAI;GACH,MAAM,UAAU,MAAMC,cAAAA,cAAc,KAAK,OAAO,MAAM,aACrDC,cAAAA,iBAAiB,MAAM,OAAO,IAAI,EAAE,CACrC;GACA,MAAM,EAAE,UAAU;GAClB,MAAM,WAAW,MAAM,YAAY,CAAC;GACpC,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,CAAC,QACvC,QAAQ,SAAS,IAAI,CAAE,QACzB;GAEA,IAAI;GACJ,IAAI,MAAM,QAAQ;IACjB,OAAO;IACP,IAAI,KAAK,WAAW,GACnB,MAAM,IAAI,iBAAiB,MAAM,OAAO,UAAU;GAEpD,OAAO,IAAI,MAAM,KAAK;IACrB,IAAI,CAAC,SAAS,MAAM,IAAI,EAAE,UACzB,MAAM,IAAI,kBAAkB,MAAM,OAAO,MAAM,GAAG;IAEnD,OAAO,CAAC,MAAM,GAAG;GAClB,OACC,MAAM,IAAI,iBAAiB,MAAM,OAAO,UAAU;GAGnD,MAAM,EAAE,QAAQ,MAAMC,eAAAA,WAAW,WAAW;IAAE;IAAa;GAAO,CAAC;GACnE,MAAM,SAASC,eAAAA,eAAe,UAAU,OAAO,SAAS,MAAM;GAC9D,MAAM,SAAuB,CAAC;GAE9B,KAAK,MAAM,OAAO,MAAM;IACvB,OAAO,eAAe;IACtB,MAAM,EAAE,SAAS,aAAa,SAAS;IACvC,MAAM,gBAAgB,MAAM,aAAa;IACzC,IAAI,CAAC,YAAY,CAAC,eACjB,MAAM,IAAI,kBAAkB,MAAM,OAAO,GAAG;IAG7C,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,SAAS,KAAK;IAChD,MAAMC,eAAAA,aAAa,KAAK;KACvB;KACA,OAAO;KACP,YAAY,MAAM;KAClB;KACA;IACD,CAAC;IACD,cAAA,eAAe,OAAO,KAAK,QAAQ;IACnC,MAAM,QAAQ,KAAK;IACnB,IAAI,QAAQ,IAAI,cAAc,SAAS,KAAK;IAC5C,OAAO,KAAK;KAAE;KAAK,MAAM;KAAS,IAAI;IAAS,CAAC;GACjD;GAEA,OAAO;EACR,UAAU;GACT,MAAM,KAAK,QAAQ;EACpB;CACD,CAAC;AACF"}
@@ -1,11 +1,11 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { i as LocalSandbox, r as storedCredentials } from "./credentials-pAtB70k3.mjs";
3
3
  import { c as withSandbox } from "./sandbox-Dm247NGx.mjs";
4
- import { k as assertDeployedStage } from "./workspace-C7NqCsQF.mjs";
4
+ import { k as assertDeployedStage } from "./workspace-QUTqYmVy.mjs";
5
5
  import { findWorkspaceRoot, loadWorkspaceConfig } from "./config.mjs";
6
- import { o as recordRollback, p as DeployJournal, t as createEmptyState } from "./state-DpkxSwzI.mjs";
7
- import { g as createStateStore } from "./sniffer-BFmdZpZ2.mjs";
8
- import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-B1b4I34Z.mjs";
6
+ import { o as recordRollback, p as DeployJournal, t as createEmptyState } from "./state-CUecOCNJ.mjs";
7
+ import { g as createStateStore } from "./sniffer-DR8AlRCk.mjs";
8
+ import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-BOO5TWZd.mjs";
9
9
  import { resolve } from "node:path";
10
10
  //#region src/target/dokploy/rollback.ts
11
11
  /**
@@ -129,4 +129,4 @@ async function rollbackStage(input) {
129
129
  //#endregion
130
130
  export { rollback_exports as a, rollbackStage as i, RollbackNeedsApp as n, StageNeverDeployed as r, NothingToRollBack as t };
131
131
 
132
- //# sourceMappingURL=rollback-CWYTUhfW.mjs.map
132
+ //# sourceMappingURL=rollback-DeQzbRqM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-CWYTUhfW.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-DeQzbRqM.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-TzCChNrA.cjs";
1
+ import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-OxE0OAn2.mjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends Error {
@@ -87,4 +87,4 @@ declare class TargetRuntimeUndeclared extends Error {
87
87
  }
88
88
  //#endregion
89
89
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
90
- //# sourceMappingURL=runtime-BzZD5HHi.d.cts.map
90
+ //# sourceMappingURL=runtime-BSvzPqXW.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-BzZD5HHi.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-BSvzPqXW.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
@@ -1,4 +1,4 @@
1
- import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-Dp9lgx_S.mjs";
1
+ import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-BdptGBFS.cjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends Error {
@@ -87,4 +87,4 @@ declare class TargetRuntimeUndeclared extends Error {
87
87
  }
88
88
  //#endregion
89
89
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
90
- //# sourceMappingURL=runtime-Cm6J6L7n.d.mts.map
90
+ //# sourceMappingURL=runtime-Cm7QA53H.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-Cm6J6L7n.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-Cm7QA53H.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}