@geekmidas/constructs 10.0.0-alpha.37 → 10.0.0-alpha.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +156 -155
  2. package/dist/{Construct-Detz65RA.mjs → Construct-BO1X-kt9.mjs} +3 -6
  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-yG9Sw-5p.cjs → Construct-DmvXceVY.cjs} +3 -6
  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-CA2oa2nC.d.cts → Cron-CMEGfRs8.d.cts} +7 -5
  11. package/dist/Cron-CMEGfRs8.d.cts.map +1 -0
  12. package/dist/{Cron-B_iuyNxr.d.mts → Cron-D6X4-xjB.d.mts} +7 -5
  13. package/dist/Cron-D6X4-xjB.d.mts.map +1 -0
  14. package/dist/{CronBuilder-B_KqaodP.d.cts → CronBuilder-CEK7aOqD.d.cts} +21 -16
  15. package/dist/CronBuilder-CEK7aOqD.d.cts.map +1 -0
  16. package/dist/{CronBuilder-BbnT7tqo.cjs → CronBuilder-DB35T5dL.cjs} +13 -11
  17. package/dist/CronBuilder-DB35T5dL.cjs.map +1 -0
  18. package/dist/{CronBuilder-BRkzUOAs.mjs → CronBuilder-Dv0IlZs0.mjs} +14 -12
  19. package/dist/CronBuilder-Dv0IlZs0.mjs.map +1 -0
  20. package/dist/{CronBuilder-BIKCLWu7.d.mts → CronBuilder-O_gvButp.d.mts} +21 -16
  21. package/dist/CronBuilder-O_gvButp.d.mts.map +1 -0
  22. package/dist/{Endpoint-DO332Dnm.mjs → Endpoint-CQAeh1Rh.mjs} +5 -5
  23. package/dist/Endpoint-CQAeh1Rh.mjs.map +1 -0
  24. package/dist/{Endpoint-QKuFg5gs.cjs → Endpoint-D1L9qu5C.cjs} +5 -5
  25. package/dist/Endpoint-D1L9qu5C.cjs.map +1 -0
  26. package/dist/{Endpoint-1-XYQSx0.d.cts → Endpoint-Dp5AKIXl.d.cts} +10 -13
  27. package/dist/Endpoint-Dp5AKIXl.d.cts.map +1 -0
  28. package/dist/{Endpoint-GFIxYb9L.d.mts → Endpoint-DtI7heFm.d.mts} +10 -13
  29. package/dist/Endpoint-DtI7heFm.d.mts.map +1 -0
  30. package/dist/{EndpointFactory-B9HAjDAP.mjs → EndpointFactory-BBdNeaGJ.mjs} +23 -52
  31. package/dist/EndpointFactory-BBdNeaGJ.mjs.map +1 -0
  32. package/dist/{EndpointFactory-BmO0WnXE.cjs → EndpointFactory-BZOCOaK6.cjs} +22 -51
  33. package/dist/EndpointFactory-BZOCOaK6.cjs.map +1 -0
  34. package/dist/{EndpointFactory-BCZdh_u3.d.mts → EndpointFactory-CgMDvERK.d.mts} +58 -48
  35. package/dist/EndpointFactory-CgMDvERK.d.mts.map +1 -0
  36. package/dist/{EndpointFactory-BnK_YkW1.d.cts → EndpointFactory-FeFRmlDZ.d.cts} +58 -48
  37. package/dist/EndpointFactory-FeFRmlDZ.d.cts.map +1 -0
  38. package/dist/{HonoEndpointAdaptor-CiqAZ5Mt.mjs → HonoEndpointAdaptor-Aui-x9Lg.mjs} +4 -3
  39. package/dist/HonoEndpointAdaptor-Aui-x9Lg.mjs.map +1 -0
  40. package/dist/{HonoEndpointAdaptor-DoEQdC3r.cjs → HonoEndpointAdaptor-Cq99r9H7.cjs} +5 -4
  41. package/dist/HonoEndpointAdaptor-Cq99r9H7.cjs.map +1 -0
  42. package/dist/{Queue-DpKTLl6E.mjs → Queue-C1uDgjxt.mjs} +29 -48
  43. package/dist/Queue-C1uDgjxt.mjs.map +1 -0
  44. package/dist/{Queue-B7yRXQmL.cjs → Queue-Ckmudcm8.cjs} +29 -48
  45. package/dist/Queue-Ckmudcm8.cjs.map +1 -0
  46. package/dist/{Queue-Bhzi2WQC.d.cts → Queue-CpQIGB_2.d.cts} +22 -33
  47. package/dist/Queue-CpQIGB_2.d.cts.map +1 -0
  48. package/dist/{Queue-BoUA-e83.d.mts → Queue-YmvN2vEP.d.mts} +21 -32
  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-DQCaiOXF.d.cts → Subscriber-B91YSkZt.d.cts} +12 -13
  59. package/dist/Subscriber-B91YSkZt.d.cts.map +1 -0
  60. package/dist/{Subscriber-CIO3pwji.d.mts → Subscriber-BjHYe5hK.d.mts} +11 -12
  61. package/dist/Subscriber-BjHYe5hK.d.mts.map +1 -0
  62. package/dist/{SubscriberBuilder-CjDGSTZc.d.cts → SubscriberBuilder-BSpQX1JT.d.cts} +19 -23
  63. package/dist/SubscriberBuilder-BSpQX1JT.d.cts.map +1 -0
  64. package/dist/{SubscriberBuilder-C2FRfd26.d.mts → SubscriberBuilder-BhMphk4z.d.mts} +18 -22
  65. package/dist/SubscriberBuilder-BhMphk4z.d.mts.map +1 -0
  66. package/dist/{SubscriberBuilder-C2bCOuPT.cjs → SubscriberBuilder-Duk028pD.cjs} +11 -19
  67. package/dist/SubscriberBuilder-Duk028pD.cjs.map +1 -0
  68. package/dist/{SubscriberBuilder-B4YRTBng.mjs → SubscriberBuilder-DzQUWE08.mjs} +11 -19
  69. package/dist/SubscriberBuilder-DzQUWE08.mjs.map +1 -0
  70. package/dist/{Topic-D5rlM9wS.cjs → Topic-BBVXC3H4.cjs} +46 -51
  71. package/dist/Topic-BBVXC3H4.cjs.map +1 -0
  72. package/dist/Topic-DOw051ch.mjs +98 -0
  73. package/dist/Topic-DOw051ch.mjs.map +1 -0
  74. package/dist/adaptors/aws.cjs +5 -5
  75. package/dist/adaptors/aws.cjs.map +1 -1
  76. package/dist/adaptors/aws.d.cts +26 -26
  77. package/dist/adaptors/aws.d.cts.map +1 -1
  78. package/dist/adaptors/aws.d.mts +25 -25
  79. package/dist/adaptors/aws.d.mts.map +1 -1
  80. package/dist/adaptors/aws.mjs +5 -5
  81. package/dist/adaptors/aws.mjs.map +1 -1
  82. package/dist/adaptors/hono.cjs +1 -1
  83. package/dist/adaptors/hono.d.cts +4 -5
  84. package/dist/adaptors/hono.d.cts.map +1 -1
  85. package/dist/adaptors/hono.d.mts +4 -5
  86. package/dist/adaptors/hono.d.mts.map +1 -1
  87. package/dist/adaptors/hono.mjs +1 -1
  88. package/dist/adaptors/testing.cjs +59 -23
  89. package/dist/adaptors/testing.cjs.map +1 -1
  90. package/dist/adaptors/testing.d.cts +40 -28
  91. package/dist/adaptors/testing.d.cts.map +1 -1
  92. package/dist/adaptors/testing.d.mts +40 -28
  93. package/dist/adaptors/testing.d.mts.map +1 -1
  94. package/dist/adaptors/testing.mjs +59 -23
  95. package/dist/adaptors/testing.mjs.map +1 -1
  96. package/dist/{auth-c6nWnvD8.d.cts → auth-CMwml9QN.d.mts} +4 -4
  97. package/dist/{auth-c6nWnvD8.d.cts.map → auth-CMwml9QN.d.mts.map} +1 -1
  98. package/dist/{auth-pS_U1H_X.d.mts → auth-rVRDjIw_.d.cts} +4 -4
  99. package/dist/{auth-pS_U1H_X.d.mts.map → auth-rVRDjIw_.d.cts.map} +1 -1
  100. package/dist/auth.d.cts +1 -1
  101. package/dist/auth.d.mts +1 -1
  102. package/dist/{cache-B2s0b-ss.d.mts → cache-C9a_hVCc.d.cts} +3 -3
  103. package/dist/{cache-B2s0b-ss.d.mts.map → cache-C9a_hVCc.d.cts.map} +1 -1
  104. package/dist/{cache-CYe2Kzjc.d.cts → cache-CeTMI8LR.d.mts} +3 -3
  105. package/dist/{cache-CYe2Kzjc.d.cts.map → cache-CeTMI8LR.d.mts.map} +1 -1
  106. package/dist/cache.d.cts +1 -1
  107. package/dist/cache.d.mts +1 -1
  108. package/dist/{construct-interface-D2gesxos.d.mts → construct-interface-_3zgxzXl.d.mts} +11 -20
  109. package/dist/{construct-interface-D2gesxos.d.mts.map → construct-interface-_3zgxzXl.d.mts.map} +1 -1
  110. package/dist/{construct-interface-DPusCUSQ.d.cts → construct-interface-_xi4BPN8.d.cts} +11 -20
  111. package/dist/{construct-interface-DPusCUSQ.d.cts.map → construct-interface-_xi4BPN8.d.cts.map} +1 -1
  112. package/dist/construct-interface.cjs +4 -33
  113. package/dist/construct-interface.cjs.map +1 -1
  114. package/dist/construct-interface.d.cts +2 -2
  115. package/dist/construct-interface.d.mts +2 -2
  116. package/dist/construct-interface.mjs +5 -32
  117. package/dist/construct-interface.mjs.map +1 -1
  118. package/dist/credential.cjs +22 -9
  119. package/dist/credential.cjs.map +1 -1
  120. package/dist/credential.d.cts +12 -2
  121. package/dist/credential.d.cts.map +1 -1
  122. package/dist/credential.d.mts +12 -2
  123. package/dist/credential.d.mts.map +1 -1
  124. package/dist/credential.mjs +22 -10
  125. package/dist/credential.mjs.map +1 -1
  126. package/dist/crons/index.cjs +1 -1
  127. package/dist/crons/index.d.cts +2 -2
  128. package/dist/crons/index.d.mts +2 -2
  129. package/dist/crons/index.mjs +1 -1
  130. package/dist/database/kysely.d.cts +1 -1
  131. package/dist/database/kysely.d.mts +1 -1
  132. package/dist/email.d.cts +1 -1
  133. package/dist/email.d.mts +1 -1
  134. package/dist/endpoints/index.cjs +5 -4
  135. package/dist/endpoints/index.d.cts +4 -13
  136. package/dist/endpoints/index.d.cts.map +1 -1
  137. package/dist/endpoints/index.d.mts +4 -13
  138. package/dist/endpoints/index.d.mts.map +1 -1
  139. package/dist/endpoints/index.mjs +4 -3
  140. package/dist/external-api-DS3mujT5.d.mts +86 -0
  141. package/dist/external-api-DS3mujT5.d.mts.map +1 -0
  142. package/dist/external-api-LBfE-q3g.d.cts +86 -0
  143. package/dist/external-api-LBfE-q3g.d.cts.map +1 -0
  144. package/dist/external-api.cjs +124 -0
  145. package/dist/external-api.cjs.map +1 -0
  146. package/dist/external-api.d.cts +2 -0
  147. package/dist/external-api.d.mts +2 -0
  148. package/dist/external-api.mjs +121 -0
  149. package/dist/external-api.mjs.map +1 -0
  150. package/dist/file-server.d.cts +1 -1
  151. package/dist/file-server.d.mts +1 -1
  152. package/dist/functions/index.cjs +1 -1
  153. package/dist/functions/index.d.cts +1 -1
  154. package/dist/functions/index.d.mts +1 -1
  155. package/dist/functions/index.mjs +1 -1
  156. package/dist/{functions-DlFm8HmH.mjs → functions-DCIfCRR-.mjs} +94 -23
  157. package/dist/functions-DCIfCRR-.mjs.map +1 -0
  158. package/dist/{functions-DKN6aQWJ.cjs → functions-ZH60FE7H.cjs} +99 -19
  159. package/dist/functions-ZH60FE7H.cjs.map +1 -0
  160. package/dist/{index-BI23K3wy.d.cts → index-B0kxstwf.d.cts} +36 -24
  161. package/dist/index-B0kxstwf.d.cts.map +1 -0
  162. package/dist/{index-yb3fXNyH.d.mts → index-CjVEjOw0.d.mts} +36 -24
  163. package/dist/index-CjVEjOw0.d.mts.map +1 -0
  164. package/dist/index.cjs +1 -1
  165. package/dist/index.d.cts +1 -1
  166. package/dist/index.d.mts +1 -1
  167. package/dist/index.mjs +1 -1
  168. package/dist/{kysely-CEVXacPN.d.cts → kysely-BJ8IQ_1P.d.mts} +4 -4
  169. package/dist/{kysely-CEVXacPN.d.cts.map → kysely-BJ8IQ_1P.d.mts.map} +1 -1
  170. package/dist/{kysely-mcTdPNhl.d.mts → kysely-DVF8wOT4.d.cts} +4 -4
  171. package/dist/{kysely-mcTdPNhl.d.mts.map → kysely-DVF8wOT4.d.cts.map} +1 -1
  172. package/dist/{lazyAccessors-BHtcqgz2.mjs → lazyAccessors-CFanua0O.mjs} +2 -39
  173. package/dist/lazyAccessors-CFanua0O.mjs.map +1 -0
  174. package/dist/{lazyAccessors-Dx9NLwJZ.cjs → lazyAccessors-hJKGv8Ay.cjs} +1 -50
  175. package/dist/lazyAccessors-hJKGv8Ay.cjs.map +1 -0
  176. package/dist/mobile-app.d.cts +1 -1
  177. package/dist/mobile-app.d.mts +1 -1
  178. package/dist/object-storage.d.cts +1 -1
  179. package/dist/object-storage.d.mts +1 -1
  180. package/dist/processAudits-BpRlPQMW.mjs.map +1 -1
  181. package/dist/processAudits-D_2W5x8k.cjs.map +1 -1
  182. package/dist/queue/index.cjs +4 -78
  183. package/dist/queue/index.d.cts +3 -53
  184. package/dist/queue/index.d.mts +3 -53
  185. package/dist/queue/index.mjs +3 -77
  186. package/dist/rest-api.cjs +2 -4
  187. package/dist/rest-api.cjs.map +1 -1
  188. package/dist/rest-api.d.cts +4 -5
  189. package/dist/rest-api.d.cts.map +1 -1
  190. package/dist/rest-api.d.mts +4 -5
  191. package/dist/rest-api.d.mts.map +1 -1
  192. package/dist/rest-api.mjs +2 -4
  193. package/dist/rest-api.mjs.map +1 -1
  194. package/dist/site.d.cts +1 -1
  195. package/dist/site.d.mts +1 -1
  196. package/dist/subscribers/index.cjs +1 -1
  197. package/dist/subscribers/index.d.cts +2 -2
  198. package/dist/subscribers/index.d.mts +2 -2
  199. package/dist/subscribers/index.mjs +1 -1
  200. package/dist/topic/index.cjs +1 -36
  201. package/dist/topic/index.d.cts +2 -3
  202. package/dist/topic/index.d.mts +2 -3
  203. package/dist/topic/index.mjs +2 -35
  204. package/dist/worker.cjs +26 -17
  205. package/dist/worker.cjs.map +1 -1
  206. package/dist/worker.d.cts +37 -29
  207. package/dist/worker.d.cts.map +1 -1
  208. package/dist/worker.d.mts +37 -29
  209. package/dist/worker.d.mts.map +1 -1
  210. package/dist/worker.mjs +26 -17
  211. package/dist/worker.mjs.map +1 -1
  212. package/package.json +41 -31
  213. package/dist/Construct-DTqYvkPG.d.cts +0 -115
  214. package/dist/Construct-DTqYvkPG.d.cts.map +0 -1
  215. package/dist/Construct-Detz65RA.mjs.map +0 -1
  216. package/dist/Construct-pVadmURD.d.mts +0 -115
  217. package/dist/Construct-pVadmURD.d.mts.map +0 -1
  218. package/dist/Construct-yG9Sw-5p.cjs.map +0 -1
  219. package/dist/Cron-B_iuyNxr.d.mts.map +0 -1
  220. package/dist/Cron-CA2oa2nC.d.cts.map +0 -1
  221. package/dist/CronBuilder-BIKCLWu7.d.mts.map +0 -1
  222. package/dist/CronBuilder-BRkzUOAs.mjs.map +0 -1
  223. package/dist/CronBuilder-B_KqaodP.d.cts.map +0 -1
  224. package/dist/CronBuilder-BbnT7tqo.cjs.map +0 -1
  225. package/dist/Endpoint-1-XYQSx0.d.cts.map +0 -1
  226. package/dist/Endpoint-DO332Dnm.mjs.map +0 -1
  227. package/dist/Endpoint-GFIxYb9L.d.mts.map +0 -1
  228. package/dist/Endpoint-QKuFg5gs.cjs.map +0 -1
  229. package/dist/EndpointFactory-B9HAjDAP.mjs.map +0 -1
  230. package/dist/EndpointFactory-BCZdh_u3.d.mts.map +0 -1
  231. package/dist/EndpointFactory-BmO0WnXE.cjs.map +0 -1
  232. package/dist/EndpointFactory-BnK_YkW1.d.cts.map +0 -1
  233. package/dist/HonoEndpointAdaptor-CiqAZ5Mt.mjs.map +0 -1
  234. package/dist/HonoEndpointAdaptor-DoEQdC3r.cjs.map +0 -1
  235. package/dist/Queue-B7yRXQmL.cjs.map +0 -1
  236. package/dist/Queue-Bhzi2WQC.d.cts.map +0 -1
  237. package/dist/Queue-BoUA-e83.d.mts.map +0 -1
  238. package/dist/Queue-DpKTLl6E.mjs.map +0 -1
  239. package/dist/Subscriber-CIO3pwji.d.mts.map +0 -1
  240. package/dist/Subscriber-DQCaiOXF.d.cts.map +0 -1
  241. package/dist/SubscriberBuilder-B4YRTBng.mjs.map +0 -1
  242. package/dist/SubscriberBuilder-C2FRfd26.d.mts.map +0 -1
  243. package/dist/SubscriberBuilder-C2bCOuPT.cjs.map +0 -1
  244. package/dist/SubscriberBuilder-CjDGSTZc.d.cts.map +0 -1
  245. package/dist/Topic-Ct3Le8Wt.mjs +0 -103
  246. package/dist/Topic-Ct3Le8Wt.mjs.map +0 -1
  247. package/dist/Topic-D5rlM9wS.cjs.map +0 -1
  248. package/dist/Topic-D6blllEn.d.cts +0 -89
  249. package/dist/Topic-D6blllEn.d.cts.map +0 -1
  250. package/dist/Topic-DVvheJ_-.d.mts +0 -89
  251. package/dist/Topic-DVvheJ_-.d.mts.map +0 -1
  252. package/dist/functions-DKN6aQWJ.cjs.map +0 -1
  253. package/dist/functions-DlFm8HmH.mjs.map +0 -1
  254. package/dist/index-BI23K3wy.d.cts.map +0 -1
  255. package/dist/index-fnpjXiA-.d.mts +0 -26
  256. package/dist/index-fnpjXiA-.d.mts.map +0 -1
  257. package/dist/index-tE_119SX.d.cts +0 -26
  258. package/dist/index-tE_119SX.d.cts.map +0 -1
  259. package/dist/index-yb3fXNyH.d.mts.map +0 -1
  260. package/dist/lazyAccessors-BHtcqgz2.mjs.map +0 -1
  261. package/dist/lazyAccessors-Dx9NLwJZ.cjs.map +0 -1
  262. package/dist/queue/index.cjs.map +0 -1
  263. package/dist/queue/index.d.cts.map +0 -1
  264. package/dist/queue/index.d.mts.map +0 -1
  265. package/dist/queue/index.mjs.map +0 -1
  266. package/dist/topic/index.cjs.map +0 -1
  267. package/dist/topic/index.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EndpointFactory-FeFRmlDZ.d.cts","names":[],"sources":["../src/endpoints/EndpointBuilder.ts","../src/endpoints/EndpointFactory.ts"],"mappings":";;;;;;;;;;;;cAyCa,gBACZ,uBACA,gBAAgB,YAChB,eAAe,sBACf,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,kBAAkB,0CAClB,oBACA,4DACA,sBAAsB,sCACtB,kDACA,qBAAqB,mCAAmC,kCAIxD,uBACA,sDACS,oBACT,QACA,WACA,WACA,SACA,eACA,0BACA,WACA;WA6BU,OAAO;WACP,QAAQ;YA5BR,SAAS;YACT;YACA,UAAU;YACV;YACA;YACA;EACV,aAAa,UAAU,WAAW,SAAS,UAAU;EAErD,YAAY,YAAY,WAAW,SAAS,UAAU,QAAQ;EAE9D,aAAa;EACb,uBAAuB;EACvB,kBAAkB;EAClB,kBAAkB,eAAe,WAAW,UAAU;EACtD,SAAS,YAAY,cAAc;;;;;;;EAOnC,UAAW;EACX,wBAAwB,eAAe;EACvC,aAAa,UAAU,WAAW,UAAU;EAC5C;EAEA,YACU,OAAO,QACP,QAAQ;EAMlB,mBACC,SAAS,QAAQ,0BAA0B;EAM5C,oBAAoB,SAAS,QAAQ,sBAAsB;EAI3D,YAAY;EAIZ,OAAO,QAAQ;;;;;;;;;;;;;;;;EAmBf,MAAM,eAAe,iBACpB,OAAO,QACP,OAAO,SAAS,QAAQ,oBAAoB,cAC1C,gBACF,QACA,SACA,YACI,WAAW,oBACf,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAmBD,KAAK;EAIL,WAAW;;;;;;;;;;;;;;;;;;;EAsBX,aAAa;EAIb,KAAK,UAAU,kBACd,QAAQ,IACN,gBACF,QACA,SACA,KAAK;IAAoB,MAAM;KAC/B,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAOD,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,SACA,KAAK;IAAqB,OAAO;KACjC,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAOD,MAAM,UAAU,kBACf,QAAQ,IACN,gBACF,QACA,SACA,KAAK;IAAqB,OAAO;KACjC,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAKD,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,SACA,KAAK;IAAsB,QAAQ;KACnC,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAOD,UACC,IAAI,YAAY,WAAW,SAAS,UAAU,QAAQ;EAKvD,UAAU,QAAQ;EAIlB,WACC,MAAM,gCACJ,gBACF,QACA,SACA,QACA,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;;;;;;;;;;;;EAkCD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,gBACF,QACA,SACA,YACI,cAAc,WAAW,KAC7B,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAkCD,SAAS,UAAU,WAClB,UAAU,IACR,gBACF,QACA,SACA,YACI,cAAc,IAClB,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAwBD,OAAO,UAAU,QAChB,QAAQ,IACN,gBACF,QACA,SACA,QACA,WACA,GACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;EAqBD,OAAO,UAAU,kBAChB,QAAQ,IACN,gBACF,QACA,SACA,QACA,WACA,SACA,GACA,UACA,cACA,eACA,0BACA,cACA,WACA;;;;;;EA0BQ,QAAQ,UAAU,mBAAmB,sBAC7C,SAAS,QAAQ,OAAO,KACtB,gBACF,QACA,SACA,QACA,WACA,SACA,WACA,UACA,cACA,GACA,OACA,0BAA0B,IAC1B,WACA;;;;;EA4BD,MACC,WAAW,eAAe,WAAW,UAAU,WAC7C,gBACF,QACA,SACA,QACA,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,WACA;;;;;;;;;;;;;;;;;;EAsBD,MAAM,QAAQ,YAAY,cAAc;;;;;;;;;;;;;;;;EAmB/B,SAAS,GAAG,sBACpB,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,KAC5C,gBACF,QACA,SACA,QACA,WACA,SACA,WACA,UACA,cACA,eACA,0BACA,cACA,GACA;;;;;;;;;;;;;;;;;;;;EA6CD,IACC,QAAQ,UAAU,WAAW,UAAU,mBAAmB;;;;;;;;;;;;;;EAyB3D;EAKA,MAAM;EAMN,OACC,IAAI,gBACH,QACA,WACA,SACA,WACA,UACA,WACA,eACA,gBAEC,SACF,QACA,SACA,QACA,WACA,WACA,SACA,UACA,eACA,0BACA,cACA,WACA;;;;cC1rBW,gBACZ,kBAAkB,gBAClB,+BACA,gBAAgB,SAAS,QACzB,oBACA,4DACA,sBAAsB,2CACtB,kDACA,qBAAqB,mCAGjB,0BAA0B,YAAY,iBAC1C,uBACA,8CACA,yBAAyB,eAAe,kBAAkB,eAEzD,iBAED,mBACG,UAAU,WAAW,UAAU;UAG1B;;;;;;;;;;;UAWA;UACA;UACA;UAOA;UAMA;;;;;;;;UAQA;UACA;UACA;UACA;UAGA;UAGA;UACA;UACA;EAER,cACC,UACA,oBACA,eACA,yBAEA,iBACA,mBACA,sBACA,uBACA,uBACA,wBACA,uBACA,uBACA,kBACA,WACE,uBACF,WACA,WACA,SACA,UACA,cACA,eACA,0BACA,WACA,sBACA,kBACA;SAuBM,UAAU,0BAA0B,kBAC1C,MAAM,GACN,WAAU,YACR,UAAU,WAAW;EAmCxB,kBAAkB,6BACjB,aAAa,IACX,gBACF,WACA,WACA,SACA,UACA,GACA,eACA,0BACA,cACA,WACA,sBACA,kBACA;;;;;;;;;;;;;;;;;EAqDD,gBAAgB,UAAU,eAAe,iBACxC,SAAS,IACP,gBACF,WACA,WACA,SACA,UACA,cACA,eACA,0BACA,cACA,WACA,sBACA,mBAAmB,GACnB;;;;;;;;;;;EA8CD,WACC,MACG,gCACM,mBACN,gCAED,gBACF,WACA,WACA,SACA,UACA,cACA,eACA,0BACA,cACA,WACA,sBACA,kBACA;EAkDD,MAAM,sBACL,MAAM,QACJ,gBACF,WACA,UAAU,WAAW,QACrB,SACA,UACA,cACA,eACA,0BACA,cACA,WACA,sBACA,kBACA;EAmCD,UACC,IAAI,YAAY,WAAW,SAAS,qBAAqB,aACvD,gBACF,WACA,WACA,SACA,UACA,cACA,eACA,0BACA,cACA,WACA,sBACA,kBACA;;;;;;;;;;;;EA6CD,gBAAgB,mBAAmB,cAClC,YAAY,IACV,oBACE,WAAW,OAAO,YACtB,WACA,SACA,UACA,cACA,eACA,0BACA,cACA,WACA,sBACA,kBAC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"}
@@ -1,5 +1,6 @@
1
- import { n as ResponseBuilder, t as Endpoint } from "./Endpoint-DO332Dnm.mjs";
2
- import { a as createHonoHeaders, i as createHonoCookies, l as publishConstructEvents } from "./lazyAccessors-BHtcqgz2.mjs";
1
+ import { i as publishConstructEvents } from "./functions-DCIfCRR-.mjs";
2
+ import { n as ResponseBuilder, t as Endpoint } from "./Endpoint-CQAeh1Rh.mjs";
3
+ import { a as createHonoHeaders, i as createHonoCookies } from "./lazyAccessors-CFanua0O.mjs";
3
4
  import { n as executeWithAuditTransaction, t as createAuditContext } from "./processAudits-BpRlPQMW.mjs";
4
5
  import { wrapError } from "@geekmidas/errors";
5
6
  import { setCookie } from "hono/cookie";
@@ -312,4 +313,4 @@ var HonoEndpoint = class HonoEndpoint {
312
313
  //#endregion
313
314
  export { HonoEndpoint as t };
314
315
 
315
- //# sourceMappingURL=HonoEndpointAdaptor-CiqAZ5Mt.mjs.map
316
+ //# sourceMappingURL=HonoEndpointAdaptor-Aui-x9Lg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HonoEndpointAdaptor-Aui-x9Lg.mjs","names":["honoLogger"],"sources":["../src/endpoints/helpers.ts","../src/endpoints/parseHonoQuery.ts","../src/endpoints/HonoEndpointAdaptor.ts"],"sourcesContent":["import path from 'node:path';\nimport type { Service } from '@geekmidas/services';\nimport fg from 'fast-glob';\nimport type { HttpMethod } from '../types';\nimport { Endpoint } from './Endpoint';\n\n// Re-export utility functions\n\n/**\n * Recursively finds the project root directory by looking for lock files.\n * Traverses up the directory tree until it finds a package manager lock file.\n *\n * @param cwd - The current working directory to start searching from\n * @returns Promise resolving to the absolute path of the project root\n *\n * @example\n * ```typescript\n * const projectRoot = await getProjectRoot(process.cwd());\n * console.log(`Project root: ${projectRoot}`);\n * // Output: Project root: /Users/user/my-project\n * ```\n */\nexport async function getProjectRoot(cwd: string): Promise<string> {\n\tif (cwd === '/') {\n\t\treturn cwd;\n\t}\n\n\tconst stream = fg.stream(\n\t\t['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json', 'deno.lock'],\n\t\t{ dot: true, cwd },\n\t);\n\n\tlet isRoot = false;\n\n\tfor await (const _ of stream) {\n\t\tisRoot = true;\n\t\tbreak;\n\t}\n\n\tif (isRoot) {\n\t\treturn cwd;\n\t}\n\n\treturn getProjectRoot(path.resolve(cwd, '..'));\n}\n\n/**\n * Discovers and imports all Endpoint instances from the specified route patterns.\n * Uses fast-glob to find files matching the patterns and extracts exported Endpoints.\n *\n * @template TServices - Array of service types used by the endpoints\n * @param routes - Array of glob patterns to match route files (e.g., ['src/routes/*.ts'])\n * @param cwd - The current working directory to resolve paths from\n * @returns Promise resolving to an array of Endpoint instances found in the matched files\n *\n * @example\n * ```typescript\n * // Find all endpoints in the routes directory\n * const endpoints = await getEndpointsFromRoutes(\n * ['src/routes/**\\/*.ts'],\n * process.cwd()\n * );\n *\n * // Register endpoints with your server\n * for (const endpoint of endpoints) {\n * server.register(endpoint);\n * }\n * ```\n *\n * @remarks\n * - Only exports that are valid Endpoint instances are included\n * - Files are imported dynamically, so they must be valid ES modules\n * - The function filters out non-Endpoint exports automatically\n */\nexport async function getEndpointsFromRoutes<TServices extends Service[]>(\n\troutes: string[],\n\tcwd: string,\n): Promise<Endpoint<string, HttpMethod, any, any, TServices>[]> {\n\tconst stream = fg.stream(routes, { cwd });\n\n\tconst endpoints: Endpoint<string, HttpMethod, any, any, TServices>[] = [];\n\n\tfor await (const f of stream) {\n\t\t// Resolve the absolute path for the route file\n\t\tconst routePath = path.resolve(cwd, f.toString());\n\t\t// Dynamically import the route module\n\t\tconst route = await import(routePath);\n\n\t\t// Filter exported values to find only Endpoint instances\n\t\tconst handlers = Object.values(route).filter((value) => {\n\t\t\treturn Endpoint.isEndpoint(value);\n\t\t}) as unknown as Endpoint<string, HttpMethod, any, any, TServices>[];\n\n\t\tendpoints.push(...handlers);\n\t}\n\n\treturn endpoints;\n}\n","import type { Context } from 'hono';\nimport qs from 'qs';\n\n/**\n * Parse Hono query parameters using qs bracket notation\n * Supports nested objects, arrays, and deep nesting via standard bracket syntax\n */\nexport function parseHonoQuery(c: Context): Record<string, any> {\n\tconst url = c.req.url;\n\tconst queryIndex = url.indexOf('?');\n\tif (queryIndex === -1) {\n\t\treturn {};\n\t}\n\tconst queryString = url.slice(queryIndex + 1);\n\treturn qs.parse(queryString) as Record<string, any>;\n}\n","import type { AuditableAction, AuditStorage } from '@geekmidas/audit';\nimport { withRlsContext } from '@geekmidas/db/rls';\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport { wrapError } from '@geekmidas/errors';\nimport type { EventPublisher } from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { checkRateLimit, getRateLimitHeaders } from '@geekmidas/rate-limit';\nimport {\n\trunWithRequestContext,\n\ttype Service,\n\tServiceDiscovery,\n\ttype ServiceRecord,\n} from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { type Context, Hono } from 'hono';\nimport { setCookie } from 'hono/cookie';\nimport { logger as honoLogger } from 'hono/logger';\nimport { timing } from 'hono/timing';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { validator } from 'hono/validator';\nimport { publishConstructEvents } from '../publisher';\nimport type { HttpMethod, LowerHttpMethod } from '../types';\nimport type { MappedAudit } from './audit';\nimport {\n\tEndpoint,\n\ttype EndpointContext,\n\ttype EndpointSchemas,\n\tResponseBuilder,\n} from './Endpoint';\nimport { getEndpointsFromRoutes } from './helpers';\nimport { createHonoCookies, createHonoHeaders } from './lazyAccessors';\nimport { parseHonoQuery } from './parseHonoQuery';\nimport {\n\tcreateAuditContext,\n\texecuteWithAuditTransaction,\n} from './processAudits';\n\nexport interface HonoEndpointOptions {\n\t/**\n\t * Path where OpenAPI documentation will be served.\n\t * Set to false to disable docs route.\n\t * @default '/docs'\n\t */\n\tdocsPath?: string | false;\n\t/**\n\t * OpenAPI schema options\n\t */\n\topenApiOptions?: {\n\t\ttitle?: string;\n\t\tversion?: string;\n\t\tdescription?: string;\n\t};\n}\n\n/**\n * Feature flags for an endpoint, analyzed once at route registration time.\n * This avoids per-request feature detection overhead.\n */\ninterface EndpointFeatures {\n\thasServices: boolean;\n\thasDatabase: boolean;\n\thasBodyValidation: boolean;\n\thasQueryValidation: boolean;\n\thasParamValidation: boolean;\n\thasAudits: boolean;\n\thasEvents: boolean;\n\thasRateLimit: boolean;\n\thasRls: boolean;\n}\n\n/**\n * Case-insensitive check for a `content-type` header in a metadata headers map.\n */\nfunction hasContentTypeHeader(headers: Record<string, string>): boolean {\n\tfor (const key of Object.keys(headers)) {\n\t\tif (key.toLowerCase() === 'content-type') return true;\n\t}\n\treturn false;\n}\n\n/**\n * Analyze endpoint features at registration time (not per-request)\n */\nfunction analyzeEndpointFeatures(\n\tendpoint: Endpoint<\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany\n\t>,\n): EndpointFeatures {\n\treturn {\n\t\thasServices: endpoint.services.length > 0,\n\t\thasDatabase: !!endpoint.databaseService,\n\t\thasBodyValidation: !!endpoint.input?.body,\n\t\thasQueryValidation: !!endpoint.input?.query,\n\t\thasParamValidation: !!endpoint.input?.params,\n\t\t// Audit context needed if declarative audits OR auditor storage service configured (for manual audits)\n\t\thasAudits:\n\t\t\t(endpoint.audits?.length ?? 0) > 0 || !!endpoint.auditorStorageService,\n\t\thasEvents: (endpoint.events?.length ?? 0) > 0,\n\t\thasRateLimit: !!endpoint.rateLimit,\n\t\thasRls: !!endpoint.rlsConfig && !endpoint.rlsBypass,\n\t};\n}\n\nexport class HonoEndpoint<\n\tTRoute extends string,\n\tTMethod extends HttpMethod,\n\tTInput extends EndpointSchemas = {},\n\tTOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tTSession = unknown,\n\tTAuditStorage extends AuditStorage | undefined = undefined,\n\tTAuditStorageServiceName extends string = string,\n\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\tstring,\n\t\tunknown\n\t>,\n\tTDatabase = undefined,\n\tTDatabaseServiceName extends string = string,\n> {\n\tconstructor(\n\t\tprivate readonly endpoint: Endpoint<\n\t\t\tTRoute,\n\t\t\tTMethod,\n\t\t\tTInput,\n\t\t\tTOutSchema,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tTSession,\n\t\t\tTAuditStorage,\n\t\t\tTAuditStorageServiceName,\n\t\t\tTAuditAction,\n\t\t\tTDatabase,\n\t\t\tTDatabaseServiceName\n\t\t>,\n\t) {}\n\n\tstatic isDev = process.env.NODE_ENV === 'development';\n\n\tstatic async validate<T extends StandardSchemaV1>(\n\t\tc: Context<any, string, {}>,\n\t\tdata: unknown,\n\t\tschema?: T,\n\t) {\n\t\tif (!schema) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parsed = await Endpoint.validate(schema, data);\n\n\t\tif (parsed.issues) {\n\t\t\treturn c.json(parsed.issues, 422);\n\t\t}\n\n\t\treturn parsed.value;\n\t}\n\taddRoute(\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t): void {\n\t\tHonoEndpoint.addRoute(this.endpoint, serviceDiscovery, app);\n\t}\n\n\t/**\n\t * @deprecated Global event middleware is no longer used.\n\t * Events are now published per-route only for endpoints that have events configured.\n\t * This method is kept for backward compatibility but does nothing.\n\t */\n\tstatic applyEventMiddleware(\n\t\t_app: Hono,\n\t\t_serviceDiscovery: ServiceDiscovery<any>,\n\t) {\n\t\t// No-op: Event publishing is now handled per-route in addRoute\n\t\t// This avoids running middleware on every request including 404s\n\t}\n\n\tstatic async fromRoutes<TLogger extends Logger, TServices extends Service[]>(\n\t\troutes: string[],\n\t\tenvParser: EnvironmentParser<{}>,\n\t\tapp = new Hono(),\n\t\t_logger: TLogger,\n\t\tcwd = process.cwd(),\n\t\toptions?: HonoEndpointOptions,\n\t): Promise<Hono> {\n\t\tconst endpoints = await getEndpointsFromRoutes<TServices>(routes, cwd);\n\t\tconst serviceDiscovery =\n\t\t\tServiceDiscovery.getInstance<ServiceRecord<TServices>>(envParser);\n\n\t\tHonoEndpoint.addRoutes(endpoints, serviceDiscovery, app, options);\n\n\t\treturn app;\n\t}\n\n\tstatic addRoutes<\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t>(\n\t\tendpoints: Endpoint<string, HttpMethod, any, any, TServices, TLogger>[],\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t\toptions?: HonoEndpointOptions,\n\t): void {\n\t\t// Add timing middleware (always enabled)\n\t\tapp.use('*', timing());\n\n\t\t// Add logger middleware in development mode\n\n\t\tif (HonoEndpoint.isDev) {\n\t\t\tapp.use('*', honoLogger());\n\t\t}\n\n\t\t// Add docs route if not disabled\n\t\tconst docsPath =\n\t\t\toptions?.docsPath !== false ? options?.docsPath || '/docs' : null;\n\t\tif (docsPath) {\n\t\t\tHonoEndpoint.addDocsRoute(\n\t\t\t\tendpoints,\n\t\t\t\tapp,\n\t\t\t\tdocsPath,\n\t\t\t\toptions?.openApiOptions,\n\t\t\t);\n\t\t}\n\n\t\t// Sort endpoints to ensure static routes come before dynamic ones\n\t\tconst sortedEndpoints = endpoints.sort((a, b) => {\n\t\t\tconst aSegments = a.route.split('/');\n\t\t\tconst bSegments = b.route.split('/');\n\n\t\t\t// Compare each segment\n\t\t\tfor (let i = 0; i < Math.max(aSegments.length, bSegments.length); i++) {\n\t\t\t\tconst aSegment = aSegments[i] || '';\n\t\t\t\tconst bSegment = bSegments[i] || '';\n\n\t\t\t\t// If one is dynamic and the other is not, static comes first\n\t\t\t\tconst aIsDynamic = aSegment.startsWith(':');\n\t\t\t\tconst bIsDynamic = bSegment.startsWith(':');\n\n\t\t\t\tif (!aIsDynamic && bIsDynamic) return -1;\n\t\t\t\tif (aIsDynamic && !bIsDynamic) return 1;\n\n\t\t\t\t// If both are the same type, compare alphabetically\n\t\t\t\tif (aSegment !== bSegment) {\n\t\t\t\t\treturn aSegment.localeCompare(bSegment);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t});\n\n\t\t// Note: Global event middleware removed for performance\n\t\t// Events are now published per-route only for endpoints with events configured\n\t\tfor (const endpoint of sortedEndpoints) {\n\t\t\tHonoEndpoint.addRoute(endpoint, serviceDiscovery, app);\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/useAdjacentOverloadSignatures: not an overload — the instance `addRoute` above registers this adaptor's own endpoint, this one registers any endpoint on a given app. They share a name because they do the same thing to different subjects.\n\tstatic addRoute<\n\t\tTRoute extends string,\n\t\tTMethod extends HttpMethod,\n\t\tTInput extends EndpointSchemas = {},\n\t\tTOutSchema extends StandardSchemaV1 | undefined = undefined,\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t\tTSession = unknown,\n\t\tTAuditStorage extends AuditStorage | undefined = undefined,\n\t\tTAuditStorageServiceName extends string = string,\n\t\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>,\n\t\tTDatabase = undefined,\n\t\tTDatabaseServiceName extends string = string,\n\t>(\n\t\tendpoint: Endpoint<\n\t\t\tTRoute,\n\t\t\tTMethod,\n\t\t\tTInput,\n\t\t\tTOutSchema,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tTSession,\n\t\t\tTAuditStorage,\n\t\t\tTAuditStorageServiceName,\n\t\t\tTAuditAction,\n\t\t\tTDatabase,\n\t\t\tTDatabaseServiceName\n\t\t>,\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t): void {\n\t\tconst { route } = endpoint;\n\t\tconst method = endpoint.method.toLowerCase() as LowerHttpMethod<TMethod>;\n\n\t\t// Analyze endpoint features once at registration time (not per-request)\n\t\tconst features = analyzeEndpointFeatures(endpoint);\n\n\t\t// Build validators array - only add validators for schemas that exist\n\t\tconst validators: any[] = [];\n\n\t\tif (features.hasBodyValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('json', (value, c) =>\n\t\t\t\t\tHonoEndpoint.validate(c, value, endpoint.input?.body),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (features.hasQueryValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('query', (_, c) => {\n\t\t\t\t\tconst parsedQuery = parseHonoQuery(c);\n\t\t\t\t\treturn HonoEndpoint.validate(c, parsedQuery, endpoint.input?.query);\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tif (features.hasParamValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('param', (params, c) =>\n\t\t\t\t\tHonoEndpoint.validate(c, params, endpoint.input?.params),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Main handler\n\t\tconst handler = async (c: Context) => {\n\t\t\t// Request context setup\n\t\t\tconst startTime = Date.now();\n\t\t\tconst requestId = c.req.header('X-Request-ID') ?? crypto.randomUUID();\n\n\t\t\tconst logger = endpoint.logger.child({\n\t\t\t\trequestId,\n\t\t\t\tendpoint: endpoint.fullPath,\n\t\t\t\troute: endpoint.route,\n\t\t\t\thost: c.req.header('host'),\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t}) as TLogger;\n\n\t\t\t// Set response header\n\t\t\tc.header('X-Request-ID', requestId);\n\n\t\t\t// Wrap entire handler in request context for services to access\n\t\t\treturn runWithRequestContext(\n\t\t\t\t{ logger, requestId, startTime },\n\t\t\t\tasync () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Lazy accessors - no upfront parsing, use native Hono methods\n\t\t\t\t\t\tconst header = createHonoHeaders(c);\n\t\t\t\t\t\tconst cookie = createHonoCookies(c);\n\n\t\t\t\t\t\t// Only register services if endpoint has any\n\t\t\t\t\t\tconst services = features.hasServices\n\t\t\t\t\t\t\t? await serviceDiscovery.register(endpoint.services)\n\t\t\t\t\t\t\t: ({} as ServiceRecord<TServices>);\n\n\t\t\t\t\t\t// Resolve database service only if configured\n\t\t\t\t\t\tconst rawDb = features.hasDatabase\n\t\t\t\t\t\t\t? await serviceDiscovery\n\t\t\t\t\t\t\t\t\t.register([endpoint.databaseService!])\n\t\t\t\t\t\t\t\t\t.then(\n\t\t\t\t\t\t\t\t\t\t(s) =>\n\t\t\t\t\t\t\t\t\t\t\ts[\n\t\t\t\t\t\t\t\t\t\t\t\tendpoint.databaseService?.serviceName as keyof typeof s\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t// Extract session (defaults to empty object)\n\t\t\t\t\t\tconst session = await endpoint.getSession({\n\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t...(rawDb !== undefined && { db: rawDb }),\n\t\t\t\t\t\t} as any);\n\n\t\t\t\t\t\t// Check authorization (defaults to true)\n\t\t\t\t\t\tconst isAuthorized = await endpoint.authorize({\n\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t...(rawDb !== undefined && { db: rawDb }),\n\t\t\t\t\t\t\tbody: features.hasBodyValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('json')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tquery: features.hasQueryValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('query')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tparams: features.hasParamValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('param')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t} as any);\n\n\t\t\t\t\t\tif (!isAuthorized) {\n\t\t\t\t\t\t\tlogger.warn('Forbidden access attempt');\n\t\t\t\t\t\t\treturn c.json({ error: 'Forbidden' }, 403);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check rate limit only if configured\n\t\t\t\t\t\tif (features.hasRateLimit) {\n\t\t\t\t\t\t\tconst rateLimitInfo = await checkRateLimit(endpoint.rateLimit!, {\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\tpath: c.req.path,\n\t\t\t\t\t\t\t\tmethod: endpoint.method,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst rateLimitHeaders = getRateLimitHeaders(\n\t\t\t\t\t\t\t\trateLimitInfo,\n\t\t\t\t\t\t\t\tendpoint.rateLimit!,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(rateLimitHeaders)) {\n\t\t\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\t\t\tc.header(key, value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create audit context only if audits are configured\n\t\t\t\t\t\tconst auditContext = features.hasAudits\n\t\t\t\t\t\t\t? await createAuditContext(\n\t\t\t\t\t\t\t\t\tendpoint as any,\n\t\t\t\t\t\t\t\t\tserviceDiscovery,\n\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\tservices: services as Record<string, unknown>,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\tconst audits = features.hasAudits\n\t\t\t\t\t\t\t? (endpoint.audits as MappedAudit<TAuditAction, TOutSchema>[])\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\t\t// Warn if declarative audits are configured but no audit storage\n\t\t\t\t\t\tif (features.hasAudits && !auditContext) {\n\t\t\t\t\t\t\tlogger.warn('No auditor storage service available');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Extract RLS context only if configured and not bypassed\n\t\t\t\t\t\tconst rlsContext =\n\t\t\t\t\t\t\tfeatures.hasRls && rawDb !== undefined\n\t\t\t\t\t\t\t\t? await endpoint.rlsConfig?.extractor({\n\t\t\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\t\t\tsession: session as TSession,\n\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t// Execute handler with automatic audit transaction support\n\t\t\t\t\t\tconst result = await executeWithAuditTransaction(\n\t\t\t\t\t\t\tauditContext,\n\t\t\t\t\t\t\tasync (auditor) => {\n\t\t\t\t\t\t\t\tconst sameDatabase =\n\t\t\t\t\t\t\t\t\tauditContext?.storage?.databaseServiceName &&\n\t\t\t\t\t\t\t\t\tauditContext.storage.databaseServiceName ===\n\t\t\t\t\t\t\t\t\t\tendpoint.databaseService?.serviceName;\n\t\t\t\t\t\t\t\tconst baseDb = sameDatabase\n\t\t\t\t\t\t\t\t\t? (auditor?.getTransaction?.() ?? rawDb)\n\t\t\t\t\t\t\t\t\t: rawDb;\n\n\t\t\t\t\t\t\t\tconst executeHandler = async (db: TDatabase | undefined) => {\n\t\t\t\t\t\t\t\t\tconst responseBuilder = new ResponseBuilder();\n\t\t\t\t\t\t\t\t\tconst response = await endpoint.handler(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t\t\tbody: features.hasBodyValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('json')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tquery: features.hasQueryValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('query')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tparams: features.hasParamValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('param')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\t\tauditor,\n\t\t\t\t\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t\t\t\t\t} as unknown as EndpointContext<\n\t\t\t\t\t\t\t\t\t\t\tTInput,\n\t\t\t\t\t\t\t\t\t\t\tTServices,\n\t\t\t\t\t\t\t\t\t\t\tTLogger,\n\t\t\t\t\t\t\t\t\t\t\tTSession,\n\t\t\t\t\t\t\t\t\t\t\tTAuditAction,\n\t\t\t\t\t\t\t\t\t\t\tTDatabase,\n\t\t\t\t\t\t\t\t\t\t\tTAuditStorage\n\t\t\t\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\t\t\t\tresponseBuilder,\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tlet data = response;\n\t\t\t\t\t\t\t\t\tlet metadata = responseBuilder.getMetadata();\n\n\t\t\t\t\t\t\t\t\tif (Endpoint.hasMetadata(response)) {\n\t\t\t\t\t\t\t\t\t\tdata = response.data;\n\t\t\t\t\t\t\t\t\t\tmetadata = response.metadata;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tconst output = endpoint.outputSchema\n\t\t\t\t\t\t\t\t\t\t? await endpoint.parseOutput(data)\n\t\t\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t\t\t\treturn { output, metadata, responseBuilder };\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\tif (features.hasRls && rlsContext && baseDb) {\n\t\t\t\t\t\t\t\t\treturn withRlsContext(\n\t\t\t\t\t\t\t\t\t\tbaseDb as any,\n\t\t\t\t\t\t\t\t\t\trlsContext,\n\t\t\t\t\t\t\t\t\t\tasync (trx) => executeHandler(trx as TDatabase),\n\t\t\t\t\t\t\t\t\t\t{ prefix: endpoint.rlsConfig?.prefix },\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn executeHandler(baseDb as TDatabase | undefined);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tasync (result, auditor) => {\n\t\t\t\t\t\t\t\tif (!audits?.length) return;\n\n\t\t\t\t\t\t\t\tfor (const audit of audits) {\n\t\t\t\t\t\t\t\t\tif (audit.when && !audit.when(result.output as any)) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst payload = audit.payload(result.output as any);\n\t\t\t\t\t\t\t\t\tconst entityId = audit.entityId?.(result.output as any);\n\t\t\t\t\t\t\t\t\tauditor.audit(audit.type as any, payload as any, {\n\t\t\t\t\t\t\t\t\t\ttable: audit.table,\n\t\t\t\t\t\t\t\t\t\tentityId,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ db: rawDb },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst { output, metadata } = result;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlet status = endpoint.status as ContentfulStatusCode;\n\n\t\t\t\t\t\t\tif (metadata.status) {\n\t\t\t\t\t\t\t\tstatus = metadata.status as ContentfulStatusCode;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (metadata.headers) {\n\t\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(metadata.headers)) {\n\t\t\t\t\t\t\t\t\tc.header(key, value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (metadata.cookies) {\n\t\t\t\t\t\t\t\tfor (const [name, { value, options }] of metadata.cookies) {\n\t\t\t\t\t\t\t\t\tsetCookie(c, name, value, options);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Only publish events if configured (no global middleware overhead)\n\t\t\t\t\t\t\tif (features.hasEvents && Endpoint.isSuccessStatus(status)) {\n\t\t\t\t\t\t\t\tawait publishConstructEvents<any>(\n\t\t\t\t\t\t\t\t\tendpoint as any,\n\t\t\t\t\t\t\t\t\toutput,\n\t\t\t\t\t\t\t\t\tserviceDiscovery,\n\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\t\tlogger.info({ status, body: output }, 'Outgoing response');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Respect the endpoint's declared responseType. For JSON (default)\n\t\t\t\t\t\t\t// we use c.json() which sets Content-Type and serializes. For any\n\t\t\t\t\t\t\t// other type, emit the body as-is and set the header explicitly —\n\t\t\t\t\t\t\t// metadata.headers (from r.header()) applied above still wins.\n\t\t\t\t\t\t\tif (endpoint.responseType === 'application/json') {\n\t\t\t\t\t\t\t\t// Hono 4.13 types `c.json`'s status well enough that the\n\t\t\t\t\t\t\t\t// suppression here is now itself an error.\n\t\t\t\t\t\t\t\treturn c.json(output, status);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!(metadata.headers && hasContentTypeHeader(metadata.headers))\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tc.header('content-type', endpoint.responseType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn c.body(output as any, status);\n\t\t\t\t\t\t} catch (validationError: any) {\n\t\t\t\t\t\t\tlogger.error(validationError, 'Output validation failed');\n\t\t\t\t\t\t\tconst error = wrapError(\n\t\t\t\t\t\t\t\tvalidationError,\n\t\t\t\t\t\t\t\t422,\n\t\t\t\t\t\t\t\t'Response validation failed',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t{ status: error.statusCode, body: error },\n\t\t\t\t\t\t\t\t\t'Outgoing response',\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn c.json(error, error.statusCode as ContentfulStatusCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tlogger.error(e, 'Error processing endpoint request');\n\t\t\t\t\t\tconst error = wrapError(e, 500, 'Internal Server Error');\n\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t{ status: error.statusCode, body: error },\n\t\t\t\t\t\t\t\t'Outgoing response',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn c.json(error, error.statusCode as ContentfulStatusCode);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\t// Register route with conditional validators.\n\t\t//\n\t\t// `route` is a generic `TRoute`, and Hono 4.13 overloads `app.get` on\n\t\t// whether the first argument is a path or a handler. A generic that is\n\t\t// only *constrained* to string does not pick the path overload, so it\n\t\t// gets matched against the handler one and reported there. Saying it is a\n\t\t// string chooses the overload that was always intended.\n\t\t//\n\t\t// The spread is why a cast is needed rather than a better type: with\n\t\t// `...validators` of unknown length, the arity is not decidable, so the\n\t\t// first overload is chosen whatever the path argument says. Naming the\n\t\t// shape we are calling states the intent the overloads cannot infer.\n\t\t(\n\t\t\tapp[method] as unknown as (\n\t\t\t\tpath: string,\n\t\t\t\t...handlers: unknown[]\n\t\t\t) => unknown\n\t\t)(route, ...validators, handler);\n\t}\n\n\tstatic addDocsRoute<\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t>(\n\t\tendpoints: Endpoint<string, HttpMethod, any, any, TServices, TLogger>[],\n\t\tapp: Hono,\n\t\tdocsPath: string,\n\t\topenApiOptions?: HonoEndpointOptions['openApiOptions'],\n\t): void {\n\t\tapp.get(docsPath, async (c) => {\n\t\t\ttry {\n\t\t\t\tconst openApiSchema = await Endpoint.buildOpenApiSchema(\n\t\t\t\t\tendpoints,\n\t\t\t\t\topenApiOptions,\n\t\t\t\t);\n\n\t\t\t\treturn c.json(openApiSchema);\n\t\t\t} catch {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{ error: 'Failed to generate OpenAPI documentation' },\n\t\t\t\t\t500,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-y5ARvAq5.cjs");
2
- const require_Endpoint = require("./Endpoint-QKuFg5gs.cjs");
3
- const require_lazyAccessors = require("./lazyAccessors-Dx9NLwJZ.cjs");
2
+ const require_functions = require("./functions-ZH60FE7H.cjs");
3
+ const require_Endpoint = require("./Endpoint-D1L9qu5C.cjs");
4
+ const require_lazyAccessors = require("./lazyAccessors-hJKGv8Ay.cjs");
4
5
  const require_processAudits = require("./processAudits-D_2W5x8k.cjs");
5
6
  let _geekmidas_errors = require("@geekmidas/errors");
6
7
  let hono_cookie = require("hono/cookie");
@@ -272,7 +273,7 @@ var HonoEndpoint = class HonoEndpoint {
272
273
  if (metadata.status) status = metadata.status;
273
274
  if (metadata.headers) for (const [key, value] of Object.entries(metadata.headers)) c.header(key, value);
274
275
  if (metadata.cookies) for (const [name, { value, options }] of metadata.cookies) (0, hono_cookie.setCookie)(c, name, value, options);
275
- if (features.hasEvents && require_Endpoint.Endpoint.isSuccessStatus(status)) await require_lazyAccessors.publishConstructEvents(endpoint, output, serviceDiscovery, logger);
276
+ if (features.hasEvents && require_Endpoint.Endpoint.isSuccessStatus(status)) await require_functions.publishConstructEvents(endpoint, output, serviceDiscovery, logger);
276
277
  if (HonoEndpoint.isDev) logger.info({
277
278
  status,
278
279
  body: output
@@ -321,4 +322,4 @@ Object.defineProperty(exports, "HonoEndpoint", {
321
322
  }
322
323
  });
323
324
 
324
- //# sourceMappingURL=HonoEndpointAdaptor-DoEQdC3r.cjs.map
325
+ //# sourceMappingURL=HonoEndpointAdaptor-Cq99r9H7.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HonoEndpointAdaptor-Cq99r9H7.cjs","names":["fg","path","Endpoint","Endpoint","Hono","ServiceDiscovery","timing","honoLogger","validator","runWithRequestContext","createHonoHeaders","createHonoCookies","checkRateLimit","getRateLimitHeaders","createAuditContext","executeWithAuditTransaction","ResponseBuilder","withRlsContext","publishConstructEvents","wrapError"],"sources":["../src/endpoints/helpers.ts","../src/endpoints/parseHonoQuery.ts","../src/endpoints/HonoEndpointAdaptor.ts"],"sourcesContent":["import path from 'node:path';\nimport type { Service } from '@geekmidas/services';\nimport fg from 'fast-glob';\nimport type { HttpMethod } from '../types';\nimport { Endpoint } from './Endpoint';\n\n// Re-export utility functions\n\n/**\n * Recursively finds the project root directory by looking for lock files.\n * Traverses up the directory tree until it finds a package manager lock file.\n *\n * @param cwd - The current working directory to start searching from\n * @returns Promise resolving to the absolute path of the project root\n *\n * @example\n * ```typescript\n * const projectRoot = await getProjectRoot(process.cwd());\n * console.log(`Project root: ${projectRoot}`);\n * // Output: Project root: /Users/user/my-project\n * ```\n */\nexport async function getProjectRoot(cwd: string): Promise<string> {\n\tif (cwd === '/') {\n\t\treturn cwd;\n\t}\n\n\tconst stream = fg.stream(\n\t\t['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json', 'deno.lock'],\n\t\t{ dot: true, cwd },\n\t);\n\n\tlet isRoot = false;\n\n\tfor await (const _ of stream) {\n\t\tisRoot = true;\n\t\tbreak;\n\t}\n\n\tif (isRoot) {\n\t\treturn cwd;\n\t}\n\n\treturn getProjectRoot(path.resolve(cwd, '..'));\n}\n\n/**\n * Discovers and imports all Endpoint instances from the specified route patterns.\n * Uses fast-glob to find files matching the patterns and extracts exported Endpoints.\n *\n * @template TServices - Array of service types used by the endpoints\n * @param routes - Array of glob patterns to match route files (e.g., ['src/routes/*.ts'])\n * @param cwd - The current working directory to resolve paths from\n * @returns Promise resolving to an array of Endpoint instances found in the matched files\n *\n * @example\n * ```typescript\n * // Find all endpoints in the routes directory\n * const endpoints = await getEndpointsFromRoutes(\n * ['src/routes/**\\/*.ts'],\n * process.cwd()\n * );\n *\n * // Register endpoints with your server\n * for (const endpoint of endpoints) {\n * server.register(endpoint);\n * }\n * ```\n *\n * @remarks\n * - Only exports that are valid Endpoint instances are included\n * - Files are imported dynamically, so they must be valid ES modules\n * - The function filters out non-Endpoint exports automatically\n */\nexport async function getEndpointsFromRoutes<TServices extends Service[]>(\n\troutes: string[],\n\tcwd: string,\n): Promise<Endpoint<string, HttpMethod, any, any, TServices>[]> {\n\tconst stream = fg.stream(routes, { cwd });\n\n\tconst endpoints: Endpoint<string, HttpMethod, any, any, TServices>[] = [];\n\n\tfor await (const f of stream) {\n\t\t// Resolve the absolute path for the route file\n\t\tconst routePath = path.resolve(cwd, f.toString());\n\t\t// Dynamically import the route module\n\t\tconst route = await import(routePath);\n\n\t\t// Filter exported values to find only Endpoint instances\n\t\tconst handlers = Object.values(route).filter((value) => {\n\t\t\treturn Endpoint.isEndpoint(value);\n\t\t}) as unknown as Endpoint<string, HttpMethod, any, any, TServices>[];\n\n\t\tendpoints.push(...handlers);\n\t}\n\n\treturn endpoints;\n}\n","import type { Context } from 'hono';\nimport qs from 'qs';\n\n/**\n * Parse Hono query parameters using qs bracket notation\n * Supports nested objects, arrays, and deep nesting via standard bracket syntax\n */\nexport function parseHonoQuery(c: Context): Record<string, any> {\n\tconst url = c.req.url;\n\tconst queryIndex = url.indexOf('?');\n\tif (queryIndex === -1) {\n\t\treturn {};\n\t}\n\tconst queryString = url.slice(queryIndex + 1);\n\treturn qs.parse(queryString) as Record<string, any>;\n}\n","import type { AuditableAction, AuditStorage } from '@geekmidas/audit';\nimport { withRlsContext } from '@geekmidas/db/rls';\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport { wrapError } from '@geekmidas/errors';\nimport type { EventPublisher } from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { checkRateLimit, getRateLimitHeaders } from '@geekmidas/rate-limit';\nimport {\n\trunWithRequestContext,\n\ttype Service,\n\tServiceDiscovery,\n\ttype ServiceRecord,\n} from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { type Context, Hono } from 'hono';\nimport { setCookie } from 'hono/cookie';\nimport { logger as honoLogger } from 'hono/logger';\nimport { timing } from 'hono/timing';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { validator } from 'hono/validator';\nimport { publishConstructEvents } from '../publisher';\nimport type { HttpMethod, LowerHttpMethod } from '../types';\nimport type { MappedAudit } from './audit';\nimport {\n\tEndpoint,\n\ttype EndpointContext,\n\ttype EndpointSchemas,\n\tResponseBuilder,\n} from './Endpoint';\nimport { getEndpointsFromRoutes } from './helpers';\nimport { createHonoCookies, createHonoHeaders } from './lazyAccessors';\nimport { parseHonoQuery } from './parseHonoQuery';\nimport {\n\tcreateAuditContext,\n\texecuteWithAuditTransaction,\n} from './processAudits';\n\nexport interface HonoEndpointOptions {\n\t/**\n\t * Path where OpenAPI documentation will be served.\n\t * Set to false to disable docs route.\n\t * @default '/docs'\n\t */\n\tdocsPath?: string | false;\n\t/**\n\t * OpenAPI schema options\n\t */\n\topenApiOptions?: {\n\t\ttitle?: string;\n\t\tversion?: string;\n\t\tdescription?: string;\n\t};\n}\n\n/**\n * Feature flags for an endpoint, analyzed once at route registration time.\n * This avoids per-request feature detection overhead.\n */\ninterface EndpointFeatures {\n\thasServices: boolean;\n\thasDatabase: boolean;\n\thasBodyValidation: boolean;\n\thasQueryValidation: boolean;\n\thasParamValidation: boolean;\n\thasAudits: boolean;\n\thasEvents: boolean;\n\thasRateLimit: boolean;\n\thasRls: boolean;\n}\n\n/**\n * Case-insensitive check for a `content-type` header in a metadata headers map.\n */\nfunction hasContentTypeHeader(headers: Record<string, string>): boolean {\n\tfor (const key of Object.keys(headers)) {\n\t\tif (key.toLowerCase() === 'content-type') return true;\n\t}\n\treturn false;\n}\n\n/**\n * Analyze endpoint features at registration time (not per-request)\n */\nfunction analyzeEndpointFeatures(\n\tendpoint: Endpoint<\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany\n\t>,\n): EndpointFeatures {\n\treturn {\n\t\thasServices: endpoint.services.length > 0,\n\t\thasDatabase: !!endpoint.databaseService,\n\t\thasBodyValidation: !!endpoint.input?.body,\n\t\thasQueryValidation: !!endpoint.input?.query,\n\t\thasParamValidation: !!endpoint.input?.params,\n\t\t// Audit context needed if declarative audits OR auditor storage service configured (for manual audits)\n\t\thasAudits:\n\t\t\t(endpoint.audits?.length ?? 0) > 0 || !!endpoint.auditorStorageService,\n\t\thasEvents: (endpoint.events?.length ?? 0) > 0,\n\t\thasRateLimit: !!endpoint.rateLimit,\n\t\thasRls: !!endpoint.rlsConfig && !endpoint.rlsBypass,\n\t};\n}\n\nexport class HonoEndpoint<\n\tTRoute extends string,\n\tTMethod extends HttpMethod,\n\tTInput extends EndpointSchemas = {},\n\tTOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tTSession = unknown,\n\tTAuditStorage extends AuditStorage | undefined = undefined,\n\tTAuditStorageServiceName extends string = string,\n\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\tstring,\n\t\tunknown\n\t>,\n\tTDatabase = undefined,\n\tTDatabaseServiceName extends string = string,\n> {\n\tconstructor(\n\t\tprivate readonly endpoint: Endpoint<\n\t\t\tTRoute,\n\t\t\tTMethod,\n\t\t\tTInput,\n\t\t\tTOutSchema,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tTSession,\n\t\t\tTAuditStorage,\n\t\t\tTAuditStorageServiceName,\n\t\t\tTAuditAction,\n\t\t\tTDatabase,\n\t\t\tTDatabaseServiceName\n\t\t>,\n\t) {}\n\n\tstatic isDev = process.env.NODE_ENV === 'development';\n\n\tstatic async validate<T extends StandardSchemaV1>(\n\t\tc: Context<any, string, {}>,\n\t\tdata: unknown,\n\t\tschema?: T,\n\t) {\n\t\tif (!schema) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parsed = await Endpoint.validate(schema, data);\n\n\t\tif (parsed.issues) {\n\t\t\treturn c.json(parsed.issues, 422);\n\t\t}\n\n\t\treturn parsed.value;\n\t}\n\taddRoute(\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t): void {\n\t\tHonoEndpoint.addRoute(this.endpoint, serviceDiscovery, app);\n\t}\n\n\t/**\n\t * @deprecated Global event middleware is no longer used.\n\t * Events are now published per-route only for endpoints that have events configured.\n\t * This method is kept for backward compatibility but does nothing.\n\t */\n\tstatic applyEventMiddleware(\n\t\t_app: Hono,\n\t\t_serviceDiscovery: ServiceDiscovery<any>,\n\t) {\n\t\t// No-op: Event publishing is now handled per-route in addRoute\n\t\t// This avoids running middleware on every request including 404s\n\t}\n\n\tstatic async fromRoutes<TLogger extends Logger, TServices extends Service[]>(\n\t\troutes: string[],\n\t\tenvParser: EnvironmentParser<{}>,\n\t\tapp = new Hono(),\n\t\t_logger: TLogger,\n\t\tcwd = process.cwd(),\n\t\toptions?: HonoEndpointOptions,\n\t): Promise<Hono> {\n\t\tconst endpoints = await getEndpointsFromRoutes<TServices>(routes, cwd);\n\t\tconst serviceDiscovery =\n\t\t\tServiceDiscovery.getInstance<ServiceRecord<TServices>>(envParser);\n\n\t\tHonoEndpoint.addRoutes(endpoints, serviceDiscovery, app, options);\n\n\t\treturn app;\n\t}\n\n\tstatic addRoutes<\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t>(\n\t\tendpoints: Endpoint<string, HttpMethod, any, any, TServices, TLogger>[],\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t\toptions?: HonoEndpointOptions,\n\t): void {\n\t\t// Add timing middleware (always enabled)\n\t\tapp.use('*', timing());\n\n\t\t// Add logger middleware in development mode\n\n\t\tif (HonoEndpoint.isDev) {\n\t\t\tapp.use('*', honoLogger());\n\t\t}\n\n\t\t// Add docs route if not disabled\n\t\tconst docsPath =\n\t\t\toptions?.docsPath !== false ? options?.docsPath || '/docs' : null;\n\t\tif (docsPath) {\n\t\t\tHonoEndpoint.addDocsRoute(\n\t\t\t\tendpoints,\n\t\t\t\tapp,\n\t\t\t\tdocsPath,\n\t\t\t\toptions?.openApiOptions,\n\t\t\t);\n\t\t}\n\n\t\t// Sort endpoints to ensure static routes come before dynamic ones\n\t\tconst sortedEndpoints = endpoints.sort((a, b) => {\n\t\t\tconst aSegments = a.route.split('/');\n\t\t\tconst bSegments = b.route.split('/');\n\n\t\t\t// Compare each segment\n\t\t\tfor (let i = 0; i < Math.max(aSegments.length, bSegments.length); i++) {\n\t\t\t\tconst aSegment = aSegments[i] || '';\n\t\t\t\tconst bSegment = bSegments[i] || '';\n\n\t\t\t\t// If one is dynamic and the other is not, static comes first\n\t\t\t\tconst aIsDynamic = aSegment.startsWith(':');\n\t\t\t\tconst bIsDynamic = bSegment.startsWith(':');\n\n\t\t\t\tif (!aIsDynamic && bIsDynamic) return -1;\n\t\t\t\tif (aIsDynamic && !bIsDynamic) return 1;\n\n\t\t\t\t// If both are the same type, compare alphabetically\n\t\t\t\tif (aSegment !== bSegment) {\n\t\t\t\t\treturn aSegment.localeCompare(bSegment);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t});\n\n\t\t// Note: Global event middleware removed for performance\n\t\t// Events are now published per-route only for endpoints with events configured\n\t\tfor (const endpoint of sortedEndpoints) {\n\t\t\tHonoEndpoint.addRoute(endpoint, serviceDiscovery, app);\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/useAdjacentOverloadSignatures: not an overload — the instance `addRoute` above registers this adaptor's own endpoint, this one registers any endpoint on a given app. They share a name because they do the same thing to different subjects.\n\tstatic addRoute<\n\t\tTRoute extends string,\n\t\tTMethod extends HttpMethod,\n\t\tTInput extends EndpointSchemas = {},\n\t\tTOutSchema extends StandardSchemaV1 | undefined = undefined,\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t\tTSession = unknown,\n\t\tTAuditStorage extends AuditStorage | undefined = undefined,\n\t\tTAuditStorageServiceName extends string = string,\n\t\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>,\n\t\tTDatabase = undefined,\n\t\tTDatabaseServiceName extends string = string,\n\t>(\n\t\tendpoint: Endpoint<\n\t\t\tTRoute,\n\t\t\tTMethod,\n\t\t\tTInput,\n\t\t\tTOutSchema,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tTSession,\n\t\t\tTAuditStorage,\n\t\t\tTAuditStorageServiceName,\n\t\t\tTAuditAction,\n\t\t\tTDatabase,\n\t\t\tTDatabaseServiceName\n\t\t>,\n\t\tserviceDiscovery: ServiceDiscovery<ServiceRecord<TServices>>,\n\t\tapp: Hono,\n\t): void {\n\t\tconst { route } = endpoint;\n\t\tconst method = endpoint.method.toLowerCase() as LowerHttpMethod<TMethod>;\n\n\t\t// Analyze endpoint features once at registration time (not per-request)\n\t\tconst features = analyzeEndpointFeatures(endpoint);\n\n\t\t// Build validators array - only add validators for schemas that exist\n\t\tconst validators: any[] = [];\n\n\t\tif (features.hasBodyValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('json', (value, c) =>\n\t\t\t\t\tHonoEndpoint.validate(c, value, endpoint.input?.body),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (features.hasQueryValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('query', (_, c) => {\n\t\t\t\t\tconst parsedQuery = parseHonoQuery(c);\n\t\t\t\t\treturn HonoEndpoint.validate(c, parsedQuery, endpoint.input?.query);\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tif (features.hasParamValidation) {\n\t\t\tvalidators.push(\n\t\t\t\tvalidator('param', (params, c) =>\n\t\t\t\t\tHonoEndpoint.validate(c, params, endpoint.input?.params),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Main handler\n\t\tconst handler = async (c: Context) => {\n\t\t\t// Request context setup\n\t\t\tconst startTime = Date.now();\n\t\t\tconst requestId = c.req.header('X-Request-ID') ?? crypto.randomUUID();\n\n\t\t\tconst logger = endpoint.logger.child({\n\t\t\t\trequestId,\n\t\t\t\tendpoint: endpoint.fullPath,\n\t\t\t\troute: endpoint.route,\n\t\t\t\thost: c.req.header('host'),\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t}) as TLogger;\n\n\t\t\t// Set response header\n\t\t\tc.header('X-Request-ID', requestId);\n\n\t\t\t// Wrap entire handler in request context for services to access\n\t\t\treturn runWithRequestContext(\n\t\t\t\t{ logger, requestId, startTime },\n\t\t\t\tasync () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Lazy accessors - no upfront parsing, use native Hono methods\n\t\t\t\t\t\tconst header = createHonoHeaders(c);\n\t\t\t\t\t\tconst cookie = createHonoCookies(c);\n\n\t\t\t\t\t\t// Only register services if endpoint has any\n\t\t\t\t\t\tconst services = features.hasServices\n\t\t\t\t\t\t\t? await serviceDiscovery.register(endpoint.services)\n\t\t\t\t\t\t\t: ({} as ServiceRecord<TServices>);\n\n\t\t\t\t\t\t// Resolve database service only if configured\n\t\t\t\t\t\tconst rawDb = features.hasDatabase\n\t\t\t\t\t\t\t? await serviceDiscovery\n\t\t\t\t\t\t\t\t\t.register([endpoint.databaseService!])\n\t\t\t\t\t\t\t\t\t.then(\n\t\t\t\t\t\t\t\t\t\t(s) =>\n\t\t\t\t\t\t\t\t\t\t\ts[\n\t\t\t\t\t\t\t\t\t\t\t\tendpoint.databaseService?.serviceName as keyof typeof s\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t// Extract session (defaults to empty object)\n\t\t\t\t\t\tconst session = await endpoint.getSession({\n\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t...(rawDb !== undefined && { db: rawDb }),\n\t\t\t\t\t\t} as any);\n\n\t\t\t\t\t\t// Check authorization (defaults to true)\n\t\t\t\t\t\tconst isAuthorized = await endpoint.authorize({\n\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t...(rawDb !== undefined && { db: rawDb }),\n\t\t\t\t\t\t\tbody: features.hasBodyValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('json')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tquery: features.hasQueryValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('query')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tparams: features.hasParamValidation\n\t\t\t\t\t\t\t\t? (c.req.valid as any)('param')\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t} as any);\n\n\t\t\t\t\t\tif (!isAuthorized) {\n\t\t\t\t\t\t\tlogger.warn('Forbidden access attempt');\n\t\t\t\t\t\t\treturn c.json({ error: 'Forbidden' }, 403);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check rate limit only if configured\n\t\t\t\t\t\tif (features.hasRateLimit) {\n\t\t\t\t\t\t\tconst rateLimitInfo = await checkRateLimit(endpoint.rateLimit!, {\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\tpath: c.req.path,\n\t\t\t\t\t\t\t\tmethod: endpoint.method,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst rateLimitHeaders = getRateLimitHeaders(\n\t\t\t\t\t\t\t\trateLimitInfo,\n\t\t\t\t\t\t\t\tendpoint.rateLimit!,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(rateLimitHeaders)) {\n\t\t\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\t\t\tc.header(key, value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create audit context only if audits are configured\n\t\t\t\t\t\tconst auditContext = features.hasAudits\n\t\t\t\t\t\t\t? await createAuditContext(\n\t\t\t\t\t\t\t\t\tendpoint as any,\n\t\t\t\t\t\t\t\t\tserviceDiscovery,\n\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\tservices: services as Record<string, unknown>,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\tconst audits = features.hasAudits\n\t\t\t\t\t\t\t? (endpoint.audits as MappedAudit<TAuditAction, TOutSchema>[])\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\t\t// Warn if declarative audits are configured but no audit storage\n\t\t\t\t\t\tif (features.hasAudits && !auditContext) {\n\t\t\t\t\t\t\tlogger.warn('No auditor storage service available');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Extract RLS context only if configured and not bypassed\n\t\t\t\t\t\tconst rlsContext =\n\t\t\t\t\t\t\tfeatures.hasRls && rawDb !== undefined\n\t\t\t\t\t\t\t\t? await endpoint.rlsConfig?.extractor({\n\t\t\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\t\t\tsession: session as TSession,\n\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t// Execute handler with automatic audit transaction support\n\t\t\t\t\t\tconst result = await executeWithAuditTransaction(\n\t\t\t\t\t\t\tauditContext,\n\t\t\t\t\t\t\tasync (auditor) => {\n\t\t\t\t\t\t\t\tconst sameDatabase =\n\t\t\t\t\t\t\t\t\tauditContext?.storage?.databaseServiceName &&\n\t\t\t\t\t\t\t\t\tauditContext.storage.databaseServiceName ===\n\t\t\t\t\t\t\t\t\t\tendpoint.databaseService?.serviceName;\n\t\t\t\t\t\t\t\tconst baseDb = sameDatabase\n\t\t\t\t\t\t\t\t\t? (auditor?.getTransaction?.() ?? rawDb)\n\t\t\t\t\t\t\t\t\t: rawDb;\n\n\t\t\t\t\t\t\t\tconst executeHandler = async (db: TDatabase | undefined) => {\n\t\t\t\t\t\t\t\t\tconst responseBuilder = new ResponseBuilder();\n\t\t\t\t\t\t\t\t\tconst response = await endpoint.handler(\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tservices,\n\t\t\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t\t\t\tbody: features.hasBodyValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('json')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tquery: features.hasQueryValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('query')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tparams: features.hasParamValidation\n\t\t\t\t\t\t\t\t\t\t\t\t? (c.req.valid as any)('param')\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t\t\t\t\tcookie,\n\t\t\t\t\t\t\t\t\t\t\tauditor,\n\t\t\t\t\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t\t\t\t\t} as unknown as EndpointContext<\n\t\t\t\t\t\t\t\t\t\t\tTInput,\n\t\t\t\t\t\t\t\t\t\t\tTServices,\n\t\t\t\t\t\t\t\t\t\t\tTLogger,\n\t\t\t\t\t\t\t\t\t\t\tTSession,\n\t\t\t\t\t\t\t\t\t\t\tTAuditAction,\n\t\t\t\t\t\t\t\t\t\t\tTDatabase,\n\t\t\t\t\t\t\t\t\t\t\tTAuditStorage\n\t\t\t\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\t\t\t\tresponseBuilder,\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tlet data = response;\n\t\t\t\t\t\t\t\t\tlet metadata = responseBuilder.getMetadata();\n\n\t\t\t\t\t\t\t\t\tif (Endpoint.hasMetadata(response)) {\n\t\t\t\t\t\t\t\t\t\tdata = response.data;\n\t\t\t\t\t\t\t\t\t\tmetadata = response.metadata;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tconst output = endpoint.outputSchema\n\t\t\t\t\t\t\t\t\t\t? await endpoint.parseOutput(data)\n\t\t\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\t\t\t\treturn { output, metadata, responseBuilder };\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\tif (features.hasRls && rlsContext && baseDb) {\n\t\t\t\t\t\t\t\t\treturn withRlsContext(\n\t\t\t\t\t\t\t\t\t\tbaseDb as any,\n\t\t\t\t\t\t\t\t\t\trlsContext,\n\t\t\t\t\t\t\t\t\t\tasync (trx) => executeHandler(trx as TDatabase),\n\t\t\t\t\t\t\t\t\t\t{ prefix: endpoint.rlsConfig?.prefix },\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn executeHandler(baseDb as TDatabase | undefined);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tasync (result, auditor) => {\n\t\t\t\t\t\t\t\tif (!audits?.length) return;\n\n\t\t\t\t\t\t\t\tfor (const audit of audits) {\n\t\t\t\t\t\t\t\t\tif (audit.when && !audit.when(result.output as any)) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst payload = audit.payload(result.output as any);\n\t\t\t\t\t\t\t\t\tconst entityId = audit.entityId?.(result.output as any);\n\t\t\t\t\t\t\t\t\tauditor.audit(audit.type as any, payload as any, {\n\t\t\t\t\t\t\t\t\t\ttable: audit.table,\n\t\t\t\t\t\t\t\t\t\tentityId,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ db: rawDb },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst { output, metadata } = result;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlet status = endpoint.status as ContentfulStatusCode;\n\n\t\t\t\t\t\t\tif (metadata.status) {\n\t\t\t\t\t\t\t\tstatus = metadata.status as ContentfulStatusCode;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (metadata.headers) {\n\t\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(metadata.headers)) {\n\t\t\t\t\t\t\t\t\tc.header(key, value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (metadata.cookies) {\n\t\t\t\t\t\t\t\tfor (const [name, { value, options }] of metadata.cookies) {\n\t\t\t\t\t\t\t\t\tsetCookie(c, name, value, options);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Only publish events if configured (no global middleware overhead)\n\t\t\t\t\t\t\tif (features.hasEvents && Endpoint.isSuccessStatus(status)) {\n\t\t\t\t\t\t\t\tawait publishConstructEvents<any>(\n\t\t\t\t\t\t\t\t\tendpoint as any,\n\t\t\t\t\t\t\t\t\toutput,\n\t\t\t\t\t\t\t\t\tserviceDiscovery,\n\t\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\t\tlogger.info({ status, body: output }, 'Outgoing response');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Respect the endpoint's declared responseType. For JSON (default)\n\t\t\t\t\t\t\t// we use c.json() which sets Content-Type and serializes. For any\n\t\t\t\t\t\t\t// other type, emit the body as-is and set the header explicitly —\n\t\t\t\t\t\t\t// metadata.headers (from r.header()) applied above still wins.\n\t\t\t\t\t\t\tif (endpoint.responseType === 'application/json') {\n\t\t\t\t\t\t\t\t// Hono 4.13 types `c.json`'s status well enough that the\n\t\t\t\t\t\t\t\t// suppression here is now itself an error.\n\t\t\t\t\t\t\t\treturn c.json(output, status);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!(metadata.headers && hasContentTypeHeader(metadata.headers))\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tc.header('content-type', endpoint.responseType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn c.body(output as any, status);\n\t\t\t\t\t\t} catch (validationError: any) {\n\t\t\t\t\t\t\tlogger.error(validationError, 'Output validation failed');\n\t\t\t\t\t\t\tconst error = wrapError(\n\t\t\t\t\t\t\t\tvalidationError,\n\t\t\t\t\t\t\t\t422,\n\t\t\t\t\t\t\t\t'Response validation failed',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t{ status: error.statusCode, body: error },\n\t\t\t\t\t\t\t\t\t'Outgoing response',\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn c.json(error, error.statusCode as ContentfulStatusCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tlogger.error(e, 'Error processing endpoint request');\n\t\t\t\t\t\tconst error = wrapError(e, 500, 'Internal Server Error');\n\t\t\t\t\t\tif (HonoEndpoint.isDev) {\n\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t{ status: error.statusCode, body: error },\n\t\t\t\t\t\t\t\t'Outgoing response',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn c.json(error, error.statusCode as ContentfulStatusCode);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\t// Register route with conditional validators.\n\t\t//\n\t\t// `route` is a generic `TRoute`, and Hono 4.13 overloads `app.get` on\n\t\t// whether the first argument is a path or a handler. A generic that is\n\t\t// only *constrained* to string does not pick the path overload, so it\n\t\t// gets matched against the handler one and reported there. Saying it is a\n\t\t// string chooses the overload that was always intended.\n\t\t//\n\t\t// The spread is why a cast is needed rather than a better type: with\n\t\t// `...validators` of unknown length, the arity is not decidable, so the\n\t\t// first overload is chosen whatever the path argument says. Naming the\n\t\t// shape we are calling states the intent the overloads cannot infer.\n\t\t(\n\t\t\tapp[method] as unknown as (\n\t\t\t\tpath: string,\n\t\t\t\t...handlers: unknown[]\n\t\t\t) => unknown\n\t\t)(route, ...validators, handler);\n\t}\n\n\tstatic addDocsRoute<\n\t\tTServices extends Service[] = [],\n\t\tTLogger extends Logger = Logger,\n\t>(\n\t\tendpoints: Endpoint<string, HttpMethod, any, any, TServices, TLogger>[],\n\t\tapp: Hono,\n\t\tdocsPath: string,\n\t\topenApiOptions?: HonoEndpointOptions['openApiOptions'],\n\t): void {\n\t\tapp.get(docsPath, async (c) => {\n\t\t\ttry {\n\t\t\t\tconst openApiSchema = await Endpoint.buildOpenApiSchema(\n\t\t\t\t\tendpoints,\n\t\t\t\t\topenApiOptions,\n\t\t\t\t);\n\n\t\t\t\treturn c.json(openApiSchema);\n\t\t\t} catch {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{ error: 'Failed to generate OpenAPI documentation' },\n\t\t\t\t\t500,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import { t as Construct } from "./Construct-Detz65RA.mjs";
2
- import { derivedFrom } from "./construct-interface.mjs";
1
+ import { t as Construct } from "./Construct-BO1X-kt9.mjs";
3
2
  import { canonicalId, provideKey, serviceKey } from "@geekmidas/manifest";
4
3
  import { DEFAULT_LOGGER } from "@geekmidas/logger/console";
5
4
  import { Publisher } from "@geekmidas/events";
@@ -7,11 +6,12 @@ import { Publisher } from "@geekmidas/events";
7
6
  /**
8
7
  * A queue worker — a point-to-point SQS-style queue and its single consumer.
9
8
  * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue
10
- * drains every message of its one `message` type. Build one with `q` (see
11
- * `QueueBuilder`); `gkm build` discovers it into the manifest's `queues` field.
9
+ * drains every message of its one `message` type. Build one from the worker
10
+ * that runs it — `worker.queue('Emails').message(schema).handle(…)` — and
11
+ * `gkm build` discovers it into the manifest's `queues` field.
12
12
  *
13
- * The producer side is {@link Queue.publisher} — a ready-to-inject `Service`
14
- * that any endpoint/function drops into `.services([...])` to send messages.
13
+ * Producers send to it by depending on it: `.dependsOn([emails])` makes
14
+ * `services.emails` the publisher.
15
15
  */
16
16
  var Queue = class extends Construct {
17
17
  name;
@@ -36,13 +36,23 @@ var Queue = class extends Construct {
36
36
  */
37
37
  id;
38
38
  /**
39
- * The producer's env key. Read by both {@link declare} and
40
- * {@link publisher}, so what the target publishes and what the producer
41
- * looks up cannot drift.
39
+ * The queue as a dependency — what `.dependsOn([emails])` dissolves into,
40
+ * reachable as `services.emails`.
41
+ *
42
+ * The producer: the queue's one consumer is the handler it was built with,
43
+ * so the only thing another construct can want from a queue is to send to
44
+ * it. It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and picks the transport
45
+ * from its protocol — `pgboss://` locally, `sqs://` deployed. A field
46
+ * assigned once, not a getter: services are cached by object identity.
47
+ */
48
+ service;
49
+ /**
50
+ * The producer's env key. Read by both {@link declare} and the service, so
51
+ * what the target publishes and what the producer looks up cannot drift.
42
52
  */
43
53
  connectionKey;
44
54
  constructor(name, handler, messageSchema, timeout = 3e4, services = [], logger = DEFAULT_LOGGER, batchSize, fifo, constructs = []) {
45
- super("dev.geekmidas.function.queue", logger, services, [], void 0, void 0, timeout, void 0, void 0, constructs);
55
+ super("dev.geekmidas.function.queue", logger, services, [], void 0, timeout, void 0, void 0, constructs);
46
56
  this.name = name;
47
57
  this.handler = handler;
48
58
  this.messageSchema = messageSchema;
@@ -53,6 +63,14 @@ var Queue = class extends Construct {
53
63
  this.fifo = fifo;
54
64
  this.id = canonicalId(name);
55
65
  this.connectionKey = provideKey(this.id, "publisherConnectionString");
66
+ const envVar = this.connectionKey;
67
+ this.service = {
68
+ serviceName: serviceKey(this.id),
69
+ async register({ envParser }) {
70
+ const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
71
+ return Publisher.fromConnectionString(connectionString);
72
+ }
73
+ };
56
74
  }
57
75
  /**
58
76
  * What this queue is in the manifest.
@@ -75,45 +93,8 @@ var Queue = class extends Construct {
75
93
  }
76
94
  }];
77
95
  }
78
- /**
79
- * The producer side — a `Service` exposing an `EventPublisher` typed to this
80
- * queue's message. Inject it via `.services([queue.publisher])`; the handler
81
- * then calls `services.<name>Publisher.publish([{ type, payload }])`.
82
- *
83
- * It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and builds the transport from
84
- * the URL protocol — `pgboss://` locally, `sqs://` deployed — so the same
85
- * code publishes to Postgres in dev and SQS in prod. Because it's a `Service`,
86
- * `Construct.getEnvironment()` sniffs it, so the env requirement flows into
87
- * the manifest and infra links exactly this queue with least privilege.
88
- */
89
- /**
90
- * The queue as a dependency — what `.dependsOn([emailsQueue])` dissolves
91
- * into, reachable as `services.emails`.
92
- *
93
- * It is the producer: a consumer is the worker written right here, so the
94
- * only thing another construct can want from a queue is the ability to send
95
- * to it. {@link publisher} is the same service under its older
96
- * `<name>Publisher` key, kept for `.services([queue.publisher])`.
97
- */
98
- get service() {
99
- const { register } = this.publisher;
100
- return {
101
- serviceName: serviceKey(this.id),
102
- register
103
- };
104
- }
105
- get publisher() {
106
- const envVar = this.connectionKey;
107
- return derivedFrom({
108
- serviceName: `${this.name}Publisher`,
109
- async register({ envParser }) {
110
- const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
111
- return Publisher.fromConnectionString(connectionString);
112
- }
113
- }, this);
114
- }
115
96
  };
116
97
  //#endregion
117
98
  export { Queue as t };
118
99
 
119
- //# sourceMappingURL=Queue-DpKTLl6E.mjs.map
100
+ //# sourceMappingURL=Queue-C1uDgjxt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queue-C1uDgjxt.mjs","names":[],"sources":["../src/queue/Queue.ts"],"sourcesContent":["import {\n\ttype EventPublisher,\n\ttype EventPublisherConnectionString,\n\ttype PublishableMessage,\n\tPublisher,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport {\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\n/**\n * The wire message a queue carries: `{ type: <queue name>, payload: <message> }`.\n * The producer publishes this shape and the worker receives the `payload`s as\n * its `messages`. Typing `type` to the queue name keeps the publisher fully\n * typed and lets pg-boss (local) / SQS (deployed) route by name.\n */\nexport type QueueMessage<\n\tTName extends string,\n\tTMessage extends StandardSchemaV1,\n> = PublishableMessage<TName, InferStandardSchema<TMessage>>;\n\n/**\n * A queue worker — a point-to-point SQS-style queue and its single consumer.\n * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue\n * drains every message of its one `message` type. Build one from the worker\n * that runs it — `worker.queue('Emails').message(schema).handle(…)` — and\n * `gkm build` discovers it into the manifest's `queues` field.\n *\n * Producers send to it by depending on it: `.dependsOn([emails])` makes\n * `services.emails` the publisher.\n */\nexport class Queue<\n\tTName extends string = string,\n\tTMessage extends StandardSchemaV1 = StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> extends Construct<TLogger, undefined, TServices> {\n\t__IS_QUEUE__ = true;\n\n\tstatic isQueue(\n\t\tobj: unknown,\n\t): obj is Queue<string, StandardSchemaV1, Service[], Logger> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\t(obj as { __IS_QUEUE__?: boolean }).__IS_QUEUE__ === true &&\n\t\t\t\t(obj as Construct).type === ConstructType.Queue,\n\t\t);\n\t}\n\n\t/**\n\t * The canonical id this queue is declared under.\n\t *\n\t * Derived from the name rather than given separately, so `emails` and\n\t * `Emails` are one queue. The name stays what it was: it is the wire `type`\n\t * a producer sends and the worker subscribes to, and changing that would\n\t * silently orphan in-flight messages.\n\t */\n\treadonly id: string;\n\n\t/**\n\t * The queue as a dependency — what `.dependsOn([emails])` dissolves into,\n\t * reachable as `services.emails`.\n\t *\n\t * The producer: the queue's one consumer is the handler it was built with,\n\t * so the only thing another construct can want from a queue is to send to\n\t * it. It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and picks the transport\n\t * from its protocol — `pgboss://` locally, `sqs://` deployed. A field\n\t * assigned once, not a getter: services are cached by object identity.\n\t */\n\treadonly service: Service<\n\t\tUncapitalize<TName>,\n\t\tEventPublisher<QueueMessage<TName, TMessage>>\n\t>;\n\n\t/**\n\t * The producer's env key. Read by both {@link declare} and the service, so\n\t * what the target publishes and what the producer looks up cannot drift.\n\t */\n\tprivate readonly connectionKey: string;\n\n\tconstructor(\n\t\tpublic readonly name: TName,\n\t\tpublic readonly handler: QueueHandler<TMessage, TServices, TLogger>,\n\t\tpublic readonly messageSchema: TMessage,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\t/** SQS event-source batch size (deployed). */\n\t\tpublic readonly batchSize?: number,\n\t\t/** Whether the queue is FIFO (deployed). */\n\t\tpublic readonly fifo?: boolean,\n\t\t/**\n\t\t * The construct ids the *worker* `.dependsOn()` named — last, so no\n\t\t * existing positional argument moves.\n\t\t */\n\t\tconstructs: string[] = [],\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Queue,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tundefined,\n\t\t\ttimeout,\n\t\t\tundefined, // memorySize\n\t\t\tundefined, // auditorStorageService\n\t\t\tconstructs,\n\t\t);\n\n\t\tthis.id = canonicalId(name);\n\t\tthis.connectionKey = provideKey(this.id, 'publisherConnectionString');\n\n\t\tconst envVar = this.connectionKey;\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(this.id) as Uncapitalize<TName>,\n\t\t\tasync register({ envParser }) {\n\t\t\t\tconst { connectionString } = envParser\n\t\t\t\t\t.create((get) => ({ connectionString: get(envVar).string() }))\n\t\t\t\t\t.parse();\n\n\t\t\t\treturn Publisher.fromConnectionString<QueueMessage<TName, TMessage>>(\n\t\t\t\t\tconnectionString as EventPublisherConnectionString,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * What this queue is in the manifest.\n\t *\n\t * A queue is a resource, not a handler: the worker is reached *through* it,\n\t * so the declaration carries the producer's key and nothing about the code\n\t * that drains it. The local target reads this to know which broker has to be\n\t * running and what connection string to inject.\n\t */\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'queue',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.connectionKey],\n\t\t\t\t...(this.fifo ? { fifo: true } : {}),\n\t\t\t\t// Nested rather than a sibling node, because position carries the\n\t\t\t\t// trigger: this handler is reached by messages on this queue and\n\t\t\t\t// by nothing else, so there is no `trigger` field to keep in step.\n\t\t\t\t//\n\t\t\t\t// `handler` is the export name; which directory the build wrote it\n\t\t\t\t// to is the target's business, and a path with a cloud in it does\n\t\t\t\t// not belong in a neutral declaration.\n\t\t\t\tworker: {\n\t\t\t\t\tid: `${this.id}Worker`,\n\t\t\t\t\thandler: `${this.id}.handler`,\n\t\t\t\t\t// Filled by the build from what the worker declared. Empty is a\n\t\t\t\t\t// stated gap, not a claim that it reaches nothing.\n\t\t\t\t\tdependencies: [],\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t}\n}\n\n/** The context a queue handler receives — a batch of typed messages. */\nexport type QueueContext<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tmessages: InferStandardSchema<TMessage>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n\nexport type QueueHandler<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = (\n\tctx: QueueContext<TMessage, TServices, TLogger>,\n) => unknown | Promise<unknown>;\n"],"mappings":";;;;;;;;;;;;;;;AAwCA,IAAa,QAAb,cAKU,UAAyC;CA6CjC;CACA;CACA;CACS;CACA;CACA;CAET;CAEA;CArDjB,eAAe;CAEf,OAAO,QACN,KAC4D;EAC5D,OAAO,QACN,OACE,IAAmC,iBAAiB,QACpD,IAAkB,SAAA,8BACrB;CACD;;;;;;;;;CAUA;;;;;;;;;;;CAYA;;;;;CASA;CAEA,YACC,MACA,SACA,eACA,UAA2C,KAC3C,WAA+C,CAAC,GAChD,SAA2C,gBAE3C,WAEA,MAKA,aAAuB,CAAC,GACvB;EACD,MAAA,gCAEC,QACA,UACA,CAAC,GACD,KAAA,GACA,SACA,KAAA,GACA,KAAA,GACA,UACD;EA1BgB,KAAA,OAAA;EACA,KAAA,UAAA;EACA,KAAA,gBAAA;EACS,KAAA,UAAA;EACA,KAAA,WAAA;EACA,KAAA,SAAA;EAET,KAAA,YAAA;EAEA,KAAA,OAAA;EAmBhB,KAAK,KAAK,YAAY,IAAI;EAC1B,KAAK,gBAAgB,WAAW,KAAK,IAAI,2BAA2B;EAEpE,MAAM,SAAS,KAAK;EACpB,KAAK,UAAU;GACd,aAAa,WAAW,KAAK,EAAE;GAC/B,MAAM,SAAS,EAAE,aAAa;IAC7B,MAAM,EAAE,qBAAqB,UAC3B,QAAQ,SAAS,EAAE,kBAAkB,IAAI,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAC7D,MAAM;IAER,OAAO,UAAU,qBAChB,gBACD;GACD;EACD;CACD;;;;;;;;;CAUA,UAAyB;EACxB,OAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,UAAU,CAAC,KAAK,aAAa;GAC7B,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;GAQlC,QAAQ;IACP,IAAI,GAAG,KAAK,GAAG;IACf,SAAS,GAAG,KAAK,GAAG;IAGpB,cAAc,CAAC;GAChB;EACD,CACD;CACD;AACD"}
@@ -1,5 +1,4 @@
1
- const require_Construct = require("./Construct-yG9Sw-5p.cjs");
2
- const require_construct_interface = require("./construct-interface.cjs");
1
+ const require_Construct = require("./Construct-DmvXceVY.cjs");
3
2
  let _geekmidas_manifest = require("@geekmidas/manifest");
4
3
  let _geekmidas_logger_console = require("@geekmidas/logger/console");
5
4
  let _geekmidas_events = require("@geekmidas/events");
@@ -7,11 +6,12 @@ let _geekmidas_events = require("@geekmidas/events");
7
6
  /**
8
7
  * A queue worker — a point-to-point SQS-style queue and its single consumer.
9
8
  * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue
10
- * drains every message of its one `message` type. Build one with `q` (see
11
- * `QueueBuilder`); `gkm build` discovers it into the manifest's `queues` field.
9
+ * drains every message of its one `message` type. Build one from the worker
10
+ * that runs it — `worker.queue('Emails').message(schema).handle(…)` — and
11
+ * `gkm build` discovers it into the manifest's `queues` field.
12
12
  *
13
- * The producer side is {@link Queue.publisher} — a ready-to-inject `Service`
14
- * that any endpoint/function drops into `.services([...])` to send messages.
13
+ * Producers send to it by depending on it: `.dependsOn([emails])` makes
14
+ * `services.emails` the publisher.
15
15
  */
16
16
  var Queue = class extends require_Construct.Construct {
17
17
  name;
@@ -36,13 +36,23 @@ var Queue = class extends require_Construct.Construct {
36
36
  */
37
37
  id;
38
38
  /**
39
- * The producer's env key. Read by both {@link declare} and
40
- * {@link publisher}, so what the target publishes and what the producer
41
- * looks up cannot drift.
39
+ * The queue as a dependency — what `.dependsOn([emails])` dissolves into,
40
+ * reachable as `services.emails`.
41
+ *
42
+ * The producer: the queue's one consumer is the handler it was built with,
43
+ * so the only thing another construct can want from a queue is to send to
44
+ * it. It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and picks the transport
45
+ * from its protocol — `pgboss://` locally, `sqs://` deployed. A field
46
+ * assigned once, not a getter: services are cached by object identity.
47
+ */
48
+ service;
49
+ /**
50
+ * The producer's env key. Read by both {@link declare} and the service, so
51
+ * what the target publishes and what the producer looks up cannot drift.
42
52
  */
43
53
  connectionKey;
44
54
  constructor(name, handler, messageSchema, timeout = 3e4, services = [], logger = _geekmidas_logger_console.DEFAULT_LOGGER, batchSize, fifo, constructs = []) {
45
- super("dev.geekmidas.function.queue", logger, services, [], void 0, void 0, timeout, void 0, void 0, constructs);
55
+ super("dev.geekmidas.function.queue", logger, services, [], void 0, timeout, void 0, void 0, constructs);
46
56
  this.name = name;
47
57
  this.handler = handler;
48
58
  this.messageSchema = messageSchema;
@@ -53,6 +63,14 @@ var Queue = class extends require_Construct.Construct {
53
63
  this.fifo = fifo;
54
64
  this.id = (0, _geekmidas_manifest.canonicalId)(name);
55
65
  this.connectionKey = (0, _geekmidas_manifest.provideKey)(this.id, "publisherConnectionString");
66
+ const envVar = this.connectionKey;
67
+ this.service = {
68
+ serviceName: (0, _geekmidas_manifest.serviceKey)(this.id),
69
+ async register({ envParser }) {
70
+ const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
71
+ return _geekmidas_events.Publisher.fromConnectionString(connectionString);
72
+ }
73
+ };
56
74
  }
57
75
  /**
58
76
  * What this queue is in the manifest.
@@ -75,43 +93,6 @@ var Queue = class extends require_Construct.Construct {
75
93
  }
76
94
  }];
77
95
  }
78
- /**
79
- * The producer side — a `Service` exposing an `EventPublisher` typed to this
80
- * queue's message. Inject it via `.services([queue.publisher])`; the handler
81
- * then calls `services.<name>Publisher.publish([{ type, payload }])`.
82
- *
83
- * It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and builds the transport from
84
- * the URL protocol — `pgboss://` locally, `sqs://` deployed — so the same
85
- * code publishes to Postgres in dev and SQS in prod. Because it's a `Service`,
86
- * `Construct.getEnvironment()` sniffs it, so the env requirement flows into
87
- * the manifest and infra links exactly this queue with least privilege.
88
- */
89
- /**
90
- * The queue as a dependency — what `.dependsOn([emailsQueue])` dissolves
91
- * into, reachable as `services.emails`.
92
- *
93
- * It is the producer: a consumer is the worker written right here, so the
94
- * only thing another construct can want from a queue is the ability to send
95
- * to it. {@link publisher} is the same service under its older
96
- * `<name>Publisher` key, kept for `.services([queue.publisher])`.
97
- */
98
- get service() {
99
- const { register } = this.publisher;
100
- return {
101
- serviceName: (0, _geekmidas_manifest.serviceKey)(this.id),
102
- register
103
- };
104
- }
105
- get publisher() {
106
- const envVar = this.connectionKey;
107
- return require_construct_interface.derivedFrom({
108
- serviceName: `${this.name}Publisher`,
109
- async register({ envParser }) {
110
- const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
111
- return _geekmidas_events.Publisher.fromConnectionString(connectionString);
112
- }
113
- }, this);
114
- }
115
96
  };
116
97
  //#endregion
117
98
  Object.defineProperty(exports, "Queue", {
@@ -121,4 +102,4 @@ Object.defineProperty(exports, "Queue", {
121
102
  }
122
103
  });
123
104
 
124
- //# sourceMappingURL=Queue-B7yRXQmL.cjs.map
105
+ //# sourceMappingURL=Queue-Ckmudcm8.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queue-Ckmudcm8.cjs","names":["Construct","DEFAULT_LOGGER","canonicalId","provideKey","serviceKey","Publisher"],"sources":["../src/queue/Queue.ts"],"sourcesContent":["import {\n\ttype EventPublisher,\n\ttype EventPublisherConnectionString,\n\ttype PublishableMessage,\n\tPublisher,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport {\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\n/**\n * The wire message a queue carries: `{ type: <queue name>, payload: <message> }`.\n * The producer publishes this shape and the worker receives the `payload`s as\n * its `messages`. Typing `type` to the queue name keeps the publisher fully\n * typed and lets pg-boss (local) / SQS (deployed) route by name.\n */\nexport type QueueMessage<\n\tTName extends string,\n\tTMessage extends StandardSchemaV1,\n> = PublishableMessage<TName, InferStandardSchema<TMessage>>;\n\n/**\n * A queue worker — a point-to-point SQS-style queue and its single consumer.\n * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue\n * drains every message of its one `message` type. Build one from the worker\n * that runs it — `worker.queue('Emails').message(schema).handle(…)` — and\n * `gkm build` discovers it into the manifest's `queues` field.\n *\n * Producers send to it by depending on it: `.dependsOn([emails])` makes\n * `services.emails` the publisher.\n */\nexport class Queue<\n\tTName extends string = string,\n\tTMessage extends StandardSchemaV1 = StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> extends Construct<TLogger, undefined, TServices> {\n\t__IS_QUEUE__ = true;\n\n\tstatic isQueue(\n\t\tobj: unknown,\n\t): obj is Queue<string, StandardSchemaV1, Service[], Logger> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\t(obj as { __IS_QUEUE__?: boolean }).__IS_QUEUE__ === true &&\n\t\t\t\t(obj as Construct).type === ConstructType.Queue,\n\t\t);\n\t}\n\n\t/**\n\t * The canonical id this queue is declared under.\n\t *\n\t * Derived from the name rather than given separately, so `emails` and\n\t * `Emails` are one queue. The name stays what it was: it is the wire `type`\n\t * a producer sends and the worker subscribes to, and changing that would\n\t * silently orphan in-flight messages.\n\t */\n\treadonly id: string;\n\n\t/**\n\t * The queue as a dependency — what `.dependsOn([emails])` dissolves into,\n\t * reachable as `services.emails`.\n\t *\n\t * The producer: the queue's one consumer is the handler it was built with,\n\t * so the only thing another construct can want from a queue is to send to\n\t * it. It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and picks the transport\n\t * from its protocol — `pgboss://` locally, `sqs://` deployed. A field\n\t * assigned once, not a getter: services are cached by object identity.\n\t */\n\treadonly service: Service<\n\t\tUncapitalize<TName>,\n\t\tEventPublisher<QueueMessage<TName, TMessage>>\n\t>;\n\n\t/**\n\t * The producer's env key. Read by both {@link declare} and the service, so\n\t * what the target publishes and what the producer looks up cannot drift.\n\t */\n\tprivate readonly connectionKey: string;\n\n\tconstructor(\n\t\tpublic readonly name: TName,\n\t\tpublic readonly handler: QueueHandler<TMessage, TServices, TLogger>,\n\t\tpublic readonly messageSchema: TMessage,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\t/** SQS event-source batch size (deployed). */\n\t\tpublic readonly batchSize?: number,\n\t\t/** Whether the queue is FIFO (deployed). */\n\t\tpublic readonly fifo?: boolean,\n\t\t/**\n\t\t * The construct ids the *worker* `.dependsOn()` named — last, so no\n\t\t * existing positional argument moves.\n\t\t */\n\t\tconstructs: string[] = [],\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Queue,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tundefined,\n\t\t\ttimeout,\n\t\t\tundefined, // memorySize\n\t\t\tundefined, // auditorStorageService\n\t\t\tconstructs,\n\t\t);\n\n\t\tthis.id = canonicalId(name);\n\t\tthis.connectionKey = provideKey(this.id, 'publisherConnectionString');\n\n\t\tconst envVar = this.connectionKey;\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(this.id) as Uncapitalize<TName>,\n\t\t\tasync register({ envParser }) {\n\t\t\t\tconst { connectionString } = envParser\n\t\t\t\t\t.create((get) => ({ connectionString: get(envVar).string() }))\n\t\t\t\t\t.parse();\n\n\t\t\t\treturn Publisher.fromConnectionString<QueueMessage<TName, TMessage>>(\n\t\t\t\t\tconnectionString as EventPublisherConnectionString,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * What this queue is in the manifest.\n\t *\n\t * A queue is a resource, not a handler: the worker is reached *through* it,\n\t * so the declaration carries the producer's key and nothing about the code\n\t * that drains it. The local target reads this to know which broker has to be\n\t * running and what connection string to inject.\n\t */\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'queue',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.connectionKey],\n\t\t\t\t...(this.fifo ? { fifo: true } : {}),\n\t\t\t\t// Nested rather than a sibling node, because position carries the\n\t\t\t\t// trigger: this handler is reached by messages on this queue and\n\t\t\t\t// by nothing else, so there is no `trigger` field to keep in step.\n\t\t\t\t//\n\t\t\t\t// `handler` is the export name; which directory the build wrote it\n\t\t\t\t// to is the target's business, and a path with a cloud in it does\n\t\t\t\t// not belong in a neutral declaration.\n\t\t\t\tworker: {\n\t\t\t\t\tid: `${this.id}Worker`,\n\t\t\t\t\thandler: `${this.id}.handler`,\n\t\t\t\t\t// Filled by the build from what the worker declared. Empty is a\n\t\t\t\t\t// stated gap, not a claim that it reaches nothing.\n\t\t\t\t\tdependencies: [],\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t}\n}\n\n/** The context a queue handler receives — a batch of typed messages. */\nexport type QueueContext<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tmessages: InferStandardSchema<TMessage>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n\nexport type QueueHandler<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = (\n\tctx: QueueContext<TMessage, TServices, TLogger>,\n) => unknown | Promise<unknown>;\n"],"mappings":";;;;;;;;;;;;;;;AAwCA,IAAa,QAAb,cAKUA,kBAAAA,UAAyC;CA6CjC;CACA;CACA;CACS;CACA;CACA;CAET;CAEA;CArDjB,eAAe;CAEf,OAAO,QACN,KAC4D;EAC5D,OAAO,QACN,OACE,IAAmC,iBAAiB,QACpD,IAAkB,SAAA,8BACrB;CACD;;;;;;;;;CAUA;;;;;;;;;;;CAYA;;;;;CASA;CAEA,YACC,MACA,SACA,eACA,UAA2C,KAC3C,WAA+C,CAAC,GAChD,SAA2CC,0BAAAA,gBAE3C,WAEA,MAKA,aAAuB,CAAC,GACvB;EACD,MAAA,gCAEC,QACA,UACA,CAAC,GACD,KAAA,GACA,SACA,KAAA,GACA,KAAA,GACA,UACD;EA1BgB,KAAA,OAAA;EACA,KAAA,UAAA;EACA,KAAA,gBAAA;EACS,KAAA,UAAA;EACA,KAAA,WAAA;EACA,KAAA,SAAA;EAET,KAAA,YAAA;EAEA,KAAA,OAAA;EAmBhB,KAAK,MAAA,GAAKC,oBAAAA,YAAAA,CAAY,IAAI;EAC1B,KAAK,iBAAA,GAAgBC,oBAAAA,WAAAA,CAAW,KAAK,IAAI,2BAA2B;EAEpE,MAAM,SAAS,KAAK;EACpB,KAAK,UAAU;GACd,cAAA,GAAaC,oBAAAA,WAAAA,CAAW,KAAK,EAAE;GAC/B,MAAM,SAAS,EAAE,aAAa;IAC7B,MAAM,EAAE,qBAAqB,UAC3B,QAAQ,SAAS,EAAE,kBAAkB,IAAI,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAC7D,MAAM;IAER,OAAOC,kBAAAA,UAAU,qBAChB,gBACD;GACD;EACD;CACD;;;;;;;;;CAUA,UAAyB;EACxB,OAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,UAAU,CAAC,KAAK,aAAa;GAC7B,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;GAQlC,QAAQ;IACP,IAAI,GAAG,KAAK,GAAG;IACf,SAAS,GAAG,KAAK,GAAG;IAGpB,cAAc,CAAC;GAChB;EACD,CACD;CACD;AACD"}
@@ -1,9 +1,9 @@
1
1
  import { t as StandardSchemaV1 } from "./index-CeEtxDmK.cjs";
2
- import { t as Construct } from "./Construct-DTqYvkPG.cjs";
3
- import { EventPublisher, PublishableMessage } from "@geekmidas/events";
2
+ import { t as Construct } from "./Construct-BQALFCh2.cjs";
4
3
  import { Logger } from "@geekmidas/logger";
5
4
  import { InferStandardSchema } from "@geekmidas/schema";
6
5
  import { Service, ServiceRecord } from "@geekmidas/services";
6
+ import { EventPublisher, PublishableMessage } from "@geekmidas/events";
7
7
  import { Declaration } from "@geekmidas/manifest";
8
8
  //#region src/queue/Queue.d.ts
9
9
  /**
@@ -16,13 +16,14 @@ type QueueMessage<TName extends string, TMessage extends StandardSchemaV1> = Pub
16
16
  /**
17
17
  * A queue worker — a point-to-point SQS-style queue and its single consumer.
18
18
  * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue
19
- * drains every message of its one `message` type. Build one with `q` (see
20
- * `QueueBuilder`); `gkm build` discovers it into the manifest's `queues` field.
19
+ * drains every message of its one `message` type. Build one from the worker
20
+ * that runs it — `worker.queue('Emails').message(schema).handle(…)` — and
21
+ * `gkm build` discovers it into the manifest's `queues` field.
21
22
  *
22
- * The producer side is {@link Queue.publisher} — a ready-to-inject `Service`
23
- * that any endpoint/function drops into `.services([...])` to send messages.
23
+ * Producers send to it by depending on it: `.dependsOn([emails])` makes
24
+ * `services.emails` the publisher.
24
25
  */
25
- declare class Queue<TName extends string = string, TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger> extends Construct<TLogger, string, undefined, undefined, TServices> {
26
+ declare class Queue<TName extends string = string, TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger> extends Construct<TLogger, undefined, TServices> {
26
27
  readonly name: TName;
27
28
  readonly handler: QueueHandler<TMessage, TServices, TLogger>;
28
29
  readonly messageSchema: TMessage;
@@ -45,9 +46,19 @@ declare class Queue<TName extends string = string, TMessage extends StandardSche
45
46
  */
46
47
  readonly id: string;
47
48
  /**
48
- * The producer's env key. Read by both {@link declare} and
49
- * {@link publisher}, so what the target publishes and what the producer
50
- * looks up cannot drift.
49
+ * The queue as a dependency — what `.dependsOn([emails])` dissolves into,
50
+ * reachable as `services.emails`.
51
+ *
52
+ * The producer: the queue's one consumer is the handler it was built with,
53
+ * so the only thing another construct can want from a queue is to send to
54
+ * it. It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and picks the transport
55
+ * from its protocol — `pgboss://` locally, `sqs://` deployed. A field
56
+ * assigned once, not a getter: services are cached by object identity.
57
+ */
58
+ readonly service: Service<Uncapitalize<TName>, EventPublisher<QueueMessage<TName, TMessage>>>;
59
+ /**
60
+ * The producer's env key. Read by both {@link declare} and the service, so
61
+ * what the target publishes and what the producer looks up cannot drift.
51
62
  */
52
63
  private readonly connectionKey;
53
64
  constructor(name: TName, handler: QueueHandler<TMessage, TServices, TLogger>, messageSchema: TMessage, timeout?: number, services?: TServices, logger?: TLogger,
@@ -69,28 +80,6 @@ declare class Queue<TName extends string = string, TMessage extends StandardSche
69
80
  * running and what connection string to inject.
70
81
  */
71
82
  declare(): Declaration[];
72
- /**
73
- * The producer side — a `Service` exposing an `EventPublisher` typed to this
74
- * queue's message. Inject it via `.services([queue.publisher])`; the handler
75
- * then calls `services.<name>Publisher.publish([{ type, payload }])`.
76
- *
77
- * It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and builds the transport from
78
- * the URL protocol — `pgboss://` locally, `sqs://` deployed — so the same
79
- * code publishes to Postgres in dev and SQS in prod. Because it's a `Service`,
80
- * `Construct.getEnvironment()` sniffs it, so the env requirement flows into
81
- * the manifest and infra links exactly this queue with least privilege.
82
- */
83
- /**
84
- * The queue as a dependency — what `.dependsOn([emailsQueue])` dissolves
85
- * into, reachable as `services.emails`.
86
- *
87
- * It is the producer: a consumer is the worker written right here, so the
88
- * only thing another construct can want from a queue is the ability to send
89
- * to it. {@link publisher} is the same service under its older
90
- * `<name>Publisher` key, kept for `.services([queue.publisher])`.
91
- */
92
- get service(): Service<Uncapitalize<TName>, EventPublisher<QueueMessage<TName, TMessage>>>;
93
- get publisher(): Service<`${TName}Publisher`, EventPublisher<QueueMessage<TName, TMessage>>>;
94
83
  }
95
84
  /** The context a queue handler receives — a batch of typed messages. */
96
85
  type QueueContext<TMessage extends StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger> = {
@@ -101,4 +90,4 @@ type QueueContext<TMessage extends StandardSchemaV1, TServices extends Service[]
101
90
  type QueueHandler<TMessage extends StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger> = (ctx: QueueContext<TMessage, TServices, TLogger>) => unknown | Promise<unknown>;
102
91
  //#endregion
103
92
  export { QueueMessage as i, QueueContext as n, QueueHandler as r, Queue as t };
104
- //# sourceMappingURL=Queue-Bhzi2WQC.d.cts.map
93
+ //# sourceMappingURL=Queue-CpQIGB_2.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queue-CpQIGB_2.d.cts","names":[],"sources":["../src/queue/Queue.ts"],"mappings":";;;;;;;;;;;;;;KAyBY,aACX,sBACA,iBAAiB,oBACd,mBAAmB,OAAO,oBAAoB;;;;;;;;;;;cAYrC,MACZ,+BACA,iBAAiB,mBAAmB,kBACpC,kBAAkB,gBAClB,gBAAgB,SAAS,gBAChB,UAAU,oBAAoB;WA6CtB,MAAM;WACN,SAAS,aAAa,UAAU,WAAW;WAC3C,eAAe;WACN;WACA,UAAU;WACV,QAAQ;;WAEjB;;WAEA;EArDjB;SAEO,QACN,eACE,OAAO,cAAc,kBAAkB,WAAW;;;;;;;;;WAgB5C;;;;;;;;;;;WAYA,SAAS,QACjB,aAAa,QACb,eAAe,aAAa,OAAO;;;;;mBAOnB;EAEjB,YACiB,MAAM,OACN,SAAS,aAAa,UAAU,WAAW,UAC3C,eAAe,UACN,kBACA,WAAU,WACV,SAAQ,SAEjB;;EAAA,gCAEA;;EAAA,4BAKhB;;;;;EAAA;;;;;;;;;EAwCD,WAAW;;;KA2BA,aACX,iBAAiB,kBACjB,kBAAkB,gBAClB,gBAAgB,SAAS;EAEzB,UAAU,oBAAoB;EAC9B,UAAU,cAAc;EACxB,QAAQ;;KAGG,aACX,iBAAiB,kBACjB,kBAAkB,gBAClB,gBAAgB,SAAS,WAEzB,KAAK,aAAa,UAAU,WAAW,uBACzB"}