@geekmidas/cli 10.0.0-alpha.5 → 10.0.0-alpha.50

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 (267) hide show
  1. package/README.md +196 -257
  2. package/bin/adjacent-tsconfig.mjs +97 -0
  3. package/bin/gkm.mjs +16 -2
  4. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  5. package/bin/owning-tsconfig-jsx.mjs +108 -0
  6. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-BZFGYYVA.cjs} +21 -22
  7. package/dist/HostingerProvider-BZFGYYVA.cjs.map +1 -0
  8. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-GF6NAZAK.mjs} +20 -21
  9. package/dist/HostingerProvider-GF6NAZAK.mjs.map +1 -0
  10. package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
  11. package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
  12. package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
  13. package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
  14. package/dist/{openapi-CA0yJUTN.cjs → OpenApiTsGenerator-BN0PIZxd.cjs} +157 -372
  15. package/dist/OpenApiTsGenerator-BN0PIZxd.cjs.map +1 -0
  16. package/dist/{openapi-kkQbsRVj.mjs → OpenApiTsGenerator-BzIGy8KE.mjs} +128 -324
  17. package/dist/OpenApiTsGenerator-BzIGy8KE.mjs.map +1 -0
  18. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
  19. package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
  20. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
  21. package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
  22. package/dist/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
  23. package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
  24. package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
  25. package/dist/SSMStateProvider-VrQ-yeqd.cjs.map +1 -0
  26. package/dist/aws-DkHdTV-p.cjs +61 -0
  27. package/dist/aws-DkHdTV-p.cjs.map +1 -0
  28. package/dist/aws-DojzQnLd.mjs +61 -0
  29. package/dist/aws-DojzQnLd.mjs.map +1 -0
  30. package/dist/backends-B9V2XD2M.cjs +82 -0
  31. package/dist/backends-B9V2XD2M.cjs.map +1 -0
  32. package/dist/backends-CSuLl0YP.mjs +59 -0
  33. package/dist/backends-CSuLl0YP.mjs.map +1 -0
  34. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
  35. package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
  36. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
  37. package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
  38. package/dist/{bundler-Be8Zg4Wd.mjs → bundler--fyybf1N.mjs} +19 -30
  39. package/dist/bundler--fyybf1N.mjs.map +1 -0
  40. package/dist/{bundler-BY1OmV1e.cjs → bundler-By6_sXiL.cjs} +20 -32
  41. package/dist/bundler-By6_sXiL.cjs.map +1 -0
  42. package/dist/{config-C21ocYNd.cjs → config-CsYSyUya.cjs} +209 -210
  43. package/dist/config-CsYSyUya.cjs.map +1 -0
  44. package/dist/{config-WRdsQYZK.mjs → config-D8J5rrTb.mjs} +142 -154
  45. package/dist/config-D8J5rrTb.mjs.map +1 -0
  46. package/dist/config.cjs +9 -6
  47. package/dist/config.d.cts +62 -33
  48. package/dist/config.d.cts.map +1 -1
  49. package/dist/config.d.mts +62 -33
  50. package/dist/config.d.mts.map +1 -1
  51. package/dist/config.mjs +3 -5
  52. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  53. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  54. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  55. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  56. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  57. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  58. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  59. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  60. package/dist/deploy/sniffer-hooks.cjs +13 -7
  61. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  62. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  63. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  64. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  65. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  66. package/dist/deploy/sniffer-hooks.mjs +9 -2
  67. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  68. package/dist/deploy/sniffer-loader.cjs +16 -7
  69. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  70. package/dist/deploy/sniffer-loader.d.cts +1 -1
  71. package/dist/deploy/sniffer-loader.d.mts +1 -1
  72. package/dist/deploy/sniffer-loader.mjs +13 -2
  73. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  74. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  75. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  76. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  77. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  78. package/dist/deploy/sniffer-routes-worker.mjs +3 -3
  79. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  80. package/dist/deploy/sniffer-worker.cjs +15 -6
  81. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  82. package/dist/deploy/sniffer-worker.d.cts +1 -3
  83. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  84. package/dist/deploy/sniffer-worker.d.mts +1 -3
  85. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  86. package/dist/deploy/sniffer-worker.mjs +15 -4
  87. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  88. package/dist/{discover-CAlFgYec.mjs → discover-Cf2jAcgF.mjs} +56 -63
  89. package/dist/discover-Cf2jAcgF.mjs.map +1 -0
  90. package/dist/{discover-DTmFeloL.cjs → discover-DXNviAh-.cjs} +86 -110
  91. package/dist/discover-DXNviAh-.cjs.map +1 -0
  92. package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
  93. package/dist/emit-C1e8qD08.mjs.map +1 -0
  94. package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
  95. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  96. package/dist/encryption-C7OGMve_.cjs +91 -0
  97. package/dist/encryption-C7OGMve_.cjs.map +1 -0
  98. package/dist/encryption-DyQnPsZN.mjs +90 -0
  99. package/dist/encryption-DyQnPsZN.mjs.map +1 -0
  100. package/dist/github-BfpadQWQ.mjs +213 -0
  101. package/dist/github-BfpadQWQ.mjs.map +1 -0
  102. package/dist/github-BrI1tv6u.cjs +213 -0
  103. package/dist/github-BrI1tv6u.cjs.map +1 -0
  104. package/dist/{index-CHB4tSzX.d.cts → index-BQhJXpaQ.d.mts} +4 -23
  105. package/dist/index-BQhJXpaQ.d.mts.map +1 -0
  106. package/dist/{index-BThUzEIp.d.mts → index-DHJePE0y.d.cts} +4 -23
  107. package/dist/index-DHJePE0y.d.cts.map +1 -0
  108. package/dist/index.cjs +9531 -7200
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.d.cts +1 -1
  111. package/dist/index.d.mts +1 -1
  112. package/dist/index.mjs +9412 -7108
  113. package/dist/index.mjs.map +1 -1
  114. package/dist/migrate-B00XpVaO.mjs +736 -0
  115. package/dist/migrate-B00XpVaO.mjs.map +1 -0
  116. package/dist/migrate-CNlew9Ek.cjs +743 -0
  117. package/dist/migrate-CNlew9Ek.cjs.map +1 -0
  118. package/dist/openapi.cjs +198 -8
  119. package/dist/openapi.cjs.map +1 -0
  120. package/dist/openapi.d.cts +53 -15
  121. package/dist/openapi.d.cts.map +1 -1
  122. package/dist/openapi.d.mts +53 -15
  123. package/dist/openapi.d.mts.map +1 -1
  124. package/dist/openapi.mjs +193 -5
  125. package/dist/openapi.mjs.map +1 -0
  126. package/dist/ready-WfT-eWlm.mjs +861 -0
  127. package/dist/ready-WfT-eWlm.mjs.map +1 -0
  128. package/dist/ready-lr2Fm-ep.cjs +932 -0
  129. package/dist/ready-lr2Fm-ep.cjs.map +1 -0
  130. package/dist/reconcile/public.cjs +3 -5
  131. package/dist/reconcile/public.d.cts +30 -33
  132. package/dist/reconcile/public.d.cts.map +1 -1
  133. package/dist/reconcile/public.d.mts +30 -33
  134. package/dist/reconcile/public.d.mts.map +1 -1
  135. package/dist/reconcile/public.mjs +3 -4
  136. package/dist/{reconcile-CFs8C_1a.mjs → reconcile--I7V4Klj.mjs} +4 -7
  137. package/dist/reconcile--I7V4Klj.mjs.map +1 -0
  138. package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  139. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  140. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  141. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  142. package/dist/storage-BzaUxmqe.mjs +124 -0
  143. package/dist/storage-BzaUxmqe.mjs.map +1 -0
  144. package/dist/storage-CSGoC3bK.cjs +152 -0
  145. package/dist/storage-CSGoC3bK.cjs.map +1 -0
  146. package/dist/store-DQgxT_WR.cjs +211 -0
  147. package/dist/store-DQgxT_WR.cjs.map +1 -0
  148. package/dist/store-DeGATCS-.mjs +182 -0
  149. package/dist/store-DeGATCS-.mjs.map +1 -0
  150. package/dist/types-BbrNu83u.d.mts +6229 -0
  151. package/dist/types-BbrNu83u.d.mts.map +1 -0
  152. package/dist/types-DNqEsctD.d.cts +6230 -0
  153. package/dist/types-DNqEsctD.d.cts.map +1 -0
  154. package/dist/vitest.cjs +65 -0
  155. package/dist/vitest.cjs.map +1 -0
  156. package/dist/vitest.d.cts +29 -0
  157. package/dist/vitest.d.cts.map +1 -0
  158. package/dist/vitest.d.mts +29 -0
  159. package/dist/vitest.d.mts.map +1 -0
  160. package/dist/vitest.mjs +65 -0
  161. package/dist/vitest.mjs.map +1 -0
  162. package/dist/workspace/index.cjs +3 -4
  163. package/dist/workspace/index.d.cts +3 -3
  164. package/dist/workspace/index.d.mts +3 -3
  165. package/dist/workspace/index.mjs +2 -3
  166. package/dist/{credentials-BBIRJVp4.mjs → workspace-BsbxbqV-.mjs} +2201 -1732
  167. package/dist/workspace-BsbxbqV-.mjs.map +1 -0
  168. package/dist/{workspace-BcucjwvA.cjs → workspace-DEibcoBe.cjs} +1038 -1118
  169. package/dist/workspace-DEibcoBe.cjs.map +1 -0
  170. package/dist/{workspace-BFMrAKqI.mjs → workspace-DNzWgM1J.mjs} +869 -972
  171. package/dist/workspace-DNzWgM1J.mjs.map +1 -0
  172. package/dist/{credentials-G1JwBoXH.cjs → workspace-j6ZxvJqq.cjs} +2337 -1849
  173. package/dist/workspace-j6ZxvJqq.cjs.map +1 -0
  174. package/package.json +29 -20
  175. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  176. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  177. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  178. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  179. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  180. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  181. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  182. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  183. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  184. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  185. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  186. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  187. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  188. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  189. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  190. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  191. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  192. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  193. package/dist/chunk-Duj1WY3L.mjs +0 -7
  194. package/dist/config-C21ocYNd.cjs.map +0 -1
  195. package/dist/config-WRdsQYZK.mjs.map +0 -1
  196. package/dist/credentials-B5zRHdAl.mjs +0 -141
  197. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  198. package/dist/credentials-BBIRJVp4.mjs.map +0 -1
  199. package/dist/credentials-BapzjyV5.cjs +0 -195
  200. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  201. package/dist/credentials-G1JwBoXH.cjs.map +0 -1
  202. package/dist/discover-CAlFgYec.mjs.map +0 -1
  203. package/dist/discover-DTmFeloL.cjs.map +0 -1
  204. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  205. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  206. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  207. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  208. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  209. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  210. package/dist/emit-CbcRolsa.cjs.map +0 -1
  211. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  212. package/dist/encryption-C6jaU0hE.cjs +0 -54
  213. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  214. package/dist/encryption-CHzzeR8a.cjs +0 -4
  215. package/dist/encryption-CQUncu7v.mjs +0 -3
  216. package/dist/encryption-D-abyhZx.mjs +0 -42
  217. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  218. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  219. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  220. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  221. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  222. package/dist/generator-CNzBw7g5.cjs +0 -289
  223. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  224. package/dist/generator-VE2JrFlY.mjs +0 -253
  225. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  226. package/dist/index-BThUzEIp.d.mts.map +0 -1
  227. package/dist/index-CHB4tSzX.d.cts.map +0 -1
  228. package/dist/openapi-CA0yJUTN.cjs.map +0 -1
  229. package/dist/openapi-kkQbsRVj.mjs.map +0 -1
  230. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  231. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  232. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  233. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  234. package/dist/openapi-react-query.cjs +0 -4
  235. package/dist/openapi-react-query.d.cts +0 -11
  236. package/dist/openapi-react-query.d.cts.map +0 -1
  237. package/dist/openapi-react-query.d.mts +0 -11
  238. package/dist/openapi-react-query.d.mts.map +0 -1
  239. package/dist/openapi-react-query.mjs +0 -4
  240. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  241. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  242. package/dist/setup-B5_oHHUj.cjs +0 -11
  243. package/dist/setup-Cm2UnAdh.cjs +0 -473
  244. package/dist/setup-Cm2UnAdh.cjs.map +0 -1
  245. package/dist/setup-DXvRLTZN.mjs +0 -443
  246. package/dist/setup-DXvRLTZN.mjs.map +0 -1
  247. package/dist/setup-ZijS4qeC.mjs +0 -11
  248. package/dist/storage-BJmzYxt8.cjs +0 -363
  249. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  250. package/dist/storage-BM9hGpgv.cjs +0 -7
  251. package/dist/storage-Bi24WfoW.mjs +0 -297
  252. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  253. package/dist/storage-CYlGwWTj.mjs +0 -3
  254. package/dist/sync-CmEuNZsB.mjs +0 -76
  255. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  256. package/dist/sync-D306yOWu.cjs +0 -4
  257. package/dist/sync-SizaChmC.cjs +0 -93
  258. package/dist/sync-SizaChmC.cjs.map +0 -1
  259. package/dist/sync-hOqAWHR6.mjs +0 -3
  260. package/dist/types-C-arnQ1r.d.mts +0 -2184
  261. package/dist/types-C-arnQ1r.d.mts.map +0 -1
  262. package/dist/types-abJQuk7m.d.cts +0 -2184
  263. package/dist/types-abJQuk7m.d.cts.map +0 -1
  264. package/dist/workspace-BFMrAKqI.mjs.map +0 -1
  265. package/dist/workspace-BcucjwvA.cjs.map +0 -1
  266. package/dist/workspace-DdJss8I6.cjs +0 -9
  267. package/dist/workspace-k4l3rsFh.mjs +0 -8
@@ -1,12 +1,8 @@
1
- import { ConstructGenerator, isPartitionedRoutes } from "./discover-CAlFgYec.mjs";
2
- import { loadWorkspaceConfig } from "./config-WRdsQYZK.mjs";
3
- import { dirname, join, relative } from "node:path";
1
+ import { i as ConstructGenerator } from "./discover-Cf2jAcgF.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) {
@@ -681,45 +667,32 @@ var EndpointGenerator = class extends ConstructGenerator {
681
667
  return Endpoint.isEndpoint(value);
682
668
  }
683
669
  async build(context, constructs, outputDir, options) {
684
- const provider = options?.provider || "aws-apigatewayv2";
670
+ const target = options?.target ?? "aws";
671
+ const root = options?.root ?? process.cwd();
685
672
  const enableOpenApi = options?.enableOpenApi || false;
686
673
  const logger = console;
687
674
  const routes = [];
688
675
  if (constructs.length === 0) return routes;
689
- if (provider === "server") {
676
+ if (target === "server") {
690
677
  await this.generateEndpointsFile(outputDir, constructs, context);
691
678
  const appFile = await this.generateAppFile(outputDir, context);
692
679
  routes.push({
693
680
  path: "*",
694
681
  method: "ALL",
695
- handler: relative(process.cwd(), appFile),
682
+ handler: relative(root, appFile),
696
683
  authorizer: "none"
697
684
  });
698
685
  logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
699
- } else if (provider === "aws-lambda") {
700
- const routesDir = join(outputDir, "routes");
701
- await mkdir(routesDir, { recursive: true });
702
- for (const { key, construct, path } of constructs) {
703
- const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, "aws-apigatewayv2", construct, context);
704
- const routeInfo = {
705
- path: construct._path,
706
- method: construct.method,
707
- handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
708
- timeout: construct.timeout,
709
- memorySize: construct.memorySize,
710
- environment: await construct.getEnvironment({ markOptional: context.markOptional }),
711
- dependencies: construct.constructs,
712
- authorizer: construct.authorizer?.name ?? "none"
713
- };
714
- routes.push(routeInfo);
715
- logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
716
- }
717
- } else for (const { key, construct, path } of constructs) {
718
- const handlerFile = await this.generateHandlerFile(outputDir, path.relative, key, provider, construct, context);
686
+ return routes;
687
+ }
688
+ const routesDir = join(outputDir, "routes");
689
+ await mkdir(routesDir, { recursive: true });
690
+ for (const { key, construct, path } of constructs) {
691
+ const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, context);
719
692
  const routeInfo = {
720
693
  path: construct._path,
721
694
  method: construct.method,
722
- handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
695
+ handler: relative(root, handlerFile).replace(/\.ts$/, ".handler"),
723
696
  timeout: construct.timeout,
724
697
  memorySize: construct.memorySize,
725
698
  environment: await construct.getEnvironment({ markOptional: context.markOptional }),
@@ -731,34 +704,17 @@ var EndpointGenerator = class extends ConstructGenerator {
731
704
  }
732
705
  return routes;
733
706
  }
734
- async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
735
- const handlerFileName = `${exportName}.ts`;
736
- const handlerPath = join(outputDir, handlerFileName);
737
- const relativePath = relative(dirname(handlerPath), sourceFile);
738
- const importPath = relativePath.replace(/\.ts$/, ".js");
739
- let content;
740
- switch (provider) {
741
- case "aws-apigatewayv1":
742
- content = this.generateAWSApiGatewayV1Handler(importPath, exportName, context.storageDrivers);
743
- break;
744
- case "aws-apigatewayv2":
745
- content = this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers);
746
- break;
747
- case "server":
748
- content = this.generateServerHandler(importPath, exportName);
749
- break;
750
- default: throw new Error(`Unsupported provider: ${provider}`);
751
- }
752
- await writeFile(handlerPath, content);
707
+ async generateHandlerFile(outputDir, sourceFile, exportName, context) {
708
+ const handlerPath = join(outputDir, `${exportName}.ts`);
709
+ const importPath = relative(dirname(handlerPath), sourceFile).replace(/\.ts$/, ".js");
710
+ await writeFile(handlerPath, this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers));
753
711
  return handlerPath;
754
712
  }
755
713
  async generateEndpointsFile(outputDir, endpoints, context) {
756
- const endpointsFileName = "endpoints.ts";
757
- const endpointsPath = join(outputDir, endpointsFileName);
714
+ const endpointsPath = join(outputDir, "endpoints.ts");
758
715
  const importsByFile = /* @__PURE__ */ new Map();
759
716
  for (const { path, key } of endpoints) {
760
- const relativePath = relative(dirname(endpointsPath), path.relative);
761
- const importPath = relativePath.replace(/\.ts$/, ".js");
717
+ const importPath = relative(dirname(endpointsPath), path.relative).replace(/\.ts$/, ".js");
762
718
  if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
763
719
  importsByFile.get(importPath)?.push(key);
764
720
  }
@@ -773,7 +729,7 @@ import { ServiceDiscovery } from '@geekmidas/services';
773
729
  import type { Hono } from 'hono';
774
730
  ${endpointImports}
775
731
 
776
- export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any, any, any>[] = [
732
+ export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any>[] = [
777
733
  ${allExportNames.join(",\n ")}
778
734
  ];
779
735
 
@@ -824,11 +780,9 @@ export async function setupEndpoints(
824
780
  const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
825
781
  const endpointImports = endpoints.map(({ key, path }) => {
826
782
  const tierDir = join(endpointsDir, "standard");
827
- const relativePath = relative(tierDir, path.relative);
828
- const importPath = relativePath.replace(/\.ts$/, ".js");
829
783
  return {
830
784
  exportName: key,
831
- importPath
785
+ importPath: relative(tierDir, path.relative).replace(/\.ts$/, ".js")
832
786
  };
833
787
  });
834
788
  const summary = summarizeAnalysis(analyses);
@@ -850,8 +804,7 @@ export async function setupEndpoints(
850
804
  }
851
805
  async generateAppFile(outputDir, context) {
852
806
  if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
853
- const appFileName = "app.ts";
854
- const appPath = join(outputDir, appFileName);
807
+ const appPath = join(outputDir, "app.ts");
855
808
  const runtime = runtimeFor(context, dirname(appPath));
856
809
  const telescopeEnabled = context.telescope?.enabled;
857
810
  const telescopeWebSocketEnabled = context.telescope?.websocket;
@@ -861,32 +814,36 @@ export async function setupEndpoints(
861
814
  const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
862
815
  const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
863
816
  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}';
817
+ if (telescopeEnabled) {
818
+ if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
819
+ import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
820
+ else if (usesExternalTelescope) {
821
+ const relativeTelescopePath = relative(dirname(appPath), context.telescope?.telescopePath);
822
+ telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
868
823
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
869
- } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
824
+ } else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
870
825
  import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
826
+ }
871
827
  let studioImports = "";
872
- if (studioEnabled) if (usesExternalStudio) {
873
- const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
874
- studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
828
+ if (studioEnabled) {
829
+ if (usesExternalStudio) {
830
+ const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
831
+ studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
875
832
  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';
833
+ } else if (studioFromDatabase) {
834
+ const dbSpecifier = importSpecifier(dirname(appPath), context.studio.database.specifier);
835
+ studioImports = `import { snifferContext } from '@geekmidas/constructs';
879
836
  import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
880
837
  import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
881
838
  import { createStudioApp } from '@geekmidas/studio/server/hono';`;
882
- } else studioImports = "";
839
+ } else studioImports = "";
840
+ }
883
841
  const cors = corsFor(context.surface);
884
842
  let hooksImports = "";
885
843
  let beforeSetupCall = "";
886
844
  let afterSetupCall = "";
887
845
  if (context.hooks?.serverHooksPath) {
888
- const relativeHooksPath = relative(dirname(appPath), context.hooks.serverHooksPath);
889
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
846
+ hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
890
847
  beforeSetupCall = `
891
848
  // Call beforeSetup hook if defined
892
849
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -932,7 +889,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
932
889
  }
933
890
  ` : "";
934
891
  let telescopeSetup = "";
935
- if (telescopeEnabled) if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
892
+ if (telescopeEnabled) {
893
+ if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
936
894
  ${telescopeWebSocketSetupCode}
937
895
  // Add telescope middleware (before endpoints to capture all requests)
938
896
  honoApp.use('*', createMiddleware(telescope));
@@ -941,7 +899,7 @@ ${telescopeWebSocketSetupCode}
941
899
  const telescopeUI = createUI(telescope);
942
900
  honoApp.route('${context.telescope?.path}', telescopeUI);
943
901
  `;
944
- else telescopeSetup = `
902
+ else telescopeSetup = `
945
903
  // Setup Telescope for debugging/monitoring
946
904
  const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
947
905
  const telescope = new Telescope({
@@ -959,6 +917,7 @@ ${telescopeWebSocketSetupCode}
959
917
  const telescopeUI = createUI(telescope);
960
918
  honoApp.route('${context.telescope?.path}', telescopeUI);
961
919
  `;
920
+ }
962
921
  let studioSetup = "";
963
922
  if (studioEnabled && studioFromDatabase) studioSetup = `
964
923
  // Studio, built from the declared database. The client comes from the
@@ -992,6 +951,7 @@ import type { Hono as HonoType } from 'hono';
992
951
  import { setupEndpoints } from './endpoints.js';
993
952
  import { setupSubscribers } from './subscribers.js';
994
953
  import { setupQueues } from './queues.js';
954
+ import { setupCrons } from './crons.js';
995
955
  ${runtime.imports}
996
956
  ${telescopeImports}
997
957
  ${studioImports}
@@ -1000,7 +960,16 @@ ${cors.imports}
1000
960
  ${context.storageDrivers?.imports ?? ""}
1001
961
 
1002
962
  ${runtime.bindings}
1003
- ${telescopeFromSurface ? "const telescope = __surface.telescope;" : ""}
963
+ ${telescopeEnabled && telescopeFromSurface ? `// The surface's own Telescope, or the one \`telescope\` config describes.
964
+ const telescope =
965
+ __surface.telescope ??
966
+ new Telescope({
967
+ enabled: true,
968
+ path: '${context.telescope?.path}',
969
+ ignorePatterns: ${JSON.stringify(context.telescope?.ignore)},
970
+ recordBody: ${context.telescope?.recordBody},
971
+ storage: new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} }),
972
+ });` : ""}
1004
973
 
1005
974
  ${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
1006
975
  // each injected URL picks one, so no construct and no application module names
@@ -1069,9 +1038,11 @@ ${afterSetupCall}
1069
1038
 
1070
1039
  const port = options.port ?? 3000;
1071
1040
 
1072
- // Start subscribers in background (non-blocking, local development only)
1073
- await setupSubscribers(envParser, logger).catch((error) => {
1041
+ // Mount pushed subscribers' routes and start polled ones. What comes
1042
+ // back subscribes the routes, once the server can answer them.
1043
+ const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
1074
1044
  logger.error({ error }, 'Failed to start subscribers');
1045
+ return async (_port: number) => {};
1075
1046
  });
1076
1047
 
1077
1048
  // Start queue workers in background (non-blocking, local development only)
@@ -1079,12 +1050,20 @@ ${afterSetupCall}
1079
1050
  logger.error({ error }, 'Failed to start queue workers');
1080
1051
  });
1081
1052
 
1053
+ // Schedule this app's crons. Caught like the others: a scheduler that
1054
+ // cannot start is not a reason for the HTTP server not to.
1055
+ await setupCrons(envParser, logger).catch((error) => {
1056
+ logger.error({ error }, 'Failed to schedule crons');
1057
+ });
1058
+
1082
1059
  logger.info({ port }, 'Starting server');
1083
1060
 
1084
1061
  // Start HTTP server using provided serve function
1085
1062
  await options.serve(honoApp, port);
1086
1063
 
1087
1064
  logger.info({ port }, 'Server started');
1065
+
1066
+ await subscribeForPush(port);
1088
1067
  }
1089
1068
  };
1090
1069
  }
@@ -1105,26 +1084,6 @@ export default createApp;
1105
1084
  * object. Nothing has to be printed now, which is also why nothing has to be
1106
1085
  * named in config.
1107
1086
  */
1108
- generateAWSApiGatewayV1Handler(importPath, exportName, drivers) {
1109
- return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
1110
- import { ${exportName} } from '${importPath}';
1111
- ${drivers?.imports ?? ""}
1112
- ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${drivers.setup}\n` : ""}
1113
- const adapter = new AmazonApiGatewayV1Endpoint(${exportName});
1114
-
1115
- export const handler = adapter.handler;
1116
- `;
1117
- }
1118
- /**
1119
- * One Lambda, one endpoint — and no environment import.
1120
- *
1121
- * The endpoint was built from its surface, so it carries the parser the
1122
- * adaptor needs. This used to read
1123
- * `import { envParser } from '../../config/env'`, a line the build wrote
1124
- * because a generator can print a module specifier and cannot print an
1125
- * object. Nothing has to be printed now, which is also why nothing has to be
1126
- * named in config.
1127
- */
1128
1087
  generateAWSApiGatewayV2Handler(importPath, exportName, drivers) {
1129
1088
  return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
1130
1089
  import { ${exportName} } from '${importPath}';
@@ -1133,13 +1092,6 @@ ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${
1133
1092
  const adapter = new AmazonApiGatewayV2Endpoint(${exportName});
1134
1093
 
1135
1094
  export const handler = adapter.handler;
1136
- `;
1137
- }
1138
- generateServerHandler(importPath, exportName) {
1139
- return `import { ${exportName} } from '${importPath}';
1140
-
1141
- // Server handler - implement based on your server framework
1142
- export const handler = ${exportName};
1143
1095
  `;
1144
1096
  }
1145
1097
  /**
@@ -1147,10 +1099,8 @@ export const handler = ${exportName};
1147
1099
  * No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
1148
1100
  */
1149
1101
  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);
1102
+ const appPath = join(outputDir, "app.ts");
1103
+ const runtime = runtimeFor(context, dirname(appPath));
1154
1104
  const production = context.production;
1155
1105
  const healthCheckPath = production.healthCheck;
1156
1106
  const enableGracefulShutdown = production.gracefulShutdown;
@@ -1161,8 +1111,7 @@ export const handler = ${exportName};
1161
1111
  let beforeSetupCall = "";
1162
1112
  let afterSetupCall = "";
1163
1113
  if (context.hooks?.serverHooksPath) {
1164
- const relativeHooksPath = relative(dirname(appPath), context.hooks.serverHooksPath);
1165
- hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
1114
+ hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
1166
1115
  beforeSetupCall = `
1167
1116
  // Call beforeSetup hook if defined
1168
1117
  if (typeof serverHooks.beforeSetup === 'function') {
@@ -1177,18 +1126,27 @@ export const handler = ${exportName};
1177
1126
  `;
1178
1127
  }
1179
1128
  const subscriberSetup = includeSubscribers ? `
1180
- // Start subscribers in background
1181
- await setupSubscribers(envParser, logger).catch((error) => {
1129
+ // Mount pushed subscribers' routes and start polled ones. What comes
1130
+ // back subscribes the routes, once the server can answer them.
1131
+ const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
1182
1132
  logger.error({ error }, 'Failed to start subscribers');
1133
+ return async (_port: number) => {};
1183
1134
  });
1184
1135
 
1185
1136
  // Start queue workers in background
1186
1137
  await setupQueues(envParser, logger).catch((error) => {
1187
1138
  logger.error({ error }, 'Failed to start queue workers');
1188
1139
  });
1140
+
1141
+ // Schedule this app's crons. Caught like the others: a scheduler that
1142
+ // cannot start is not a reason for the HTTP server not to.
1143
+ await setupCrons(envParser, logger).catch((error) => {
1144
+ logger.error({ error }, 'Failed to schedule crons');
1145
+ });
1189
1146
  ` : "";
1190
1147
  const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
1191
- import { setupQueues } from './queues.js';` : "";
1148
+ import { setupQueues } from './queues.js';
1149
+ import { setupCrons } from './crons.js';` : "";
1192
1150
  const gracefulShutdownCode = enableGracefulShutdown ? `
1193
1151
  // Graceful shutdown handling
1194
1152
  let isShuttingDown = false;
@@ -1204,7 +1162,6 @@ import { setupQueues } from './queues.js';` : "";
1204
1162
  process.on('SIGTERM', shutdown);
1205
1163
  process.on('SIGINT', shutdown);
1206
1164
  ` : "";
1207
- const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
1208
1165
  const content = `/**
1209
1166
  * Generated production server application
1210
1167
  *
@@ -1216,10 +1173,10 @@ import { setupQueues } from './queues.js';` : "";
1216
1173
  */
1217
1174
  import { Hono } from 'hono';
1218
1175
  import type { Hono as HonoType } from 'hono';
1219
- import { setupEndpoints } from '${endpointsImportPath}';
1176
+ import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
1220
1177
  ${subscriberImport}
1221
- import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
1222
- import ${context.loggerImportPattern} from '${relativeLoggerPath}';
1178
+ ${runtime.imports}
1179
+ ${runtime.bindings}
1223
1180
  ${hooksImports}
1224
1181
  ${cors.imports}
1225
1182
  ${context.storageDrivers?.imports ?? ""}
@@ -1267,6 +1224,7 @@ ${gracefulShutdownCode}${subscriberSetup}
1267
1224
  await options.serve(honoApp, port);
1268
1225
 
1269
1226
  logger.info({ port }, 'Production server started');
1227
+ ${includeSubscribers ? "\n await subscribeForPush(port);" : ""}
1270
1228
  }
1271
1229
  };
1272
1230
  }
@@ -1283,10 +1241,10 @@ export default createApp;
1283
1241
  */
1284
1242
  async generateProductionServerEntry(outputDir) {
1285
1243
  const serverPath = join(outputDir, "server.ts");
1286
- const content = `#!/usr/bin/env node
1244
+ await writeFile(serverPath, `#!/usr/bin/env node
1287
1245
  /**
1288
1246
  * Production server entry point
1289
- * Generated by 'gkm build --provider server --production'
1247
+ * Generated by 'gkm build --production'
1290
1248
  */
1291
1249
  import { serve } from '@hono/node-server';
1292
1250
  import { createApp } from './app.js';
@@ -1299,11 +1257,9 @@ await start({
1299
1257
  port,
1300
1258
  serve: (app, port) => { serve({ fetch: app.fetch, port }); },
1301
1259
  });
1302
- `;
1303
- await writeFile(serverPath, content);
1260
+ `);
1304
1261
  }
1305
1262
  };
1306
-
1307
1263
  //#endregion
1308
1264
  //#region src/generators/OpenApiTsGenerator.ts
1309
1265
  /**
@@ -1458,7 +1414,7 @@ var OpenApiTsGenerator = class {
1458
1414
  for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
1459
1415
  const defName = this.pascalCase(rawName);
1460
1416
  if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
1461
- const { id: _id, $defs: _defs,...rest } = rawSchema;
1417
+ const { id: _id, $defs: _defs, ...rest } = rawSchema;
1462
1418
  collectedDefs.set(defName, rest);
1463
1419
  }
1464
1420
  for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
@@ -1494,17 +1450,17 @@ var OpenApiTsGenerator = class {
1494
1450
  async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
1495
1451
  try {
1496
1452
  const vendor = schema["~standard"]?.vendor;
1497
- if (!vendor || !(vendor in StandardSchemaJsonSchema)) return null;
1453
+ if (!vendor || !(vendor in StandardSchemaJsonSchema)) return unknownType(name);
1498
1454
  const toJsonSchema = StandardSchemaJsonSchema[vendor];
1499
1455
  const jsonSchema = await toJsonSchema(schema);
1500
- if (!jsonSchema) return null;
1456
+ if (!jsonSchema) return unknownType(name);
1501
1457
  if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
1502
1458
  for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
1503
- const { id,...schemaWithoutId } = defSchema;
1459
+ const { id, ...schemaWithoutId } = defSchema;
1504
1460
  collectedDefs.set(defName, schemaWithoutId);
1505
1461
  }
1506
1462
  }
1507
- const { $defs,...schemaWithoutDefs } = jsonSchema;
1463
+ const { $defs, ...schemaWithoutDefs } = jsonSchema;
1508
1464
  const ref = schemaWithoutDefs.$ref;
1509
1465
  if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
1510
1466
  const target = ref.split("/").pop();
@@ -1512,14 +1468,11 @@ var OpenApiTsGenerator = class {
1512
1468
  }
1513
1469
  return this.jsonSchemaToInterface(schemaWithoutDefs, name);
1514
1470
  } catch {
1515
- return null;
1471
+ return unknownType(name);
1516
1472
  }
1517
1473
  }
1518
1474
  jsonSchemaToInterface(schema, name) {
1519
- if (schema.type !== "object" || !schema.properties) {
1520
- const typeStr = this.jsonSchemaTypeToTs(schema);
1521
- return `export type ${name} = ${typeStr};`;
1522
- }
1475
+ if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
1523
1476
  const props = [];
1524
1477
  const required = new Set(schema.required || []);
1525
1478
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
@@ -1532,13 +1485,15 @@ var OpenApiTsGenerator = class {
1532
1485
  }
1533
1486
  jsonSchemaTypeToTs(schema) {
1534
1487
  if (!schema) return "unknown";
1535
- if (schema.$ref) {
1536
- const refName = schema.$ref.split("/").pop() || "unknown";
1537
- return refName;
1538
- }
1488
+ if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
1489
+ if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
1539
1490
  if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1540
1491
  if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
1541
1492
  if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
1493
+ if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
1494
+ ...schema,
1495
+ type
1496
+ })).join(" | ");
1542
1497
  switch (schema.type) {
1543
1498
  case "string":
1544
1499
  if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
@@ -1562,10 +1517,7 @@ var OpenApiTsGenerator = class {
1562
1517
  }
1563
1518
  return `{ ${props.join("; ")} }`;
1564
1519
  }
1565
- if (schema.additionalProperties) {
1566
- const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
1567
- return `Record<string, ${valueType}>`;
1568
- }
1520
+ if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
1569
1521
  return "Record<string, unknown>";
1570
1522
  default: return "unknown";
1571
1523
  }
@@ -1586,10 +1538,7 @@ var OpenApiTsGenerator = class {
1586
1538
  }
1587
1539
  const firstWithParams = infos.find((i) => i.input?.params);
1588
1540
  let paramsEntry = "";
1589
- if (firstWithParams?.input?.params) {
1590
- const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
1591
- paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
1592
- }
1541
+ if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
1593
1542
  pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
1594
1543
  }
1595
1544
  return `export interface paths {\n${pathEntries.join("\n")}\n}`;
@@ -1628,8 +1577,7 @@ var OpenApiTsGenerator = class {
1628
1577
  return acc;
1629
1578
  }, {});
1630
1579
  const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
1631
- const hasSecuritySchemes = schemeNames.length > 0;
1632
- const createApiSection = hasSecuritySchemes ? `
1580
+ const createApiSection = schemeNames.length > 0 ? `
1633
1581
  // ============================================================
1634
1582
  // API Client Factory
1635
1583
  // ============================================================
@@ -1653,6 +1601,8 @@ export interface CreateApiOptions {
1653
1601
  queryClient?: QueryClient;
1654
1602
  /** Optional request interceptor */
1655
1603
  onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
1604
+ /** The \`fetch\` requests go out on — a test browser's, for one */
1605
+ fetch?: typeof fetch;
1656
1606
  }
1657
1607
 
1658
1608
  /**
@@ -1682,6 +1632,7 @@ export function createApi(options: CreateApiOptions) {
1682
1632
  securitySchemes,
1683
1633
  authStrategies: options.authStrategies,
1684
1634
  onRequest: options.onRequest,
1635
+ ...(options.fetch ? { fetch: options.fetch } : {}),
1685
1636
  });
1686
1637
 
1687
1638
  const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
@@ -1806,162 +1757,15 @@ ${createApiSection}
1806
1757
  `;
1807
1758
  }
1808
1759
  };
1809
-
1810
- //#endregion
1811
- //#region src/workspace/client-generator.ts
1812
1760
  /**
1813
- * Normalize routes to an array of patterns.
1814
- * Handles string, string[], and PartitionedRoutes (extracts paths).
1815
- * @internal Exported for use in dev command
1761
+ * The declaration for a schema that cannot be converted — a vendor with no
1762
+ * converter, or one that fails. The paths interface names it either way, so
1763
+ * leaving it undeclared made the generated client fail to compile.
1816
1764
  */
1817
- function normalizeRoutes(routes) {
1818
- if (!routes) return [];
1819
- if (isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
1820
- return Array.isArray(routes) ? routes : [routes];
1765
+ function unknownType(name) {
1766
+ return `export type ${name} = unknown;`;
1821
1767
  }
1822
-
1823
1768
  //#endregion
1824
- //#region src/openapi.ts
1825
- /**
1826
- * Default output path for generated OpenAPI client (used for single-app configs)
1827
- */
1828
- const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
1829
- /**
1830
- * Resolve OpenAPI config from GkmConfig
1831
- */
1832
- function resolveOpenApiConfig(config) {
1833
- if (config.openapi === false) return { enabled: false };
1834
- if (config.openapi === true || config.openapi === void 0) return {
1835
- enabled: true,
1836
- title: "API Documentation",
1837
- version: "1.0.0",
1838
- description: "Auto-generated API documentation from endpoints"
1839
- };
1840
- return {
1841
- enabled: config.openapi.enabled !== false,
1842
- title: config.openapi.title || "API Documentation",
1843
- version: config.openapi.version || "1.0.0",
1844
- description: config.openapi.description || "Auto-generated API documentation from endpoints"
1845
- };
1846
- }
1847
- /**
1848
- * Generate OpenAPI spec from endpoints
1849
- * @returns Object with output path and endpoint count, or null if disabled
1850
- */
1851
- async function generateOpenApi(config, options = {}) {
1852
- const logger = options.silent ? { log: () => {} } : console;
1853
- const openApiConfig = resolveOpenApiConfig(config);
1854
- if (!openApiConfig.enabled) return null;
1855
- const endpointGenerator = new EndpointGenerator();
1856
- const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
1857
- if (loadedEndpoints.length === 0) {
1858
- logger.log("No valid endpoints found for OpenAPI generation");
1859
- return null;
1860
- }
1861
- const endpoints = loadedEndpoints.map(({ construct }) => construct);
1862
- const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);
1863
- await mkdir(dirname(outputPath), { recursive: true });
1864
- const tsGenerator = new OpenApiTsGenerator();
1865
- const tsContent = await tsGenerator.generate(endpoints, {
1866
- title: openApiConfig.title,
1867
- version: openApiConfig.version,
1868
- description: openApiConfig.description
1869
- });
1870
- await writeFile(outputPath, tsContent);
1871
- logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
1872
- return {
1873
- outputPath,
1874
- endpointCount: loadedEndpoints.length
1875
- };
1876
- }
1877
- async function openapiCommand(options = {}) {
1878
- const logger = console;
1879
- try {
1880
- const loadedConfig = await loadWorkspaceConfig(options.cwd);
1881
- if (loadedConfig.type === "single") {
1882
- const config = loadedConfig.raw;
1883
- if (!config.openapi) config.openapi = { enabled: true };
1884
- const result = await generateOpenApi(config);
1885
- if (result) logger.log(`Found ${result.endpointCount} endpoints`);
1886
- } else {
1887
- const { workspace } = loadedConfig;
1888
- const workspaceRoot = workspace.root;
1889
- 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));
1890
- if (backendApps.length === 0) {
1891
- logger.log("No backend apps with OpenAPI enabled found");
1892
- return;
1893
- }
1894
- if (options.app) {
1895
- const entry = backendApps.find(([name]) => name === options.app);
1896
- if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
1897
- const [appName, app] = entry;
1898
- const result = await generateOpenApiForApp(workspaceRoot, appName, app);
1899
- if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
1900
- return;
1901
- }
1902
- for (const [appName, app] of backendApps) {
1903
- if (app.type !== "backend" || !app.routes) continue;
1904
- const appPath = join(workspaceRoot, app.path);
1905
- await runOpenApiInSubprocess(appPath, appName);
1906
- }
1907
- }
1908
- } catch (error) {
1909
- throw new Error(`OpenAPI generation failed: ${error.message}`);
1910
- }
1911
- }
1912
- /**
1913
- * Generate OpenAPI for a single named app within a workspace.
1914
- * Runs in-process. The caller is responsible for ensuring `process.cwd()`
1915
- * is the app's directory so tsx loads the app's tsconfig path aliases.
1916
- */
1917
- async function generateOpenApiForApp(workspaceRoot, _appName, app) {
1918
- if (app.type !== "backend" || !app.routes) return null;
1919
- const appPath = join(workspaceRoot, app.path);
1920
- const routes = normalizeRoutes(app.routes);
1921
- const routesGlob = routes.map((r) => join(appPath, r));
1922
- const gkmConfig = {
1923
- routes: routesGlob,
1924
- envParser: app.envParser || "",
1925
- logger: app.logger || "",
1926
- openapi: app.openapi
1927
- };
1928
- return generateOpenApi(gkmConfig, { silent: true });
1929
- }
1930
- /**
1931
- * Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
1932
- * to avoid depending on the built dist.
1933
- */
1934
- function resolveGkmBinPath() {
1935
- if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
1936
- return fileURLToPath(new URL("../bin/gkm.mjs", import.meta.url));
1937
- }
1938
- /**
1939
- * Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
1940
- * the app's directory. Inherits `NODE_OPTIONS` (which already contains
1941
- * `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
1942
- * discovery picks up the app's tsconfig path aliases.
1943
- */
1944
- async function runOpenApiInSubprocess(appCwd, appName) {
1945
- const binPath = resolveGkmBinPath();
1946
- await new Promise((resolve$1, reject) => {
1947
- const child = spawn(process.execPath, [
1948
- binPath,
1949
- "openapi",
1950
- "--app",
1951
- appName
1952
- ], {
1953
- cwd: appCwd,
1954
- stdio: "inherit",
1955
- env: process.env
1956
- });
1957
- child.on("error", reject);
1958
- child.on("close", (code) => {
1959
- if (code === 0) resolve$1();
1960
- else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
1961
- });
1962
- });
1963
- }
1769
+ export { EndpointGenerator as n, runtimeFor as r, OpenApiTsGenerator as t };
1964
1770
 
1965
- //#endregion
1966
- export { EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, normalizeRoutes, openapiCommand, resolveOpenApiConfig };
1967
- //# sourceMappingURL=openapi-kkQbsRVj.mjs.map
1771
+ //# sourceMappingURL=OpenApiTsGenerator-BzIGy8KE.mjs.map