@geekmidas/constructs 10.0.0-alpha.1 → 10.0.0-alpha.100

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 (422) hide show
  1. package/README.md +223 -158
  2. package/dist/{Construct-CdhThxDI.mjs → Construct-B1vGBPme.mjs} +45 -33
  3. package/dist/Construct-B1vGBPme.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-roId57cU.cjs → Construct-DUSXuTHP.cjs} +65 -47
  7. package/dist/Construct-DUSXuTHP.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-DI3nKoic.d.cts +45 -0
  11. package/dist/Cron-DI3nKoic.d.cts.map +1 -0
  12. package/dist/Cron-uYAHPnp7.d.mts +45 -0
  13. package/dist/Cron-uYAHPnp7.d.mts.map +1 -0
  14. package/dist/CronBuilder-C0Ek1-RA.cjs +121 -0
  15. package/dist/CronBuilder-C0Ek1-RA.cjs.map +1 -0
  16. package/dist/CronBuilder-DaSUm2Na.d.mts +47 -0
  17. package/dist/CronBuilder-DaSUm2Na.d.mts.map +1 -0
  18. package/dist/CronBuilder-Dmix_Pen.mjs +109 -0
  19. package/dist/CronBuilder-Dmix_Pen.mjs.map +1 -0
  20. package/dist/CronBuilder-g1lZLWyG.d.cts +47 -0
  21. package/dist/CronBuilder-g1lZLWyG.d.cts.map +1 -0
  22. package/dist/{Endpoint-BTj58Gob.mjs → Endpoint-BG4UJ9oA.mjs} +146 -109
  23. package/dist/Endpoint-BG4UJ9oA.mjs.map +1 -0
  24. package/dist/{Endpoint-BBkV6l0k.cjs → Endpoint-BoUg8ocM.cjs} +174 -131
  25. package/dist/Endpoint-BoUg8ocM.cjs.map +1 -0
  26. package/dist/{Endpoint-BKR5QH6O.d.mts → Endpoint-Du-NwPX2.d.mts} +83 -91
  27. package/dist/Endpoint-Du-NwPX2.d.mts.map +1 -0
  28. package/dist/{Endpoint-BQ9O0P1w.d.cts → Endpoint-aCvBMPoH.d.cts} +82 -90
  29. package/dist/Endpoint-aCvBMPoH.d.cts.map +1 -0
  30. package/dist/{EndpointFactory-BejSTzbB.mjs → EndpointFactory-BDtsrEvJ.mjs} +60 -77
  31. package/dist/EndpointFactory-BDtsrEvJ.mjs.map +1 -0
  32. package/dist/{EndpointFactory-DYoGLaIT.cjs → EndpointFactory-DJ7gXLpR.cjs} +96 -113
  33. package/dist/EndpointFactory-DJ7gXLpR.cjs.map +1 -0
  34. package/dist/{index-D5zqAJ2e.d.cts → EndpointFactory-DMYdJCOj.d.mts} +78 -134
  35. package/dist/EndpointFactory-DMYdJCOj.d.mts.map +1 -0
  36. package/dist/{index-Cvz551AO.d.mts → EndpointFactory-I7s1co3Y.d.cts} +79 -135
  37. package/dist/EndpointFactory-I7s1co3Y.d.cts.map +1 -0
  38. package/dist/Function-DuqGcbOI.d.mts +76 -0
  39. package/dist/Function-DuqGcbOI.d.mts.map +1 -0
  40. package/dist/Function-Pu-1kKZz.d.cts +76 -0
  41. package/dist/Function-Pu-1kKZz.d.cts.map +1 -0
  42. package/dist/{HonoEndpointAdaptor-7aYNdqJq.mjs → HonoEndpointAdaptor-PtPlbeKY.mjs} +75 -57
  43. package/dist/HonoEndpointAdaptor-PtPlbeKY.mjs.map +1 -0
  44. package/dist/{HonoEndpointAdaptor-wMsCyMgt.cjs → HonoEndpointAdaptor-zVzVLJEO.cjs} +83 -62
  45. package/dist/HonoEndpointAdaptor-zVzVLJEO.cjs.map +1 -0
  46. package/dist/Queue-A3wfD0it.cjs +109 -0
  47. package/dist/Queue-A3wfD0it.cjs.map +1 -0
  48. package/dist/Queue-D6USGS4q.mjs +104 -0
  49. package/dist/Queue-D6USGS4q.mjs.map +1 -0
  50. package/dist/{Queue-D6WeziRD.d.cts → Queue-DlsHRzUp.d.mts} +48 -48
  51. package/dist/Queue-DlsHRzUp.d.mts.map +1 -0
  52. package/dist/{Queue-DpUeqdC8.d.mts → Queue-HPyi0e1i.d.cts} +49 -49
  53. package/dist/Queue-HPyi0e1i.d.cts.map +1 -0
  54. package/dist/QueueBuilder-BjuF0UBl.cjs +135 -0
  55. package/dist/QueueBuilder-BjuF0UBl.cjs.map +1 -0
  56. package/dist/QueueBuilder-Cue73M4t.mjs +118 -0
  57. package/dist/QueueBuilder-Cue73M4t.mjs.map +1 -0
  58. package/dist/QueueBuilder-OSi6LkV9.d.cts +75 -0
  59. package/dist/QueueBuilder-OSi6LkV9.d.cts.map +1 -0
  60. package/dist/QueueBuilder-QHsnVt1P.d.mts +75 -0
  61. package/dist/QueueBuilder-QHsnVt1P.d.mts.map +1 -0
  62. package/dist/{Subscriber-4rBJgDKI.d.mts → Subscriber-Bpp02cGr.d.cts} +30 -21
  63. package/dist/Subscriber-Bpp02cGr.d.cts.map +1 -0
  64. package/dist/{Subscriber-DVQowdyj.d.cts → Subscriber-CtN9R48-.d.mts} +29 -20
  65. package/dist/Subscriber-CtN9R48-.d.mts.map +1 -0
  66. package/dist/SubscriberBuilder-CDy4nHCz.mjs +134 -0
  67. package/dist/SubscriberBuilder-CDy4nHCz.mjs.map +1 -0
  68. package/dist/SubscriberBuilder-CuCMFpYW.d.mts +67 -0
  69. package/dist/SubscriberBuilder-CuCMFpYW.d.mts.map +1 -0
  70. package/dist/SubscriberBuilder-D_owVoHo.cjs +145 -0
  71. package/dist/SubscriberBuilder-D_owVoHo.cjs.map +1 -0
  72. package/dist/SubscriberBuilder-g3fAVWgs.d.cts +67 -0
  73. package/dist/SubscriberBuilder-g3fAVWgs.d.cts.map +1 -0
  74. package/dist/Topic-D74b5cgs.mjs +99 -0
  75. package/dist/Topic-D74b5cgs.mjs.map +1 -0
  76. package/dist/Topic-GHxcU8AG.cjs +104 -0
  77. package/dist/Topic-GHxcU8AG.cjs.map +1 -0
  78. package/dist/adaptors/aws.cjs +332 -188
  79. package/dist/adaptors/aws.cjs.map +1 -1
  80. package/dist/adaptors/aws.d.cts +114 -44
  81. package/dist/adaptors/aws.d.cts.map +1 -1
  82. package/dist/adaptors/aws.d.mts +114 -44
  83. package/dist/adaptors/aws.d.mts.map +1 -1
  84. package/dist/adaptors/aws.mjs +308 -166
  85. package/dist/adaptors/aws.mjs.map +1 -1
  86. package/dist/adaptors/hono.cjs +3 -11
  87. package/dist/adaptors/hono.d.cts +7 -16
  88. package/dist/adaptors/hono.d.cts.map +1 -1
  89. package/dist/adaptors/hono.d.mts +8 -17
  90. package/dist/adaptors/hono.d.mts.map +1 -1
  91. package/dist/adaptors/hono.mjs +2 -11
  92. package/dist/adaptors/testing.cjs +743 -90
  93. package/dist/adaptors/testing.cjs.map +1 -1
  94. package/dist/adaptors/testing.d.cts +351 -54
  95. package/dist/adaptors/testing.d.cts.map +1 -1
  96. package/dist/adaptors/testing.d.mts +351 -54
  97. package/dist/adaptors/testing.d.mts.map +1 -1
  98. package/dist/adaptors/testing.mjs +706 -71
  99. package/dist/adaptors/testing.mjs.map +1 -1
  100. package/dist/auth-BMCJN30Y.d.cts +268 -0
  101. package/dist/auth-BMCJN30Y.d.cts.map +1 -0
  102. package/dist/auth-CcuceLYo.d.mts +268 -0
  103. package/dist/auth-CcuceLYo.d.mts.map +1 -0
  104. package/dist/auth.cjs +302 -34
  105. package/dist/auth.cjs.map +1 -1
  106. package/dist/auth.d.cts +2 -108
  107. package/dist/auth.d.mts +2 -108
  108. package/dist/auth.mjs +290 -28
  109. package/dist/auth.mjs.map +1 -1
  110. package/dist/{cache-CdQ7OLpR.d.cts → cache-CXh6GIgb.d.mts} +4 -7
  111. package/dist/cache-CXh6GIgb.d.mts.map +1 -0
  112. package/dist/{cache-DYoJFcfd.d.mts → cache-DnGDGly3.d.cts} +4 -7
  113. package/dist/cache-DnGDGly3.d.cts.map +1 -0
  114. package/dist/cache.cjs +68 -2
  115. package/dist/cache.cjs.map +1 -0
  116. package/dist/cache.d.cts +1 -2
  117. package/dist/cache.d.mts +1 -2
  118. package/dist/cache.mjs +67 -2
  119. package/dist/cache.mjs.map +1 -0
  120. package/dist/cipher-C1lEFX63.mjs +225 -0
  121. package/dist/cipher-C1lEFX63.mjs.map +1 -0
  122. package/dist/cipher-CVxfwLjk.cjs +332 -0
  123. package/dist/cipher-CVxfwLjk.cjs.map +1 -0
  124. package/dist/{clone-DblgEZZa.mjs → clone-EKNovYHu.mjs} +3 -3
  125. package/dist/clone-EKNovYHu.mjs.map +1 -0
  126. package/dist/{clone-Dy0cR2SZ.cjs → clone-UGJpvQnL.cjs} +7 -8
  127. package/dist/clone-UGJpvQnL.cjs.map +1 -0
  128. package/dist/{construct-interface-BqwRNYA2.d.mts → construct-interface-B1AfqRl4.d.cts} +43 -12
  129. package/dist/construct-interface-B1AfqRl4.d.cts.map +1 -0
  130. package/dist/{construct-interface-D2nNkHUN.d.cts → construct-interface-DluK3_da.d.mts} +43 -12
  131. package/dist/construct-interface-DluK3_da.d.mts.map +1 -0
  132. package/dist/construct-interface.cjs +113 -7
  133. package/dist/construct-interface.cjs.map +1 -0
  134. package/dist/construct-interface.d.cts +2 -2
  135. package/dist/construct-interface.d.mts +2 -2
  136. package/dist/construct-interface.mjs +106 -2
  137. package/dist/construct-interface.mjs.map +1 -0
  138. package/dist/credential.cjs +77 -17
  139. package/dist/credential.cjs.map +1 -1
  140. package/dist/credential.d.cts +34 -9
  141. package/dist/credential.d.cts.map +1 -1
  142. package/dist/credential.d.mts +34 -9
  143. package/dist/credential.d.mts.map +1 -1
  144. package/dist/credential.mjs +71 -13
  145. package/dist/credential.mjs.map +1 -1
  146. package/dist/crons/index.cjs +189 -85
  147. package/dist/crons/index.cjs.map +1 -1
  148. package/dist/crons/index.d.cts +70 -48
  149. package/dist/crons/index.d.cts.map +1 -1
  150. package/dist/crons/index.d.mts +70 -48
  151. package/dist/crons/index.d.mts.map +1 -1
  152. package/dist/crons/index.mjs +183 -81
  153. package/dist/crons/index.mjs.map +1 -1
  154. package/dist/database/kysely.cjs +4 -181
  155. package/dist/database/kysely.d.cts +2 -152
  156. package/dist/database/kysely.d.mts +2 -152
  157. package/dist/database/kysely.mjs +2 -180
  158. package/dist/email.cjs +25 -12
  159. package/dist/email.cjs.map +1 -1
  160. package/dist/email.d.cts +3 -7
  161. package/dist/email.d.cts.map +1 -1
  162. package/dist/email.d.mts +3 -7
  163. package/dist/email.d.mts.map +1 -1
  164. package/dist/email.mjs +16 -3
  165. package/dist/email.mjs.map +1 -1
  166. package/dist/encryption.cjs +96 -0
  167. package/dist/encryption.cjs.map +1 -0
  168. package/dist/encryption.d.cts +117 -0
  169. package/dist/encryption.d.cts.map +1 -0
  170. package/dist/encryption.d.mts +117 -0
  171. package/dist/encryption.d.mts.map +1 -0
  172. package/dist/encryption.mjs +83 -0
  173. package/dist/encryption.mjs.map +1 -0
  174. package/dist/endpoints/index.cjs +8 -11
  175. package/dist/endpoints/index.d.cts +51 -7
  176. package/dist/endpoints/index.d.cts.map +1 -0
  177. package/dist/endpoints/index.d.mts +51 -7
  178. package/dist/endpoints/index.d.mts.map +1 -0
  179. package/dist/endpoints/index.mjs +6 -11
  180. package/dist/external-api-MJ8id87V.d.mts +105 -0
  181. package/dist/external-api-MJ8id87V.d.mts.map +1 -0
  182. package/dist/external-api-O107yzZJ.d.cts +105 -0
  183. package/dist/external-api-O107yzZJ.d.cts.map +1 -0
  184. package/dist/external-api.cjs +142 -0
  185. package/dist/external-api.cjs.map +1 -0
  186. package/dist/external-api.d.cts +2 -0
  187. package/dist/external-api.d.mts +2 -0
  188. package/dist/external-api.mjs +139 -0
  189. package/dist/external-api.mjs.map +1 -0
  190. package/dist/file-server.cjs +42 -10
  191. package/dist/file-server.cjs.map +1 -1
  192. package/dist/file-server.d.cts +6 -10
  193. package/dist/file-server.d.cts.map +1 -1
  194. package/dist/file-server.d.mts +6 -10
  195. package/dist/file-server.d.mts.map +1 -1
  196. package/dist/file-server.mjs +34 -2
  197. package/dist/file-server.mjs.map +1 -1
  198. package/dist/functions/index.cjs +2 -6
  199. package/dist/functions/index.d.cts +3 -4
  200. package/dist/functions/index.d.mts +3 -4
  201. package/dist/functions/index.mjs +2 -6
  202. package/dist/{functions-Cpff1uZH.mjs → functions-BFizikJU.mjs} +394 -243
  203. package/dist/functions-BFizikJU.mjs.map +1 -0
  204. package/dist/{functions-DukjG8ov.cjs → functions-CfzJG9hK.cjs} +432 -275
  205. package/dist/functions-CfzJG9hK.cjs.map +1 -0
  206. package/dist/index-BuzRvKOQ.d.cts +115 -0
  207. package/dist/index-BuzRvKOQ.d.cts.map +1 -0
  208. package/dist/index-CTkKOer4.d.mts +115 -0
  209. package/dist/index-CTkKOer4.d.mts.map +1 -0
  210. package/dist/index-CeEtxDmK.d.cts +79 -0
  211. package/dist/index-CeEtxDmK.d.cts.map +1 -0
  212. package/dist/index-CeEtxDmK.d.mts +79 -0
  213. package/dist/index-CeEtxDmK.d.mts.map +1 -0
  214. package/dist/index.cjs +6 -3
  215. package/dist/index.d.cts +27 -4
  216. package/dist/index.d.cts.map +1 -0
  217. package/dist/index.d.mts +27 -4
  218. package/dist/index.d.mts.map +1 -0
  219. package/dist/index.mjs +3 -3
  220. package/dist/kms-B-Hm3d5r.cjs +85 -0
  221. package/dist/kms-B-Hm3d5r.cjs.map +1 -0
  222. package/dist/kms-BdUlMJEZ.mjs +85 -0
  223. package/dist/kms-BdUlMJEZ.mjs.map +1 -0
  224. package/dist/kysely-Bii4l6eP.mjs +370 -0
  225. package/dist/kysely-Bii4l6eP.mjs.map +1 -0
  226. package/dist/kysely-CO_Dk43W.cjs +383 -0
  227. package/dist/kysely-CO_Dk43W.cjs.map +1 -0
  228. package/dist/kysely-D0bpzgPs.d.cts +175 -0
  229. package/dist/kysely-D0bpzgPs.d.cts.map +1 -0
  230. package/dist/kysely-DUqC3Ie0.d.mts +175 -0
  231. package/dist/kysely-DUqC3Ie0.d.mts.map +1 -0
  232. package/dist/{telemetry-C3L0iS28.d.cts → lambdaTelemetry-8vnmVZQ5.d.cts} +3 -6
  233. package/dist/lambdaTelemetry-8vnmVZQ5.d.cts.map +1 -0
  234. package/dist/{telemetry-D7bVFLGi.d.mts → lambdaTelemetry-8vnmVZQ5.d.mts} +3 -6
  235. package/dist/lambdaTelemetry-8vnmVZQ5.d.mts.map +1 -0
  236. package/dist/{lazyAccessors-DM6HcXQk.mjs → lazyAccessors-CFanua0O.mjs} +20 -21
  237. package/dist/lazyAccessors-CFanua0O.mjs.map +1 -0
  238. package/dist/{lazyAccessors-DrJj8NpA.cjs → lazyAccessors-hJKGv8Ay.cjs} +60 -62
  239. package/dist/lazyAccessors-hJKGv8Ay.cjs.map +1 -0
  240. package/dist/mobile-app.cjs +73 -0
  241. package/dist/mobile-app.cjs.map +1 -0
  242. package/dist/mobile-app.d.cts +61 -0
  243. package/dist/mobile-app.d.cts.map +1 -0
  244. package/dist/mobile-app.d.mts +61 -0
  245. package/dist/mobile-app.d.mts.map +1 -0
  246. package/dist/mobile-app.mjs +72 -0
  247. package/dist/mobile-app.mjs.map +1 -0
  248. package/dist/object-storage.cjs +18 -10
  249. package/dist/object-storage.cjs.map +1 -1
  250. package/dist/object-storage.d.cts +3 -7
  251. package/dist/object-storage.d.cts.map +1 -1
  252. package/dist/object-storage.d.mts +3 -7
  253. package/dist/object-storage.d.mts.map +1 -1
  254. package/dist/object-storage.mjs +11 -3
  255. package/dist/object-storage.mjs.map +1 -1
  256. package/dist/processAudits-BRRVVHUB.mjs +131 -0
  257. package/dist/processAudits-BRRVVHUB.mjs.map +1 -0
  258. package/dist/processAudits-DasOZjPl.cjs +154 -0
  259. package/dist/processAudits-DasOZjPl.cjs.map +1 -0
  260. package/dist/queue/index.cjs +6 -189
  261. package/dist/queue/index.d.cts +3 -60
  262. package/dist/queue/index.d.mts +3 -60
  263. package/dist/queue/index.mjs +3 -186
  264. package/dist/rest-api.cjs +92 -63
  265. package/dist/rest-api.cjs.map +1 -1
  266. package/dist/rest-api.d.cts +81 -61
  267. package/dist/rest-api.d.cts.map +1 -1
  268. package/dist/rest-api.d.mts +81 -61
  269. package/dist/rest-api.d.mts.map +1 -1
  270. package/dist/rest-api.mjs +84 -55
  271. package/dist/rest-api.mjs.map +1 -1
  272. package/dist/{chunk-DWy1uDak.cjs → rolldown-runtime-y5ARvAq5.cjs} +14 -18
  273. package/dist/runSubscriber-BHvJ8POr.mjs +109 -0
  274. package/dist/runSubscriber-BHvJ8POr.mjs.map +1 -0
  275. package/dist/runSubscriber-D8nLXIv1.cjs +126 -0
  276. package/dist/runSubscriber-D8nLXIv1.cjs.map +1 -0
  277. package/dist/shutdown-BMJmAhSt.cjs +38 -0
  278. package/dist/shutdown-BMJmAhSt.cjs.map +1 -0
  279. package/dist/shutdown-C7xa8x9S.mjs +27 -0
  280. package/dist/shutdown-C7xa8x9S.mjs.map +1 -0
  281. package/dist/site.cjs +35 -9
  282. package/dist/site.cjs.map +1 -1
  283. package/dist/site.d.cts +25 -22
  284. package/dist/site.d.cts.map +1 -1
  285. package/dist/site.d.mts +25 -22
  286. package/dist/site.d.mts.map +1 -1
  287. package/dist/site.mjs +31 -5
  288. package/dist/site.mjs.map +1 -1
  289. package/dist/stages-BSCF19o2.d.cts +56 -0
  290. package/dist/stages-BSCF19o2.d.cts.map +1 -0
  291. package/dist/stages-BSCF19o2.d.mts +56 -0
  292. package/dist/stages-BSCF19o2.d.mts.map +1 -0
  293. package/dist/subscribers/index.cjs +111 -101
  294. package/dist/subscribers/index.cjs.map +1 -1
  295. package/dist/subscribers/index.d.cts +44 -56
  296. package/dist/subscribers/index.d.cts.map +1 -1
  297. package/dist/subscribers/index.d.mts +44 -56
  298. package/dist/subscribers/index.d.mts.map +1 -1
  299. package/dist/subscribers/index.mjs +108 -98
  300. package/dist/subscribers/index.mjs.map +1 -1
  301. package/dist/surfaceEnv-CNimK76p.cjs +56 -0
  302. package/dist/surfaceEnv-CNimK76p.cjs.map +1 -0
  303. package/dist/surfaceEnv-wMT5QzgZ.mjs +45 -0
  304. package/dist/surfaceEnv-wMT5QzgZ.mjs.map +1 -0
  305. package/dist/telemetry-B48RLjyk.d.cts +40 -0
  306. package/dist/telemetry-B48RLjyk.d.cts.map +1 -0
  307. package/dist/telemetry-DRtT1_0A.d.mts +40 -0
  308. package/dist/telemetry-DRtT1_0A.d.mts.map +1 -0
  309. package/dist/telemetry.cjs +56 -0
  310. package/dist/telemetry.cjs.map +1 -0
  311. package/dist/telemetry.d.cts +2 -0
  312. package/dist/telemetry.d.mts +2 -0
  313. package/dist/telemetry.mjs +55 -0
  314. package/dist/telemetry.mjs.map +1 -0
  315. package/dist/topic/index.cjs +3 -137
  316. package/dist/topic/index.d.cts +2 -32
  317. package/dist/topic/index.d.mts +2 -32
  318. package/dist/topic/index.mjs +2 -134
  319. package/dist/tracing-CxaZ98IB.mjs +110 -0
  320. package/dist/tracing-CxaZ98IB.mjs.map +1 -0
  321. package/dist/tracing-DPMidF_r.cjs +127 -0
  322. package/dist/tracing-DPMidF_r.cjs.map +1 -0
  323. package/dist/{types-BlAkSuGI.d.cts → types-DMuSQeLL.d.cts} +3 -5
  324. package/dist/types-DMuSQeLL.d.cts.map +1 -0
  325. package/dist/{types-aKksMEWL.d.mts → types-DMuSQeLL.d.mts} +3 -5
  326. package/dist/types-DMuSQeLL.d.mts.map +1 -0
  327. package/dist/types.d.cts +1 -1
  328. package/dist/types.d.mts +1 -1
  329. package/dist/types.mjs +1 -0
  330. package/dist/worker.cjs +191 -0
  331. package/dist/worker.cjs.map +1 -0
  332. package/dist/worker.d.cts +171 -0
  333. package/dist/worker.d.cts.map +1 -0
  334. package/dist/worker.d.mts +171 -0
  335. package/dist/worker.d.mts.map +1 -0
  336. package/dist/worker.mjs +190 -0
  337. package/dist/worker.mjs.map +1 -0
  338. package/package.json +116 -70
  339. package/dist/AWSScheduledFunction-9bJS4WdJ.d.cts +0 -122
  340. package/dist/AWSScheduledFunction-9bJS4WdJ.d.cts.map +0 -1
  341. package/dist/AWSScheduledFunction-BJjj8B5V.mjs +0 -243
  342. package/dist/AWSScheduledFunction-BJjj8B5V.mjs.map +0 -1
  343. package/dist/AWSScheduledFunction-BO5iEMSh.d.mts +0 -122
  344. package/dist/AWSScheduledFunction-BO5iEMSh.d.mts.map +0 -1
  345. package/dist/AWSScheduledFunction-qu4ieRZR.cjs +0 -255
  346. package/dist/AWSScheduledFunction-qu4ieRZR.cjs.map +0 -1
  347. package/dist/Construct-B-xc0SE9.d.mts +0 -104
  348. package/dist/Construct-B-xc0SE9.d.mts.map +0 -1
  349. package/dist/Construct-CdhThxDI.mjs.map +0 -1
  350. package/dist/Construct-WhCXIOPV.d.cts +0 -104
  351. package/dist/Construct-WhCXIOPV.d.cts.map +0 -1
  352. package/dist/Construct-roId57cU.cjs.map +0 -1
  353. package/dist/Endpoint-BBkV6l0k.cjs.map +0 -1
  354. package/dist/Endpoint-BKR5QH6O.d.mts.map +0 -1
  355. package/dist/Endpoint-BQ9O0P1w.d.cts.map +0 -1
  356. package/dist/Endpoint-BTj58Gob.mjs.map +0 -1
  357. package/dist/EndpointFactory-BejSTzbB.mjs.map +0 -1
  358. package/dist/EndpointFactory-DYoGLaIT.cjs.map +0 -1
  359. package/dist/HonoEndpointAdaptor-7aYNdqJq.mjs.map +0 -1
  360. package/dist/HonoEndpointAdaptor-wMsCyMgt.cjs.map +0 -1
  361. package/dist/Queue-D6WeziRD.d.cts.map +0 -1
  362. package/dist/Queue-DpUeqdC8.d.mts.map +0 -1
  363. package/dist/Subscriber-4rBJgDKI.d.mts.map +0 -1
  364. package/dist/Subscriber-DVQowdyj.d.cts.map +0 -1
  365. package/dist/Topic-Ohx9dvWr.d.cts +0 -91
  366. package/dist/Topic-Ohx9dvWr.d.cts.map +0 -1
  367. package/dist/Topic-cmy2jOUy.d.mts +0 -91
  368. package/dist/Topic-cmy2jOUy.d.mts.map +0 -1
  369. package/dist/auth.d.cts.map +0 -1
  370. package/dist/auth.d.mts.map +0 -1
  371. package/dist/cache-0ANvRQnD.mjs +0 -51
  372. package/dist/cache-0ANvRQnD.mjs.map +0 -1
  373. package/dist/cache-3WSvAulx.cjs +0 -57
  374. package/dist/cache-3WSvAulx.cjs.map +0 -1
  375. package/dist/cache-CdQ7OLpR.d.cts.map +0 -1
  376. package/dist/cache-DYoJFcfd.d.mts.map +0 -1
  377. package/dist/clone-DblgEZZa.mjs.map +0 -1
  378. package/dist/clone-Dy0cR2SZ.cjs.map +0 -1
  379. package/dist/construct-interface-BfjcOD_E.cjs +0 -117
  380. package/dist/construct-interface-BfjcOD_E.cjs.map +0 -1
  381. package/dist/construct-interface-BqwRNYA2.d.mts.map +0 -1
  382. package/dist/construct-interface-D2nNkHUN.d.cts.map +0 -1
  383. package/dist/construct-interface-Z4CpS8tK.mjs +0 -81
  384. package/dist/construct-interface-Z4CpS8tK.mjs.map +0 -1
  385. package/dist/database/kysely.cjs.map +0 -1
  386. package/dist/database/kysely.d.cts.map +0 -1
  387. package/dist/database/kysely.d.mts.map +0 -1
  388. package/dist/database/kysely.mjs.map +0 -1
  389. package/dist/functions-Cpff1uZH.mjs.map +0 -1
  390. package/dist/functions-DukjG8ov.cjs.map +0 -1
  391. package/dist/index-BTvozlUD.d.cts +0 -163
  392. package/dist/index-BTvozlUD.d.cts.map +0 -1
  393. package/dist/index-Cvz551AO.d.mts.map +0 -1
  394. package/dist/index-D5zqAJ2e.d.cts.map +0 -1
  395. package/dist/index-L7pz0R0T.d.mts +0 -162
  396. package/dist/index-L7pz0R0T.d.mts.map +0 -1
  397. package/dist/lazyAccessors-DM6HcXQk.mjs.map +0 -1
  398. package/dist/lazyAccessors-DrJj8NpA.cjs.map +0 -1
  399. package/dist/processAudits-Bc8rz6Ev.cjs +0 -92
  400. package/dist/processAudits-Bc8rz6Ev.cjs.map +0 -1
  401. package/dist/processAudits-D89tICM4.mjs +0 -80
  402. package/dist/processAudits-D89tICM4.mjs.map +0 -1
  403. package/dist/publisher-CGEo8UKD.mjs +0 -41
  404. package/dist/publisher-CGEo8UKD.mjs.map +0 -1
  405. package/dist/publisher-CqGsXB2X.cjs +0 -53
  406. package/dist/publisher-CqGsXB2X.cjs.map +0 -1
  407. package/dist/queue/index.cjs.map +0 -1
  408. package/dist/queue/index.d.cts.map +0 -1
  409. package/dist/queue/index.d.mts.map +0 -1
  410. package/dist/queue/index.mjs.map +0 -1
  411. package/dist/surfaceEnv-BFXEms2f.cjs +0 -39
  412. package/dist/surfaceEnv-BFXEms2f.cjs.map +0 -1
  413. package/dist/surfaceEnv-C3Ktahea.mjs +0 -27
  414. package/dist/surfaceEnv-C3Ktahea.mjs.map +0 -1
  415. package/dist/telemetry-C3L0iS28.d.cts.map +0 -1
  416. package/dist/telemetry-D7bVFLGi.d.mts.map +0 -1
  417. package/dist/topic/index.cjs.map +0 -1
  418. package/dist/topic/index.d.cts.map +0 -1
  419. package/dist/topic/index.d.mts.map +0 -1
  420. package/dist/topic/index.mjs.map +0 -1
  421. package/dist/types-BlAkSuGI.d.cts.map +0 -1
  422. package/dist/types-aKksMEWL.d.mts.map +0 -1
@@ -1,26 +1,63 @@
1
- import "../Construct-CdhThxDI.mjs";
2
- import "../construct-interface-Z4CpS8tK.mjs";
3
- import { FunctionBuilder } from "../functions-Cpff1uZH.mjs";
4
- import "../clone-DblgEZZa.mjs";
5
- import { Endpoint, ResponseBuilder } from "../Endpoint-BTj58Gob.mjs";
6
- import { publishConstructEvents, publishEvents } from "../publisher-CGEo8UKD.mjs";
7
- import { executeWithAuditTransaction } from "../processAudits-D89tICM4.mjs";
8
- import { createCookieHeaderAccessor, createObjectHeaders } from "../lazyAccessors-DM6HcXQk.mjs";
9
- import { HonoEndpoint } from "../HonoEndpointAdaptor-7aYNdqJq.mjs";
1
+ import { isConsumable } from "../construct-interface.mjs";
2
+ import { BetterAuth } from "../auth.mjs";
3
+ import { a as publishEvents, i as publishConstructEvents, t as FunctionBuilder } from "../functions-BFizikJU.mjs";
4
+ import { n as ResponseBuilder, t as Endpoint } from "../Endpoint-BG4UJ9oA.mjs";
5
+ import { t as Queue } from "../Queue-D6USGS4q.mjs";
6
+ import { Email } from "../email.mjs";
7
+ import { t as KyselyDatabase } from "../kysely-Bii4l6eP.mjs";
8
+ import { c as createObjectHeaders, r as createCookieHeaderAccessor } from "../lazyAccessors-CFanua0O.mjs";
9
+ import { t as Topic } from "../Topic-D74b5cgs.mjs";
10
+ import { t as HonoEndpoint } from "../HonoEndpointAdaptor-PtPlbeKY.mjs";
11
+ import { n as executeWithAuditTransaction } from "../processAudits-BRRVVHUB.mjs";
12
+ import { provideKey } from "@geekmidas/manifest";
13
+ import { randomUUID } from "node:crypto";
10
14
  import { ForbiddenError } from "@geekmidas/errors";
11
15
  import { EnvironmentParser } from "@geekmidas/envkit";
12
- import { ServiceDiscovery, runWithRequestContext } from "@geekmidas/services";
13
- import { DefaultAuditor } from "@geekmidas/audit";
16
+ import { ServiceDiscovery, runWithRequestContext, serviceContext } from "@geekmidas/services";
14
17
  import { Hono } from "hono";
18
+ import { DefaultAuditor } from "@geekmidas/audit";
19
+ import { TEST_CONTEXT_HEADER, currentTestContext, installContextFetch, runAsServer, runInTestContext, testContextOf } from "@geekmidas/testkit/context";
15
20
  import { http } from "msw";
16
-
17
- //#region src/endpoints/MswEndpointAdaptor.ts
21
+ import { Browser } from "@geekmidas/testkit/browser";
22
+ import { faker } from "@geekmidas/testkit/faker";
23
+ import { createMailbox } from "@geekmidas/testkit/mailbox";
24
+ import { TransactionRegistry } from "@geekmidas/testkit/transactions";
25
+ import { setupServer } from "msw/node";
26
+ import { afterAll, beforeAll, test } from "vitest";
27
+ import { existsSync, readFileSync } from "node:fs";
28
+ import tls from "node:tls";
29
+ import { fileURLToPath } from "node:url";
30
+ //#region src/testing/peer.ts
18
31
  /**
19
- * Header used to identify which test context a request belongs to.
20
- * Each concurrent test registers its own context (services, db transaction, etc.)
21
- * and the MSW handler looks it up by this header value.
32
+ * The TCP peer a test's in-process requests arrive from.
33
+ *
34
+ * A feature test hands a request straight to a surface's Hono app — no
35
+ * socket, no server — so the app's bindings have no peer to read. Deployed,
36
+ * every request has one, and what a surface trusts follows from it: the auth
37
+ * server honours `x-gkm-client-ip` only from an internal caller, a loopback
38
+ * or private peer with no `Origin` and no forwarding header. With no peer at
39
+ * all the header was dropped, and every test's session check became the same
40
+ * client to Better Auth's rate limiter.
41
+ *
42
+ * So an in-process dispatch says where it came from, the way
43
+ * `@hono/node-server` does: its bindings carry `incoming.socket.remoteAddress`.
44
+ * The address is loopback because that is the truth — the request came from
45
+ * this process. A browser's own address still travels in its
46
+ * `x-forwarded-for`, which makes it outside traffic exactly as it would be
47
+ * behind the stack's proxy.
48
+ *
49
+ * Only a test's dispatch passes these. A runtime with no socket of its own
50
+ * (Lambda, Bun) still has no peer, and a request with no peer is still not an
51
+ * internal caller's.
22
52
  */
23
- const TEST_CONTEXT_HEADER = "x-test-context-id";
53
+ /** The address an in-process request presents as its peer. */
54
+ const IN_PROCESS_PEER_ADDRESS = "127.0.0.1";
55
+ /** Bindings for `app.fetch(request, bindings)` from inside this process. */
56
+ function inProcessBindings() {
57
+ return { incoming: { socket: { remoteAddress: IN_PROCESS_PEER_ADDRESS } } };
58
+ }
59
+ //#endregion
60
+ //#region src/endpoints/MswEndpointAdaptor.ts
24
61
  const MSW_HTTP_METHODS = [
25
62
  "get",
26
63
  "post",
@@ -68,7 +105,6 @@ function createMswHandlers(endpoints, options) {
68
105
  break;
69
106
  }
70
107
  }
71
- if (ctxOptions.publisher) serviceDefs.push(ctxOptions.publisher);
72
108
  if (ctxOptions.auditorStorage !== void 0) {
73
109
  for (const endpoint of endpoints) if (endpoint.auditorStorageService) {
74
110
  serviceDefs.push({
@@ -99,7 +135,7 @@ function createMswHandlers(endpoints, options) {
99
135
  });
100
136
  const app = new Hono();
101
137
  HonoEndpoint.addRoute(endpoint, ctx.serviceDiscovery, app);
102
- const response = await app.request(request);
138
+ const response = await app.request(request, void 0, inProcessBindings());
103
139
  return new Response(response.body, {
104
140
  status: response.status,
105
141
  statusText: response.statusText,
@@ -112,7 +148,6 @@ function createMswHandlers(endpoints, options) {
112
148
  registerContext
113
149
  };
114
150
  }
115
-
116
151
  //#endregion
117
152
  //#region src/endpoints/TestEndpointAdaptor.ts
118
153
  /**
@@ -132,6 +167,8 @@ function serializeCookie(name, value, options) {
132
167
  return cookieString;
133
168
  }
134
169
  var TestEndpointAdaptor = class TestEndpointAdaptor {
170
+ endpoint;
171
+ serviceDiscovery;
135
172
  static getDefaultServiceDiscover(_endpoint) {
136
173
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
137
174
  }
@@ -154,10 +191,12 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
154
191
  method: this.endpoint.method
155
192
  });
156
193
  const rawDb = ctx.database;
194
+ const operation = `${this.endpoint.method} ${this.endpoint.route}`;
157
195
  return runWithRequestContext({
158
196
  logger,
159
197
  requestId,
160
- startTime
198
+ startTime,
199
+ operation
161
200
  }, async () => {
162
201
  const session = await this.endpoint.getSession({
163
202
  logger,
@@ -166,7 +205,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
166
205
  cookie,
167
206
  ...rawDb !== void 0 && { db: rawDb }
168
207
  });
169
- const isAuthorized = await this.endpoint.authorize({
208
+ if (!await this.endpoint.authorize({
170
209
  header,
171
210
  cookie,
172
211
  services: ctx.services,
@@ -176,8 +215,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
176
215
  body,
177
216
  query,
178
217
  params
179
- });
180
- if (!isAuthorized) {
218
+ })) {
181
219
  logger.warn("Forbidden access attempt");
182
220
  throw new ForbiddenError("Forbidden access to the endpoint", "You do not have permission to access this resource.");
183
221
  }
@@ -199,24 +237,22 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
199
237
  } catch (error) {
200
238
  logger.error(error, "Failed to extract actor for audits");
201
239
  }
202
- const auditor = new DefaultAuditor({
203
- actor,
204
- storage: auditorStorage,
205
- metadata: {
206
- endpoint: this.endpoint.route,
207
- method: this.endpoint.method
208
- }
209
- });
210
240
  auditContext = {
211
- auditor,
241
+ auditor: new DefaultAuditor({
242
+ actor,
243
+ storage: auditorStorage,
244
+ metadata: {
245
+ endpoint: this.endpoint.route,
246
+ method: this.endpoint.method
247
+ }
248
+ }),
212
249
  storage: auditorStorage
213
250
  };
214
251
  }
215
252
  const audits = this.endpoint.audits;
216
253
  if (!auditContext && audits?.length) logger.warn("No auditor storage service available");
217
- const result = await executeWithAuditTransaction(auditContext, async (auditor) => {
218
- const trx = auditor?.getTransaction?.();
219
- const db = trx ?? rawDb;
254
+ const { output, metadata } = await executeWithAuditTransaction(auditContext, async (auditor) => {
255
+ const db = auditor?.getTransaction?.() ?? rawDb;
220
256
  const responseBuilder = new ResponseBuilder();
221
257
  const response = await this.endpoint.handler({
222
258
  body,
@@ -231,36 +267,33 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
231
267
  db
232
268
  }, responseBuilder);
233
269
  let data = response;
234
- let metadata$1 = responseBuilder.getMetadata();
270
+ let metadata = responseBuilder.getMetadata();
235
271
  if (Endpoint.hasMetadata(response)) {
236
272
  data = response.data;
237
- metadata$1 = response.metadata;
273
+ metadata = response.metadata;
238
274
  }
239
- const output$1 = await this.endpoint.parseOutput(data);
240
275
  return {
241
- output: output$1,
242
- metadata: metadata$1,
276
+ output: await this.endpoint.parseOutput(data),
277
+ metadata,
243
278
  responseBuilder
244
279
  };
245
- }, async (result$1, auditor) => {
280
+ }, async (result, auditor) => {
246
281
  if (!audits?.length) return;
247
282
  for (const audit of audits) {
248
- if (audit.when && !audit.when(result$1.output)) continue;
249
- const payload = audit.payload(result$1.output);
250
- const entityId = audit.entityId?.(result$1.output);
283
+ if (audit.when && !audit.when(result.output)) continue;
284
+ const payload = audit.payload(result.output);
285
+ const entityId = audit.entityId?.(result.output);
251
286
  auditor.audit(audit.type, payload, {
252
287
  table: audit.table,
253
288
  entityId
254
289
  });
255
290
  }
256
291
  }, { db: rawDb });
257
- const { output, metadata } = result;
258
- ctx.publisher && await this.serviceDiscovery.register([ctx.publisher]);
259
- await publishConstructEvents(this.endpoint, output, this.serviceDiscovery);
292
+ await publishConstructEvents(this.endpoint, output, this.serviceDiscovery, this.endpoint.logger, ctx.services);
260
293
  const headers = { ...metadata.headers || {} };
261
294
  if (metadata.cookies && metadata.cookies.size > 0) {
262
295
  const setCookieValues = [];
263
- for (const [name, cookie$1] of metadata.cookies.entries()) setCookieValues.push(serializeCookie(name, cookie$1.value, cookie$1.options));
296
+ for (const [name, cookie] of metadata.cookies.entries()) setCookieValues.push(serializeCookie(name, cookie.value, cookie.options));
264
297
  headers["set-cookie"] = setCookieValues;
265
298
  }
266
299
  return {
@@ -271,14 +304,14 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
271
304
  });
272
305
  }
273
306
  async request(ctx) {
274
- const response = await this.fullRequest(ctx);
275
- return response.body;
307
+ return (await this.fullRequest(ctx)).body;
276
308
  }
277
309
  };
278
-
279
310
  //#endregion
280
311
  //#region src/functions/TestFunctionAdaptor.ts
281
312
  var TestFunctionAdaptor = class TestFunctionAdaptor {
313
+ fn;
314
+ serviceDiscovery;
282
315
  static getDefaultServiceDiscovery(_fn) {
283
316
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
284
317
  }
@@ -294,15 +327,11 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
294
327
  else services = await this.serviceDiscovery.register(this.fn.services);
295
328
  let db;
296
329
  if ("db" in ctx && ctx.db !== void 0) db = ctx.db;
297
- else if (this.fn.databaseService) {
298
- const dbServices = await this.serviceDiscovery.register([this.fn.databaseService]);
299
- db = dbServices[this.fn.databaseService.serviceName];
300
- }
330
+ else if (this.fn.databaseService) db = (await this.serviceDiscovery.register([this.fn.databaseService]))[this.fn.databaseService.serviceName];
301
331
  let auditor;
302
332
  if ("auditor" in ctx && ctx.auditor !== void 0) auditor = ctx.auditor;
303
333
  else if (this.fn.auditorStorageService) {
304
- const auditServices = await this.serviceDiscovery.register([this.fn.auditorStorageService]);
305
- const storage = auditServices[this.fn.auditorStorageService.serviceName];
334
+ const storage = (await this.serviceDiscovery.register([this.fn.auditorStorageService]))[this.fn.auditorStorageService.serviceName];
306
335
  auditor = new DefaultAuditor({
307
336
  actor: {
308
337
  id: "system",
@@ -316,11 +345,10 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
316
345
  });
317
346
  }
318
347
  const requestId = `test-${Date.now()}`;
319
- const startTime = Date.now();
320
348
  return runWithRequestContext({
321
349
  logger,
322
350
  requestId,
323
- startTime
351
+ startTime: Date.now()
324
352
  }, async () => {
325
353
  const response = await this.fn.fn({
326
354
  input: parsedInput,
@@ -337,24 +365,26 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
337
365
  await auditor.flush();
338
366
  }
339
367
  }
340
- await publishEvents(logger, this.serviceDiscovery, this.fn.events, output, this.fn.publisherService);
368
+ await publishEvents(logger, this.serviceDiscovery, this.fn.events, output, services);
341
369
  return output;
342
370
  });
343
371
  }
344
372
  };
345
-
346
373
  //#endregion
347
374
  //#region src/queue/TestQueueAdaptor.ts
348
375
  /**
349
376
  * In-memory test driver for a {@link Queue} worker. Hand it a batch of messages
350
377
  * and it registers the queue's services, runs the handler in a request context,
351
- * and returns the handler result — no SQS/pg-boss required.
378
+ * and returns the handler result — no SQS/pg-boss required. A queue with a
379
+ * database gets `db` registered from it, or the one the request passes.
352
380
  *
353
381
  * @example
354
382
  * const adapter = new TestQueueAdaptor(ordersQueue);
355
383
  * await adapter.invoke({ messages: [{ orderId: '123' }] });
356
384
  */
357
385
  var TestQueueAdaptor = class TestQueueAdaptor {
386
+ queue;
387
+ serviceDiscovery;
358
388
  static getDefaultServiceDiscovery() {
359
389
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
360
390
  }
@@ -365,23 +395,33 @@ var TestQueueAdaptor = class TestQueueAdaptor {
365
395
  async invoke(request) {
366
396
  const logger = this.queue.logger.child({ test: true });
367
397
  const services = request.services ?? await this.serviceDiscovery.register(this.queue.services);
398
+ const db = request.db !== void 0 ? request.db : await this.getDatabase();
368
399
  const requestId = `test-${Date.now()}`;
369
400
  const startTime = Date.now();
401
+ const operation = `queue ${this.queue.name}`;
370
402
  return runWithRequestContext({
371
403
  logger,
372
404
  requestId,
373
- startTime
405
+ startTime,
406
+ operation
374
407
  }, () => this.queue.handler({
375
408
  messages: request.messages,
376
409
  services,
377
- logger
410
+ logger,
411
+ db
378
412
  }));
379
413
  }
414
+ async getDatabase() {
415
+ const service = this.queue.databaseService;
416
+ if (!service) return void 0;
417
+ return (await this.serviceDiscovery.register([service]))[service.serviceName];
418
+ }
380
419
  };
381
-
382
420
  //#endregion
383
421
  //#region src/subscribers/TestSubscriberAdaptor.ts
384
422
  var TestSubscriberAdaptor = class TestSubscriberAdaptor {
423
+ subscriber;
424
+ serviceDiscovery;
385
425
  static getDefaultServiceDiscovery() {
386
426
  return ServiceDiscovery.getInstance(new EnvironmentParser({}));
387
427
  }
@@ -394,19 +434,23 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
394
434
  let services;
395
435
  if (request.services) services = request.services;
396
436
  else services = await this.serviceDiscovery.register(this.subscriber.services);
437
+ const db = request.db !== void 0 ? request.db : await this.getDatabase();
397
438
  const filteredEvents = this.filterEvents(request.events);
398
439
  if (filteredEvents.length === 0) return { batchItemFailures: [] };
399
440
  const requestId = `test-${Date.now()}`;
400
441
  const startTime = Date.now();
442
+ const operation = `subscriber ${this.subscriber.topicName ?? "test"}`;
401
443
  return runWithRequestContext({
402
444
  logger,
403
445
  requestId,
404
- startTime
446
+ startTime,
447
+ operation
405
448
  }, async () => {
406
449
  const result = await this.subscriber.handler({
407
450
  events: filteredEvents,
408
451
  services,
409
- logger
452
+ logger,
453
+ db
410
454
  });
411
455
  let output = result;
412
456
  if (this.subscriber.outputSchema && result) {
@@ -414,16 +458,607 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
414
458
  if (validationResult.issues) throw new Error("Subscriber output validation failed");
415
459
  output = validationResult.value;
416
460
  }
417
- await publishEvents(logger, this.serviceDiscovery, this.subscriber.events, output, this.subscriber.publisherService);
418
461
  return output;
419
462
  });
420
463
  }
464
+ async getDatabase() {
465
+ const service = this.subscriber.databaseService;
466
+ if (!service) return void 0;
467
+ return (await this.serviceDiscovery.register([service]))[service.serviceName];
468
+ }
421
469
  filterEvents(events) {
422
470
  if (!this.subscriber.subscribedEvents) return events;
423
471
  return events.filter((event) => this.subscriber.subscribedEvents.includes(event.type));
424
472
  }
425
473
  };
426
-
427
474
  //#endregion
428
- export { TEST_CONTEXT_HEADER, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, createMswHandlers };
475
+ //#region src/testing/manifest.ts
476
+ /**
477
+ * The test manifest: what `gkm test` knows about an app, written down for the
478
+ * suite it starts.
479
+ *
480
+ * `gkm test` discovers the constructs, reconciles the test stage and resolves
481
+ * its environment — then, until this existed, threw all of it away and left a
482
+ * test to declare it again by hand. The manifest keeps it: which construct and
483
+ * endpoint is exported where, and the environment the test stage resolved,
484
+ * under the keys the constructs themselves derive. A feature test is built from
485
+ * it, so nothing a test says can drift from what the app declares.
486
+ */
487
+ /** The environment variable `gkm test` names the manifest in. */
488
+ const TEST_MANIFEST_ENV = "GKM_TEST_MANIFEST";
489
+ /**
490
+ * Read a test manifest: from a path, a `file:` URL, or — given nothing — the
491
+ * one `gkm test` named in `GKM_TEST_MANIFEST`.
492
+ */
493
+ function loadTestManifest(from) {
494
+ const location = from ?? process.env["GKM_TEST_MANIFEST"];
495
+ if (!location) throw new NoTestManifest();
496
+ trustLocalEdge();
497
+ const path = location instanceof URL || location.startsWith("file:") ? fileURLToPath(location) : location;
498
+ return JSON.parse(readFileSync(path, "utf-8"));
499
+ }
500
+ let trusted = false;
501
+ /**
502
+ * Trust the local edge's certificate authority in this thread.
503
+ *
504
+ * `NODE_EXTRA_CA_CERTS` does it for a process started with it — which a
505
+ * suite started by `gkm test` is, and one started by plain `vitest` or an
506
+ * editor is not: its setup only learns the path once Vitest is running, and a
507
+ * worker *thread* shares that process and keeps a TLS store of its own. Every
508
+ * feature test loads the manifest, so this is the one place each worker passes
509
+ * through.
510
+ */
511
+ function trustLocalEdge() {
512
+ const certificate = process.env.NODE_EXTRA_CA_CERTS;
513
+ if (trusted || !certificate || !existsSync(certificate)) return;
514
+ trusted = true;
515
+ tls.setDefaultCACertificates([...tls.getCACertificates("default"), readFileSync(certificate, "utf-8")]);
516
+ }
517
+ /** A feature test ran without a manifest to build itself from. */
518
+ var NoTestManifest = class extends Error {
519
+ constructor() {
520
+ 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}.`);
521
+ this.name = "NoTestManifest";
522
+ }
523
+ };
524
+ //#endregion
525
+ //#region src/testing/featureTest.ts
526
+ /**
527
+ * `featureTest`: an app, driven the way it runs deployed.
528
+ *
529
+ * A browser signs in and calls the API; the API calls the auth server; each
530
+ * over its URL, each database in its own transaction. Nothing runs as a server:
531
+ * every URL an app's constructs answer on is served in-process through MSW,
532
+ * from the real handler, for the test that made the request. Everything else
533
+ * with a real local equivalent — Postgres, Mailpit, MinIO — is used directly.
534
+ *
535
+ * It is built from the test manifest `gkm test` writes — the constructs and
536
+ * endpoints the app exports, and the environment the test stage resolved — so
537
+ * a test declares none of it. `gkm test` also generates the configured `it`
538
+ * and a `Browser` with a typed client per surface:
539
+ *
540
+ * ```ts
541
+ * import { it } from '#test';
542
+ *
543
+ * it('shows the signed-in user their profile', async ({ browser, mailbox }) => {
544
+ * await browser.auth.signIn.magicLink({ email: 'ada@shop.test' });
545
+ * await browser.visit((await mailbox('ada@shop.test').last()).link!);
546
+ * expect(await browser.api.get('/profile')).toMatchObject({ email: 'ada@shop.test' });
547
+ * });
548
+ * ```
549
+ */
550
+ /** Every test in flight in this process, by id. */
551
+ const contexts = /* @__PURE__ */ new Map();
552
+ /** Databases already resolving to test transactions — patched once each. */
553
+ const bound = /* @__PURE__ */ new WeakSet();
554
+ function featureTest(options = {}) {
555
+ const manifest = options.manifest ?? loadTestManifest();
556
+ const BrowserClass = options.browser ?? Browser;
557
+ let app;
558
+ let factoryDatabases = [];
559
+ let owned = [];
560
+ let network;
561
+ let restoreFetch = () => {};
562
+ beforeAll(async () => {
563
+ app = await load(manifest, options.modules ?? {});
564
+ owned = ownDatabases(app, manifest);
565
+ factoryDatabases = databasesFor(options.factories ?? {}, owned);
566
+ for (const database of app.databases) bindToTests(database);
567
+ 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)));
568
+ network.listen({ onUnhandledRequest(request, print) {
569
+ if (isLocal(new URL(request.url))) return;
570
+ print.error();
571
+ } });
572
+ const restoreStamp = installContextFetch();
573
+ const stamped = globalThis.fetch;
574
+ globalThis.fetch = deliveringFetch(stamped, (id) => {
575
+ const state = contexts.get(id);
576
+ return state ? deliver(app, state, id) : Promise.resolve();
577
+ });
578
+ restoreFetch = () => {
579
+ globalThis.fetch = stamped;
580
+ restoreStamp();
581
+ };
582
+ });
583
+ afterAll(() => {
584
+ restoreFetch();
585
+ network?.close();
586
+ });
587
+ const run = (name, fn) => async () => {
588
+ const id = randomUUID();
589
+ faker.seed(seedOf(name));
590
+ const state = {
591
+ transactions: new TransactionRegistry(),
592
+ discovery: new ServiceDiscovery(app.envParser),
593
+ surfaces: /* @__PURE__ */ new Map(),
594
+ auth: /* @__PURE__ */ new Map(),
595
+ addresses: /* @__PURE__ */ new Set(),
596
+ published: /* @__PURE__ */ new Map(),
597
+ pending: [],
598
+ delivering: false
599
+ };
600
+ const readMail = app.readMail;
601
+ if (readMail) state.mailbox = (address) => {
602
+ state.addresses.add(address);
603
+ return readMail(address);
604
+ };
605
+ contexts.set(id, state);
606
+ await state.discovery.register(recorders(app.channels, state));
607
+ try {
608
+ await runInTestContext(id, async () => {
609
+ const browser = new BrowserClass();
610
+ const restore = browser.install();
611
+ try {
612
+ const transaction = (database) => state.transactions.get(database.id, urlOf(database, app.envParser), database.clientConfig);
613
+ const db = { get: (name) => {
614
+ const database = owned.find((candidate) => candidate.service.serviceName === name);
615
+ if (!database) throw new UnknownDatabase(name, owned.map((candidate) => candidate.service.serviceName));
616
+ return transaction(database);
617
+ } };
618
+ const built = /* @__PURE__ */ new Map();
619
+ await fn({
620
+ browser,
621
+ db,
622
+ factories: { get: (name) => {
623
+ const database = factoryDatabases.find(([candidate]) => candidate === name)?.[1];
624
+ if (!database) throw new UnknownFactory(name, factoryDatabases.map(([candidate]) => candidate));
625
+ let factory = built.get(name);
626
+ if (!factory) {
627
+ factory = transaction(database).then(options.factories[name]);
628
+ built.set(name, factory);
629
+ }
630
+ return factory;
631
+ } },
632
+ faker,
633
+ mailbox: (address) => {
634
+ if (!state.mailbox) throw new NoInbox();
635
+ return state.mailbox(address);
636
+ },
637
+ published: (channel) => [...state.published.get(channel.id) ?? []],
638
+ services: { get: (name) => resolveService(app, state, name) },
639
+ subscriber: (subscriber) => thenDeliver(new TestSubscriberAdaptor(subscriber, state.discovery), () => deliver(app, state, id)),
640
+ queue: (queue) => thenDeliver(new TestQueueAdaptor(queue, state.discovery), () => deliver(app, state, id))
641
+ });
642
+ } finally {
643
+ restore();
644
+ }
645
+ });
646
+ } finally {
647
+ contexts.delete(id);
648
+ await Promise.all([state.transactions.rollbackAll(), ...[...state.addresses].map((address) => app.readMail?.(address).clear())]);
649
+ }
650
+ };
651
+ const it = ((name, fn, timeout) => test(name, run(name, fn), timeout));
652
+ it.only = (name, fn, timeout) => test.only(name, run(name, fn), timeout);
653
+ it.skip = (name, fn, timeout) => test.skip(name, run(name, fn), timeout);
654
+ return it;
655
+ }
656
+ /**
657
+ * A test's faker seed, from its name: the same test draws the same data on
658
+ * every run, and two tests draw different data.
659
+ */
660
+ function seedOf(name) {
661
+ let hash = 0;
662
+ for (const char of name) hash = Math.imul(hash, 31) + char.charCodeAt(0) | 0;
663
+ return hash >>> 0;
664
+ }
665
+ /**
666
+ * Import what the manifest points at.
667
+ *
668
+ * The same modules the app runs, so a construct here *is* the app's construct —
669
+ * the one its endpoints were built from — never a copy declared again.
670
+ */
671
+ async function load(manifest, modules) {
672
+ const envParser = new EnvironmentParser({ ...manifest.env });
673
+ const imported = async ({ file, export: name }) => (modules[file] ?? await import(file))[name];
674
+ const constructs = await Promise.all(Object.values(manifest.constructs).map(({ source }) => imported(source)));
675
+ const endpoints = (await Promise.all(manifest.endpoints.map(({ source }) => imported(source)))).filter((value) => Endpoint.isEndpoint(value));
676
+ const subscribers = (await Promise.all((manifest.subscribers ?? []).map(async ({ source }) => ({
677
+ name: source.export,
678
+ subscriber: await imported(source)
679
+ })))).filter((entry) => entry.subscriber?.__IS_SUBSCRIBER__ === true);
680
+ const unique = (values) => [...new Set(values)];
681
+ const databases = unique(constructs.filter((value) => value instanceof KyselyDatabase));
682
+ const auths = unique(constructs.filter((value) => value instanceof BetterAuth));
683
+ const emails = unique(constructs.filter((value) => value instanceof Email));
684
+ const consumables = unique(constructs.filter(isConsumable));
685
+ const channels = unique(constructs.filter((value) => value instanceof Topic || value instanceof Queue));
686
+ const inbox = emails.map((email) => manifest.env[provideKey(email.id, "inboxUrl")]).find(Boolean);
687
+ return {
688
+ envParser,
689
+ endpoints,
690
+ databases,
691
+ auths,
692
+ emails,
693
+ channels,
694
+ consumables,
695
+ subscribers,
696
+ ...inbox ? { readMail: createMailbox({ inbox }) } : {}
697
+ };
698
+ }
699
+ /**
700
+ * A publisher that records rather than sends, under the name a topic or queue
701
+ * is injected by — `services.users` — which is also the one `.event(users, …)`
702
+ * publishes through.
703
+ */
704
+ function recorders(channels, state) {
705
+ return channels.map((channel) => {
706
+ const publisher = { async publish(messages) {
707
+ const sent = messages.map(({ type, payload }) => ({
708
+ type,
709
+ payload
710
+ }));
711
+ state.published.set(channel.id, [...state.published.get(channel.id) ?? [], ...sent]);
712
+ state.pending.push({
713
+ channel,
714
+ messages: sent
715
+ });
716
+ } };
717
+ return {
718
+ serviceName: channel.service.serviceName,
719
+ register: () => publisher
720
+ };
721
+ });
722
+ }
723
+ /**
724
+ * The databases a test is handed: the app's own. A schema tenant an auth server
725
+ * owns is reached through that server, as the app reaches it, and a reader is
726
+ * the same database through a read-only role — neither is another database to
727
+ * test against.
728
+ */
729
+ function ownDatabases(app, manifest) {
730
+ const owners = new Set(app.auths.map((auth) => auth.databaseId));
731
+ return app.databases.filter((database) => !owners.has(database.id) && manifest.constructs[database.id]?.kind !== "database-reader");
732
+ }
733
+ /** Each factory's database, found by the service name it is keyed by. */
734
+ function databasesFor(factories, databases) {
735
+ return Object.keys(factories).map((name) => {
736
+ const database = databases.find((candidate) => candidate.service.serviceName === name);
737
+ if (!database) throw new UnknownFactory(name, databases.map((candidate) => candidate.service.serviceName));
738
+ return [name, database];
739
+ });
740
+ }
741
+ /**
742
+ * Make a database resolve, inside a test, to that test's transaction.
743
+ *
744
+ * Everything reaches a database through its service — an endpoint through
745
+ * service discovery, the auth server through its tenant directly — so this is
746
+ * the one place a test's connection can be handed over. Outside a test it is
747
+ * the database it always was.
748
+ */
749
+ /** Rounds of delivery before a chain of consumers is called a loop. */
750
+ const MAX_DELIVERY_ROUNDS = 25;
751
+ /**
752
+ * Deliver what this test published, in-process, as the broker would — and
753
+ * keep delivering what the consumers publish in turn, until nothing is left.
754
+ *
755
+ * - A queue's messages go to its one consumer, as a batch.
756
+ * - A topic's events go to every subscriber that named their type, and only
757
+ * those: fan-out, as the filter policy (SNS) or the per-subscriber queue
758
+ * (pg-boss) does it.
759
+ * - Each payload is checked against the consumer's schema first. Turning an
760
+ * SNS envelope or an SQS record into `{ type, payload }` is each adaptor's
761
+ * job and tested there; what is tested here is what the handler is handed.
762
+ * - Consumers run as the server side of this test, so their databases are
763
+ * this test's transactions and their writes roll back with it.
764
+ * - A consumer that throws fails the test. Deployed, the message would be
765
+ * retried; here a retry would only hide the bug.
766
+ */
767
+ async function deliver(app, state, id) {
768
+ if (state.delivering) return;
769
+ state.delivering = true;
770
+ try {
771
+ for (let round = 0; state.pending.length > 0; round++) {
772
+ if (round === MAX_DELIVERY_ROUNDS) throw new DeliveryDidNotSettle(MAX_DELIVERY_ROUNDS, [...new Set(state.pending.map(({ channel }) => channel.id))]);
773
+ for (const { channel, messages } of state.pending.splice(0)) if (channel instanceof Queue) await toQueue(channel, messages, state, id);
774
+ else await toSubscribers(channel, messages, app, state, id);
775
+ }
776
+ } finally {
777
+ state.delivering = false;
778
+ }
779
+ }
780
+ async function toQueue(queue, messages, state, id) {
781
+ const payloads = [];
782
+ for (const message of messages) payloads.push(await accepted(queue.messageSchema, message, `queue '${queue.name}'`));
783
+ await runAsServer(id, () => new TestQueueAdaptor(queue, state.discovery).invoke({ messages: payloads })).catch((error) => {
784
+ throw new DeliveryFailed(`queue '${queue.name}'`, messages, error);
785
+ });
786
+ }
787
+ async function toSubscribers(topic, messages, app, state, id) {
788
+ for (const { name, subscriber } of app.subscribers) {
789
+ if (subscriber.topicName !== topic.name) continue;
790
+ const named = messages.filter(({ type }) => (subscriber.subscribedEvents ?? []).includes(type));
791
+ if (named.length === 0) continue;
792
+ const consumer = `subscriber '${name}'`;
793
+ const events = [];
794
+ for (const message of named) {
795
+ const schema = topic.eventSchemas[message.type];
796
+ events.push({
797
+ type: message.type,
798
+ payload: await accepted(schema, message, consumer)
799
+ });
800
+ }
801
+ await runAsServer(id, () => new TestSubscriberAdaptor(subscriber, state.discovery).invoke({ events })).catch((error) => {
802
+ throw new DeliveryFailed(consumer, named, error);
803
+ });
804
+ }
805
+ }
806
+ /** The payload, if the consumer's schema takes it — what the handler is handed. */
807
+ async function accepted(schema, message, consumer) {
808
+ const standard = schema?.["~standard"];
809
+ if (!standard) return message.payload;
810
+ const result = await standard.validate(message.payload);
811
+ if (result.issues) throw new MessageRejected(consumer, message, result.issues);
812
+ return result.value;
813
+ }
814
+ /** `fetch`, delivering what the test published once each of its requests answers. */
815
+ function deliveringFetch(inner, settle) {
816
+ return async (input, init) => {
817
+ const context = currentTestContext();
818
+ const response = await inner(input, init);
819
+ if (context?.side === "client") await settle(context.id);
820
+ return response;
821
+ };
822
+ }
823
+ /** An adaptor whose `invoke` delivers what it published before returning. */
824
+ function thenDeliver(adaptor, settle) {
825
+ const invoke = adaptor.invoke.bind(adaptor);
826
+ adaptor.invoke = (async (...args) => {
827
+ const result = await invoke(...args);
828
+ await settle();
829
+ return result;
830
+ });
831
+ return adaptor;
832
+ }
833
+ function bindToTests(database) {
834
+ if (bound.has(database)) return;
835
+ bound.add(database);
836
+ const service = database.service;
837
+ const register = service.register;
838
+ service.register = (options) => {
839
+ const context = currentTestContext();
840
+ const state = context && contexts.get(context.id);
841
+ if (!state) return register(options);
842
+ return state.transactions.get(database.id, urlOf(database, options.envParser), database.clientConfig);
843
+ };
844
+ }
845
+ function urlOf(database, envParser) {
846
+ return envParser.create((get) => ({ url: get(provideKey(database.id, "url")).string() })).parse().url;
847
+ }
848
+ /** Each surface's endpoints, served at its URL for the test that asked. */
849
+ function surfaceHandlers(endpoints, env) {
850
+ const bySurface = /* @__PURE__ */ new Map();
851
+ for (const endpoint of endpoints) {
852
+ const surface = endpoint.surface?.id;
853
+ if (!surface) continue;
854
+ bySurface.set(surface, [...bySurface.get(surface) ?? [], endpoint]);
855
+ }
856
+ return [...bySurface].flatMap(([surface, served]) => {
857
+ const base = env[provideKey(surface, "url")];
858
+ if (!base) return [];
859
+ return http.all(`${trim(base)}/*`, ({ request }) => serve(request, async (state) => {
860
+ let app = state.surfaces.get(surface);
861
+ if (!app) {
862
+ app = Promise.resolve().then(() => {
863
+ const hono = new Hono();
864
+ HonoEndpoint.addRoutes(served, state.discovery, hono);
865
+ return hono;
866
+ });
867
+ state.surfaces.set(surface, app);
868
+ }
869
+ return (await app).fetch(request, inProcessBindings());
870
+ }));
871
+ });
872
+ }
873
+ /**
874
+ * An external API's app fake, answering at the URL the test stage resolved for
875
+ * it — so a handler that calls Polar calls the fake, and the test sets up
876
+ * nothing.
877
+ *
878
+ * Not per test, unlike a surface: a fake stands in for somebody else's server,
879
+ * which no test's transaction reaches. An image fake has no handler here — its
880
+ * container answers on localhost, which is let through.
881
+ */
882
+ function fakeHandler(id, fake, env) {
883
+ const base = env[provideKey(id, "url")];
884
+ if (fake.kind !== "app" || !base) return [];
885
+ return [http.all(`${trim(base)}/*`, ({ request }) => fake.handler.fetch(request))];
886
+ }
887
+ /**
888
+ * A construct's client for this test, by service name — through the test's own
889
+ * discovery, so a topic or queue is its recorder and a database its
890
+ * transaction, exactly as the test's endpoints get them.
891
+ */
892
+ async function resolveService(app, state, name) {
893
+ const construct = app.consumables.find((candidate) => candidate.service.serviceName === name);
894
+ if (!construct) throw new UnknownService(name, app.consumables.map((candidate) => candidate.service.serviceName));
895
+ return (await state.discovery.register([construct.service]))[name];
896
+ }
897
+ /** An auth server, served at its URL, on the transaction of the test that asked. */
898
+ function authHandler(auth, env, envParser) {
899
+ const base = trim(env[provideKey(auth.id, "url")] ?? "");
900
+ return http.all(`${base}/*`, ({ request }) => serve(request, async (state) => {
901
+ let app = state.auth.get(auth);
902
+ if (!app) {
903
+ app = auth.server({
904
+ envParser,
905
+ context: serviceContext
906
+ }).then(({ app }) => app);
907
+ state.auth.set(auth, app);
908
+ }
909
+ return (await app).fetch(request, inProcessBindings());
910
+ }));
911
+ }
912
+ /** Handle a request as the server side of the test it was made for. */
913
+ async function serve(request, handle) {
914
+ const id = testContextOf(request);
915
+ const state = id ? contexts.get(id) : void 0;
916
+ if (!id || !state) throw new UnknownTestContext(request.url, id);
917
+ return runAsServer(id, () => handle(state));
918
+ }
919
+ function trim(url) {
920
+ return url.replace(/\/$/, "");
921
+ }
922
+ function isLocal(url) {
923
+ return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname.endsWith(".localhost");
924
+ }
925
+ /**
926
+ * Sign a test's browser in the way a person does: ask the auth server for a
927
+ * magic link, open the email it sent, follow the link.
928
+ *
929
+ * What the generated `browser.signIn(email)` calls. The address's mail is
930
+ * cleared first — so the link is this request's, not one an earlier test left
931
+ * — and cleared again after the test, like any address a test reads. Returns
932
+ * the session the auth server then reports, as better-auth hands it back.
933
+ */
934
+ async function signInWithMagicLink(browser, auth, email = freshAddress()) {
935
+ const context = currentTestContext();
936
+ const state = context && contexts.get(context.id);
937
+ if (!state) throw new UnknownTestContext("signIn", context?.id);
938
+ if (!state.mailbox) throw new NoInbox();
939
+ const inbox = state.mailbox(email);
940
+ await inbox.clear();
941
+ const requested = await auth.signIn.magicLink({ email });
942
+ if (requested.error) throw new SignInFailed(email, `the auth server refused the magic link: ${requested.error.message ?? "no reason given"}`);
943
+ const mail = await inbox.last();
944
+ if (!mail.link) throw new SignInFailed(email, "its email held no link");
945
+ await browser.visit(mail.link);
946
+ const { data } = await auth.getSession();
947
+ if (!data) throw new SignInFailed(email, "the auth server reported no session after the link was opened");
948
+ return data;
949
+ }
950
+ /**
951
+ * An address nobody else signs in as — what `browser.signIn()` uses when the
952
+ * test does not care who it is.
953
+ *
954
+ * Unique rather than only seeded: tests in other files run at the same time,
955
+ * against the same Mailpit and the same unique columns, and a seeded address
956
+ * repeats wherever two tests share a name. The readable half is the seeded
957
+ * faker's, so a failure still names somebody.
958
+ */
959
+ function freshAddress() {
960
+ return `${faker.internet.username().toLowerCase().replace(/[^a-z0-9]/g, "")}.${randomUUID().slice(0, 8)}@example.test`;
961
+ }
962
+ /** `browser.signIn` finished without a session. */
963
+ var SignInFailed = class extends Error {
964
+ email;
965
+ reason;
966
+ constructor(email, reason) {
967
+ super(`Signing ${email} in failed: ${reason}.`);
968
+ this.email = email;
969
+ this.reason = reason;
970
+ this.name = "SignInFailed";
971
+ }
972
+ };
973
+ /** A request reached an in-process server without a test to belong to. */
974
+ var UnknownTestContext = class extends Error {
975
+ url;
976
+ id;
977
+ constructor(url, id) {
978
+ 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.`);
979
+ this.url = url;
980
+ this.id = id;
981
+ this.name = "UnknownTestContext";
982
+ }
983
+ };
984
+ /** `mailbox` was used in an app that declares no Email construct. */
985
+ var NoInbox = class extends Error {
986
+ constructor() {
987
+ 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.");
988
+ this.name = "NoInbox";
989
+ }
990
+ };
991
+ /** `db.get(name)` named no database the test is handed. */
992
+ var UnknownDatabase = class extends Error {
993
+ database;
994
+ known;
995
+ constructor(database, known) {
996
+ 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.");
997
+ this.database = database;
998
+ this.known = known;
999
+ this.name = "UnknownDatabase";
1000
+ }
1001
+ };
1002
+ /** A factory keyed by a service name no database the app declares has. */
1003
+ var UnknownFactory = class extends Error {
1004
+ factory;
1005
+ known;
1006
+ constructor(factory, known) {
1007
+ 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.`);
1008
+ this.factory = factory;
1009
+ this.known = known;
1010
+ this.name = "UnknownFactory";
1011
+ }
1012
+ };
1013
+ /** A published message the consumer's own schema refuses. */
1014
+ var MessageRejected = class extends Error {
1015
+ consumer;
1016
+ published;
1017
+ issues;
1018
+ constructor(consumer, published, issues) {
1019
+ super(`${consumer} refuses '${published.type}': ${issues.map((issue) => issue.message).join("; ")}. What is published must be what the consumer's schema takes — fix the producer, or the schema.`);
1020
+ this.consumer = consumer;
1021
+ this.published = published;
1022
+ this.issues = issues;
1023
+ this.name = "MessageRejected";
1024
+ }
1025
+ };
1026
+ /** A consumer that threw while handling what the test published. */
1027
+ var DeliveryFailed = class extends Error {
1028
+ consumer;
1029
+ messages;
1030
+ cause;
1031
+ constructor(consumer, messages, cause) {
1032
+ super(`${consumer} failed handling ${messages.map(({ type }) => `'${type}'`).join(", ")}: ${cause?.message ?? String(cause)}. Deployed, the message would be retried; here the failure is the result.`, { cause });
1033
+ this.consumer = consumer;
1034
+ this.messages = messages;
1035
+ this.cause = cause;
1036
+ this.name = "DeliveryFailed";
1037
+ }
1038
+ };
1039
+ /** Consumers that kept publishing to each other without settling. */
1040
+ var DeliveryDidNotSettle = class extends Error {
1041
+ rounds;
1042
+ channels;
1043
+ constructor(rounds, channels) {
1044
+ super(`Delivery did not settle after ${rounds} rounds — consumers are still publishing to ${channels.join(", ")}. A consumer that publishes to what triggers it loops forever deployed too.`);
1045
+ this.rounds = rounds;
1046
+ this.channels = channels;
1047
+ this.name = "DeliveryDidNotSettle";
1048
+ }
1049
+ };
1050
+ /** `services.get(name)` for a name no construct of the app is served by. */
1051
+ var UnknownService = class extends Error {
1052
+ serviceName;
1053
+ available;
1054
+ constructor(serviceName, available) {
1055
+ super(`The app declares no construct served as '${serviceName}'. Its services are: ${available.join(", ") || "none"}.`);
1056
+ this.serviceName = serviceName;
1057
+ this.available = available;
1058
+ this.name = "UnknownService";
1059
+ }
1060
+ };
1061
+ //#endregion
1062
+ export { DeliveryDidNotSettle, DeliveryFailed, IN_PROCESS_PEER_ADDRESS, MessageRejected, NoInbox, NoTestManifest, SignInFailed, TEST_CONTEXT_HEADER, TEST_MANIFEST_ENV, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, UnknownDatabase, UnknownFactory, UnknownService, UnknownTestContext, createMswHandlers, featureTest, inProcessBindings, loadTestManifest, signInWithMagicLink };
1063
+
429
1064
  //# sourceMappingURL=testing.mjs.map