@geekmidas/constructs 0.0.21 → 0.1.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 (186) hide show
  1. package/README.md +90 -0
  2. package/dist/{AWSLambdaFunction-qWpalqfr.d.mts → AWSLambdaFunction-DCh1tOhB.d.mts} +3 -3
  3. package/dist/{AWSLambdaSubscriberAdaptor-CWbBNRz3.d.mts → AWSLambdaSubscriberAdaptor-DtNZPMoV.d.mts} +2 -2
  4. package/dist/{AmazonApiGatewayEndpointAdaptor-BQ0IJdaI.d.mts → AmazonApiGatewayEndpointAdaptor-BaTM2TNu.d.mts} +3 -3
  5. package/dist/{AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs → AmazonApiGatewayEndpointAdaptor-CPqlw2Rx.cjs} +3 -3
  6. package/dist/{AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs.map → AmazonApiGatewayEndpointAdaptor-CPqlw2Rx.cjs.map} +1 -1
  7. package/dist/{AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs → AmazonApiGatewayEndpointAdaptor-Cm4iD199.mjs} +3 -3
  8. package/dist/{AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs.map → AmazonApiGatewayEndpointAdaptor-Cm4iD199.mjs.map} +1 -1
  9. package/dist/{AmazonApiGatewayEndpointAdaptor-Da9BR5On.d.cts → AmazonApiGatewayEndpointAdaptor-TP_hLNAa.d.cts} +2 -2
  10. package/dist/{AmazonApiGatewayV1EndpointAdaptor-C4_AZ1ek.d.mts → AmazonApiGatewayV1EndpointAdaptor-B2ZpUFiC.d.mts} +4 -4
  11. package/dist/{AmazonApiGatewayV1EndpointAdaptor-CSm3NsWz.d.cts → AmazonApiGatewayV1EndpointAdaptor-CConfCqz.d.cts} +3 -3
  12. package/dist/{AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs → AmazonApiGatewayV1EndpointAdaptor-D38HuQa9.mjs} +2 -2
  13. package/dist/{AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs.map → AmazonApiGatewayV1EndpointAdaptor-D38HuQa9.mjs.map} +1 -1
  14. package/dist/{AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs → AmazonApiGatewayV1EndpointAdaptor-tjpvLBRb.cjs} +2 -2
  15. package/dist/{AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs.map → AmazonApiGatewayV1EndpointAdaptor-tjpvLBRb.cjs.map} +1 -1
  16. package/dist/{AmazonApiGatewayV2EndpointAdaptor-DdM8Tr1X.d.mts → AmazonApiGatewayV2EndpointAdaptor-BwMQInBi.d.mts} +4 -4
  17. package/dist/{AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs → AmazonApiGatewayV2EndpointAdaptor-ByYtiJtN.mjs} +2 -2
  18. package/dist/{AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs.map → AmazonApiGatewayV2EndpointAdaptor-ByYtiJtN.mjs.map} +1 -1
  19. package/dist/{AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs → AmazonApiGatewayV2EndpointAdaptor-DcJ_w3ro.cjs} +2 -2
  20. package/dist/{AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs.map → AmazonApiGatewayV2EndpointAdaptor-DcJ_w3ro.cjs.map} +1 -1
  21. package/dist/{AmazonApiGatewayV2EndpointAdaptor-6hsBFVLf.d.cts → AmazonApiGatewayV2EndpointAdaptor-DurJvFwa.d.cts} +3 -3
  22. package/dist/Authorizer-C0ge_tc8.cjs +92 -0
  23. package/dist/Authorizer-C0ge_tc8.cjs.map +1 -0
  24. package/dist/Authorizer-CpSUMTIs.d.cts +125 -0
  25. package/dist/Authorizer-D1w7MpK6.d.mts +125 -0
  26. package/dist/Authorizer-r9U3y_ms.mjs +68 -0
  27. package/dist/Authorizer-r9U3y_ms.mjs.map +1 -0
  28. package/dist/{BaseFunctionBuilder-Ct6zY6Jq.d.mts → BaseFunctionBuilder-Oc2xmxmg.d.mts} +2 -2
  29. package/dist/{Construct-DDR0295I.d.mts → Construct-DCPATqec.d.mts} +1 -1
  30. package/dist/Construct.d.mts +1 -1
  31. package/dist/{Cron-DnMRWPFR.d.mts → Cron-DPEcDCDW.d.mts} +2 -2
  32. package/dist/{CronBuilder-RLDitFmP.d.mts → CronBuilder-CxKTiepV.d.mts} +4 -4
  33. package/dist/{Endpoint-D2Imgihs.d.cts → Endpoint-BJPJTGjV.d.cts} +2 -2
  34. package/dist/{Endpoint-PtQ-wLIS.d.mts → Endpoint-DoY1Owv2.d.mts} +4 -4
  35. package/dist/{EndpointBuilder-B5QPf5Wd.mjs → EndpointBuilder-69uVrKZL.mjs} +15 -2
  36. package/dist/EndpointBuilder-69uVrKZL.mjs.map +1 -0
  37. package/dist/{EndpointBuilder-BPHpUekp.d.mts → EndpointBuilder-BJRkivxQ.d.mts} +6 -5
  38. package/dist/{EndpointBuilder-DrJbIf3Z.cjs → EndpointBuilder-Bhyft7WY.cjs} +15 -2
  39. package/dist/EndpointBuilder-Bhyft7WY.cjs.map +1 -0
  40. package/dist/{EndpointBuilder-TApJQhtG.d.cts → EndpointBuilder-CQ-jOXsD.d.cts} +4 -3
  41. package/dist/{EndpointFactory-DNwMexc7.mjs → EndpointFactory-ARUlRlyM.mjs} +94 -13
  42. package/dist/EndpointFactory-ARUlRlyM.mjs.map +1 -0
  43. package/dist/{EndpointFactory-TJ6gtM0W.d.mts → EndpointFactory-BKEPcQgE.d.mts} +50 -19
  44. package/dist/{EndpointFactory-CSeDcWYn.cjs → EndpointFactory-BcVbkrxf.cjs} +94 -13
  45. package/dist/EndpointFactory-BcVbkrxf.cjs.map +1 -0
  46. package/dist/{EndpointFactory-D94AFjIc.d.cts → EndpointFactory-DgwmAR_8.d.cts} +50 -19
  47. package/dist/{Function-CD3rXWfa.d.mts → Function-Dthlh2Fb.d.mts} +2 -2
  48. package/dist/{FunctionBuilder-j2VkwuGf.d.mts → FunctionBuilder-CZFBLfdV.d.mts} +4 -4
  49. package/dist/{FunctionExecutionWrapper-B0WP-Vec.d.mts → FunctionExecutionWrapper-CfuajSB5.d.mts} +2 -2
  50. package/dist/{HonoEndpointAdaptor-Bg_vTyA5.mjs → HonoEndpointAdaptor-BmB4Sc7L.mjs} +3 -3
  51. package/dist/{HonoEndpointAdaptor-Bg_vTyA5.mjs.map → HonoEndpointAdaptor-BmB4Sc7L.mjs.map} +1 -1
  52. package/dist/{HonoEndpointAdaptor-B_gJPWGD.cjs → HonoEndpointAdaptor-CnqR6PSB.cjs} +3 -3
  53. package/dist/{HonoEndpointAdaptor-B_gJPWGD.cjs.map → HonoEndpointAdaptor-CnqR6PSB.cjs.map} +1 -1
  54. package/dist/{HonoEndpointAdaptor-DB_DdiJr.d.cts → HonoEndpointAdaptor-DBjipl6Q.d.mts} +8 -8
  55. package/dist/{HonoEndpointAdaptor-D99d4b-Z.d.mts → HonoEndpointAdaptor-sSG85VER.d.cts} +6 -6
  56. package/dist/{Subscriber-itwm7ugy.d.mts → Subscriber-BfxLwZpX.d.mts} +2 -2
  57. package/dist/{Subscriber-D-FPWts6.cjs → Subscriber-DvOtIyWq.cjs} +1 -1
  58. package/dist/{Subscriber-D-FPWts6.cjs.map → Subscriber-DvOtIyWq.cjs.map} +1 -1
  59. package/dist/{Subscriber-CGb8LjZa.mjs → Subscriber-JzcFFi4p.mjs} +1 -1
  60. package/dist/{Subscriber-CGb8LjZa.mjs.map → Subscriber-JzcFFi4p.mjs.map} +1 -1
  61. package/dist/{SubscriberBuilder-BfE2cL1q.cjs → SubscriberBuilder-DUuV207i.cjs} +2 -2
  62. package/dist/{SubscriberBuilder-BfE2cL1q.cjs.map → SubscriberBuilder-DUuV207i.cjs.map} +1 -1
  63. package/dist/{SubscriberBuilder-9j3JCu8-.d.mts → SubscriberBuilder-lTiTUS1o.d.mts} +2 -2
  64. package/dist/{SubscriberBuilder-BcAspHv9.mjs → SubscriberBuilder-tm4oVOt3.mjs} +2 -2
  65. package/dist/{SubscriberBuilder-BcAspHv9.mjs.map → SubscriberBuilder-tm4oVOt3.mjs.map} +1 -1
  66. package/dist/{TestEndpointAdaptor-Bew9lWsx.cjs → TestEndpointAdaptor-BtLcw4JW.cjs} +3 -3
  67. package/dist/{TestEndpointAdaptor-Bew9lWsx.cjs.map → TestEndpointAdaptor-BtLcw4JW.cjs.map} +1 -1
  68. package/dist/{TestEndpointAdaptor-C-c8v7VI.d.mts → TestEndpointAdaptor-CGQVysE0.d.mts} +3 -3
  69. package/dist/{TestEndpointAdaptor-BYCwwiYk.d.cts → TestEndpointAdaptor-CJO-og9U.d.cts} +2 -2
  70. package/dist/{TestEndpointAdaptor-JONQJeXc.mjs → TestEndpointAdaptor-o7JbNcL-.mjs} +3 -3
  71. package/dist/{TestEndpointAdaptor-JONQJeXc.mjs.map → TestEndpointAdaptor-o7JbNcL-.mjs.map} +1 -1
  72. package/dist/adaptors/aws.cjs +4 -4
  73. package/dist/adaptors/aws.d.cts +6 -6
  74. package/dist/adaptors/aws.d.mts +15 -15
  75. package/dist/adaptors/aws.mjs +4 -4
  76. package/dist/adaptors/hono.cjs +2 -2
  77. package/dist/adaptors/hono.d.cts +4 -4
  78. package/dist/adaptors/hono.d.mts +9 -9
  79. package/dist/adaptors/hono.mjs +2 -2
  80. package/dist/adaptors/testing.cjs +2 -2
  81. package/dist/adaptors/testing.d.cts +4 -4
  82. package/dist/adaptors/testing.d.mts +9 -9
  83. package/dist/adaptors/testing.mjs +2 -2
  84. package/dist/crons/Cron.d.cts +1 -1
  85. package/dist/crons/Cron.d.mts +6 -6
  86. package/dist/crons/CronBuilder.d.cts +1 -1
  87. package/dist/crons/CronBuilder.d.mts +7 -7
  88. package/dist/crons/index.d.cts +5 -5
  89. package/dist/crons/index.d.mts +11 -11
  90. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +2 -2
  91. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +4 -4
  92. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +9 -9
  93. package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +2 -2
  94. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +3 -3
  95. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +5 -5
  96. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +10 -10
  97. package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +3 -3
  98. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +3 -3
  99. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +5 -5
  100. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +10 -10
  101. package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +3 -3
  102. package/dist/endpoints/Authorizer.cjs +5 -14
  103. package/dist/endpoints/Authorizer.d.cts +2 -2
  104. package/dist/endpoints/Authorizer.d.mts +2 -2
  105. package/dist/endpoints/Authorizer.mjs +2 -13
  106. package/dist/endpoints/Endpoint.d.cts +3 -3
  107. package/dist/endpoints/Endpoint.d.mts +8 -8
  108. package/dist/endpoints/EndpointBuilder.cjs +2 -1
  109. package/dist/endpoints/EndpointBuilder.d.cts +4 -4
  110. package/dist/endpoints/EndpointBuilder.d.mts +9 -9
  111. package/dist/endpoints/EndpointBuilder.mjs +2 -1
  112. package/dist/endpoints/EndpointFactory.cjs +3 -2
  113. package/dist/endpoints/EndpointFactory.d.cts +5 -5
  114. package/dist/endpoints/EndpointFactory.d.mts +10 -10
  115. package/dist/endpoints/EndpointFactory.mjs +3 -2
  116. package/dist/endpoints/HonoEndpointAdaptor.cjs +2 -2
  117. package/dist/endpoints/HonoEndpointAdaptor.d.cts +4 -4
  118. package/dist/endpoints/HonoEndpointAdaptor.d.mts +9 -9
  119. package/dist/endpoints/HonoEndpointAdaptor.mjs +2 -2
  120. package/dist/endpoints/TestEndpointAdaptor.cjs +2 -2
  121. package/dist/endpoints/TestEndpointAdaptor.d.cts +4 -4
  122. package/dist/endpoints/TestEndpointAdaptor.d.mts +9 -9
  123. package/dist/endpoints/TestEndpointAdaptor.mjs +2 -2
  124. package/dist/endpoints/audit.d.cts +3 -3
  125. package/dist/endpoints/audit.d.mts +8 -8
  126. package/dist/endpoints/helpers.d.cts +3 -3
  127. package/dist/endpoints/helpers.d.mts +8 -8
  128. package/dist/endpoints/index.cjs +3 -2
  129. package/dist/endpoints/index.cjs.map +1 -1
  130. package/dist/endpoints/index.d.cts +7 -7
  131. package/dist/endpoints/index.d.mts +12 -12
  132. package/dist/endpoints/index.mjs +3 -2
  133. package/dist/endpoints/index.mjs.map +1 -1
  134. package/dist/endpoints/processAudits.cjs +1 -1
  135. package/dist/endpoints/processAudits.d.cts +25 -6
  136. package/dist/endpoints/processAudits.d.mts +30 -11
  137. package/dist/endpoints/processAudits.mjs +1 -1
  138. package/dist/functions/AWSLambdaFunction.d.mts +4 -4
  139. package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
  140. package/dist/functions/Function.d.mts +2 -2
  141. package/dist/functions/FunctionBuilder.d.mts +4 -4
  142. package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
  143. package/dist/functions/TestFunctionAdaptor.d.mts +2 -2
  144. package/dist/functions/index.d.cts +1 -1
  145. package/dist/functions/index.d.mts +5 -5
  146. package/dist/{index-IoTEI3As.d.mts → index-9gJrM7Rw.d.mts} +2 -2
  147. package/dist/index-Ceo-GuhJ.d.cts +10 -0
  148. package/dist/index.d.mts +2 -2
  149. package/dist/{processAudits-BFokHhCO.cjs → processAudits-CzHkPokQ.cjs} +13 -7
  150. package/dist/processAudits-CzHkPokQ.cjs.map +1 -0
  151. package/dist/{processAudits-DfcB-X-4.mjs → processAudits-Dj8UGqcW.mjs} +13 -7
  152. package/dist/processAudits-Dj8UGqcW.mjs.map +1 -0
  153. package/dist/publisher.d.mts +1 -1
  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.cts +2 -2
  163. package/dist/subscribers/index.d.mts +5 -5
  164. package/dist/subscribers/index.mjs +2 -2
  165. package/dist/{types-DKf0juBf.d.mts → types-Cy1IhmUB.d.mts} +1 -1
  166. package/dist/types.d.mts +1 -1
  167. package/package.json +6 -6
  168. package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +2 -0
  169. package/src/endpoints/Authorizer.ts +119 -1
  170. package/src/endpoints/EndpointBuilder.ts +24 -4
  171. package/src/endpoints/EndpointFactory.ts +215 -22
  172. package/src/endpoints/HonoEndpointAdaptor.ts +2 -0
  173. package/src/endpoints/TestEndpointAdaptor.ts +2 -0
  174. package/src/endpoints/__tests__/EndpointFactory.authorizers.spec.ts +141 -0
  175. package/src/endpoints/processAudits.ts +39 -16
  176. package/dist/Authorizer-BTmly8ps.d.cts +0 -29
  177. package/dist/Authorizer-pmPvIVgv.d.mts +0 -29
  178. package/dist/EndpointBuilder-B5QPf5Wd.mjs.map +0 -1
  179. package/dist/EndpointBuilder-DrJbIf3Z.cjs.map +0 -1
  180. package/dist/EndpointFactory-CSeDcWYn.cjs.map +0 -1
  181. package/dist/EndpointFactory-DNwMexc7.mjs.map +0 -1
  182. package/dist/endpoints/Authorizer.cjs.map +0 -1
  183. package/dist/endpoints/Authorizer.mjs.map +0 -1
  184. package/dist/index-C6vCFivC.d.cts +0 -10
  185. package/dist/processAudits-BFokHhCO.cjs.map +0 -1
  186. package/dist/processAudits-DfcB-X-4.mjs.map +0 -1
@@ -12,7 +12,8 @@ import uniqBy from 'lodash.uniqby';
12
12
  import { ConstructType } from '../Construct';
13
13
  import { BaseFunctionBuilder } from '../functions';
14
14
  import type { HttpMethod } from '../types';
15
- import type { Authorizer } from './Authorizer';
15
+ import type { Authorizer, SecurityScheme } from './Authorizer';
16
+ import { getSecurityScheme } from './Authorizer';
16
17
  import { Endpoint, type EndpointSchemas } from './Endpoint';
17
18
  import type {
18
19
  AuthorizeFn,
@@ -66,6 +67,7 @@ export class EndpointBuilder<
66
67
  _authorizerName?: TAuthorizers[number];
67
68
  _actorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
68
69
  _audits: MappedAudit<TAuditAction, OutSchema>[] = [];
70
+ _customSecuritySchemes: Record<string, SecurityScheme> = {};
69
71
 
70
72
  constructor(
71
73
  readonly route: TRoute,
@@ -616,9 +618,27 @@ export class EndpointBuilder<
616
618
  TDatabaseServiceName
617
619
  > {
618
620
  // Find authorizer metadata if name is set
619
- const authorizer = this._authorizerName
620
- ? this._availableAuthorizers.find((a) => a.name === this._authorizerName)
621
- : undefined;
621
+ // If the authorizer name is set but not in availableAuthorizers, create a simple authorizer object
622
+ let authorizer: Authorizer | undefined;
623
+ if (this._authorizerName) {
624
+ const existingAuthorizer = this._availableAuthorizers.find(
625
+ (a) => a.name === this._authorizerName,
626
+ );
627
+
628
+ if (existingAuthorizer) {
629
+ authorizer = existingAuthorizer;
630
+ } else {
631
+ // Create authorizer with security scheme if available (built-in or custom)
632
+ const securityScheme = getSecurityScheme(
633
+ this._authorizerName as string,
634
+ this._customSecuritySchemes,
635
+ );
636
+ authorizer = {
637
+ name: this._authorizerName as string,
638
+ securityScheme,
639
+ };
640
+ }
641
+ }
622
642
 
623
643
  return new Endpoint({
624
644
  fn,
@@ -9,7 +9,11 @@ import { ConsoleLogger } from '@geekmidas/logger/console';
9
9
  import type { Service } from '@geekmidas/services';
10
10
  import uniqBy from 'lodash.uniqby';
11
11
  import type { HttpMethod } from '../types';
12
- import type { Authorizer } from './Authorizer';
12
+ import type {
13
+ Authorizer,
14
+ BuiltInSecuritySchemeId,
15
+ SecurityScheme,
16
+ } from './Authorizer';
13
17
  import type { AuthorizeFn, SessionFn } from './Endpoint';
14
18
  import { EndpointBuilder } from './EndpointBuilder';
15
19
  import type { ActorExtractor } from './audit';
@@ -32,6 +36,10 @@ export class EndpointFactory<
32
36
  > = ExtractStorageAuditAction<NonNullable<TAuditStorage>>,
33
37
  TDatabase = undefined,
34
38
  TDatabaseServiceName extends string = string,
39
+ TSecuritySchemes extends Record<string, SecurityScheme> = Record<
40
+ string,
41
+ SecurityScheme
42
+ >,
35
43
  > {
36
44
  // @ts-ignore
37
45
  private defaultServices: TServices;
@@ -56,6 +64,7 @@ export class EndpointFactory<
56
64
  | Service<TDatabaseServiceName, TDatabase>
57
65
  | undefined;
58
66
  private defaultActorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
67
+ private customSecuritySchemes: TSecuritySchemes = {} as TSecuritySchemes;
59
68
 
60
69
  constructor({
61
70
  basePath,
@@ -70,6 +79,7 @@ export class EndpointFactory<
70
79
  defaultAuditorStorage,
71
80
  defaultDatabaseService,
72
81
  defaultActorExtractor,
82
+ customSecuritySchemes = {} as TSecuritySchemes,
73
83
  }: EndpointFactoryOptions<
74
84
  TServices,
75
85
  TBasePath,
@@ -81,7 +91,8 @@ export class EndpointFactory<
81
91
  TAuditStorage,
82
92
  TAuditStorageServiceName,
83
93
  TDatabase,
84
- TDatabaseServiceName
94
+ TDatabaseServiceName,
95
+ TSecuritySchemes
85
96
  > = {}) {
86
97
  // Initialize default services
87
98
  this.defaultServices = uniqBy(
@@ -99,6 +110,7 @@ export class EndpointFactory<
99
110
  this.defaultAuditorStorage = defaultAuditorStorage;
100
111
  this.defaultDatabaseService = defaultDatabaseService;
101
112
  this.defaultActorExtractor = defaultActorExtractor;
113
+ this.customSecuritySchemes = customSecuritySchemes;
102
114
  }
103
115
 
104
116
  static joinPaths<TBasePath extends string, P extends string>(
@@ -153,7 +165,8 @@ export class EndpointFactory<
153
165
  TAuditStorageServiceName,
154
166
  TAuditAction,
155
167
  TDatabase,
156
- TDatabaseServiceName
168
+ TDatabaseServiceName,
169
+ TSecuritySchemes
157
170
  > {
158
171
  const authorizerConfigs = authorizers.map((name) => ({
159
172
  name,
@@ -170,7 +183,8 @@ export class EndpointFactory<
170
183
  TAuditStorageServiceName,
171
184
  TAuditAction,
172
185
  TDatabase,
173
- TDatabaseServiceName
186
+ TDatabaseServiceName,
187
+ TSecuritySchemes
174
188
  >({
175
189
  defaultServices: this.defaultServices,
176
190
  basePath: this.basePath,
@@ -183,6 +197,150 @@ export class EndpointFactory<
183
197
  defaultAuditorStorage: this.defaultAuditorStorage,
184
198
  defaultDatabaseService: this.defaultDatabaseService,
185
199
  defaultActorExtractor: this.defaultActorExtractor,
200
+ customSecuritySchemes: this.customSecuritySchemes,
201
+ });
202
+ }
203
+
204
+ /**
205
+ * Define custom security schemes for this factory.
206
+ * These extend the built-in schemes (jwt, bearer, apiKey, oauth2, oidc).
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * const router = e.securitySchemes({
211
+ * awsIamSigV4: {
212
+ * type: 'apiKey',
213
+ * in: 'header',
214
+ * name: 'Authorization',
215
+ * 'x-amazon-apigateway-authtype': 'awsSigv4',
216
+ * },
217
+ * });
218
+ * ```
219
+ */
220
+ securitySchemes<T extends Record<string, SecurityScheme>>(
221
+ schemes: T,
222
+ ): EndpointFactory<
223
+ TServices,
224
+ TBasePath,
225
+ TLogger,
226
+ TSession,
227
+ TEventPublisher,
228
+ TEventPublisherServiceName,
229
+ TAuthorizers,
230
+ TAuditStorage,
231
+ TAuditStorageServiceName,
232
+ TAuditAction,
233
+ TDatabase,
234
+ TDatabaseServiceName,
235
+ TSecuritySchemes & T
236
+ > {
237
+ return new EndpointFactory<
238
+ TServices,
239
+ TBasePath,
240
+ TLogger,
241
+ TSession,
242
+ TEventPublisher,
243
+ TEventPublisherServiceName,
244
+ TAuthorizers,
245
+ TAuditStorage,
246
+ TAuditStorageServiceName,
247
+ TAuditAction,
248
+ TDatabase,
249
+ TDatabaseServiceName,
250
+ TSecuritySchemes & T
251
+ >({
252
+ defaultServices: this.defaultServices,
253
+ basePath: this.basePath,
254
+ defaultAuthorizeFn: this.defaultAuthorizeFn,
255
+ defaultLogger: this.defaultLogger,
256
+ defaultSessionExtractor: this.defaultSessionExtractor,
257
+ defaultEventPublisher: this.defaultEventPublisher,
258
+ availableAuthorizers: this.availableAuthorizers,
259
+ defaultAuthorizerName: this.defaultAuthorizerName,
260
+ defaultAuditorStorage: this.defaultAuditorStorage,
261
+ defaultDatabaseService: this.defaultDatabaseService,
262
+ defaultActorExtractor: this.defaultActorExtractor,
263
+ customSecuritySchemes: {
264
+ ...this.customSecuritySchemes,
265
+ ...schemes,
266
+ } as TSecuritySchemes & T,
267
+ });
268
+ }
269
+
270
+ /**
271
+ * Set the default authorizer for all endpoints created from this factory.
272
+ * Individual endpoints can override this by calling `.authorizer()` on the builder.
273
+ * Use `'none'` to explicitly disable authorization for all endpoints.
274
+ *
275
+ * Accepts:
276
+ * - Built-in security scheme names: 'jwt', 'bearer', 'apiKey', 'oauth2', 'oidc'
277
+ * - Custom security scheme names defined via `.securitySchemes()`
278
+ * - 'none' to disable authorization
279
+ */
280
+ authorizer(
281
+ name:
282
+ | BuiltInSecuritySchemeId
283
+ | keyof TSecuritySchemes
284
+ | TAuthorizers[number]
285
+ | 'none',
286
+ ): EndpointFactory<
287
+ TServices,
288
+ TBasePath,
289
+ TLogger,
290
+ TSession,
291
+ TEventPublisher,
292
+ TEventPublisherServiceName,
293
+ TAuthorizers,
294
+ TAuditStorage,
295
+ TAuditStorageServiceName,
296
+ TAuditAction,
297
+ TDatabase,
298
+ TDatabaseServiceName,
299
+ TSecuritySchemes
300
+ > {
301
+ // Validate that the authorizer exists in available authorizers (if authorizers() was called)
302
+ if (name !== 'none' && this.availableAuthorizers.length > 0) {
303
+ const authorizerExists = this.availableAuthorizers.some(
304
+ (a) => a.name === name,
305
+ );
306
+ if (!authorizerExists) {
307
+ const available = this.availableAuthorizers
308
+ .map((a) => a.name)
309
+ .join(', ');
310
+ throw new Error(
311
+ `Authorizer "${name as string}" not found in available authorizers: ${available}`,
312
+ );
313
+ }
314
+ }
315
+
316
+ return new EndpointFactory<
317
+ TServices,
318
+ TBasePath,
319
+ TLogger,
320
+ TSession,
321
+ TEventPublisher,
322
+ TEventPublisherServiceName,
323
+ TAuthorizers,
324
+ TAuditStorage,
325
+ TAuditStorageServiceName,
326
+ TAuditAction,
327
+ TDatabase,
328
+ TDatabaseServiceName,
329
+ TSecuritySchemes
330
+ >({
331
+ defaultServices: this.defaultServices,
332
+ basePath: this.basePath,
333
+ defaultAuthorizeFn: this.defaultAuthorizeFn,
334
+ defaultLogger: this.defaultLogger,
335
+ defaultSessionExtractor: this.defaultSessionExtractor,
336
+ defaultEventPublisher: this.defaultEventPublisher,
337
+ availableAuthorizers: this.availableAuthorizers,
338
+ defaultAuthorizerName:
339
+ name === 'none' ? undefined : (name as TAuthorizers[number]),
340
+ defaultAuditorStorage: this.defaultAuditorStorage,
341
+ defaultDatabaseService: this.defaultDatabaseService,
342
+ defaultActorExtractor: this.defaultActorExtractor,
343
+ customSecuritySchemes: this.customSecuritySchemes,
186
344
  });
187
345
  }
188
346
 
@@ -201,7 +359,8 @@ export class EndpointFactory<
201
359
  TAuditStorageServiceName,
202
360
  TAuditAction,
203
361
  TDatabase,
204
- TDatabaseServiceName
362
+ TDatabaseServiceName,
363
+ TSecuritySchemes
205
364
  > {
206
365
  const newBasePath = EndpointFactory.joinPaths(path, this.basePath);
207
366
  return new EndpointFactory<
@@ -216,7 +375,8 @@ export class EndpointFactory<
216
375
  TAuditStorageServiceName,
217
376
  TAuditAction,
218
377
  TDatabase,
219
- TDatabaseServiceName
378
+ TDatabaseServiceName,
379
+ TSecuritySchemes
220
380
  >({
221
381
  defaultServices: this.defaultServices,
222
382
  basePath: newBasePath,
@@ -229,6 +389,7 @@ export class EndpointFactory<
229
389
  defaultAuditorStorage: this.defaultAuditorStorage,
230
390
  defaultDatabaseService: this.defaultDatabaseService,
231
391
  defaultActorExtractor: this.defaultActorExtractor,
392
+ customSecuritySchemes: this.customSecuritySchemes,
232
393
  });
233
394
  }
234
395
 
@@ -247,7 +408,8 @@ export class EndpointFactory<
247
408
  TAuditStorageServiceName,
248
409
  TAuditAction,
249
410
  TDatabase,
250
- TDatabaseServiceName
411
+ TDatabaseServiceName,
412
+ TSecuritySchemes
251
413
  > {
252
414
  return new EndpointFactory<
253
415
  TServices,
@@ -261,7 +423,8 @@ export class EndpointFactory<
261
423
  TAuditStorageServiceName,
262
424
  TAuditAction,
263
425
  TDatabase,
264
- TDatabaseServiceName
426
+ TDatabaseServiceName,
427
+ TSecuritySchemes
265
428
  >({
266
429
  defaultServices: this.defaultServices,
267
430
  basePath: this.basePath,
@@ -274,6 +437,7 @@ export class EndpointFactory<
274
437
  defaultAuditorStorage: this.defaultAuditorStorage,
275
438
  defaultDatabaseService: this.defaultDatabaseService,
276
439
  defaultActorExtractor: this.defaultActorExtractor,
440
+ customSecuritySchemes: this.customSecuritySchemes,
277
441
  });
278
442
  }
279
443
 
@@ -292,7 +456,8 @@ export class EndpointFactory<
292
456
  TAuditStorageServiceName,
293
457
  TAuditAction,
294
458
  TDatabase,
295
- TDatabaseServiceName
459
+ TDatabaseServiceName,
460
+ TSecuritySchemes
296
461
  > {
297
462
  return new EndpointFactory<
298
463
  [...S, ...TServices],
@@ -306,7 +471,8 @@ export class EndpointFactory<
306
471
  TAuditStorageServiceName,
307
472
  TAuditAction,
308
473
  TDatabase,
309
- TDatabaseServiceName
474
+ TDatabaseServiceName,
475
+ TSecuritySchemes
310
476
  >({
311
477
  defaultServices: [...services, ...this.defaultServices],
312
478
  basePath: this.basePath,
@@ -319,6 +485,7 @@ export class EndpointFactory<
319
485
  defaultAuditorStorage: this.defaultAuditorStorage,
320
486
  defaultDatabaseService: this.defaultDatabaseService,
321
487
  defaultActorExtractor: this.defaultActorExtractor,
488
+ customSecuritySchemes: this.customSecuritySchemes,
322
489
  });
323
490
  }
324
491
 
@@ -336,7 +503,8 @@ export class EndpointFactory<
336
503
  TAuditStorageServiceName,
337
504
  TAuditAction,
338
505
  TDatabase,
339
- TDatabaseServiceName
506
+ TDatabaseServiceName,
507
+ TSecuritySchemes
340
508
  > {
341
509
  return new EndpointFactory<
342
510
  TServices,
@@ -350,7 +518,8 @@ export class EndpointFactory<
350
518
  TAuditStorageServiceName,
351
519
  TAuditAction,
352
520
  TDatabase,
353
- TDatabaseServiceName
521
+ TDatabaseServiceName,
522
+ TSecuritySchemes
354
523
  >({
355
524
  defaultServices: this.defaultServices,
356
525
  basePath: this.basePath,
@@ -377,6 +546,7 @@ export class EndpointFactory<
377
546
  TSession,
378
547
  L
379
548
  >,
549
+ customSecuritySchemes: this.customSecuritySchemes,
380
550
  });
381
551
  }
382
552
 
@@ -397,7 +567,8 @@ export class EndpointFactory<
397
567
  TAuditStorageServiceName,
398
568
  TAuditAction,
399
569
  TDatabase,
400
- TDatabaseServiceName
570
+ TDatabaseServiceName,
571
+ TSecuritySchemes
401
572
  > {
402
573
  return new EndpointFactory<
403
574
  TServices,
@@ -411,7 +582,8 @@ export class EndpointFactory<
411
582
  TAuditStorageServiceName,
412
583
  TAuditAction,
413
584
  TDatabase,
414
- TDatabaseServiceName
585
+ TDatabaseServiceName,
586
+ TSecuritySchemes
415
587
  >({
416
588
  defaultServices: this.defaultServices,
417
589
  basePath: this.basePath,
@@ -424,6 +596,7 @@ export class EndpointFactory<
424
596
  defaultAuditorStorage: this.defaultAuditorStorage,
425
597
  defaultDatabaseService: this.defaultDatabaseService,
426
598
  defaultActorExtractor: this.defaultActorExtractor,
599
+ customSecuritySchemes: this.customSecuritySchemes,
427
600
  });
428
601
  }
429
602
 
@@ -441,7 +614,8 @@ export class EndpointFactory<
441
614
  TAuditStorageServiceName,
442
615
  TAuditAction,
443
616
  TDatabase,
444
- TDatabaseServiceName
617
+ TDatabaseServiceName,
618
+ TSecuritySchemes
445
619
  > {
446
620
  return new EndpointFactory<
447
621
  TServices,
@@ -455,7 +629,8 @@ export class EndpointFactory<
455
629
  TAuditStorageServiceName,
456
630
  TAuditAction,
457
631
  TDatabase,
458
- TDatabaseServiceName
632
+ TDatabaseServiceName,
633
+ TSecuritySchemes
459
634
  >({
460
635
  defaultServices: this.defaultServices,
461
636
  basePath: this.basePath,
@@ -477,6 +652,7 @@ export class EndpointFactory<
477
652
  T,
478
653
  TLogger
479
654
  >,
655
+ customSecuritySchemes: this.customSecuritySchemes,
480
656
  });
481
657
  }
482
658
 
@@ -498,7 +674,8 @@ export class EndpointFactory<
498
674
  TAuditStorageServiceName,
499
675
  TAuditAction,
500
676
  T,
501
- TName
677
+ TName,
678
+ TSecuritySchemes
502
679
  > {
503
680
  return new EndpointFactory<
504
681
  TServices,
@@ -512,7 +689,8 @@ export class EndpointFactory<
512
689
  TAuditStorageServiceName,
513
690
  TAuditAction,
514
691
  T,
515
- TName
692
+ TName,
693
+ TSecuritySchemes
516
694
  >({
517
695
  defaultServices: this.defaultServices,
518
696
  basePath: this.basePath,
@@ -528,6 +706,7 @@ export class EndpointFactory<
528
706
  defaultAuthorizerName: this.defaultAuthorizerName,
529
707
  defaultAuditorStorage: this.defaultAuditorStorage,
530
708
  defaultDatabaseService: service,
709
+ customSecuritySchemes: this.customSecuritySchemes,
531
710
  });
532
711
  }
533
712
 
@@ -550,7 +729,8 @@ export class EndpointFactory<
550
729
  TName,
551
730
  ExtractStorageAuditAction<T>,
552
731
  TDatabase,
553
- TDatabaseServiceName
732
+ TDatabaseServiceName,
733
+ TSecuritySchemes
554
734
  > {
555
735
  return new EndpointFactory<
556
736
  TServices,
@@ -564,7 +744,8 @@ export class EndpointFactory<
564
744
  TName,
565
745
  ExtractStorageAuditAction<T>,
566
746
  TDatabase,
567
- TDatabaseServiceName
747
+ TDatabaseServiceName,
748
+ TSecuritySchemes
568
749
  >({
569
750
  defaultServices: this.defaultServices,
570
751
  basePath: this.basePath,
@@ -582,6 +763,7 @@ export class EndpointFactory<
582
763
  TSession,
583
764
  TLogger
584
765
  >,
766
+ customSecuritySchemes: this.customSecuritySchemes,
585
767
  });
586
768
  }
587
769
 
@@ -603,7 +785,8 @@ export class EndpointFactory<
603
785
  TAuditStorageServiceName,
604
786
  TAuditAction,
605
787
  TDatabase,
606
- TDatabaseServiceName
788
+ TDatabaseServiceName,
789
+ TSecuritySchemes
607
790
  > {
608
791
  return new EndpointFactory<
609
792
  TServices,
@@ -617,7 +800,8 @@ export class EndpointFactory<
617
800
  TAuditStorageServiceName,
618
801
  TAuditAction,
619
802
  TDatabase,
620
- TDatabaseServiceName
803
+ TDatabaseServiceName,
804
+ TSecuritySchemes
621
805
  >({
622
806
  defaultServices: this.defaultServices,
623
807
  basePath: this.basePath,
@@ -630,6 +814,7 @@ export class EndpointFactory<
630
814
  defaultAuditorStorage: this.defaultAuditorStorage,
631
815
  defaultDatabaseService: this.defaultDatabaseService,
632
816
  defaultActorExtractor: extractor,
817
+ customSecuritySchemes: this.customSecuritySchemes,
633
818
  });
634
819
  }
635
820
 
@@ -718,6 +903,9 @@ export class EndpointFactory<
718
903
  builder._actorExtractor = this.defaultActorExtractor;
719
904
  }
720
905
 
906
+ // Set custom security schemes
907
+ builder._customSecuritySchemes = this.customSecuritySchemes;
908
+
721
909
  return builder;
722
910
  }
723
911
 
@@ -785,6 +973,10 @@ export interface EndpointFactoryOptions<
785
973
  TAuditStorageServiceName extends string = string,
786
974
  TDatabase = undefined,
787
975
  TDatabaseServiceName extends string = string,
976
+ TSecuritySchemes extends Record<string, SecurityScheme> = Record<
977
+ string,
978
+ SecurityScheme
979
+ >,
788
980
  > {
789
981
  defaultServices?: TServices;
790
982
  basePath?: TBasePath;
@@ -798,6 +990,7 @@ export interface EndpointFactoryOptions<
798
990
  defaultAuditorStorage?: Service<TAuditStorageServiceName, TAuditStorage>;
799
991
  defaultDatabaseService?: Service<TDatabaseServiceName, TDatabase>;
800
992
  defaultActorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
993
+ customSecuritySchemes?: TSecuritySchemes;
801
994
  }
802
995
 
803
996
  export const e = new EndpointFactory();
@@ -443,6 +443,8 @@ export class HonoEndpoint<
443
443
  });
444
444
  }
445
445
  },
446
+ // Pass rawDb so storage can reuse existing transactions
447
+ { db: rawDb },
446
448
  );
447
449
 
448
450
  const { output, metadata } = result;
@@ -293,6 +293,8 @@ export class TestEndpointAdaptor<
293
293
  });
294
294
  }
295
295
  },
296
+ // Pass rawDb so storage can reuse existing transactions
297
+ { db: rawDb },
296
298
  );
297
299
 
298
300
  const { output, metadata } = result;
@@ -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
+ });