@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,13 +1,8 @@
1
- const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const require_discover = require('./discover-DTmFeloL.cjs');
3
- const require_config = require('./config-BholeD-0.cjs');
4
- const node_path = require_chunk.__toESM(require("node:path"));
5
- const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
6
- const node_child_process = require_chunk.__toESM(require("node:child_process"));
7
- const __geekmidas_constructs_endpoints = require_chunk.__toESM(require("@geekmidas/constructs/endpoints"));
8
- const node_url = require_chunk.__toESM(require("node:url"));
9
- const __geekmidas_schema_conversion = require_chunk.__toESM(require("@geekmidas/schema/conversion"));
10
-
1
+ const require_discover = require("./discover-CroTIm0K.cjs");
2
+ let node_fs_promises = require("node:fs/promises");
3
+ let node_path = require("node:path");
4
+ let _geekmidas_constructs_endpoints = require("@geekmidas/constructs/endpoints");
5
+ let _geekmidas_schema_conversion = require("@geekmidas/schema/conversion");
11
6
  //#region src/build/endpoint-analyzer.ts
12
7
  /**
13
8
  * Analyze an endpoint to extract its features
@@ -84,7 +79,6 @@ function summarizeAnalysis(analyses) {
84
79
  byFeature
85
80
  };
86
81
  }
87
-
88
82
  //#endregion
89
83
  //#region src/build/handler-templates.ts
90
84
  /**
@@ -106,8 +100,7 @@ function generateMinimalHandler(analysis) {
106
100
  const { exportName, features } = analysis;
107
101
  const method = analysis.method.toLowerCase();
108
102
  const validators = generateValidators(exportName, features);
109
- const hasValidators = validators.length > 0;
110
- if (!hasValidators && !features.hasOutputValidation) return `
103
+ if (!(validators.length > 0) && !features.hasOutputValidation) return `
111
104
  // Minimal handler: ${analysis.route} (${analysis.method})
112
105
  app.${method}('${analysis.route}', async (c) => {
113
106
  const result = await ${exportName}.handler(
@@ -255,10 +248,10 @@ function generateValidatorsFile(analyses) {
255
248
  const needsQuery = analyses.some((a) => a.features.hasQueryValidation);
256
249
  const needsParams = analyses.some((a) => a.features.hasParamValidation);
257
250
  if (!needsBody && !needsQuery && !needsParams) return `// No validators needed for this build\nexport {};\n`;
258
- const exports$1 = [];
251
+ const exports = [];
259
252
  const factories = [];
260
253
  if (needsBody) {
261
- exports$1.push("validateBody");
254
+ exports.push("validateBody");
262
255
  factories.push(`
263
256
  export const validateBody = (endpoint: any) =>
264
257
  validator('json', async (value, c) => {
@@ -269,7 +262,7 @@ export const validateBody = (endpoint: any) =>
269
262
  });`);
270
263
  }
271
264
  if (needsQuery) {
272
- exports$1.push("validateQuery");
265
+ exports.push("validateQuery");
273
266
  factories.push(`
274
267
  export const validateQuery = (endpoint: any) =>
275
268
  validator('query', async (_, c) => {
@@ -281,7 +274,7 @@ export const validateQuery = (endpoint: any) =>
281
274
  });`);
282
275
  }
283
276
  if (needsParams) {
284
- exports$1.push("validateParams");
277
+ exports.push("validateParams");
285
278
  factories.push(`
286
279
  export const validateParams = (endpoint: any) =>
287
280
  validator('param', async (params, c) => {
@@ -305,8 +298,7 @@ ${factories.join("\n")}
305
298
  */
306
299
  function generateMinimalEndpointFile(analysis, endpointImport) {
307
300
  const { exportName, features } = analysis;
308
- const needsValidators = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation;
309
- const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
301
+ const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
310
302
  const handler = generateMinimalHandler(analysis);
311
303
  return `/**
312
304
  * Minimal endpoint: ${analysis.route} (${analysis.method})
@@ -331,8 +323,7 @@ ${handler}
331
323
  */
332
324
  function generateStandardEndpointFile(analysis, endpointImport) {
333
325
  const { exportName, features } = analysis;
334
- const needsValidators = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation;
335
- const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
326
+ const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
336
327
  const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
337
328
  const handler = generateStandardHandler(analysis);
338
329
  return `/**
@@ -424,7 +415,7 @@ export function setupFullEndpoints(
424
415
  }
425
416
  const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
426
417
  if (tier === "minimal") {
427
- 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");
428
419
  return `/**
429
420
  * Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
430
421
  * Near-raw-Hono performance
@@ -437,12 +428,12 @@ export function setupMinimalEndpoints(
437
428
  app: Hono,
438
429
  logger: Logger,
439
430
  ): void {
440
- ${calls$1}
431
+ ${calls}
441
432
  }
442
433
  `;
443
434
  }
444
435
  if (tier === "standard") {
445
- 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");
446
437
  return `/**
447
438
  * Standard-tier endpoint index (${tierEndpoints.length} endpoints)
448
439
  * Auth and/or services enabled
@@ -457,7 +448,7 @@ export function setupStandardEndpoints(
457
448
  serviceDiscovery: ServiceDiscovery<any, any>,
458
449
  logger: Logger,
459
450
  ): void {
460
- ${calls$1}
451
+ ${calls}
461
452
  }
462
453
  `;
463
454
  }
@@ -527,9 +518,7 @@ function generateEndpointFilesNested(analyses, endpointImports) {
527
518
  case "standard":
528
519
  files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
529
520
  break;
530
- case "full":
531
- files[fileName] = generateFullEndpointFile(analysis, endpointImport);
532
- break;
521
+ case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
533
522
  }
534
523
  }
535
524
  return files;
@@ -586,7 +575,6 @@ export async function setupEndpoints(
586
575
  }
587
576
  `;
588
577
  }
589
-
590
578
  //#endregion
591
579
  //#region src/generators/EndpointGenerator.ts
592
580
  /**
@@ -603,24 +591,21 @@ export async function setupEndpoints(
603
591
  *
604
592
  * Falls back to the configured paths for an app that declares no surface.
605
593
  */
606
- function runtimeFor(context, fromDir) {
607
- const module$1 = context.surface?.module;
608
- if (module$1) {
609
- const specifier = importSpecifier(fromDir, module$1.specifier);
594
+ function runtimeFor(context, fromDir, owner) {
595
+ const module = owner ? context.owners?.[owner] ?? context.surface?.module : context.surface?.module;
596
+ if (module) {
597
+ const specifier = importSpecifier(fromDir, module.specifier);
610
598
  return {
611
- imports: `import { ${module$1.exportName} as __surface } from '${specifier}';`,
599
+ imports: `import { ${module.exportName} as __surface } from '${specifier}';`,
612
600
  bindings: [
613
- "// What this surface was declared with. Objects, not module paths:",
614
- "// 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.",
615
603
  "const envParser = __surface.envParser;",
616
604
  "const logger = __surface.logger;"
617
605
  ].join("\n")
618
606
  };
619
607
  }
620
- return {
621
- imports: [`import ${context.envParserImportPattern} from '${importSpecifier(fromDir, context.envParserPath)}';`, `import ${context.loggerImportPattern} from '${importSpecifier(fromDir, context.loggerPath)}';`].join("\n"),
622
- bindings: ""
623
- };
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\`.`);
624
609
  }
625
610
  /** A relative specifier ESM will accept: always prefixed, never bare. */
626
611
  function importSpecifier(fromDir, target) {
@@ -679,7 +664,7 @@ function corsFor(surface) {
679
664
  }
680
665
  var EndpointGenerator = class extends require_discover.ConstructGenerator {
681
666
  isConstruct(value) {
682
- return __geekmidas_constructs_endpoints.Endpoint.isEndpoint(value);
667
+ return _geekmidas_constructs_endpoints.Endpoint.isEndpoint(value);
683
668
  }
684
669
  async build(context, constructs, outputDir, options) {
685
670
  const provider = options?.provider || "aws-apigatewayv2";
@@ -735,8 +720,7 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
735
720
  async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
736
721
  const handlerFileName = `${exportName}.ts`;
737
722
  const handlerPath = (0, node_path.join)(outputDir, handlerFileName);
738
- const relativePath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile);
739
- const importPath = relativePath.replace(/\.ts$/, ".js");
723
+ const importPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile).replace(/\.ts$/, ".js");
740
724
  let content;
741
725
  switch (provider) {
742
726
  case "aws-apigatewayv1":
@@ -754,16 +738,14 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
754
738
  return handlerPath;
755
739
  }
756
740
  async generateEndpointsFile(outputDir, endpoints, context) {
757
- const endpointsFileName = "endpoints.ts";
758
- const endpointsPath = (0, node_path.join)(outputDir, endpointsFileName);
741
+ const endpointsPath = (0, node_path.join)(outputDir, "endpoints.ts");
759
742
  const importsByFile = /* @__PURE__ */ new Map();
760
743
  for (const { path, key } of endpoints) {
761
- const relativePath = (0, node_path.relative)((0, node_path.dirname)(endpointsPath), path.relative);
762
- const importPath = relativePath.replace(/\.ts$/, ".js");
744
+ const importPath = (0, node_path.relative)((0, node_path.dirname)(endpointsPath), path.relative).replace(/\.ts$/, ".js");
763
745
  if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
764
746
  importsByFile.get(importPath)?.push(key);
765
747
  }
766
- const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports$1]) => `import { ${exports$1.join(", ")} } from '${importPath}';`).join("\n");
748
+ const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n");
767
749
  const allExportNames = endpoints.map(({ key }) => key);
768
750
  if (context.production?.enabled && context.production.optimizedHandlers) return this.generateOptimizedEndpointsFile(endpointsPath, endpoints, endpointImports, allExportNames);
769
751
  const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
@@ -825,11 +807,9 @@ export async function setupEndpoints(
825
807
  const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
826
808
  const endpointImports = endpoints.map(({ key, path }) => {
827
809
  const tierDir = (0, node_path.join)(endpointsDir, "standard");
828
- const relativePath = (0, node_path.relative)(tierDir, path.relative);
829
- const importPath = relativePath.replace(/\.ts$/, ".js");
830
810
  return {
831
811
  exportName: key,
832
- importPath
812
+ importPath: (0, node_path.relative)(tierDir, path.relative).replace(/\.ts$/, ".js")
833
813
  };
834
814
  });
835
815
  const summary = summarizeAnalysis(analyses);
@@ -851,8 +831,7 @@ export async function setupEndpoints(
851
831
  }
852
832
  async generateAppFile(outputDir, context) {
853
833
  if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
854
- const appFileName = "app.ts";
855
- const appPath = (0, node_path.join)(outputDir, appFileName);
834
+ const appPath = (0, node_path.join)(outputDir, "app.ts");
856
835
  const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
857
836
  const telescopeEnabled = context.telescope?.enabled;
858
837
  const telescopeWebSocketEnabled = context.telescope?.websocket;
@@ -862,32 +841,36 @@ export async function setupEndpoints(
862
841
  const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
863
842
  const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
864
843
  let telescopeImports = "";
865
- if (telescopeEnabled) if (telescopeFromSurface) telescopeImports = "import { createMiddleware, createUI } from '@geekmidas/telescope/hono';";
866
- else if (usesExternalTelescope) {
867
- const relativeTelescopePath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.telescope?.telescopePath);
868
- telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
844
+ if (telescopeEnabled) {
845
+ if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
869
846
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
870
- } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
847
+ else if (usesExternalTelescope) {
848
+ const relativeTelescopePath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.telescope?.telescopePath);
849
+ telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
871
850
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
851
+ } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
852
+ import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
853
+ }
872
854
  let studioImports = "";
873
- if (studioEnabled) if (usesExternalStudio) {
874
- const relativeStudioPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.studio?.studioPath);
875
- studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
855
+ if (studioEnabled) {
856
+ if (usesExternalStudio) {
857
+ const relativeStudioPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.studio?.studioPath);
858
+ studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
876
859
  import { createStudioApp } from '@geekmidas/studio/server/hono';`;
877
- } else if (studioFromDatabase) {
878
- const dbSpecifier = importSpecifier((0, node_path.dirname)(appPath), context.studio.database.specifier);
879
- studioImports = `import { snifferContext } from '@geekmidas/constructs';
860
+ } else if (studioFromDatabase) {
861
+ const dbSpecifier = importSpecifier((0, node_path.dirname)(appPath), context.studio.database.specifier);
862
+ studioImports = `import { snifferContext } from '@geekmidas/constructs';
880
863
  import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
881
864
  import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
882
865
  import { createStudioApp } from '@geekmidas/studio/server/hono';`;
883
- } else studioImports = "";
866
+ } else studioImports = "";
867
+ }
884
868
  const cors = corsFor(context.surface);
885
869
  let hooksImports = "";
886
870
  let beforeSetupCall = "";
887
871
  let afterSetupCall = "";
888
872
  if (context.hooks?.serverHooksPath) {
889
- const relativeHooksPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath);
890
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
873
+ hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
891
874
  beforeSetupCall = `
892
875
  // Call beforeSetup hook if defined
893
876
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -933,7 +916,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
933
916
  }
934
917
  ` : "";
935
918
  let telescopeSetup = "";
936
- if (telescopeEnabled) if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
919
+ if (telescopeEnabled) {
920
+ if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
937
921
  ${telescopeWebSocketSetupCode}
938
922
  // Add telescope middleware (before endpoints to capture all requests)
939
923
  honoApp.use('*', createMiddleware(telescope));
@@ -942,7 +926,7 @@ ${telescopeWebSocketSetupCode}
942
926
  const telescopeUI = createUI(telescope);
943
927
  honoApp.route('${context.telescope?.path}', telescopeUI);
944
928
  `;
945
- else telescopeSetup = `
929
+ else telescopeSetup = `
946
930
  // Setup Telescope for debugging/monitoring
947
931
  const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
948
932
  const telescope = new Telescope({
@@ -960,6 +944,7 @@ ${telescopeWebSocketSetupCode}
960
944
  const telescopeUI = createUI(telescope);
961
945
  honoApp.route('${context.telescope?.path}', telescopeUI);
962
946
  `;
947
+ }
963
948
  let studioSetup = "";
964
949
  if (studioEnabled && studioFromDatabase) studioSetup = `
965
950
  // Studio, built from the declared database. The client comes from the
@@ -993,6 +978,7 @@ import type { Hono as HonoType } from 'hono';
993
978
  import { setupEndpoints } from './endpoints.js';
994
979
  import { setupSubscribers } from './subscribers.js';
995
980
  import { setupQueues } from './queues.js';
981
+ import { setupCrons } from './crons.js';
996
982
  ${runtime.imports}
997
983
  ${telescopeImports}
998
984
  ${studioImports}
@@ -1001,7 +987,16 @@ ${cors.imports}
1001
987
  ${context.storageDrivers?.imports ?? ""}
1002
988
 
1003
989
  ${runtime.bindings}
1004
- ${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
+ });` : ""}
1005
1000
 
1006
1001
  ${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
1007
1002
  // each injected URL picks one, so no construct and no application module names
@@ -1080,6 +1075,12 @@ ${afterSetupCall}
1080
1075
  logger.error({ error }, 'Failed to start queue workers');
1081
1076
  });
1082
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
+
1083
1084
  logger.info({ port }, 'Starting server');
1084
1085
 
1085
1086
  // Start HTTP server using provided serve function
@@ -1148,10 +1149,8 @@ export const handler = ${exportName};
1148
1149
  * No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
1149
1150
  */
1150
1151
  async generateProductionAppFile(outputDir, context) {
1151
- const appFileName = "app.ts";
1152
- const appPath = (0, node_path.join)(outputDir, appFileName);
1153
- const relativeLoggerPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.loggerPath);
1154
- const relativeEnvParserPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.envParserPath);
1152
+ const appPath = (0, node_path.join)(outputDir, "app.ts");
1153
+ const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
1155
1154
  const production = context.production;
1156
1155
  const healthCheckPath = production.healthCheck;
1157
1156
  const enableGracefulShutdown = production.gracefulShutdown;
@@ -1162,8 +1161,7 @@ export const handler = ${exportName};
1162
1161
  let beforeSetupCall = "";
1163
1162
  let afterSetupCall = "";
1164
1163
  if (context.hooks?.serverHooksPath) {
1165
- const relativeHooksPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath);
1166
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
1164
+ hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
1167
1165
  beforeSetupCall = `
1168
1166
  // Call beforeSetup hook if defined
1169
1167
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -1187,9 +1185,16 @@ export const handler = ${exportName};
1187
1185
  await setupQueues(envParser, logger).catch((error) => {
1188
1186
  logger.error({ error }, 'Failed to start queue workers');
1189
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
+ });
1190
1194
  ` : "";
1191
1195
  const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
1192
- import { setupQueues } from './queues.js';` : "";
1196
+ import { setupQueues } from './queues.js';
1197
+ import { setupCrons } from './crons.js';` : "";
1193
1198
  const gracefulShutdownCode = enableGracefulShutdown ? `
1194
1199
  // Graceful shutdown handling
1195
1200
  let isShuttingDown = false;
@@ -1205,7 +1210,6 @@ import { setupQueues } from './queues.js';` : "";
1205
1210
  process.on('SIGTERM', shutdown);
1206
1211
  process.on('SIGINT', shutdown);
1207
1212
  ` : "";
1208
- const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
1209
1213
  const content = `/**
1210
1214
  * Generated production server application
1211
1215
  *
@@ -1217,10 +1221,10 @@ import { setupQueues } from './queues.js';` : "";
1217
1221
  */
1218
1222
  import { Hono } from 'hono';
1219
1223
  import type { Hono as HonoType } from 'hono';
1220
- import { setupEndpoints } from '${endpointsImportPath}';
1224
+ import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
1221
1225
  ${subscriberImport}
1222
- import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
1223
- import ${context.loggerImportPattern} from '${relativeLoggerPath}';
1226
+ ${runtime.imports}
1227
+ ${runtime.bindings}
1224
1228
  ${hooksImports}
1225
1229
  ${cors.imports}
1226
1230
  ${context.storageDrivers?.imports ?? ""}
@@ -1284,7 +1288,7 @@ export default createApp;
1284
1288
  */
1285
1289
  async generateProductionServerEntry(outputDir) {
1286
1290
  const serverPath = (0, node_path.join)(outputDir, "server.ts");
1287
- const content = `#!/usr/bin/env node
1291
+ await (0, node_fs_promises.writeFile)(serverPath, `#!/usr/bin/env node
1288
1292
  /**
1289
1293
  * Production server entry point
1290
1294
  * Generated by 'gkm build --provider server --production'
@@ -1300,11 +1304,9 @@ await start({
1300
1304
  port,
1301
1305
  serve: (app, port) => { serve({ fetch: app.fetch, port }); },
1302
1306
  });
1303
- `;
1304
- await (0, node_fs_promises.writeFile)(serverPath, content);
1307
+ `);
1305
1308
  }
1306
1309
  };
1307
-
1308
1310
  //#endregion
1309
1311
  //#region src/generators/OpenApiTsGenerator.ts
1310
1312
  /**
@@ -1455,11 +1457,11 @@ var OpenApiTsGenerator = class {
1455
1457
  }
1456
1458
  }
1457
1459
  }
1458
- const registrySchemas = await (0, __geekmidas_schema_conversion.getRegisteredZodJsonSchemas)();
1460
+ const registrySchemas = await (0, _geekmidas_schema_conversion.getRegisteredZodJsonSchemas)();
1459
1461
  for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
1460
1462
  const defName = this.pascalCase(rawName);
1461
1463
  if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
1462
- const { id: _id, $defs: _defs,...rest } = rawSchema;
1464
+ const { id: _id, $defs: _defs, ...rest } = rawSchema;
1463
1465
  collectedDefs.set(defName, rest);
1464
1466
  }
1465
1467
  for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
@@ -1475,7 +1477,7 @@ var OpenApiTsGenerator = class {
1475
1477
  */
1476
1478
  async getSchemaName(schema, defaultName) {
1477
1479
  try {
1478
- const metadata = await (0, __geekmidas_schema_conversion.getSchemaMetadata)(schema);
1480
+ const metadata = await (0, _geekmidas_schema_conversion.getSchemaMetadata)(schema);
1479
1481
  if (metadata?.id) return this.pascalCase(metadata.id);
1480
1482
  } catch {}
1481
1483
  return defaultName;
@@ -1495,27 +1497,29 @@ var OpenApiTsGenerator = class {
1495
1497
  async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
1496
1498
  try {
1497
1499
  const vendor = schema["~standard"]?.vendor;
1498
- if (!vendor || !(vendor in __geekmidas_schema_conversion.StandardSchemaJsonSchema)) return null;
1499
- const toJsonSchema = __geekmidas_schema_conversion.StandardSchemaJsonSchema[vendor];
1500
+ if (!vendor || !(vendor in _geekmidas_schema_conversion.StandardSchemaJsonSchema)) return unknownType(name);
1501
+ const toJsonSchema = _geekmidas_schema_conversion.StandardSchemaJsonSchema[vendor];
1500
1502
  const jsonSchema = await toJsonSchema(schema);
1501
- if (!jsonSchema) return null;
1503
+ if (!jsonSchema) return unknownType(name);
1502
1504
  if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
1503
1505
  for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
1504
- const { id,...schemaWithoutId } = defSchema;
1506
+ const { id, ...schemaWithoutId } = defSchema;
1505
1507
  collectedDefs.set(defName, schemaWithoutId);
1506
1508
  }
1507
1509
  }
1508
- 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
+ }
1509
1516
  return this.jsonSchemaToInterface(schemaWithoutDefs, name);
1510
1517
  } catch {
1511
- return null;
1518
+ return unknownType(name);
1512
1519
  }
1513
1520
  }
1514
1521
  jsonSchemaToInterface(schema, name) {
1515
- if (schema.type !== "object" || !schema.properties) {
1516
- const typeStr = this.jsonSchemaTypeToTs(schema);
1517
- return `export type ${name} = ${typeStr};`;
1518
- }
1522
+ if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
1519
1523
  const props = [];
1520
1524
  const required = new Set(schema.required || []);
1521
1525
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
@@ -1528,13 +1532,15 @@ var OpenApiTsGenerator = class {
1528
1532
  }
1529
1533
  jsonSchemaTypeToTs(schema) {
1530
1534
  if (!schema) return "unknown";
1531
- if (schema.$ref) {
1532
- const refName = schema.$ref.split("/").pop() || "unknown";
1533
- return refName;
1534
- }
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);
1535
1537
  if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1536
1538
  if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1537
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(" | ");
1538
1544
  switch (schema.type) {
1539
1545
  case "string":
1540
1546
  if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
@@ -1558,10 +1564,7 @@ var OpenApiTsGenerator = class {
1558
1564
  }
1559
1565
  return `{ ${props.join("; ")} }`;
1560
1566
  }
1561
- if (schema.additionalProperties) {
1562
- const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
1563
- return `Record<string, ${valueType}>`;
1564
- }
1567
+ if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
1565
1568
  return "Record<string, unknown>";
1566
1569
  default: return "unknown";
1567
1570
  }
@@ -1582,10 +1585,7 @@ var OpenApiTsGenerator = class {
1582
1585
  }
1583
1586
  const firstWithParams = infos.find((i) => i.input?.params);
1584
1587
  let paramsEntry = "";
1585
- if (firstWithParams?.input?.params) {
1586
- const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
1587
- paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
1588
- }
1588
+ if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
1589
1589
  pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
1590
1590
  }
1591
1591
  return `export interface paths {\n${pathEntries.join("\n")}\n}`;
@@ -1624,8 +1624,7 @@ var OpenApiTsGenerator = class {
1624
1624
  return acc;
1625
1625
  }, {});
1626
1626
  const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
1627
- const hasSecuritySchemes = schemeNames.length > 0;
1628
- const createApiSection = hasSecuritySchemes ? `
1627
+ const createApiSection = schemeNames.length > 0 ? `
1629
1628
  // ============================================================
1630
1629
  // API Client Factory
1631
1630
  // ============================================================
@@ -1649,6 +1648,8 @@ export interface CreateApiOptions {
1649
1648
  queryClient?: QueryClient;
1650
1649
  /** Optional request interceptor */
1651
1650
  onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
1651
+ /** The \`fetch\` requests go out on — a test browser's, for one */
1652
+ fetch?: typeof fetch;
1652
1653
  }
1653
1654
 
1654
1655
  /**
@@ -1678,6 +1679,7 @@ export function createApi(options: CreateApiOptions) {
1678
1679
  securitySchemes,
1679
1680
  authStrategies: options.authStrategies,
1680
1681
  onRequest: options.onRequest,
1682
+ ...(options.fetch ? { fetch: options.fetch } : {}),
1681
1683
  });
1682
1684
 
1683
1685
  const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
@@ -1802,197 +1804,32 @@ ${createApiSection}
1802
1804
  `;
1803
1805
  }
1804
1806
  };
1805
-
1806
- //#endregion
1807
- //#region src/workspace/client-generator.ts
1808
1807
  /**
1809
- * Normalize routes to an array of patterns.
1810
- * Handles string, string[], and PartitionedRoutes (extracts paths).
1811
- * @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.
1812
1811
  */
1813
- function normalizeRoutes(routes) {
1814
- if (!routes) return [];
1815
- if (require_discover.isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
1816
- return Array.isArray(routes) ? routes : [routes];
1812
+ function unknownType(name) {
1813
+ return `export type ${name} = unknown;`;
1817
1814
  }
1818
-
1819
1815
  //#endregion
1820
- //#region src/openapi.ts
1821
- /**
1822
- * Default output path for generated OpenAPI client (used for single-app configs)
1823
- */
1824
- const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
1825
- /**
1826
- * Resolve OpenAPI config from GkmConfig
1827
- */
1828
- function resolveOpenApiConfig(config) {
1829
- if (config.openapi === false) return { enabled: false };
1830
- if (config.openapi === true || config.openapi === void 0) return {
1831
- enabled: true,
1832
- title: "API Documentation",
1833
- version: "1.0.0",
1834
- description: "Auto-generated API documentation from endpoints"
1835
- };
1836
- return {
1837
- enabled: config.openapi.enabled !== false,
1838
- title: config.openapi.title || "API Documentation",
1839
- version: config.openapi.version || "1.0.0",
1840
- description: config.openapi.description || "Auto-generated API documentation from endpoints"
1841
- };
1842
- }
1843
- /**
1844
- * Generate OpenAPI spec from endpoints
1845
- * @returns Object with output path and endpoint count, or null if disabled
1846
- */
1847
- async function generateOpenApi(config, options = {}) {
1848
- const logger = options.silent ? { log: () => {} } : console;
1849
- const openApiConfig = resolveOpenApiConfig(config);
1850
- if (!openApiConfig.enabled) return null;
1851
- const endpointGenerator = new EndpointGenerator();
1852
- const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
1853
- if (loadedEndpoints.length === 0) {
1854
- logger.log("No valid endpoints found for OpenAPI generation");
1855
- return null;
1856
- }
1857
- const endpoints = loadedEndpoints.map(({ construct }) => construct);
1858
- const outputPath = (0, node_path.join)(process.cwd(), OPENAPI_OUTPUT_PATH);
1859
- await (0, node_fs_promises.mkdir)((0, node_path.dirname)(outputPath), { recursive: true });
1860
- const tsGenerator = new OpenApiTsGenerator();
1861
- const tsContent = await tsGenerator.generate(endpoints, {
1862
- title: openApiConfig.title,
1863
- version: openApiConfig.version,
1864
- description: openApiConfig.description
1865
- });
1866
- await (0, node_fs_promises.writeFile)(outputPath, tsContent);
1867
- logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
1868
- return {
1869
- outputPath,
1870
- endpointCount: loadedEndpoints.length
1871
- };
1872
- }
1873
- async function openapiCommand(options = {}) {
1874
- const logger = console;
1875
- try {
1876
- const loadedConfig = await require_config.loadWorkspaceConfig(options.cwd);
1877
- if (loadedConfig.type === "single") {
1878
- const config = loadedConfig.raw;
1879
- if (!config.openapi) config.openapi = { enabled: true };
1880
- const result = await generateOpenApi(config);
1881
- if (result) logger.log(`Found ${result.endpointCount} endpoints`);
1882
- } else {
1883
- const { workspace } = loadedConfig;
1884
- const workspaceRoot = workspace.root;
1885
- 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));
1886
- if (backendApps.length === 0) {
1887
- logger.log("No backend apps with OpenAPI enabled found");
1888
- return;
1889
- }
1890
- if (options.app) {
1891
- const entry = backendApps.find(([name]) => name === options.app);
1892
- if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
1893
- const [appName, app] = entry;
1894
- const result = await generateOpenApiForApp(workspaceRoot, appName, app);
1895
- if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
1896
- return;
1897
- }
1898
- for (const [appName, app] of backendApps) {
1899
- if (app.type !== "backend" || !app.routes) continue;
1900
- const appPath = (0, node_path.join)(workspaceRoot, app.path);
1901
- await runOpenApiInSubprocess(appPath, appName);
1902
- }
1903
- }
1904
- } catch (error) {
1905
- throw new Error(`OpenAPI generation failed: ${error.message}`);
1816
+ Object.defineProperty(exports, "EndpointGenerator", {
1817
+ enumerable: true,
1818
+ get: function() {
1819
+ return EndpointGenerator;
1906
1820
  }
1907
- }
1908
- /**
1909
- * Generate OpenAPI for a single named app within a workspace.
1910
- * Runs in-process. The caller is responsible for ensuring `process.cwd()`
1911
- * is the app's directory so tsx loads the app's tsconfig path aliases.
1912
- */
1913
- async function generateOpenApiForApp(workspaceRoot, _appName, app) {
1914
- if (app.type !== "backend" || !app.routes) return null;
1915
- const appPath = (0, node_path.join)(workspaceRoot, app.path);
1916
- const routes = normalizeRoutes(app.routes);
1917
- const routesGlob = routes.map((r) => (0, node_path.join)(appPath, r));
1918
- const gkmConfig = {
1919
- routes: routesGlob,
1920
- envParser: app.envParser || "",
1921
- logger: app.logger || "",
1922
- openapi: app.openapi
1923
- };
1924
- return generateOpenApi(gkmConfig, { silent: true });
1925
- }
1926
- /**
1927
- * Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
1928
- * to avoid depending on the built dist.
1929
- */
1930
- function resolveGkmBinPath() {
1931
- if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
1932
- return (0, node_url.fileURLToPath)(new URL("../bin/gkm.mjs", require("url").pathToFileURL(__filename).href));
1933
- }
1934
- /**
1935
- * Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
1936
- * the app's directory. Inherits `NODE_OPTIONS` (which already contains
1937
- * `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
1938
- * discovery picks up the app's tsconfig path aliases.
1939
- */
1940
- async function runOpenApiInSubprocess(appCwd, appName) {
1941
- const binPath = resolveGkmBinPath();
1942
- await new Promise((resolve, reject) => {
1943
- const child = (0, node_child_process.spawn)(process.execPath, [
1944
- binPath,
1945
- "openapi",
1946
- "--app",
1947
- appName
1948
- ], {
1949
- cwd: appCwd,
1950
- stdio: "inherit",
1951
- env: process.env
1952
- });
1953
- child.on("error", reject);
1954
- child.on("close", (code) => {
1955
- if (code === 0) resolve();
1956
- else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
1957
- });
1958
- });
1959
- }
1960
-
1961
- //#endregion
1962
- Object.defineProperty(exports, 'EndpointGenerator', {
1963
- enumerable: true,
1964
- get: function () {
1965
- return EndpointGenerator;
1966
- }
1967
- });
1968
- Object.defineProperty(exports, 'OPENAPI_OUTPUT_PATH', {
1969
- enumerable: true,
1970
- get: function () {
1971
- return OPENAPI_OUTPUT_PATH;
1972
- }
1973
1821
  });
1974
- Object.defineProperty(exports, 'generateOpenApi', {
1975
- enumerable: true,
1976
- get: function () {
1977
- return generateOpenApi;
1978
- }
1979
- });
1980
- Object.defineProperty(exports, 'normalizeRoutes', {
1981
- enumerable: true,
1982
- get: function () {
1983
- return normalizeRoutes;
1984
- }
1985
- });
1986
- Object.defineProperty(exports, 'openapiCommand', {
1987
- enumerable: true,
1988
- get: function () {
1989
- return openapiCommand;
1990
- }
1822
+ Object.defineProperty(exports, "OpenApiTsGenerator", {
1823
+ enumerable: true,
1824
+ get: function() {
1825
+ return OpenApiTsGenerator;
1826
+ }
1991
1827
  });
1992
- Object.defineProperty(exports, 'resolveOpenApiConfig', {
1993
- enumerable: true,
1994
- get: function () {
1995
- return resolveOpenApiConfig;
1996
- }
1828
+ Object.defineProperty(exports, "runtimeFor", {
1829
+ enumerable: true,
1830
+ get: function() {
1831
+ return runtimeFor;
1832
+ }
1997
1833
  });
1998
- //# sourceMappingURL=openapi-c9bpieI5.cjs.map
1834
+
1835
+ //# sourceMappingURL=OpenApiTsGenerator-D1nhN98m.cjs.map