@geekmidas/constructs 0.0.1 → 0.0.3

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 (215) hide show
  1. package/dist/{AWSLambdaFunction-CpHFE2m6.d.mts → AWSLambdaFunction-CANc3Qo2.d.mts} +3 -3
  2. package/dist/{AWSLambdaFunction-qA5LqPsv.cjs → AWSLambdaFunction-DW9qrBNR.cjs} +2 -2
  3. package/dist/{AWSLambdaFunction-qA5LqPsv.cjs.map → AWSLambdaFunction-DW9qrBNR.cjs.map} +1 -1
  4. package/dist/{AWSLambdaFunction-DWIZYsCy.mjs → AWSLambdaFunction-nic3vzt3.mjs} +2 -2
  5. package/dist/{AWSLambdaFunction-DWIZYsCy.mjs.map → AWSLambdaFunction-nic3vzt3.mjs.map} +1 -1
  6. package/dist/{AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs → AWSLambdaSubscriberAdaptor-BhqrpTVc.mjs} +1 -1
  7. package/dist/{AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs.map → AWSLambdaSubscriberAdaptor-BhqrpTVc.mjs.map} +1 -1
  8. package/dist/{AWSLambdaSubscriberAdaptor-C1wQuucQ.d.mts → AWSLambdaSubscriberAdaptor-C6JYIZxn.d.mts} +2 -2
  9. package/dist/{AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs → AWSLambdaSubscriberAdaptor-ZuQAhW9_.cjs} +1 -1
  10. package/dist/{AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs.map → AWSLambdaSubscriberAdaptor-ZuQAhW9_.cjs.map} +1 -1
  11. package/dist/{AmazonApiGatewayEndpointAdaptor-BoBh7vvD.d.mts → AmazonApiGatewayEndpointAdaptor-DNZLntHj.d.mts} +3 -3
  12. package/dist/{AmazonApiGatewayEndpointAdaptor-i74DEUbc.cjs → AmazonApiGatewayEndpointAdaptor-D_Q_NTMT.cjs} +3 -3
  13. package/dist/{AmazonApiGatewayEndpointAdaptor-i74DEUbc.cjs.map → AmazonApiGatewayEndpointAdaptor-D_Q_NTMT.cjs.map} +1 -1
  14. package/dist/{AmazonApiGatewayEndpointAdaptor-Cx1oqcqh.mjs → AmazonApiGatewayEndpointAdaptor-QzIAnWzS.mjs} +3 -3
  15. package/dist/{AmazonApiGatewayEndpointAdaptor-Cx1oqcqh.mjs.map → AmazonApiGatewayEndpointAdaptor-QzIAnWzS.mjs.map} +1 -1
  16. package/dist/{AmazonApiGatewayV1EndpointAdaptor-CLmBDYsl.mjs → AmazonApiGatewayV1EndpointAdaptor-BF5bGWV1.mjs} +3 -3
  17. package/dist/{AmazonApiGatewayV1EndpointAdaptor-CLmBDYsl.mjs.map → AmazonApiGatewayV1EndpointAdaptor-BF5bGWV1.mjs.map} +1 -1
  18. package/dist/{AmazonApiGatewayV1EndpointAdaptor-GkMAUPL5.cjs → AmazonApiGatewayV1EndpointAdaptor-Bh4tckwd.cjs} +3 -3
  19. package/dist/{AmazonApiGatewayV1EndpointAdaptor-GkMAUPL5.cjs.map → AmazonApiGatewayV1EndpointAdaptor-Bh4tckwd.cjs.map} +1 -1
  20. package/dist/{AmazonApiGatewayV1EndpointAdaptor-EhMd1YqV.d.mts → AmazonApiGatewayV1EndpointAdaptor-DbJa4cpU.d.mts} +4 -4
  21. package/dist/{AmazonApiGatewayV2EndpointAdaptor-3RqegmJC.mjs → AmazonApiGatewayV2EndpointAdaptor-BOaOkLXF.mjs} +3 -3
  22. package/dist/{AmazonApiGatewayV2EndpointAdaptor-3RqegmJC.mjs.map → AmazonApiGatewayV2EndpointAdaptor-BOaOkLXF.mjs.map} +1 -1
  23. package/dist/{AmazonApiGatewayV2EndpointAdaptor-zfd1gqXA.d.mts → AmazonApiGatewayV2EndpointAdaptor-BlKn-KJ6.d.mts} +4 -4
  24. package/dist/{AmazonApiGatewayV2EndpointAdaptor-YlFoFSS9.cjs → AmazonApiGatewayV2EndpointAdaptor-L4Ywv3Pk.cjs} +3 -3
  25. package/dist/{AmazonApiGatewayV2EndpointAdaptor-YlFoFSS9.cjs.map → AmazonApiGatewayV2EndpointAdaptor-L4Ywv3Pk.cjs.map} +1 -1
  26. package/dist/{BaseFunctionBuilder-BFPVGnKi.d.mts → BaseFunctionBuilder-Dda7AiID.d.mts} +2 -2
  27. package/dist/{Construct-DIguIyw4.d.mts → Construct-DdyYENBD.d.mts} +1 -1
  28. package/dist/Construct.d.mts +1 -1
  29. package/dist/{Cron-Bgs6EQOb.mjs → Cron-BgJo6EW6.mjs} +1 -1
  30. package/dist/{Cron-Bgs6EQOb.mjs.map → Cron-BgJo6EW6.mjs.map} +1 -1
  31. package/dist/{Cron-ztnK6zgU.d.cts → Cron-BxMXmn4t.d.cts} +1 -1
  32. package/dist/{Cron-DQiCj3ef.cjs → Cron-JYYGj5ik.cjs} +1 -1
  33. package/dist/{Cron-DQiCj3ef.cjs.map → Cron-JYYGj5ik.cjs.map} +1 -1
  34. package/dist/{Cron-FpAw03k6.d.mts → Cron-NDBlJhb3.d.mts} +2 -2
  35. package/dist/{CronBuilder-DIBqJkh_.cjs → CronBuilder-BDDS21OP.cjs} +2 -2
  36. package/dist/{CronBuilder-DIBqJkh_.cjs.map → CronBuilder-BDDS21OP.cjs.map} +1 -1
  37. package/dist/{CronBuilder-Cje9K8lZ.d.cts → CronBuilder-C6K5AbIO.d.cts} +2 -2
  38. package/dist/{CronBuilder-DecAvvcn.mjs → CronBuilder-DVuhB_kA.mjs} +2 -2
  39. package/dist/{CronBuilder-DecAvvcn.mjs.map → CronBuilder-DVuhB_kA.mjs.map} +1 -1
  40. package/dist/{CronBuilder-B2clNQSP.d.mts → CronBuilder-s5x8V8hH.d.mts} +4 -4
  41. package/dist/{Endpoint-BaHC9y4Z.cjs → Endpoint-D1nnEsBU.cjs} +1 -1
  42. package/dist/{Endpoint-BaHC9y4Z.cjs.map → Endpoint-D1nnEsBU.cjs.map} +1 -1
  43. package/dist/{Endpoint-ierdM62O.mjs → Endpoint-DNlmybXV.mjs} +1 -1
  44. package/dist/{Endpoint-ierdM62O.mjs.map → Endpoint-DNlmybXV.mjs.map} +1 -1
  45. package/dist/{Endpoint-DCn53Vd8.d.mts → Endpoint-DYUjJdEs.d.mts} +3 -3
  46. package/dist/{EndpointBuilder-CP9RGwZH.d.cts → EndpointBuilder-1fw103D6.d.cts} +1 -1
  47. package/dist/{EndpointBuilder-Bfnb2oJr.d.mts → EndpointBuilder-B2iScUND.d.mts} +4 -4
  48. package/dist/{EndpointBuilder-BHFSpbPR.cjs → EndpointBuilder-BhRd626m.cjs} +2 -2
  49. package/dist/{EndpointBuilder-BHFSpbPR.cjs.map → EndpointBuilder-BhRd626m.cjs.map} +1 -1
  50. package/dist/{EndpointBuilder-BLUsoK3l.mjs → EndpointBuilder-CpjIMYb0.mjs} +2 -2
  51. package/dist/{EndpointBuilder-BLUsoK3l.mjs.map → EndpointBuilder-CpjIMYb0.mjs.map} +1 -1
  52. package/dist/{EndpointFactory-CXX4E6Gx.cjs → EndpointFactory-ChmVHWim.cjs} +2 -2
  53. package/dist/{EndpointFactory-CXX4E6Gx.cjs.map → EndpointFactory-ChmVHWim.cjs.map} +1 -1
  54. package/dist/{EndpointFactory-D2zgWbXZ.d.cts → EndpointFactory-D576BhaH.d.cts} +2 -2
  55. package/dist/{EndpointFactory-BYdDVCNj.mjs → EndpointFactory-DLpEbLzL.mjs} +2 -2
  56. package/dist/{EndpointFactory-BYdDVCNj.mjs.map → EndpointFactory-DLpEbLzL.mjs.map} +1 -1
  57. package/dist/{EndpointFactory-CNtMXgIh.d.mts → EndpointFactory-DZQpM-9K.d.mts} +3 -3
  58. package/dist/{Function-BsBxc2wA.d.mts → Function-C98H68DW.d.mts} +2 -2
  59. package/dist/{FunctionBuilder-C-PfPN3r.d.mts → FunctionBuilder-DBwR7jg7.d.mts} +4 -4
  60. package/dist/{FunctionExecutionWrapper-DvglBBjE.d.mts → FunctionExecutionWrapper-B0V7V8YS.d.mts} +2 -2
  61. package/dist/{FunctionExecutionWrapper-XGrSAAPD.mjs → FunctionExecutionWrapper-CPzSbfaI.mjs} +1 -1
  62. package/dist/{FunctionExecutionWrapper-XGrSAAPD.mjs.map → FunctionExecutionWrapper-CPzSbfaI.mjs.map} +1 -1
  63. package/dist/{FunctionExecutionWrapper-CElXEjPe.cjs → FunctionExecutionWrapper-UzfHDM2R.cjs} +1 -1
  64. package/dist/{FunctionExecutionWrapper-CElXEjPe.cjs.map → FunctionExecutionWrapper-UzfHDM2R.cjs.map} +1 -1
  65. package/dist/{HonoEndpointAdaptor-B0IO1zj2.d.mts → HonoEndpointAdaptor-01cH100U.d.mts} +5 -5
  66. package/dist/{HonoEndpointAdaptor-B4snrp7v.cjs → HonoEndpointAdaptor-6LERutxi.cjs} +4 -4
  67. package/dist/{HonoEndpointAdaptor-B4snrp7v.cjs.map → HonoEndpointAdaptor-6LERutxi.cjs.map} +1 -1
  68. package/dist/{HonoEndpointAdaptor-D-M4-6Tf.mjs → HonoEndpointAdaptor-fs2928iO.mjs} +4 -4
  69. package/dist/{HonoEndpointAdaptor-D-M4-6Tf.mjs.map → HonoEndpointAdaptor-fs2928iO.mjs.map} +1 -1
  70. package/dist/{HonoEndpointAdaptor-B6lW9Q1k.d.cts → HonoEndpointAdaptor-ua6mp3gt.d.cts} +3 -3
  71. package/dist/{Subscriber-BwuCaC9G.mjs → Subscriber-BTwKnz3c.mjs} +1 -1
  72. package/dist/{Subscriber-BwuCaC9G.mjs.map → Subscriber-BTwKnz3c.mjs.map} +1 -1
  73. package/dist/{Subscriber-THGsj7Iy.d.mts → Subscriber-BxH6n8zQ.d.mts} +2 -2
  74. package/dist/{Subscriber-iMRFG7ba.cjs → Subscriber-G7EUI3yc.cjs} +1 -1
  75. package/dist/{Subscriber-iMRFG7ba.cjs.map → Subscriber-G7EUI3yc.cjs.map} +1 -1
  76. package/dist/{SubscriberBuilder-CiPxgnKT.d.mts → SubscriberBuilder-BpSDPzBz.d.mts} +2 -2
  77. package/dist/{SubscriberBuilder-Dhz0C_t-.mjs → SubscriberBuilder-C1me_972.mjs} +2 -2
  78. package/dist/{SubscriberBuilder-Dhz0C_t-.mjs.map → SubscriberBuilder-C1me_972.mjs.map} +1 -1
  79. package/dist/{SubscriberBuilder-wthr-FL9.cjs → SubscriberBuilder-C6iZvuDe.cjs} +2 -2
  80. package/dist/{SubscriberBuilder-wthr-FL9.cjs.map → SubscriberBuilder-C6iZvuDe.cjs.map} +1 -1
  81. package/dist/{SubscriberBuilder-DuIgxuzc.d.cts → SubscriberBuilder-DgljKtYu.d.cts} +1 -1
  82. package/dist/TestEndpointAdaptor-B4SvJvK-.cjs +54 -0
  83. package/dist/TestEndpointAdaptor-B4SvJvK-.cjs.map +1 -0
  84. package/dist/TestEndpointAdaptor-CHcgyI3V.d.cts +24 -0
  85. package/dist/TestEndpointAdaptor-CelYsQi0.mjs +48 -0
  86. package/dist/TestEndpointAdaptor-CelYsQi0.mjs.map +1 -0
  87. package/dist/TestEndpointAdaptor-Da0ooGt2.d.mts +24 -0
  88. package/dist/adaptors/aws.cjs +8 -8
  89. package/dist/adaptors/aws.d.cts +1 -1
  90. package/dist/adaptors/aws.d.mts +14 -14
  91. package/dist/adaptors/aws.mjs +8 -8
  92. package/dist/adaptors/hono.cjs +4 -4
  93. package/dist/adaptors/hono.d.cts +2 -2
  94. package/dist/adaptors/hono.d.mts +8 -8
  95. package/dist/adaptors/hono.mjs +4 -4
  96. package/dist/adaptors/testing.cjs +10 -0
  97. package/dist/adaptors/testing.d.cts +9 -0
  98. package/dist/adaptors/testing.d.mts +9 -0
  99. package/dist/adaptors/testing.mjs +10 -0
  100. package/dist/crons/Cron.cjs +1 -1
  101. package/dist/crons/Cron.d.cts +2 -2
  102. package/dist/crons/Cron.d.mts +6 -6
  103. package/dist/crons/Cron.mjs +1 -1
  104. package/dist/crons/CronBuilder.cjs +2 -2
  105. package/dist/crons/CronBuilder.d.cts +3 -3
  106. package/dist/crons/CronBuilder.d.mts +7 -7
  107. package/dist/crons/CronBuilder.mjs +2 -2
  108. package/dist/crons/index.cjs +2 -2
  109. package/dist/crons/index.d.cts +7 -7
  110. package/dist/crons/index.d.mts +11 -11
  111. package/dist/crons/index.mjs +2 -2
  112. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +2 -2
  113. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +1 -1
  114. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +8 -8
  115. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +2 -2
  116. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +4 -4
  117. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +1 -1
  118. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +9 -9
  119. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +4 -4
  120. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +4 -4
  121. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +1 -1
  122. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +9 -9
  123. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +4 -4
  124. package/dist/endpoints/Endpoint.cjs +1 -1
  125. package/dist/endpoints/Endpoint.d.cts +1 -1
  126. package/dist/endpoints/Endpoint.d.mts +7 -7
  127. package/dist/endpoints/Endpoint.mjs +1 -1
  128. package/dist/endpoints/EndpointBuilder.cjs +2 -2
  129. package/dist/endpoints/EndpointBuilder.d.cts +2 -2
  130. package/dist/endpoints/EndpointBuilder.d.mts +8 -8
  131. package/dist/endpoints/EndpointBuilder.mjs +2 -2
  132. package/dist/endpoints/EndpointFactory.cjs +3 -3
  133. package/dist/endpoints/EndpointFactory.d.cts +3 -3
  134. package/dist/endpoints/EndpointFactory.d.mts +9 -9
  135. package/dist/endpoints/EndpointFactory.mjs +3 -3
  136. package/dist/endpoints/HonoEndpointAdaptor.cjs +4 -4
  137. package/dist/endpoints/HonoEndpointAdaptor.d.cts +2 -2
  138. package/dist/endpoints/HonoEndpointAdaptor.d.mts +8 -8
  139. package/dist/endpoints/HonoEndpointAdaptor.mjs +4 -4
  140. package/dist/endpoints/TestEndpointAdaptor.cjs +4 -48
  141. package/dist/endpoints/TestEndpointAdaptor.d.cts +5 -25
  142. package/dist/endpoints/TestEndpointAdaptor.d.mts +9 -29
  143. package/dist/endpoints/TestEndpointAdaptor.mjs +4 -47
  144. package/dist/endpoints/helpers.cjs +2 -2
  145. package/dist/endpoints/helpers.d.cts +1 -1
  146. package/dist/endpoints/helpers.d.mts +7 -7
  147. package/dist/endpoints/helpers.mjs +2 -2
  148. package/dist/endpoints/index.cjs +3 -3
  149. package/dist/endpoints/index.d.cts +5 -5
  150. package/dist/endpoints/index.d.mts +11 -11
  151. package/dist/endpoints/index.mjs +3 -3
  152. package/dist/endpoints/parseHonoQuery.cjs +1 -1
  153. package/dist/endpoints/parseHonoQuery.mjs +1 -1
  154. package/dist/endpoints/parseQueryParams.cjs +1 -1
  155. package/dist/endpoints/parseQueryParams.mjs +1 -1
  156. package/dist/functions/AWSLambdaFunction.cjs +2 -2
  157. package/dist/functions/AWSLambdaFunction.d.mts +4 -4
  158. package/dist/functions/AWSLambdaFunction.mjs +2 -2
  159. package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
  160. package/dist/functions/Function.d.mts +2 -2
  161. package/dist/functions/FunctionBuilder.d.mts +4 -4
  162. package/dist/functions/FunctionExecutionWrapper.cjs +1 -1
  163. package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
  164. package/dist/functions/FunctionExecutionWrapper.mjs +1 -1
  165. package/dist/functions/TestFunctionAdaptor.d.mts +2 -2
  166. package/dist/functions/index.d.cts +1 -1
  167. package/dist/functions/index.d.mts +5 -5
  168. package/dist/{helpers-DbpO95aE.mjs → helpers-CP7A0U_s.mjs} +2 -2
  169. package/dist/{helpers-DbpO95aE.mjs.map → helpers-CP7A0U_s.mjs.map} +1 -1
  170. package/dist/{helpers-BeGM4pP_.cjs → helpers-CjvCSIF5.cjs} +2 -2
  171. package/dist/{helpers-BeGM4pP_.cjs.map → helpers-CjvCSIF5.cjs.map} +1 -1
  172. package/dist/index-BXTN4mwI.d.mts +9 -0
  173. package/dist/index-zOH9f4sh.d.cts +9 -0
  174. package/dist/index.d.mts +2 -2
  175. package/dist/{parseHonoQuery-DopC24vB.cjs → parseHonoQuery-BiPp8bEJ.cjs} +1 -1
  176. package/dist/{parseHonoQuery-DopC24vB.cjs.map → parseHonoQuery-BiPp8bEJ.cjs.map} +1 -1
  177. package/dist/{parseHonoQuery-znDKBhdE.mjs → parseHonoQuery-yWRoKFFl.mjs} +1 -1
  178. package/dist/{parseHonoQuery-znDKBhdE.mjs.map → parseHonoQuery-yWRoKFFl.mjs.map} +1 -1
  179. package/dist/{parseQueryParams-BzPop4I1.cjs → parseQueryParams-C2EjouGt.cjs} +1 -1
  180. package/dist/{parseQueryParams-BzPop4I1.cjs.map → parseQueryParams-C2EjouGt.cjs.map} +1 -1
  181. package/dist/{parseQueryParams-BJaRh3OB.mjs → parseQueryParams-DSk9xl09.mjs} +1 -1
  182. package/dist/{parseQueryParams-BJaRh3OB.mjs.map → parseQueryParams-DSk9xl09.mjs.map} +1 -1
  183. package/dist/publisher.d.mts +1 -1
  184. package/dist/subscribers/AWSLambdaSubscriberAdaptor.cjs +1 -1
  185. package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +3 -3
  186. package/dist/subscribers/AWSLambdaSubscriberAdaptor.mjs +1 -1
  187. package/dist/subscribers/Subscriber.cjs +1 -1
  188. package/dist/subscribers/Subscriber.d.mts +2 -2
  189. package/dist/subscribers/Subscriber.mjs +1 -1
  190. package/dist/subscribers/SubscriberBuilder.cjs +2 -2
  191. package/dist/subscribers/SubscriberBuilder.d.cts +1 -1
  192. package/dist/subscribers/SubscriberBuilder.d.mts +3 -3
  193. package/dist/subscribers/SubscriberBuilder.mjs +2 -2
  194. package/dist/subscribers/index.cjs +2 -2
  195. package/dist/subscribers/index.d.cts +3 -3
  196. package/dist/subscribers/index.d.mts +5 -5
  197. package/dist/subscribers/index.mjs +2 -2
  198. package/dist/{types-DBKNYvsW.d.mts → types-CVq20-fE.d.mts} +1 -1
  199. package/dist/types.d.mts +1 -1
  200. package/package.json +10 -5
  201. package/src/adaptors/testing.ts +1 -0
  202. package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +62 -13
  203. package/src/endpoints/Endpoint.ts +243 -19
  204. package/src/endpoints/HonoEndpointAdaptor.ts +52 -16
  205. package/src/endpoints/TestEndpointAdaptor.ts +45 -12
  206. package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +240 -0
  207. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +177 -200
  208. package/src/endpoints/__tests__/Endpoint.cookies.spec.ts +120 -0
  209. package/src/endpoints/__tests__/Endpoint.spec.ts +12 -0
  210. package/src/endpoints/__tests__/ResponseBuilder.spec.ts +235 -0
  211. package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +348 -0
  212. package/dist/endpoints/TestEndpointAdaptor.cjs.map +0 -1
  213. package/dist/endpoints/TestEndpointAdaptor.mjs.map +0 -1
  214. package/dist/index-CuGR4L7O.d.mts +0 -9
  215. package/dist/index-Fg3N3EKD.d.cts +0 -9
@@ -6,11 +6,7 @@ import type { OpenAPIV3_1 } from 'openapi-types';
6
6
 
7
7
  import type { Service, ServiceRecord } from '@geekmidas/services';
8
8
  import { ConstructType } from '../Construct';
9
- import {
10
- Function,
11
- type FunctionContext,
12
- type FunctionHandler,
13
- } from '../functions';
9
+ import { Function, type FunctionHandler } from '../functions';
14
10
 
15
11
  import type {
16
12
  EventPublisher,
@@ -88,6 +84,8 @@ export class Endpoint<
88
84
  tags?: string[];
89
85
  /** The HTTP success status code to return (default: 200) */
90
86
  public readonly status: SuccessStatus;
87
+ /** Default headers to apply to all responses */
88
+ public readonly defaultHeaders: Record<string, string> = {};
91
89
  /** Function to extract session data from the request context */
92
90
  public getSession: SessionFn<TServices, TLogger, TSession> = () =>
93
91
  ({}) as TSession;
@@ -95,6 +93,14 @@ export class Endpoint<
95
93
  public authorize: AuthorizeFn<TServices, TLogger, TSession> = () => true;
96
94
  /** Optional rate limiting configuration */
97
95
  public rateLimit?: RateLimitConfig;
96
+ /** The endpoint handler function */
97
+ private endpointFn!: EndpointHandler<
98
+ TInput,
99
+ TServices,
100
+ TLogger,
101
+ OutSchema,
102
+ TSession
103
+ >;
98
104
 
99
105
  /**
100
106
  * Builds a complete OpenAPI 3.1 schema from an array of endpoints.
@@ -188,6 +194,81 @@ export class Endpoint<
188
194
  };
189
195
  }
190
196
 
197
+ /**
198
+ * Parses cookie string and creates a cookie lookup function.
199
+ *
200
+ * @param cookieHeader - The Cookie header value
201
+ * @returns Function to retrieve cookie values by name
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * const cookieFn = Endpoint.createCookies('session=abc123; theme=dark');
206
+ * cookieFn('session'); // Returns 'abc123'
207
+ * cookieFn('theme'); // Returns 'dark'
208
+ * ```
209
+ */
210
+ static createCookies(cookieHeader: string | undefined): CookieFn {
211
+ const cookieMap = new Map<string, string>();
212
+
213
+ if (cookieHeader) {
214
+ // Parse cookie string: "name1=value1; name2=value2"
215
+ const cookies = cookieHeader.split(';');
216
+ for (const cookie of cookies) {
217
+ const [name, ...valueParts] = cookie.trim().split('=');
218
+ if (name) {
219
+ const value = valueParts.join('='); // Handle values with = in them
220
+ cookieMap.set(name, decodeURIComponent(value));
221
+ }
222
+ }
223
+ }
224
+
225
+ return function get(name: string): string | undefined {
226
+ return cookieMap.get(name);
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Formats a cookie as a Set-Cookie header string.
232
+ *
233
+ * @param name - Cookie name
234
+ * @param value - Cookie value
235
+ * @param options - Cookie options (httpOnly, secure, sameSite, etc.)
236
+ * @returns Formatted Set-Cookie header string
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * const header = Endpoint.formatCookieHeader('session', 'abc123', {
241
+ * httpOnly: true,
242
+ * secure: true,
243
+ * sameSite: 'strict',
244
+ * maxAge: 3600
245
+ * });
246
+ * // Returns: "session=abc123; Max-Age=3600; HttpOnly; Secure; SameSite=Strict"
247
+ * ```
248
+ */
249
+ static formatCookieHeader(
250
+ name: string,
251
+ value: string,
252
+ options?: CookieOptions,
253
+ ): string {
254
+ let cookie = `${name}=${value}`;
255
+
256
+ if (options) {
257
+ if (options.domain) cookie += `; Domain=${options.domain}`;
258
+ if (options.path) cookie += `; Path=${options.path}`;
259
+ if (options.expires)
260
+ cookie += `; Expires=${options.expires.toUTCString()}`;
261
+ if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`;
262
+ if (options.httpOnly) cookie += '; HttpOnly';
263
+ if (options.secure) cookie += '; Secure';
264
+ if (options.sameSite) {
265
+ cookie += `; SameSite=${options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1)}`;
266
+ }
267
+ }
268
+
269
+ return cookie;
270
+ }
271
+
191
272
  /**
192
273
  * Extracts and refines input data from the endpoint context.
193
274
  *
@@ -207,18 +288,36 @@ export class Endpoint<
207
288
  return input;
208
289
  }
209
290
 
210
- handler: EndpointHandler<TInput, TServices, TLogger, OutSchema, TSession> = (
291
+ handler = (
211
292
  ctx: EndpointContext<TInput, TServices, TLogger, TSession>,
293
+ response: ResponseBuilder,
212
294
  ): OutSchema extends StandardSchemaV1
213
- ? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>
214
- : void | Promise<void> => {
215
- return this.fn({
216
- ...this.refineInput(ctx),
217
- services: ctx.services,
218
- logger: ctx.logger,
219
- header: ctx.header,
220
- session: ctx.session,
221
- } as unknown as FunctionContext<TInput, TServices, TLogger>);
295
+ ?
296
+ | InferStandardSchema<OutSchema>
297
+ | ResponseWithMetadata<InferStandardSchema<OutSchema>>
298
+ | Promise<InferStandardSchema<OutSchema>>
299
+ | Promise<ResponseWithMetadata<InferStandardSchema<OutSchema>>>
300
+ :
301
+ | any
302
+ | ResponseWithMetadata<any>
303
+ | Promise<any>
304
+ | Promise<ResponseWithMetadata<any>> => {
305
+ // Apply default headers to response builder
306
+ for (const [key, value] of Object.entries(this.defaultHeaders)) {
307
+ response.header(key, value);
308
+ }
309
+
310
+ return this.endpointFn(
311
+ {
312
+ ...this.refineInput(ctx),
313
+ services: ctx.services,
314
+ logger: ctx.logger,
315
+ header: ctx.header,
316
+ cookie: ctx.cookie,
317
+ session: ctx.session,
318
+ } as EndpointContext<TInput, TServices, TLogger, TSession>,
319
+ response,
320
+ );
222
321
  };
223
322
 
224
323
  /**
@@ -235,6 +334,20 @@ export class Endpoint<
235
334
  );
236
335
  }
237
336
 
337
+ /**
338
+ * Helper to check if response has metadata
339
+ */
340
+ static hasMetadata<T>(
341
+ response: T | ResponseWithMetadata<T>,
342
+ ): response is ResponseWithMetadata<T> {
343
+ return (
344
+ response !== null &&
345
+ typeof response === 'object' &&
346
+ 'data' in response &&
347
+ 'metadata' in response
348
+ );
349
+ }
350
+
238
351
  /**
239
352
  * Converts Express-style route params to OpenAPI format.
240
353
  * @returns Route with ':param' converted to '{param}'
@@ -433,6 +546,8 @@ export class Endpoint<
433
546
  this.description = description;
434
547
  this.tags = tags;
435
548
  this.status = status;
549
+ this.endpointFn = fn;
550
+
436
551
  if (getSession) {
437
552
  this.getSession = getSession;
438
553
  }
@@ -553,6 +668,7 @@ export type AuthorizeContext<
553
668
  services: ServiceRecord<TServices>;
554
669
  logger: TLogger;
555
670
  header: HeaderFn;
671
+ cookie: CookieFn;
556
672
  session: TSession;
557
673
  };
558
674
  /**
@@ -587,6 +703,7 @@ export type SessionContext<
587
703
  services: ServiceRecord<TServices>;
588
704
  logger: TLogger;
589
705
  header: HeaderFn;
706
+ cookie: CookieFn;
590
707
  };
591
708
  /**
592
709
  * Function type for extracting session data from a request.
@@ -669,9 +786,96 @@ export type EndpointHeaders = Map<string, string>;
669
786
  */
670
787
  export type HeaderFn = SingleHeaderFn;
671
788
 
789
+ /**
790
+ * Function type for retrieving cookie values.
791
+ *
792
+ * @param name - The cookie name
793
+ * @returns The cookie value or undefined if not found
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * const sessionId = cookie('session');
798
+ * ```
799
+ */
800
+ export type CookieFn = (name: string) => string | undefined;
801
+
802
+ /**
803
+ * Cookie options matching standard Set-Cookie attributes
804
+ */
805
+ export interface CookieOptions {
806
+ domain?: string;
807
+ path?: string;
808
+ expires?: Date;
809
+ maxAge?: number;
810
+ httpOnly?: boolean;
811
+ secure?: boolean;
812
+ sameSite?: 'strict' | 'lax' | 'none';
813
+ }
814
+
815
+ /**
816
+ * Response metadata that handlers can set
817
+ */
818
+ export interface ResponseMetadata {
819
+ headers?: Record<string, string>;
820
+ cookies?: Map<string, { value: string; options?: CookieOptions }>;
821
+ status?: SuccessStatus;
822
+ }
823
+
824
+ /**
825
+ * Return type for handlers that want to set response metadata
826
+ */
827
+ export interface ResponseWithMetadata<T> {
828
+ data: T;
829
+ metadata: ResponseMetadata;
830
+ }
831
+
832
+ /**
833
+ * Response builder for fluent API in handlers
834
+ */
835
+ export class ResponseBuilder {
836
+ private metadata: ResponseMetadata = {
837
+ headers: {},
838
+ cookies: new Map(),
839
+ };
840
+
841
+ header(key: string, value: string): this {
842
+ this.metadata.headers![key] = value;
843
+ return this;
844
+ }
845
+
846
+ cookie(name: string, value: string, options?: CookieOptions): this {
847
+ this.metadata.cookies!.set(name, { value, options });
848
+ return this;
849
+ }
850
+
851
+ deleteCookie(
852
+ name: string,
853
+ options?: Pick<CookieOptions, 'domain' | 'path'>,
854
+ ): this {
855
+ this.metadata.cookies!.set(name, {
856
+ value: '',
857
+ options: { ...options, maxAge: 0, expires: new Date(0) },
858
+ });
859
+ return this;
860
+ }
861
+
862
+ status(code: SuccessStatus): this {
863
+ this.metadata.status = code;
864
+ return this;
865
+ }
866
+
867
+ send<T>(data: T): ResponseWithMetadata<T> {
868
+ return { data, metadata: this.metadata };
869
+ }
870
+
871
+ getMetadata(): ResponseMetadata {
872
+ return this.metadata;
873
+ }
874
+ }
875
+
672
876
  /**
673
877
  * The execution context provided to endpoint handlers.
674
- * Contains all parsed input data, services, logger, headers, and session.
878
+ * Contains all parsed input data, services, logger, headers, cookies, and session.
675
879
  *
676
880
  * @template Input - The input schemas (body, query, params)
677
881
  * @template TServices - Available service dependencies
@@ -690,6 +894,8 @@ export type EndpointContext<
690
894
  logger: TLogger;
691
895
  /** Function to retrieve request headers */
692
896
  header: HeaderFn;
897
+ /** Function to retrieve request cookies */
898
+ cookie: CookieFn;
693
899
  /** Session data extracted by getSession */
694
900
  session: TSession;
695
901
  } & InferComposableStandardSchema<Input>;
@@ -704,14 +910,23 @@ export type EndpointContext<
704
910
  * @template TSession - Session data type
705
911
  *
706
912
  * @param ctx - The endpoint execution context
707
- * @returns The response data (validated if OutSchema is provided)
913
+ * @param response - Response builder for setting cookies, headers, and status
914
+ * @returns The response data (validated if OutSchema is provided) or ResponseWithMetadata
708
915
  *
709
916
  * @example
710
917
  * ```typescript
918
+ * // Simple response
711
919
  * const handler: EndpointHandler<Input, [UserService], Logger, UserSchema> =
712
920
  * async ({ params, services }) => {
713
921
  * return await services.users.findById(params.id);
714
922
  * };
923
+ *
924
+ * // With response builder
925
+ * const handler: EndpointHandler<Input, [UserService], Logger, UserSchema> =
926
+ * async ({ params, services }, response) => {
927
+ * const user = await services.users.findById(params.id);
928
+ * return response.header('X-User-Id', user.id).send(user);
929
+ * };
715
930
  * ```
716
931
  */
717
932
  export type EndpointHandler<
@@ -722,9 +937,18 @@ export type EndpointHandler<
722
937
  TSession = unknown,
723
938
  > = (
724
939
  ctx: EndpointContext<TInput, TServices, TLogger, TSession>,
940
+ response: ResponseBuilder,
725
941
  ) => OutSchema extends StandardSchemaV1
726
- ? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>
727
- : any | Promise<any>;
942
+ ?
943
+ | InferStandardSchema<OutSchema>
944
+ | ResponseWithMetadata<InferStandardSchema<OutSchema>>
945
+ | Promise<InferStandardSchema<OutSchema>>
946
+ | Promise<ResponseWithMetadata<InferStandardSchema<OutSchema>>>
947
+ :
948
+ | unknown
949
+ | ResponseWithMetadata<unknown>
950
+ | Promise<unknown>
951
+ | Promise<ResponseWithMetadata<unknown>>;
728
952
 
729
953
  /**
730
954
  * HTTP success status codes that can be returned by endpoints.
@@ -4,12 +4,14 @@ import type { Logger } from '@geekmidas/logger';
4
4
  import { checkRateLimit, getRateLimitHeaders } from '@geekmidas/rate-limit';
5
5
  import type { StandardSchemaV1 } from '@standard-schema/spec';
6
6
  import { type Context, Hono } from 'hono';
7
+ import { setCookie } from 'hono/cookie';
7
8
  import { validator } from 'hono/validator';
8
9
  import type { HttpMethod, LowerHttpMethod } from '../types';
9
10
  import {
10
11
  Endpoint,
11
12
  type EndpointContext,
12
13
  type EndpointSchemas,
14
+ ResponseBuilder,
13
15
  } from './Endpoint';
14
16
  import { getEndpointsFromRoutes } from './helpers';
15
17
  import { parseHonoQuery } from './parseHonoQuery';
@@ -242,6 +244,7 @@ export class HonoEndpoint<
242
244
  const headerValues = c.req.header();
243
245
 
244
246
  const header = Endpoint.createHeaders(headerValues);
247
+ const cookie = Endpoint.createCookies(headerValues.cookie);
245
248
 
246
249
  const services = await serviceDiscovery.register(endpoint.services);
247
250
 
@@ -249,10 +252,12 @@ export class HonoEndpoint<
249
252
  services,
250
253
  logger,
251
254
  header,
255
+ cookie,
252
256
  });
253
257
 
254
258
  const isAuthorized = await endpoint.authorize({
255
259
  header,
260
+ cookie,
256
261
  services,
257
262
  logger,
258
263
  session,
@@ -286,29 +291,60 @@ export class HonoEndpoint<
286
291
  }
287
292
  }
288
293
 
289
- const response = await endpoint.handler({
290
- services,
291
- logger,
292
- body: c.req.valid('json'),
293
- query: c.req.valid('query'),
294
- params: c.req.valid('param'),
295
- session,
296
- header: Endpoint.createHeaders(headerValues),
297
- } as unknown as EndpointContext<
298
- TInput,
299
- TServices,
300
- TLogger,
301
- TSession
302
- >);
294
+ const responseBuilder = new ResponseBuilder();
295
+ const response = await endpoint.handler(
296
+ {
297
+ services,
298
+ logger,
299
+ body: c.req.valid('json'),
300
+ query: c.req.valid('query'),
301
+ params: c.req.valid('param'),
302
+ session,
303
+ header: Endpoint.createHeaders(headerValues),
304
+ cookie: Endpoint.createCookies(headerValues.cookie),
305
+ } as unknown as EndpointContext<
306
+ TInput,
307
+ TServices,
308
+ TLogger,
309
+ TSession
310
+ >,
311
+ responseBuilder,
312
+ );
303
313
 
304
314
  // Publish events if configured
305
315
 
306
316
  // Validate output if schema is defined
307
317
 
308
318
  try {
309
- const status = endpoint.status as ContentfulStatusCode;
319
+ // Check if response has metadata
320
+ let data = response;
321
+ let metadata = responseBuilder.getMetadata();
322
+ let status = endpoint.status as ContentfulStatusCode;
323
+
324
+ if (Endpoint.hasMetadata(response)) {
325
+ data = response.data;
326
+ metadata = response.metadata;
327
+ }
328
+
329
+ // Apply response metadata
330
+ if (metadata.status) {
331
+ status = metadata.status as ContentfulStatusCode;
332
+ }
333
+
334
+ if (metadata.headers) {
335
+ for (const [key, value] of Object.entries(metadata.headers)) {
336
+ c.header(key, value);
337
+ }
338
+ }
339
+
340
+ if (metadata.cookies) {
341
+ for (const [name, { value, options }] of metadata.cookies) {
342
+ setCookie(c, name, value, options);
343
+ }
344
+ }
345
+
310
346
  const output = endpoint.outputSchema
311
- ? await endpoint.parseOutput(response)
347
+ ? await endpoint.parseOutput(data)
312
348
  : ({} as any);
313
349
  // @ts-ignore
314
350
  c.set('__response', output);
@@ -13,7 +13,12 @@ import {
13
13
  import type { StandardSchemaV1 } from '@standard-schema/spec';
14
14
  import { publishConstructEvents } from '../publisher';
15
15
  import type { HttpMethod } from '../types';
16
- import { Endpoint, type EndpointSchemas } from './Endpoint';
16
+ import {
17
+ Endpoint,
18
+ type EndpointSchemas,
19
+ ResponseBuilder,
20
+ type ResponseWithMetadata,
21
+ } from './Endpoint';
17
22
 
18
23
  export class TestEndpointAdaptor<
19
24
  TRoute extends string,
@@ -79,7 +84,10 @@ export class TestEndpointAdaptor<
79
84
  TEventPublisher,
80
85
  TEventPublisherServiceName
81
86
  >,
82
- ): Promise<InferStandardSchema<TOutSchema>> {
87
+ ): Promise<
88
+ | InferStandardSchema<TOutSchema>
89
+ | ResponseWithMetadata<InferStandardSchema<TOutSchema>>
90
+ > {
83
91
  const body = await this.endpoint.parseInput((ctx as any).body, 'body');
84
92
  const query = await this.endpoint.parseInput((ctx as any).query, 'query');
85
93
  const params = await this.endpoint.parseInput(
@@ -88,6 +96,7 @@ export class TestEndpointAdaptor<
88
96
  );
89
97
 
90
98
  const header = Endpoint.createHeaders(ctx.headers);
99
+ const cookie = Endpoint.createCookies(ctx.headers.cookie);
91
100
  const logger = this.endpoint.logger.child({
92
101
  route: this.endpoint.route,
93
102
  host: ctx.headers.host,
@@ -97,23 +106,47 @@ export class TestEndpointAdaptor<
97
106
  logger,
98
107
  services: ctx.services,
99
108
  header,
109
+ cookie,
100
110
  });
101
111
 
102
- const response = await this.endpoint.handler({
103
- body,
104
- query,
105
- params,
106
- session,
107
- services: ctx.services,
108
- logger,
109
- header,
110
- } as any);
112
+ const responseBuilder = new ResponseBuilder();
113
+ const response = await this.endpoint.handler(
114
+ {
115
+ body,
116
+ query,
117
+ params,
118
+ session,
119
+ services: ctx.services,
120
+ logger,
121
+ header,
122
+ cookie,
123
+ } as any,
124
+ responseBuilder,
125
+ );
126
+
127
+ // Check if response has metadata
128
+ let data = response;
129
+ let metadata = responseBuilder.getMetadata();
111
130
 
112
- const output = await this.endpoint.parseOutput(response);
131
+ if (Endpoint.hasMetadata(response)) {
132
+ data = response.data;
133
+ metadata = response.metadata;
134
+ }
135
+
136
+ const output = await this.endpoint.parseOutput(data);
113
137
  ctx.publisher && (await this.serviceDiscovery.register([ctx.publisher]));
114
138
 
115
139
  await publishConstructEvents(this.endpoint, output, this.serviceDiscovery);
116
140
 
141
+ // Return with metadata if any was set
142
+ if (
143
+ (metadata.headers && Object.keys(metadata.headers).length > 0) ||
144
+ (metadata.cookies && metadata.cookies.size > 0) ||
145
+ metadata.status
146
+ ) {
147
+ return { data: output, metadata };
148
+ }
149
+
117
150
  return output;
118
151
  }
119
152
  }