@geekmidas/cli 10.0.0-alpha.9 → 10.0.0-alpha.91

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 (457) hide show
  1. package/README.md +315 -414
  2. package/bin/adjacent-tsconfig.mjs +46 -8
  3. package/bin/gkm.mjs +11 -3
  4. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  5. package/bin/owning-tsconfig-jsx.mjs +108 -0
  6. package/dist/EndpointGenerator-CVc6Oi1Y.mjs +1021 -0
  7. package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +1 -0
  8. package/dist/EndpointGenerator-CwLjBCFE.cjs +1080 -0
  9. package/dist/EndpointGenerator-CwLjBCFE.cjs.map +1 -0
  10. package/dist/GoDaddyProvider-DSStJVAv.mjs +387 -0
  11. package/dist/GoDaddyProvider-DSStJVAv.mjs.map +1 -0
  12. package/dist/GoDaddyProvider-DqZ1qD_F.cjs +387 -0
  13. package/dist/GoDaddyProvider-DqZ1qD_F.cjs.map +1 -0
  14. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BI6J7oJr.mjs} +22 -23
  15. package/dist/HostingerProvider-BI6J7oJr.mjs.map +1 -0
  16. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-CyTpG_jy.cjs} +22 -23
  17. package/dist/HostingerProvider-CyTpG_jy.cjs.map +1 -0
  18. package/dist/LegacyStateStore-DXmNA7hy.cjs +89 -0
  19. package/dist/LegacyStateStore-DXmNA7hy.cjs.map +1 -0
  20. package/dist/LegacyStateStore-ZkdmiUFZ.mjs +89 -0
  21. package/dist/LegacyStateStore-ZkdmiUFZ.mjs.map +1 -0
  22. package/dist/LocalStateStore-BBeTlRTH.cjs +178 -0
  23. package/dist/LocalStateStore-BBeTlRTH.cjs.map +1 -0
  24. package/dist/LocalStateStore-CU-O0SBp.mjs +167 -0
  25. package/dist/LocalStateStore-CU-O0SBp.mjs.map +1 -0
  26. package/dist/OpenApiTsGenerator-B--HV-sW.cjs +541 -0
  27. package/dist/OpenApiTsGenerator-B--HV-sW.cjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-CkvsPdgg.mjs +536 -0
  29. package/dist/OpenApiTsGenerator-CkvsPdgg.mjs.map +1 -0
  30. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
  31. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  32. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
  33. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  34. package/dist/S3StateStore-Br8VMY22.cjs +160 -0
  35. package/dist/S3StateStore-Br8VMY22.cjs.map +1 -0
  36. package/dist/S3StateStore-bwxcI_wQ.mjs +161 -0
  37. package/dist/S3StateStore-bwxcI_wQ.mjs.map +1 -0
  38. package/dist/SSMStateStore-CsOS0W1y.mjs +154 -0
  39. package/dist/SSMStateStore-CsOS0W1y.mjs.map +1 -0
  40. package/dist/SSMStateStore-DoZE1Wi1.cjs +153 -0
  41. package/dist/SSMStateStore-DoZE1Wi1.cjs.map +1 -0
  42. package/dist/SubscriberGenerator-BPqQf8fB.mjs +448 -0
  43. package/dist/SubscriberGenerator-BPqQf8fB.mjs.map +1 -0
  44. package/dist/SubscriberGenerator-BVn7cQ-2.cjs +489 -0
  45. package/dist/SubscriberGenerator-BVn7cQ-2.cjs.map +1 -0
  46. package/dist/add-BSHk5Ngn.mjs +747 -0
  47. package/dist/add-BSHk5Ngn.mjs.map +1 -0
  48. package/dist/add-DmmBDV2e.cjs +749 -0
  49. package/dist/add-DmmBDV2e.cjs.map +1 -0
  50. package/dist/appPorts-C9z9Pzn9.mjs +223 -0
  51. package/dist/appPorts-C9z9Pzn9.mjs.map +1 -0
  52. package/dist/appPorts-Cu79hJF6.cjs +264 -0
  53. package/dist/appPorts-Cu79hJF6.cjs.map +1 -0
  54. package/dist/aws-B-6uEhgP.mjs +71 -0
  55. package/dist/aws-B-6uEhgP.mjs.map +1 -0
  56. package/dist/aws-BTawF0F-.cjs +82 -0
  57. package/dist/aws-BTawF0F-.cjs.map +1 -0
  58. package/dist/awsStore-7VmS_cZR.cjs +54 -0
  59. package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
  60. package/dist/awsStore-B529csle.mjs +43 -0
  61. package/dist/awsStore-B529csle.mjs.map +1 -0
  62. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
  63. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  64. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-oDEsPj02.cjs} +22 -20
  65. package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
  66. package/dist/{bundler-BY1OmV1e.cjs → bundler-BQJiB7Ub.cjs} +38 -35
  67. package/dist/bundler-BQJiB7Ub.cjs.map +1 -0
  68. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D6eBfVkl.mjs} +36 -32
  69. package/dist/bundler-D6eBfVkl.mjs.map +1 -0
  70. package/dist/cli-BE9mqeX8.cjs +69 -0
  71. package/dist/cli-BE9mqeX8.cjs.map +1 -0
  72. package/dist/cli-DD-Yk-I5.mjs +69 -0
  73. package/dist/cli-DD-Yk-I5.mjs.map +1 -0
  74. package/dist/compose-Bhmf0n4o.mjs +3140 -0
  75. package/dist/compose-Bhmf0n4o.mjs.map +1 -0
  76. package/dist/compose-CvpU6ooi.cjs +3265 -0
  77. package/dist/compose-CvpU6ooi.cjs.map +1 -0
  78. package/dist/config-CdEcTrjG.d.mts +269 -0
  79. package/dist/config-CdEcTrjG.d.mts.map +1 -0
  80. package/dist/config-pST7E0CS.d.cts +269 -0
  81. package/dist/config-pST7E0CS.d.cts.map +1 -0
  82. package/dist/config.cjs +420 -11
  83. package/dist/config.cjs.map +1 -0
  84. package/dist/config.d.cts +4 -120
  85. package/dist/config.d.mts +4 -120
  86. package/dist/config.mjs +404 -4
  87. package/dist/config.mjs.map +1 -0
  88. package/dist/credentialSchemas-BJqRJNK4.mjs +236 -0
  89. package/dist/credentialSchemas-BJqRJNK4.mjs.map +1 -0
  90. package/dist/credentialSchemas-DCR4Wd1W.cjs +271 -0
  91. package/dist/credentialSchemas-DCR4Wd1W.cjs.map +1 -0
  92. package/dist/credentials-BKfIugu2.cjs +513 -0
  93. package/dist/credentials-BKfIugu2.cjs.map +1 -0
  94. package/dist/credentials-CnVqoXMb.mjs +388 -0
  95. package/dist/credentials-CnVqoXMb.mjs.map +1 -0
  96. package/dist/databases-BY-pEImp.cjs +597 -0
  97. package/dist/databases-BY-pEImp.cjs.map +1 -0
  98. package/dist/databases-CzszQV0N.mjs +494 -0
  99. package/dist/databases-CzszQV0N.mjs.map +1 -0
  100. package/dist/define-DR8xGYfL.mjs +97 -0
  101. package/dist/define-DR8xGYfL.mjs.map +1 -0
  102. package/dist/define-DzRz8FgH.cjs +144 -0
  103. package/dist/define-DzRz8FgH.cjs.map +1 -0
  104. package/dist/deploy/public.cjs +208 -0
  105. package/dist/deploy/public.cjs.map +1 -0
  106. package/dist/deploy/public.d.cts +649 -0
  107. package/dist/deploy/public.d.cts.map +1 -0
  108. package/dist/deploy/public.d.mts +649 -0
  109. package/dist/deploy/public.d.mts.map +1 -0
  110. package/dist/deploy/public.mjs +142 -0
  111. package/dist/deploy/public.mjs.map +1 -0
  112. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  113. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  114. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  115. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  116. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  117. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  118. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  119. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  120. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  121. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  122. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  123. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  124. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  125. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  126. package/dist/deploy/sniffer-hooks.cjs +13 -7
  127. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  128. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  129. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  130. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  131. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  132. package/dist/deploy/sniffer-hooks.mjs +10 -3
  133. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  134. package/dist/deploy/sniffer-loader.cjs +16 -7
  135. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  136. package/dist/deploy/sniffer-loader.d.cts +1 -1
  137. package/dist/deploy/sniffer-loader.d.mts +1 -1
  138. package/dist/deploy/sniffer-loader.mjs +14 -3
  139. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  140. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  141. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  142. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  143. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  144. package/dist/deploy/sniffer-routes-worker.mjs +4 -4
  145. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  146. package/dist/deploy/sniffer-worker.cjs +15 -6
  147. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  148. package/dist/deploy/sniffer-worker.d.cts +1 -3
  149. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  150. package/dist/deploy/sniffer-worker.d.mts +1 -3
  151. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  152. package/dist/deploy/sniffer-worker.mjs +15 -4
  153. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  154. package/dist/deploy-CuHasEA4.cjs +554 -0
  155. package/dist/deploy-CuHasEA4.cjs.map +1 -0
  156. package/dist/deploy-QNtx_eWR.mjs +525 -0
  157. package/dist/deploy-QNtx_eWR.mjs.map +1 -0
  158. package/dist/derive-B4vDpzgP.mjs +150 -0
  159. package/dist/derive-B4vDpzgP.mjs.map +1 -0
  160. package/dist/derive-DAbo49sm.cjs +161 -0
  161. package/dist/derive-DAbo49sm.cjs.map +1 -0
  162. package/dist/discover-BPelzeGW.mjs +526 -0
  163. package/dist/discover-BPelzeGW.mjs.map +1 -0
  164. package/dist/discover-CU0paUyH.d.cts +108 -0
  165. package/dist/discover-CU0paUyH.d.cts.map +1 -0
  166. package/dist/discover-D1It5r_h.cjs +599 -0
  167. package/dist/discover-D1It5r_h.cjs.map +1 -0
  168. package/dist/discover-DFiJxwfv.d.mts +108 -0
  169. package/dist/discover-DFiJxwfv.d.mts.map +1 -0
  170. package/dist/dokploy-CYcMLh9-.mjs +38 -0
  171. package/dist/dokploy-CYcMLh9-.mjs.map +1 -0
  172. package/dist/dokploy-DIowwyIB.cjs +38 -0
  173. package/dist/dokploy-DIowwyIB.cjs.map +1 -0
  174. package/dist/drivers-DTZzxeIl.mjs +177 -0
  175. package/dist/drivers-DTZzxeIl.mjs.map +1 -0
  176. package/dist/drivers-LYSdQDmd.cjs +200 -0
  177. package/dist/drivers-LYSdQDmd.cjs.map +1 -0
  178. package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
  179. package/dist/emit-C1e8qD08.mjs.map +1 -0
  180. package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
  181. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  182. package/dist/encryption-BrEef7Jk.mjs +88 -0
  183. package/dist/encryption-BrEef7Jk.mjs.map +1 -0
  184. package/dist/encryption-CjYdUb2s.cjs +89 -0
  185. package/dist/encryption-CjYdUb2s.cjs.map +1 -0
  186. package/dist/engine-2h4k5ICq.mjs +3085 -0
  187. package/dist/engine-2h4k5ICq.mjs.map +1 -0
  188. package/dist/engine-BhJ7ZP9K.cjs +3198 -0
  189. package/dist/engine-BhJ7ZP9K.cjs.map +1 -0
  190. package/dist/github-B5Bw4HIu.cjs +669 -0
  191. package/dist/github-B5Bw4HIu.cjs.map +1 -0
  192. package/dist/github-BCDF6xVH.mjs +669 -0
  193. package/dist/github-BCDF6xVH.mjs.map +1 -0
  194. package/dist/{index-C6e-ULLx.d.mts → index-D-F_hTDz.d.cts} +39 -24
  195. package/dist/index-D-F_hTDz.d.cts.map +1 -0
  196. package/dist/{index-CR5urhWX.d.cts → index-YFNxR5Ns.d.mts} +39 -24
  197. package/dist/index-YFNxR5Ns.d.mts.map +1 -0
  198. package/dist/index.cjs +9487 -12080
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +1 -1
  201. package/dist/index.d.mts +1 -1
  202. package/dist/index.mjs +9420 -12026
  203. package/dist/index.mjs.map +1 -1
  204. package/dist/local-BjxDfPvy.cjs +241 -0
  205. package/dist/local-BjxDfPvy.cjs.map +1 -0
  206. package/dist/local-IuoIF3CT.mjs +224 -0
  207. package/dist/local-IuoIF3CT.mjs.map +1 -0
  208. package/dist/migrate-CGaancHY.cjs +93 -0
  209. package/dist/migrate-CGaancHY.cjs.map +1 -0
  210. package/dist/migrate-DWZz9kah.mjs +93 -0
  211. package/dist/migrate-DWZz9kah.mjs.map +1 -0
  212. package/dist/migrate-DbtcuOr_.mjs +265 -0
  213. package/dist/migrate-DbtcuOr_.mjs.map +1 -0
  214. package/dist/migrate-q2YYLJLE.cjs +270 -0
  215. package/dist/migrate-q2YYLJLE.cjs.map +1 -0
  216. package/dist/openapi.cjs +214 -10
  217. package/dist/openapi.cjs.map +1 -0
  218. package/dist/openapi.d.cts +47 -17
  219. package/dist/openapi.d.cts.map +1 -1
  220. package/dist/openapi.d.mts +47 -17
  221. package/dist/openapi.d.mts.map +1 -1
  222. package/dist/openapi.mjs +208 -5
  223. package/dist/openapi.mjs.map +1 -0
  224. package/dist/provider-C9_-45d5.cjs +56 -0
  225. package/dist/provider-C9_-45d5.cjs.map +1 -0
  226. package/dist/provider-q4lsYzYG.mjs +45 -0
  227. package/dist/provider-q4lsYzYG.mjs.map +1 -0
  228. package/dist/ready-BpNbORRB.cjs +402 -0
  229. package/dist/ready-BpNbORRB.cjs.map +1 -0
  230. package/dist/ready-b6vm0-W-.mjs +373 -0
  231. package/dist/ready-b6vm0-W-.mjs.map +1 -0
  232. package/dist/reconcile/public.cjs +3 -5
  233. package/dist/reconcile/public.d.cts +11 -87
  234. package/dist/reconcile/public.d.cts.map +1 -1
  235. package/dist/reconcile/public.d.mts +11 -87
  236. package/dist/reconcile/public.d.mts.map +1 -1
  237. package/dist/reconcile/public.mjs +3 -4
  238. package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  239. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  240. package/dist/{reconcile-CFs8C_1a.mjs → reconcile-Dh1Jk7WE.mjs} +4 -7
  241. package/dist/reconcile-Dh1Jk7WE.mjs.map +1 -0
  242. package/dist/resolve-Cns0v6dN.cjs +315 -0
  243. package/dist/resolve-Cns0v6dN.cjs.map +1 -0
  244. package/dist/resolve-DNg0icnh.mjs +262 -0
  245. package/dist/resolve-DNg0icnh.mjs.map +1 -0
  246. package/dist/rollback-CFrNLmxs.mjs +132 -0
  247. package/dist/rollback-CFrNLmxs.mjs.map +1 -0
  248. package/dist/rollback-UIjS25F1.cjs +161 -0
  249. package/dist/rollback-UIjS25F1.cjs.map +1 -0
  250. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  251. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  252. package/dist/runtime-CN_kmqxo.d.cts +90 -0
  253. package/dist/runtime-CN_kmqxo.d.cts.map +1 -0
  254. package/dist/runtime-Cjvon3oj.d.mts +90 -0
  255. package/dist/runtime-Cjvon3oj.d.mts.map +1 -0
  256. package/dist/sandbox/config-worker.cjs +43 -0
  257. package/dist/sandbox/config-worker.cjs.map +1 -0
  258. package/dist/sandbox/config-worker.d.cts +1 -0
  259. package/dist/sandbox/config-worker.d.mts +1 -0
  260. package/dist/sandbox/config-worker.mjs +44 -0
  261. package/dist/sandbox/config-worker.mjs.map +1 -0
  262. package/dist/sandbox/credentials-worker.cjs +54 -0
  263. package/dist/sandbox/credentials-worker.cjs.map +1 -0
  264. package/dist/sandbox/credentials-worker.d.cts +1 -0
  265. package/dist/sandbox/credentials-worker.d.mts +1 -0
  266. package/dist/sandbox/credentials-worker.mjs +55 -0
  267. package/dist/sandbox/credentials-worker.mjs.map +1 -0
  268. package/dist/sandbox/discover-worker.cjs +47 -0
  269. package/dist/sandbox/discover-worker.cjs.map +1 -0
  270. package/dist/sandbox/discover-worker.d.cts +1 -0
  271. package/dist/sandbox/discover-worker.d.mts +1 -0
  272. package/dist/sandbox/discover-worker.mjs +48 -0
  273. package/dist/sandbox/discover-worker.mjs.map +1 -0
  274. package/dist/sandbox/migrate-worker.cjs +75 -0
  275. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  276. package/dist/sandbox/migrate-worker.d.cts +1 -0
  277. package/dist/sandbox/migrate-worker.d.mts +1 -0
  278. package/dist/sandbox/migrate-worker.mjs +76 -0
  279. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  280. package/dist/sandbox-CL--ZDui.cjs +164 -0
  281. package/dist/sandbox-CL--ZDui.cjs.map +1 -0
  282. package/dist/sandbox-Dm247NGx.mjs +117 -0
  283. package/dist/sandbox-Dm247NGx.mjs.map +1 -0
  284. package/dist/sandbox-M8UnLhXE.d.cts +126 -0
  285. package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
  286. package/dist/sandbox-M8UnLhXE.d.mts +126 -0
  287. package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
  288. package/dist/{workspace-zoqRbihZ.mjs → schemas-BObwxB_t.cjs} +998 -1659
  289. package/dist/schemas-BObwxB_t.cjs.map +1 -0
  290. package/dist/{workspace-C6VJQVtG.cjs → schemas-D-xeKJDD.mjs} +913 -1842
  291. package/dist/schemas-D-xeKJDD.mjs.map +1 -0
  292. package/dist/secretsManager-Chs9VV2r.mjs +76 -0
  293. package/dist/secretsManager-Chs9VV2r.mjs.map +1 -0
  294. package/dist/secretsManager-DcMlHnRC.cjs +87 -0
  295. package/dist/secretsManager-DcMlHnRC.cjs.map +1 -0
  296. package/dist/seeds-CkIPFGNO.cjs +10560 -0
  297. package/dist/seeds-CkIPFGNO.cjs.map +1 -0
  298. package/dist/seeds-odfgSCmu.mjs +9538 -0
  299. package/dist/seeds-odfgSCmu.mjs.map +1 -0
  300. package/dist/sniffer-BTtX3NUM.mjs +1262 -0
  301. package/dist/sniffer-BTtX3NUM.mjs.map +1 -0
  302. package/dist/sniffer-IAQEpsQb.cjs +1333 -0
  303. package/dist/sniffer-IAQEpsQb.cjs.map +1 -0
  304. package/dist/sst-BgcOsaBi.cjs +453 -0
  305. package/dist/sst-BgcOsaBi.cjs.map +1 -0
  306. package/dist/sst-CJzvyrEz.mjs +430 -0
  307. package/dist/sst-CJzvyrEz.mjs.map +1 -0
  308. package/dist/stages-CUn6gvXL.cjs +174 -0
  309. package/dist/stages-CUn6gvXL.cjs.map +1 -0
  310. package/dist/stages-CnZRYmkI.mjs +174 -0
  311. package/dist/stages-CnZRYmkI.mjs.map +1 -0
  312. package/dist/target/public.cjs +15 -0
  313. package/dist/target/public.d.cts +28 -0
  314. package/dist/target/public.d.cts.map +1 -0
  315. package/dist/target/public.d.mts +28 -0
  316. package/dist/target/public.d.mts.map +1 -0
  317. package/dist/target/public.mjs +4 -0
  318. package/dist/terminal-D8TPK7o9.mjs +84 -0
  319. package/dist/terminal-D8TPK7o9.mjs.map +1 -0
  320. package/dist/terminal-DuapRxh6.cjs +84 -0
  321. package/dist/terminal-DuapRxh6.cjs.map +1 -0
  322. package/dist/types-NqX1Hz4P.d.cts +7454 -0
  323. package/dist/types-NqX1Hz4P.d.cts.map +1 -0
  324. package/dist/types-ZHuZ89hv.d.mts +7453 -0
  325. package/dist/types-ZHuZ89hv.d.mts.map +1 -0
  326. package/dist/utils-D2Nk1Nv2.cjs +205 -0
  327. package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
  328. package/dist/utils-D_fxUqvU.mjs +156 -0
  329. package/dist/utils-D_fxUqvU.mjs.map +1 -0
  330. package/dist/vitest.cjs +65 -0
  331. package/dist/vitest.cjs.map +1 -0
  332. package/dist/vitest.d.cts +29 -0
  333. package/dist/vitest.d.cts.map +1 -0
  334. package/dist/vitest.d.mts +29 -0
  335. package/dist/vitest.d.mts.map +1 -0
  336. package/dist/vitest.mjs +65 -0
  337. package/dist/vitest.mjs.map +1 -0
  338. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  339. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  340. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  341. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  342. package/dist/workspace/index.cjs +8 -4
  343. package/dist/workspace/index.d.cts +3 -3
  344. package/dist/workspace/index.d.mts +3 -3
  345. package/dist/workspace/index.mjs +2 -3
  346. package/dist/workspace-CJ0lKFq-.mjs +1979 -0
  347. package/dist/workspace-CJ0lKFq-.mjs.map +1 -0
  348. package/dist/workspace-CwW3Gkru.cjs +2355 -0
  349. package/dist/workspace-CwW3Gkru.cjs.map +1 -0
  350. package/package.json +53 -22
  351. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  352. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  353. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  354. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  355. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  356. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  357. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  358. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  359. package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
  360. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  361. package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
  362. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  363. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  364. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  365. package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
  366. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  367. package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
  368. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  369. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  370. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  371. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  372. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  373. package/dist/chunk-Duj1WY3L.mjs +0 -7
  374. package/dist/config-BZ1F0WuA.cjs +0 -462
  375. package/dist/config-BZ1F0WuA.cjs.map +0 -1
  376. package/dist/config-DVVph9yz.mjs +0 -402
  377. package/dist/config-DVVph9yz.mjs.map +0 -1
  378. package/dist/config.d.cts.map +0 -1
  379. package/dist/config.d.mts.map +0 -1
  380. package/dist/credentials-B5zRHdAl.mjs +0 -141
  381. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  382. package/dist/credentials-BapzjyV5.cjs +0 -195
  383. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  384. package/dist/credentials-Xamqe_NJ.cjs +0 -2681
  385. package/dist/credentials-Xamqe_NJ.cjs.map +0 -1
  386. package/dist/credentials-dP8vRVRv.mjs +0 -2549
  387. package/dist/credentials-dP8vRVRv.mjs.map +0 -1
  388. package/dist/discover-CAlFgYec.mjs +0 -229
  389. package/dist/discover-CAlFgYec.mjs.map +0 -1
  390. package/dist/discover-DTmFeloL.cjs +0 -271
  391. package/dist/discover-DTmFeloL.cjs.map +0 -1
  392. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  393. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  394. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  395. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  396. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  397. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  398. package/dist/emit-CbcRolsa.cjs.map +0 -1
  399. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  400. package/dist/encryption-C6jaU0hE.cjs +0 -54
  401. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  402. package/dist/encryption-CHzzeR8a.cjs +0 -4
  403. package/dist/encryption-CQUncu7v.mjs +0 -3
  404. package/dist/encryption-D-abyhZx.mjs +0 -42
  405. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  406. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  407. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  408. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  409. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  410. package/dist/generator-CNzBw7g5.cjs +0 -289
  411. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  412. package/dist/generator-VE2JrFlY.mjs +0 -253
  413. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  414. package/dist/index-C6e-ULLx.d.mts.map +0 -1
  415. package/dist/index-CR5urhWX.d.cts.map +0 -1
  416. package/dist/openapi-SjsgARie.cjs +0 -2075
  417. package/dist/openapi-SjsgARie.cjs.map +0 -1
  418. package/dist/openapi-Xx0A7Wg0.mjs +0 -2021
  419. package/dist/openapi-Xx0A7Wg0.mjs.map +0 -1
  420. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  421. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  422. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  423. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  424. package/dist/openapi-react-query.cjs +0 -4
  425. package/dist/openapi-react-query.d.cts +0 -11
  426. package/dist/openapi-react-query.d.cts.map +0 -1
  427. package/dist/openapi-react-query.d.mts +0 -11
  428. package/dist/openapi-react-query.d.mts.map +0 -1
  429. package/dist/openapi-react-query.mjs +0 -4
  430. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  431. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  432. package/dist/setup-BA8ciTPU.mjs +0 -11
  433. package/dist/setup-BsZvZP6f.cjs +0 -11
  434. package/dist/setup-C8KOx8_8.mjs +0 -443
  435. package/dist/setup-C8KOx8_8.mjs.map +0 -1
  436. package/dist/setup-hC6hI86f.cjs +0 -473
  437. package/dist/setup-hC6hI86f.cjs.map +0 -1
  438. package/dist/storage-BJmzYxt8.cjs +0 -363
  439. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  440. package/dist/storage-BM9hGpgv.cjs +0 -7
  441. package/dist/storage-Bi24WfoW.mjs +0 -297
  442. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  443. package/dist/storage-CYlGwWTj.mjs +0 -3
  444. package/dist/sync-CmEuNZsB.mjs +0 -76
  445. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  446. package/dist/sync-D306yOWu.cjs +0 -4
  447. package/dist/sync-SizaChmC.cjs +0 -93
  448. package/dist/sync-SizaChmC.cjs.map +0 -1
  449. package/dist/sync-hOqAWHR6.mjs +0 -3
  450. package/dist/types-6pkp2RRj.d.mts +0 -2220
  451. package/dist/types-6pkp2RRj.d.mts.map +0 -1
  452. package/dist/types-Y3fKQSAK.d.cts +0 -2220
  453. package/dist/types-Y3fKQSAK.d.cts.map +0 -1
  454. package/dist/workspace-BzrG_2SI.mjs +0 -8
  455. package/dist/workspace-C6VJQVtG.cjs.map +0 -1
  456. package/dist/workspace-XXtNhqJl.cjs +0 -9
  457. package/dist/workspace-zoqRbihZ.mjs.map +0 -1
@@ -0,0 +1,402 @@
1
+ const require_discover = require("./discover-D1It5r_h.cjs");
2
+ const require_EndpointGenerator = require("./EndpointGenerator-CwLjBCFE.cjs");
3
+ const require_OpenApiTsGenerator = require("./OpenApiTsGenerator-B--HV-sW.cjs");
4
+ const require_SubscriberGenerator = require("./SubscriberGenerator-BVn7cQ-2.cjs");
5
+ const require_drivers = require("./drivers-LYSdQDmd.cjs");
6
+ let node_path = require("node:path");
7
+ let node_fs_promises = require("node:fs/promises");
8
+ let _geekmidas_manifest = require("@geekmidas/manifest");
9
+ let node_url = require("node:url");
10
+ let _geekmidas_envkit = require("@geekmidas/envkit");
11
+ let _geekmidas_services = require("@geekmidas/services");
12
+ //#region src/test/harness.ts
13
+ /**
14
+ * What `gkm test` writes for a feature test to be built from.
15
+ *
16
+ * `gkm test` already discovers an app's constructs and resolves the test
17
+ * stage's environment; this keeps both, under `.gkm/test/`:
18
+ *
19
+ * - `manifest.json` — which construct and endpoint is exported where, and the
20
+ * environment the test stage resolved, keyed as the constructs derive keys.
21
+ * - `clients/<surface>.ts` — each surface's typed client, from the same
22
+ * generator `gkm build` uses for the app's own.
23
+ * - `index.ts` — the configured `it`, and a `Browser` holding one client per
24
+ * surface and one per auth server, each on the browser's `fetch`.
25
+ *
26
+ * A test imports `it` from there and declares nothing — not a construct, not an
27
+ * environment key, not a client.
28
+ */
29
+ /**
30
+ * The variable the manifest's path travels in — what
31
+ * `@geekmidas/constructs/testing` reads. Its own constant rather than an import:
32
+ * that entry carries the whole harness (MSW, Hono, Vitest), and importing it
33
+ * here put all of it on the start-up path of every `gkm` command.
34
+ */
35
+ const TEST_MANIFEST_ENV = "GKM_TEST_MANIFEST";
36
+ /** Where the harness lives, relative to the workspace root. */
37
+ const TEST_HARNESS_DIR = ".gkm/test";
38
+ /**
39
+ * Better-auth's client plugin for each server plugin id.
40
+ *
41
+ * Written down rather than derived: the ids and the client names do not follow
42
+ * one rule (`admin` pairs with `adminClient`, `email-otp` with
43
+ * `emailOTPClient`), and a guess that missed would hand a test a client
44
+ * silently lacking every method of that plugin. A server plugin not listed has
45
+ * no client counterpart — `bearer`, `open-api` — or needs one from another
46
+ * package, and is left out.
47
+ */
48
+ const CLIENT_PLUGINS = {
49
+ admin: "adminClient",
50
+ anonymous: "anonymousClient",
51
+ "device-authorization": "deviceAuthorizationClient",
52
+ "email-otp": "emailOTPClient",
53
+ jwt: "jwtClient",
54
+ "last-login-method": "lastLoginMethodClient",
55
+ "magic-link": "magicLinkClient",
56
+ "multi-session": "multiSessionClient",
57
+ "oauth-popup": "oauthPopupClient",
58
+ "one-tap": "oneTapClient",
59
+ "one-time-token": "oneTimeTokenClient",
60
+ organization: "organizationClient",
61
+ "phone-number": "phoneNumberClient",
62
+ siwe: "siweClient",
63
+ "two-factor": "twoFactorClient",
64
+ username: "usernameClient"
65
+ };
66
+ /** Where a project keeps its test factories, relative to its root. */
67
+ const DEFAULT_FACTORIES_DIR = "test/factories";
68
+ /** A file in the factories folder that names no database construct. */
69
+ var UnknownFactoryFile = class extends Error {
70
+ file;
71
+ known;
72
+ constructor(file, known) {
73
+ super(`${file} names no database construct, so no test could be handed it. ` + (known.length > 0 ? `The databases: ${known.join(", ")}. ` : "This project declares no database. ") + `Name a factory after its database: test/factories/<construct>.ts.`);
74
+ this.file = file;
75
+ this.known = known;
76
+ this.name = "UnknownFactoryFile";
77
+ }
78
+ };
79
+ /** A factory file that exports no `createFactory`. */
80
+ var FactoryHasNoCreate = class extends Error {
81
+ file;
82
+ constructor(file) {
83
+ super(`${file} is a test factory but exports no \`createFactory\`. Export \`function createFactory(db: Kysely<Database>)\` returning the factory.`);
84
+ this.file = file;
85
+ this.name = "FactoryHasNoCreate";
86
+ }
87
+ };
88
+ /**
89
+ * The factories in a folder, each matched to the database it is named after.
90
+ *
91
+ * A file that names no database, or exports no `createFactory`, is refused
92
+ * rather than skipped: either is a factory no test would ever be handed.
93
+ */
94
+ async function factorySources(folder, databases) {
95
+ if (!folder) return [];
96
+ const entries = await (0, node_fs_promises.readdir)(folder, { withFileTypes: true }).catch((error) => {
97
+ if (error.code === "ENOENT") return [];
98
+ throw error;
99
+ });
100
+ const found = [];
101
+ for (const entry of entries) {
102
+ if (!entry.isFile() || !isFactoryFile(entry.name)) continue;
103
+ const file = (0, node_path.join)(folder, entry.name);
104
+ const id = (0, _geekmidas_manifest.canonicalId)(entry.name.slice(0, -(0, node_path.extname)(entry.name).length));
105
+ if (!databases.includes(id)) throw new UnknownFactoryFile(file, databases);
106
+ if (typeof (await import((0, node_url.pathToFileURL)(file).href)).createFactory !== "function") throw new FactoryHasNoCreate(file);
107
+ found.push({
108
+ file,
109
+ service: (0, _geekmidas_manifest.serviceKey)(id)
110
+ });
111
+ }
112
+ return found.sort((a, b) => a.service < b.service ? -1 : 1);
113
+ }
114
+ function isFactoryFile(file) {
115
+ if (file.endsWith(".d.ts")) return false;
116
+ if (/\.(spec|test)\.[cm]?[jt]s$/.test(file)) return false;
117
+ return [
118
+ ".ts",
119
+ ".mts",
120
+ ".js",
121
+ ".mjs"
122
+ ].includes((0, node_path.extname)(file));
123
+ }
124
+ /** Write the manifest, the clients and the harness; return the manifest path. */
125
+ async function writeTestHarness(options) {
126
+ const sources = {};
127
+ const declared = await require_discover.discover({
128
+ patterns: options.patterns,
129
+ cwd: options.root,
130
+ sources
131
+ });
132
+ const endpoints = (await new require_EndpointGenerator.EndpointGenerator().load(options.patterns, options.root)).map(({ key, construct, path }) => ({
133
+ surface: construct.owner ?? construct.surface?.id,
134
+ construct,
135
+ source: {
136
+ file: path.absolute,
137
+ export: key
138
+ }
139
+ })).filter((endpoint) => endpoint.surface !== void 0);
140
+ const subscribers = (await new require_SubscriberGenerator.SubscriberGenerator().load(options.patterns, options.root)).map(({ key, path }) => ({ source: {
141
+ file: path.absolute,
142
+ export: key
143
+ } }));
144
+ const manifest = {
145
+ stage: options.stage,
146
+ constructs: Object.fromEntries(Object.entries(declared).flatMap(([id, declaration]) => {
147
+ const source = sources[id];
148
+ return source ? [[id, {
149
+ kind: declaration.kind,
150
+ source: {
151
+ file: source.file,
152
+ export: source.exportName
153
+ }
154
+ }]] : [];
155
+ })),
156
+ endpoints: endpoints.map(({ surface, source }) => ({
157
+ surface,
158
+ source
159
+ })),
160
+ subscribers,
161
+ env: options.env
162
+ };
163
+ const surfaces = [...new Set(endpoints.map(({ surface }) => surface))];
164
+ const generator = new require_OpenApiTsGenerator.OpenApiTsGenerator();
165
+ const clients = await Promise.all(surfaces.map(async (surface) => ({
166
+ file: `${(0, _geekmidas_manifest.kebabCase)(surface)}.ts`,
167
+ content: await generator.generate(endpoints.filter((endpoint) => endpoint.surface === surface).map(({ construct }) => construct), {
168
+ title: surface,
169
+ version: "1.0.0"
170
+ })
171
+ })));
172
+ const auths = await authClients(declared, sources, options.env);
173
+ const drivers = require_drivers.driversFor({
174
+ appRoot: options.root,
175
+ cache: require_drivers.cacheBackendsIn(declared, options.cacheBackend),
176
+ events: require_drivers.eventsBackendsIn(declared, options.eventsBackend)
177
+ });
178
+ const owners = new Set(auths.map((auth) => auth.databaseId));
179
+ const databases = databaseSources(declared, sources).filter(({ id, kind }) => !owners.has(id) && kind !== "database-reader");
180
+ const factories = await factorySources(options.factories, databases.map(({ id }) => id));
181
+ const fakes = Object.entries(await require_SubscriberGenerator.readFakes(options.root, declared)).map(([id, { file }]) => ({
182
+ id,
183
+ file
184
+ }));
185
+ const services = serviceSources(declared, sources).filter(({ id }) => !owners.has(id));
186
+ const files = [.../* @__PURE__ */ new Set([
187
+ ...Object.values(manifest.constructs).map(({ source }) => source.file),
188
+ ...manifest.endpoints.map(({ source }) => source.file),
189
+ ...(manifest.subscribers ?? []).map(({ source }) => source.file)
190
+ ])];
191
+ const harnessFor = (dir) => harnessModule({
192
+ dir,
193
+ files,
194
+ databases,
195
+ surfaces: surfaces.map((id, index) => ({
196
+ id,
197
+ secured: clients[index].content.includes("authStrategies:")
198
+ })),
199
+ auths,
200
+ drivers,
201
+ factories,
202
+ fakes,
203
+ services,
204
+ mail: Object.values(declared).some(({ kind }) => kind === "email")
205
+ });
206
+ const json = `${JSON.stringify(manifest, null, 2)}\n`;
207
+ return (await Promise.all([...new Set(options.targets)].map(async (target) => {
208
+ const dir = (0, node_path.join)(target, TEST_HARNESS_DIR);
209
+ await (0, node_fs_promises.rm)(dir, {
210
+ recursive: true,
211
+ force: true
212
+ });
213
+ await (0, node_fs_promises.mkdir)((0, node_path.join)(dir, "clients"), { recursive: true });
214
+ await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "manifest.json"), json);
215
+ await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "index.ts"), harnessFor(dir));
216
+ for (const client of clients) await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "clients", client.file), client.content);
217
+ return (0, node_path.join)(dir, "manifest.json");
218
+ })))[0];
219
+ }
220
+ /** Each auth server, with the client plugins its server plugins pair with. */
221
+ async function authClients(declared, sources, env) {
222
+ const clients = [];
223
+ const envParser = new _geekmidas_envkit.EnvironmentParser({ ...env });
224
+ for (const [id, declaration] of Object.entries(declared)) {
225
+ const source = sources[id];
226
+ if (declaration.kind !== "rest-api" || !source) continue;
227
+ const exported = (await import(source.file))[source.exportName];
228
+ if (!isBetterAuth(exported) || exported.id !== id) continue;
229
+ const ids = await exported.pluginIds({
230
+ envParser,
231
+ context: _geekmidas_services.serviceContext
232
+ });
233
+ clients.push({
234
+ id,
235
+ basePath: exported.basePath,
236
+ plugins: ids.flatMap((plugin) => CLIENT_PLUGINS[plugin] ?? []),
237
+ databaseId: exported.databaseId
238
+ });
239
+ }
240
+ return clients;
241
+ }
242
+ function isBetterAuth(value) {
243
+ return typeof value === "object" && value !== null && "pluginIds" in value && "basePath" in value;
244
+ }
245
+ /** `Api` → `api`, `AdminApi` → `adminApi`: a construct id as a property name. */
246
+ function propertyOf(id) {
247
+ return id.charAt(0).toLowerCase() + id.slice(1);
248
+ }
249
+ /**
250
+ * Every database construct the app declares — a database, a schema tenant, a
251
+ * reader — keyed as a test is handed its transaction.
252
+ */
253
+ function databaseSources(declared, sources) {
254
+ return Object.entries(declared).filter(([id, declaration]) => Boolean(sources[id] && declaration.kind.startsWith("database"))).map(([id, declaration]) => ({
255
+ id,
256
+ kind: declaration.kind,
257
+ service: (0, _geekmidas_manifest.serviceKey)(id),
258
+ source: sources[id]
259
+ }));
260
+ }
261
+ /** The kinds whose construct hands a handler a client — what `services` reaches. */
262
+ const SERVICE_KINDS = /* @__PURE__ */ new Set([
263
+ "cache",
264
+ "credential",
265
+ "database",
266
+ "database-schema",
267
+ "database-reader",
268
+ "email",
269
+ "encryption",
270
+ "external-api",
271
+ "file-server",
272
+ "objects",
273
+ "queue",
274
+ "topic"
275
+ ]);
276
+ function serviceSources(declared, sources) {
277
+ return Object.entries(declared).filter(([id, declaration]) => Boolean(sources[id] && SERVICE_KINDS.has(declaration.kind))).map(([id, declaration]) => ({
278
+ id,
279
+ kind: declaration.kind,
280
+ service: (0, _geekmidas_manifest.serviceKey)(id),
281
+ source: sources[id]
282
+ }));
283
+ }
284
+ /** An import specifier for `file`, from the harness written into `dir`. */
285
+ function specifierFrom(dir, file) {
286
+ const path = (0, node_path.relative)(dir, file).replace(/\.tsx?$/, ".js");
287
+ return path.startsWith(".") ? path : `./${path}`;
288
+ }
289
+ function harnessModule(options) {
290
+ const { surfaces, auths, drivers, databases, services, dir, files, factories, fakes, mail } = options;
291
+ const magicLinks = mail ? auths.filter(({ plugins }) => plugins.includes("magicLinkClient")) : [];
292
+ const signIn = magicLinks.length === 1 ? magicLinks[0] : void 0;
293
+ const plugins = [...new Set(auths.flatMap(({ plugins }) => plugins))].sort();
294
+ const imports = [
295
+ `import {${services.length ? " type ClientOf," : ""}${databases.length ? " type DatabaseOf," : ""} featureTest, loadTestManifest${signIn ? ", signInWithMagicLink" : ""} } from '@geekmidas/constructs/testing';`,
296
+ ...[...new Map([...databases, ...services].map((construct) => [construct.id, construct])).values()].map(({ id, source }) => `import type { ${source.exportName} as __${id} } from '${specifierFrom(dir, source.file)}';`),
297
+ `import { Browser as TestBrowser } from '@geekmidas/testkit/browser';`,
298
+ ...surfaces.map(({ id }) => `import { createApi as create${id} } from './clients/${(0, _geekmidas_manifest.kebabCase)(id)}.js';`),
299
+ ...auths.length ? [`import { createAuthClient } from 'better-auth/client';`] : [],
300
+ ...plugins.length ? [`import { ${plugins.join(", ")} } from 'better-auth/client/plugins';`] : [],
301
+ ...drivers.imports ? [drivers.imports] : [],
302
+ ...factories.map(({ file, service }) => `import { createFactory as __${service}Factory } from '${specifierFrom(dir, file)}';`),
303
+ ...fakes.map(({ id, file }) => `import __${id}Fake from '${specifierFrom(dir, file)}';`),
304
+ ...files.map((file, index) => `import * as __module${index} from '${specifierFrom(dir, file)}';`)
305
+ ];
306
+ const url = (id) => `manifest.env[${JSON.stringify((0, _geekmidas_manifest.provideKey)(id, "url"))}]!`;
307
+ const members = [
308
+ ...surfaces.map(({ id, secured }) => ` /** \`${id}\`, at ${(0, _geekmidas_manifest.provideKey)(id, "url")}. */
309
+ readonly ${propertyOf(id)} = create${id}({
310
+ baseURL: ${url(id)},
311
+ fetch: this.fetch,${secured ? `
312
+ // Served in-process: no authorizer runs, so nothing is signed. A scheme
313
+ // with no strategy sends its request without credentials.
314
+ authStrategies: {} as never,` : ""}
315
+ });`),
316
+ ...auths.map((auth) => ` /** \`${auth.id}\`, at ${(0, _geekmidas_manifest.provideKey)(auth.id, "url")}. */
317
+ readonly ${propertyOf(auth.id)} = createAuthClient({
318
+ baseURL: \`\${${url(auth.id)}}${auth.basePath}\`,
319
+ plugins: [${auth.plugins.map((plugin) => `${plugin}()`).join(", ")}],
320
+ fetchOptions: { customFetchImpl: this.fetch },
321
+ });`),
322
+ ...signIn ? [` /**
323
+ * Sign in as \`email\` through \`${signIn.id}\`'s magic link, the way a person
324
+ * does — the email opened, the link followed. The session it then reports.
325
+ * Without an address, as somebody new: \`user.email\` says who.
326
+ */
327
+ signIn(email?: string) {
328
+ return signInWithMagicLink(this, this.${propertyOf(signIn.id)}, email);
329
+ }`] : []
330
+ ];
331
+ const factoriesType = factories.length ? `{ ${factories.map(({ service }) => `${service}: typeof __${service}Factory`).join("; ")} }` : "";
332
+ const factoriesOption = factories.length ? `, factories: { ${factories.map(({ service }) => `${service}: __${service}Factory`).join(", ")} }` : "";
333
+ const fakesOption = fakes.length ? `, fakes: { ${fakes.map(({ id }) => `${id}: __${id}Fake`).join(", ")} }` : "";
334
+ const databasesType = `{ ${databases.map(({ id, service }) => `${service}: DatabaseOf<typeof __${id}>`).join("; ")} }`;
335
+ const servicesType = services.length ? `{ ${services.map(({ id, service }) => `${service}: ClientOf<typeof __${id}>`).join("; ")} }` : "";
336
+ const generics = databases.length || factoriesType || servicesType ? `<Browser, ${databases.length ? databasesType : "{}"}${factoriesType || servicesType ? `, ${factoriesType || "{}"}` : ""}${servicesType ? `, ${servicesType}` : ""}>` : "";
337
+ return `// Generated by \`gkm test\` from the app's constructs — do not edit.
338
+ ${imports.join("\n")}
339
+
340
+ ${drivers.setup ? `// The drivers the app's server entry registers, registered the same way.\n${drivers.setup}\n\n` : ""}const manifest = loadTestManifest(new URL('./manifest.json', import.meta.url));
341
+
342
+ /** A browser with a client for every surface the app declares. */
343
+ export class Browser extends TestBrowser {
344
+ ${members.join("\n\n")}
345
+ }
346
+
347
+ /** The app's modules, by the path the manifest records for each. */
348
+ const modules = {
349
+ ${files.map((file, index) => `\t${JSON.stringify(file)}: __module${index},`).join("\n")}
350
+ };
351
+
352
+ /** \`it\`, for a test that drives the app the way it runs deployed. */
353
+ export const it = featureTest${generics}({ manifest, modules, browser: Browser${factoriesOption}${fakesOption} });
354
+ `;
355
+ }
356
+ //#endregion
357
+ //#region src/test/ready.ts
358
+ /**
359
+ * The hand-off between `gkm test` and the Vitest global setup.
360
+ *
361
+ * `gkm test` reconciles and migrates the test stage before Vitest starts; the
362
+ * setup, run inside Vitest, only has to load what that left. Started by plain
363
+ * `vitest` instead, the setup runs `gkm test --setup` itself first — so there is
364
+ * one way the stage gets ready, whichever started the suite.
365
+ */
366
+ /** Set on the Vitest process by `gkm test`: the stage is ready, here. */
367
+ const TEST_READY_ENV = "GKM_TEST_READY";
368
+ /** Where `gkm test` records what it prepared, from where it ran. */
369
+ const TEST_READY_FILE = ".gkm/test-ready.json";
370
+ //#endregion
371
+ Object.defineProperty(exports, "DEFAULT_FACTORIES_DIR", {
372
+ enumerable: true,
373
+ get: function() {
374
+ return DEFAULT_FACTORIES_DIR;
375
+ }
376
+ });
377
+ Object.defineProperty(exports, "TEST_MANIFEST_ENV", {
378
+ enumerable: true,
379
+ get: function() {
380
+ return TEST_MANIFEST_ENV;
381
+ }
382
+ });
383
+ Object.defineProperty(exports, "TEST_READY_ENV", {
384
+ enumerable: true,
385
+ get: function() {
386
+ return TEST_READY_ENV;
387
+ }
388
+ });
389
+ Object.defineProperty(exports, "TEST_READY_FILE", {
390
+ enumerable: true,
391
+ get: function() {
392
+ return TEST_READY_FILE;
393
+ }
394
+ });
395
+ Object.defineProperty(exports, "writeTestHarness", {
396
+ enumerable: true,
397
+ get: function() {
398
+ return writeTestHarness;
399
+ }
400
+ });
401
+
402
+ //# sourceMappingURL=ready-BpNbORRB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ready-BpNbORRB.cjs","names":["readdir","join","canonicalId","extname","pathToFileURL","serviceKey","discover","EndpointGenerator","SubscriberGenerator","OpenApiTsGenerator","kebabCase","driversFor","cacheBackendsIn","eventsBackendsIn","readFakes","rm","mkdir","writeFile","EnvironmentParser","serviceContext","relative","provideKey"],"sources":["../src/test/harness.ts","../src/test/ready.ts"],"sourcesContent":["/**\n * What `gkm test` writes for a feature test to be built from.\n *\n * `gkm test` already discovers an app's constructs and resolves the test\n * stage's environment; this keeps both, under `.gkm/test/`:\n *\n * - `manifest.json` — which construct and endpoint is exported where, and the\n * environment the test stage resolved, keyed as the constructs derive keys.\n * - `clients/<surface>.ts` — each surface's typed client, from the same\n * generator `gkm build` uses for the app's own.\n * - `index.ts` — the configured `it`, and a `Browser` holding one client per\n * surface and one per auth server, each on the browser's `fetch`.\n *\n * A test imports `it` from there and declares nothing — not a construct, not an\n * environment key, not a client.\n */\n\nimport { mkdir, readdir, rm, writeFile } from 'node:fs/promises';\nimport { extname, join, relative } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { TestStage } from '@geekmidas/constructs';\nimport type { BetterAuth } from '@geekmidas/constructs/auth';\nimport type { Endpoint } from '@geekmidas/constructs/endpoints';\nimport type { TestManifest } from '@geekmidas/constructs/testing';\nimport { EnvironmentParser } from '@geekmidas/envkit';\nimport {\n\tcanonicalId,\n\tkebabCase,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport { serviceContext } from '@geekmidas/services';\nimport {\n\tcacheBackendsIn,\n\tdriversFor,\n\teventsBackendsIn,\n\ttype RuntimeDrivers,\n} from '../generators/drivers.js';\nimport { EndpointGenerator } from '../generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from '../generators/OpenApiTsGenerator.js';\nimport { SubscriberGenerator } from '../generators/SubscriberGenerator.js';\nimport { type ConstructSource, discover } from '../reconcile/discover.js';\nimport { readFakes } from '../reconcile/fakes.js';\nimport type { CacheBackend, EventsBackend } from '../types.js';\n\n/**\n * The variable the manifest's path travels in — what\n * `@geekmidas/constructs/testing` reads. Its own constant rather than an import:\n * that entry carries the whole harness (MSW, Hono, Vitest), and importing it\n * here put all of it on the start-up path of every `gkm` command.\n */\nexport const TEST_MANIFEST_ENV = 'GKM_TEST_MANIFEST';\n\n/** Where the harness lives, relative to the workspace root. */\nexport const TEST_HARNESS_DIR = '.gkm/test';\n\n/**\n * Better-auth's client plugin for each server plugin id.\n *\n * Written down rather than derived: the ids and the client names do not follow\n * one rule (`admin` pairs with `adminClient`, `email-otp` with\n * `emailOTPClient`), and a guess that missed would hand a test a client\n * silently lacking every method of that plugin. A server plugin not listed has\n * no client counterpart — `bearer`, `open-api` — or needs one from another\n * package, and is left out.\n */\nconst CLIENT_PLUGINS: Readonly<Record<string, string>> = {\n\tadmin: 'adminClient',\n\tanonymous: 'anonymousClient',\n\t'device-authorization': 'deviceAuthorizationClient',\n\t'email-otp': 'emailOTPClient',\n\tjwt: 'jwtClient',\n\t'last-login-method': 'lastLoginMethodClient',\n\t'magic-link': 'magicLinkClient',\n\t'multi-session': 'multiSessionClient',\n\t'oauth-popup': 'oauthPopupClient',\n\t'one-tap': 'oneTapClient',\n\t'one-time-token': 'oneTimeTokenClient',\n\torganization: 'organizationClient',\n\t'phone-number': 'phoneNumberClient',\n\tsiwe: 'siweClient',\n\t'two-factor': 'twoFactorClient',\n\tusername: 'usernameClient',\n};\n\nexport interface WriteTestHarnessOptions {\n\t/** The workspace root: where discovery runs from. */\n\troot: string;\n\t/**\n\t * The directories to write `.gkm/test/` into — each app's own. A package\n\t * maps its `#test` import only to a path inside itself, so each app gets its\n\t * own copy of the harness rather than one at the root it cannot reach.\n\t */\n\ttargets: string[];\n\t/** The constructs glob — the same patterns reconcile and the build use. */\n\tpatterns: string[];\n\t/** The stage the environment was resolved for: always `test`. */\n\tstage: TestStage;\n\t/** The environment the suite runs with. */\n\tenv: Record<string, string>;\n\t/**\n\t * Where a cache lives when it names nowhere — the target's default, which\n\t * the build's server entry registers a driver for.\n\t */\n\tcacheBackend: CacheBackend;\n\t/**\n\t * The broker the target puts topics and queues on, which the server entry\n\t * registers a driver for when the app declares one.\n\t */\n\teventsBackend: EventsBackend;\n\t/**\n\t * The folder of test factories, absolute: `test/factories` at the root, or\n\t * where `test.factories` in the config points. Absent or empty, a test is\n\t * handed no factories.\n\t */\n\tfactories?: string;\n}\n\n/** Where a project keeps its test factories, relative to its root. */\nexport const DEFAULT_FACTORIES_DIR = 'test/factories';\n\n/** A file in the factories folder that names no database construct. */\nexport class UnknownFactoryFile extends Error {\n\tconstructor(\n\t\treadonly file: string,\n\t\treadonly known: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`${file} names no database construct, so no test could be handed it. ` +\n\t\t\t\t(known.length > 0\n\t\t\t\t\t? `The databases: ${known.join(', ')}. `\n\t\t\t\t\t: 'This project declares no database. ') +\n\t\t\t\t`Name a factory after its database: test/factories/<construct>.ts.`,\n\t\t);\n\t\tthis.name = 'UnknownFactoryFile';\n\t}\n}\n\n/** A factory file that exports no `createFactory`. */\nexport class FactoryHasNoCreate extends Error {\n\tconstructor(readonly file: string) {\n\t\tsuper(\n\t\t\t`${file} is a test factory but exports no \\`createFactory\\`. ` +\n\t\t\t\t`Export \\`function createFactory(db: Kysely<Database>)\\` returning ` +\n\t\t\t\t`the factory.`,\n\t\t);\n\t\tthis.name = 'FactoryHasNoCreate';\n\t}\n}\n\n/** One database's factory: the file, and the service name a test keys it by. */\nexport interface FactorySource {\n\tfile: string;\n\tservice: string;\n}\n\n/**\n * The factories in a folder, each matched to the database it is named after.\n *\n * A file that names no database, or exports no `createFactory`, is refused\n * rather than skipped: either is a factory no test would ever be handed.\n */\nexport async function factorySources(\n\tfolder: string | undefined,\n\tdatabases: readonly string[],\n): Promise<FactorySource[]> {\n\tif (!folder) return [];\n\n\tconst entries = await readdir(folder, { withFileTypes: true }).catch(\n\t\t(error: NodeJS.ErrnoException) => {\n\t\t\tif (error.code === 'ENOENT') return [];\n\t\t\tthrow error;\n\t\t},\n\t);\n\n\tconst found: FactorySource[] = [];\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !isFactoryFile(entry.name)) continue;\n\n\t\tconst file = join(folder, entry.name);\n\t\tconst id = canonicalId(entry.name.slice(0, -extname(entry.name).length));\n\t\tif (!databases.includes(id)) {\n\t\t\tthrow new UnknownFactoryFile(file, databases);\n\t\t}\n\n\t\tconst module = (await import(pathToFileURL(file).href)) as {\n\t\t\tcreateFactory?: unknown;\n\t\t};\n\t\tif (typeof module.createFactory !== 'function') {\n\t\t\tthrow new FactoryHasNoCreate(file);\n\t\t}\n\n\t\tfound.push({ file, service: serviceKey(id) });\n\t}\n\n\treturn found.sort((a, b) => (a.service < b.service ? -1 : 1));\n}\n\nfunction isFactoryFile(file: string): boolean {\n\tif (file.endsWith('.d.ts')) return false;\n\tif (/\\.(spec|test)\\.[cm]?[jt]s$/.test(file)) return false;\n\treturn ['.ts', '.mts', '.js', '.mjs'].includes(extname(file));\n}\n\n/** Write the manifest, the clients and the harness; return the manifest path. */\nexport async function writeTestHarness(\n\toptions: WriteTestHarnessOptions,\n): Promise<string> {\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst declared = await discover({\n\t\tpatterns: options.patterns,\n\t\tcwd: options.root,\n\t\tsources,\n\t});\n\n\tconst loaded = await new EndpointGenerator().load(\n\t\toptions.patterns,\n\t\toptions.root,\n\t);\n\tconst endpoints = loaded\n\t\t.map(({ key, construct, path }) => ({\n\t\t\tsurface: construct.owner ?? construct.surface?.id,\n\t\t\tconstruct,\n\t\t\tsource: { file: path.absolute, export: key },\n\t\t}))\n\t\t.filter(\n\t\t\t(endpoint): endpoint is typeof endpoint & { surface: string } =>\n\t\t\t\tendpoint.surface !== undefined,\n\t\t);\n\n\t// Topic subscribers, which a test delivers to. Not constructs, so the build\n\t// finds them the way it finds endpoints.\n\tconst subscribers = (\n\t\tawait new SubscriberGenerator().load(options.patterns, options.root)\n\t).map(({ key, path }) => ({ source: { file: path.absolute, export: key } }));\n\n\tconst manifest: TestManifest = {\n\t\tstage: options.stage,\n\t\tconstructs: Object.fromEntries(\n\t\t\tObject.entries(declared).flatMap(([id, declaration]) => {\n\t\t\t\tconst source = sources[id];\n\t\t\t\treturn source\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tkind: declaration.kind,\n\t\t\t\t\t\t\t\t\tsource: { file: source.file, export: source.exportName },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\t}),\n\t\t),\n\t\tendpoints: endpoints.map(({ surface, source }) => ({ surface, source })),\n\t\tsubscribers,\n\t\tenv: options.env,\n\t};\n\t// One typed client per surface, from the generator the build uses.\n\tconst surfaces = [...new Set(endpoints.map(({ surface }) => surface))];\n\tconst generator = new OpenApiTsGenerator();\n\tconst clients = await Promise.all(\n\t\tsurfaces.map(async (surface) => ({\n\t\t\tfile: `${kebabCase(surface)}.ts`,\n\t\t\tcontent: await generator.generate(\n\t\t\t\tendpoints\n\t\t\t\t\t.filter((endpoint) => endpoint.surface === surface)\n\t\t\t\t\t.map(({ construct }) => construct as Endpoint<any, any, any, any>),\n\t\t\t\t{ title: surface, version: '1.0.0' },\n\t\t\t),\n\t\t})),\n\t);\n\n\tconst auths = await authClients(declared, sources, options.env);\n\t// The drivers the server entry registers — which cache and storage clients\n\t// exist is the entry's decision, and the harness stands where the entry does.\n\tconst drivers = driversFor({\n\t\tappRoot: options.root,\n\t\tcache: cacheBackendsIn(declared, options.cacheBackend),\n\t\tevents: eventsBackendsIn(declared, options.eventsBackend),\n\t});\n\n\t// The app's own databases: not a tenant an auth server owns — reached\n\t// through that server — and not a reader of one. What a test is handed.\n\tconst owners = new Set(auths.map((auth) => auth.databaseId));\n\tconst databases = databaseSources(declared, sources).filter(\n\t\t({ id, kind }) => !owners.has(id) && kind !== 'database-reader',\n\t);\n\tconst factories = await factorySources(\n\t\toptions.factories,\n\t\tdatabases.map(({ id }) => id),\n\t);\n\t// Each external API's fake, from the convention rather than the construct —\n\t// which is what keeps a fake out of every deployed bundle.\n\tconst fakes = Object.entries(await readFakes(options.root, declared)).map(\n\t\t([id, { file }]) => ({ id, file }),\n\t);\n\t// Every construct a handler can depend on — what a test reaches through\n\t// `services.get(…)`, typed by the client its service registers. A tenant an\n\t// auth server owns is reached through that server, as databases are.\n\tconst services = serviceSources(declared, sources).filter(\n\t\t({ id }) => !owners.has(id),\n\t);\n\tconst files = [\n\t\t...new Set([\n\t\t\t...Object.values(manifest.constructs).map(({ source }) => source.file),\n\t\t\t...manifest.endpoints.map(({ source }) => source.file),\n\t\t\t// Delivery loads each subscriber too. Left to a dynamic import, it is\n\t\t\t// resolved by Node — which knows nothing of the app's tsconfig paths, so\n\t\t\t// a subscriber importing `~/…` failed every test file that delivered.\n\t\t\t...(manifest.subscribers ?? []).map(({ source }) => source.file),\n\t\t]),\n\t];\n\tconst harnessFor = (dir: string) =>\n\t\tharnessModule({\n\t\t\tdir,\n\t\t\tfiles,\n\t\t\tdatabases,\n\t\t\tsurfaces: surfaces.map((id, index) => ({\n\t\t\t\tid,\n\t\t\t\t// The client the generator writes for a surface with authorizers\n\t\t\t\t// takes a strategy per scheme; one without takes none.\n\t\t\t\tsecured: clients[index]!.content.includes('authStrategies:'),\n\t\t\t})),\n\t\t\tauths,\n\t\t\tdrivers,\n\t\t\tfactories,\n\t\t\tfakes,\n\t\t\tservices,\n\t\t\tmail: Object.values(declared).some(({ kind }) => kind === 'email'),\n\t\t});\n\tconst json = `${JSON.stringify(manifest, null, 2)}\\n`;\n\n\tconst written = await Promise.all(\n\t\t[...new Set(options.targets)].map(async (target) => {\n\t\t\tconst dir = join(target, TEST_HARNESS_DIR);\n\t\t\t// Rewritten whole on every run: a client for a surface that no longer\n\t\t\t// exists is not something a test should be able to import.\n\t\t\tawait rm(dir, { recursive: true, force: true });\n\t\t\tawait mkdir(join(dir, 'clients'), { recursive: true });\n\t\t\tawait writeFile(join(dir, 'manifest.json'), json);\n\t\t\tawait writeFile(join(dir, 'index.ts'), harnessFor(dir));\n\t\t\tfor (const client of clients) {\n\t\t\t\tawait writeFile(join(dir, 'clients', client.file), client.content);\n\t\t\t}\n\t\t\treturn join(dir, 'manifest.json');\n\t\t}),\n\t);\n\n\treturn written[0]!;\n}\n\ninterface AuthClient {\n\tid: string;\n\tbasePath: string;\n\tplugins: string[];\n\t/** The schema tenant it owns — reached through it, never by a test. */\n\tdatabaseId: string;\n}\n\n/** Each auth server, with the client plugins its server plugins pair with. */\nasync function authClients(\n\tdeclared: Awaited<ReturnType<typeof discover>>,\n\tsources: Record<string, ConstructSource>,\n\tenv: Record<string, string>,\n): Promise<AuthClient[]> {\n\tconst clients: AuthClient[] = [];\n\tconst envParser = new EnvironmentParser({ ...env });\n\n\tfor (const [id, declaration] of Object.entries(declared)) {\n\t\tconst source = sources[id];\n\t\tif (declaration.kind !== 'rest-api' || !source) continue;\n\n\t\tconst exported = (await import(source.file))[source.exportName] as unknown;\n\t\tif (!isBetterAuth(exported) || exported.id !== id) continue;\n\n\t\tconst ids = await exported.pluginIds({\n\t\t\tenvParser,\n\t\t\tcontext: serviceContext,\n\t\t});\n\t\tclients.push({\n\t\t\tid,\n\t\t\tbasePath: exported.basePath,\n\t\t\tplugins: ids.flatMap((plugin) => CLIENT_PLUGINS[plugin] ?? []),\n\t\t\tdatabaseId: exported.databaseId,\n\t\t});\n\t}\n\n\treturn clients;\n}\n\nfunction isBetterAuth(value: unknown): value is BetterAuth {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'pluginIds' in value &&\n\t\t'basePath' in value\n\t);\n}\n\n/** `Api` → `api`, `AdminApi` → `adminApi`: a construct id as a property name. */\nfunction propertyOf(id: string): string {\n\treturn id.charAt(0).toLowerCase() + id.slice(1);\n}\n\n/**\n * The database a test's `db` is — the one the endpoints were given with\n * `.database()`, found by the service they hold, which is the construct's own.\n * The same rule `featureTest` applies at runtime, applied here so `db` can be\n * typed by the construct's schema.\n */\n/** A database construct: its id, its service name, and where it is exported. */\ninterface DatabaseSource {\n\tid: string;\n\tkind: string;\n\tservice: string;\n\tsource: ConstructSource;\n}\n\n/**\n * Every database construct the app declares — a database, a schema tenant, a\n * reader — keyed as a test is handed its transaction.\n */\nfunction databaseSources(\n\tdeclared: Awaited<ReturnType<typeof discover>>,\n\tsources: Record<string, ConstructSource>,\n): DatabaseSource[] {\n\treturn Object.entries(declared)\n\t\t.filter(([id, declaration]) =>\n\t\t\tBoolean(sources[id] && declaration.kind.startsWith('database')),\n\t\t)\n\t\t.map(([id, declaration]) => ({\n\t\t\tid,\n\t\t\tkind: declaration.kind,\n\t\t\tservice: serviceKey(id),\n\t\t\tsource: sources[id]!,\n\t\t}));\n}\n\n/** The kinds whose construct hands a handler a client — what `services` reaches. */\nconst SERVICE_KINDS = new Set([\n\t'cache',\n\t'credential',\n\t'database',\n\t'database-schema',\n\t'database-reader',\n\t'email',\n\t'encryption',\n\t'external-api',\n\t'file-server',\n\t'objects',\n\t'queue',\n\t'topic',\n]);\n\nfunction serviceSources(\n\tdeclared: Awaited<ReturnType<typeof discover>>,\n\tsources: Record<string, ConstructSource>,\n): DatabaseSource[] {\n\treturn Object.entries(declared)\n\t\t.filter(([id, declaration]) =>\n\t\t\tBoolean(sources[id] && SERVICE_KINDS.has(declaration.kind)),\n\t\t)\n\t\t.map(([id, declaration]) => ({\n\t\t\tid,\n\t\t\tkind: declaration.kind,\n\t\t\tservice: serviceKey(id),\n\t\t\tsource: sources[id]!,\n\t\t}));\n}\n\n/** An import specifier for `file`, from the harness written into `dir`. */\nfunction specifierFrom(dir: string, file: string): string {\n\tconst path = relative(dir, file).replace(/\\.tsx?$/, '.js');\n\treturn path.startsWith('.') ? path : `./${path}`;\n}\n\nfunction harnessModule(options: {\n\tdir: string;\n\t/** Every module the manifest points at, by absolute path. */\n\tfiles: string[];\n\tdatabases: DatabaseSource[];\n\t/** Every construct a test reaches through `services`, by service name. */\n\tservices: DatabaseSource[];\n\tsurfaces: { id: string; secured: boolean }[];\n\tauths: AuthClient[];\n\tdrivers: RuntimeDrivers;\n\tfactories: FactorySource[];\n\t/** Each external API's fake, by construct id and the file it lives in. */\n\tfakes: { id: string; file: string }[];\n\t/** Whether the app sends mail — what a magic-link sign-in is read from. */\n\tmail: boolean;\n}): string {\n\tconst {\n\t\tsurfaces,\n\t\tauths,\n\t\tdrivers,\n\t\tdatabases,\n\t\tservices,\n\t\tdir,\n\t\tfiles,\n\t\tfactories,\n\t\tfakes,\n\t\tmail,\n\t} = options;\n\t// One auth server a test can sign in to without a person: a magic link,\n\t// read from the app's inbox. With two, which one \\`signIn\\` means is a\n\t// guess, so neither gets it.\n\tconst magicLinks = mail\n\t\t? auths.filter(({ plugins }) => plugins.includes('magicLinkClient'))\n\t\t: [];\n\tconst signIn = magicLinks.length === 1 ? magicLinks[0] : undefined;\n\tconst plugins = [...new Set(auths.flatMap(({ plugins }) => plugins))].sort();\n\n\tconst imports = [\n\t\t`import {${services.length ? ' type ClientOf,' : ''}${databases.length ? ' type DatabaseOf,' : ''} featureTest, loadTestManifest${signIn ? ', signInWithMagicLink' : ''} } from '@geekmidas/constructs/testing';`,\n\t\t// A type import per construct the types name: each database, and each\n\t\t// construct a test reaches through `services` — once, though a database\n\t\t// is both.\n\t\t...[\n\t\t\t...new Map(\n\t\t\t\t[...databases, ...services].map((construct) => [\n\t\t\t\t\tconstruct.id,\n\t\t\t\t\tconstruct,\n\t\t\t\t]),\n\t\t\t).values(),\n\t\t].map(\n\t\t\t({ id, source }) =>\n\t\t\t\t`import type { ${source.exportName} as __${id} } from '${specifierFrom(dir, source.file)}';`,\n\t\t),\n\t\t`import { Browser as TestBrowser } from '@geekmidas/testkit/browser';`,\n\t\t...surfaces.map(\n\t\t\t({ id }) =>\n\t\t\t\t`import { createApi as create${id} } from './clients/${kebabCase(id)}.js';`,\n\t\t),\n\t\t...(auths.length\n\t\t\t? [`import { createAuthClient } from 'better-auth/client';`]\n\t\t\t: []),\n\t\t...(plugins.length\n\t\t\t? [`import { ${plugins.join(', ')} } from 'better-auth/client/plugins';`]\n\t\t\t: []),\n\t\t...(drivers.imports ? [drivers.imports] : []),\n\t\t...factories.map(\n\t\t\t({ file, service }) =>\n\t\t\t\t`import { createFactory as __${service}Factory } from '${specifierFrom(dir, file)}';`,\n\t\t),\n\t\t...fakes.map(\n\t\t\t({ id, file }) =>\n\t\t\t\t`import __${id}Fake from '${specifierFrom(dir, file)}';`,\n\t\t),\n\t\t// Every construct and endpoint module, imported here — inside the app,\n\t\t// where its tsconfig paths resolve — rather than by path from the kit.\n\t\t...files.map(\n\t\t\t(file, index) =>\n\t\t\t\t`import * as __module${index} from '${specifierFrom(dir, file)}';`,\n\t\t),\n\t];\n\n\tconst url = (id: string) =>\n\t\t`manifest.env[${JSON.stringify(provideKey(id, 'url'))}]!`;\n\n\tconst members = [\n\t\t...surfaces.map(\n\t\t\t({ id, secured }) => `\t/** \\`${id}\\`, at ${provideKey(id, 'url')}. */\n\treadonly ${propertyOf(id)} = create${id}({\n\t\tbaseURL: ${url(id)},\n\t\tfetch: this.fetch,${\n\t\t\tsecured\n\t\t\t\t? `\n\t\t// Served in-process: no authorizer runs, so nothing is signed. A scheme\n\t\t// with no strategy sends its request without credentials.\n\t\tauthStrategies: {} as never,`\n\t\t\t\t: ''\n\t\t}\n\t});`,\n\t\t),\n\t\t...auths.map(\n\t\t\t(auth) => `\t/** \\`${auth.id}\\`, at ${provideKey(auth.id, 'url')}. */\n\treadonly ${propertyOf(auth.id)} = createAuthClient({\n\t\tbaseURL: \\`\\${${url(auth.id)}}${auth.basePath}\\`,\n\t\tplugins: [${auth.plugins.map((plugin) => `${plugin}()`).join(', ')}],\n\t\tfetchOptions: { customFetchImpl: this.fetch },\n\t});`,\n\t\t),\n\t\t...(signIn\n\t\t\t? [\n\t\t\t\t\t`\t/**\n\t * Sign in as \\`email\\` through \\`${signIn.id}\\`'s magic link, the way a person\n\t * does — the email opened, the link followed. The session it then reports.\n\t * Without an address, as somebody new: \\`user.email\\` says who.\n\t */\n\tsignIn(email?: string) {\n\t\treturn signInWithMagicLink(this, this.${propertyOf(signIn.id)}, email);\n\t}`,\n\t\t\t\t]\n\t\t\t: []),\n\t];\n\n\t// Each database's factory, keyed as the test is handed it.\n\tconst factoriesType = factories.length\n\t\t? `{ ${factories.map(({ service }) => `${service}: typeof __${service}Factory`).join('; ')} }`\n\t\t: '';\n\tconst factoriesOption = factories.length\n\t\t? `, factories: { ${factories.map(({ service }) => `${service}: __${service}Factory`).join(', ')} }`\n\t\t: '';\n\tconst fakesOption = fakes.length\n\t\t? `, fakes: { ${fakes.map(({ id }) => `${id}: __${id}Fake`).join(', ')} }`\n\t\t: '';\n\t// Each database's schema, keyed as the test is handed its transaction.\n\tconst databasesType = `{ ${databases.map(({ id, service }) => `${service}: DatabaseOf<typeof __${id}>`).join('; ')} }`;\n\t// Each construct's client, keyed as `services.get(…)` is called.\n\tconst servicesType = services.length\n\t\t? `{ ${services.map(({ id, service }) => `${service}: ClientOf<typeof __${id}>`).join('; ')} }`\n\t\t: '';\n\t// Positional, so a later one needs those before it, even when empty.\n\tconst generics =\n\t\tdatabases.length || factoriesType || servicesType\n\t\t\t? `<Browser, ${databases.length ? databasesType : '{}'}${\n\t\t\t\t\tfactoriesType || servicesType ? `, ${factoriesType || '{}'}` : ''\n\t\t\t\t}${servicesType ? `, ${servicesType}` : ''}>`\n\t\t\t: '';\n\n\treturn `// Generated by \\`gkm test\\` from the app's constructs — do not edit.\n${imports.join('\\n')}\n\n${drivers.setup ? `// The drivers the app's server entry registers, registered the same way.\\n${drivers.setup}\\n\\n` : ''}const manifest = loadTestManifest(new URL('./manifest.json', import.meta.url));\n\n/** A browser with a client for every surface the app declares. */\nexport class Browser extends TestBrowser {\n${members.join('\\n\\n')}\n}\n\n/** The app's modules, by the path the manifest records for each. */\nconst modules = {\n${files.map((file, index) => `\\t${JSON.stringify(file)}: __module${index},`).join('\\n')}\n};\n\n/** \\`it\\`, for a test that drives the app the way it runs deployed. */\nexport const it = featureTest${generics}({ manifest, modules, browser: Browser${factoriesOption}${fakesOption} });\n`;\n}\n","/**\n * The hand-off between `gkm test` and the Vitest global setup.\n *\n * `gkm test` reconciles and migrates the test stage before Vitest starts; the\n * setup, run inside Vitest, only has to load what that left. Started by plain\n * `vitest` instead, the setup runs `gkm test --setup` itself first — so there is\n * one way the stage gets ready, whichever started the suite.\n */\n\n/** Set on the Vitest process by `gkm test`: the stage is ready, here. */\nexport const TEST_READY_ENV = 'GKM_TEST_READY';\n\n/** Where `gkm test` records what it prepared, from where it ran. */\nexport const TEST_READY_FILE = '.gkm/test-ready.json';\n\nexport interface TestReady {\n\t/** The resolved environment, as a JSON object of strings. */\n\tenv: string;\n\t/** The test manifest the `#test` harness reads. */\n\tmanifest?: string;\n\t/**\n\t * The test stage's databases this run created, and the port of the\n\t * Postgres that holds them: what `gkm test --teardown` drops when the\n\t * suite ends — or, if a run was killed before its teardown, what the next\n\t * one drops before it starts.\n\t */\n\tdatabases?: { port: number; names: string[] };\n}\n"],"mappings":"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"}