@geekmidas/constructs 10.0.0-alpha.4 → 10.0.0-alpha.41

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 (370) hide show
  1. package/README.md +223 -158
  2. package/dist/{Construct-BD5neF7w.mjs → Construct-BO1X-kt9.mjs} +32 -33
  3. package/dist/Construct-BO1X-kt9.mjs.map +1 -0
  4. package/dist/Construct-BQALFCh2.d.cts +230 -0
  5. package/dist/Construct-BQALFCh2.d.cts.map +1 -0
  6. package/dist/{Construct-CyS3RpTL.cjs → Construct-DmvXceVY.cjs} +52 -47
  7. package/dist/Construct-DmvXceVY.cjs.map +1 -0
  8. package/dist/Construct-QXnl3VqT.d.mts +230 -0
  9. package/dist/Construct-QXnl3VqT.d.mts.map +1 -0
  10. package/dist/{Cron-B2OFsfDM.d.cts → Cron-CMEGfRs8.d.cts} +21 -8
  11. package/dist/Cron-CMEGfRs8.d.cts.map +1 -0
  12. package/dist/{Cron-ByxdOfpE.d.mts → Cron-D6X4-xjB.d.mts} +21 -8
  13. package/dist/Cron-D6X4-xjB.d.mts.map +1 -0
  14. package/dist/CronBuilder-CEK7aOqD.d.cts +46 -0
  15. package/dist/CronBuilder-CEK7aOqD.d.cts.map +1 -0
  16. package/dist/CronBuilder-DB35T5dL.cjs +116 -0
  17. package/dist/CronBuilder-DB35T5dL.cjs.map +1 -0
  18. package/dist/CronBuilder-Dv0IlZs0.mjs +104 -0
  19. package/dist/CronBuilder-Dv0IlZs0.mjs.map +1 -0
  20. package/dist/CronBuilder-O_gvButp.d.mts +46 -0
  21. package/dist/CronBuilder-O_gvButp.d.mts.map +1 -0
  22. package/dist/{Endpoint-Dij_wOcc.mjs → Endpoint-CQAeh1Rh.mjs} +117 -109
  23. package/dist/Endpoint-CQAeh1Rh.mjs.map +1 -0
  24. package/dist/{Endpoint-DODn1RhN.cjs → Endpoint-D1L9qu5C.cjs} +145 -131
  25. package/dist/Endpoint-D1L9qu5C.cjs.map +1 -0
  26. package/dist/{Endpoint-2Wg7T7Cq.d.mts → Endpoint-Dp5AKIXl.d.cts} +69 -93
  27. package/dist/Endpoint-Dp5AKIXl.d.cts.map +1 -0
  28. package/dist/{Endpoint-DrD8a1yH.d.cts → Endpoint-DtI7heFm.d.mts} +70 -94
  29. package/dist/Endpoint-DtI7heFm.d.mts.map +1 -0
  30. package/dist/{EndpointFactory-b4ituq-s.mjs → EndpointFactory-BBdNeaGJ.mjs} +39 -74
  31. package/dist/EndpointFactory-BBdNeaGJ.mjs.map +1 -0
  32. package/dist/{EndpointFactory-BHFMmFkV.cjs → EndpointFactory-BZOCOaK6.cjs} +75 -110
  33. package/dist/EndpointFactory-BZOCOaK6.cjs.map +1 -0
  34. package/dist/{index-BxHDdy6a.d.mts → EndpointFactory-CgMDvERK.d.mts} +63 -133
  35. package/dist/EndpointFactory-CgMDvERK.d.mts.map +1 -0
  36. package/dist/{index-B8g8POkr.d.cts → EndpointFactory-FeFRmlDZ.d.cts} +62 -132
  37. package/dist/EndpointFactory-FeFRmlDZ.d.cts.map +1 -0
  38. package/dist/{HonoEndpointAdaptor-BM2jbWht.mjs → HonoEndpointAdaptor-Aui-x9Lg.mjs} +41 -47
  39. package/dist/HonoEndpointAdaptor-Aui-x9Lg.mjs.map +1 -0
  40. package/dist/{HonoEndpointAdaptor-De6IlBZe.cjs → HonoEndpointAdaptor-Cq99r9H7.cjs} +50 -53
  41. package/dist/HonoEndpointAdaptor-Cq99r9H7.cjs.map +1 -0
  42. package/dist/Queue-C1uDgjxt.mjs +100 -0
  43. package/dist/Queue-C1uDgjxt.mjs.map +1 -0
  44. package/dist/Queue-Ckmudcm8.cjs +105 -0
  45. package/dist/Queue-Ckmudcm8.cjs.map +1 -0
  46. package/dist/{Queue-D7ZuwBhy.d.cts → Queue-CpQIGB_2.d.cts} +28 -40
  47. package/dist/Queue-CpQIGB_2.d.cts.map +1 -0
  48. package/dist/{Queue-gVGfi2Yk.d.mts → Queue-YmvN2vEP.d.mts} +28 -40
  49. package/dist/Queue-YmvN2vEP.d.mts.map +1 -0
  50. package/dist/QueueBuilder-CJNcv4dy.cjs +112 -0
  51. package/dist/QueueBuilder-CJNcv4dy.cjs.map +1 -0
  52. package/dist/QueueBuilder-CM0WUxfw.d.mts +62 -0
  53. package/dist/QueueBuilder-CM0WUxfw.d.mts.map +1 -0
  54. package/dist/QueueBuilder-XEnnOWGe.d.cts +62 -0
  55. package/dist/QueueBuilder-XEnnOWGe.d.cts.map +1 -0
  56. package/dist/QueueBuilder-XuPKZwKH.mjs +95 -0
  57. package/dist/QueueBuilder-XuPKZwKH.mjs.map +1 -0
  58. package/dist/{Subscriber-2mEi0ImH.d.cts → Subscriber-B91YSkZt.d.cts} +14 -16
  59. package/dist/Subscriber-B91YSkZt.d.cts.map +1 -0
  60. package/dist/{Subscriber-xTJ9ayPN.d.mts → Subscriber-BjHYe5hK.d.mts} +14 -16
  61. package/dist/Subscriber-BjHYe5hK.d.mts.map +1 -0
  62. package/dist/SubscriberBuilder-BSpQX1JT.d.cts +55 -0
  63. package/dist/SubscriberBuilder-BSpQX1JT.d.cts.map +1 -0
  64. package/dist/SubscriberBuilder-BhMphk4z.d.mts +55 -0
  65. package/dist/SubscriberBuilder-BhMphk4z.d.mts.map +1 -0
  66. package/dist/{SubscriberBuilder-4OPehf2R.cjs → SubscriberBuilder-Duk028pD.cjs} +34 -37
  67. package/dist/SubscriberBuilder-Duk028pD.cjs.map +1 -0
  68. package/dist/{SubscriberBuilder-BjkbeT9l.mjs → SubscriberBuilder-DzQUWE08.mjs} +23 -25
  69. package/dist/SubscriberBuilder-DzQUWE08.mjs.map +1 -0
  70. package/dist/Topic-CkxOTrMv.cjs +104 -0
  71. package/dist/Topic-CkxOTrMv.cjs.map +1 -0
  72. package/dist/Topic-hPffOsot.mjs +99 -0
  73. package/dist/Topic-hPffOsot.mjs.map +1 -0
  74. package/dist/adaptors/aws.cjs +171 -108
  75. package/dist/adaptors/aws.cjs.map +1 -1
  76. package/dist/adaptors/aws.d.cts +75 -43
  77. package/dist/adaptors/aws.d.cts.map +1 -1
  78. package/dist/adaptors/aws.d.mts +76 -44
  79. package/dist/adaptors/aws.d.mts.map +1 -1
  80. package/dist/adaptors/aws.mjs +143 -83
  81. package/dist/adaptors/aws.mjs.map +1 -1
  82. package/dist/adaptors/hono.cjs +3 -10
  83. package/dist/adaptors/hono.d.cts +7 -16
  84. package/dist/adaptors/hono.d.cts.map +1 -1
  85. package/dist/adaptors/hono.d.mts +8 -17
  86. package/dist/adaptors/hono.d.mts.map +1 -1
  87. package/dist/adaptors/hono.mjs +2 -10
  88. package/dist/adaptors/testing.cjs +515 -87
  89. package/dist/adaptors/testing.cjs.map +1 -1
  90. package/dist/adaptors/testing.d.cts +250 -48
  91. package/dist/adaptors/testing.d.cts.map +1 -1
  92. package/dist/adaptors/testing.d.mts +250 -48
  93. package/dist/adaptors/testing.d.mts.map +1 -1
  94. package/dist/adaptors/testing.mjs +484 -68
  95. package/dist/adaptors/testing.mjs.map +1 -1
  96. package/dist/auth-CMwml9QN.d.mts +188 -0
  97. package/dist/auth-CMwml9QN.d.mts.map +1 -0
  98. package/dist/auth-rVRDjIw_.d.cts +188 -0
  99. package/dist/auth-rVRDjIw_.d.cts.map +1 -0
  100. package/dist/auth.cjs +171 -31
  101. package/dist/auth.cjs.map +1 -1
  102. package/dist/auth.d.cts +2 -108
  103. package/dist/auth.d.mts +2 -108
  104. package/dist/auth.mjs +160 -24
  105. package/dist/auth.mjs.map +1 -1
  106. package/dist/{cache-BrRz3fEB.d.mts → cache-C9a_hVCc.d.cts} +4 -7
  107. package/dist/cache-C9a_hVCc.d.cts.map +1 -0
  108. package/dist/{cache-BtZY_tHe.d.cts → cache-CeTMI8LR.d.mts} +4 -7
  109. package/dist/cache-CeTMI8LR.d.mts.map +1 -0
  110. package/dist/cache.cjs +68 -2
  111. package/dist/cache.cjs.map +1 -0
  112. package/dist/cache.d.cts +1 -2
  113. package/dist/cache.d.mts +1 -2
  114. package/dist/cache.mjs +67 -2
  115. package/dist/cache.mjs.map +1 -0
  116. package/dist/{clone-DblgEZZa.mjs → clone-EKNovYHu.mjs} +3 -3
  117. package/dist/clone-EKNovYHu.mjs.map +1 -0
  118. package/dist/{clone-Dy0cR2SZ.cjs → clone-UGJpvQnL.cjs} +7 -8
  119. package/dist/clone-UGJpvQnL.cjs.map +1 -0
  120. package/dist/{construct-interface-g5GM5pwR.d.mts → construct-interface-_3zgxzXl.d.mts} +20 -11
  121. package/dist/construct-interface-_3zgxzXl.d.mts.map +1 -0
  122. package/dist/{construct-interface-D9d4Gm4p.d.cts → construct-interface-_xi4BPN8.d.cts} +20 -11
  123. package/dist/construct-interface-_xi4BPN8.d.cts.map +1 -0
  124. package/dist/construct-interface.cjs +87 -7
  125. package/dist/construct-interface.cjs.map +1 -0
  126. package/dist/construct-interface.d.cts +2 -2
  127. package/dist/construct-interface.d.mts +2 -2
  128. package/dist/construct-interface.mjs +81 -2
  129. package/dist/construct-interface.mjs.map +1 -0
  130. package/dist/credential.cjs +63 -16
  131. package/dist/credential.cjs.map +1 -1
  132. package/dist/credential.d.cts +16 -9
  133. package/dist/credential.d.cts.map +1 -1
  134. package/dist/credential.d.mts +16 -9
  135. package/dist/credential.d.mts.map +1 -1
  136. package/dist/credential.mjs +58 -12
  137. package/dist/credential.mjs.map +1 -1
  138. package/dist/crons/index.cjs +68 -10
  139. package/dist/crons/index.cjs.map +1 -1
  140. package/dist/crons/index.d.cts +32 -14
  141. package/dist/crons/index.d.cts.map +1 -1
  142. package/dist/crons/index.d.mts +32 -14
  143. package/dist/crons/index.d.mts.map +1 -1
  144. package/dist/crons/index.mjs +66 -10
  145. package/dist/crons/index.mjs.map +1 -1
  146. package/dist/database/kysely.cjs +40 -15
  147. package/dist/database/kysely.cjs.map +1 -1
  148. package/dist/database/kysely.d.cts +2 -152
  149. package/dist/database/kysely.d.mts +2 -152
  150. package/dist/database/kysely.mjs +28 -5
  151. package/dist/database/kysely.mjs.map +1 -1
  152. package/dist/email.cjs +25 -12
  153. package/dist/email.cjs.map +1 -1
  154. package/dist/email.d.cts +3 -7
  155. package/dist/email.d.cts.map +1 -1
  156. package/dist/email.d.mts +3 -7
  157. package/dist/email.d.mts.map +1 -1
  158. package/dist/email.mjs +16 -3
  159. package/dist/email.mjs.map +1 -1
  160. package/dist/endpoints/index.cjs +8 -10
  161. package/dist/endpoints/index.d.cts +51 -7
  162. package/dist/endpoints/index.d.cts.map +1 -0
  163. package/dist/endpoints/index.d.mts +51 -7
  164. package/dist/endpoints/index.d.mts.map +1 -0
  165. package/dist/endpoints/index.mjs +6 -10
  166. package/dist/external-api-DS3mujT5.d.mts +86 -0
  167. package/dist/external-api-DS3mujT5.d.mts.map +1 -0
  168. package/dist/external-api-LBfE-q3g.d.cts +86 -0
  169. package/dist/external-api-LBfE-q3g.d.cts.map +1 -0
  170. package/dist/external-api.cjs +124 -0
  171. package/dist/external-api.cjs.map +1 -0
  172. package/dist/external-api.d.cts +2 -0
  173. package/dist/external-api.d.mts +2 -0
  174. package/dist/external-api.mjs +121 -0
  175. package/dist/external-api.mjs.map +1 -0
  176. package/dist/file-server.cjs +42 -10
  177. package/dist/file-server.cjs.map +1 -1
  178. package/dist/file-server.d.cts +6 -10
  179. package/dist/file-server.d.cts.map +1 -1
  180. package/dist/file-server.d.mts +6 -10
  181. package/dist/file-server.d.mts.map +1 -1
  182. package/dist/file-server.mjs +34 -2
  183. package/dist/file-server.mjs.map +1 -1
  184. package/dist/functions/index.cjs +2 -6
  185. package/dist/functions/index.d.cts +2 -4
  186. package/dist/functions/index.d.mts +2 -4
  187. package/dist/functions/index.mjs +2 -6
  188. package/dist/{functions-Ck21Uyq0.mjs → functions-DCIfCRR-.mjs} +371 -241
  189. package/dist/functions-DCIfCRR-.mjs.map +1 -0
  190. package/dist/{functions-DJJA7VGc.cjs → functions-ZH60FE7H.cjs} +409 -273
  191. package/dist/functions-ZH60FE7H.cjs.map +1 -0
  192. package/dist/{index-AIfVzkhi.d.cts → index-B0kxstwf.d.cts} +49 -42
  193. package/dist/index-B0kxstwf.d.cts.map +1 -0
  194. package/dist/index-CeEtxDmK.d.cts +79 -0
  195. package/dist/index-CeEtxDmK.d.cts.map +1 -0
  196. package/dist/index-CeEtxDmK.d.mts +79 -0
  197. package/dist/index-CeEtxDmK.d.mts.map +1 -0
  198. package/dist/{index-CubPzHd9.d.mts → index-CjVEjOw0.d.mts} +49 -42
  199. package/dist/index-CjVEjOw0.d.mts.map +1 -0
  200. package/dist/index.cjs +3 -3
  201. package/dist/index.d.cts +4 -4
  202. package/dist/index.d.mts +4 -4
  203. package/dist/index.mjs +2 -3
  204. package/dist/kysely-BJ8IQ_1P.d.mts +159 -0
  205. package/dist/kysely-BJ8IQ_1P.d.mts.map +1 -0
  206. package/dist/kysely-DVF8wOT4.d.cts +159 -0
  207. package/dist/kysely-DVF8wOT4.d.cts.map +1 -0
  208. package/dist/{lazyAccessors-BoJN3SMd.mjs → lazyAccessors-CFanua0O.mjs} +20 -60
  209. package/dist/lazyAccessors-CFanua0O.mjs.map +1 -0
  210. package/dist/{lazyAccessors-e3j2oE2m.cjs → lazyAccessors-hJKGv8Ay.cjs} +60 -113
  211. package/dist/lazyAccessors-hJKGv8Ay.cjs.map +1 -0
  212. package/dist/mobile-app.cjs +70 -0
  213. package/dist/mobile-app.cjs.map +1 -0
  214. package/dist/mobile-app.d.cts +61 -0
  215. package/dist/mobile-app.d.cts.map +1 -0
  216. package/dist/mobile-app.d.mts +61 -0
  217. package/dist/mobile-app.d.mts.map +1 -0
  218. package/dist/mobile-app.mjs +69 -0
  219. package/dist/mobile-app.mjs.map +1 -0
  220. package/dist/object-storage.cjs +18 -10
  221. package/dist/object-storage.cjs.map +1 -1
  222. package/dist/object-storage.d.cts +3 -7
  223. package/dist/object-storage.d.cts.map +1 -1
  224. package/dist/object-storage.d.mts +3 -7
  225. package/dist/object-storage.d.mts.map +1 -1
  226. package/dist/object-storage.mjs +11 -3
  227. package/dist/object-storage.mjs.map +1 -1
  228. package/dist/{processAudits-Dmts9H_b.mjs → processAudits-BpRlPQMW.mjs} +16 -19
  229. package/dist/processAudits-BpRlPQMW.mjs.map +1 -0
  230. package/dist/{processAudits-CGqttuXm.cjs → processAudits-D_2W5x8k.cjs} +26 -30
  231. package/dist/processAudits-D_2W5x8k.cjs.map +1 -0
  232. package/dist/queue/index.cjs +6 -189
  233. package/dist/queue/index.d.cts +3 -60
  234. package/dist/queue/index.d.mts +3 -60
  235. package/dist/queue/index.mjs +3 -186
  236. package/dist/rest-api.cjs +87 -63
  237. package/dist/rest-api.cjs.map +1 -1
  238. package/dist/rest-api.d.cts +62 -61
  239. package/dist/rest-api.d.cts.map +1 -1
  240. package/dist/rest-api.d.mts +62 -61
  241. package/dist/rest-api.d.mts.map +1 -1
  242. package/dist/rest-api.mjs +79 -55
  243. package/dist/rest-api.mjs.map +1 -1
  244. package/dist/{chunk-DWy1uDak.cjs → rolldown-runtime-y5ARvAq5.cjs} +14 -18
  245. package/dist/site.cjs +33 -9
  246. package/dist/site.cjs.map +1 -1
  247. package/dist/site.d.cts +11 -22
  248. package/dist/site.d.cts.map +1 -1
  249. package/dist/site.d.mts +11 -22
  250. package/dist/site.d.mts.map +1 -1
  251. package/dist/site.mjs +29 -5
  252. package/dist/site.mjs.map +1 -1
  253. package/dist/subscribers/index.cjs +2 -11
  254. package/dist/subscribers/index.d.cts +3 -14
  255. package/dist/subscribers/index.d.mts +3 -14
  256. package/dist/subscribers/index.mjs +2 -11
  257. package/dist/surfaceEnv-CNimK76p.cjs +56 -0
  258. package/dist/surfaceEnv-CNimK76p.cjs.map +1 -0
  259. package/dist/surfaceEnv-wMT5QzgZ.mjs +45 -0
  260. package/dist/surfaceEnv-wMT5QzgZ.mjs.map +1 -0
  261. package/dist/{telemetry-C3L0iS28.d.cts → telemetry-DGcFlVpB.d.cts} +2 -5
  262. package/dist/telemetry-DGcFlVpB.d.cts.map +1 -0
  263. package/dist/{telemetry-D7bVFLGi.d.mts → telemetry-DGcFlVpB.d.mts} +2 -5
  264. package/dist/telemetry-DGcFlVpB.d.mts.map +1 -0
  265. package/dist/topic/index.cjs +3 -137
  266. package/dist/topic/index.d.cts +2 -32
  267. package/dist/topic/index.d.mts +2 -32
  268. package/dist/topic/index.mjs +2 -134
  269. package/dist/{types-BlAkSuGI.d.cts → types-DMuSQeLL.d.cts} +3 -5
  270. package/dist/types-DMuSQeLL.d.cts.map +1 -0
  271. package/dist/{types-aKksMEWL.d.mts → types-DMuSQeLL.d.mts} +3 -5
  272. package/dist/types-DMuSQeLL.d.mts.map +1 -0
  273. package/dist/types.d.cts +1 -1
  274. package/dist/types.d.mts +1 -1
  275. package/dist/types.mjs +1 -0
  276. package/dist/worker.cjs +118 -35
  277. package/dist/worker.cjs.map +1 -1
  278. package/dist/worker.d.cts +95 -42
  279. package/dist/worker.d.cts.map +1 -1
  280. package/dist/worker.d.mts +95 -42
  281. package/dist/worker.d.mts.map +1 -1
  282. package/dist/worker.mjs +113 -30
  283. package/dist/worker.mjs.map +1 -1
  284. package/package.json +66 -41
  285. package/dist/Construct-BD5neF7w.mjs.map +0 -1
  286. package/dist/Construct-C0ijr2qp.d.cts +0 -117
  287. package/dist/Construct-C0ijr2qp.d.cts.map +0 -1
  288. package/dist/Construct-Ct8nalEi.d.mts +0 -117
  289. package/dist/Construct-Ct8nalEi.d.mts.map +0 -1
  290. package/dist/Construct-CyS3RpTL.cjs.map +0 -1
  291. package/dist/Cron-B2OFsfDM.d.cts.map +0 -1
  292. package/dist/Cron-ByxdOfpE.d.mts.map +0 -1
  293. package/dist/CronBuilder-BL0AP6fs.d.mts +0 -44
  294. package/dist/CronBuilder-BL0AP6fs.d.mts.map +0 -1
  295. package/dist/CronBuilder-CdibiHNB.mjs +0 -84
  296. package/dist/CronBuilder-CdibiHNB.mjs.map +0 -1
  297. package/dist/CronBuilder-DyUr6nYz.cjs +0 -96
  298. package/dist/CronBuilder-DyUr6nYz.cjs.map +0 -1
  299. package/dist/CronBuilder-LSJMfqnq.d.cts +0 -44
  300. package/dist/CronBuilder-LSJMfqnq.d.cts.map +0 -1
  301. package/dist/Endpoint-2Wg7T7Cq.d.mts.map +0 -1
  302. package/dist/Endpoint-DODn1RhN.cjs.map +0 -1
  303. package/dist/Endpoint-Dij_wOcc.mjs.map +0 -1
  304. package/dist/Endpoint-DrD8a1yH.d.cts.map +0 -1
  305. package/dist/EndpointFactory-BHFMmFkV.cjs.map +0 -1
  306. package/dist/EndpointFactory-b4ituq-s.mjs.map +0 -1
  307. package/dist/HonoEndpointAdaptor-BM2jbWht.mjs.map +0 -1
  308. package/dist/HonoEndpointAdaptor-De6IlBZe.cjs.map +0 -1
  309. package/dist/Queue-D7ZuwBhy.d.cts.map +0 -1
  310. package/dist/Queue-gVGfi2Yk.d.mts.map +0 -1
  311. package/dist/Subscriber-2mEi0ImH.d.cts.map +0 -1
  312. package/dist/Subscriber-xTJ9ayPN.d.mts.map +0 -1
  313. package/dist/SubscriberBuilder-4OPehf2R.cjs.map +0 -1
  314. package/dist/SubscriberBuilder-BjkbeT9l.mjs.map +0 -1
  315. package/dist/SubscriberBuilder-Dptmo-1A.d.mts +0 -62
  316. package/dist/SubscriberBuilder-Dptmo-1A.d.mts.map +0 -1
  317. package/dist/SubscriberBuilder-waNhzjSM.d.cts +0 -62
  318. package/dist/SubscriberBuilder-waNhzjSM.d.cts.map +0 -1
  319. package/dist/Topic-19QeHBIR.d.cts +0 -91
  320. package/dist/Topic-19QeHBIR.d.cts.map +0 -1
  321. package/dist/Topic-DuFeqkBh.d.mts +0 -91
  322. package/dist/Topic-DuFeqkBh.d.mts.map +0 -1
  323. package/dist/auth.d.cts.map +0 -1
  324. package/dist/auth.d.mts.map +0 -1
  325. package/dist/cache-0ANvRQnD.mjs +0 -51
  326. package/dist/cache-0ANvRQnD.mjs.map +0 -1
  327. package/dist/cache-3WSvAulx.cjs +0 -57
  328. package/dist/cache-3WSvAulx.cjs.map +0 -1
  329. package/dist/cache-BrRz3fEB.d.mts.map +0 -1
  330. package/dist/cache-BtZY_tHe.d.cts.map +0 -1
  331. package/dist/clone-DblgEZZa.mjs.map +0 -1
  332. package/dist/clone-Dy0cR2SZ.cjs.map +0 -1
  333. package/dist/construct-interface-BfjcOD_E.cjs +0 -117
  334. package/dist/construct-interface-BfjcOD_E.cjs.map +0 -1
  335. package/dist/construct-interface-D9d4Gm4p.d.cts.map +0 -1
  336. package/dist/construct-interface-Z4CpS8tK.mjs +0 -81
  337. package/dist/construct-interface-Z4CpS8tK.mjs.map +0 -1
  338. package/dist/construct-interface-g5GM5pwR.d.mts.map +0 -1
  339. package/dist/database/kysely.d.cts.map +0 -1
  340. package/dist/database/kysely.d.mts.map +0 -1
  341. package/dist/functions-Ck21Uyq0.mjs.map +0 -1
  342. package/dist/functions-DJJA7VGc.cjs.map +0 -1
  343. package/dist/index-AIfVzkhi.d.cts.map +0 -1
  344. package/dist/index-B8g8POkr.d.cts.map +0 -1
  345. package/dist/index-BxHDdy6a.d.mts.map +0 -1
  346. package/dist/index-CubPzHd9.d.mts.map +0 -1
  347. package/dist/lazyAccessors-BoJN3SMd.mjs.map +0 -1
  348. package/dist/lazyAccessors-e3j2oE2m.cjs.map +0 -1
  349. package/dist/processAudits-CGqttuXm.cjs.map +0 -1
  350. package/dist/processAudits-Dmts9H_b.mjs.map +0 -1
  351. package/dist/queue/index.cjs.map +0 -1
  352. package/dist/queue/index.d.cts.map +0 -1
  353. package/dist/queue/index.d.mts.map +0 -1
  354. package/dist/queue/index.mjs.map +0 -1
  355. package/dist/subscribers/index.cjs.map +0 -1
  356. package/dist/subscribers/index.d.cts.map +0 -1
  357. package/dist/subscribers/index.d.mts.map +0 -1
  358. package/dist/subscribers/index.mjs.map +0 -1
  359. package/dist/surfaceEnv-BFXEms2f.cjs +0 -39
  360. package/dist/surfaceEnv-BFXEms2f.cjs.map +0 -1
  361. package/dist/surfaceEnv-C3Ktahea.mjs +0 -27
  362. package/dist/surfaceEnv-C3Ktahea.mjs.map +0 -1
  363. package/dist/telemetry-C3L0iS28.d.cts.map +0 -1
  364. package/dist/telemetry-D7bVFLGi.d.mts.map +0 -1
  365. package/dist/topic/index.cjs.map +0 -1
  366. package/dist/topic/index.d.cts.map +0 -1
  367. package/dist/topic/index.d.mts.map +0 -1
  368. package/dist/topic/index.mjs.map +0 -1
  369. package/dist/types-BlAkSuGI.d.cts.map +0 -1
  370. package/dist/types-aKksMEWL.d.mts.map +0 -1
@@ -1,25 +1,32 @@
1
- import "../Construct-BD5neF7w.mjs";
2
- import "../construct-interface-Z4CpS8tK.mjs";
3
- import { FunctionBuilder } from "../functions-Ck21Uyq0.mjs";
4
- import "../clone-DblgEZZa.mjs";
5
- import { Endpoint, ResponseBuilder } from "../Endpoint-Dij_wOcc.mjs";
6
- import { createCookieHeaderAccessor, createObjectHeaders, publishConstructEvents, publishEvents } from "../lazyAccessors-BoJN3SMd.mjs";
7
- import { executeWithAuditTransaction } from "../processAudits-Dmts9H_b.mjs";
8
- import { HonoEndpoint } from "../HonoEndpointAdaptor-BM2jbWht.mjs";
1
+ import { BetterAuth } from "../auth.mjs";
2
+ import { a as publishEvents, i as publishConstructEvents, t as FunctionBuilder } from "../functions-DCIfCRR-.mjs";
3
+ import { n as ResponseBuilder, t as Endpoint } from "../Endpoint-CQAeh1Rh.mjs";
4
+ import { t as Queue } from "../Queue-C1uDgjxt.mjs";
5
+ import { Email } from "../email.mjs";
6
+ import { KyselyDatabase } from "../database/kysely.mjs";
7
+ import { c as createObjectHeaders, r as createCookieHeaderAccessor } from "../lazyAccessors-CFanua0O.mjs";
8
+ import { t as Topic } from "../Topic-hPffOsot.mjs";
9
+ import { t as HonoEndpoint } from "../HonoEndpointAdaptor-Aui-x9Lg.mjs";
10
+ import { n as executeWithAuditTransaction } from "../processAudits-BpRlPQMW.mjs";
11
+ import { provideKey } from "@geekmidas/manifest";
9
12
  import { ForbiddenError } from "@geekmidas/errors";
10
13
  import { EnvironmentParser } from "@geekmidas/envkit";
11
- import { ServiceDiscovery, runWithRequestContext } from "@geekmidas/services";
12
- import { DefaultAuditor } from "@geekmidas/audit";
14
+ import { ServiceDiscovery, runWithRequestContext, serviceContext } from "@geekmidas/services";
13
15
  import { Hono } from "hono";
16
+ import { DefaultAuditor } from "@geekmidas/audit";
17
+ import { TEST_CONTEXT_HEADER, currentTestContext, installContextFetch, runAsServer, runInTestContext, testContextOf } from "@geekmidas/testkit/context";
14
18
  import { http } from "msw";
15
-
19
+ import { randomUUID } from "node:crypto";
20
+ import { Browser } from "@geekmidas/testkit/browser";
21
+ import { faker } from "@geekmidas/testkit/faker";
22
+ import { createMailbox } from "@geekmidas/testkit/mailbox";
23
+ import { TransactionRegistry } from "@geekmidas/testkit/transactions";
24
+ import { setupServer } from "msw/node";
25
+ import { afterAll, beforeAll, test } from "vitest";
26
+ import { existsSync, readFileSync } from "node:fs";
27
+ import tls from "node:tls";
28
+ import { fileURLToPath } from "node:url";
16
29
  //#region src/endpoints/MswEndpointAdaptor.ts
17
- /**
18
- * Header used to identify which test context a request belongs to.
19
- * Each concurrent test registers its own context (services, db transaction, etc.)
20
- * and the MSW handler looks it up by this header value.
21
- */
22
- const TEST_CONTEXT_HEADER = "x-test-context-id";
23
30
  const MSW_HTTP_METHODS = [
24
31
  "get",
25
32
  "post",
@@ -67,7 +74,6 @@ function createMswHandlers(endpoints, options) {
67
74
  break;
68
75
  }
69
76
  }
70
- if (ctxOptions.publisher) serviceDefs.push(ctxOptions.publisher);
71
77
  if (ctxOptions.auditorStorage !== void 0) {
72
78
  for (const endpoint of endpoints) if (endpoint.auditorStorageService) {
73
79
  serviceDefs.push({
@@ -111,7 +117,6 @@ function createMswHandlers(endpoints, options) {
111
117
  registerContext
112
118
  };
113
119
  }
114
-
115
120
  //#endregion
116
121
  //#region src/endpoints/TestEndpointAdaptor.ts
117
122
  /**
@@ -131,6 +136,8 @@ function serializeCookie(name, value, options) {
131
136
  return cookieString;
132
137
  }
133
138
  var TestEndpointAdaptor = class TestEndpointAdaptor {
139
+ endpoint;
140
+ serviceDiscovery;
134
141
  static getDefaultServiceDiscover(_endpoint) {
135
142
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
136
143
  }
@@ -165,7 +172,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
165
172
  cookie,
166
173
  ...rawDb !== void 0 && { db: rawDb }
167
174
  });
168
- const isAuthorized = await this.endpoint.authorize({
175
+ if (!await this.endpoint.authorize({
169
176
  header,
170
177
  cookie,
171
178
  services: ctx.services,
@@ -175,8 +182,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
175
182
  body,
176
183
  query,
177
184
  params
178
- });
179
- if (!isAuthorized) {
185
+ })) {
180
186
  logger.warn("Forbidden access attempt");
181
187
  throw new ForbiddenError("Forbidden access to the endpoint", "You do not have permission to access this resource.");
182
188
  }
@@ -198,24 +204,22 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
198
204
  } catch (error) {
199
205
  logger.error(error, "Failed to extract actor for audits");
200
206
  }
201
- const auditor = new DefaultAuditor({
202
- actor,
203
- storage: auditorStorage,
204
- metadata: {
205
- endpoint: this.endpoint.route,
206
- method: this.endpoint.method
207
- }
208
- });
209
207
  auditContext = {
210
- auditor,
208
+ auditor: new DefaultAuditor({
209
+ actor,
210
+ storage: auditorStorage,
211
+ metadata: {
212
+ endpoint: this.endpoint.route,
213
+ method: this.endpoint.method
214
+ }
215
+ }),
211
216
  storage: auditorStorage
212
217
  };
213
218
  }
214
219
  const audits = this.endpoint.audits;
215
220
  if (!auditContext && audits?.length) logger.warn("No auditor storage service available");
216
- const result = await executeWithAuditTransaction(auditContext, async (auditor) => {
217
- const trx = auditor?.getTransaction?.();
218
- const db = trx ?? rawDb;
221
+ const { output, metadata } = await executeWithAuditTransaction(auditContext, async (auditor) => {
222
+ const db = auditor?.getTransaction?.() ?? rawDb;
219
223
  const responseBuilder = new ResponseBuilder();
220
224
  const response = await this.endpoint.handler({
221
225
  body,
@@ -230,36 +234,33 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
230
234
  db
231
235
  }, responseBuilder);
232
236
  let data = response;
233
- let metadata$1 = responseBuilder.getMetadata();
237
+ let metadata = responseBuilder.getMetadata();
234
238
  if (Endpoint.hasMetadata(response)) {
235
239
  data = response.data;
236
- metadata$1 = response.metadata;
240
+ metadata = response.metadata;
237
241
  }
238
- const output$1 = await this.endpoint.parseOutput(data);
239
242
  return {
240
- output: output$1,
241
- metadata: metadata$1,
243
+ output: await this.endpoint.parseOutput(data),
244
+ metadata,
242
245
  responseBuilder
243
246
  };
244
- }, async (result$1, auditor) => {
247
+ }, async (result, auditor) => {
245
248
  if (!audits?.length) return;
246
249
  for (const audit of audits) {
247
- if (audit.when && !audit.when(result$1.output)) continue;
248
- const payload = audit.payload(result$1.output);
249
- const entityId = audit.entityId?.(result$1.output);
250
+ if (audit.when && !audit.when(result.output)) continue;
251
+ const payload = audit.payload(result.output);
252
+ const entityId = audit.entityId?.(result.output);
250
253
  auditor.audit(audit.type, payload, {
251
254
  table: audit.table,
252
255
  entityId
253
256
  });
254
257
  }
255
258
  }, { db: rawDb });
256
- const { output, metadata } = result;
257
- ctx.publisher && await this.serviceDiscovery.register([ctx.publisher]);
258
- await publishConstructEvents(this.endpoint, output, this.serviceDiscovery);
259
+ await publishConstructEvents(this.endpoint, output, this.serviceDiscovery, this.endpoint.logger, ctx.services);
259
260
  const headers = { ...metadata.headers || {} };
260
261
  if (metadata.cookies && metadata.cookies.size > 0) {
261
262
  const setCookieValues = [];
262
- for (const [name, cookie$1] of metadata.cookies.entries()) setCookieValues.push(serializeCookie(name, cookie$1.value, cookie$1.options));
263
+ for (const [name, cookie] of metadata.cookies.entries()) setCookieValues.push(serializeCookie(name, cookie.value, cookie.options));
263
264
  headers["set-cookie"] = setCookieValues;
264
265
  }
265
266
  return {
@@ -270,14 +271,14 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
270
271
  });
271
272
  }
272
273
  async request(ctx) {
273
- const response = await this.fullRequest(ctx);
274
- return response.body;
274
+ return (await this.fullRequest(ctx)).body;
275
275
  }
276
276
  };
277
-
278
277
  //#endregion
279
278
  //#region src/functions/TestFunctionAdaptor.ts
280
279
  var TestFunctionAdaptor = class TestFunctionAdaptor {
280
+ fn;
281
+ serviceDiscovery;
281
282
  static getDefaultServiceDiscovery(_fn) {
282
283
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
283
284
  }
@@ -293,15 +294,11 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
293
294
  else services = await this.serviceDiscovery.register(this.fn.services);
294
295
  let db;
295
296
  if ("db" in ctx && ctx.db !== void 0) db = ctx.db;
296
- else if (this.fn.databaseService) {
297
- const dbServices = await this.serviceDiscovery.register([this.fn.databaseService]);
298
- db = dbServices[this.fn.databaseService.serviceName];
299
- }
297
+ else if (this.fn.databaseService) db = (await this.serviceDiscovery.register([this.fn.databaseService]))[this.fn.databaseService.serviceName];
300
298
  let auditor;
301
299
  if ("auditor" in ctx && ctx.auditor !== void 0) auditor = ctx.auditor;
302
300
  else if (this.fn.auditorStorageService) {
303
- const auditServices = await this.serviceDiscovery.register([this.fn.auditorStorageService]);
304
- const storage = auditServices[this.fn.auditorStorageService.serviceName];
301
+ const storage = (await this.serviceDiscovery.register([this.fn.auditorStorageService]))[this.fn.auditorStorageService.serviceName];
305
302
  auditor = new DefaultAuditor({
306
303
  actor: {
307
304
  id: "system",
@@ -315,11 +312,10 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
315
312
  });
316
313
  }
317
314
  const requestId = `test-${Date.now()}`;
318
- const startTime = Date.now();
319
315
  return runWithRequestContext({
320
316
  logger,
321
317
  requestId,
322
- startTime
318
+ startTime: Date.now()
323
319
  }, async () => {
324
320
  const response = await this.fn.fn({
325
321
  input: parsedInput,
@@ -336,12 +332,11 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
336
332
  await auditor.flush();
337
333
  }
338
334
  }
339
- await publishEvents(logger, this.serviceDiscovery, this.fn.events, output, this.fn.publisherService);
335
+ await publishEvents(logger, this.serviceDiscovery, this.fn.events, output, services);
340
336
  return output;
341
337
  });
342
338
  }
343
339
  };
344
-
345
340
  //#endregion
346
341
  //#region src/queue/TestQueueAdaptor.ts
347
342
  /**
@@ -354,6 +349,8 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
354
349
  * await adapter.invoke({ messages: [{ orderId: '123' }] });
355
350
  */
356
351
  var TestQueueAdaptor = class TestQueueAdaptor {
352
+ queue;
353
+ serviceDiscovery;
357
354
  static getDefaultServiceDiscovery() {
358
355
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
359
356
  }
@@ -365,11 +362,10 @@ var TestQueueAdaptor = class TestQueueAdaptor {
365
362
  const logger = this.queue.logger.child({ test: true });
366
363
  const services = request.services ?? await this.serviceDiscovery.register(this.queue.services);
367
364
  const requestId = `test-${Date.now()}`;
368
- const startTime = Date.now();
369
365
  return runWithRequestContext({
370
366
  logger,
371
367
  requestId,
372
- startTime
368
+ startTime: Date.now()
373
369
  }, () => this.queue.handler({
374
370
  messages: request.messages,
375
371
  services,
@@ -377,10 +373,11 @@ var TestQueueAdaptor = class TestQueueAdaptor {
377
373
  }));
378
374
  }
379
375
  };
380
-
381
376
  //#endregion
382
377
  //#region src/subscribers/TestSubscriberAdaptor.ts
383
378
  var TestSubscriberAdaptor = class TestSubscriberAdaptor {
379
+ subscriber;
380
+ serviceDiscovery;
384
381
  static getDefaultServiceDiscovery() {
385
382
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
386
383
  }
@@ -396,11 +393,10 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
396
393
  const filteredEvents = this.filterEvents(request.events);
397
394
  if (filteredEvents.length === 0) return { batchItemFailures: [] };
398
395
  const requestId = `test-${Date.now()}`;
399
- const startTime = Date.now();
400
396
  return runWithRequestContext({
401
397
  logger,
402
398
  requestId,
403
- startTime
399
+ startTime: Date.now()
404
400
  }, async () => {
405
401
  const result = await this.subscriber.handler({
406
402
  events: filteredEvents,
@@ -413,7 +409,6 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
413
409
  if (validationResult.issues) throw new Error("Subscriber output validation failed");
414
410
  output = validationResult.value;
415
411
  }
416
- await publishEvents(logger, this.serviceDiscovery, this.subscriber.events, output, this.subscriber.publisherService);
417
412
  return output;
418
413
  });
419
414
  }
@@ -422,7 +417,428 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
422
417
  return events.filter((event) => this.subscriber.subscribedEvents.includes(event.type));
423
418
  }
424
419
  };
425
-
426
420
  //#endregion
427
- export { TEST_CONTEXT_HEADER, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, createMswHandlers };
421
+ //#region src/testing/manifest.ts
422
+ /**
423
+ * The test manifest: what `gkm test` knows about an app, written down for the
424
+ * suite it starts.
425
+ *
426
+ * `gkm test` discovers the constructs, reconciles the test stage and resolves
427
+ * its environment — then, until this existed, threw all of it away and left a
428
+ * test to declare it again by hand. The manifest keeps it: which construct and
429
+ * endpoint is exported where, and the environment the test stage resolved,
430
+ * under the keys the constructs themselves derive. A feature test is built from
431
+ * it, so nothing a test says can drift from what the app declares.
432
+ */
433
+ /** The environment variable `gkm test` names the manifest in. */
434
+ const TEST_MANIFEST_ENV = "GKM_TEST_MANIFEST";
435
+ /**
436
+ * Read a test manifest: from a path, a `file:` URL, or — given nothing — the
437
+ * one `gkm test` named in `GKM_TEST_MANIFEST`.
438
+ */
439
+ function loadTestManifest(from) {
440
+ const location = from ?? process.env["GKM_TEST_MANIFEST"];
441
+ if (!location) throw new NoTestManifest();
442
+ trustLocalEdge();
443
+ const path = location instanceof URL || location.startsWith("file:") ? fileURLToPath(location) : location;
444
+ return JSON.parse(readFileSync(path, "utf-8"));
445
+ }
446
+ let trusted = false;
447
+ /**
448
+ * Trust the local edge's certificate authority in this thread.
449
+ *
450
+ * `NODE_EXTRA_CA_CERTS` does it for a process started with it — which a
451
+ * suite started by `gkm test` is, and one started by plain `vitest` or an
452
+ * editor is not: its setup only learns the path once Vitest is running, and a
453
+ * worker *thread* shares that process and keeps a TLS store of its own. Every
454
+ * feature test loads the manifest, so this is the one place each worker passes
455
+ * through.
456
+ */
457
+ function trustLocalEdge() {
458
+ const certificate = process.env.NODE_EXTRA_CA_CERTS;
459
+ if (trusted || !certificate || !existsSync(certificate)) return;
460
+ trusted = true;
461
+ tls.setDefaultCACertificates([...tls.getCACertificates("default"), readFileSync(certificate, "utf-8")]);
462
+ }
463
+ /** A feature test ran without a manifest to build itself from. */
464
+ var NoTestManifest = class extends Error {
465
+ constructor() {
466
+ super(`No test manifest: run the suite with \`gkm test\`, or add \`globalSetup: ['@geekmidas/cli/vitest']\` to the root vitest config — either writes one and names it in ${TEST_MANIFEST_ENV}.`);
467
+ this.name = "NoTestManifest";
468
+ }
469
+ };
470
+ //#endregion
471
+ //#region src/testing/featureTest.ts
472
+ /**
473
+ * `featureTest`: an app, driven the way it runs deployed.
474
+ *
475
+ * A browser signs in and calls the API; the API calls the auth server; each
476
+ * over its URL, each database in its own transaction. Nothing runs as a server:
477
+ * every URL an app's constructs answer on is served in-process through MSW,
478
+ * from the real handler, for the test that made the request. Everything else
479
+ * with a real local equivalent — Postgres, Mailpit, MinIO — is used directly.
480
+ *
481
+ * It is built from the test manifest `gkm test` writes — the constructs and
482
+ * endpoints the app exports, and the environment the test stage resolved — so
483
+ * a test declares none of it. `gkm test` also generates the configured `it`
484
+ * and a `Browser` with a typed client per surface:
485
+ *
486
+ * ```ts
487
+ * import { it } from '#test';
488
+ *
489
+ * it('shows the signed-in user their profile', async ({ browser, mailbox }) => {
490
+ * await browser.auth.signIn.magicLink({ email: 'ada@shop.test' });
491
+ * await browser.visit((await mailbox('ada@shop.test').last()).link!);
492
+ * expect(await browser.api.get('/profile')).toMatchObject({ email: 'ada@shop.test' });
493
+ * });
494
+ * ```
495
+ */
496
+ /** Every test in flight in this process, by id. */
497
+ const contexts = /* @__PURE__ */ new Map();
498
+ /** Databases already resolving to test transactions — patched once each. */
499
+ const bound = /* @__PURE__ */ new WeakSet();
500
+ function featureTest(options = {}) {
501
+ const manifest = options.manifest ?? loadTestManifest();
502
+ const BrowserClass = options.browser ?? Browser;
503
+ let app;
504
+ let factoryDatabases = [];
505
+ let owned = [];
506
+ let network;
507
+ let restoreFetch = () => {};
508
+ beforeAll(async () => {
509
+ app = await load(manifest, options.modules ?? {});
510
+ owned = ownDatabases(app, manifest);
511
+ factoryDatabases = databasesFor(options.factories ?? {}, owned);
512
+ for (const database of app.databases) bindToTests(database);
513
+ network = setupServer(...surfaceHandlers(app.endpoints, manifest.env), ...app.auths.map((auth) => authHandler(auth, manifest.env, app.envParser)), ...Object.entries(options.fakes ?? {}).flatMap(([id, fake]) => fakeHandler(id, fake, manifest.env)));
514
+ network.listen({ onUnhandledRequest(request, print) {
515
+ if (isLocal(new URL(request.url))) return;
516
+ print.error();
517
+ } });
518
+ restoreFetch = installContextFetch();
519
+ });
520
+ afterAll(() => {
521
+ restoreFetch();
522
+ network?.close();
523
+ });
524
+ const run = (name, fn) => async () => {
525
+ const id = randomUUID();
526
+ faker.seed(seedOf(name));
527
+ const state = {
528
+ transactions: new TransactionRegistry(),
529
+ discovery: new ServiceDiscovery(app.envParser),
530
+ surfaces: /* @__PURE__ */ new Map(),
531
+ auth: /* @__PURE__ */ new Map(),
532
+ addresses: /* @__PURE__ */ new Set(),
533
+ published: /* @__PURE__ */ new Map()
534
+ };
535
+ const readMail = app.readMail;
536
+ if (readMail) state.mailbox = (address) => {
537
+ state.addresses.add(address);
538
+ return readMail(address);
539
+ };
540
+ contexts.set(id, state);
541
+ await state.discovery.register(recorders(app.channels, state));
542
+ try {
543
+ await runInTestContext(id, async () => {
544
+ const browser = new BrowserClass();
545
+ const restore = browser.install();
546
+ try {
547
+ const transaction = (database) => state.transactions.get(database.id, urlOf(database, app.envParser), database.clientConfig);
548
+ const db = { get: (name) => {
549
+ const database = owned.find((candidate) => candidate.service.serviceName === name);
550
+ if (!database) throw new UnknownDatabase(name, owned.map((candidate) => candidate.service.serviceName));
551
+ return transaction(database);
552
+ } };
553
+ const built = /* @__PURE__ */ new Map();
554
+ await fn({
555
+ browser,
556
+ db,
557
+ factories: { get: (name) => {
558
+ const database = factoryDatabases.find(([candidate]) => candidate === name)?.[1];
559
+ if (!database) throw new UnknownFactory(name, factoryDatabases.map(([candidate]) => candidate));
560
+ let factory = built.get(name);
561
+ if (!factory) {
562
+ factory = transaction(database).then(options.factories[name]);
563
+ built.set(name, factory);
564
+ }
565
+ return factory;
566
+ } },
567
+ faker,
568
+ mailbox: (address) => {
569
+ if (!state.mailbox) throw new NoInbox();
570
+ return state.mailbox(address);
571
+ },
572
+ published: (channel) => [...state.published.get(channel.id) ?? []],
573
+ subscriber: (subscriber) => new TestSubscriberAdaptor(subscriber, state.discovery),
574
+ queue: (queue) => new TestQueueAdaptor(queue, state.discovery)
575
+ });
576
+ } finally {
577
+ restore();
578
+ }
579
+ });
580
+ } finally {
581
+ contexts.delete(id);
582
+ await Promise.all([state.transactions.rollbackAll(), ...[...state.addresses].map((address) => app.readMail?.(address).clear())]);
583
+ }
584
+ };
585
+ const it = ((name, fn, timeout) => test(name, run(name, fn), timeout));
586
+ it.only = (name, fn, timeout) => test.only(name, run(name, fn), timeout);
587
+ it.skip = (name, fn, timeout) => test.skip(name, run(name, fn), timeout);
588
+ return it;
589
+ }
590
+ /**
591
+ * A test's faker seed, from its name: the same test draws the same data on
592
+ * every run, and two tests draw different data.
593
+ */
594
+ function seedOf(name) {
595
+ let hash = 0;
596
+ for (const char of name) hash = Math.imul(hash, 31) + char.charCodeAt(0) | 0;
597
+ return hash >>> 0;
598
+ }
599
+ /**
600
+ * Import what the manifest points at.
601
+ *
602
+ * The same modules the app runs, so a construct here *is* the app's construct —
603
+ * the one its endpoints were built from — never a copy declared again.
604
+ */
605
+ async function load(manifest, modules) {
606
+ const envParser = new EnvironmentParser({ ...manifest.env });
607
+ const imported = async ({ file, export: name }) => (modules[file] ?? await import(file))[name];
608
+ const constructs = await Promise.all(Object.values(manifest.constructs).map(({ source }) => imported(source)));
609
+ const endpoints = (await Promise.all(manifest.endpoints.map(({ source }) => imported(source)))).filter((value) => Endpoint.isEndpoint(value));
610
+ const unique = (values) => [...new Set(values)];
611
+ const databases = unique(constructs.filter((value) => value instanceof KyselyDatabase));
612
+ const auths = unique(constructs.filter((value) => value instanceof BetterAuth));
613
+ const emails = unique(constructs.filter((value) => value instanceof Email));
614
+ const channels = unique(constructs.filter((value) => value instanceof Topic || value instanceof Queue));
615
+ const inbox = emails.map((email) => manifest.env[provideKey(email.id, "inboxUrl")]).find(Boolean);
616
+ return {
617
+ envParser,
618
+ endpoints,
619
+ databases,
620
+ auths,
621
+ emails,
622
+ channels,
623
+ ...inbox ? { readMail: createMailbox({ inbox }) } : {}
624
+ };
625
+ }
626
+ /**
627
+ * A publisher that records rather than sends, under the name a topic or queue
628
+ * is injected by — `services.users` — which is also the one `.event(users, …)`
629
+ * publishes through.
630
+ */
631
+ function recorders(channels, state) {
632
+ return channels.map((channel) => {
633
+ const publisher = { async publish(messages) {
634
+ state.published.set(channel.id, [...state.published.get(channel.id) ?? [], ...messages.map(({ type, payload }) => ({
635
+ type,
636
+ payload
637
+ }))]);
638
+ } };
639
+ return {
640
+ serviceName: channel.service.serviceName,
641
+ register: () => publisher
642
+ };
643
+ });
644
+ }
645
+ /**
646
+ * The databases a test is handed: the app's own. A schema tenant an auth server
647
+ * owns is reached through that server, as the app reaches it, and a reader is
648
+ * the same database through a read-only role — neither is another database to
649
+ * test against.
650
+ */
651
+ function ownDatabases(app, manifest) {
652
+ const owners = new Set(app.auths.map((auth) => auth.databaseId));
653
+ return app.databases.filter((database) => !owners.has(database.id) && manifest.constructs[database.id]?.kind !== "database-reader");
654
+ }
655
+ /** Each factory's database, found by the service name it is keyed by. */
656
+ function databasesFor(factories, databases) {
657
+ return Object.keys(factories).map((name) => {
658
+ const database = databases.find((candidate) => candidate.service.serviceName === name);
659
+ if (!database) throw new UnknownFactory(name, databases.map((candidate) => candidate.service.serviceName));
660
+ return [name, database];
661
+ });
662
+ }
663
+ /**
664
+ * Make a database resolve, inside a test, to that test's transaction.
665
+ *
666
+ * Everything reaches a database through its service — an endpoint through
667
+ * service discovery, the auth server through its tenant directly — so this is
668
+ * the one place a test's connection can be handed over. Outside a test it is
669
+ * the database it always was.
670
+ */
671
+ function bindToTests(database) {
672
+ if (bound.has(database)) return;
673
+ bound.add(database);
674
+ const service = database.service;
675
+ const register = service.register;
676
+ service.register = (options) => {
677
+ const context = currentTestContext();
678
+ const state = context && contexts.get(context.id);
679
+ if (!state) return register(options);
680
+ return state.transactions.get(database.id, urlOf(database, options.envParser), database.clientConfig);
681
+ };
682
+ }
683
+ function urlOf(database, envParser) {
684
+ return envParser.create((get) => ({ url: get(provideKey(database.id, "url")).string() })).parse().url;
685
+ }
686
+ /** Each surface's endpoints, served at its URL for the test that asked. */
687
+ function surfaceHandlers(endpoints, env) {
688
+ const bySurface = /* @__PURE__ */ new Map();
689
+ for (const endpoint of endpoints) {
690
+ const surface = endpoint.surface?.id;
691
+ if (!surface) continue;
692
+ bySurface.set(surface, [...bySurface.get(surface) ?? [], endpoint]);
693
+ }
694
+ return [...bySurface].flatMap(([surface, served]) => {
695
+ const base = env[provideKey(surface, "url")];
696
+ if (!base) return [];
697
+ return http.all(`${trim(base)}/*`, ({ request }) => serve(request, async (state) => {
698
+ let app = state.surfaces.get(surface);
699
+ if (!app) {
700
+ app = Promise.resolve().then(() => {
701
+ const hono = new Hono();
702
+ HonoEndpoint.addRoutes(served, state.discovery, hono);
703
+ return hono;
704
+ });
705
+ state.surfaces.set(surface, app);
706
+ }
707
+ return (await app).fetch(request);
708
+ }));
709
+ });
710
+ }
711
+ /**
712
+ * An external API's app fake, answering at the URL the test stage resolved for
713
+ * it — so a handler that calls Polar calls the fake, and the test sets up
714
+ * nothing.
715
+ *
716
+ * Not per test, unlike a surface: a fake stands in for somebody else's server,
717
+ * which no test's transaction reaches. An image fake has no handler here — its
718
+ * container answers on localhost, which is let through.
719
+ */
720
+ function fakeHandler(id, fake, env) {
721
+ const base = env[provideKey(id, "url")];
722
+ if (fake.kind !== "app" || !base) return [];
723
+ return [http.all(`${trim(base)}/*`, ({ request }) => fake.handler.fetch(request))];
724
+ }
725
+ /** An auth server, served at its URL, on the transaction of the test that asked. */
726
+ function authHandler(auth, env, envParser) {
727
+ const base = trim(env[provideKey(auth.id, "url")] ?? "");
728
+ return http.all(`${base}/*`, ({ request }) => serve(request, async (state) => {
729
+ let app = state.auth.get(auth);
730
+ if (!app) {
731
+ app = auth.server({
732
+ envParser,
733
+ context: serviceContext
734
+ }).then(({ app }) => app);
735
+ state.auth.set(auth, app);
736
+ }
737
+ return (await app).fetch(request);
738
+ }));
739
+ }
740
+ /** Handle a request as the server side of the test it was made for. */
741
+ async function serve(request, handle) {
742
+ const id = testContextOf(request);
743
+ const state = id ? contexts.get(id) : void 0;
744
+ if (!id || !state) throw new UnknownTestContext(request.url, id);
745
+ return runAsServer(id, () => handle(state));
746
+ }
747
+ function trim(url) {
748
+ return url.replace(/\/$/, "");
749
+ }
750
+ function isLocal(url) {
751
+ return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname.endsWith(".localhost");
752
+ }
753
+ /**
754
+ * Sign a test's browser in the way a person does: ask the auth server for a
755
+ * magic link, open the email it sent, follow the link.
756
+ *
757
+ * What the generated `browser.signIn(email)` calls. The address's mail is
758
+ * cleared first — so the link is this request's, not one an earlier test left
759
+ * — and cleared again after the test, like any address a test reads. Returns
760
+ * the session the auth server then reports, as better-auth hands it back.
761
+ */
762
+ async function signInWithMagicLink(browser, auth, email = freshAddress()) {
763
+ const context = currentTestContext();
764
+ const state = context && contexts.get(context.id);
765
+ if (!state) throw new UnknownTestContext("signIn", context?.id);
766
+ if (!state.mailbox) throw new NoInbox();
767
+ const inbox = state.mailbox(email);
768
+ await inbox.clear();
769
+ const requested = await auth.signIn.magicLink({ email });
770
+ if (requested.error) throw new SignInFailed(email, `the auth server refused the magic link: ${requested.error.message ?? "no reason given"}`);
771
+ const mail = await inbox.last();
772
+ if (!mail.link) throw new SignInFailed(email, "its email held no link");
773
+ await browser.visit(mail.link);
774
+ const { data } = await auth.getSession();
775
+ if (!data) throw new SignInFailed(email, "the auth server reported no session after the link was opened");
776
+ return data;
777
+ }
778
+ /**
779
+ * An address nobody else signs in as — what `browser.signIn()` uses when the
780
+ * test does not care who it is.
781
+ *
782
+ * Unique rather than only seeded: tests in other files run at the same time,
783
+ * against the same Mailpit and the same unique columns, and a seeded address
784
+ * repeats wherever two tests share a name. The readable half is the seeded
785
+ * faker's, so a failure still names somebody.
786
+ */
787
+ function freshAddress() {
788
+ return `${faker.internet.username().toLowerCase().replace(/[^a-z0-9]/g, "")}.${randomUUID().slice(0, 8)}@example.test`;
789
+ }
790
+ /** `browser.signIn` finished without a session. */
791
+ var SignInFailed = class extends Error {
792
+ email;
793
+ reason;
794
+ constructor(email, reason) {
795
+ super(`Signing ${email} in failed: ${reason}.`);
796
+ this.email = email;
797
+ this.reason = reason;
798
+ this.name = "SignInFailed";
799
+ }
800
+ };
801
+ /** A request reached an in-process server without a test to belong to. */
802
+ var UnknownTestContext = class extends Error {
803
+ url;
804
+ id;
805
+ constructor(url, id) {
806
+ super(id ? `${url} was requested for test ${id}, which is not running. A request that outlives its test — an un-awaited call — lands here.` : `${url} was requested outside any test. Make the request inside a featureTest, so it reaches that test's transactions.`);
807
+ this.url = url;
808
+ this.id = id;
809
+ this.name = "UnknownTestContext";
810
+ }
811
+ };
812
+ /** `mailbox` was used in an app that declares no Email construct. */
813
+ var NoInbox = class extends Error {
814
+ constructor() {
815
+ super("mailbox() reads the inbox of the app's Email construct, and none was found in featureTest's modules — or `gkm test` did not inject its <ID>_INBOX_URL.");
816
+ this.name = "NoInbox";
817
+ }
818
+ };
819
+ /** `db.get(name)` named no database the test is handed. */
820
+ var UnknownDatabase = class extends Error {
821
+ database;
822
+ known;
823
+ constructor(database, known) {
824
+ super(`db.get('${database}') names no database of this app's. ` + (known.length > 0 ? `Its databases: ${known.join(", ")}. ` : "It declares no database of its own. ") + "A tenant an auth server owns is reached through that server, and a reader through the database it reads.");
825
+ this.database = database;
826
+ this.known = known;
827
+ this.name = "UnknownDatabase";
828
+ }
829
+ };
830
+ /** A factory keyed by a service name no database the app declares has. */
831
+ var UnknownFactory = class extends Error {
832
+ factory;
833
+ known;
834
+ constructor(factory, known) {
835
+ super(`There is a test factory for '${factory}', and no database this app declares is called that. ` + (known.length > 0 ? `Its databases: ${known.join(", ")}. ` : "It declares no database. ") + `Name the file after the database construct: test/factories/<construct>.ts.`);
836
+ this.factory = factory;
837
+ this.known = known;
838
+ this.name = "UnknownFactory";
839
+ }
840
+ };
841
+ //#endregion
842
+ export { NoInbox, NoTestManifest, SignInFailed, TEST_CONTEXT_HEADER, TEST_MANIFEST_ENV, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, UnknownDatabase, UnknownFactory, UnknownTestContext, createMswHandlers, featureTest, loadTestManifest, signInWithMagicLink };
843
+
428
844
  //# sourceMappingURL=testing.mjs.map