@geekmidas/constructs 10.0.0-alpha.12 → 10.0.0-alpha.120

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 (454) hide show
  1. package/README.md +222 -158
  2. package/dist/Construct-B7AXn0xH.d.mts +230 -0
  3. package/dist/Construct-B7AXn0xH.d.mts.map +1 -0
  4. package/dist/Construct-CFW0zjdD.d.cts +230 -0
  5. package/dist/Construct-CFW0zjdD.d.cts.map +1 -0
  6. package/dist/{Construct-BD5neF7w.mjs → Construct-CKUA-CTA.mjs} +35 -35
  7. package/dist/Construct-CKUA-CTA.mjs.map +1 -0
  8. package/dist/{Construct-CyS3RpTL.cjs → Construct-DEOVauyA.cjs} +55 -49
  9. package/dist/Construct-DEOVauyA.cjs.map +1 -0
  10. package/dist/{Cron-DmQ8vQ4b.d.cts → Cron-bdGRSROY.d.cts} +15 -9
  11. package/dist/Cron-bdGRSROY.d.cts.map +1 -0
  12. package/dist/{Cron-dh4rUgib.d.mts → Cron-i4Uetezh.d.mts} +15 -9
  13. package/dist/Cron-i4Uetezh.d.mts.map +1 -0
  14. package/dist/CronBuilder-9H4BnD6W.d.mts +47 -0
  15. package/dist/CronBuilder-9H4BnD6W.d.mts.map +1 -0
  16. package/dist/{CronBuilder-Da0C0edR.cjs → CronBuilder-BXTG10u5.cjs} +47 -31
  17. package/dist/CronBuilder-BXTG10u5.cjs.map +1 -0
  18. package/dist/CronBuilder-B_24LZpn.d.cts +47 -0
  19. package/dist/CronBuilder-B_24LZpn.d.cts.map +1 -0
  20. package/dist/{CronBuilder-CYKT5RiO.mjs → CronBuilder-D3sF9tS_.mjs} +37 -21
  21. package/dist/CronBuilder-D3sF9tS_.mjs.map +1 -0
  22. package/dist/{Endpoint-BjWKinFA.d.mts → Endpoint-CeFkSwh5.d.mts} +129 -99
  23. package/dist/Endpoint-CeFkSwh5.d.mts.map +1 -0
  24. package/dist/{Endpoint-dav89W6-.d.cts → Endpoint-DgrpG15P.d.cts} +127 -97
  25. package/dist/Endpoint-DgrpG15P.d.cts.map +1 -0
  26. package/dist/{Endpoint-DCQPMdUX.mjs → Endpoint-gPXhHKhJ.mjs} +208 -100
  27. package/dist/Endpoint-gPXhHKhJ.mjs.map +1 -0
  28. package/dist/{Endpoint-DcWXE-SZ.cjs → Endpoint-yhR2T2Wt.cjs} +248 -122
  29. package/dist/Endpoint-yhR2T2Wt.cjs.map +1 -0
  30. package/dist/{EndpointFactory-CdWB7wPw.cjs → EndpointFactory-CSrAyazj.cjs} +361 -112
  31. package/dist/EndpointFactory-CSrAyazj.cjs.map +1 -0
  32. package/dist/{index-lAO9egTb.d.mts → EndpointFactory-Cc863XJS.d.cts} +190 -136
  33. package/dist/EndpointFactory-Cc863XJS.d.cts.map +1 -0
  34. package/dist/{index-Bd5FqCoe.d.cts → EndpointFactory-Dbw9ugkX.d.mts} +189 -135
  35. package/dist/EndpointFactory-Dbw9ugkX.d.mts.map +1 -0
  36. package/dist/{EndpointFactory-CjV8F_lJ.mjs → EndpointFactory-c2ZugGig.mjs} +283 -76
  37. package/dist/EndpointFactory-c2ZugGig.mjs.map +1 -0
  38. package/dist/Function-B0uZhZnU.d.cts +76 -0
  39. package/dist/Function-B0uZhZnU.d.cts.map +1 -0
  40. package/dist/Function-B_9R7Zy1.d.mts +76 -0
  41. package/dist/Function-B_9R7Zy1.d.mts.map +1 -0
  42. package/dist/{HonoEndpointAdaptor-DtL9j19R.cjs → HonoEndpointAdaptor-CN1jjUBJ.cjs} +115 -71
  43. package/dist/HonoEndpointAdaptor-CN1jjUBJ.cjs.map +1 -0
  44. package/dist/{HonoEndpointAdaptor-P1ahhZHu.mjs → HonoEndpointAdaptor-euH1oSdY.mjs} +105 -64
  45. package/dist/HonoEndpointAdaptor-euH1oSdY.mjs.map +1 -0
  46. package/dist/{Queue-D7ZuwBhy.d.cts → Queue-B-dDXyjF.d.mts} +48 -48
  47. package/dist/Queue-B-dDXyjF.d.mts.map +1 -0
  48. package/dist/Queue-BhuofM3k.cjs +109 -0
  49. package/dist/Queue-BhuofM3k.cjs.map +1 -0
  50. package/dist/{Queue-gVGfi2Yk.d.mts → Queue-JbIjVtTf.d.cts} +49 -49
  51. package/dist/Queue-JbIjVtTf.d.cts.map +1 -0
  52. package/dist/Queue-cmhqEBOB.mjs +104 -0
  53. package/dist/Queue-cmhqEBOB.mjs.map +1 -0
  54. package/dist/QueueBuilder-48W-q8In.d.mts +75 -0
  55. package/dist/QueueBuilder-48W-q8In.d.mts.map +1 -0
  56. package/dist/QueueBuilder-DXu1qxT1.mjs +118 -0
  57. package/dist/QueueBuilder-DXu1qxT1.mjs.map +1 -0
  58. package/dist/QueueBuilder-DdU2klPu.cjs +135 -0
  59. package/dist/QueueBuilder-DdU2klPu.cjs.map +1 -0
  60. package/dist/QueueBuilder-MfpkJ3R9.d.cts +75 -0
  61. package/dist/QueueBuilder-MfpkJ3R9.d.cts.map +1 -0
  62. package/dist/{Subscriber-2mEi0ImH.d.cts → Subscriber-CEt7kHkc.d.cts} +29 -20
  63. package/dist/Subscriber-CEt7kHkc.d.cts.map +1 -0
  64. package/dist/{Subscriber-xTJ9ayPN.d.mts → Subscriber-dsxc5LKa.d.mts} +29 -20
  65. package/dist/Subscriber-dsxc5LKa.d.mts.map +1 -0
  66. package/dist/SubscriberBuilder-BRa_nrmH.d.cts +67 -0
  67. package/dist/SubscriberBuilder-BRa_nrmH.d.cts.map +1 -0
  68. package/dist/SubscriberBuilder-D9bkrYzH.d.mts +67 -0
  69. package/dist/SubscriberBuilder-D9bkrYzH.d.mts.map +1 -0
  70. package/dist/{SubscriberBuilder-BjkbeT9l.mjs → SubscriberBuilder-DRXfxWn_.mjs} +50 -24
  71. package/dist/SubscriberBuilder-DRXfxWn_.mjs.map +1 -0
  72. package/dist/{SubscriberBuilder-4OPehf2R.cjs → SubscriberBuilder-M2EAgQhC.cjs} +61 -36
  73. package/dist/SubscriberBuilder-M2EAgQhC.cjs.map +1 -0
  74. package/dist/Topic-D2R0r24C.mjs +99 -0
  75. package/dist/Topic-D2R0r24C.mjs.map +1 -0
  76. package/dist/Topic-DwS3QO0m.cjs +104 -0
  77. package/dist/Topic-DwS3QO0m.cjs.map +1 -0
  78. package/dist/adaptors/aws.cjs +200 -246
  79. package/dist/adaptors/aws.cjs.map +1 -1
  80. package/dist/adaptors/aws.d.cts +58 -62
  81. package/dist/adaptors/aws.d.cts.map +1 -1
  82. package/dist/adaptors/aws.d.mts +59 -63
  83. package/dist/adaptors/aws.d.mts.map +1 -1
  84. package/dist/adaptors/aws.mjs +171 -219
  85. package/dist/adaptors/aws.mjs.map +1 -1
  86. package/dist/adaptors/hono.cjs +3 -10
  87. package/dist/adaptors/hono.d.cts +7 -16
  88. package/dist/adaptors/hono.d.cts.map +1 -1
  89. package/dist/adaptors/hono.d.mts +9 -18
  90. package/dist/adaptors/hono.d.mts.map +1 -1
  91. package/dist/adaptors/hono.mjs +2 -10
  92. package/dist/adaptors/testing.cjs +765 -99
  93. package/dist/adaptors/testing.cjs.map +1 -1
  94. package/dist/adaptors/testing.d.cts +351 -54
  95. package/dist/adaptors/testing.d.cts.map +1 -1
  96. package/dist/adaptors/testing.d.mts +351 -54
  97. package/dist/adaptors/testing.d.mts.map +1 -1
  98. package/dist/adaptors/testing.mjs +726 -78
  99. package/dist/adaptors/testing.mjs.map +1 -1
  100. package/dist/auth-BMCJN30Y.d.cts +268 -0
  101. package/dist/auth-BMCJN30Y.d.cts.map +1 -0
  102. package/dist/auth-D_0788uW.d.mts +268 -0
  103. package/dist/auth-D_0788uW.d.mts.map +1 -0
  104. package/dist/auth.cjs +301 -33
  105. package/dist/auth.cjs.map +1 -1
  106. package/dist/auth.d.cts +2 -108
  107. package/dist/auth.d.mts +2 -108
  108. package/dist/auth.mjs +289 -27
  109. package/dist/auth.mjs.map +1 -1
  110. package/dist/{cache-BrRz3fEB.d.mts → cache-5QZzh5Er.d.mts} +3 -6
  111. package/dist/cache-5QZzh5Er.d.mts.map +1 -0
  112. package/dist/{cache-BtZY_tHe.d.cts → cache-DnGDGly3.d.cts} +3 -6
  113. package/dist/cache-DnGDGly3.d.cts.map +1 -0
  114. package/dist/cache.cjs +68 -2
  115. package/dist/cache.cjs.map +1 -0
  116. package/dist/cache.d.cts +1 -2
  117. package/dist/cache.d.mts +1 -2
  118. package/dist/cache.mjs +67 -2
  119. package/dist/cache.mjs.map +1 -0
  120. package/dist/cipher-C1lEFX63.mjs +225 -0
  121. package/dist/cipher-C1lEFX63.mjs.map +1 -0
  122. package/dist/cipher-CVxfwLjk.cjs +332 -0
  123. package/dist/cipher-CVxfwLjk.cjs.map +1 -0
  124. package/dist/cipher-DSDxPRIp.d.cts +106 -0
  125. package/dist/cipher-DSDxPRIp.d.cts.map +1 -0
  126. package/dist/cipher-DSDxPRIp.d.mts +106 -0
  127. package/dist/cipher-DSDxPRIp.d.mts.map +1 -0
  128. package/dist/{clone-DblgEZZa.mjs → clone-EKNovYHu.mjs} +3 -3
  129. package/dist/clone-EKNovYHu.mjs.map +1 -0
  130. package/dist/{clone-Dy0cR2SZ.cjs → clone-UGJpvQnL.cjs} +7 -8
  131. package/dist/clone-UGJpvQnL.cjs.map +1 -0
  132. package/dist/{construct-interface-D9d4Gm4p.d.cts → construct-interface-B1AfqRl4.d.cts} +42 -11
  133. package/dist/construct-interface-B1AfqRl4.d.cts.map +1 -0
  134. package/dist/{construct-interface-g5GM5pwR.d.mts → construct-interface-ZvYQbivO.d.mts} +42 -11
  135. package/dist/construct-interface-ZvYQbivO.d.mts.map +1 -0
  136. package/dist/construct-interface.cjs +113 -7
  137. package/dist/construct-interface.cjs.map +1 -0
  138. package/dist/construct-interface.d.cts +2 -2
  139. package/dist/construct-interface.d.mts +2 -2
  140. package/dist/construct-interface.mjs +106 -2
  141. package/dist/construct-interface.mjs.map +1 -0
  142. package/dist/credential-DYymbp_7.cjs +257 -0
  143. package/dist/credential-DYymbp_7.cjs.map +1 -0
  144. package/dist/credential-DfSAOOdY.mjs +222 -0
  145. package/dist/credential-DfSAOOdY.mjs.map +1 -0
  146. package/dist/credential.cjs +8 -96
  147. package/dist/credential.d.cts +2 -61
  148. package/dist/credential.d.mts +2 -61
  149. package/dist/credential.mjs +2 -94
  150. package/dist/crons/index.cjs +129 -7
  151. package/dist/crons/index.cjs.map +1 -1
  152. package/dist/crons/index.d.cts +45 -11
  153. package/dist/crons/index.d.cts.map +1 -1
  154. package/dist/crons/index.d.mts +45 -11
  155. package/dist/crons/index.d.mts.map +1 -1
  156. package/dist/crons/index.mjs +127 -8
  157. package/dist/crons/index.mjs.map +1 -1
  158. package/dist/database/kysely.cjs +4 -181
  159. package/dist/database/kysely.d.cts +2 -152
  160. package/dist/database/kysely.d.mts +2 -152
  161. package/dist/database/kysely.mjs +2 -180
  162. package/dist/email.cjs +25 -12
  163. package/dist/email.cjs.map +1 -1
  164. package/dist/email.d.cts +3 -7
  165. package/dist/email.d.cts.map +1 -1
  166. package/dist/email.d.mts +4 -8
  167. package/dist/email.d.mts.map +1 -1
  168. package/dist/email.mjs +16 -3
  169. package/dist/email.mjs.map +1 -1
  170. package/dist/encryption/kms.cjs +95 -0
  171. package/dist/encryption/kms.cjs.map +1 -0
  172. package/dist/encryption/kms.d.cts +7 -0
  173. package/dist/encryption/kms.d.cts.map +1 -0
  174. package/dist/encryption/kms.d.mts +7 -0
  175. package/dist/encryption/kms.d.mts.map +1 -0
  176. package/dist/encryption/kms.mjs +93 -0
  177. package/dist/encryption/kms.mjs.map +1 -0
  178. package/dist/encryption.cjs +116 -0
  179. package/dist/encryption.cjs.map +1 -0
  180. package/dist/encryption.d.cts +37 -0
  181. package/dist/encryption.d.cts.map +1 -0
  182. package/dist/encryption.d.mts +37 -0
  183. package/dist/encryption.d.mts.map +1 -0
  184. package/dist/encryption.mjs +101 -0
  185. package/dist/encryption.mjs.map +1 -0
  186. package/dist/endpoints/index.cjs +27 -16
  187. package/dist/endpoints/index.d.cts +105 -7
  188. package/dist/endpoints/index.d.cts.map +1 -0
  189. package/dist/endpoints/index.d.mts +105 -7
  190. package/dist/endpoints/index.d.mts.map +1 -0
  191. package/dist/endpoints/index.mjs +6 -10
  192. package/dist/expire-C586zznE.d.cts +38 -0
  193. package/dist/expire-C586zznE.d.cts.map +1 -0
  194. package/dist/expire-C586zznE.d.mts +38 -0
  195. package/dist/expire-C586zznE.d.mts.map +1 -0
  196. package/dist/expire-CieftS01.cjs +67 -0
  197. package/dist/expire-CieftS01.cjs.map +1 -0
  198. package/dist/expire-CpzUAfr9.mjs +50 -0
  199. package/dist/expire-CpzUAfr9.mjs.map +1 -0
  200. package/dist/external-api.cjs +106 -0
  201. package/dist/external-api.cjs.map +1 -0
  202. package/dist/external-api.d.cts +2 -0
  203. package/dist/external-api.d.mts +2 -0
  204. package/dist/external-api.mjs +103 -0
  205. package/dist/external-api.mjs.map +1 -0
  206. package/dist/fake-B7rvi4Qp.d.cts +201 -0
  207. package/dist/fake-B7rvi4Qp.d.cts.map +1 -0
  208. package/dist/fake-JXbkdao8.d.mts +201 -0
  209. package/dist/fake-JXbkdao8.d.mts.map +1 -0
  210. package/dist/file-server.cjs +66 -11
  211. package/dist/file-server.cjs.map +1 -1
  212. package/dist/file-server.d.cts +25 -10
  213. package/dist/file-server.d.cts.map +1 -1
  214. package/dist/file-server.d.mts +25 -10
  215. package/dist/file-server.d.mts.map +1 -1
  216. package/dist/file-server.mjs +58 -4
  217. package/dist/file-server.mjs.map +1 -1
  218. package/dist/functions/index.cjs +3 -6
  219. package/dist/functions/index.d.cts +3 -4
  220. package/dist/functions/index.d.mts +3 -4
  221. package/dist/functions/index.mjs +2 -6
  222. package/dist/{functions-14lpEFL4.mjs → functions-CTI-hDem.mjs} +376 -238
  223. package/dist/{functions-14lpEFL4.mjs.map → functions-CTI-hDem.mjs.map} +1 -1
  224. package/dist/{functions-i_la-N5r.cjs → functions-D7O5SGVc.cjs} +414 -264
  225. package/dist/functions-D7O5SGVc.cjs.map +1 -0
  226. package/dist/index-Cd2w-DRL.d.cts +115 -0
  227. package/dist/index-Cd2w-DRL.d.cts.map +1 -0
  228. package/dist/index-DdRjYhiJ.d.cts +119 -0
  229. package/dist/index-DdRjYhiJ.d.cts.map +1 -0
  230. package/dist/index-DdRjYhiJ.d.mts +119 -0
  231. package/dist/index-DdRjYhiJ.d.mts.map +1 -0
  232. package/dist/index-aBIcAiH5.d.mts +115 -0
  233. package/dist/index-aBIcAiH5.d.mts.map +1 -0
  234. package/dist/index.cjs +6 -3
  235. package/dist/index.d.cts +27 -4
  236. package/dist/index.d.cts.map +1 -0
  237. package/dist/index.d.mts +27 -4
  238. package/dist/index.d.mts.map +1 -0
  239. package/dist/index.mjs +3 -3
  240. package/dist/kysely-BHYV-WC-.d.cts +216 -0
  241. package/dist/kysely-BHYV-WC-.d.cts.map +1 -0
  242. package/dist/kysely-CAW3QSqp.d.mts +216 -0
  243. package/dist/kysely-CAW3QSqp.d.mts.map +1 -0
  244. package/dist/kysely-Cs4uPO8k.mjs +371 -0
  245. package/dist/kysely-Cs4uPO8k.mjs.map +1 -0
  246. package/dist/kysely-CukArHJ0.cjs +384 -0
  247. package/dist/kysely-CukArHJ0.cjs.map +1 -0
  248. package/dist/{telemetry-C3L0iS28.d.cts → lambdaTelemetry-8vnmVZQ5.d.cts} +3 -6
  249. package/dist/lambdaTelemetry-8vnmVZQ5.d.cts.map +1 -0
  250. package/dist/{telemetry-D7bVFLGi.d.mts → lambdaTelemetry-8vnmVZQ5.d.mts} +3 -6
  251. package/dist/lambdaTelemetry-8vnmVZQ5.d.mts.map +1 -0
  252. package/dist/mobile-app.cjs +74 -0
  253. package/dist/mobile-app.cjs.map +1 -0
  254. package/dist/mobile-app.d.cts +73 -0
  255. package/dist/mobile-app.d.cts.map +1 -0
  256. package/dist/mobile-app.d.mts +73 -0
  257. package/dist/mobile-app.d.mts.map +1 -0
  258. package/dist/mobile-app.mjs +73 -0
  259. package/dist/mobile-app.mjs.map +1 -0
  260. package/dist/object-storage.cjs +26 -11
  261. package/dist/object-storage.cjs.map +1 -1
  262. package/dist/object-storage.d.cts +12 -7
  263. package/dist/object-storage.d.cts.map +1 -1
  264. package/dist/object-storage.d.mts +12 -7
  265. package/dist/object-storage.d.mts.map +1 -1
  266. package/dist/object-storage.mjs +18 -5
  267. package/dist/object-storage.mjs.map +1 -1
  268. package/dist/queue/index.cjs +6 -189
  269. package/dist/queue/index.d.cts +3 -60
  270. package/dist/queue/index.d.mts +3 -60
  271. package/dist/queue/index.mjs +3 -186
  272. package/dist/random-password.cjs +86 -0
  273. package/dist/random-password.cjs.map +1 -0
  274. package/dist/random-password.d.cts +30 -0
  275. package/dist/random-password.d.cts.map +1 -0
  276. package/dist/random-password.d.mts +30 -0
  277. package/dist/random-password.d.mts.map +1 -0
  278. package/dist/random-password.mjs +84 -0
  279. package/dist/random-password.mjs.map +1 -0
  280. package/dist/{lazyAccessors-BoJN3SMd.mjs → readRequestBody-BTIl3k-D.mjs} +117 -60
  281. package/dist/readRequestBody-BTIl3k-D.mjs.map +1 -0
  282. package/dist/readRequestBody-Dej_L3c4.cjs +342 -0
  283. package/dist/readRequestBody-Dej_L3c4.cjs.map +1 -0
  284. package/dist/requestLogger-BZcXwdBs.cjs +207 -0
  285. package/dist/requestLogger-BZcXwdBs.cjs.map +1 -0
  286. package/dist/requestLogger-pA4gi3E1.mjs +178 -0
  287. package/dist/requestLogger-pA4gi3E1.mjs.map +1 -0
  288. package/dist/rest-api.cjs +90 -59
  289. package/dist/rest-api.cjs.map +1 -1
  290. package/dist/rest-api.d.cts +70 -42
  291. package/dist/rest-api.d.cts.map +1 -1
  292. package/dist/rest-api.d.mts +70 -42
  293. package/dist/rest-api.d.mts.map +1 -1
  294. package/dist/rest-api.mjs +82 -51
  295. package/dist/rest-api.mjs.map +1 -1
  296. package/dist/{chunk-DWy1uDak.cjs → rolldown-runtime-y5ARvAq5.cjs} +14 -18
  297. package/dist/runSubscriber-BHvJ8POr.mjs +109 -0
  298. package/dist/runSubscriber-BHvJ8POr.mjs.map +1 -0
  299. package/dist/runSubscriber-D8nLXIv1.cjs +126 -0
  300. package/dist/runSubscriber-D8nLXIv1.cjs.map +1 -0
  301. package/dist/shutdown-BMJmAhSt.cjs +38 -0
  302. package/dist/shutdown-BMJmAhSt.cjs.map +1 -0
  303. package/dist/shutdown-C7xa8x9S.mjs +27 -0
  304. package/dist/shutdown-C7xa8x9S.mjs.map +1 -0
  305. package/dist/site.cjs +33 -7
  306. package/dist/site.cjs.map +1 -1
  307. package/dist/site.d.cts +17 -7
  308. package/dist/site.d.cts.map +1 -1
  309. package/dist/site.d.mts +17 -7
  310. package/dist/site.d.mts.map +1 -1
  311. package/dist/site.mjs +29 -3
  312. package/dist/site.mjs.map +1 -1
  313. package/dist/stages-BSCF19o2.d.cts +56 -0
  314. package/dist/stages-BSCF19o2.d.cts.map +1 -0
  315. package/dist/stages-BSCF19o2.d.mts +56 -0
  316. package/dist/stages-BSCF19o2.d.mts.map +1 -0
  317. package/dist/subscribers/index.cjs +118 -6
  318. package/dist/subscribers/index.cjs.map +1 -0
  319. package/dist/subscribers/index.d.cts +51 -6
  320. package/dist/subscribers/index.d.cts.map +1 -0
  321. package/dist/subscribers/index.d.mts +51 -6
  322. package/dist/subscribers/index.d.mts.map +1 -0
  323. package/dist/subscribers/index.mjs +115 -5
  324. package/dist/subscribers/index.mjs.map +1 -0
  325. package/dist/surfaceEnv-CNimK76p.cjs +56 -0
  326. package/dist/surfaceEnv-CNimK76p.cjs.map +1 -0
  327. package/dist/surfaceEnv-wMT5QzgZ.mjs +45 -0
  328. package/dist/surfaceEnv-wMT5QzgZ.mjs.map +1 -0
  329. package/dist/telemetry-B48RLjyk.d.cts +40 -0
  330. package/dist/telemetry-B48RLjyk.d.cts.map +1 -0
  331. package/dist/telemetry-BEoBn6GO.d.mts +40 -0
  332. package/dist/telemetry-BEoBn6GO.d.mts.map +1 -0
  333. package/dist/telemetry.cjs +56 -0
  334. package/dist/telemetry.cjs.map +1 -0
  335. package/dist/telemetry.d.cts +2 -0
  336. package/dist/telemetry.d.mts +2 -0
  337. package/dist/telemetry.mjs +55 -0
  338. package/dist/telemetry.mjs.map +1 -0
  339. package/dist/topic/index.cjs +3 -137
  340. package/dist/topic/index.d.cts +2 -4
  341. package/dist/topic/index.d.mts +2 -4
  342. package/dist/topic/index.mjs +2 -134
  343. package/dist/tracing-Bbj1uoFJ.mjs +127 -0
  344. package/dist/tracing-Bbj1uoFJ.mjs.map +1 -0
  345. package/dist/tracing-C0ooU0V2.cjs +150 -0
  346. package/dist/tracing-C0ooU0V2.cjs.map +1 -0
  347. package/dist/{types-BlAkSuGI.d.cts → types-DMuSQeLL.d.cts} +3 -5
  348. package/dist/types-DMuSQeLL.d.cts.map +1 -0
  349. package/dist/{types-aKksMEWL.d.mts → types-DMuSQeLL.d.mts} +3 -5
  350. package/dist/types-DMuSQeLL.d.mts.map +1 -0
  351. package/dist/types.d.cts +1 -1
  352. package/dist/types.d.mts +1 -1
  353. package/dist/types.mjs +1 -0
  354. package/dist/worker.cjs +59 -34
  355. package/dist/worker.cjs.map +1 -1
  356. package/dist/worker.d.cts +70 -45
  357. package/dist/worker.d.cts.map +1 -1
  358. package/dist/worker.d.mts +71 -45
  359. package/dist/worker.d.mts.map +1 -1
  360. package/dist/worker.mjs +54 -29
  361. package/dist/worker.mjs.map +1 -1
  362. package/package.json +115 -41
  363. package/dist/Construct-BD5neF7w.mjs.map +0 -1
  364. package/dist/Construct-C0ijr2qp.d.cts +0 -117
  365. package/dist/Construct-C0ijr2qp.d.cts.map +0 -1
  366. package/dist/Construct-Ct8nalEi.d.mts +0 -117
  367. package/dist/Construct-Ct8nalEi.d.mts.map +0 -1
  368. package/dist/Construct-CyS3RpTL.cjs.map +0 -1
  369. package/dist/Cron-DmQ8vQ4b.d.cts.map +0 -1
  370. package/dist/Cron-dh4rUgib.d.mts.map +0 -1
  371. package/dist/CronBuilder-BquXDbDI.d.cts +0 -44
  372. package/dist/CronBuilder-BquXDbDI.d.cts.map +0 -1
  373. package/dist/CronBuilder-CGgY2080.d.mts +0 -44
  374. package/dist/CronBuilder-CGgY2080.d.mts.map +0 -1
  375. package/dist/CronBuilder-CYKT5RiO.mjs.map +0 -1
  376. package/dist/CronBuilder-Da0C0edR.cjs.map +0 -1
  377. package/dist/Endpoint-BjWKinFA.d.mts.map +0 -1
  378. package/dist/Endpoint-DCQPMdUX.mjs.map +0 -1
  379. package/dist/Endpoint-DcWXE-SZ.cjs.map +0 -1
  380. package/dist/Endpoint-dav89W6-.d.cts.map +0 -1
  381. package/dist/EndpointFactory-CdWB7wPw.cjs.map +0 -1
  382. package/dist/EndpointFactory-CjV8F_lJ.mjs.map +0 -1
  383. package/dist/HonoEndpointAdaptor-DtL9j19R.cjs.map +0 -1
  384. package/dist/HonoEndpointAdaptor-P1ahhZHu.mjs.map +0 -1
  385. package/dist/Queue-D7ZuwBhy.d.cts.map +0 -1
  386. package/dist/Queue-gVGfi2Yk.d.mts.map +0 -1
  387. package/dist/Subscriber-2mEi0ImH.d.cts.map +0 -1
  388. package/dist/Subscriber-xTJ9ayPN.d.mts.map +0 -1
  389. package/dist/SubscriberBuilder-4OPehf2R.cjs.map +0 -1
  390. package/dist/SubscriberBuilder-BjkbeT9l.mjs.map +0 -1
  391. package/dist/SubscriberBuilder-Dptmo-1A.d.mts +0 -62
  392. package/dist/SubscriberBuilder-Dptmo-1A.d.mts.map +0 -1
  393. package/dist/SubscriberBuilder-waNhzjSM.d.cts +0 -62
  394. package/dist/SubscriberBuilder-waNhzjSM.d.cts.map +0 -1
  395. package/dist/Topic-19QeHBIR.d.cts +0 -91
  396. package/dist/Topic-19QeHBIR.d.cts.map +0 -1
  397. package/dist/Topic-DuFeqkBh.d.mts +0 -91
  398. package/dist/Topic-DuFeqkBh.d.mts.map +0 -1
  399. package/dist/auth.d.cts.map +0 -1
  400. package/dist/auth.d.mts.map +0 -1
  401. package/dist/cache-0ANvRQnD.mjs +0 -51
  402. package/dist/cache-0ANvRQnD.mjs.map +0 -1
  403. package/dist/cache-3WSvAulx.cjs +0 -57
  404. package/dist/cache-3WSvAulx.cjs.map +0 -1
  405. package/dist/cache-BrRz3fEB.d.mts.map +0 -1
  406. package/dist/cache-BtZY_tHe.d.cts.map +0 -1
  407. package/dist/clone-DblgEZZa.mjs.map +0 -1
  408. package/dist/clone-Dy0cR2SZ.cjs.map +0 -1
  409. package/dist/construct-interface-BfjcOD_E.cjs +0 -117
  410. package/dist/construct-interface-BfjcOD_E.cjs.map +0 -1
  411. package/dist/construct-interface-D9d4Gm4p.d.cts.map +0 -1
  412. package/dist/construct-interface-Z4CpS8tK.mjs +0 -81
  413. package/dist/construct-interface-Z4CpS8tK.mjs.map +0 -1
  414. package/dist/construct-interface-g5GM5pwR.d.mts.map +0 -1
  415. package/dist/credential.cjs.map +0 -1
  416. package/dist/credential.d.cts.map +0 -1
  417. package/dist/credential.d.mts.map +0 -1
  418. package/dist/credential.mjs.map +0 -1
  419. package/dist/database/kysely.cjs.map +0 -1
  420. package/dist/database/kysely.d.cts.map +0 -1
  421. package/dist/database/kysely.d.mts.map +0 -1
  422. package/dist/database/kysely.mjs.map +0 -1
  423. package/dist/functions-i_la-N5r.cjs.map +0 -1
  424. package/dist/index-Bd5FqCoe.d.cts.map +0 -1
  425. package/dist/index-BknhM6Ux.d.mts +0 -31
  426. package/dist/index-BknhM6Ux.d.mts.map +0 -1
  427. package/dist/index-CBSfrowv.d.cts +0 -31
  428. package/dist/index-CBSfrowv.d.cts.map +0 -1
  429. package/dist/index-D24Xm79M.d.cts +0 -171
  430. package/dist/index-D24Xm79M.d.cts.map +0 -1
  431. package/dist/index-_ajboYxK.d.mts +0 -171
  432. package/dist/index-_ajboYxK.d.mts.map +0 -1
  433. package/dist/index-lAO9egTb.d.mts.map +0 -1
  434. package/dist/lazyAccessors-BoJN3SMd.mjs.map +0 -1
  435. package/dist/lazyAccessors-e3j2oE2m.cjs +0 -274
  436. package/dist/lazyAccessors-e3j2oE2m.cjs.map +0 -1
  437. package/dist/processAudits-CGqttuXm.cjs +0 -92
  438. package/dist/processAudits-CGqttuXm.cjs.map +0 -1
  439. package/dist/processAudits-Dmts9H_b.mjs +0 -80
  440. package/dist/processAudits-Dmts9H_b.mjs.map +0 -1
  441. package/dist/queue/index.cjs.map +0 -1
  442. package/dist/queue/index.d.cts.map +0 -1
  443. package/dist/queue/index.d.mts.map +0 -1
  444. package/dist/queue/index.mjs.map +0 -1
  445. package/dist/surfaceEnv-BFXEms2f.cjs +0 -39
  446. package/dist/surfaceEnv-BFXEms2f.cjs.map +0 -1
  447. package/dist/surfaceEnv-C3Ktahea.mjs +0 -27
  448. package/dist/surfaceEnv-C3Ktahea.mjs.map +0 -1
  449. package/dist/telemetry-C3L0iS28.d.cts.map +0 -1
  450. package/dist/telemetry-D7bVFLGi.d.mts.map +0 -1
  451. package/dist/topic/index.cjs.map +0 -1
  452. package/dist/topic/index.mjs.map +0 -1
  453. package/dist/types-BlAkSuGI.d.cts.map +0 -1
  454. package/dist/types-aKksMEWL.d.mts.map +0 -1
@@ -1,9 +1,127 @@
1
- import "../Construct-BD5neF7w.mjs";
2
- import "../construct-interface-Z4CpS8tK.mjs";
3
- import "../functions-14lpEFL4.mjs";
4
- import "../clone-DblgEZZa.mjs";
5
- import { Cron, CronBuilder } from "../CronBuilder-CYKT5RiO.mjs";
6
-
1
+ import { a as publishEvents } from "../functions-CTI-hDem.mjs";
2
+ import { n as Cron, t as CronBuilder } from "../CronBuilder-D3sF9tS_.mjs";
3
+ import { runWithRequestContext } from "@geekmidas/services";
4
+ import { ROOT_CONTEXT, SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api";
5
+ import { CronExpressionParser } from "cron-parser";
6
+ //#region src/crons/inProcess.ts
7
+ /**
8
+ * The longest delay a timer takes. Node clamps anything longer to 1ms, so a
9
+ * monthly cron would fire at once and then every millisecond.
10
+ */
11
+ const MAX_DELAY = 2 ** 31 - 1;
12
+ /**
13
+ * Run `fire` on a cron expression, in this process, by timer.
14
+ *
15
+ * For the one process that has no broker to keep a schedule: `gkm dev` on a
16
+ * target whose crons are infrastructure once deployed — an EventBridge rule on
17
+ * AWS. Deployed, a timer is the wrong tool: each replica would fire every job
18
+ * once, and nothing would say so. That is why a server schedules through
19
+ * pg-boss, and why this is never what a deployed process does.
20
+ *
21
+ * In UTC, as the deployed schedule is. The next firing is worked out from the
22
+ * clock after each run rather than read off a sequence, so a run that outlasts
23
+ * its interval skips what it overran instead of firing them back to back.
24
+ */
25
+ function scheduleInProcess(expression, fire) {
26
+ CronExpressionParser.parse(expression, { tz: "UTC" });
27
+ let timer;
28
+ let stopped = false;
29
+ const arm = (at) => {
30
+ if (stopped) return;
31
+ const delay = at - Date.now();
32
+ timer = setTimeout(async () => {
33
+ if (Date.now() < at) return arm(at);
34
+ await fire();
35
+ arm(nextAfter(expression, /* @__PURE__ */ new Date()));
36
+ }, Math.min(Math.max(delay, 0), MAX_DELAY));
37
+ timer.unref?.();
38
+ };
39
+ arm(nextAfter(expression, /* @__PURE__ */ new Date()));
40
+ return { stop() {
41
+ stopped = true;
42
+ clearTimeout(timer);
43
+ } };
44
+ }
45
+ function nextAfter(expression, from) {
46
+ return CronExpressionParser.parse(expression, {
47
+ tz: "UTC",
48
+ currentDate: from
49
+ }).next().getTime();
50
+ }
51
+ //#endregion
52
+ //#region src/crons/runCron.ts
53
+ /**
54
+ * Run a cron once, in this process: what an EventBridge rule's invocation does
55
+ * on Lambda, for a server that schedules its own.
56
+ *
57
+ * The same steps as the Lambda adaptor — its services, its worker's database
58
+ * as `db`, an auditor when it declared one, its output parsed, its events
59
+ * published — because a cron that ran differently on a server than deployed
60
+ * would pass locally and fail where it matters. Services come through the
61
+ * discovery, which keeps one instance of each, so running every minute does not
62
+ * reconnect a database every minute.
63
+ *
64
+ * Each run is a trace of its own: a root span, `cron <name>`, whatever was
65
+ * active when the timer or the broker fired it.
66
+ */
67
+ async function runCron(cron, serviceDiscovery, name) {
68
+ const span = trace.getTracer("@geekmidas/constructs").startSpan(`cron ${name ?? cron.schedule ?? "manual"}`, {
69
+ kind: SpanKind.INTERNAL,
70
+ attributes: {
71
+ ...name && { "gkm.cron.name": name },
72
+ ...cron.schedule && { "gkm.cron.schedule": cron.schedule }
73
+ }
74
+ }, ROOT_CONTEXT);
75
+ return context.with(trace.setSpan(ROOT_CONTEXT, span), async () => {
76
+ try {
77
+ return await run(cron, serviceDiscovery);
78
+ } catch (error) {
79
+ if (error instanceof Error) span.recordException(error);
80
+ span.setStatus({ code: SpanStatusCode.ERROR });
81
+ throw error;
82
+ } finally {
83
+ span.end();
84
+ }
85
+ });
86
+ }
87
+ async function run(cron, serviceDiscovery) {
88
+ const services = cron.services.length > 0 ? await serviceDiscovery.register(cron.services) : {};
89
+ const db = cron.databaseService ? (await serviceDiscovery.register([cron.databaseService]))[cron.databaseService.serviceName] : void 0;
90
+ let auditor;
91
+ if (cron.auditorStorageService) {
92
+ const { DefaultAuditor } = await import("@geekmidas/audit");
93
+ const storage = (await serviceDiscovery.register([cron.auditorStorageService]))[cron.auditorStorageService.serviceName];
94
+ auditor = new DefaultAuditor({
95
+ actor: {
96
+ id: "system",
97
+ type: "system"
98
+ },
99
+ storage,
100
+ metadata: { function: cron.type }
101
+ });
102
+ }
103
+ const logger = cron.logger;
104
+ const requestId = `cron-${Date.now()}`;
105
+ return runWithRequestContext({
106
+ logger,
107
+ requestId,
108
+ startTime: Date.now(),
109
+ operation: `cron ${cron.schedule ?? "manual"}`
110
+ }, async () => {
111
+ const response = await cron.fn({
112
+ input: void 0,
113
+ services,
114
+ logger,
115
+ db,
116
+ auditor
117
+ });
118
+ const output = await cron.parseOutput(response);
119
+ await auditor?.flush();
120
+ await publishEvents(logger, serviceDiscovery, cron.events, output);
121
+ return output;
122
+ });
123
+ }
124
+ //#endregion
7
125
  //#region src/crons/schedule.ts
8
126
  /**
9
127
  * A schedule a cron runner can take, as standard five-field cron.
@@ -24,6 +142,7 @@ import { Cron, CronBuilder } from "../CronBuilder-CYKT5RiO.mjs";
24
142
  * adjusted by the framework is a bug nobody goes looking for.
25
143
  */
26
144
  var UnrepresentableSchedule = class extends Error {
145
+ schedule;
27
146
  constructor(schedule, reason) {
28
147
  super(`\`${schedule}\` has no exact cron equivalent: ${reason}.\n\nCron says *when*, not *how often*, so an interval is only exact when it divides its unit evenly.
29
148
  Write the schedule you mean instead — \`cron(0 */6 * * *)\` for every sixth hour, say — or pick an interval that divides: minutes into 60, hours into 24.`);
@@ -66,7 +185,7 @@ function toCronExpression(schedule) {
66
185
  throw new UnrepresentableSchedule(schedule, "day-of-month restarts every month, so no multi-day interval is even");
67
186
  }
68
187
  }
69
-
70
188
  //#endregion
71
- export { Cron, CronBuilder, UnrepresentableSchedule, toCronExpression };
189
+ export { Cron, CronBuilder, UnrepresentableSchedule, runCron, scheduleInProcess, toCronExpression };
190
+
72
191
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["schedule: string","reason: string","schedule: ScheduleExpression"],"sources":["../../src/crons/schedule.ts"],"sourcesContent":["import type { ScheduleExpression } from './Cron';\n\n/**\n * A schedule a cron runner can take, as standard five-field cron.\n *\n * `ScheduleExpression` has two spellings. `cron(m h dom mon dow)` is already\n * five-field cron and unwraps; `rate(n unit)` is an interval, and an interval\n * is not a schedule — it says how often, where cron says when.\n *\n * Most intervals still have an exact cron equivalent, because they divide their\n * unit evenly: `rate(5 minutes)` is every fifth minute of every hour, and that\n * is `*​/5 * * * *` precisely. `rate(7 hours)` has none. There is no cron field\n * that means \"every seven hours\" — `*​/7` in the hour field fires at 0, 7, 14\n * and 21 and then starts over at midnight, so the gap between the last firing\n * of one day and the first of the next is three hours rather than seven.\n *\n * Those are refused rather than rounded. A job that runs at the wrong hour is\n * far harder to notice than one that refused to build, and a schedule quietly\n * adjusted by the framework is a bug nobody goes looking for.\n */\nexport class UnrepresentableSchedule extends Error {\n\tconstructor(\n\t\treadonly schedule: string,\n\t\treason: string,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${schedule}\\` has no exact cron equivalent: ${reason}.\\n\\n` +\n\t\t\t\t'Cron says *when*, not *how often*, so an interval is only exact when ' +\n\t\t\t\t'it divides its unit evenly.\\n' +\n\t\t\t\t'Write the schedule you mean instead — `cron(0 */6 * * *)` for every ' +\n\t\t\t\t'sixth hour, say — or pick an interval that divides: minutes into 60, ' +\n\t\t\t\t'hours into 24.',\n\t\t);\n\t\tthis.name = 'UnrepresentableSchedule';\n\t}\n}\n\n/** Units `rate(…)` accepts, singular or plural. */\nconst UNITS = ['minute', 'hour', 'day'] as const;\ntype Unit = (typeof UNITS)[number];\n\n/**\n * Standard five-field cron for a schedule expression.\n *\n * @throws {UnrepresentableSchedule} when a `rate(…)` has no exact equivalent.\n */\nexport function toCronExpression(schedule: ScheduleExpression): string {\n\tconst cron = /^cron\\((.+)\\)$/.exec(schedule);\n\tif (cron?.[1]) return cron[1].trim();\n\n\tconst rate = /^rate\\(\\s*(\\d+)\\s+(\\w+?)s?\\s*\\)$/.exec(schedule);\n\tif (!rate) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t'it is neither `cron(…)` nor `rate(n unit)`',\n\t\t);\n\t}\n\n\tconst every = Number(rate[1]);\n\tconst unit = rate[2] as Unit;\n\t/* c8 ignore next */ if (!unit)\n\t\tthrow new UnrepresentableSchedule(schedule, 'no unit');\n\n\tif (!UNITS.includes(unit)) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t`\\`${unit}\\` is not one of ${UNITS.join(', ')}`,\n\t\t);\n\t}\n\n\tif (every < 1) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t'an interval must be at least 1',\n\t\t);\n\t}\n\n\tswitch (unit) {\n\t\tcase 'minute':\n\t\t\tif (every === 1) return '* * * * *';\n\t\t\tif (60 % every !== 0) {\n\t\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\t\tschedule,\n\t\t\t\t\t`${every} does not divide 60, so the interval would reset at the top of each hour`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn `*/${every} * * * *`;\n\n\t\tcase 'hour':\n\t\t\tif (every === 1) return '0 * * * *';\n\t\t\tif (24 % every !== 0) {\n\t\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\t\tschedule,\n\t\t\t\t\t`${every} does not divide 24, so the interval would reset at midnight`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn `0 */${every} * * *`;\n\n\t\tcase 'day':\n\t\t\tif (every === 1) return '0 0 * * *';\n\t\t\t// `*/n` in day-of-month restarts on the 1st, so a 2-day interval fires\n\t\t\t// on the 1st and 3rd of a 31-day month and then again on the 1st — one\n\t\t\t// day later, not two. No month length makes that come out even.\n\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\tschedule,\n\t\t\t\t'day-of-month restarts every month, so no multi-day interval is even',\n\t\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,0BAAb,cAA6C,MAAM;CAClD,YACUA,UACTC,QACC;AACD,SACE,IAAI,SAAS,mCAAmC,OAAO;2JAMxD;EAVQ;AAWT,OAAK,OAAO;CACZ;AACD;;AAGD,MAAM,QAAQ;CAAC;CAAU;CAAQ;AAAM;;;;;;AAQvC,SAAgB,iBAAiBC,UAAsC;CACtE,MAAM,OAAO,iBAAiB,KAAK,SAAS;AAC5C,KAAI,OAAO,GAAI,QAAO,KAAK,GAAG,MAAM;CAEpC,MAAM,OAAO,mCAAmC,KAAK,SAAS;AAC9D,MAAK,KACJ,OAAM,IAAI,wBACT,UACA;CAIF,MAAM,QAAQ,OAAO,KAAK,GAAG;CAC7B,MAAM,OAAO,KAAK;qBACG,MAAK,KACzB,OAAM,IAAI,wBAAwB,UAAU;AAE7C,MAAK,MAAM,SAAS,KAAK,CACxB,OAAM,IAAI,wBACT,WACC,IAAI,KAAK,mBAAmB,MAAM,KAAK,KAAK,CAAC;AAIhD,KAAI,QAAQ,EACX,OAAM,IAAI,wBACT,UACA;AAIF,SAAQ,MAAR;EACC,KAAK;AACJ,OAAI,UAAU,EAAG,QAAO;AACxB,OAAI,KAAK,UAAU,EAClB,OAAM,IAAI,wBACT,WACC,EAAE,MAAM;AAGX,WAAQ,IAAI,MAAM;EAEnB,KAAK;AACJ,OAAI,UAAU,EAAG,QAAO;AACxB,OAAI,KAAK,UAAU,EAClB,OAAM,IAAI,wBACT,WACC,EAAE,MAAM;AAGX,WAAQ,MAAM,MAAM;EAErB,KAAK;AACJ,OAAI,UAAU,EAAG,QAAO;AAIxB,SAAM,IAAI,wBACT,UACA;CAEF;AACD"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/crons/inProcess.ts","../../src/crons/runCron.ts","../../src/crons/schedule.ts"],"sourcesContent":["import { CronExpressionParser } from 'cron-parser';\n\n/**\n * The longest delay a timer takes. Node clamps anything longer to 1ms, so a\n * monthly cron would fire at once and then every millisecond.\n */\nconst MAX_DELAY = 2 ** 31 - 1;\n\n/** A schedule that is running, and the way to stop it. */\nexport interface InProcessSchedule {\n\tstop(): void;\n}\n\n/**\n * Run `fire` on a cron expression, in this process, by timer.\n *\n * For the one process that has no broker to keep a schedule: `gkm dev` on a\n * target whose crons are infrastructure once deployed — an EventBridge rule on\n * AWS. Deployed, a timer is the wrong tool: each replica would fire every job\n * once, and nothing would say so. That is why a server schedules through\n * pg-boss, and why this is never what a deployed process does.\n *\n * In UTC, as the deployed schedule is. The next firing is worked out from the\n * clock after each run rather than read off a sequence, so a run that outlasts\n * its interval skips what it overran instead of firing them back to back.\n */\nexport function scheduleInProcess(\n\texpression: string,\n\tfire: () => Promise<unknown> | unknown,\n): InProcessSchedule {\n\t// Parsed once up front, so a bad expression throws here — to the caller\n\t// scheduling it — rather than inside a timer.\n\tCronExpressionParser.parse(expression, { tz: 'UTC' });\n\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet stopped = false;\n\n\tconst arm = (at: number) => {\n\t\tif (stopped) return;\n\t\tconst delay = at - Date.now();\n\t\ttimer = setTimeout(\n\t\t\tasync () => {\n\t\t\t\tif (Date.now() < at) return arm(at);\n\t\t\t\tawait fire();\n\t\t\t\tarm(nextAfter(expression, new Date()));\n\t\t\t},\n\t\t\tMath.min(Math.max(delay, 0), MAX_DELAY),\n\t\t);\n\t\t// The server keeps the process alive; a schedule alone should not.\n\t\ttimer.unref?.();\n\t};\n\n\tarm(nextAfter(expression, new Date()));\n\n\treturn {\n\t\tstop() {\n\t\t\tstopped = true;\n\t\t\tclearTimeout(timer);\n\t\t},\n\t};\n}\n\nfunction nextAfter(expression: string, from: Date): number {\n\treturn CronExpressionParser.parse(expression, {\n\t\ttz: 'UTC',\n\t\tcurrentDate: from,\n\t})\n\t\t.next()\n\t\t.getTime();\n}\n","import type { AuditStorage } from '@geekmidas/audit';\nimport {\n\trunWithRequestContext,\n\ttype ServiceDiscovery,\n} from '@geekmidas/services';\nimport {\n\tcontext,\n\tROOT_CONTEXT,\n\tSpanKind,\n\tSpanStatusCode,\n\ttrace,\n} from '@opentelemetry/api';\nimport { publishEvents } from '../publisher';\nimport type { Cron } from './Cron';\n\n/**\n * Run a cron once, in this process: what an EventBridge rule's invocation does\n * on Lambda, for a server that schedules its own.\n *\n * The same steps as the Lambda adaptor — its services, its worker's database\n * as `db`, an auditor when it declared one, its output parsed, its events\n * published — because a cron that ran differently on a server than deployed\n * would pass locally and fail where it matters. Services come through the\n * discovery, which keeps one instance of each, so running every minute does not\n * reconnect a database every minute.\n *\n * Each run is a trace of its own: a root span, `cron <name>`, whatever was\n * active when the timer or the broker fired it.\n */\nexport async function runCron(\n\tcron: Cron<any, any, any, any, any, any>,\n\tserviceDiscovery: ServiceDiscovery<any>,\n\t/** The cron's export name, for its span. */\n\tname?: string,\n): Promise<unknown> {\n\tconst span = trace.getTracer('@geekmidas/constructs').startSpan(\n\t\t`cron ${name ?? cron.schedule ?? 'manual'}`,\n\t\t{\n\t\t\tkind: SpanKind.INTERNAL,\n\t\t\tattributes: {\n\t\t\t\t...(name && { 'gkm.cron.name': name }),\n\t\t\t\t...(cron.schedule && { 'gkm.cron.schedule': cron.schedule }),\n\t\t\t},\n\t\t},\n\t\tROOT_CONTEXT,\n\t);\n\n\treturn context.with(trace.setSpan(ROOT_CONTEXT, span), async () => {\n\t\ttry {\n\t\t\treturn await run(cron, serviceDiscovery);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) span.recordException(error);\n\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tspan.end();\n\t\t}\n\t});\n}\n\nasync function run(\n\tcron: Cron<any, any, any, any, any, any>,\n\tserviceDiscovery: ServiceDiscovery<any>,\n): Promise<unknown> {\n\tconst services =\n\t\tcron.services.length > 0\n\t\t\t? await serviceDiscovery.register(cron.services)\n\t\t\t: {};\n\n\tconst db = cron.databaseService\n\t\t? (await serviceDiscovery.register([cron.databaseService]))[\n\t\t\t\tcron.databaseService.serviceName\n\t\t\t]\n\t\t: undefined;\n\n\t// Only imported for a cron that audits: `@geekmidas/audit` is optional.\n\tlet auditor: { flush(): Promise<void> } | undefined;\n\tif (cron.auditorStorageService) {\n\t\tconst { DefaultAuditor } = await import('@geekmidas/audit');\n\t\tconst registered: Record<string, unknown> = await serviceDiscovery.register(\n\t\t\t[cron.auditorStorageService],\n\t\t);\n\t\tconst storage = registered[\n\t\t\tcron.auditorStorageService.serviceName\n\t\t] as AuditStorage;\n\t\tauditor = new DefaultAuditor({\n\t\t\tactor: { id: 'system', type: 'system' },\n\t\t\tstorage,\n\t\t\tmetadata: { function: cron.type },\n\t\t});\n\t}\n\n\tconst logger = cron.logger;\n\tconst requestId = `cron-${Date.now()}`;\n\n\treturn runWithRequestContext(\n\t\t{\n\t\t\tlogger,\n\t\t\trequestId,\n\t\t\tstartTime: Date.now(),\n\t\t\toperation: `cron ${cron.schedule ?? 'manual'}`,\n\t\t},\n\t\tasync () => {\n\t\t\tconst response = await cron.fn({\n\t\t\t\tinput: undefined,\n\t\t\t\tservices,\n\t\t\t\tlogger,\n\t\t\t\tdb,\n\t\t\t\tauditor,\n\t\t\t} as any);\n\t\t\tconst output = await cron.parseOutput(response);\n\n\t\t\tawait auditor?.flush();\n\t\t\t// The cron's output schema is erased by the `any` it is typed with here.\n\t\t\tawait publishEvents(\n\t\t\t\tlogger,\n\t\t\t\tserviceDiscovery,\n\t\t\t\tcron.events,\n\t\t\t\toutput as never,\n\t\t\t);\n\n\t\t\treturn output;\n\t\t},\n\t);\n}\n","import type { ScheduleExpression } from './Cron';\n\n/**\n * A schedule a cron runner can take, as standard five-field cron.\n *\n * `ScheduleExpression` has two spellings. `cron(m h dom mon dow)` is already\n * five-field cron and unwraps; `rate(n unit)` is an interval, and an interval\n * is not a schedule — it says how often, where cron says when.\n *\n * Most intervals still have an exact cron equivalent, because they divide their\n * unit evenly: `rate(5 minutes)` is every fifth minute of every hour, and that\n * is `*​/5 * * * *` precisely. `rate(7 hours)` has none. There is no cron field\n * that means \"every seven hours\" — `*​/7` in the hour field fires at 0, 7, 14\n * and 21 and then starts over at midnight, so the gap between the last firing\n * of one day and the first of the next is three hours rather than seven.\n *\n * Those are refused rather than rounded. A job that runs at the wrong hour is\n * far harder to notice than one that refused to build, and a schedule quietly\n * adjusted by the framework is a bug nobody goes looking for.\n */\nexport class UnrepresentableSchedule extends Error {\n\tconstructor(\n\t\treadonly schedule: string,\n\t\treason: string,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${schedule}\\` has no exact cron equivalent: ${reason}.\\n\\n` +\n\t\t\t\t'Cron says *when*, not *how often*, so an interval is only exact when ' +\n\t\t\t\t'it divides its unit evenly.\\n' +\n\t\t\t\t'Write the schedule you mean instead — `cron(0 */6 * * *)` for every ' +\n\t\t\t\t'sixth hour, say — or pick an interval that divides: minutes into 60, ' +\n\t\t\t\t'hours into 24.',\n\t\t);\n\t\tthis.name = 'UnrepresentableSchedule';\n\t}\n}\n\n/** Units `rate(…)` accepts, singular or plural. */\nconst UNITS = ['minute', 'hour', 'day'] as const;\ntype Unit = (typeof UNITS)[number];\n\n/**\n * Standard five-field cron for a schedule expression.\n *\n * @throws {UnrepresentableSchedule} when a `rate(…)` has no exact equivalent.\n */\nexport function toCronExpression(schedule: ScheduleExpression): string {\n\tconst cron = /^cron\\((.+)\\)$/.exec(schedule);\n\tif (cron?.[1]) return cron[1].trim();\n\n\tconst rate = /^rate\\(\\s*(\\d+)\\s+(\\w+?)s?\\s*\\)$/.exec(schedule);\n\tif (!rate) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t'it is neither `cron(…)` nor `rate(n unit)`',\n\t\t);\n\t}\n\n\tconst every = Number(rate[1]);\n\tconst unit = rate[2] as Unit;\n\t/* c8 ignore next */ if (!unit)\n\t\tthrow new UnrepresentableSchedule(schedule, 'no unit');\n\n\tif (!UNITS.includes(unit)) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t`\\`${unit}\\` is not one of ${UNITS.join(', ')}`,\n\t\t);\n\t}\n\n\tif (every < 1) {\n\t\tthrow new UnrepresentableSchedule(\n\t\t\tschedule,\n\t\t\t'an interval must be at least 1',\n\t\t);\n\t}\n\n\tswitch (unit) {\n\t\tcase 'minute':\n\t\t\tif (every === 1) return '* * * * *';\n\t\t\tif (60 % every !== 0) {\n\t\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\t\tschedule,\n\t\t\t\t\t`${every} does not divide 60, so the interval would reset at the top of each hour`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn `*/${every} * * * *`;\n\n\t\tcase 'hour':\n\t\t\tif (every === 1) return '0 * * * *';\n\t\t\tif (24 % every !== 0) {\n\t\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\t\tschedule,\n\t\t\t\t\t`${every} does not divide 24, so the interval would reset at midnight`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn `0 */${every} * * *`;\n\n\t\tcase 'day':\n\t\t\tif (every === 1) return '0 0 * * *';\n\t\t\t// `*/n` in day-of-month restarts on the 1st, so a 2-day interval fires\n\t\t\t// on the 1st and 3rd of a 31-day month and then again on the 1st — one\n\t\t\t// day later, not two. No month length makes that come out even.\n\t\t\tthrow new UnrepresentableSchedule(\n\t\t\t\tschedule,\n\t\t\t\t'day-of-month restarts every month, so no multi-day interval is even',\n\t\t\t);\n\t}\n}\n"],"mappings":"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"}
@@ -1,181 +1,4 @@
1
- const require_chunk = require('../chunk-DWy1uDak.cjs');
2
- const require_cache = require('../cache-3WSvAulx.cjs');
3
- const __geekmidas_manifest = require_chunk.__toESM(require("@geekmidas/manifest"));
4
- const kysely = require_chunk.__toESM(require("kysely"));
5
- const pg = require_chunk.__toESM(require("pg"));
6
-
7
- //#region src/database/kysely.ts
8
- /** The schema a database uses when it does not say otherwise. */
9
- const DEFAULT_SCHEMA = "app";
10
- /**
11
- * @typeParam DB - the database's schema.
12
- * @typeParam TName - the canonical id. TypeScript has no partial
13
- * type-argument inference, so `new KyselyDatabase<OrdersDB>('orders')` leaves
14
- * this at its default and the service key widens to `string`. `db` still types
15
- * through `.database()`, which infers from the service.
16
- */
17
- var KyselyDatabase = class KyselyDatabase {
18
- id;
19
- service;
20
- /**
21
- * Declared once and read by both `declare()` and `connect()`, so the key the
22
- * build publishes and the key the client reads cannot drift.
23
- */
24
- config;
25
- schemaName;
26
- roles;
27
- version;
28
- derivedFrom;
29
- constructor(id, options = {}, derivedFrom) {
30
- this.options = options;
31
- const canonical = (0, __geekmidas_manifest.canonicalId)(id);
32
- this.id = canonical;
33
- this.config = {
34
- url: (0, __geekmidas_manifest.provideKey)(canonical, "url"),
35
- ownerUrl: (0, __geekmidas_manifest.provideKey)(canonical, "ownerUrl")
36
- };
37
- this.schemaName = options.schema ?? DEFAULT_SCHEMA;
38
- this.roles = options.roles ?? true;
39
- this.version = options.version ?? __geekmidas_manifest.DEFAULT_POSTGRES_VERSION;
40
- this.derivedFrom = derivedFrom;
41
- this.service = {
42
- serviceName: (0, __geekmidas_manifest.serviceKey)(canonical),
43
- register: (registerOptions) => this.connect(registerOptions)
44
- };
45
- }
46
- declare() {
47
- if (this.derivedFrom) {
48
- const { kind, of, schema } = this.derivedFrom;
49
- return [kind === "database-schema" ? {
50
- kind,
51
- id: this.id,
52
- of,
53
- schema: schema ?? this.schemaName,
54
- provides: [this.config.url]
55
- } : {
56
- kind,
57
- id: this.id,
58
- of,
59
- provides: [this.config.url]
60
- }];
61
- }
62
- return [{
63
- kind: "database",
64
- id: this.id,
65
- engine: "postgres",
66
- schema: this.schemaName,
67
- version: this.version,
68
- provides: [this.config.url],
69
- ...this.roles ? {} : { roles: false }
70
- }];
71
- }
72
- /**
73
- * A read-only endpoint on this database.
74
- *
75
- * Read-only is enforced by the reader role's grants rather than by which
76
- * endpoint it resolves to, so falling back to the writer where no replica
77
- * exists is safe rather than a silently writable connection behind a name
78
- * that says reader. There is no `writer()`: the database *is* the writer, so
79
- * a replica can never be reached by accident.
80
- *
81
- * The return type is narrower than this class on purpose — see
82
- * {@link ReadOnlyDatabase}.
83
- */
84
- reader() {
85
- return new KyselyDatabase(`${this.id}Reader`, this.options, {
86
- kind: "database-reader",
87
- of: this.id
88
- });
89
- }
90
- /**
91
- * A cache that lives in this database.
92
- *
93
- * The same strengthening `schema()` is over a second database: `new
94
- * Cache('Sessions')` says the app caches and leaves where to the deployment,
95
- * while this says it caches *here* — which is a fact about the application
96
- * and so belongs in its code.
97
- *
98
- * What it buys beyond being explicit: the table's schema and the role that
99
- * reaches it come from this database rather than from a second convention,
100
- * and the backend no longer has to guess which database "the database" meant
101
- * when an app declares two.
102
- *
103
- * A cache is not a `KyselyDatabase`, so this returns a `Cache` — the client
104
- * is a key/value store, not a query builder, and typing it as the parent
105
- * would be a convenience that lies.
106
- */
107
- cache(id = `${this.id}Cache`, options = {}) {
108
- return new require_cache.Cache(id, {
109
- of: this.id,
110
- ...options.table ? { table: options.table } : {}
111
- });
112
- }
113
- /**
114
- * A second schema in this database, with its own role(s) and its own URL —
115
- * so this database's role holds no grant on those tables at all.
116
- *
117
- * Typed separately because a tenant has its own tables: the point is that
118
- * `auth.selectFrom('sessions')` type-checks and
119
- * `orders.selectFrom('sessions')` does not.
120
- */
121
- schema(id, options = {}) {
122
- return new KyselyDatabase(id, options, {
123
- kind: "database-schema",
124
- of: this.id,
125
- schema: options.schema ?? id.toLowerCase()
126
- });
127
- }
128
- /**
129
- * A connection as the *owner* role — the one that may create, alter and drop.
130
- *
131
- * A `Service` rather than part of the construct, and deliberately so: a
132
- * construct is what `.dependsOn()` accepts, and nothing should be able to
133
- * depend on this. A migrator asks for it by name; a handler cannot ask at
134
- * all, which is the security property the role split exists for.
135
- *
136
- * Falls back to the runtime URL where no owner URL was published — the
137
- * `roles: false` downgrade, where there is only one credential and it is the
138
- * cluster master's.
139
- */
140
- get owner() {
141
- return {
142
- serviceName: `${(0, __geekmidas_manifest.serviceKey)(this.id)}Owner`,
143
- register: (options) => this.connect(options, { owner: true })
144
- };
145
- }
146
- async connect(options, as = {}) {
147
- const { url, ownerUrl } = options.envParser.create((get) => ({
148
- url: get(this.config.url).string(),
149
- ownerUrl: get(this.config.ownerUrl).string().optional()
150
- })).parse();
151
- const { schema: _schema, roles: _roles,...kysely$1 } = this.options;
152
- return new kysely.Kysely({
153
- ...kysely$1,
154
- dialect: new kysely.PostgresDialect({ pool: pool(as.owner ? ownerUrl ?? url : url) })
155
- });
156
- }
157
- };
158
- /**
159
- * A pool for one URL, with its schema actually on the search path.
160
- *
161
- * `?search_path=` is not a libpq parameter — a URL carrying it connects
162
- * happily and then resolves every unqualified name against `public`, which is
163
- * how a schema tenant silently writes its tables into the database it was
164
- * separated from. Postgres takes it as a startup option instead, so the URL
165
- * keeps the readable form the target derives and this turns it into the thing
166
- * the server understands.
167
- */
168
- function pool(url) {
169
- const parsed = new URL(url);
170
- const searchPath = parsed.searchParams.get("search_path");
171
- if (!searchPath) return new pg.default.Pool({ connectionString: url });
172
- parsed.searchParams.delete("search_path");
173
- return new pg.default.Pool({
174
- connectionString: parsed.toString(),
175
- options: `-c search_path=${searchPath}`
176
- });
177
- }
178
-
179
- //#endregion
180
- exports.KyselyDatabase = KyselyDatabase;
181
- //# sourceMappingURL=kysely.cjs.map
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_kysely = require("../kysely-CukArHJ0.cjs");
3
+ exports.KyselyDatabase = require_kysely.KyselyDatabase;
4
+ exports.closeDatabasePools = require_kysely.closeDatabasePools;
@@ -1,152 +1,2 @@
1
- import { Construct } from "../construct-interface-D9d4Gm4p.cjs";
2
- import { Cache } from "../cache-BtZY_tHe.cjs";
3
- import { Service } from "@geekmidas/services";
4
- import { ConstructName, Declaration, PostgresVersion } from "@geekmidas/manifest";
5
- import { Kysely, KyselyConfig } from "kysely";
6
-
7
- //#region src/database/kysely.d.ts
8
-
9
- /**
10
- * Everything Kysely takes, plus what this construct declares.
11
- *
12
- * `dialect` is omitted because the construct owns it — it is built from the one
13
- * URL the adapter supplied, which is the whole point of the construct. The rest
14
- * of `KyselyConfig` (`plugins`, `log`) is the app's business and passes
15
- * straight through, so anything Kysely adds later arrives without being
16
- * tracked here.
17
- */
18
- interface KyselyDatabaseOptions extends Omit<KyselyConfig, 'dialect'> {
19
- /**
20
- * The schema, pinned on both roles' `search_path`.
21
- *
22
- * Defaults to `app` — the role the schema plays, rather than a restatement
23
- * of the database's own name, which reads correctly beside `auth` and
24
- * `pgboss` and keeps the application off `public`.
25
- */
26
- schema?: string;
27
- /**
28
- * Provision the owner/runtime role split. Defaults to on.
29
- *
30
- * Off falls back to the cluster's master credential in both URLs, giving up
31
- * the DDL/DML split and putting credentials that can drop a table into the
32
- * function's environment. A deliberate downgrade, not a default.
33
- */
34
- roles?: boolean;
35
- /**
36
- * The Postgres major version to provision.
37
- *
38
- * Declared here so one statement reaches both targets. It was previously
39
- * set in two unrelated places — a container tag locally, nothing at all on
40
- * AWS (so Aurora chose) — which is how local came to run 18 while deployed
41
- * ran 17.7 with nothing recording the difference.
42
- *
43
- * Defaults to {@link DEFAULT_POSTGRES_VERSION}.
44
- */
45
- version?: PostgresVersion;
46
- }
47
- /** What makes a construct derived rather than a database in its own right. */
48
- interface DerivedFrom {
49
- kind: 'database-reader' | 'database-schema';
50
- of: string;
51
- schema?: string;
52
- }
53
- /**
54
- * @typeParam DB - the database's schema.
55
- * @typeParam TName - the canonical id. TypeScript has no partial
56
- * type-argument inference, so `new KyselyDatabase<OrdersDB>('orders')` leaves
57
- * this at its default and the service key widens to `string`. `db` still types
58
- * through `.database()`, which infers from the service.
59
- */
60
- declare class KyselyDatabase<DB = unknown, TName extends string = string> implements Construct<TName, Kysely<DB>> {
61
- private readonly options;
62
- readonly id: TName;
63
- readonly service: Service<Uncapitalize<TName>, Kysely<DB>>;
64
- /**
65
- * Declared once and read by both `declare()` and `connect()`, so the key the
66
- * build publishes and the key the client reads cannot drift.
67
- */
68
- private readonly config;
69
- private readonly schemaName;
70
- private readonly roles;
71
- private readonly version;
72
- private readonly derivedFrom?;
73
- constructor(id: ConstructName<TName>, options?: KyselyDatabaseOptions, derivedFrom?: DerivedFrom);
74
- declare(): Declaration[];
75
- /**
76
- * A read-only endpoint on this database.
77
- *
78
- * Read-only is enforced by the reader role's grants rather than by which
79
- * endpoint it resolves to, so falling back to the writer where no replica
80
- * exists is safe rather than a silently writable connection behind a name
81
- * that says reader. There is no `writer()`: the database *is* the writer, so
82
- * a replica can never be reached by accident.
83
- *
84
- * The return type is narrower than this class on purpose — see
85
- * {@link ReadOnlyDatabase}.
86
- */
87
- reader(): ReadOnlyDatabase<DB, `${TName}Reader`>;
88
- /**
89
- * A cache that lives in this database.
90
- *
91
- * The same strengthening `schema()` is over a second database: `new
92
- * Cache('Sessions')` says the app caches and leaves where to the deployment,
93
- * while this says it caches *here* — which is a fact about the application
94
- * and so belongs in its code.
95
- *
96
- * What it buys beyond being explicit: the table's schema and the role that
97
- * reaches it come from this database rather than from a second convention,
98
- * and the backend no longer has to guess which database "the database" meant
99
- * when an app declares two.
100
- *
101
- * A cache is not a `KyselyDatabase`, so this returns a `Cache` — the client
102
- * is a key/value store, not a query builder, and typing it as the parent
103
- * would be a convenience that lies.
104
- */
105
- cache<TCache extends string = `${TName}Cache`>(id?: ConstructName<TCache>, options?: {
106
- table?: string;
107
- }): Cache<TCache>;
108
- /**
109
- * A second schema in this database, with its own role(s) and its own URL —
110
- * so this database's role holds no grant on those tables at all.
111
- *
112
- * Typed separately because a tenant has its own tables: the point is that
113
- * `auth.selectFrom('sessions')` type-checks and
114
- * `orders.selectFrom('sessions')` does not.
115
- */
116
- schema<TenantDB, TTenant extends string>(id: ConstructName<TTenant>, options?: KyselyDatabaseOptions): KyselyDatabase<TenantDB, TTenant>;
117
- /**
118
- * A connection as the *owner* role — the one that may create, alter and drop.
119
- *
120
- * A `Service` rather than part of the construct, and deliberately so: a
121
- * construct is what `.dependsOn()` accepts, and nothing should be able to
122
- * depend on this. A migrator asks for it by name; a handler cannot ask at
123
- * all, which is the security property the role split exists for.
124
- *
125
- * Falls back to the runtime URL where no owner URL was published — the
126
- * `roles: false` downgrade, where there is only one credential and it is the
127
- * cluster master's.
128
- */
129
- get owner(): Service<`${Uncapitalize<TName>}Owner`, Kysely<DB>>;
130
- private connect;
131
- }
132
- /**
133
- * A database you may read through, and derive nothing from.
134
- *
135
- * A reader is terminal in the graph, and this is that fact in the type system.
136
- * `DERIVES_FROM` gives `cache` and `database-schema` no `database-reader`
137
- * parent, and there is no reader of a reader — so `orders.reader().cache(…)`
138
- * has always been illegal, but it type-checked and failed later at
139
- * `assertDerivations`. That is a long way round to learn that a read-only
140
- * endpoint cannot own a table something writes to.
141
- *
142
- * Omitting the three deriving methods rather than making them throw keeps the
143
- * failure where it costs least: the editor, on the line that wrote it.
144
- *
145
- * The result is deliberately not assignable back to `KyselyDatabase` — a
146
- * reader is not one, and anything that genuinely needs the writer should say
147
- * so.
148
- */
149
- type ReadOnlyDatabase<DB, TName extends string> = Omit<KyselyDatabase<DB, TName>, 'reader' | 'cache' | 'schema'>;
150
- //#endregion
151
- export { KyselyDatabase, KyselyDatabaseOptions, ReadOnlyDatabase };
152
- //# sourceMappingURL=kysely.d.cts.map
1
+ import { a as closeDatabasePools, i as ReadOnlyDatabase, n as KyselyDatabaseOptions, r as PostgresRuntime, t as KyselyDatabase } from "../kysely-BHYV-WC-.cjs";
2
+ export { KyselyDatabase, KyselyDatabaseOptions, PostgresRuntime, ReadOnlyDatabase, closeDatabasePools };