@geekmidas/constructs 0.0.20 → 0.0.22

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 (205) hide show
  1. package/dist/{AWSLambdaFunction-B-Oxr8qt.d.cts → AWSLambdaFunction-gpqm7UBb.d.cts} +3 -3
  2. package/dist/{AWSLambdaFunction-CAm9r5ZX.d.mts → AWSLambdaFunction-qWpalqfr.d.mts} +3 -3
  3. package/dist/{AWSLambdaSubscriberAdaptor-Cknp_nn1.d.cts → AWSLambdaSubscriberAdaptor-CWbBNRz3.d.mts} +4 -4
  4. package/dist/{AWSLambdaSubscriberAdaptor-DpHzp-AM.d.mts → AWSLambdaSubscriberAdaptor-DT8icDRf.d.cts} +4 -4
  5. package/dist/{AmazonApiGatewayEndpointAdaptor-4hPy5vty.d.mts → AmazonApiGatewayEndpointAdaptor-BQ0IJdaI.d.mts} +3 -2
  6. package/dist/{AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs → AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs} +16 -5
  7. package/dist/AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs.map +1 -0
  8. package/dist/{AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs → AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs} +16 -5
  9. package/dist/AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs.map +1 -0
  10. package/dist/{AmazonApiGatewayEndpointAdaptor-ro0RMLzr.d.cts → AmazonApiGatewayEndpointAdaptor-Da9BR5On.d.cts} +3 -2
  11. package/dist/{AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs → AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs} +2 -2
  12. package/dist/{AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs.map → AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs.map} +1 -1
  13. package/dist/{AmazonApiGatewayV1EndpointAdaptor-hyR-WwyP.d.mts → AmazonApiGatewayV1EndpointAdaptor-C4_AZ1ek.d.mts} +3 -3
  14. package/dist/{AmazonApiGatewayV1EndpointAdaptor-BWJWKqQT.d.cts → AmazonApiGatewayV1EndpointAdaptor-CSm3NsWz.d.cts} +3 -3
  15. package/dist/{AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs → AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs} +2 -2
  16. package/dist/{AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs.map → AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs.map} +1 -1
  17. package/dist/{AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs → AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs} +2 -2
  18. package/dist/{AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs.map → AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs.map} +1 -1
  19. package/dist/{AmazonApiGatewayV2EndpointAdaptor-D1Irdggp.d.cts → AmazonApiGatewayV2EndpointAdaptor-6hsBFVLf.d.cts} +3 -3
  20. package/dist/{AmazonApiGatewayV2EndpointAdaptor-DX3SuI5S.d.mts → AmazonApiGatewayV2EndpointAdaptor-DdM8Tr1X.d.mts} +3 -3
  21. package/dist/{AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs → AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs} +2 -2
  22. package/dist/{AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs.map → AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs.map} +1 -1
  23. package/dist/{BaseFunctionBuilder-CbDnPZpD.d.mts → BaseFunctionBuilder-Ct6zY6Jq.d.mts} +2 -2
  24. package/dist/{BaseFunctionBuilder-DUZMbEr3.d.cts → BaseFunctionBuilder-DaQA0uKE.d.cts} +2 -2
  25. package/dist/{Construct-ZPqE0vhn.d.mts → Construct-DDR0295I.d.mts} +7 -7
  26. package/dist/{Construct-dI_rgdSp.d.cts → Construct-Dkd8Kvc9.d.cts} +7 -7
  27. package/dist/Construct.d.cts +1 -1
  28. package/dist/Construct.d.mts +1 -1
  29. package/dist/{Cron-COdfP0Jd.d.cts → Cron-7VPR2cNR.d.cts} +6 -5
  30. package/dist/Cron-Bi3QOge_.cjs.map +1 -1
  31. package/dist/{Cron-D8cn_ahj.d.mts → Cron-DnMRWPFR.d.mts} +6 -5
  32. package/dist/Cron-Dy_HW2Vv.mjs.map +1 -1
  33. package/dist/{CronBuilder-DntF6H3A.d.cts → CronBuilder-290th4zF.d.cts} +4 -4
  34. package/dist/{CronBuilder-DoMnSs_0.d.mts → CronBuilder-RLDitFmP.d.mts} +4 -4
  35. package/dist/{Endpoint-DDpF7NO1.cjs → Endpoint-CA-byrDr.cjs} +1 -3
  36. package/dist/Endpoint-CA-byrDr.cjs.map +1 -0
  37. package/dist/{Endpoint-Bu8Phz6y.d.cts → Endpoint-D2Imgihs.d.cts} +31 -7
  38. package/dist/{Endpoint-S6Yh2_PN.mjs → Endpoint-DbPsw13b.mjs} +1 -3
  39. package/dist/Endpoint-DbPsw13b.mjs.map +1 -0
  40. package/dist/{Endpoint-Bbs_sFvg.d.mts → Endpoint-PtQ-wLIS.d.mts} +31 -7
  41. package/dist/{EndpointBuilder-D02Qo4Ha.d.mts → EndpointBuilder-BPHpUekp.d.mts} +4 -4
  42. package/dist/{EndpointBuilder-vxy3s960.cjs → EndpointBuilder-CYkeYpsL.cjs} +3 -3
  43. package/dist/EndpointBuilder-CYkeYpsL.cjs.map +1 -0
  44. package/dist/{EndpointBuilder-DHPOWw0B.d.cts → EndpointBuilder-TApJQhtG.d.cts} +4 -4
  45. package/dist/{EndpointBuilder-D47py-H1.mjs → EndpointBuilder-W5fdXxYQ.mjs} +3 -3
  46. package/dist/EndpointBuilder-W5fdXxYQ.mjs.map +1 -0
  47. package/dist/{EndpointFactory-HOCnoBNT.mjs → EndpointFactory-B27nfeiE.mjs} +29 -2
  48. package/dist/EndpointFactory-B27nfeiE.mjs.map +1 -0
  49. package/dist/{EndpointFactory-DFFXRU-l.d.cts → EndpointFactory-B5fOINuc.d.cts} +11 -5
  50. package/dist/{EndpointFactory-g84YJjGf.d.mts → EndpointFactory-CNlfBDuD.d.mts} +11 -5
  51. package/dist/{EndpointFactory-DSTXeokM.cjs → EndpointFactory-D5lFZXqY.cjs} +29 -2
  52. package/dist/EndpointFactory-D5lFZXqY.cjs.map +1 -0
  53. package/dist/{Function-V9M9UVHp.d.mts → Function-CD3rXWfa.d.mts} +5 -5
  54. package/dist/{Function-VI1TB3Mh.d.cts → Function-DHD1V9QW.d.cts} +5 -5
  55. package/dist/{FunctionBuilder-CjVEFTYC.d.cts → FunctionBuilder-FV6r3I7X.d.cts} +4 -4
  56. package/dist/{FunctionBuilder-D1ofSeMd.d.mts → FunctionBuilder-j2VkwuGf.d.mts} +4 -4
  57. package/dist/{FunctionExecutionWrapper-CwtwYozd.d.cts → FunctionExecutionWrapper-B0WP-Vec.d.mts} +4 -4
  58. package/dist/{FunctionExecutionWrapper-rhbIYT0Q.d.mts → FunctionExecutionWrapper-DYt3C8b9.d.cts} +4 -4
  59. package/dist/{HonoEndpointAdaptor-CdWWj3EJ.cjs → HonoEndpointAdaptor-B_gJPWGD.cjs} +6 -5
  60. package/dist/HonoEndpointAdaptor-B_gJPWGD.cjs.map +1 -0
  61. package/dist/{HonoEndpointAdaptor-BI0tA0Fg.mjs → HonoEndpointAdaptor-Bg_vTyA5.mjs} +6 -5
  62. package/dist/HonoEndpointAdaptor-Bg_vTyA5.mjs.map +1 -0
  63. package/dist/{HonoEndpointAdaptor-BTwjymKt.d.mts → HonoEndpointAdaptor-C9gYYBWu.d.mts} +5 -5
  64. package/dist/{HonoEndpointAdaptor-CDL4pkMO.d.cts → HonoEndpointAdaptor-CLOpobdq.d.cts} +5 -5
  65. package/dist/{Subscriber-CJOWwaw1.mjs → Subscriber-CGb8LjZa.mjs} +1 -1
  66. package/dist/{Subscriber-CJOWwaw1.mjs.map → Subscriber-CGb8LjZa.mjs.map} +1 -1
  67. package/dist/{Subscriber-Bdh8rMSL.cjs → Subscriber-D-FPWts6.cjs} +1 -1
  68. package/dist/{Subscriber-Bdh8rMSL.cjs.map → Subscriber-D-FPWts6.cjs.map} +1 -1
  69. package/dist/{Subscriber-BhzqUzs-.d.cts → Subscriber-DMSzvO_J.d.cts} +6 -6
  70. package/dist/{Subscriber-s6yfjeOc.d.mts → Subscriber-itwm7ugy.d.mts} +6 -6
  71. package/dist/{SubscriberBuilder-BCVkp-ga.d.cts → SubscriberBuilder-9j3JCu8-.d.mts} +3 -3
  72. package/dist/{SubscriberBuilder-BWQmiYd8.mjs → SubscriberBuilder-BcAspHv9.mjs} +2 -2
  73. package/dist/{SubscriberBuilder-BWQmiYd8.mjs.map → SubscriberBuilder-BcAspHv9.mjs.map} +1 -1
  74. package/dist/{SubscriberBuilder-DieD_60p.cjs → SubscriberBuilder-BfE2cL1q.cjs} +2 -2
  75. package/dist/{SubscriberBuilder-DieD_60p.cjs.map → SubscriberBuilder-BfE2cL1q.cjs.map} +1 -1
  76. package/dist/{SubscriberBuilder-aCua5_wA.d.mts → SubscriberBuilder-BxJM3Hz_.d.cts} +3 -3
  77. package/dist/{TestEndpointAdaptor-ByXqQufk.d.cts → TestEndpointAdaptor-BYCwwiYk.d.cts} +2 -2
  78. package/dist/{TestEndpointAdaptor-C5qwQSnQ.cjs → TestEndpointAdaptor-Bew9lWsx.cjs} +5 -4
  79. package/dist/TestEndpointAdaptor-Bew9lWsx.cjs.map +1 -0
  80. package/dist/{TestEndpointAdaptor-Bl2ic-yr.d.mts → TestEndpointAdaptor-C-c8v7VI.d.mts} +2 -2
  81. package/dist/{TestEndpointAdaptor-DFDT9m8q.mjs → TestEndpointAdaptor-JONQJeXc.mjs} +5 -4
  82. package/dist/TestEndpointAdaptor-JONQJeXc.mjs.map +1 -0
  83. package/dist/adaptors/aws.cjs +4 -4
  84. package/dist/adaptors/aws.d.cts +13 -13
  85. package/dist/adaptors/aws.d.mts +13 -13
  86. package/dist/adaptors/aws.mjs +4 -4
  87. package/dist/adaptors/hono.cjs +3 -3
  88. package/dist/adaptors/hono.d.cts +7 -7
  89. package/dist/adaptors/hono.d.mts +7 -7
  90. package/dist/adaptors/hono.mjs +3 -3
  91. package/dist/adaptors/testing.cjs +2 -2
  92. package/dist/adaptors/testing.d.cts +7 -7
  93. package/dist/adaptors/testing.d.mts +7 -7
  94. package/dist/adaptors/testing.mjs +2 -2
  95. package/dist/crons/Cron.d.cts +6 -6
  96. package/dist/crons/Cron.d.mts +6 -6
  97. package/dist/crons/CronBuilder.d.cts +7 -7
  98. package/dist/crons/CronBuilder.d.mts +7 -7
  99. package/dist/crons/index.d.cts +11 -11
  100. package/dist/crons/index.d.mts +7 -7
  101. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +2 -2
  102. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +7 -7
  103. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +7 -7
  104. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +2 -2
  105. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +3 -3
  106. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +8 -8
  107. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +8 -8
  108. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +3 -3
  109. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +3 -3
  110. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +8 -8
  111. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +8 -8
  112. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +3 -3
  113. package/dist/endpoints/Endpoint.cjs +1 -1
  114. package/dist/endpoints/Endpoint.d.cts +6 -6
  115. package/dist/endpoints/Endpoint.d.mts +6 -6
  116. package/dist/endpoints/Endpoint.mjs +1 -1
  117. package/dist/endpoints/EndpointBuilder.cjs +2 -2
  118. package/dist/endpoints/EndpointBuilder.d.cts +7 -7
  119. package/dist/endpoints/EndpointBuilder.d.mts +7 -7
  120. package/dist/endpoints/EndpointBuilder.mjs +2 -2
  121. package/dist/endpoints/EndpointFactory.cjs +3 -3
  122. package/dist/endpoints/EndpointFactory.d.cts +8 -8
  123. package/dist/endpoints/EndpointFactory.d.mts +8 -8
  124. package/dist/endpoints/EndpointFactory.mjs +3 -3
  125. package/dist/endpoints/HonoEndpointAdaptor.cjs +3 -3
  126. package/dist/endpoints/HonoEndpointAdaptor.d.cts +7 -7
  127. package/dist/endpoints/HonoEndpointAdaptor.d.mts +7 -7
  128. package/dist/endpoints/HonoEndpointAdaptor.mjs +3 -3
  129. package/dist/endpoints/TestEndpointAdaptor.cjs +2 -2
  130. package/dist/endpoints/TestEndpointAdaptor.d.cts +7 -7
  131. package/dist/endpoints/TestEndpointAdaptor.d.mts +7 -7
  132. package/dist/endpoints/TestEndpointAdaptor.mjs +2 -2
  133. package/dist/endpoints/audit.d.cts +6 -6
  134. package/dist/endpoints/audit.d.mts +6 -6
  135. package/dist/endpoints/helpers.cjs +2 -2
  136. package/dist/endpoints/helpers.d.cts +6 -6
  137. package/dist/endpoints/helpers.d.mts +6 -6
  138. package/dist/endpoints/helpers.mjs +2 -2
  139. package/dist/endpoints/index.cjs +3 -3
  140. package/dist/endpoints/index.d.cts +10 -10
  141. package/dist/endpoints/index.d.mts +10 -10
  142. package/dist/endpoints/index.mjs +3 -3
  143. package/dist/endpoints/processAudits.d.cts +6 -6
  144. package/dist/endpoints/processAudits.d.mts +6 -6
  145. package/dist/functions/AWSLambdaFunction.d.cts +4 -4
  146. package/dist/functions/AWSLambdaFunction.d.mts +4 -4
  147. package/dist/functions/BaseFunctionBuilder.d.cts +2 -2
  148. package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
  149. package/dist/functions/Function.d.cts +2 -2
  150. package/dist/functions/Function.d.mts +2 -2
  151. package/dist/functions/FunctionBuilder.d.cts +4 -4
  152. package/dist/functions/FunctionBuilder.d.mts +4 -4
  153. package/dist/functions/FunctionExecutionWrapper.d.cts +3 -3
  154. package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
  155. package/dist/functions/TestFunctionAdaptor.d.cts +2 -2
  156. package/dist/functions/TestFunctionAdaptor.d.mts +2 -2
  157. package/dist/functions/index.d.cts +5 -5
  158. package/dist/functions/index.d.mts +5 -5
  159. package/dist/{helpers-2CLKTnRm.mjs → helpers-CrrdyA04.mjs} +2 -2
  160. package/dist/{helpers-2CLKTnRm.mjs.map → helpers-CrrdyA04.mjs.map} +1 -1
  161. package/dist/{helpers-Khuhi_Qx.cjs → helpers-DiPZVJQC.cjs} +2 -2
  162. package/dist/{helpers-Khuhi_Qx.cjs.map → helpers-DiPZVJQC.cjs.map} +1 -1
  163. package/dist/index-Ceo-GuhJ.d.cts +10 -0
  164. package/dist/{index-Sxtb_Pzw.d.mts → index-licEVXjh.d.mts} +2 -2
  165. package/dist/index.d.cts +1 -1
  166. package/dist/index.d.mts +1 -1
  167. package/dist/publisher.d.cts +2 -2
  168. package/dist/publisher.d.mts +2 -2
  169. package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.cts +3 -3
  170. package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +3 -3
  171. package/dist/subscribers/Subscriber.cjs +1 -1
  172. package/dist/subscribers/Subscriber.d.cts +2 -2
  173. package/dist/subscribers/Subscriber.d.mts +2 -2
  174. package/dist/subscribers/Subscriber.mjs +1 -1
  175. package/dist/subscribers/SubscriberBuilder.cjs +2 -2
  176. package/dist/subscribers/SubscriberBuilder.d.cts +3 -3
  177. package/dist/subscribers/SubscriberBuilder.d.mts +3 -3
  178. package/dist/subscribers/SubscriberBuilder.mjs +2 -2
  179. package/dist/subscribers/index.cjs +2 -2
  180. package/dist/subscribers/index.d.cts +5 -5
  181. package/dist/subscribers/index.d.mts +5 -5
  182. package/dist/subscribers/index.mjs +2 -2
  183. package/package.json +5 -5
  184. package/src/crons/Cron.ts +7 -6
  185. package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +31 -10
  186. package/src/endpoints/Endpoint.ts +41 -6
  187. package/src/endpoints/EndpointBuilder.ts +6 -2
  188. package/src/endpoints/EndpointFactory.ts +77 -4
  189. package/src/endpoints/HonoEndpointAdaptor.ts +12 -11
  190. package/src/endpoints/TestEndpointAdaptor.ts +11 -6
  191. package/src/endpoints/__tests__/EndpointFactory.authorizers.spec.ts +141 -0
  192. package/src/endpoints/__tests__/TestEndpointAdaptor.audits.spec.ts +30 -42
  193. package/dist/AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs.map +0 -1
  194. package/dist/AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs.map +0 -1
  195. package/dist/Endpoint-DDpF7NO1.cjs.map +0 -1
  196. package/dist/Endpoint-S6Yh2_PN.mjs.map +0 -1
  197. package/dist/EndpointBuilder-D47py-H1.mjs.map +0 -1
  198. package/dist/EndpointBuilder-vxy3s960.cjs.map +0 -1
  199. package/dist/EndpointFactory-DSTXeokM.cjs.map +0 -1
  200. package/dist/EndpointFactory-HOCnoBNT.mjs.map +0 -1
  201. package/dist/HonoEndpointAdaptor-BI0tA0Fg.mjs.map +0 -1
  202. package/dist/HonoEndpointAdaptor-CdWWj3EJ.cjs.map +0 -1
  203. package/dist/TestEndpointAdaptor-C5qwQSnQ.cjs.map +0 -1
  204. package/dist/TestEndpointAdaptor-DFDT9m8q.mjs.map +0 -1
  205. package/dist/index-CkBMFqhI.d.cts +0 -10
@@ -1,6 +1,6 @@
1
1
  require('../Construct-BYSPikVm.cjs');
2
- const require_Subscriber = require('../Subscriber-Bdh8rMSL.cjs');
3
- const require_SubscriberBuilder = require('../SubscriberBuilder-DieD_60p.cjs');
2
+ const require_Subscriber = require('../Subscriber-D-FPWts6.cjs');
3
+ const require_SubscriberBuilder = require('../SubscriberBuilder-BfE2cL1q.cjs');
4
4
 
5
5
  //#region src/subscribers/index.ts
6
6
  const s = new require_SubscriberBuilder.SubscriberBuilder();
@@ -1,10 +1,10 @@
1
- import "../Construct-dI_rgdSp.cjs";
2
- import { Subscriber } from "../Subscriber-BhzqUzs-.cjs";
3
- import { SubscriberBuilder } from "../SubscriberBuilder-BCVkp-ga.cjs";
4
- import * as _geekmidas_logger9 from "@geekmidas/logger";
1
+ import "../Construct-Dkd8Kvc9.cjs";
2
+ import { Subscriber } from "../Subscriber-DMSzvO_J.cjs";
3
+ import { SubscriberBuilder } from "../SubscriberBuilder-BxJM3Hz_.cjs";
4
+ import * as _geekmidas_logger4 from "@geekmidas/logger";
5
5
 
6
6
  //#region src/subscribers/index.d.ts
7
- declare const s: SubscriberBuilder<[], _geekmidas_logger9.Logger, undefined, undefined, string, []>;
7
+ declare const s: SubscriberBuilder<[], _geekmidas_logger4.Logger, undefined, undefined, string, []>;
8
8
  //#endregion
9
9
  export { Subscriber, SubscriberBuilder, s };
10
10
  //# sourceMappingURL=index.d.cts.map
@@ -1,10 +1,10 @@
1
- import "../Construct-ZPqE0vhn.mjs";
2
- import { Subscriber } from "../Subscriber-s6yfjeOc.mjs";
3
- import { SubscriberBuilder } from "../SubscriberBuilder-aCua5_wA.mjs";
4
- import * as _geekmidas_logger6 from "@geekmidas/logger";
1
+ import "../Construct-DDR0295I.mjs";
2
+ import { Subscriber } from "../Subscriber-itwm7ugy.mjs";
3
+ import { SubscriberBuilder } from "../SubscriberBuilder-9j3JCu8-.mjs";
4
+ import * as _geekmidas_logger9 from "@geekmidas/logger";
5
5
 
6
6
  //#region src/subscribers/index.d.ts
7
- declare const s: SubscriberBuilder<[], _geekmidas_logger6.Logger, undefined, undefined, string, []>;
7
+ declare const s: SubscriberBuilder<[], _geekmidas_logger9.Logger, undefined, undefined, string, []>;
8
8
  //#endregion
9
9
  export { Subscriber, SubscriberBuilder, s };
10
10
  //# sourceMappingURL=index.d.mts.map
@@ -1,6 +1,6 @@
1
1
  import "../Construct-LWeB1rSQ.mjs";
2
- import { Subscriber } from "../Subscriber-CJOWwaw1.mjs";
3
- import { SubscriberBuilder } from "../SubscriberBuilder-BWQmiYd8.mjs";
2
+ import { Subscriber } from "../Subscriber-CGb8LjZa.mjs";
3
+ import { SubscriberBuilder } from "../SubscriberBuilder-BcAspHv9.mjs";
4
4
 
5
5
  //#region src/subscribers/index.ts
6
6
  const s = new SubscriberBuilder();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/constructs",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -52,7 +52,7 @@
52
52
  },
53
53
  "repository": {
54
54
  "type": "git",
55
- "url": "https://github.com/geekmidas/toolbox.git"
55
+ "url": "https://github.com/geekmidas/toolbox"
56
56
  },
57
57
  "publishConfig": {
58
58
  "registry": "https://registry.npmjs.org/",
@@ -67,12 +67,12 @@
67
67
  "lodash.uniqby": "~4.7.0",
68
68
  "openapi-types": "~12.1.3",
69
69
  "@geekmidas/audit": "0.0.8",
70
- "@geekmidas/schema": "0.0.2",
71
- "@geekmidas/rate-limit": "0.1.0",
72
70
  "@geekmidas/cache": "0.0.7",
73
71
  "@geekmidas/events": "0.0.2",
74
72
  "@geekmidas/errors": "0.0.1",
75
73
  "@geekmidas/logger": "0.0.1",
74
+ "@geekmidas/rate-limit": "0.1.0",
75
+ "@geekmidas/schema": "0.0.2",
76
76
  "@geekmidas/services": "0.0.1"
77
77
  },
78
78
  "devDependencies": {
@@ -84,7 +84,7 @@
84
84
  "@types/pg": "~8.15.6",
85
85
  "kysely": "~0.28.8",
86
86
  "pg": "~8.16.3",
87
- "zod": "~4.1.12",
87
+ "zod": "~4.1.13",
88
88
  "@geekmidas/testkit": "0.0.17"
89
89
  },
90
90
  "peerDependencies": {
package/src/crons/Cron.ts CHANGED
@@ -1,13 +1,13 @@
1
+ import type { AuditableAction } from '@geekmidas/audit';
2
+ import type { EventPublisher } from '@geekmidas/events';
1
3
  import type { Logger } from '@geekmidas/logger';
4
+ import type { ComposableStandardSchema } from '@geekmidas/schema';
5
+ import type { Service } from '@geekmidas/services';
2
6
  import type { StandardSchemaV1 } from '@standard-schema/spec';
3
7
 
4
8
  import { ConstructType } from '../Construct';
5
9
  import { Function, type FunctionHandler } from '../functions';
6
10
 
7
- import type { EventPublisher } from '@geekmidas/events';
8
- import type { ComposableStandardSchema } from '@geekmidas/schema';
9
- import type { Service } from '@geekmidas/services';
10
-
11
11
  export class Cron<
12
12
  TInput extends ComposableStandardSchema | undefined = undefined,
13
13
  TServices extends Service[] = [],
@@ -22,13 +22,14 @@ export class Cron<
22
22
  TServices,
23
23
  TLogger,
24
24
  OutSchema,
25
- FunctionHandler<TInput, TServices, TLogger, OutSchema, TDatabase>,
26
25
  TEventPublisher,
27
26
  TEventPublisherServiceName,
28
27
  undefined,
29
28
  string,
30
29
  TDatabase,
31
- TDatabaseServiceName
30
+ TDatabaseServiceName,
31
+ AuditableAction<string, unknown>,
32
+ FunctionHandler<TInput, TServices, TLogger, OutSchema, TDatabase>
32
33
  > {
33
34
  static isCron(obj: any): obj is Cron<any, any, any, any> {
34
35
  return Boolean(
@@ -191,17 +191,44 @@ export abstract class AmazonApiGatewayEndpoint<
191
191
  };
192
192
  }
193
193
 
194
+ private database(): Middleware<TEvent, TInput, TServices, TLogger> {
195
+ return {
196
+ before: async (req) => {
197
+ if (!this.endpoint.databaseService) {
198
+ return;
199
+ }
200
+
201
+ const logger = req.event.logger as TLogger;
202
+ const serviceDiscovery = ServiceDiscovery.getInstance<
203
+ ServiceRecord<TServices>,
204
+ TLogger
205
+ >(logger, this.envParser);
206
+
207
+ const db = await serviceDiscovery
208
+ .register([this.endpoint.databaseService])
209
+ .then(
210
+ (s) =>
211
+ s[this.endpoint.databaseService!.serviceName as keyof typeof s],
212
+ );
213
+
214
+ (req.event as any).db = db;
215
+ },
216
+ };
217
+ }
218
+
194
219
  private session(): Middleware<TEvent, TInput, TServices, TLogger> {
195
220
  return {
196
221
  before: async (req) => {
197
222
  const logger = req.event.logger as TLogger;
198
223
  const services = req.event.services;
224
+ const db = (req.event as any).db;
199
225
  req.event.session = (await this.endpoint.getSession({
200
226
  logger,
201
227
  services,
202
228
  header: req.event.header,
203
229
  cookie: req.event.cookie,
204
- })) as TSession;
230
+ ...(db !== undefined && { db }),
231
+ } as any)) as TSession;
205
232
  },
206
233
  };
207
234
  }
@@ -267,15 +294,8 @@ export abstract class AmazonApiGatewayEndpoint<
267
294
  logger.warn('No auditor storage service available');
268
295
  }
269
296
 
270
- // Resolve database service if configured
271
- const rawDb = this.endpoint.databaseService
272
- ? await serviceDiscovery
273
- .register([this.endpoint.databaseService])
274
- .then(
275
- (s) =>
276
- s[this.endpoint.databaseService!.serviceName as keyof typeof s],
277
- )
278
- : undefined;
297
+ // Get pre-resolved database from middleware
298
+ const rawDb = (event as any).db;
279
299
 
280
300
  // Execute handler with automatic audit transaction support
281
301
  const result = await executeWithAuditTransaction(
@@ -382,6 +402,7 @@ export abstract class AmazonApiGatewayEndpoint<
382
402
  .use(this.error())
383
403
  .use(this.services())
384
404
  .use(this.input())
405
+ .use(this.database())
385
406
  .use(this.session())
386
407
  .use(this.authorize())
387
408
  .use(this.events()) as unknown as THandler;
@@ -109,7 +109,7 @@ export class Endpoint<
109
109
  /** Default headers to apply to all responses */
110
110
  public readonly defaultHeaders: Record<string, string> = {};
111
111
  /** Function to extract session data from the request context */
112
- public getSession: SessionFn<TServices, TLogger, TSession> = () =>
112
+ public getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>
113
113
  ({}) as TSession;
114
114
  /** Function to determine if the request is authorized */
115
115
  public authorize: AuthorizeFn<TServices, TLogger, TSession> = () => true;
@@ -122,7 +122,7 @@ export class Endpoint<
122
122
  /** Declarative audit definitions */
123
123
  public audits: MappedAudit<TAuditAction, OutSchema>[] = [];
124
124
  /** Database service for this endpoint */
125
- public databaseService?: Service<TDatabaseServiceName, TDatabase>;
125
+ public declare databaseService?: Service<TDatabaseServiceName, TDatabase>;
126
126
  /** The endpoint handler function */
127
127
  private endpointFn!: EndpointHandler<
128
128
  TInput,
@@ -752,7 +752,7 @@ export interface EndpointOptions<
752
752
  /** Logger instance */
753
753
  logger: TLogger;
754
754
  /** Optional session extraction function */
755
- getSession: SessionFn<TServices, TLogger, TSession> | undefined;
755
+ getSession: SessionFn<TServices, TLogger, TSession, TDatabase> | undefined;
756
756
  /** Optional rate limiting configuration */
757
757
  rateLimit?: RateLimitConfig;
758
758
  /** Success HTTP status code */
@@ -826,7 +826,10 @@ export type AuthorizeFn<
826
826
  ctx: AuthorizeContext<TServices, TLogger, TSession>,
827
827
  ) => Promise<boolean> | boolean;
828
828
 
829
- export type SessionContext<
829
+ /**
830
+ * Base session context without database
831
+ */
832
+ type BaseSessionContext<
830
833
  TServices extends Service[] = [],
831
834
  TLogger extends Logger = Logger,
832
835
  > = {
@@ -835,29 +838,61 @@ export type SessionContext<
835
838
  header: HeaderFn;
836
839
  cookie: CookieFn;
837
840
  };
841
+
842
+ /**
843
+ * Conditional database context for session - only present when database service is configured
844
+ */
845
+ type SessionDatabaseContext<TDatabase = undefined> = TDatabase extends undefined
846
+ ? {}
847
+ : {
848
+ /**
849
+ * Database instance for session extraction.
850
+ * Available when a database service is configured via `.database()`.
851
+ * Useful for looking up user data from the database based on auth tokens.
852
+ */
853
+ db: TDatabase;
854
+ };
855
+
856
+ export type SessionContext<
857
+ TServices extends Service[] = [],
858
+ TLogger extends Logger = Logger,
859
+ TDatabase = undefined,
860
+ > = BaseSessionContext<TServices, TLogger> & SessionDatabaseContext<TDatabase>;
838
861
  /**
839
862
  * Function type for extracting session data from a request.
840
863
  *
841
864
  * @template TServices - Available service dependencies
842
865
  * @template TLogger - Logger type
843
866
  * @template TSession - Session data type to extract
867
+ * @template TDatabase - Database type (when database service is configured)
844
868
  *
845
- * @param ctx - Context containing services, logger, and headers
869
+ * @param ctx - Context containing services, logger, headers, and optionally database
846
870
  * @returns The extracted session data
847
871
  *
848
872
  * @example
849
873
  * ```typescript
874
+ * // Without database
850
875
  * const getSession: SessionFn<Services, Logger, UserSession> = async ({ header, services }) => {
851
876
  * const token = header('authorization');
852
877
  * return await services.auth.verifyToken(token);
853
878
  * };
879
+ *
880
+ * // With database
881
+ * const getSession: SessionFn<Services, Logger, UserSession, Database> = async ({ header, db }) => {
882
+ * const token = header('authorization');
883
+ * const user = await db.selectFrom('users').where('token', '=', token).executeTakeFirst();
884
+ * return { userId: user?.id };
885
+ * };
854
886
  * ```
855
887
  */
856
888
  export type SessionFn<
857
889
  TServices extends Service[] = [],
858
890
  TLogger extends Logger = Logger,
859
891
  TSession = unknown,
860
- > = (ctx: SessionContext<TServices, TLogger>) => Promise<TSession> | TSession;
892
+ TDatabase = undefined,
893
+ > = (
894
+ ctx: SessionContext<TServices, TLogger, TDatabase>,
895
+ ) => Promise<TSession> | TSession;
861
896
 
862
897
  /**
863
898
  * Utility type that converts Express-style route parameters to OpenAPI format.
@@ -58,7 +58,8 @@ export class EndpointBuilder<
58
58
  protected _status?: SuccessStatus;
59
59
  protected _tags?: string[];
60
60
  protected _memorySize?: number;
61
- _getSession: SessionFn<TServices, TLogger, TSession> = () => ({}) as TSession;
61
+ _getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>
62
+ ({}) as TSession;
62
63
  _authorize: AuthorizeFn<TServices, TLogger, TSession> = () => true;
63
64
  _rateLimit?: RateLimitConfig;
64
65
  _availableAuthorizers: Authorizer[] = [];
@@ -615,8 +616,11 @@ export class EndpointBuilder<
615
616
  TDatabaseServiceName
616
617
  > {
617
618
  // Find authorizer metadata if name is set
619
+ // If the authorizer name is set but not in availableAuthorizers, create a simple authorizer object
618
620
  const authorizer = this._authorizerName
619
- ? this._availableAuthorizers.find((a) => a.name === this._authorizerName)
621
+ ? (this._availableAuthorizers.find(
622
+ (a) => a.name === this._authorizerName,
623
+ ) ?? { name: this._authorizerName })
620
624
  : undefined;
621
625
 
622
626
  return new Endpoint({
@@ -40,7 +40,12 @@ export class EndpointFactory<
40
40
  private defaultEventPublisher:
41
41
  | Service<TEventPublisherServiceName, TEventPublisher>
42
42
  | undefined;
43
- private defaultSessionExtractor?: SessionFn<TServices, TLogger, TSession>;
43
+ private defaultSessionExtractor?: SessionFn<
44
+ TServices,
45
+ TLogger,
46
+ TSession,
47
+ TDatabase
48
+ >;
44
49
  private defaultLogger: TLogger = DEFAULT_LOGGER;
45
50
  private availableAuthorizers: Authorizer[] = [];
46
51
  private defaultAuthorizerName?: TAuthorizers[number];
@@ -181,6 +186,70 @@ export class EndpointFactory<
181
186
  });
182
187
  }
183
188
 
189
+ /**
190
+ * Set the default authorizer for all endpoints created from this factory.
191
+ * Individual endpoints can override this by calling `.authorizer()` on the builder.
192
+ * Use `'none'` to explicitly disable authorization for all endpoints.
193
+ */
194
+ authorizer(
195
+ name: TAuthorizers[number] | 'none',
196
+ ): EndpointFactory<
197
+ TServices,
198
+ TBasePath,
199
+ TLogger,
200
+ TSession,
201
+ TEventPublisher,
202
+ TEventPublisherServiceName,
203
+ TAuthorizers,
204
+ TAuditStorage,
205
+ TAuditStorageServiceName,
206
+ TAuditAction,
207
+ TDatabase,
208
+ TDatabaseServiceName
209
+ > {
210
+ // Validate that the authorizer exists in available authorizers
211
+ if (name !== 'none' && this.availableAuthorizers.length > 0) {
212
+ const authorizerExists = this.availableAuthorizers.some(
213
+ (a) => a.name === name,
214
+ );
215
+ if (!authorizerExists) {
216
+ const available = this.availableAuthorizers
217
+ .map((a) => a.name)
218
+ .join(', ');
219
+ throw new Error(
220
+ `Authorizer "${name as string}" not found in available authorizers: ${available}`,
221
+ );
222
+ }
223
+ }
224
+
225
+ return new EndpointFactory<
226
+ TServices,
227
+ TBasePath,
228
+ TLogger,
229
+ TSession,
230
+ TEventPublisher,
231
+ TEventPublisherServiceName,
232
+ TAuthorizers,
233
+ TAuditStorage,
234
+ TAuditStorageServiceName,
235
+ TAuditAction,
236
+ TDatabase,
237
+ TDatabaseServiceName
238
+ >({
239
+ defaultServices: this.defaultServices,
240
+ basePath: this.basePath,
241
+ defaultAuthorizeFn: this.defaultAuthorizeFn,
242
+ defaultLogger: this.defaultLogger,
243
+ defaultSessionExtractor: this.defaultSessionExtractor,
244
+ defaultEventPublisher: this.defaultEventPublisher,
245
+ availableAuthorizers: this.availableAuthorizers,
246
+ defaultAuthorizerName: name === 'none' ? undefined : name,
247
+ defaultAuditorStorage: this.defaultAuditorStorage,
248
+ defaultDatabaseService: this.defaultDatabaseService,
249
+ defaultActorExtractor: this.defaultActorExtractor,
250
+ });
251
+ }
252
+
184
253
  // Create a sub-router with a path prefix
185
254
  route<TPath extends string>(
186
255
  path: TPath,
@@ -423,7 +492,7 @@ export class EndpointFactory<
423
492
  }
424
493
 
425
494
  session<T>(
426
- session: SessionFn<TServices, TLogger, T>,
495
+ session: SessionFn<TServices, TLogger, T, TDatabase>,
427
496
  ): EndpointFactory<
428
497
  TServices,
429
498
  TBasePath,
@@ -513,7 +582,11 @@ export class EndpointFactory<
513
582
  basePath: this.basePath,
514
583
  defaultAuthorizeFn: this.defaultAuthorizeFn,
515
584
  defaultLogger: this.defaultLogger,
516
- defaultSessionExtractor: this.defaultSessionExtractor,
585
+ // Reset session extractor when database changes - user should call .session() after .database()
586
+ // to get proper type inference for the new database type
587
+ defaultSessionExtractor: this.defaultSessionExtractor as unknown as
588
+ | SessionFn<TServices, TLogger, TSession, T>
589
+ | undefined,
517
590
  defaultEventPublisher: this.defaultEventPublisher,
518
591
  availableAuthorizers: this.availableAuthorizers,
519
592
  defaultAuthorizerName: this.defaultAuthorizerName,
@@ -781,7 +854,7 @@ export interface EndpointFactoryOptions<
781
854
  basePath?: TBasePath;
782
855
  defaultAuthorizeFn?: AuthorizeFn<TServices, TLogger, TSession>;
783
856
  defaultLogger?: TLogger;
784
- defaultSessionExtractor?: SessionFn<TServices, TLogger, TSession>;
857
+ defaultSessionExtractor?: SessionFn<TServices, TLogger, TSession, TDatabase>;
785
858
  defaultEventPublisher?: Service<TEventPublisherServiceName, TEventPublisher>;
786
859
  defaultEvents?: MappedEvent<TEventPublisher, undefined>[];
787
860
  availableAuthorizers?: Authorizer[];
@@ -298,12 +298,23 @@ export class HonoEndpoint<
298
298
 
299
299
  const services = await serviceDiscovery.register(endpoint.services);
300
300
 
301
+ // Resolve database service early so it's available for session extraction
302
+ const rawDb = endpoint.databaseService
303
+ ? await serviceDiscovery
304
+ .register([endpoint.databaseService])
305
+ .then(
306
+ (s) =>
307
+ s[endpoint.databaseService!.serviceName as keyof typeof s],
308
+ )
309
+ : undefined;
310
+
301
311
  const session = await endpoint.getSession({
302
312
  services,
303
313
  logger,
304
314
  header,
305
315
  cookie,
306
- });
316
+ ...(rawDb !== undefined && { db: rawDb }),
317
+ } as any);
307
318
 
308
319
  const isAuthorized = await endpoint.authorize({
309
320
  header,
@@ -363,16 +374,6 @@ export class HonoEndpoint<
363
374
  logger.warn('No auditor storage service available');
364
375
  }
365
376
 
366
- // Resolve database service if configured
367
- const rawDb = endpoint.databaseService
368
- ? await serviceDiscovery
369
- .register([endpoint.databaseService])
370
- .then(
371
- (s) =>
372
- s[endpoint.databaseService!.serviceName as keyof typeof s],
373
- )
374
- : undefined;
375
-
376
377
  // Execute handler with automatic audit transaction support
377
378
  const result = await executeWithAuditTransaction(
378
379
  auditContext,
@@ -1,4 +1,8 @@
1
- import type { AuditActor, AuditStorage, AuditableAction } from '@geekmidas/audit';
1
+ import type {
2
+ AuditActor,
3
+ AuditStorage,
4
+ AuditableAction,
5
+ } from '@geekmidas/audit';
2
6
  import { DefaultAuditor } from '@geekmidas/audit';
3
7
  import { EnvironmentParser } from '@geekmidas/envkit';
4
8
  import type { EventPublisher } from '@geekmidas/events';
@@ -179,12 +183,17 @@ export class TestEndpointAdaptor<
179
183
  host: ctx.headers.host,
180
184
  method: this.endpoint.method,
181
185
  }) as TLogger;
186
+
187
+ // Get database from context for session extraction
188
+ const rawDb = (ctx as any).database as TDatabase;
189
+
182
190
  const session = await this.endpoint.getSession({
183
191
  logger,
184
192
  services: ctx.services,
185
193
  header,
186
194
  cookie,
187
- });
195
+ ...(rawDb !== undefined && { db: rawDb }),
196
+ } as any);
188
197
 
189
198
  // Create audit context if audit storage is provided
190
199
  // The auditorStorage instance is required when endpoint uses .auditor()
@@ -229,10 +238,6 @@ export class TestEndpointAdaptor<
229
238
  logger.warn('No auditor storage service available');
230
239
  }
231
240
 
232
- // Use database instance directly from context
233
- // The database instance is required when endpoint uses .database()
234
- const rawDb = (ctx as any).database as TDatabase;
235
-
236
241
  // Execute handler with automatic audit transaction support
237
242
  const result = await executeWithAuditTransaction(
238
243
  auditContext,
@@ -294,3 +294,144 @@ describe('EndpointFactory.authorizers', () => {
294
294
  expect(endpoint.tags).toEqual(['public', 'contact']);
295
295
  });
296
296
  });
297
+
298
+ describe('EndpointFactory.authorizer (default)', () => {
299
+ it('should set default authorizer for all endpoints', () => {
300
+ const factory = new EndpointFactory()
301
+ .authorizers(['iam', 'jwt'] as const)
302
+ .authorizer('jwt');
303
+
304
+ const endpoint1 = factory.get('/users').handle(async () => ({ users: [] }));
305
+ const endpoint2 = factory
306
+ .post('/users')
307
+ .body(z.object({ name: z.string() }))
308
+ .handle(async () => ({ id: '1' }));
309
+
310
+ expect(endpoint1.authorizer).toEqual({ name: 'jwt' });
311
+ expect(endpoint2.authorizer).toEqual({ name: 'jwt' });
312
+ });
313
+
314
+ it('should allow endpoint to override factory default authorizer', () => {
315
+ const factory = new EndpointFactory()
316
+ .authorizers(['iam', 'jwt'] as const)
317
+ .authorizer('jwt');
318
+
319
+ const endpoint = factory
320
+ .get('/admin')
321
+ .authorizer('iam')
322
+ .handle(async () => ({ admin: true }));
323
+
324
+ expect(endpoint.authorizer).toEqual({ name: 'iam' });
325
+ });
326
+
327
+ it('should allow endpoint to disable authorizer with none', () => {
328
+ const factory = new EndpointFactory()
329
+ .authorizers(['iam', 'jwt'] as const)
330
+ .authorizer('jwt');
331
+
332
+ const endpoint = factory
333
+ .get('/public')
334
+ .authorizer('none')
335
+ .handle(async () => ({ public: true }));
336
+
337
+ expect(endpoint.authorizer).toBeUndefined();
338
+ });
339
+
340
+ it('should throw error when setting non-existent default authorizer', () => {
341
+ const factory = new EndpointFactory().authorizers(['iam', 'jwt'] as const);
342
+
343
+ expect(() => {
344
+ // @ts-expect-error - testing invalid authorizer
345
+ factory.authorizer('invalid');
346
+ }).toThrow(
347
+ 'Authorizer "invalid" not found in available authorizers: iam, jwt',
348
+ );
349
+ });
350
+
351
+ it('should preserve default authorizer when chaining factory methods', () => {
352
+ const factory = new EndpointFactory()
353
+ .authorizers(['iam', 'jwt'] as const)
354
+ .authorizer('jwt')
355
+ .route('/api/v1');
356
+
357
+ const endpoint = factory.get('/users').handle(async () => ({ users: [] }));
358
+
359
+ expect(endpoint.authorizer).toEqual({ name: 'jwt' });
360
+ expect(endpoint.route).toBe('/api/v1/users');
361
+ });
362
+
363
+ it('should preserve default authorizer with services', () => {
364
+ const dbService = {
365
+ serviceName: 'database' as const,
366
+ register: async () => ({ query: async () => [] }),
367
+ };
368
+
369
+ const factory = new EndpointFactory()
370
+ .authorizers(['jwt'] as const)
371
+ .authorizer('jwt')
372
+ .services([dbService]);
373
+
374
+ const endpoint = factory.get('/users').handle(async ({ services }) => {
375
+ await services.database.query();
376
+ return { users: [] };
377
+ });
378
+
379
+ expect(endpoint.authorizer).toEqual({ name: 'jwt' });
380
+ });
381
+
382
+ it('should allow factory.authorizer("none") to clear default', () => {
383
+ const factory = new EndpointFactory()
384
+ .authorizers(['iam', 'jwt'] as const)
385
+ .authorizer('jwt')
386
+ .authorizer('none');
387
+
388
+ const endpoint = factory.get('/test').handle(async () => ({ test: true }));
389
+
390
+ expect(endpoint.authorizer).toBeUndefined();
391
+ });
392
+
393
+ it('should allow setting default authorizer without calling authorizers() first', () => {
394
+ // When no authorizers are defined, validation is skipped
395
+ const factory = new EndpointFactory().authorizer('custom');
396
+
397
+ const endpoint = factory.get('/test').handle(async () => ({ test: true }));
398
+
399
+ expect(endpoint.authorizer).toEqual({ name: 'custom' });
400
+ });
401
+
402
+ it('should work with nested route factories', () => {
403
+ const rootFactory = new EndpointFactory()
404
+ .authorizers(['iam', 'jwt', 'api-key'] as const)
405
+ .authorizer('jwt');
406
+
407
+ const apiFactory = rootFactory.route('/api');
408
+ const adminFactory = apiFactory.route('/admin');
409
+
410
+ const endpoint = adminFactory
411
+ .delete('/users/:id')
412
+ .params(z.object({ id: z.string() }))
413
+ .handle(async () => ({ deleted: true }));
414
+
415
+ expect(endpoint.route).toBe('/api/admin/users/:id');
416
+ expect(endpoint.authorizer).toEqual({ name: 'jwt' });
417
+ });
418
+
419
+ it('should allow sub-factory to override parent default authorizer', () => {
420
+ const rootFactory = new EndpointFactory()
421
+ .authorizers(['iam', 'jwt'] as const)
422
+ .authorizer('jwt');
423
+
424
+ const adminFactory = rootFactory.route('/admin').authorizer('iam');
425
+
426
+ const publicEndpoint = rootFactory
427
+ .get('/public')
428
+ .handle(async () => ({ public: true }));
429
+
430
+ const adminEndpoint = adminFactory
431
+ .get('/dashboard')
432
+ .handle(async () => ({ admin: true }));
433
+
434
+ expect(publicEndpoint.authorizer).toEqual({ name: 'jwt' });
435
+ expect(adminEndpoint.authorizer).toEqual({ name: 'iam' });
436
+ });
437
+ });