@geekmidas/cli 10.0.0-alpha.3 → 10.0.0-alpha.30

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 (255) hide show
  1. package/README.md +25 -48
  2. package/bin/adjacent-tsconfig.mjs +97 -0
  3. package/bin/gkm.mjs +7 -1
  4. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-BZFGYYVA.cjs} +21 -22
  5. package/dist/HostingerProvider-BZFGYYVA.cjs.map +1 -0
  6. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-GF6NAZAK.mjs} +20 -21
  7. package/dist/HostingerProvider-GF6NAZAK.mjs.map +1 -0
  8. package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
  9. package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
  10. package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
  11. package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
  12. package/dist/{openapi-c9bpieI5.cjs → OpenApiTsGenerator-D1nhN98m.cjs} +135 -298
  13. package/dist/OpenApiTsGenerator-D1nhN98m.cjs.map +1 -0
  14. package/dist/{openapi-CY9xFkTH.mjs → OpenApiTsGenerator-hDINScnz.mjs} +106 -250
  15. package/dist/OpenApiTsGenerator-hDINScnz.mjs.map +1 -0
  16. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
  17. package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
  18. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
  19. package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
  20. package/dist/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
  21. package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
  22. package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
  23. package/dist/SSMStateProvider-VrQ-yeqd.cjs.map +1 -0
  24. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
  25. package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
  26. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
  27. package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
  28. package/dist/{bundler-BY1OmV1e.cjs → bundler-CYF5mWi9.cjs} +10 -28
  29. package/dist/bundler-CYF5mWi9.cjs.map +1 -0
  30. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D9IPNvDt.mjs} +9 -26
  31. package/dist/bundler-D9IPNvDt.mjs.map +1 -0
  32. package/dist/{config-CzWnfcXM.mjs → config-BH3Ki69F.mjs} +49 -89
  33. package/dist/config-BH3Ki69F.mjs.map +1 -0
  34. package/dist/{config-BholeD-0.cjs → config-URVD4bTj.cjs} +101 -148
  35. package/dist/config-URVD4bTj.cjs.map +1 -0
  36. package/dist/config.cjs +5 -5
  37. package/dist/config.d.cts +25 -17
  38. package/dist/config.d.cts.map +1 -1
  39. package/dist/config.d.mts +25 -17
  40. package/dist/config.d.mts.map +1 -1
  41. package/dist/config.mjs +3 -5
  42. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  43. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  44. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  45. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  46. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  47. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  48. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  49. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  50. package/dist/deploy/sniffer-hooks.cjs +13 -7
  51. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  52. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  53. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  54. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  55. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  56. package/dist/deploy/sniffer-hooks.mjs +9 -2
  57. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  58. package/dist/deploy/sniffer-loader.cjs +16 -7
  59. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  60. package/dist/deploy/sniffer-loader.d.cts +1 -1
  61. package/dist/deploy/sniffer-loader.d.mts +1 -1
  62. package/dist/deploy/sniffer-loader.mjs +13 -2
  63. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  64. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  65. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  66. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  67. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  68. package/dist/deploy/sniffer-routes-worker.mjs +3 -3
  69. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  70. package/dist/deploy/sniffer-worker.cjs +15 -6
  71. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  72. package/dist/deploy/sniffer-worker.d.cts +1 -3
  73. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  74. package/dist/deploy/sniffer-worker.d.mts +1 -3
  75. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  76. package/dist/deploy/sniffer-worker.mjs +15 -4
  77. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  78. package/dist/{discover-CAlFgYec.mjs → discover-CMxesskG.mjs} +66 -22
  79. package/dist/discover-CMxesskG.mjs.map +1 -0
  80. package/dist/{discover-DTmFeloL.cjs → discover-CroTIm0K.cjs} +117 -66
  81. package/dist/discover-CroTIm0K.cjs.map +1 -0
  82. package/dist/{emit-CbcRolsa.cjs → emit-BdoPFjZf.cjs} +53 -36
  83. package/dist/emit-BdoPFjZf.cjs.map +1 -0
  84. package/dist/{emit-CiZS_5Ub.mjs → emit-Bzq7JsMP.mjs} +24 -6
  85. package/dist/emit-Bzq7JsMP.mjs.map +1 -0
  86. package/dist/github-B2fis34P.cjs +216 -0
  87. package/dist/github-B2fis34P.cjs.map +1 -0
  88. package/dist/github-BrDmlm1x.mjs +216 -0
  89. package/dist/github-BrDmlm1x.mjs.map +1 -0
  90. package/dist/{index-CHB4tSzX.d.cts → index-p89EzILa.d.mts} +4 -23
  91. package/dist/index-p89EzILa.d.mts.map +1 -0
  92. package/dist/{index-BThUzEIp.d.mts → index-rU9u761a.d.cts} +4 -23
  93. package/dist/index-rU9u761a.d.cts.map +1 -0
  94. package/dist/index.cjs +6001 -4452
  95. package/dist/index.cjs.map +1 -1
  96. package/dist/index.d.cts +1 -1
  97. package/dist/index.d.mts +1 -1
  98. package/dist/index.mjs +5895 -4367
  99. package/dist/index.mjs.map +1 -1
  100. package/dist/migrate-BuCx7tIv.cjs +498 -0
  101. package/dist/migrate-BuCx7tIv.cjs.map +1 -0
  102. package/dist/migrate-CBICVMAi.mjs +493 -0
  103. package/dist/migrate-CBICVMAi.mjs.map +1 -0
  104. package/dist/openapi.cjs +197 -8
  105. package/dist/openapi.cjs.map +1 -0
  106. package/dist/openapi.d.cts +47 -14
  107. package/dist/openapi.d.cts.map +1 -1
  108. package/dist/openapi.d.mts +47 -14
  109. package/dist/openapi.d.mts.map +1 -1
  110. package/dist/openapi.mjs +191 -5
  111. package/dist/openapi.mjs.map +1 -0
  112. package/dist/ready-CvP3JVEw.mjs +355 -0
  113. package/dist/ready-CvP3JVEw.mjs.map +1 -0
  114. package/dist/ready-DXtNfk7v.cjs +390 -0
  115. package/dist/ready-DXtNfk7v.cjs.map +1 -0
  116. package/dist/reconcile/public.cjs +4 -4
  117. package/dist/reconcile/public.d.cts +27 -26
  118. package/dist/reconcile/public.d.cts.map +1 -1
  119. package/dist/reconcile/public.d.mts +27 -26
  120. package/dist/reconcile/public.d.mts.map +1 -1
  121. package/dist/reconcile/public.mjs +3 -4
  122. package/dist/reconcile-BxZTV2vl.cjs +332 -0
  123. package/dist/reconcile-BxZTV2vl.cjs.map +1 -0
  124. package/dist/reconcile-yNq6Shau.mjs +279 -0
  125. package/dist/reconcile-yNq6Shau.mjs.map +1 -0
  126. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  127. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  128. package/dist/ssm-BKN1Cg4z.mjs +60 -0
  129. package/dist/ssm-BKN1Cg4z.mjs.map +1 -0
  130. package/dist/ssm-FxeSAt35.cjs +60 -0
  131. package/dist/ssm-FxeSAt35.cjs.map +1 -0
  132. package/dist/{storage-Bi24WfoW.mjs → storage-BjTLjDDp.mjs} +22 -22
  133. package/dist/storage-BjTLjDDp.mjs.map +1 -0
  134. package/dist/{storage-BJmzYxt8.cjs → storage-C2JC31V9.cjs} +65 -84
  135. package/dist/storage-C2JC31V9.cjs.map +1 -0
  136. package/dist/types-CzK6hsXP.d.mts +6286 -0
  137. package/dist/types-CzK6hsXP.d.mts.map +1 -0
  138. package/dist/types-DOOAevjG.d.cts +6287 -0
  139. package/dist/types-DOOAevjG.d.cts.map +1 -0
  140. package/dist/vitest.cjs +61 -0
  141. package/dist/vitest.cjs.map +1 -0
  142. package/dist/vitest.d.cts +28 -0
  143. package/dist/vitest.d.cts.map +1 -0
  144. package/dist/vitest.d.mts +28 -0
  145. package/dist/vitest.d.mts.map +1 -0
  146. package/dist/vitest.mjs +61 -0
  147. package/dist/vitest.mjs.map +1 -0
  148. package/dist/workspace/index.cjs +3 -4
  149. package/dist/workspace/index.d.cts +3 -3
  150. package/dist/workspace/index.d.mts +3 -3
  151. package/dist/workspace/index.mjs +2 -3
  152. package/dist/workspace-Bav3TVrP.cjs +6710 -0
  153. package/dist/workspace-Bav3TVrP.cjs.map +1 -0
  154. package/dist/{credentials-DQmbRnr1.cjs → workspace-BhiMkRuA.cjs} +2076 -1963
  155. package/dist/workspace-BhiMkRuA.cjs.map +1 -0
  156. package/dist/{credentials-BZcp3CGx.mjs → workspace-C97QUCIf.mjs} +1957 -1837
  157. package/dist/workspace-C97QUCIf.mjs.map +1 -0
  158. package/dist/workspace-T4IVGSoB.mjs +6538 -0
  159. package/dist/workspace-T4IVGSoB.mjs.map +1 -0
  160. package/package.json +45 -38
  161. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  162. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  163. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  164. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  165. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  166. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  167. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  168. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  169. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  170. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  171. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  172. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  173. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  174. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  175. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  176. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  177. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  178. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  179. package/dist/chunk-Duj1WY3L.mjs +0 -7
  180. package/dist/config-BholeD-0.cjs.map +0 -1
  181. package/dist/config-CzWnfcXM.mjs.map +0 -1
  182. package/dist/credentials-B5zRHdAl.mjs +0 -141
  183. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  184. package/dist/credentials-BZcp3CGx.mjs.map +0 -1
  185. package/dist/credentials-BapzjyV5.cjs +0 -195
  186. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  187. package/dist/credentials-DQmbRnr1.cjs.map +0 -1
  188. package/dist/discover-CAlFgYec.mjs.map +0 -1
  189. package/dist/discover-DTmFeloL.cjs.map +0 -1
  190. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  191. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  192. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  193. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  194. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  195. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  196. package/dist/emit-CbcRolsa.cjs.map +0 -1
  197. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  198. package/dist/encryption-C6jaU0hE.cjs +0 -54
  199. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  200. package/dist/encryption-CHzzeR8a.cjs +0 -4
  201. package/dist/encryption-CQUncu7v.mjs +0 -3
  202. package/dist/encryption-D-abyhZx.mjs +0 -42
  203. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  204. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  205. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  206. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  207. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  208. package/dist/generator-CNzBw7g5.cjs +0 -289
  209. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  210. package/dist/generator-VE2JrFlY.mjs +0 -253
  211. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  212. package/dist/index-BThUzEIp.d.mts.map +0 -1
  213. package/dist/index-CHB4tSzX.d.cts.map +0 -1
  214. package/dist/openapi-CY9xFkTH.mjs.map +0 -1
  215. package/dist/openapi-c9bpieI5.cjs.map +0 -1
  216. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  217. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  218. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  219. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  220. package/dist/openapi-react-query.cjs +0 -4
  221. package/dist/openapi-react-query.d.cts +0 -11
  222. package/dist/openapi-react-query.d.cts.map +0 -1
  223. package/dist/openapi-react-query.d.mts +0 -11
  224. package/dist/openapi-react-query.d.mts.map +0 -1
  225. package/dist/openapi-react-query.mjs +0 -4
  226. package/dist/reconcile-CFs8C_1a.mjs +0 -37
  227. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  228. package/dist/reconcile-D0pimNiy.cjs +0 -37
  229. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  230. package/dist/setup-Bc73t0ve.mjs +0 -443
  231. package/dist/setup-Bc73t0ve.mjs.map +0 -1
  232. package/dist/setup-C48C9hto.cjs +0 -473
  233. package/dist/setup-C48C9hto.cjs.map +0 -1
  234. package/dist/setup-DCuudnCl.mjs +0 -11
  235. package/dist/setup-fG_ivuxO.cjs +0 -11
  236. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  237. package/dist/storage-BM9hGpgv.cjs +0 -7
  238. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  239. package/dist/storage-CYlGwWTj.mjs +0 -3
  240. package/dist/sync-CmEuNZsB.mjs +0 -76
  241. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  242. package/dist/sync-D306yOWu.cjs +0 -4
  243. package/dist/sync-SizaChmC.cjs +0 -93
  244. package/dist/sync-SizaChmC.cjs.map +0 -1
  245. package/dist/sync-hOqAWHR6.mjs +0 -3
  246. package/dist/types-C-arnQ1r.d.mts +0 -2184
  247. package/dist/types-C-arnQ1r.d.mts.map +0 -1
  248. package/dist/types-abJQuk7m.d.cts +0 -2184
  249. package/dist/types-abJQuk7m.d.cts.map +0 -1
  250. package/dist/workspace-7FqprxuJ.mjs +0 -4323
  251. package/dist/workspace-7FqprxuJ.mjs.map +0 -1
  252. package/dist/workspace-BO_KWohI.cjs +0 -9
  253. package/dist/workspace-DK4WWJIn.mjs +0 -8
  254. package/dist/workspace-XvqO9jIv.cjs +0 -4472
  255. package/dist/workspace-XvqO9jIv.cjs.map +0 -1
@@ -1,12 +1,8 @@
1
- import { ConstructGenerator, isPartitionedRoutes } from "./discover-CAlFgYec.mjs";
2
- import { loadWorkspaceConfig } from "./config-CzWnfcXM.mjs";
3
- import { dirname, join, relative } from "node:path";
1
+ import { i as ConstructGenerator } from "./discover-CMxesskG.mjs";
4
2
  import { mkdir, writeFile } from "node:fs/promises";
5
- import { spawn } from "node:child_process";
3
+ import { dirname, join, relative } from "node:path";
6
4
  import { Endpoint } from "@geekmidas/constructs/endpoints";
7
- import { fileURLToPath } from "node:url";
8
5
  import { StandardSchemaJsonSchema, getRegisteredZodJsonSchemas, getSchemaMetadata } from "@geekmidas/schema/conversion";
9
-
10
6
  //#region src/build/endpoint-analyzer.ts
11
7
  /**
12
8
  * Analyze an endpoint to extract its features
@@ -83,7 +79,6 @@ function summarizeAnalysis(analyses) {
83
79
  byFeature
84
80
  };
85
81
  }
86
-
87
82
  //#endregion
88
83
  //#region src/build/handler-templates.ts
89
84
  /**
@@ -105,8 +100,7 @@ function generateMinimalHandler(analysis) {
105
100
  const { exportName, features } = analysis;
106
101
  const method = analysis.method.toLowerCase();
107
102
  const validators = generateValidators(exportName, features);
108
- const hasValidators = validators.length > 0;
109
- if (!hasValidators && !features.hasOutputValidation) return `
103
+ if (!(validators.length > 0) && !features.hasOutputValidation) return `
110
104
  // Minimal handler: ${analysis.route} (${analysis.method})
111
105
  app.${method}('${analysis.route}', async (c) => {
112
106
  const result = await ${exportName}.handler(
@@ -304,8 +298,7 @@ ${factories.join("\n")}
304
298
  */
305
299
  function generateMinimalEndpointFile(analysis, endpointImport) {
306
300
  const { exportName, features } = analysis;
307
- const needsValidators = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation;
308
- const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
301
+ const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
309
302
  const handler = generateMinimalHandler(analysis);
310
303
  return `/**
311
304
  * Minimal endpoint: ${analysis.route} (${analysis.method})
@@ -330,8 +323,7 @@ ${handler}
330
323
  */
331
324
  function generateStandardEndpointFile(analysis, endpointImport) {
332
325
  const { exportName, features } = analysis;
333
- const needsValidators = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation;
334
- const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
326
+ const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
335
327
  const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
336
328
  const handler = generateStandardHandler(analysis);
337
329
  return `/**
@@ -423,7 +415,7 @@ export function setupFullEndpoints(
423
415
  }
424
416
  const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
425
417
  if (tier === "minimal") {
426
- const calls$1 = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
418
+ const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
427
419
  return `/**
428
420
  * Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
429
421
  * Near-raw-Hono performance
@@ -436,12 +428,12 @@ export function setupMinimalEndpoints(
436
428
  app: Hono,
437
429
  logger: Logger,
438
430
  ): void {
439
- ${calls$1}
431
+ ${calls}
440
432
  }
441
433
  `;
442
434
  }
443
435
  if (tier === "standard") {
444
- const calls$1 = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
436
+ const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
445
437
  return `/**
446
438
  * Standard-tier endpoint index (${tierEndpoints.length} endpoints)
447
439
  * Auth and/or services enabled
@@ -456,7 +448,7 @@ export function setupStandardEndpoints(
456
448
  serviceDiscovery: ServiceDiscovery<any, any>,
457
449
  logger: Logger,
458
450
  ): void {
459
- ${calls$1}
451
+ ${calls}
460
452
  }
461
453
  `;
462
454
  }
@@ -526,9 +518,7 @@ function generateEndpointFilesNested(analyses, endpointImports) {
526
518
  case "standard":
527
519
  files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
528
520
  break;
529
- case "full":
530
- files[fileName] = generateFullEndpointFile(analysis, endpointImport);
531
- break;
521
+ case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
532
522
  }
533
523
  }
534
524
  return files;
@@ -585,7 +575,6 @@ export async function setupEndpoints(
585
575
  }
586
576
  `;
587
577
  }
588
-
589
578
  //#endregion
590
579
  //#region src/generators/EndpointGenerator.ts
591
580
  /**
@@ -602,24 +591,21 @@ export async function setupEndpoints(
602
591
  *
603
592
  * Falls back to the configured paths for an app that declares no surface.
604
593
  */
605
- function runtimeFor(context, fromDir) {
606
- const module = context.surface?.module;
594
+ function runtimeFor(context, fromDir, owner) {
595
+ const module = owner ? context.owners?.[owner] ?? context.surface?.module : context.surface?.module;
607
596
  if (module) {
608
597
  const specifier = importSpecifier(fromDir, module.specifier);
609
598
  return {
610
599
  imports: `import { ${module.exportName} as __surface } from '${specifier}';`,
611
600
  bindings: [
612
- "// What this surface was declared with. Objects, not module paths:",
613
- "// the entry imports the surface, so there is nothing to print.",
601
+ "// What this construct was declared with. Objects, not module paths:",
602
+ "// the entry imports the owner, so there is nothing to print.",
614
603
  "const envParser = __surface.envParser;",
615
604
  "const logger = __surface.logger;"
616
605
  ].join("\n")
617
606
  };
618
607
  }
619
- return {
620
- imports: [`import ${context.envParserImportPattern} from '${importSpecifier(fromDir, context.envParserPath)}';`, `import ${context.loggerImportPattern} from '${importSpecifier(fromDir, context.loggerPath)}';`].join("\n"),
621
- bindings: ""
622
- };
608
+ throw new Error(`No owner to take a logger and an environment parser from${owner ? ` for "${owner}"` : ""}. Build it from a \`RestApi\` or a \`Worker\`.`);
623
609
  }
624
610
  /** A relative specifier ESM will accept: always prefixed, never bare. */
625
611
  function importSpecifier(fromDir, target) {
@@ -734,8 +720,7 @@ var EndpointGenerator = class extends ConstructGenerator {
734
720
  async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
735
721
  const handlerFileName = `${exportName}.ts`;
736
722
  const handlerPath = join(outputDir, handlerFileName);
737
- const relativePath = relative(dirname(handlerPath), sourceFile);
738
- const importPath = relativePath.replace(/\.ts$/, ".js");
723
+ const importPath = relative(dirname(handlerPath), sourceFile).replace(/\.ts$/, ".js");
739
724
  let content;
740
725
  switch (provider) {
741
726
  case "aws-apigatewayv1":
@@ -753,12 +738,10 @@ var EndpointGenerator = class extends ConstructGenerator {
753
738
  return handlerPath;
754
739
  }
755
740
  async generateEndpointsFile(outputDir, endpoints, context) {
756
- const endpointsFileName = "endpoints.ts";
757
- const endpointsPath = join(outputDir, endpointsFileName);
741
+ const endpointsPath = join(outputDir, "endpoints.ts");
758
742
  const importsByFile = /* @__PURE__ */ new Map();
759
743
  for (const { path, key } of endpoints) {
760
- const relativePath = relative(dirname(endpointsPath), path.relative);
761
- const importPath = relativePath.replace(/\.ts$/, ".js");
744
+ const importPath = relative(dirname(endpointsPath), path.relative).replace(/\.ts$/, ".js");
762
745
  if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
763
746
  importsByFile.get(importPath)?.push(key);
764
747
  }
@@ -824,11 +807,9 @@ export async function setupEndpoints(
824
807
  const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
825
808
  const endpointImports = endpoints.map(({ key, path }) => {
826
809
  const tierDir = join(endpointsDir, "standard");
827
- const relativePath = relative(tierDir, path.relative);
828
- const importPath = relativePath.replace(/\.ts$/, ".js");
829
810
  return {
830
811
  exportName: key,
831
- importPath
812
+ importPath: relative(tierDir, path.relative).replace(/\.ts$/, ".js")
832
813
  };
833
814
  });
834
815
  const summary = summarizeAnalysis(analyses);
@@ -850,8 +831,7 @@ export async function setupEndpoints(
850
831
  }
851
832
  async generateAppFile(outputDir, context) {
852
833
  if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
853
- const appFileName = "app.ts";
854
- const appPath = join(outputDir, appFileName);
834
+ const appPath = join(outputDir, "app.ts");
855
835
  const runtime = runtimeFor(context, dirname(appPath));
856
836
  const telescopeEnabled = context.telescope?.enabled;
857
837
  const telescopeWebSocketEnabled = context.telescope?.websocket;
@@ -861,32 +841,36 @@ export async function setupEndpoints(
861
841
  const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
862
842
  const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
863
843
  let telescopeImports = "";
864
- if (telescopeEnabled) if (telescopeFromSurface) telescopeImports = "import { createMiddleware, createUI } from '@geekmidas/telescope/hono';";
865
- else if (usesExternalTelescope) {
866
- const relativeTelescopePath = relative(dirname(appPath), context.telescope?.telescopePath);
867
- telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
844
+ if (telescopeEnabled) {
845
+ if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
846
+ import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
847
+ else if (usesExternalTelescope) {
848
+ const relativeTelescopePath = relative(dirname(appPath), context.telescope?.telescopePath);
849
+ telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
868
850
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
869
- } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
851
+ } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
870
852
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
853
+ }
871
854
  let studioImports = "";
872
- if (studioEnabled) if (usesExternalStudio) {
873
- const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
874
- studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
855
+ if (studioEnabled) {
856
+ if (usesExternalStudio) {
857
+ const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
858
+ studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
875
859
  import { createStudioApp } from '@geekmidas/studio/server/hono';`;
876
- } else if (studioFromDatabase) {
877
- const dbSpecifier = importSpecifier(dirname(appPath), context.studio.database.specifier);
878
- studioImports = `import { snifferContext } from '@geekmidas/constructs';
860
+ } else if (studioFromDatabase) {
861
+ const dbSpecifier = importSpecifier(dirname(appPath), context.studio.database.specifier);
862
+ studioImports = `import { snifferContext } from '@geekmidas/constructs';
879
863
  import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
880
864
  import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
881
865
  import { createStudioApp } from '@geekmidas/studio/server/hono';`;
882
- } else studioImports = "";
866
+ } else studioImports = "";
867
+ }
883
868
  const cors = corsFor(context.surface);
884
869
  let hooksImports = "";
885
870
  let beforeSetupCall = "";
886
871
  let afterSetupCall = "";
887
872
  if (context.hooks?.serverHooksPath) {
888
- const relativeHooksPath = relative(dirname(appPath), context.hooks.serverHooksPath);
889
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
873
+ hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
890
874
  beforeSetupCall = `
891
875
  // Call beforeSetup hook if defined
892
876
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -932,7 +916,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
932
916
  }
933
917
  ` : "";
934
918
  let telescopeSetup = "";
935
- if (telescopeEnabled) if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
919
+ if (telescopeEnabled) {
920
+ if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
936
921
  ${telescopeWebSocketSetupCode}
937
922
  // Add telescope middleware (before endpoints to capture all requests)
938
923
  honoApp.use('*', createMiddleware(telescope));
@@ -941,7 +926,7 @@ ${telescopeWebSocketSetupCode}
941
926
  const telescopeUI = createUI(telescope);
942
927
  honoApp.route('${context.telescope?.path}', telescopeUI);
943
928
  `;
944
- else telescopeSetup = `
929
+ else telescopeSetup = `
945
930
  // Setup Telescope for debugging/monitoring
946
931
  const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
947
932
  const telescope = new Telescope({
@@ -959,6 +944,7 @@ ${telescopeWebSocketSetupCode}
959
944
  const telescopeUI = createUI(telescope);
960
945
  honoApp.route('${context.telescope?.path}', telescopeUI);
961
946
  `;
947
+ }
962
948
  let studioSetup = "";
963
949
  if (studioEnabled && studioFromDatabase) studioSetup = `
964
950
  // Studio, built from the declared database. The client comes from the
@@ -992,6 +978,7 @@ import type { Hono as HonoType } from 'hono';
992
978
  import { setupEndpoints } from './endpoints.js';
993
979
  import { setupSubscribers } from './subscribers.js';
994
980
  import { setupQueues } from './queues.js';
981
+ import { setupCrons } from './crons.js';
995
982
  ${runtime.imports}
996
983
  ${telescopeImports}
997
984
  ${studioImports}
@@ -1000,7 +987,16 @@ ${cors.imports}
1000
987
  ${context.storageDrivers?.imports ?? ""}
1001
988
 
1002
989
  ${runtime.bindings}
1003
- ${telescopeFromSurface ? "const telescope = __surface.telescope;" : ""}
990
+ ${telescopeEnabled && telescopeFromSurface ? `// The surface's own Telescope, or the one \`telescope\` config describes.
991
+ const telescope =
992
+ __surface.telescope ??
993
+ new Telescope({
994
+ enabled: true,
995
+ path: '${context.telescope?.path}',
996
+ ignorePatterns: ${JSON.stringify(context.telescope?.ignore)},
997
+ recordBody: ${context.telescope?.recordBody},
998
+ storage: new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} }),
999
+ });` : ""}
1004
1000
 
1005
1001
  ${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
1006
1002
  // each injected URL picks one, so no construct and no application module names
@@ -1079,6 +1075,12 @@ ${afterSetupCall}
1079
1075
  logger.error({ error }, 'Failed to start queue workers');
1080
1076
  });
1081
1077
 
1078
+ // Schedule this app's crons. Caught like the others: a scheduler that
1079
+ // cannot start is not a reason for the HTTP server not to.
1080
+ await setupCrons(envParser, logger).catch((error) => {
1081
+ logger.error({ error }, 'Failed to schedule crons');
1082
+ });
1083
+
1082
1084
  logger.info({ port }, 'Starting server');
1083
1085
 
1084
1086
  // Start HTTP server using provided serve function
@@ -1147,10 +1149,8 @@ export const handler = ${exportName};
1147
1149
  * No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
1148
1150
  */
1149
1151
  async generateProductionAppFile(outputDir, context) {
1150
- const appFileName = "app.ts";
1151
- const appPath = join(outputDir, appFileName);
1152
- const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);
1153
- const relativeEnvParserPath = relative(dirname(appPath), context.envParserPath);
1152
+ const appPath = join(outputDir, "app.ts");
1153
+ const runtime = runtimeFor(context, dirname(appPath));
1154
1154
  const production = context.production;
1155
1155
  const healthCheckPath = production.healthCheck;
1156
1156
  const enableGracefulShutdown = production.gracefulShutdown;
@@ -1161,8 +1161,7 @@ export const handler = ${exportName};
1161
1161
  let beforeSetupCall = "";
1162
1162
  let afterSetupCall = "";
1163
1163
  if (context.hooks?.serverHooksPath) {
1164
- const relativeHooksPath = relative(dirname(appPath), context.hooks.serverHooksPath);
1165
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
1164
+ hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
1166
1165
  beforeSetupCall = `
1167
1166
  // Call beforeSetup hook if defined
1168
1167
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -1186,9 +1185,16 @@ export const handler = ${exportName};
1186
1185
  await setupQueues(envParser, logger).catch((error) => {
1187
1186
  logger.error({ error }, 'Failed to start queue workers');
1188
1187
  });
1188
+
1189
+ // Schedule this app's crons. Caught like the others: a scheduler that
1190
+ // cannot start is not a reason for the HTTP server not to.
1191
+ await setupCrons(envParser, logger).catch((error) => {
1192
+ logger.error({ error }, 'Failed to schedule crons');
1193
+ });
1189
1194
  ` : "";
1190
1195
  const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
1191
- import { setupQueues } from './queues.js';` : "";
1196
+ import { setupQueues } from './queues.js';
1197
+ import { setupCrons } from './crons.js';` : "";
1192
1198
  const gracefulShutdownCode = enableGracefulShutdown ? `
1193
1199
  // Graceful shutdown handling
1194
1200
  let isShuttingDown = false;
@@ -1204,7 +1210,6 @@ import { setupQueues } from './queues.js';` : "";
1204
1210
  process.on('SIGTERM', shutdown);
1205
1211
  process.on('SIGINT', shutdown);
1206
1212
  ` : "";
1207
- const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
1208
1213
  const content = `/**
1209
1214
  * Generated production server application
1210
1215
  *
@@ -1216,10 +1221,10 @@ import { setupQueues } from './queues.js';` : "";
1216
1221
  */
1217
1222
  import { Hono } from 'hono';
1218
1223
  import type { Hono as HonoType } from 'hono';
1219
- import { setupEndpoints } from '${endpointsImportPath}';
1224
+ import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
1220
1225
  ${subscriberImport}
1221
- import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
1222
- import ${context.loggerImportPattern} from '${relativeLoggerPath}';
1226
+ ${runtime.imports}
1227
+ ${runtime.bindings}
1223
1228
  ${hooksImports}
1224
1229
  ${cors.imports}
1225
1230
  ${context.storageDrivers?.imports ?? ""}
@@ -1283,7 +1288,7 @@ export default createApp;
1283
1288
  */
1284
1289
  async generateProductionServerEntry(outputDir) {
1285
1290
  const serverPath = join(outputDir, "server.ts");
1286
- const content = `#!/usr/bin/env node
1291
+ await writeFile(serverPath, `#!/usr/bin/env node
1287
1292
  /**
1288
1293
  * Production server entry point
1289
1294
  * Generated by 'gkm build --provider server --production'
@@ -1299,11 +1304,9 @@ await start({
1299
1304
  port,
1300
1305
  serve: (app, port) => { serve({ fetch: app.fetch, port }); },
1301
1306
  });
1302
- `;
1303
- await writeFile(serverPath, content);
1307
+ `);
1304
1308
  }
1305
1309
  };
1306
-
1307
1310
  //#endregion
1308
1311
  //#region src/generators/OpenApiTsGenerator.ts
1309
1312
  /**
@@ -1458,7 +1461,7 @@ var OpenApiTsGenerator = class {
1458
1461
  for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
1459
1462
  const defName = this.pascalCase(rawName);
1460
1463
  if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
1461
- const { id: _id, $defs: _defs,...rest } = rawSchema;
1464
+ const { id: _id, $defs: _defs, ...rest } = rawSchema;
1462
1465
  collectedDefs.set(defName, rest);
1463
1466
  }
1464
1467
  for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
@@ -1494,27 +1497,29 @@ var OpenApiTsGenerator = class {
1494
1497
  async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
1495
1498
  try {
1496
1499
  const vendor = schema["~standard"]?.vendor;
1497
- if (!vendor || !(vendor in StandardSchemaJsonSchema)) return null;
1500
+ if (!vendor || !(vendor in StandardSchemaJsonSchema)) return unknownType(name);
1498
1501
  const toJsonSchema = StandardSchemaJsonSchema[vendor];
1499
1502
  const jsonSchema = await toJsonSchema(schema);
1500
- if (!jsonSchema) return null;
1503
+ if (!jsonSchema) return unknownType(name);
1501
1504
  if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
1502
1505
  for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
1503
- const { id,...schemaWithoutId } = defSchema;
1506
+ const { id, ...schemaWithoutId } = defSchema;
1504
1507
  collectedDefs.set(defName, schemaWithoutId);
1505
1508
  }
1506
1509
  }
1507
- const { $defs,...schemaWithoutDefs } = jsonSchema;
1510
+ const { $defs, ...schemaWithoutDefs } = jsonSchema;
1511
+ const ref = schemaWithoutDefs.$ref;
1512
+ if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
1513
+ const target = ref.split("/").pop();
1514
+ return target === name ? null : `export type ${name} = ${target};`;
1515
+ }
1508
1516
  return this.jsonSchemaToInterface(schemaWithoutDefs, name);
1509
1517
  } catch {
1510
- return null;
1518
+ return unknownType(name);
1511
1519
  }
1512
1520
  }
1513
1521
  jsonSchemaToInterface(schema, name) {
1514
- if (schema.type !== "object" || !schema.properties) {
1515
- const typeStr = this.jsonSchemaTypeToTs(schema);
1516
- return `export type ${name} = ${typeStr};`;
1517
- }
1522
+ if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
1518
1523
  const props = [];
1519
1524
  const required = new Set(schema.required || []);
1520
1525
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
@@ -1527,13 +1532,15 @@ var OpenApiTsGenerator = class {
1527
1532
  }
1528
1533
  jsonSchemaTypeToTs(schema) {
1529
1534
  if (!schema) return "unknown";
1530
- if (schema.$ref) {
1531
- const refName = schema.$ref.split("/").pop() || "unknown";
1532
- return refName;
1533
- }
1535
+ if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
1536
+ if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
1534
1537
  if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1535
1538
  if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1536
1539
  if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
1540
+ if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
1541
+ ...schema,
1542
+ type
1543
+ })).join(" | ");
1537
1544
  switch (schema.type) {
1538
1545
  case "string":
1539
1546
  if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
@@ -1557,10 +1564,7 @@ var OpenApiTsGenerator = class {
1557
1564
  }
1558
1565
  return `{ ${props.join("; ")} }`;
1559
1566
  }
1560
- if (schema.additionalProperties) {
1561
- const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
1562
- return `Record<string, ${valueType}>`;
1563
- }
1567
+ if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
1564
1568
  return "Record<string, unknown>";
1565
1569
  default: return "unknown";
1566
1570
  }
@@ -1581,10 +1585,7 @@ var OpenApiTsGenerator = class {
1581
1585
  }
1582
1586
  const firstWithParams = infos.find((i) => i.input?.params);
1583
1587
  let paramsEntry = "";
1584
- if (firstWithParams?.input?.params) {
1585
- const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
1586
- paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
1587
- }
1588
+ if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
1588
1589
  pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
1589
1590
  }
1590
1591
  return `export interface paths {\n${pathEntries.join("\n")}\n}`;
@@ -1623,8 +1624,7 @@ var OpenApiTsGenerator = class {
1623
1624
  return acc;
1624
1625
  }, {});
1625
1626
  const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
1626
- const hasSecuritySchemes = schemeNames.length > 0;
1627
- const createApiSection = hasSecuritySchemes ? `
1627
+ const createApiSection = schemeNames.length > 0 ? `
1628
1628
  // ============================================================
1629
1629
  // API Client Factory
1630
1630
  // ============================================================
@@ -1648,6 +1648,8 @@ export interface CreateApiOptions {
1648
1648
  queryClient?: QueryClient;
1649
1649
  /** Optional request interceptor */
1650
1650
  onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
1651
+ /** The \`fetch\` requests go out on — a test browser's, for one */
1652
+ fetch?: typeof fetch;
1651
1653
  }
1652
1654
 
1653
1655
  /**
@@ -1677,6 +1679,7 @@ export function createApi(options: CreateApiOptions) {
1677
1679
  securitySchemes,
1678
1680
  authStrategies: options.authStrategies,
1679
1681
  onRequest: options.onRequest,
1682
+ ...(options.fetch ? { fetch: options.fetch } : {}),
1680
1683
  });
1681
1684
 
1682
1685
  const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
@@ -1801,162 +1804,15 @@ ${createApiSection}
1801
1804
  `;
1802
1805
  }
1803
1806
  };
1804
-
1805
- //#endregion
1806
- //#region src/workspace/client-generator.ts
1807
1807
  /**
1808
- * Normalize routes to an array of patterns.
1809
- * Handles string, string[], and PartitionedRoutes (extracts paths).
1810
- * @internal Exported for use in dev command
1808
+ * The declaration for a schema that cannot be converted — a vendor with no
1809
+ * converter, or one that fails. The paths interface names it either way, so
1810
+ * leaving it undeclared made the generated client fail to compile.
1811
1811
  */
1812
- function normalizeRoutes(routes) {
1813
- if (!routes) return [];
1814
- if (isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
1815
- return Array.isArray(routes) ? routes : [routes];
1812
+ function unknownType(name) {
1813
+ return `export type ${name} = unknown;`;
1816
1814
  }
1817
-
1818
1815
  //#endregion
1819
- //#region src/openapi.ts
1820
- /**
1821
- * Default output path for generated OpenAPI client (used for single-app configs)
1822
- */
1823
- const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
1824
- /**
1825
- * Resolve OpenAPI config from GkmConfig
1826
- */
1827
- function resolveOpenApiConfig(config) {
1828
- if (config.openapi === false) return { enabled: false };
1829
- if (config.openapi === true || config.openapi === void 0) return {
1830
- enabled: true,
1831
- title: "API Documentation",
1832
- version: "1.0.0",
1833
- description: "Auto-generated API documentation from endpoints"
1834
- };
1835
- return {
1836
- enabled: config.openapi.enabled !== false,
1837
- title: config.openapi.title || "API Documentation",
1838
- version: config.openapi.version || "1.0.0",
1839
- description: config.openapi.description || "Auto-generated API documentation from endpoints"
1840
- };
1841
- }
1842
- /**
1843
- * Generate OpenAPI spec from endpoints
1844
- * @returns Object with output path and endpoint count, or null if disabled
1845
- */
1846
- async function generateOpenApi(config, options = {}) {
1847
- const logger = options.silent ? { log: () => {} } : console;
1848
- const openApiConfig = resolveOpenApiConfig(config);
1849
- if (!openApiConfig.enabled) return null;
1850
- const endpointGenerator = new EndpointGenerator();
1851
- const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
1852
- if (loadedEndpoints.length === 0) {
1853
- logger.log("No valid endpoints found for OpenAPI generation");
1854
- return null;
1855
- }
1856
- const endpoints = loadedEndpoints.map(({ construct }) => construct);
1857
- const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);
1858
- await mkdir(dirname(outputPath), { recursive: true });
1859
- const tsGenerator = new OpenApiTsGenerator();
1860
- const tsContent = await tsGenerator.generate(endpoints, {
1861
- title: openApiConfig.title,
1862
- version: openApiConfig.version,
1863
- description: openApiConfig.description
1864
- });
1865
- await writeFile(outputPath, tsContent);
1866
- logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
1867
- return {
1868
- outputPath,
1869
- endpointCount: loadedEndpoints.length
1870
- };
1871
- }
1872
- async function openapiCommand(options = {}) {
1873
- const logger = console;
1874
- try {
1875
- const loadedConfig = await loadWorkspaceConfig(options.cwd);
1876
- if (loadedConfig.type === "single") {
1877
- const config = loadedConfig.raw;
1878
- if (!config.openapi) config.openapi = { enabled: true };
1879
- const result = await generateOpenApi(config);
1880
- if (result) logger.log(`Found ${result.endpointCount} endpoints`);
1881
- } else {
1882
- const { workspace } = loadedConfig;
1883
- const workspaceRoot = workspace.root;
1884
- const backendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "backend" && app.routes !== void 0 && app.openapi !== false && (typeof app.openapi !== "object" || app.openapi.enabled !== false));
1885
- if (backendApps.length === 0) {
1886
- logger.log("No backend apps with OpenAPI enabled found");
1887
- return;
1888
- }
1889
- if (options.app) {
1890
- const entry = backendApps.find(([name]) => name === options.app);
1891
- if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
1892
- const [appName, app] = entry;
1893
- const result = await generateOpenApiForApp(workspaceRoot, appName, app);
1894
- if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
1895
- return;
1896
- }
1897
- for (const [appName, app] of backendApps) {
1898
- if (app.type !== "backend" || !app.routes) continue;
1899
- const appPath = join(workspaceRoot, app.path);
1900
- await runOpenApiInSubprocess(appPath, appName);
1901
- }
1902
- }
1903
- } catch (error) {
1904
- throw new Error(`OpenAPI generation failed: ${error.message}`);
1905
- }
1906
- }
1907
- /**
1908
- * Generate OpenAPI for a single named app within a workspace.
1909
- * Runs in-process. The caller is responsible for ensuring `process.cwd()`
1910
- * is the app's directory so tsx loads the app's tsconfig path aliases.
1911
- */
1912
- async function generateOpenApiForApp(workspaceRoot, _appName, app) {
1913
- if (app.type !== "backend" || !app.routes) return null;
1914
- const appPath = join(workspaceRoot, app.path);
1915
- const routes = normalizeRoutes(app.routes);
1916
- const routesGlob = routes.map((r) => join(appPath, r));
1917
- const gkmConfig = {
1918
- routes: routesGlob,
1919
- envParser: app.envParser || "",
1920
- logger: app.logger || "",
1921
- openapi: app.openapi
1922
- };
1923
- return generateOpenApi(gkmConfig, { silent: true });
1924
- }
1925
- /**
1926
- * Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
1927
- * to avoid depending on the built dist.
1928
- */
1929
- function resolveGkmBinPath() {
1930
- if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
1931
- return fileURLToPath(new URL("../bin/gkm.mjs", import.meta.url));
1932
- }
1933
- /**
1934
- * Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
1935
- * the app's directory. Inherits `NODE_OPTIONS` (which already contains
1936
- * `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
1937
- * discovery picks up the app's tsconfig path aliases.
1938
- */
1939
- async function runOpenApiInSubprocess(appCwd, appName) {
1940
- const binPath = resolveGkmBinPath();
1941
- await new Promise((resolve$1, reject) => {
1942
- const child = spawn(process.execPath, [
1943
- binPath,
1944
- "openapi",
1945
- "--app",
1946
- appName
1947
- ], {
1948
- cwd: appCwd,
1949
- stdio: "inherit",
1950
- env: process.env
1951
- });
1952
- child.on("error", reject);
1953
- child.on("close", (code) => {
1954
- if (code === 0) resolve$1();
1955
- else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
1956
- });
1957
- });
1958
- }
1816
+ export { EndpointGenerator as n, runtimeFor as r, OpenApiTsGenerator as t };
1959
1817
 
1960
- //#endregion
1961
- export { EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, normalizeRoutes, openapiCommand, resolveOpenApiConfig };
1962
- //# sourceMappingURL=openapi-CY9xFkTH.mjs.map
1818
+ //# sourceMappingURL=OpenApiTsGenerator-hDINScnz.mjs.map