@geekmidas/constructs 0.1.0 → 0.2.0

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 (182) hide show
  1. package/dist/{AWSLambdaFunction-DCh1tOhB.d.mts → AWSLambdaFunction-D9RZhm0N.d.mts} +3 -3
  2. package/dist/{AWSLambdaSubscriberAdaptor-DtNZPMoV.d.mts → AWSLambdaSubscriberAdaptor-C0aZBU64.d.mts} +2 -2
  3. package/dist/{AmazonApiGatewayEndpointAdaptor-CPqlw2Rx.cjs → AmazonApiGatewayEndpointAdaptor-Bk6ssx3K.cjs} +38 -25
  4. package/dist/AmazonApiGatewayEndpointAdaptor-Bk6ssx3K.cjs.map +1 -0
  5. package/dist/{AmazonApiGatewayEndpointAdaptor-TP_hLNAa.d.cts → AmazonApiGatewayEndpointAdaptor-CbJqLU6I.d.cts} +2 -2
  6. package/dist/{AmazonApiGatewayEndpointAdaptor-BaTM2TNu.d.mts → AmazonApiGatewayEndpointAdaptor-DC3N7zY_.d.mts} +3 -3
  7. package/dist/{AmazonApiGatewayEndpointAdaptor-Cm4iD199.mjs → AmazonApiGatewayEndpointAdaptor-pEWzF2uY.mjs} +38 -25
  8. package/dist/AmazonApiGatewayEndpointAdaptor-pEWzF2uY.mjs.map +1 -0
  9. package/dist/{AmazonApiGatewayV1EndpointAdaptor-B2ZpUFiC.d.mts → AmazonApiGatewayV1EndpointAdaptor-BVxgQ-7J.d.mts} +4 -4
  10. package/dist/{AmazonApiGatewayV1EndpointAdaptor-CConfCqz.d.cts → AmazonApiGatewayV1EndpointAdaptor-CVwJ5k16.d.cts} +3 -3
  11. package/dist/{AmazonApiGatewayV1EndpointAdaptor-D38HuQa9.mjs → AmazonApiGatewayV1EndpointAdaptor-MJpRbIaQ.mjs} +2 -2
  12. package/dist/{AmazonApiGatewayV1EndpointAdaptor-D38HuQa9.mjs.map → AmazonApiGatewayV1EndpointAdaptor-MJpRbIaQ.mjs.map} +1 -1
  13. package/dist/{AmazonApiGatewayV1EndpointAdaptor-tjpvLBRb.cjs → AmazonApiGatewayV1EndpointAdaptor-uBp_4zLf.cjs} +2 -2
  14. package/dist/{AmazonApiGatewayV1EndpointAdaptor-tjpvLBRb.cjs.map → AmazonApiGatewayV1EndpointAdaptor-uBp_4zLf.cjs.map} +1 -1
  15. package/dist/{AmazonApiGatewayV2EndpointAdaptor-DurJvFwa.d.cts → AmazonApiGatewayV2EndpointAdaptor-1oBZdQH3.d.cts} +3 -3
  16. package/dist/{AmazonApiGatewayV2EndpointAdaptor-BwMQInBi.d.mts → AmazonApiGatewayV2EndpointAdaptor-C3H8Hpv7.d.mts} +4 -4
  17. package/dist/{AmazonApiGatewayV2EndpointAdaptor-ByYtiJtN.mjs → AmazonApiGatewayV2EndpointAdaptor-ChO8BlDz.mjs} +2 -2
  18. package/dist/{AmazonApiGatewayV2EndpointAdaptor-ByYtiJtN.mjs.map → AmazonApiGatewayV2EndpointAdaptor-ChO8BlDz.mjs.map} +1 -1
  19. package/dist/{AmazonApiGatewayV2EndpointAdaptor-DcJ_w3ro.cjs → AmazonApiGatewayV2EndpointAdaptor-I1W23Nvn.cjs} +2 -2
  20. package/dist/{AmazonApiGatewayV2EndpointAdaptor-DcJ_w3ro.cjs.map → AmazonApiGatewayV2EndpointAdaptor-I1W23Nvn.cjs.map} +1 -1
  21. package/dist/{Authorizer-D1w7MpK6.d.mts → Authorizer-Cpx59w_q.d.mts} +1 -1
  22. package/dist/{BaseFunctionBuilder-Oc2xmxmg.d.mts → BaseFunctionBuilder-CoV7J45W.d.mts} +2 -2
  23. package/dist/{Construct-DCPATqec.d.mts → Construct-jBKqb-Zi.d.mts} +1 -1
  24. package/dist/Construct.d.mts +1 -1
  25. package/dist/{Cron-DPEcDCDW.d.mts → Cron-JZkp_fHy.d.mts} +2 -2
  26. package/dist/{CronBuilder-CxKTiepV.d.mts → CronBuilder-BmFDO0Dm.d.mts} +4 -4
  27. package/dist/{Endpoint-DbPsw13b.mjs → Endpoint-B70_KKhu.mjs} +8 -2
  28. package/dist/Endpoint-B70_KKhu.mjs.map +1 -0
  29. package/dist/{Endpoint-CA-byrDr.cjs → Endpoint-BJo9Hhwm.cjs} +8 -2
  30. package/dist/Endpoint-BJo9Hhwm.cjs.map +1 -0
  31. package/dist/{Endpoint-DoY1Owv2.d.mts → Endpoint-C5djXyae.d.mts} +69 -6
  32. package/dist/{Endpoint-BJPJTGjV.d.cts → Endpoint-CC2RGjkl.d.cts} +66 -3
  33. package/dist/{EndpointBuilder-BJRkivxQ.d.mts → EndpointBuilder-CD8LkBda.d.mts} +42 -5
  34. package/dist/{EndpointBuilder-Bhyft7WY.cjs → EndpointBuilder-DeswNQdG.cjs} +55 -3
  35. package/dist/EndpointBuilder-DeswNQdG.cjs.map +1 -0
  36. package/dist/{EndpointBuilder-69uVrKZL.mjs → EndpointBuilder-FyyoFTJ5.mjs} +55 -3
  37. package/dist/{EndpointBuilder-Bhyft7WY.cjs.map → EndpointBuilder-FyyoFTJ5.mjs.map} +1 -1
  38. package/dist/{EndpointBuilder-CQ-jOXsD.d.cts → EndpointBuilder-vXk6eIJk.d.cts} +39 -2
  39. package/dist/{EndpointFactory-DgwmAR_8.d.cts → EndpointFactory-3g-7Rznt.d.cts} +30 -8
  40. package/dist/{EndpointFactory-BKEPcQgE.d.mts → EndpointFactory-DaFR9LQG.d.mts} +31 -9
  41. package/dist/{EndpointFactory-BcVbkrxf.cjs → EndpointFactory-DcT_g9M_.cjs} +63 -14
  42. package/dist/EndpointFactory-DcT_g9M_.cjs.map +1 -0
  43. package/dist/{EndpointFactory-ARUlRlyM.mjs → EndpointFactory-KJAjBWmO.mjs} +63 -14
  44. package/dist/EndpointFactory-KJAjBWmO.mjs.map +1 -0
  45. package/dist/{Function-Dthlh2Fb.d.mts → Function-Vh1t-Qjj.d.mts} +2 -2
  46. package/dist/{FunctionBuilder-CZFBLfdV.d.mts → FunctionBuilder-3jsoFffg.d.mts} +4 -4
  47. package/dist/{FunctionExecutionWrapper-CfuajSB5.d.mts → FunctionExecutionWrapper-CI3CaoCo.d.mts} +2 -2
  48. package/dist/{HonoEndpointAdaptor-sSG85VER.d.cts → HonoEndpointAdaptor-BJh4J-J9.d.cts} +2 -2
  49. package/dist/{HonoEndpointAdaptor-BmB4Sc7L.mjs → HonoEndpointAdaptor-CcvXzoYV.mjs} +41 -28
  50. package/dist/HonoEndpointAdaptor-CcvXzoYV.mjs.map +1 -0
  51. package/dist/{HonoEndpointAdaptor-CnqR6PSB.cjs → HonoEndpointAdaptor-DodwLM0-.cjs} +41 -28
  52. package/dist/HonoEndpointAdaptor-DodwLM0-.cjs.map +1 -0
  53. package/dist/{HonoEndpointAdaptor-DBjipl6Q.d.mts → HonoEndpointAdaptor-kb1ByjUL.d.mts} +5 -5
  54. package/dist/{Subscriber-DvOtIyWq.cjs → Subscriber-DOt3svUC.cjs} +1 -1
  55. package/dist/{Subscriber-DvOtIyWq.cjs.map → Subscriber-DOt3svUC.cjs.map} +1 -1
  56. package/dist/{Subscriber-BfxLwZpX.d.mts → Subscriber-aNr1qkxR.d.mts} +2 -2
  57. package/dist/{Subscriber-JzcFFi4p.mjs → Subscriber-kCHbH2fZ.mjs} +1 -1
  58. package/dist/{Subscriber-JzcFFi4p.mjs.map → Subscriber-kCHbH2fZ.mjs.map} +1 -1
  59. package/dist/{SubscriberBuilder-lTiTUS1o.d.mts → SubscriberBuilder-CWS4tdbp.d.mts} +2 -2
  60. package/dist/{SubscriberBuilder-DUuV207i.cjs → SubscriberBuilder-Cj2u9k5Q.cjs} +2 -2
  61. package/dist/{SubscriberBuilder-DUuV207i.cjs.map → SubscriberBuilder-Cj2u9k5Q.cjs.map} +1 -1
  62. package/dist/{SubscriberBuilder-tm4oVOt3.mjs → SubscriberBuilder-DmxMU89X.mjs} +2 -2
  63. package/dist/{SubscriberBuilder-tm4oVOt3.mjs.map → SubscriberBuilder-DmxMU89X.mjs.map} +1 -1
  64. package/dist/{TestEndpointAdaptor-o7JbNcL-.mjs → TestEndpointAdaptor-1pPixE6y.mjs} +2 -2
  65. package/dist/{TestEndpointAdaptor-o7JbNcL-.mjs.map → TestEndpointAdaptor-1pPixE6y.mjs.map} +1 -1
  66. package/dist/{TestEndpointAdaptor-CGQVysE0.d.mts → TestEndpointAdaptor-5-unBV8O.d.mts} +3 -3
  67. package/dist/{TestEndpointAdaptor-CJO-og9U.d.cts → TestEndpointAdaptor-Bm0UjDtV.d.cts} +2 -2
  68. package/dist/{TestEndpointAdaptor-BtLcw4JW.cjs → TestEndpointAdaptor-wA-fmq4v.cjs} +2 -2
  69. package/dist/{TestEndpointAdaptor-BtLcw4JW.cjs.map → TestEndpointAdaptor-wA-fmq4v.cjs.map} +1 -1
  70. package/dist/adaptors/aws.cjs +4 -4
  71. package/dist/adaptors/aws.d.cts +4 -4
  72. package/dist/adaptors/aws.d.mts +15 -15
  73. package/dist/adaptors/aws.mjs +4 -4
  74. package/dist/adaptors/hono.cjs +3 -3
  75. package/dist/adaptors/hono.d.cts +2 -2
  76. package/dist/adaptors/hono.d.mts +9 -9
  77. package/dist/adaptors/hono.mjs +3 -3
  78. package/dist/adaptors/testing.cjs +2 -2
  79. package/dist/adaptors/testing.d.cts +2 -2
  80. package/dist/adaptors/testing.d.mts +9 -9
  81. package/dist/adaptors/testing.mjs +2 -2
  82. package/dist/crons/Cron.d.mts +6 -6
  83. package/dist/crons/CronBuilder.d.mts +7 -7
  84. package/dist/crons/index.d.mts +7 -7
  85. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +2 -2
  86. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +2 -2
  87. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +9 -9
  88. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +2 -2
  89. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +3 -3
  90. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +3 -3
  91. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +10 -10
  92. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +3 -3
  93. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +3 -3
  94. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +3 -3
  95. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +10 -10
  96. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +3 -3
  97. package/dist/endpoints/Authorizer.d.mts +1 -1
  98. package/dist/endpoints/Endpoint.cjs +1 -1
  99. package/dist/endpoints/Endpoint.d.cts +1 -1
  100. package/dist/endpoints/Endpoint.d.mts +8 -8
  101. package/dist/endpoints/Endpoint.mjs +1 -1
  102. package/dist/endpoints/EndpointBuilder.cjs +3 -2
  103. package/dist/endpoints/EndpointBuilder.d.cts +2 -2
  104. package/dist/endpoints/EndpointBuilder.d.mts +9 -9
  105. package/dist/endpoints/EndpointBuilder.mjs +3 -2
  106. package/dist/endpoints/EndpointFactory.cjs +4 -3
  107. package/dist/endpoints/EndpointFactory.d.cts +3 -3
  108. package/dist/endpoints/EndpointFactory.d.mts +10 -10
  109. package/dist/endpoints/EndpointFactory.mjs +4 -3
  110. package/dist/endpoints/HonoEndpointAdaptor.cjs +3 -3
  111. package/dist/endpoints/HonoEndpointAdaptor.d.cts +2 -2
  112. package/dist/endpoints/HonoEndpointAdaptor.d.mts +9 -9
  113. package/dist/endpoints/HonoEndpointAdaptor.mjs +3 -3
  114. package/dist/endpoints/TestEndpointAdaptor.cjs +2 -2
  115. package/dist/endpoints/TestEndpointAdaptor.d.cts +2 -2
  116. package/dist/endpoints/TestEndpointAdaptor.d.mts +9 -9
  117. package/dist/endpoints/TestEndpointAdaptor.mjs +2 -2
  118. package/dist/endpoints/audit.d.cts +1 -1
  119. package/dist/endpoints/audit.d.mts +8 -8
  120. package/dist/endpoints/helpers.cjs +2 -2
  121. package/dist/endpoints/helpers.d.cts +1 -1
  122. package/dist/endpoints/helpers.d.mts +8 -8
  123. package/dist/endpoints/helpers.mjs +2 -2
  124. package/dist/endpoints/index.cjs +5 -3
  125. package/dist/endpoints/index.cjs.map +1 -1
  126. package/dist/endpoints/index.d.cts +5 -5
  127. package/dist/endpoints/index.d.mts +13 -13
  128. package/dist/endpoints/index.mjs +5 -4
  129. package/dist/endpoints/index.mjs.map +1 -1
  130. package/dist/endpoints/processAudits.d.cts +1 -1
  131. package/dist/endpoints/processAudits.d.mts +8 -8
  132. package/dist/endpoints/rls.cjs +3 -0
  133. package/dist/endpoints/rls.d.cts +9 -0
  134. package/dist/endpoints/rls.d.mts +9 -0
  135. package/dist/endpoints/rls.mjs +3 -0
  136. package/dist/functions/AWSLambdaFunction.d.mts +4 -4
  137. package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
  138. package/dist/functions/Function.d.mts +2 -2
  139. package/dist/functions/FunctionBuilder.d.mts +4 -4
  140. package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
  141. package/dist/functions/TestFunctionAdaptor.d.mts +2 -2
  142. package/dist/functions/index.d.mts +5 -5
  143. package/dist/{helpers-CrrdyA04.mjs → helpers-C3B2lVrM.mjs} +2 -2
  144. package/dist/{helpers-CrrdyA04.mjs.map → helpers-C3B2lVrM.mjs.map} +1 -1
  145. package/dist/{helpers-DiPZVJQC.cjs → helpers-DxxSpLfw.cjs} +2 -2
  146. package/dist/{helpers-DiPZVJQC.cjs.map → helpers-DxxSpLfw.cjs.map} +1 -1
  147. package/dist/{index-9gJrM7Rw.d.mts → index-CFyaRrck.d.mts} +2 -2
  148. package/dist/index.d.mts +2 -2
  149. package/dist/publisher.d.mts +1 -1
  150. package/dist/rls-Bf3FRwto.mjs +9 -0
  151. package/dist/rls-Bf3FRwto.mjs.map +1 -0
  152. package/dist/rls-CmJ7bRsz.cjs +15 -0
  153. package/dist/rls-CmJ7bRsz.cjs.map +1 -0
  154. package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +3 -3
  155. package/dist/subscribers/Subscriber.cjs +1 -1
  156. package/dist/subscribers/Subscriber.d.mts +2 -2
  157. package/dist/subscribers/Subscriber.mjs +1 -1
  158. package/dist/subscribers/SubscriberBuilder.cjs +2 -2
  159. package/dist/subscribers/SubscriberBuilder.d.mts +3 -3
  160. package/dist/subscribers/SubscriberBuilder.mjs +2 -2
  161. package/dist/subscribers/index.cjs +2 -2
  162. package/dist/subscribers/index.d.mts +3 -3
  163. package/dist/subscribers/index.mjs +2 -2
  164. package/dist/{types-Cy1IhmUB.d.mts → types-CScirkHt.d.mts} +1 -1
  165. package/dist/types.d.mts +1 -1
  166. package/package.json +6 -5
  167. package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +57 -26
  168. package/src/endpoints/Endpoint.ts +19 -0
  169. package/src/endpoints/EndpointBuilder.ts +57 -0
  170. package/src/endpoints/EndpointFactory.ts +119 -12
  171. package/src/endpoints/HonoEndpointAdaptor.ts +66 -37
  172. package/src/endpoints/index.ts +7 -0
  173. package/src/endpoints/rls.ts +67 -0
  174. package/dist/AmazonApiGatewayEndpointAdaptor-CPqlw2Rx.cjs.map +0 -1
  175. package/dist/AmazonApiGatewayEndpointAdaptor-Cm4iD199.mjs.map +0 -1
  176. package/dist/Endpoint-CA-byrDr.cjs.map +0 -1
  177. package/dist/Endpoint-DbPsw13b.mjs.map +0 -1
  178. package/dist/EndpointBuilder-69uVrKZL.mjs.map +0 -1
  179. package/dist/EndpointFactory-ARUlRlyM.mjs.map +0 -1
  180. package/dist/EndpointFactory-BcVbkrxf.cjs.map +0 -1
  181. package/dist/HonoEndpointAdaptor-BmB4Sc7L.mjs.map +0 -1
  182. package/dist/HonoEndpointAdaptor-CnqR6PSB.cjs.map +0 -1
@@ -17,6 +17,7 @@ import type {
17
17
  import type { AuthorizeFn, SessionFn } from './Endpoint';
18
18
  import { EndpointBuilder } from './EndpointBuilder';
19
19
  import type { ActorExtractor } from './audit';
20
+ import type { RlsConfig } from './rls';
20
21
 
21
22
  const DEFAULT_LOGGER = new ConsoleLogger() as any;
22
23
 
@@ -40,6 +41,9 @@ export class EndpointFactory<
40
41
  string,
41
42
  SecurityScheme
42
43
  >,
44
+ TRlsConfig extends
45
+ | RlsConfig<TServices, TSession, TLogger>
46
+ | undefined = undefined,
43
47
  > {
44
48
  // @ts-ignore
45
49
  private defaultServices: TServices;
@@ -65,6 +69,7 @@ export class EndpointFactory<
65
69
  | undefined;
66
70
  private defaultActorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
67
71
  private customSecuritySchemes: TSecuritySchemes = {} as TSecuritySchemes;
72
+ private defaultRlsConfig?: TRlsConfig;
68
73
 
69
74
  constructor({
70
75
  basePath,
@@ -80,6 +85,7 @@ export class EndpointFactory<
80
85
  defaultDatabaseService,
81
86
  defaultActorExtractor,
82
87
  customSecuritySchemes = {} as TSecuritySchemes,
88
+ defaultRlsConfig,
83
89
  }: EndpointFactoryOptions<
84
90
  TServices,
85
91
  TBasePath,
@@ -92,7 +98,8 @@ export class EndpointFactory<
92
98
  TAuditStorageServiceName,
93
99
  TDatabase,
94
100
  TDatabaseServiceName,
95
- TSecuritySchemes
101
+ TSecuritySchemes,
102
+ TRlsConfig
96
103
  > = {}) {
97
104
  // Initialize default services
98
105
  this.defaultServices = uniqBy(
@@ -111,6 +118,7 @@ export class EndpointFactory<
111
118
  this.defaultDatabaseService = defaultDatabaseService;
112
119
  this.defaultActorExtractor = defaultActorExtractor;
113
120
  this.customSecuritySchemes = customSecuritySchemes;
121
+ this.defaultRlsConfig = defaultRlsConfig;
114
122
  }
115
123
 
116
124
  static joinPaths<TBasePath extends string, P extends string>(
@@ -184,7 +192,8 @@ export class EndpointFactory<
184
192
  TAuditAction,
185
193
  TDatabase,
186
194
  TDatabaseServiceName,
187
- TSecuritySchemes
195
+ TSecuritySchemes,
196
+ TRlsConfig
188
197
  >({
189
198
  defaultServices: this.defaultServices,
190
199
  basePath: this.basePath,
@@ -198,6 +207,7 @@ export class EndpointFactory<
198
207
  defaultDatabaseService: this.defaultDatabaseService,
199
208
  defaultActorExtractor: this.defaultActorExtractor,
200
209
  customSecuritySchemes: this.customSecuritySchemes,
210
+ defaultRlsConfig: this.defaultRlsConfig,
201
211
  });
202
212
  }
203
213
 
@@ -326,7 +336,8 @@ export class EndpointFactory<
326
336
  TAuditAction,
327
337
  TDatabase,
328
338
  TDatabaseServiceName,
329
- TSecuritySchemes
339
+ TSecuritySchemes,
340
+ TRlsConfig
330
341
  >({
331
342
  defaultServices: this.defaultServices,
332
343
  basePath: this.basePath,
@@ -341,6 +352,7 @@ export class EndpointFactory<
341
352
  defaultDatabaseService: this.defaultDatabaseService,
342
353
  defaultActorExtractor: this.defaultActorExtractor,
343
354
  customSecuritySchemes: this.customSecuritySchemes,
355
+ defaultRlsConfig: this.defaultRlsConfig,
344
356
  });
345
357
  }
346
358
 
@@ -376,7 +388,8 @@ export class EndpointFactory<
376
388
  TAuditAction,
377
389
  TDatabase,
378
390
  TDatabaseServiceName,
379
- TSecuritySchemes
391
+ TSecuritySchemes,
392
+ TRlsConfig
380
393
  >({
381
394
  defaultServices: this.defaultServices,
382
395
  basePath: newBasePath,
@@ -390,6 +403,7 @@ export class EndpointFactory<
390
403
  defaultDatabaseService: this.defaultDatabaseService,
391
404
  defaultActorExtractor: this.defaultActorExtractor,
392
405
  customSecuritySchemes: this.customSecuritySchemes,
406
+ defaultRlsConfig: this.defaultRlsConfig,
393
407
  });
394
408
  }
395
409
 
@@ -424,7 +438,8 @@ export class EndpointFactory<
424
438
  TAuditAction,
425
439
  TDatabase,
426
440
  TDatabaseServiceName,
427
- TSecuritySchemes
441
+ TSecuritySchemes,
442
+ TRlsConfig
428
443
  >({
429
444
  defaultServices: this.defaultServices,
430
445
  basePath: this.basePath,
@@ -438,6 +453,7 @@ export class EndpointFactory<
438
453
  defaultDatabaseService: this.defaultDatabaseService,
439
454
  defaultActorExtractor: this.defaultActorExtractor,
440
455
  customSecuritySchemes: this.customSecuritySchemes,
456
+ defaultRlsConfig: this.defaultRlsConfig,
441
457
  });
442
458
  }
443
459
 
@@ -472,7 +488,8 @@ export class EndpointFactory<
472
488
  TAuditAction,
473
489
  TDatabase,
474
490
  TDatabaseServiceName,
475
- TSecuritySchemes
491
+ TSecuritySchemes,
492
+ TRlsConfig
476
493
  >({
477
494
  defaultServices: [...services, ...this.defaultServices],
478
495
  basePath: this.basePath,
@@ -486,6 +503,7 @@ export class EndpointFactory<
486
503
  defaultDatabaseService: this.defaultDatabaseService,
487
504
  defaultActorExtractor: this.defaultActorExtractor,
488
505
  customSecuritySchemes: this.customSecuritySchemes,
506
+ defaultRlsConfig: this.defaultRlsConfig,
489
507
  });
490
508
  }
491
509
 
@@ -519,7 +537,8 @@ export class EndpointFactory<
519
537
  TAuditAction,
520
538
  TDatabase,
521
539
  TDatabaseServiceName,
522
- TSecuritySchemes
540
+ TSecuritySchemes,
541
+ TRlsConfig
523
542
  >({
524
543
  defaultServices: this.defaultServices,
525
544
  basePath: this.basePath,
@@ -547,6 +566,7 @@ export class EndpointFactory<
547
566
  L
548
567
  >,
549
568
  customSecuritySchemes: this.customSecuritySchemes,
569
+ defaultRlsConfig: this.defaultRlsConfig,
550
570
  });
551
571
  }
552
572
 
@@ -583,7 +603,8 @@ export class EndpointFactory<
583
603
  TAuditAction,
584
604
  TDatabase,
585
605
  TDatabaseServiceName,
586
- TSecuritySchemes
606
+ TSecuritySchemes,
607
+ TRlsConfig
587
608
  >({
588
609
  defaultServices: this.defaultServices,
589
610
  basePath: this.basePath,
@@ -597,6 +618,7 @@ export class EndpointFactory<
597
618
  defaultDatabaseService: this.defaultDatabaseService,
598
619
  defaultActorExtractor: this.defaultActorExtractor,
599
620
  customSecuritySchemes: this.customSecuritySchemes,
621
+ defaultRlsConfig: this.defaultRlsConfig,
600
622
  });
601
623
  }
602
624
 
@@ -630,7 +652,8 @@ export class EndpointFactory<
630
652
  TAuditAction,
631
653
  TDatabase,
632
654
  TDatabaseServiceName,
633
- TSecuritySchemes
655
+ TSecuritySchemes,
656
+ TRlsConfig
634
657
  >({
635
658
  defaultServices: this.defaultServices,
636
659
  basePath: this.basePath,
@@ -653,6 +676,7 @@ export class EndpointFactory<
653
676
  TLogger
654
677
  >,
655
678
  customSecuritySchemes: this.customSecuritySchemes,
679
+ defaultRlsConfig: this.defaultRlsConfig,
656
680
  });
657
681
  }
658
682
 
@@ -690,7 +714,8 @@ export class EndpointFactory<
690
714
  TAuditAction,
691
715
  T,
692
716
  TName,
693
- TSecuritySchemes
717
+ TSecuritySchemes,
718
+ TRlsConfig
694
719
  >({
695
720
  defaultServices: this.defaultServices,
696
721
  basePath: this.basePath,
@@ -707,6 +732,7 @@ export class EndpointFactory<
707
732
  defaultAuditorStorage: this.defaultAuditorStorage,
708
733
  defaultDatabaseService: service,
709
734
  customSecuritySchemes: this.customSecuritySchemes,
735
+ defaultRlsConfig: this.defaultRlsConfig,
710
736
  });
711
737
  }
712
738
 
@@ -745,7 +771,8 @@ export class EndpointFactory<
745
771
  ExtractStorageAuditAction<T>,
746
772
  TDatabase,
747
773
  TDatabaseServiceName,
748
- TSecuritySchemes
774
+ TSecuritySchemes,
775
+ TRlsConfig
749
776
  >({
750
777
  defaultServices: this.defaultServices,
751
778
  basePath: this.basePath,
@@ -764,6 +791,7 @@ export class EndpointFactory<
764
791
  TLogger
765
792
  >,
766
793
  customSecuritySchemes: this.customSecuritySchemes,
794
+ defaultRlsConfig: this.defaultRlsConfig,
767
795
  });
768
796
  }
769
797
 
@@ -801,7 +829,8 @@ export class EndpointFactory<
801
829
  TAuditAction,
802
830
  TDatabase,
803
831
  TDatabaseServiceName,
804
- TSecuritySchemes
832
+ TSecuritySchemes,
833
+ TRlsConfig
805
834
  >({
806
835
  defaultServices: this.defaultServices,
807
836
  basePath: this.basePath,
@@ -815,6 +844,75 @@ export class EndpointFactory<
815
844
  defaultDatabaseService: this.defaultDatabaseService,
816
845
  defaultActorExtractor: extractor,
817
846
  customSecuritySchemes: this.customSecuritySchemes,
847
+ defaultRlsConfig: this.defaultRlsConfig,
848
+ });
849
+ }
850
+
851
+ /**
852
+ * Set the RLS (Row-Level Security) configuration for endpoints created from this factory.
853
+ * This enables automatic PostgreSQL session variable setting for RLS policies.
854
+ *
855
+ * @example
856
+ * ```typescript
857
+ * const api = new EndpointFactory()
858
+ * .database(databaseService)
859
+ * .session(extractSession)
860
+ * .rls({
861
+ * extractor: ({ session }) => ({
862
+ * user_id: session.userId,
863
+ * tenant_id: session.tenantId,
864
+ * }),
865
+ * prefix: 'app',
866
+ * });
867
+ * ```
868
+ */
869
+ rls<TConfig extends RlsConfig<TServices, TSession, TLogger>>(
870
+ config: TConfig,
871
+ ): EndpointFactory<
872
+ TServices,
873
+ TBasePath,
874
+ TLogger,
875
+ TSession,
876
+ TEventPublisher,
877
+ TEventPublisherServiceName,
878
+ TAuthorizers,
879
+ TAuditStorage,
880
+ TAuditStorageServiceName,
881
+ TAuditAction,
882
+ TDatabase,
883
+ TDatabaseServiceName,
884
+ TSecuritySchemes,
885
+ TConfig
886
+ > {
887
+ return new EndpointFactory<
888
+ TServices,
889
+ TBasePath,
890
+ TLogger,
891
+ TSession,
892
+ TEventPublisher,
893
+ TEventPublisherServiceName,
894
+ TAuthorizers,
895
+ TAuditStorage,
896
+ TAuditStorageServiceName,
897
+ TAuditAction,
898
+ TDatabase,
899
+ TDatabaseServiceName,
900
+ TSecuritySchemes,
901
+ TConfig
902
+ >({
903
+ defaultServices: this.defaultServices,
904
+ basePath: this.basePath,
905
+ defaultAuthorizeFn: this.defaultAuthorizeFn,
906
+ defaultLogger: this.defaultLogger,
907
+ defaultSessionExtractor: this.defaultSessionExtractor,
908
+ defaultEventPublisher: this.defaultEventPublisher,
909
+ availableAuthorizers: this.availableAuthorizers,
910
+ defaultAuthorizerName: this.defaultAuthorizerName,
911
+ defaultAuditorStorage: this.defaultAuditorStorage,
912
+ defaultDatabaseService: this.defaultDatabaseService,
913
+ defaultActorExtractor: this.defaultActorExtractor,
914
+ customSecuritySchemes: this.customSecuritySchemes,
915
+ defaultRlsConfig: config,
818
916
  });
819
917
  }
820
918
 
@@ -906,6 +1004,11 @@ export class EndpointFactory<
906
1004
  // Set custom security schemes
907
1005
  builder._customSecuritySchemes = this.customSecuritySchemes;
908
1006
 
1007
+ // Set RLS config if configured
1008
+ if (this.defaultRlsConfig) {
1009
+ builder._rlsConfig = this.defaultRlsConfig as any;
1010
+ }
1011
+
909
1012
  return builder;
910
1013
  }
911
1014
 
@@ -977,6 +1080,9 @@ export interface EndpointFactoryOptions<
977
1080
  string,
978
1081
  SecurityScheme
979
1082
  >,
1083
+ TRlsConfig extends
1084
+ | RlsConfig<TServices, TSession, TLogger>
1085
+ | undefined = undefined,
980
1086
  > {
981
1087
  defaultServices?: TServices;
982
1088
  basePath?: TBasePath;
@@ -991,6 +1097,7 @@ export interface EndpointFactoryOptions<
991
1097
  defaultDatabaseService?: Service<TDatabaseServiceName, TDatabase>;
992
1098
  defaultActorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
993
1099
  customSecuritySchemes?: TSecuritySchemes;
1100
+ defaultRlsConfig?: TRlsConfig;
994
1101
  }
995
1102
 
996
1103
  export const e = new EndpointFactory();
@@ -19,6 +19,7 @@ import {
19
19
  import { getEndpointsFromRoutes } from './helpers';
20
20
  import { parseHonoQuery } from './parseHonoQuery';
21
21
 
22
+ import { withRlsContext } from '@geekmidas/db/rls';
22
23
  import { wrapError } from '@geekmidas/errors';
23
24
  import {
24
25
  type Service,
@@ -374,6 +375,19 @@ export class HonoEndpoint<
374
375
  logger.warn('No auditor storage service available');
375
376
  }
376
377
 
378
+ // Extract RLS context if configured and not bypassed
379
+ const rlsActive =
380
+ endpoint.rlsConfig && !endpoint.rlsBypass && rawDb !== undefined;
381
+ const rlsContext = rlsActive
382
+ ? await endpoint.rlsConfig!.extractor({
383
+ services,
384
+ session,
385
+ header,
386
+ cookie,
387
+ logger,
388
+ })
389
+ : undefined;
390
+
377
391
  // Execute handler with automatic audit transaction support
378
392
  const result = await executeWithAuditTransaction(
379
393
  auditContext,
@@ -383,49 +397,64 @@ export class HonoEndpoint<
383
397
  auditContext?.storage?.databaseServiceName &&
384
398
  auditContext.storage.databaseServiceName ===
385
399
  endpoint.databaseService?.serviceName;
386
- const db = sameDatabase
400
+ const baseDb = sameDatabase
387
401
  ? (auditor?.getTransaction?.() ?? rawDb)
388
402
  : rawDb;
389
403
 
390
- const responseBuilder = new ResponseBuilder();
391
- const response = await endpoint.handler(
392
- {
393
- services,
394
- logger,
395
- body: c.req.valid('json'),
396
- query: c.req.valid('query'),
397
- params: c.req.valid('param'),
398
- session,
399
- header,
400
- cookie,
401
- auditor,
402
- db,
403
- } as unknown as EndpointContext<
404
- TInput,
405
- TServices,
406
- TLogger,
407
- TSession,
408
- TAuditAction,
409
- TDatabase,
410
- TAuditStorage
411
- >,
412
- responseBuilder,
413
- );
414
-
415
- // Check if response has metadata
416
- let data = response;
417
- let metadata = responseBuilder.getMetadata();
404
+ // Helper to execute handler with given db
405
+ const executeHandler = async (db: TDatabase | undefined) => {
406
+ const responseBuilder = new ResponseBuilder();
407
+ const response = await endpoint.handler(
408
+ {
409
+ services,
410
+ logger,
411
+ body: c.req.valid('json'),
412
+ query: c.req.valid('query'),
413
+ params: c.req.valid('param'),
414
+ session,
415
+ header,
416
+ cookie,
417
+ auditor,
418
+ db,
419
+ } as unknown as EndpointContext<
420
+ TInput,
421
+ TServices,
422
+ TLogger,
423
+ TSession,
424
+ TAuditAction,
425
+ TDatabase,
426
+ TAuditStorage
427
+ >,
428
+ responseBuilder,
429
+ );
430
+
431
+ // Check if response has metadata
432
+ let data = response;
433
+ let metadata = responseBuilder.getMetadata();
434
+
435
+ if (Endpoint.hasMetadata(response)) {
436
+ data = response.data;
437
+ metadata = response.metadata;
438
+ }
418
439
 
419
- if (Endpoint.hasMetadata(response)) {
420
- data = response.data;
421
- metadata = response.metadata;
440
+ const output = endpoint.outputSchema
441
+ ? await endpoint.parseOutput(data)
442
+ : undefined;
443
+
444
+ return { output, metadata, responseBuilder };
445
+ };
446
+
447
+ // If RLS is active, wrap handler with RLS context
448
+ if (rlsActive && rlsContext && baseDb) {
449
+ return withRlsContext(
450
+ baseDb as any,
451
+ rlsContext,
452
+ async (trx) => executeHandler(trx as TDatabase),
453
+ { prefix: endpoint.rlsConfig!.prefix },
454
+ );
422
455
  }
423
456
 
424
- const output = endpoint.outputSchema
425
- ? await endpoint.parseOutput(data)
426
- : undefined;
427
-
428
- return { output, metadata, responseBuilder };
457
+ return executeHandler(baseDb as TDatabase | undefined);
429
458
  },
430
459
  // Process declarative audits after handler (inside transaction)
431
460
  async (result, auditor) => {
@@ -10,5 +10,12 @@ export {
10
10
  } from './Endpoint';
11
11
  export { EndpointBuilder } from './EndpointBuilder';
12
12
  export { type MappedAudit, type ActorExtractor } from './audit';
13
+ export {
14
+ type RlsConfig,
15
+ type RlsContext,
16
+ type RlsContextExtractor,
17
+ RLS_BYPASS,
18
+ type RlsBypass,
19
+ } from './rls';
13
20
 
14
21
  export const e = new EndpointFactory();
@@ -0,0 +1,67 @@
1
+ import type { Logger } from '@geekmidas/logger';
2
+ import type { Service, ServiceRecord } from '@geekmidas/services';
3
+ import type { CookieFn, HeaderFn } from './Endpoint';
4
+
5
+ /**
6
+ * RLS context - key-value pairs to set as PostgreSQL session variables.
7
+ * Keys become `prefix.key` (e.g., `app.user_id`).
8
+ */
9
+ export interface RlsContext {
10
+ [key: string]: string | number | boolean | null | undefined;
11
+ }
12
+
13
+ /**
14
+ * Function type for extracting RLS context from request context.
15
+ *
16
+ * @template TServices - Available service dependencies
17
+ * @template TSession - Session data type
18
+ * @template TLogger - Logger type
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const extractor: RlsContextExtractor<[], UserSession> = ({ session }) => ({
23
+ * user_id: session.userId,
24
+ * tenant_id: session.tenantId,
25
+ * roles: session.roles.join(','),
26
+ * });
27
+ * ```
28
+ */
29
+ export type RlsContextExtractor<
30
+ TServices extends Service[] = [],
31
+ TSession = unknown,
32
+ TLogger extends Logger = Logger,
33
+ > = (ctx: {
34
+ services: ServiceRecord<TServices>;
35
+ session: TSession;
36
+ header: HeaderFn;
37
+ cookie: CookieFn;
38
+ logger: TLogger;
39
+ }) => RlsContext | Promise<RlsContext>;
40
+
41
+ /**
42
+ * Configuration for RLS on an endpoint or factory.
43
+ *
44
+ * @template TServices - Available service dependencies
45
+ * @template TSession - Session data type
46
+ * @template TLogger - Logger type
47
+ */
48
+ export interface RlsConfig<
49
+ TServices extends Service[] = [],
50
+ TSession = unknown,
51
+ TLogger extends Logger = Logger,
52
+ > {
53
+ /** Function to extract RLS context from request */
54
+ extractor: RlsContextExtractor<TServices, TSession, TLogger>;
55
+ /** Prefix for PostgreSQL session variables (default: 'app') */
56
+ prefix?: string;
57
+ }
58
+
59
+ /**
60
+ * Symbol used to bypass RLS for an endpoint.
61
+ */
62
+ export const RLS_BYPASS = Symbol.for('geekmidas.rls.bypass');
63
+
64
+ /**
65
+ * Type for RLS bypass marker.
66
+ */
67
+ export type RlsBypass = typeof RLS_BYPASS;
@@ -1 +0,0 @@
1
- {"version":3,"file":"AmazonApiGatewayEndpointAdaptor-CPqlw2Rx.cjs","names":["envParser: EnvironmentParser<{}>","endpoint: Endpoint<\n TRoute,\n TMethod,\n TInput,\n TOutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction\n >","UnprocessableEntityError","UnauthorizedError","event: Event<TEvent, TInput, TServices, TLogger, TSession>","ResponseBuilder","metadata","output","result","lambdaResponse: AmazonApiGatewayEndpointHandlerResponse","setCookieHeaders: string[]"],"sources":["../src/endpoints/AmazonApiGatewayEndpointAdaptor.ts"],"sourcesContent":["import type { AuditStorage, AuditableAction } from '@geekmidas/audit';\nimport type { Logger } from '@geekmidas/logger';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { HttpMethod } from '../types';\nimport { Endpoint, type EndpointSchemas, ResponseBuilder } from './Endpoint';\n\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport middy, { type MiddlewareObj } from '@middy/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n Context,\n} from 'aws-lambda';\nimport set from 'lodash.set';\n\nimport {\n UnauthorizedError,\n UnprocessableEntityError,\n wrapError,\n} from '@geekmidas/errors';\nimport type { EventPublisher } from '@geekmidas/events';\nimport {\n type Service,\n ServiceDiscovery,\n type ServiceRecord,\n} from '@geekmidas/services';\n\nimport type {\n InferComposableStandardSchema,\n InferStandardSchema,\n} from '@geekmidas/schema';\nimport { publishConstructEvents } from '../publisher';\nimport type { CookieFn, HeaderFn } from './Endpoint';\nimport type { MappedAudit } from './audit';\nimport {\n createAuditContext,\n executeWithAuditTransaction,\n} from './processAudits';\n\n// Helper function to publish events\n\nexport abstract class AmazonApiGatewayEndpoint<\n THandler extends\n | AmazonApiGatewayV1EndpointHandler\n | AmazonApiGatewayV2EndpointHandler,\n TEvent extends HandlerEvent<THandler>,\n TRoute extends string,\n TMethod extends HttpMethod,\n TInput extends EndpointSchemas = {},\n TOutSchema extends StandardSchemaV1 | undefined = undefined,\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n TEventPublisher extends EventPublisher<any> | undefined = undefined,\n TEventPublisherServiceName extends string = string,\n TAuditStorage extends AuditStorage | undefined = undefined,\n TAuditStorageServiceName extends string = string,\n TAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n string,\n unknown\n >,\n> {\n constructor(\n protected envParser: EnvironmentParser<{}>,\n protected readonly endpoint: Endpoint<\n TRoute,\n TMethod,\n TInput,\n TOutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction\n >,\n ) {}\n\n private error(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n onError: (req) => {\n (req.event.logger || this.endpoint.logger).error(\n req.error || {},\n 'Error processing request',\n );\n const wrappedError = wrapError(req.error);\n\n // Set the response with the proper status code from the HttpError\n req.response = {\n statusCode: wrappedError.statusCode,\n body: wrappedError.body,\n };\n },\n };\n }\n abstract getInput(e: TEvent): GetInputResponse;\n\n private input(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n try {\n const { body, query, params } = this.getInput(req.event);\n const headers = req.event.headers as Record<string, string>;\n const header = Endpoint.createHeaders(headers);\n const cookie = Endpoint.createCookies(headers.cookie);\n\n set(req.event, 'body', await this.endpoint.parseInput(body, 'body'));\n\n set(\n req.event,\n 'query',\n await this.endpoint.parseInput(query, 'query'),\n );\n set(\n req.event,\n 'params',\n await this.endpoint.parseInput(params, 'params'),\n );\n set(req.event, 'header', header);\n set(req.event, 'cookie', cookie);\n } catch (error) {\n // Convert validation errors to 422 Unprocessable Entity\n if (error && typeof error === 'object' && Array.isArray(error)) {\n throw new UnprocessableEntityError('Validation failed', error);\n }\n throw error;\n }\n },\n };\n }\n\n abstract getLoggerContext(data: TEvent, context: Context): LoggerContext;\n\n private logger(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: (req) => {\n req.event.logger = this.endpoint.logger.child({\n route: this.endpoint.route,\n host: req.event.headers?.host,\n method: this.endpoint.method,\n ...this.getLoggerContext(req.event, req.context),\n }) as TLogger;\n },\n };\n }\n private services(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n const services = await serviceDiscovery.register(\n this.endpoint.services,\n );\n\n req.event.services = services;\n },\n };\n }\n\n private authorize(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const services = req.event.services;\n const header = req.event.header;\n const cookie = req.event.cookie;\n const session = req.event.session as TSession;\n\n const isAuthorized = await this.endpoint.authorize({\n header,\n cookie,\n services,\n logger,\n session,\n });\n\n if (!isAuthorized) {\n logger.warn('Unauthorized access attempt');\n throw new UnauthorizedError(\n 'Unauthorized access to the endpoint',\n 'You do not have permission to access this resource.',\n );\n }\n },\n };\n }\n\n private database(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n if (!this.endpoint.databaseService) {\n return;\n }\n\n const logger = req.event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n const db = await serviceDiscovery\n .register([this.endpoint.databaseService])\n .then(\n (s) =>\n s[this.endpoint.databaseService!.serviceName as keyof typeof s],\n );\n\n (req.event as any).db = db;\n },\n };\n }\n\n private session(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const services = req.event.services;\n const db = (req.event as any).db;\n req.event.session = (await this.endpoint.getSession({\n logger,\n services,\n header: req.event.header,\n cookie: req.event.cookie,\n ...(db !== undefined && { db }),\n } as any)) as TSession;\n },\n };\n }\n\n private events(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n after: async (req) => {\n const event = req.event;\n const response = (event as any)\n .__response as InferStandardSchema<TOutSchema>;\n const statusCode = req.response?.statusCode ?? this.endpoint.status;\n\n // Only publish events on successful responses (2xx status codes)\n // Note: Audits are processed inside the handler's transaction\n if (Endpoint.isSuccessStatus(statusCode)) {\n const logger = event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n // Publish events\n await publishConstructEvents(\n this.endpoint,\n response,\n serviceDiscovery,\n logger,\n );\n }\n },\n };\n }\n\n private async _handler(\n event: Event<TEvent, TInput, TServices, TLogger, TSession>,\n ) {\n const input = this.endpoint.refineInput(event);\n const logger = event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n // Create audit context if audit storage is configured\n const auditContext = await createAuditContext(\n this.endpoint,\n serviceDiscovery,\n logger,\n {\n session: event.session,\n header: event.header,\n cookie: event.cookie,\n services: event.services as Record<string, unknown>,\n },\n );\n\n // Warn if declarative audits are configured but no audit storage\n const audits = this.endpoint.audits as MappedAudit<\n TAuditAction,\n TOutSchema\n >[];\n if (!auditContext && audits?.length) {\n logger.warn('No auditor storage service available');\n }\n\n // Get pre-resolved database from middleware\n const rawDb = (event as any).db;\n\n // Execute handler with automatic audit transaction support\n const result = await executeWithAuditTransaction(\n auditContext,\n async (auditor) => {\n // Use audit transaction as db only if the storage uses the same database service\n const sameDatabase =\n auditContext?.storage?.databaseServiceName &&\n auditContext.storage.databaseServiceName ===\n this.endpoint.databaseService?.serviceName;\n const db = sameDatabase\n ? (auditor?.getTransaction?.() ?? rawDb)\n : rawDb;\n\n const responseBuilder = new ResponseBuilder();\n const response = await this.endpoint.handler(\n {\n header: event.header,\n cookie: event.cookie,\n logger: event.logger,\n services: event.services,\n session: event.session,\n auditor,\n db,\n ...input,\n } as any,\n responseBuilder,\n );\n\n // Check if response has metadata\n let data = response;\n let metadata = responseBuilder.getMetadata();\n\n if (Endpoint.hasMetadata(response)) {\n data = response.data;\n metadata = response.metadata;\n }\n\n const output = this.endpoint.outputSchema\n ? await this.endpoint.parseOutput(data)\n : undefined;\n\n return { output, metadata, responseBuilder };\n },\n // Process declarative audits after handler (inside transaction)\n async (result, auditor) => {\n if (!audits?.length) return;\n\n for (const audit of audits) {\n if (audit.when && !audit.when(result.output as any)) {\n continue;\n }\n const payload = audit.payload(result.output as any);\n const entityId = audit.entityId?.(result.output as any);\n auditor.audit(audit.type as any, payload as any, {\n table: audit.table,\n entityId,\n });\n }\n },\n // Pass rawDb so storage can reuse existing transactions\n { db: rawDb },\n );\n\n const { output, metadata } = result;\n const body = output !== undefined ? JSON.stringify(output) : undefined;\n\n // Store response for middleware access\n (event as any).__response = output;\n\n // Build response with metadata\n const lambdaResponse: AmazonApiGatewayEndpointHandlerResponse = {\n statusCode: metadata.status ?? this.endpoint.status,\n body,\n };\n\n // Add custom headers\n if (metadata.headers && Object.keys(metadata.headers).length > 0) {\n lambdaResponse.headers = { ...metadata.headers };\n }\n\n // Format cookies as Set-Cookie headers\n if (metadata.cookies && metadata.cookies.size > 0) {\n const setCookieHeaders: string[] = [];\n for (const [name, { value, options }] of metadata.cookies) {\n setCookieHeaders.push(\n Endpoint.formatCookieHeader(name, value, options),\n );\n }\n\n if (setCookieHeaders.length > 0) {\n lambdaResponse.multiValueHeaders = {\n ...lambdaResponse.multiValueHeaders,\n 'Set-Cookie': setCookieHeaders,\n };\n }\n }\n\n return lambdaResponse;\n }\n\n get handler() {\n const handler = this._handler.bind(this);\n return middy(handler)\n .use(this.logger())\n .use(this.error())\n .use(this.services())\n .use(this.input())\n .use(this.database())\n .use(this.session())\n .use(this.authorize())\n .use(this.events()) as unknown as THandler;\n }\n}\n\nexport type Event<\n TEvent extends APIGatewayProxyEvent | APIGatewayProxyEventV2,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n> = {\n services: ServiceRecord<TServices>;\n logger: TLogger;\n header: HeaderFn;\n cookie: CookieFn;\n session: TSession;\n} & TEvent &\n InferComposableStandardSchema<TInput>;\n\ntype Middleware<\n TEvent extends APIGatewayProxyEvent | APIGatewayProxyEventV2,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n> = MiddlewareObj<Event<TEvent, TInput, TServices, TLogger, TSession>>;\n\nexport type AmazonApiGatewayEndpointHandlerResponse = {\n statusCode: number;\n body: string | undefined;\n headers?: Record<string, string>;\n multiValueHeaders?: Record<string, string[]>;\n};\n\nexport type LoggerContext = {\n fn: {\n name: string;\n version: string;\n };\n req: {\n id: string | undefined;\n awsRequestId: string;\n path: string;\n ip: string | undefined;\n userAgent: string | undefined;\n };\n};\n\nexport type GetInputResponse = {\n body: any;\n query: any;\n params: any;\n};\n\nexport type AmazonApiGatewayV1EndpointHandler = (\n event: APIGatewayProxyEvent,\n context: Context,\n) => Promise<AmazonApiGatewayEndpointHandlerResponse>;\n\nexport type AmazonApiGatewayV2EndpointHandler = (\n event: APIGatewayProxyEventV2,\n context: Context,\n) => Promise<AmazonApiGatewayEndpointHandlerResponse>;\n\nexport type HandlerEvent<T extends Function> = T extends (\n event: infer E,\n context: Context,\n) => any\n ? E\n : never;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AmazonApiGatewayEndpointAdaptor-Cm4iD199.mjs","names":["envParser: EnvironmentParser<{}>","endpoint: Endpoint<\n TRoute,\n TMethod,\n TInput,\n TOutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction\n >","event: Event<TEvent, TInput, TServices, TLogger, TSession>","metadata","output","result","lambdaResponse: AmazonApiGatewayEndpointHandlerResponse","setCookieHeaders: string[]"],"sources":["../src/endpoints/AmazonApiGatewayEndpointAdaptor.ts"],"sourcesContent":["import type { AuditStorage, AuditableAction } from '@geekmidas/audit';\nimport type { Logger } from '@geekmidas/logger';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { HttpMethod } from '../types';\nimport { Endpoint, type EndpointSchemas, ResponseBuilder } from './Endpoint';\n\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport middy, { type MiddlewareObj } from '@middy/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n Context,\n} from 'aws-lambda';\nimport set from 'lodash.set';\n\nimport {\n UnauthorizedError,\n UnprocessableEntityError,\n wrapError,\n} from '@geekmidas/errors';\nimport type { EventPublisher } from '@geekmidas/events';\nimport {\n type Service,\n ServiceDiscovery,\n type ServiceRecord,\n} from '@geekmidas/services';\n\nimport type {\n InferComposableStandardSchema,\n InferStandardSchema,\n} from '@geekmidas/schema';\nimport { publishConstructEvents } from '../publisher';\nimport type { CookieFn, HeaderFn } from './Endpoint';\nimport type { MappedAudit } from './audit';\nimport {\n createAuditContext,\n executeWithAuditTransaction,\n} from './processAudits';\n\n// Helper function to publish events\n\nexport abstract class AmazonApiGatewayEndpoint<\n THandler extends\n | AmazonApiGatewayV1EndpointHandler\n | AmazonApiGatewayV2EndpointHandler,\n TEvent extends HandlerEvent<THandler>,\n TRoute extends string,\n TMethod extends HttpMethod,\n TInput extends EndpointSchemas = {},\n TOutSchema extends StandardSchemaV1 | undefined = undefined,\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n TEventPublisher extends EventPublisher<any> | undefined = undefined,\n TEventPublisherServiceName extends string = string,\n TAuditStorage extends AuditStorage | undefined = undefined,\n TAuditStorageServiceName extends string = string,\n TAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n string,\n unknown\n >,\n> {\n constructor(\n protected envParser: EnvironmentParser<{}>,\n protected readonly endpoint: Endpoint<\n TRoute,\n TMethod,\n TInput,\n TOutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction\n >,\n ) {}\n\n private error(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n onError: (req) => {\n (req.event.logger || this.endpoint.logger).error(\n req.error || {},\n 'Error processing request',\n );\n const wrappedError = wrapError(req.error);\n\n // Set the response with the proper status code from the HttpError\n req.response = {\n statusCode: wrappedError.statusCode,\n body: wrappedError.body,\n };\n },\n };\n }\n abstract getInput(e: TEvent): GetInputResponse;\n\n private input(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n try {\n const { body, query, params } = this.getInput(req.event);\n const headers = req.event.headers as Record<string, string>;\n const header = Endpoint.createHeaders(headers);\n const cookie = Endpoint.createCookies(headers.cookie);\n\n set(req.event, 'body', await this.endpoint.parseInput(body, 'body'));\n\n set(\n req.event,\n 'query',\n await this.endpoint.parseInput(query, 'query'),\n );\n set(\n req.event,\n 'params',\n await this.endpoint.parseInput(params, 'params'),\n );\n set(req.event, 'header', header);\n set(req.event, 'cookie', cookie);\n } catch (error) {\n // Convert validation errors to 422 Unprocessable Entity\n if (error && typeof error === 'object' && Array.isArray(error)) {\n throw new UnprocessableEntityError('Validation failed', error);\n }\n throw error;\n }\n },\n };\n }\n\n abstract getLoggerContext(data: TEvent, context: Context): LoggerContext;\n\n private logger(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: (req) => {\n req.event.logger = this.endpoint.logger.child({\n route: this.endpoint.route,\n host: req.event.headers?.host,\n method: this.endpoint.method,\n ...this.getLoggerContext(req.event, req.context),\n }) as TLogger;\n },\n };\n }\n private services(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n const services = await serviceDiscovery.register(\n this.endpoint.services,\n );\n\n req.event.services = services;\n },\n };\n }\n\n private authorize(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const services = req.event.services;\n const header = req.event.header;\n const cookie = req.event.cookie;\n const session = req.event.session as TSession;\n\n const isAuthorized = await this.endpoint.authorize({\n header,\n cookie,\n services,\n logger,\n session,\n });\n\n if (!isAuthorized) {\n logger.warn('Unauthorized access attempt');\n throw new UnauthorizedError(\n 'Unauthorized access to the endpoint',\n 'You do not have permission to access this resource.',\n );\n }\n },\n };\n }\n\n private database(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n if (!this.endpoint.databaseService) {\n return;\n }\n\n const logger = req.event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n const db = await serviceDiscovery\n .register([this.endpoint.databaseService])\n .then(\n (s) =>\n s[this.endpoint.databaseService!.serviceName as keyof typeof s],\n );\n\n (req.event as any).db = db;\n },\n };\n }\n\n private session(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n before: async (req) => {\n const logger = req.event.logger as TLogger;\n const services = req.event.services;\n const db = (req.event as any).db;\n req.event.session = (await this.endpoint.getSession({\n logger,\n services,\n header: req.event.header,\n cookie: req.event.cookie,\n ...(db !== undefined && { db }),\n } as any)) as TSession;\n },\n };\n }\n\n private events(): Middleware<TEvent, TInput, TServices, TLogger> {\n return {\n after: async (req) => {\n const event = req.event;\n const response = (event as any)\n .__response as InferStandardSchema<TOutSchema>;\n const statusCode = req.response?.statusCode ?? this.endpoint.status;\n\n // Only publish events on successful responses (2xx status codes)\n // Note: Audits are processed inside the handler's transaction\n if (Endpoint.isSuccessStatus(statusCode)) {\n const logger = event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n // Publish events\n await publishConstructEvents(\n this.endpoint,\n response,\n serviceDiscovery,\n logger,\n );\n }\n },\n };\n }\n\n private async _handler(\n event: Event<TEvent, TInput, TServices, TLogger, TSession>,\n ) {\n const input = this.endpoint.refineInput(event);\n const logger = event.logger as TLogger;\n const serviceDiscovery = ServiceDiscovery.getInstance<\n ServiceRecord<TServices>,\n TLogger\n >(logger, this.envParser);\n\n // Create audit context if audit storage is configured\n const auditContext = await createAuditContext(\n this.endpoint,\n serviceDiscovery,\n logger,\n {\n session: event.session,\n header: event.header,\n cookie: event.cookie,\n services: event.services as Record<string, unknown>,\n },\n );\n\n // Warn if declarative audits are configured but no audit storage\n const audits = this.endpoint.audits as MappedAudit<\n TAuditAction,\n TOutSchema\n >[];\n if (!auditContext && audits?.length) {\n logger.warn('No auditor storage service available');\n }\n\n // Get pre-resolved database from middleware\n const rawDb = (event as any).db;\n\n // Execute handler with automatic audit transaction support\n const result = await executeWithAuditTransaction(\n auditContext,\n async (auditor) => {\n // Use audit transaction as db only if the storage uses the same database service\n const sameDatabase =\n auditContext?.storage?.databaseServiceName &&\n auditContext.storage.databaseServiceName ===\n this.endpoint.databaseService?.serviceName;\n const db = sameDatabase\n ? (auditor?.getTransaction?.() ?? rawDb)\n : rawDb;\n\n const responseBuilder = new ResponseBuilder();\n const response = await this.endpoint.handler(\n {\n header: event.header,\n cookie: event.cookie,\n logger: event.logger,\n services: event.services,\n session: event.session,\n auditor,\n db,\n ...input,\n } as any,\n responseBuilder,\n );\n\n // Check if response has metadata\n let data = response;\n let metadata = responseBuilder.getMetadata();\n\n if (Endpoint.hasMetadata(response)) {\n data = response.data;\n metadata = response.metadata;\n }\n\n const output = this.endpoint.outputSchema\n ? await this.endpoint.parseOutput(data)\n : undefined;\n\n return { output, metadata, responseBuilder };\n },\n // Process declarative audits after handler (inside transaction)\n async (result, auditor) => {\n if (!audits?.length) return;\n\n for (const audit of audits) {\n if (audit.when && !audit.when(result.output as any)) {\n continue;\n }\n const payload = audit.payload(result.output as any);\n const entityId = audit.entityId?.(result.output as any);\n auditor.audit(audit.type as any, payload as any, {\n table: audit.table,\n entityId,\n });\n }\n },\n // Pass rawDb so storage can reuse existing transactions\n { db: rawDb },\n );\n\n const { output, metadata } = result;\n const body = output !== undefined ? JSON.stringify(output) : undefined;\n\n // Store response for middleware access\n (event as any).__response = output;\n\n // Build response with metadata\n const lambdaResponse: AmazonApiGatewayEndpointHandlerResponse = {\n statusCode: metadata.status ?? this.endpoint.status,\n body,\n };\n\n // Add custom headers\n if (metadata.headers && Object.keys(metadata.headers).length > 0) {\n lambdaResponse.headers = { ...metadata.headers };\n }\n\n // Format cookies as Set-Cookie headers\n if (metadata.cookies && metadata.cookies.size > 0) {\n const setCookieHeaders: string[] = [];\n for (const [name, { value, options }] of metadata.cookies) {\n setCookieHeaders.push(\n Endpoint.formatCookieHeader(name, value, options),\n );\n }\n\n if (setCookieHeaders.length > 0) {\n lambdaResponse.multiValueHeaders = {\n ...lambdaResponse.multiValueHeaders,\n 'Set-Cookie': setCookieHeaders,\n };\n }\n }\n\n return lambdaResponse;\n }\n\n get handler() {\n const handler = this._handler.bind(this);\n return middy(handler)\n .use(this.logger())\n .use(this.error())\n .use(this.services())\n .use(this.input())\n .use(this.database())\n .use(this.session())\n .use(this.authorize())\n .use(this.events()) as unknown as THandler;\n }\n}\n\nexport type Event<\n TEvent extends APIGatewayProxyEvent | APIGatewayProxyEventV2,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n> = {\n services: ServiceRecord<TServices>;\n logger: TLogger;\n header: HeaderFn;\n cookie: CookieFn;\n session: TSession;\n} & TEvent &\n InferComposableStandardSchema<TInput>;\n\ntype Middleware<\n TEvent extends APIGatewayProxyEvent | APIGatewayProxyEventV2,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n TSession = unknown,\n> = MiddlewareObj<Event<TEvent, TInput, TServices, TLogger, TSession>>;\n\nexport type AmazonApiGatewayEndpointHandlerResponse = {\n statusCode: number;\n body: string | undefined;\n headers?: Record<string, string>;\n multiValueHeaders?: Record<string, string[]>;\n};\n\nexport type LoggerContext = {\n fn: {\n name: string;\n version: string;\n };\n req: {\n id: string | undefined;\n awsRequestId: string;\n path: string;\n ip: string | undefined;\n userAgent: string | undefined;\n };\n};\n\nexport type GetInputResponse = {\n body: any;\n query: any;\n params: any;\n};\n\nexport type AmazonApiGatewayV1EndpointHandler = (\n event: APIGatewayProxyEvent,\n context: Context,\n) => Promise<AmazonApiGatewayEndpointHandlerResponse>;\n\nexport type AmazonApiGatewayV2EndpointHandler = (\n event: APIGatewayProxyEventV2,\n context: Context,\n) => Promise<AmazonApiGatewayEndpointHandlerResponse>;\n\nexport type HandlerEvent<T extends Function> = T extends (\n event: infer E,\n context: Context,\n) => any\n ? E\n : never;\n"],"mappings":"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"}