@geekmidas/constructs 0.0.22 → 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.
- package/README.md +90 -0
- package/dist/{AWSLambdaFunction-qWpalqfr.d.mts → AWSLambdaFunction-D9RZhm0N.d.mts} +3 -3
- package/dist/{AWSLambdaSubscriberAdaptor-CWbBNRz3.d.mts → AWSLambdaSubscriberAdaptor-C0aZBU64.d.mts} +2 -2
- package/dist/{AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs → AmazonApiGatewayEndpointAdaptor-Bk6ssx3K.cjs} +40 -27
- package/dist/AmazonApiGatewayEndpointAdaptor-Bk6ssx3K.cjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-Da9BR5On.d.cts → AmazonApiGatewayEndpointAdaptor-CbJqLU6I.d.cts} +2 -2
- package/dist/{AmazonApiGatewayEndpointAdaptor-BQ0IJdaI.d.mts → AmazonApiGatewayEndpointAdaptor-DC3N7zY_.d.mts} +3 -3
- package/dist/{AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs → AmazonApiGatewayEndpointAdaptor-pEWzF2uY.mjs} +40 -27
- package/dist/AmazonApiGatewayEndpointAdaptor-pEWzF2uY.mjs.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-C4_AZ1ek.d.mts → AmazonApiGatewayV1EndpointAdaptor-BVxgQ-7J.d.mts} +4 -4
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CSm3NsWz.d.cts → AmazonApiGatewayV1EndpointAdaptor-CVwJ5k16.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs → AmazonApiGatewayV1EndpointAdaptor-MJpRbIaQ.mjs} +2 -2
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-BpnG55R7.mjs.map → AmazonApiGatewayV1EndpointAdaptor-MJpRbIaQ.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs → AmazonApiGatewayV1EndpointAdaptor-uBp_4zLf.cjs} +2 -2
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-Df4kszio.cjs.map → AmazonApiGatewayV1EndpointAdaptor-uBp_4zLf.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-6hsBFVLf.d.cts → AmazonApiGatewayV2EndpointAdaptor-1oBZdQH3.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DdM8Tr1X.d.mts → AmazonApiGatewayV2EndpointAdaptor-C3H8Hpv7.d.mts} +4 -4
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs → AmazonApiGatewayV2EndpointAdaptor-ChO8BlDz.mjs} +2 -2
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-ZORzMEET.mjs.map → AmazonApiGatewayV2EndpointAdaptor-ChO8BlDz.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs → AmazonApiGatewayV2EndpointAdaptor-I1W23Nvn.cjs} +2 -2
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-5SIvqPby.cjs.map → AmazonApiGatewayV2EndpointAdaptor-I1W23Nvn.cjs.map} +1 -1
- package/dist/Authorizer-C0ge_tc8.cjs +92 -0
- package/dist/Authorizer-C0ge_tc8.cjs.map +1 -0
- package/dist/Authorizer-CpSUMTIs.d.cts +125 -0
- package/dist/Authorizer-Cpx59w_q.d.mts +125 -0
- package/dist/Authorizer-r9U3y_ms.mjs +68 -0
- package/dist/Authorizer-r9U3y_ms.mjs.map +1 -0
- package/dist/{BaseFunctionBuilder-Ct6zY6Jq.d.mts → BaseFunctionBuilder-CoV7J45W.d.mts} +2 -2
- package/dist/{Construct-DDR0295I.d.mts → Construct-jBKqb-Zi.d.mts} +1 -1
- package/dist/Construct.d.mts +1 -1
- package/dist/{Cron-DnMRWPFR.d.mts → Cron-JZkp_fHy.d.mts} +2 -2
- package/dist/{CronBuilder-RLDitFmP.d.mts → CronBuilder-BmFDO0Dm.d.mts} +4 -4
- package/dist/{Endpoint-DbPsw13b.mjs → Endpoint-B70_KKhu.mjs} +8 -2
- package/dist/Endpoint-B70_KKhu.mjs.map +1 -0
- package/dist/{Endpoint-CA-byrDr.cjs → Endpoint-BJo9Hhwm.cjs} +8 -2
- package/dist/Endpoint-BJo9Hhwm.cjs.map +1 -0
- package/dist/{Endpoint-PtQ-wLIS.d.mts → Endpoint-C5djXyae.d.mts} +69 -6
- package/dist/{Endpoint-D2Imgihs.d.cts → Endpoint-CC2RGjkl.d.cts} +67 -4
- package/dist/{EndpointBuilder-BPHpUekp.d.mts → EndpointBuilder-CD8LkBda.d.mts} +43 -5
- package/dist/{EndpointBuilder-CYkeYpsL.cjs → EndpointBuilder-DeswNQdG.cjs} +69 -4
- package/dist/EndpointBuilder-DeswNQdG.cjs.map +1 -0
- package/dist/{EndpointBuilder-W5fdXxYQ.mjs → EndpointBuilder-FyyoFTJ5.mjs} +69 -4
- package/dist/EndpointBuilder-FyyoFTJ5.mjs.map +1 -0
- package/dist/{EndpointBuilder-TApJQhtG.d.cts → EndpointBuilder-vXk6eIJk.d.cts} +41 -3
- package/dist/{EndpointFactory-CNlfBDuD.d.mts → EndpointFactory-3g-7Rznt.d.cts} +68 -21
- package/dist/{EndpointFactory-B5fOINuc.d.cts → EndpointFactory-DaFR9LQG.d.mts} +68 -21
- package/dist/{EndpointFactory-D5lFZXqY.cjs → EndpointFactory-DcT_g9M_.cjs} +117 -14
- package/dist/EndpointFactory-DcT_g9M_.cjs.map +1 -0
- package/dist/{EndpointFactory-B27nfeiE.mjs → EndpointFactory-KJAjBWmO.mjs} +117 -14
- package/dist/EndpointFactory-KJAjBWmO.mjs.map +1 -0
- package/dist/{Function-CD3rXWfa.d.mts → Function-Vh1t-Qjj.d.mts} +2 -2
- package/dist/{FunctionBuilder-j2VkwuGf.d.mts → FunctionBuilder-3jsoFffg.d.mts} +4 -4
- package/dist/{FunctionExecutionWrapper-B0WP-Vec.d.mts → FunctionExecutionWrapper-CI3CaoCo.d.mts} +2 -2
- package/dist/{HonoEndpointAdaptor-CLOpobdq.d.cts → HonoEndpointAdaptor-BJh4J-J9.d.cts} +4 -4
- package/dist/{HonoEndpointAdaptor-Bg_vTyA5.mjs → HonoEndpointAdaptor-CcvXzoYV.mjs} +43 -30
- package/dist/HonoEndpointAdaptor-CcvXzoYV.mjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-B_gJPWGD.cjs → HonoEndpointAdaptor-DodwLM0-.cjs} +43 -30
- package/dist/HonoEndpointAdaptor-DodwLM0-.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-C9gYYBWu.d.mts → HonoEndpointAdaptor-kb1ByjUL.d.mts} +5 -5
- package/dist/{Subscriber-D-FPWts6.cjs → Subscriber-DOt3svUC.cjs} +1 -1
- package/dist/{Subscriber-D-FPWts6.cjs.map → Subscriber-DOt3svUC.cjs.map} +1 -1
- package/dist/{Subscriber-itwm7ugy.d.mts → Subscriber-aNr1qkxR.d.mts} +2 -2
- package/dist/{Subscriber-CGb8LjZa.mjs → Subscriber-kCHbH2fZ.mjs} +1 -1
- package/dist/{Subscriber-CGb8LjZa.mjs.map → Subscriber-kCHbH2fZ.mjs.map} +1 -1
- package/dist/{SubscriberBuilder-9j3JCu8-.d.mts → SubscriberBuilder-CWS4tdbp.d.mts} +2 -2
- package/dist/{SubscriberBuilder-BfE2cL1q.cjs → SubscriberBuilder-Cj2u9k5Q.cjs} +2 -2
- package/dist/{SubscriberBuilder-BfE2cL1q.cjs.map → SubscriberBuilder-Cj2u9k5Q.cjs.map} +1 -1
- package/dist/{SubscriberBuilder-BcAspHv9.mjs → SubscriberBuilder-DmxMU89X.mjs} +2 -2
- package/dist/{SubscriberBuilder-BcAspHv9.mjs.map → SubscriberBuilder-DmxMU89X.mjs.map} +1 -1
- package/dist/{TestEndpointAdaptor-JONQJeXc.mjs → TestEndpointAdaptor-1pPixE6y.mjs} +4 -4
- package/dist/{TestEndpointAdaptor-JONQJeXc.mjs.map → TestEndpointAdaptor-1pPixE6y.mjs.map} +1 -1
- package/dist/{TestEndpointAdaptor-C-c8v7VI.d.mts → TestEndpointAdaptor-5-unBV8O.d.mts} +3 -3
- package/dist/{TestEndpointAdaptor-BYCwwiYk.d.cts → TestEndpointAdaptor-Bm0UjDtV.d.cts} +2 -2
- package/dist/{TestEndpointAdaptor-Bew9lWsx.cjs → TestEndpointAdaptor-wA-fmq4v.cjs} +4 -4
- package/dist/{TestEndpointAdaptor-Bew9lWsx.cjs.map → TestEndpointAdaptor-wA-fmq4v.cjs.map} +1 -1
- package/dist/adaptors/aws.cjs +5 -5
- package/dist/adaptors/aws.d.cts +5 -5
- package/dist/adaptors/aws.d.mts +15 -15
- package/dist/adaptors/aws.mjs +5 -5
- package/dist/adaptors/hono.cjs +4 -4
- package/dist/adaptors/hono.d.cts +3 -3
- package/dist/adaptors/hono.d.mts +9 -9
- package/dist/adaptors/hono.mjs +4 -4
- package/dist/adaptors/testing.cjs +3 -3
- package/dist/adaptors/testing.d.cts +3 -3
- package/dist/adaptors/testing.d.mts +9 -9
- package/dist/adaptors/testing.mjs +3 -3
- package/dist/crons/Cron.d.mts +6 -6
- package/dist/crons/CronBuilder.d.mts +7 -7
- package/dist/crons/index.d.cts +4 -4
- package/dist/crons/index.d.mts +7 -7
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +3 -3
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +3 -3
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +10 -10
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +10 -10
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +4 -4
- package/dist/endpoints/Authorizer.cjs +5 -14
- package/dist/endpoints/Authorizer.d.cts +2 -2
- package/dist/endpoints/Authorizer.d.mts +2 -2
- package/dist/endpoints/Authorizer.mjs +2 -13
- package/dist/endpoints/Endpoint.cjs +1 -1
- package/dist/endpoints/Endpoint.d.cts +2 -2
- package/dist/endpoints/Endpoint.d.mts +8 -8
- package/dist/endpoints/Endpoint.mjs +1 -1
- package/dist/endpoints/EndpointBuilder.cjs +4 -2
- package/dist/endpoints/EndpointBuilder.d.cts +3 -3
- package/dist/endpoints/EndpointBuilder.d.mts +9 -9
- package/dist/endpoints/EndpointBuilder.mjs +4 -2
- package/dist/endpoints/EndpointFactory.cjs +5 -3
- package/dist/endpoints/EndpointFactory.d.cts +4 -4
- package/dist/endpoints/EndpointFactory.d.mts +10 -10
- package/dist/endpoints/EndpointFactory.mjs +5 -3
- package/dist/endpoints/HonoEndpointAdaptor.cjs +4 -4
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/HonoEndpointAdaptor.mjs +4 -4
- package/dist/endpoints/TestEndpointAdaptor.cjs +3 -3
- package/dist/endpoints/TestEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/TestEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/TestEndpointAdaptor.mjs +3 -3
- package/dist/endpoints/audit.d.cts +2 -2
- package/dist/endpoints/audit.d.mts +8 -8
- package/dist/endpoints/helpers.cjs +2 -2
- package/dist/endpoints/helpers.d.cts +2 -2
- package/dist/endpoints/helpers.d.mts +8 -8
- package/dist/endpoints/helpers.mjs +2 -2
- package/dist/endpoints/index.cjs +6 -3
- package/dist/endpoints/index.cjs.map +1 -1
- package/dist/endpoints/index.d.cts +7 -7
- package/dist/endpoints/index.d.mts +13 -13
- package/dist/endpoints/index.mjs +6 -4
- package/dist/endpoints/index.mjs.map +1 -1
- package/dist/endpoints/processAudits.cjs +1 -1
- package/dist/endpoints/processAudits.d.cts +24 -5
- package/dist/endpoints/processAudits.d.mts +30 -11
- package/dist/endpoints/processAudits.mjs +1 -1
- package/dist/endpoints/rls.cjs +3 -0
- package/dist/endpoints/rls.d.cts +9 -0
- package/dist/endpoints/rls.d.mts +9 -0
- package/dist/endpoints/rls.mjs +3 -0
- package/dist/functions/AWSLambdaFunction.d.mts +4 -4
- package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
- package/dist/functions/Function.d.mts +2 -2
- package/dist/functions/FunctionBuilder.d.mts +4 -4
- package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
- package/dist/functions/TestFunctionAdaptor.d.mts +2 -2
- package/dist/functions/index.d.mts +5 -5
- package/dist/{helpers-CrrdyA04.mjs → helpers-C3B2lVrM.mjs} +2 -2
- package/dist/{helpers-CrrdyA04.mjs.map → helpers-C3B2lVrM.mjs.map} +1 -1
- package/dist/{helpers-DiPZVJQC.cjs → helpers-DxxSpLfw.cjs} +2 -2
- package/dist/{helpers-DiPZVJQC.cjs.map → helpers-DxxSpLfw.cjs.map} +1 -1
- package/dist/index-CFyaRrck.d.mts +10 -0
- package/dist/index.d.mts +2 -2
- package/dist/{processAudits-BFokHhCO.cjs → processAudits-CzHkPokQ.cjs} +13 -7
- package/dist/processAudits-CzHkPokQ.cjs.map +1 -0
- package/dist/{processAudits-DfcB-X-4.mjs → processAudits-Dj8UGqcW.mjs} +13 -7
- package/dist/processAudits-Dj8UGqcW.mjs.map +1 -0
- package/dist/publisher.d.mts +1 -1
- package/dist/rls-Bf3FRwto.mjs +9 -0
- package/dist/rls-Bf3FRwto.mjs.map +1 -0
- package/dist/rls-CmJ7bRsz.cjs +15 -0
- package/dist/rls-CmJ7bRsz.cjs.map +1 -0
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +3 -3
- package/dist/subscribers/Subscriber.cjs +1 -1
- package/dist/subscribers/Subscriber.d.mts +2 -2
- package/dist/subscribers/Subscriber.mjs +1 -1
- package/dist/subscribers/SubscriberBuilder.cjs +2 -2
- package/dist/subscribers/SubscriberBuilder.d.mts +3 -3
- package/dist/subscribers/SubscriberBuilder.mjs +2 -2
- package/dist/subscribers/index.cjs +2 -2
- package/dist/subscribers/index.d.cts +2 -2
- package/dist/subscribers/index.d.mts +5 -5
- package/dist/subscribers/index.mjs +2 -2
- package/dist/{types-DKf0juBf.d.mts → types-CScirkHt.d.mts} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +4 -3
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +59 -26
- package/src/endpoints/Authorizer.ts +119 -1
- package/src/endpoints/Endpoint.ts +19 -0
- package/src/endpoints/EndpointBuilder.ts +80 -6
- package/src/endpoints/EndpointFactory.ts +263 -27
- package/src/endpoints/HonoEndpointAdaptor.ts +68 -37
- package/src/endpoints/TestEndpointAdaptor.ts +2 -0
- package/src/endpoints/index.ts +7 -0
- package/src/endpoints/processAudits.ts +39 -16
- package/src/endpoints/rls.ts +67 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-CacGag6F.mjs.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-DXssXsJi.cjs.map +0 -1
- package/dist/Authorizer-BTmly8ps.d.cts +0 -29
- package/dist/Authorizer-pmPvIVgv.d.mts +0 -29
- package/dist/Endpoint-CA-byrDr.cjs.map +0 -1
- package/dist/Endpoint-DbPsw13b.mjs.map +0 -1
- package/dist/EndpointBuilder-CYkeYpsL.cjs.map +0 -1
- package/dist/EndpointBuilder-W5fdXxYQ.mjs.map +0 -1
- package/dist/EndpointFactory-B27nfeiE.mjs.map +0 -1
- package/dist/EndpointFactory-D5lFZXqY.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-B_gJPWGD.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-Bg_vTyA5.mjs.map +0 -1
- package/dist/endpoints/Authorizer.cjs.map +0 -1
- package/dist/endpoints/Authorizer.mjs.map +0 -1
- package/dist/index-licEVXjh.d.mts +0 -10
- package/dist/processAudits-BFokHhCO.cjs.map +0 -1
- package/dist/processAudits-DfcB-X-4.mjs.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
2
|
const require_Construct = require('./Construct-BYSPikVm.cjs');
|
|
3
3
|
const require_BaseFunctionBuilder = require('./BaseFunctionBuilder-C5Se7pdL.cjs');
|
|
4
|
-
const require_Endpoint = require('./Endpoint-
|
|
4
|
+
const require_Endpoint = require('./Endpoint-BJo9Hhwm.cjs');
|
|
5
|
+
const require_Authorizer = require('./Authorizer-C0ge_tc8.cjs');
|
|
6
|
+
const require_rls = require('./rls-CmJ7bRsz.cjs');
|
|
5
7
|
const lodash_uniqby = require_chunk.__toESM(require("lodash.uniqby"));
|
|
6
8
|
|
|
7
9
|
//#region src/endpoints/EndpointBuilder.ts
|
|
@@ -18,6 +20,9 @@ var EndpointBuilder = class extends require_BaseFunctionBuilder.BaseFunctionBuil
|
|
|
18
20
|
_authorizerName;
|
|
19
21
|
_actorExtractor;
|
|
20
22
|
_audits = [];
|
|
23
|
+
_customSecuritySchemes = {};
|
|
24
|
+
_rlsConfig;
|
|
25
|
+
_rlsBypass;
|
|
21
26
|
constructor(route, method) {
|
|
22
27
|
super(require_Construct.ConstructType.Endpoint);
|
|
23
28
|
this.route = route;
|
|
@@ -157,11 +162,69 @@ var EndpointBuilder = class extends require_BaseFunctionBuilder.BaseFunctionBuil
|
|
|
157
162
|
this._databaseService = service;
|
|
158
163
|
return this;
|
|
159
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Configure RLS (Row-Level Security) context for this endpoint.
|
|
167
|
+
* Pass `false` or `RLS_BYPASS` to explicitly bypass RLS for this endpoint.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* // Custom RLS config for this endpoint
|
|
172
|
+
* .rls({
|
|
173
|
+
* extractor: ({ session }) => ({
|
|
174
|
+
* user_id: session.userId,
|
|
175
|
+
* tenant_id: session.tenantId,
|
|
176
|
+
* }),
|
|
177
|
+
* prefix: 'app',
|
|
178
|
+
* })
|
|
179
|
+
*
|
|
180
|
+
* // Bypass RLS (for admin endpoints)
|
|
181
|
+
* .rls(false)
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
rls(config) {
|
|
185
|
+
if (config === false || config === require_rls.RLS_BYPASS) {
|
|
186
|
+
this._rlsBypass = true;
|
|
187
|
+
this._rlsConfig = void 0;
|
|
188
|
+
} else {
|
|
189
|
+
this._rlsConfig = config;
|
|
190
|
+
this._rlsBypass = false;
|
|
191
|
+
}
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Explicitly bypass RLS for this endpoint.
|
|
196
|
+
* Useful for admin operations that need unrestricted database access.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* .rlsBypass()
|
|
201
|
+
* .handle(async ({ db }) => {
|
|
202
|
+
* // Full access, no RLS filtering
|
|
203
|
+
* return db.selectFrom('orders').selectAll().execute();
|
|
204
|
+
* })
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
rlsBypass() {
|
|
208
|
+
this._rlsBypass = true;
|
|
209
|
+
this._rlsConfig = void 0;
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
160
212
|
input(_schema) {
|
|
161
213
|
throw new Error("EndpointBuilder does not support generic input. Use body(), query(), or params() instead.");
|
|
162
214
|
}
|
|
163
215
|
handle(fn) {
|
|
164
|
-
|
|
216
|
+
let authorizer;
|
|
217
|
+
if (this._authorizerName) {
|
|
218
|
+
const existingAuthorizer = this._availableAuthorizers.find((a) => a.name === this._authorizerName);
|
|
219
|
+
if (existingAuthorizer) authorizer = existingAuthorizer;
|
|
220
|
+
else {
|
|
221
|
+
const securityScheme = require_Authorizer.getSecurityScheme(this._authorizerName, this._customSecuritySchemes);
|
|
222
|
+
authorizer = {
|
|
223
|
+
name: this._authorizerName,
|
|
224
|
+
securityScheme
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
165
228
|
return new require_Endpoint.Endpoint({
|
|
166
229
|
fn,
|
|
167
230
|
method: this.method,
|
|
@@ -184,7 +247,9 @@ var EndpointBuilder = class extends require_BaseFunctionBuilder.BaseFunctionBuil
|
|
|
184
247
|
auditorStorageService: this._auditorStorage,
|
|
185
248
|
actorExtractor: this._actorExtractor,
|
|
186
249
|
audits: this._audits,
|
|
187
|
-
databaseService: this._databaseService
|
|
250
|
+
databaseService: this._databaseService,
|
|
251
|
+
rlsConfig: this._rlsConfig,
|
|
252
|
+
rlsBypass: this._rlsBypass
|
|
188
253
|
});
|
|
189
254
|
}
|
|
190
255
|
};
|
|
@@ -196,4 +261,4 @@ Object.defineProperty(exports, 'EndpointBuilder', {
|
|
|
196
261
|
return EndpointBuilder;
|
|
197
262
|
}
|
|
198
263
|
});
|
|
199
|
-
//# sourceMappingURL=EndpointBuilder-
|
|
264
|
+
//# sourceMappingURL=EndpointBuilder-DeswNQdG.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EndpointBuilder-DeswNQdG.cjs","names":["BaseFunctionBuilder","route: TRoute","method: TMethod","ConstructType","publisher: Service<TEventPublisherServiceName, TEventPublisher>","storage: Service<TAuditStorageServiceName, TAuditStorage>","service: Service<TDatabaseServiceName, TDatabase>","description: string","status: SuccessStatus","event: TEvent","tags: string[]","memorySize: number","publisher: Service<TName, T>","schema: T","config: RateLimitConfig","name: TAuthorizers[number] | 'none'","services: T","logger: T","storage: Service<TName, T>","extractor: ActorExtractor<TServices, TSession, TLogger>","audits: MappedAudit<TAuditAction, OutSchema>[]","service: Service<TName, T>","config: RlsConfig<TServices, TSession, TLogger> | false | RlsBypass","RLS_BYPASS","_schema: any","fn: EndpointHandler<\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TDatabase,\n TAuditStorage,\n TAuditAction\n >","authorizer: Authorizer | undefined","Endpoint"],"sources":["../src/endpoints/EndpointBuilder.ts"],"sourcesContent":["import type {\n AuditStorage,\n AuditableAction,\n ExtractStorageAuditAction,\n} from '@geekmidas/audit';\nimport type { EventPublisher, MappedEvent } from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport type { RateLimitConfig } from '@geekmidas/rate-limit';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport uniqBy from 'lodash.uniqby';\nimport { ConstructType } from '../Construct';\nimport { BaseFunctionBuilder } from '../functions';\nimport type { HttpMethod } from '../types';\nimport type { Authorizer, SecurityScheme } from './Authorizer';\nimport { getSecurityScheme } from './Authorizer';\nimport { Endpoint, type EndpointSchemas } from './Endpoint';\nimport type {\n AuthorizeFn,\n EndpointHandler,\n SessionFn,\n SuccessStatus,\n} from './Endpoint';\nimport type { ActorExtractor, MappedAudit } from './audit';\nimport type { RlsBypass, RlsConfig } from './rls';\nimport { RLS_BYPASS } from './rls';\n\nexport class EndpointBuilder<\n TRoute extends string,\n TMethod extends HttpMethod,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n OutSchema extends StandardSchemaV1 | undefined = undefined,\n TSession = unknown,\n TEventPublisher extends EventPublisher<any> | undefined = undefined,\n TEventPublisherServiceName extends string = string,\n TAuthorizers extends readonly string[] = readonly 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 TDatabase = undefined,\n TDatabaseServiceName extends string = string,\n> extends BaseFunctionBuilder<\n TInput,\n OutSchema,\n TServices,\n TLogger,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TDatabase,\n TDatabaseServiceName\n> {\n protected schemas: TInput = {} as TInput;\n protected _description?: string;\n protected _status?: SuccessStatus;\n protected _tags?: string[];\n protected _memorySize?: number;\n _getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>\n ({}) as TSession;\n _authorize: AuthorizeFn<TServices, TLogger, TSession> = () => true;\n _rateLimit?: RateLimitConfig;\n _availableAuthorizers: Authorizer[] = [];\n _authorizerName?: TAuthorizers[number];\n _actorExtractor?: ActorExtractor<TServices, TSession, TLogger>;\n _audits: MappedAudit<TAuditAction, OutSchema>[] = [];\n _customSecuritySchemes: Record<string, SecurityScheme> = {};\n _rlsConfig?: RlsConfig<TServices, TSession, TLogger>;\n _rlsBypass?: boolean;\n\n constructor(\n readonly route: TRoute,\n readonly method: TMethod,\n ) {\n super(ConstructType.Endpoint);\n }\n\n // Internal setter for EndpointFactory to set default publisher\n _setPublisher(\n publisher: Service<TEventPublisherServiceName, TEventPublisher>,\n ) {\n this._publisher = publisher;\n }\n\n // Internal setter for EndpointFactory to set default auditor storage\n _setAuditorStorage(\n storage: Service<TAuditStorageServiceName, TAuditStorage>,\n ) {\n this._auditorStorage = storage;\n }\n\n // Internal setter for EndpointFactory to set default database service\n _setDatabaseService(service: Service<TDatabaseServiceName, TDatabase>) {\n this._databaseService = service;\n }\n\n description(description: string): this {\n this._description = description;\n return this;\n }\n\n status(status: SuccessStatus): this {\n this._status = status;\n return this;\n }\n\n event<TEvent extends MappedEvent<TEventPublisher, OutSchema>>(\n event: TEvent,\n ): this {\n this._events.push(event);\n return this;\n }\n\n tags(tags: string[]): this {\n this._tags = tags;\n return this;\n }\n\n memorySize(memorySize: number): this {\n this._memorySize = memorySize;\n return this;\n }\n\n publisher<T extends EventPublisher<any>, TName extends string>(\n publisher: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n T,\n TName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._publisher = publisher as unknown as Service<\n TEventPublisherServiceName,\n TEventPublisher\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n T,\n TName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n body<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'body'> & { body: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.body = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n search<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'query'> & { query: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.query = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n query<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'query'> & { query: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n return this.search(schema);\n }\n\n params<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'params'> & { params: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.params = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n rateLimit(config: RateLimitConfig): this {\n this._rateLimit = config;\n return this;\n }\n\n authorizer(\n name: TAuthorizers[number] | 'none',\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n // Special case: 'none' explicitly marks endpoint as having no authorizer\n if (name === 'none') {\n this._authorizerName = undefined;\n return this;\n }\n\n // Validate that the authorizer exists in available authorizers\n const authorizerExists = this._availableAuthorizers.some(\n (a) => a.name === name,\n );\n if (!authorizerExists && this._availableAuthorizers.length > 0) {\n const available = this._availableAuthorizers\n .map((a) => a.name)\n .join(', ');\n throw new Error(\n `Authorizer \"${name as string}\" not found in available authorizers: ${available}`,\n );\n }\n this._authorizerName = name;\n return this;\n }\n\n services<T extends Service[]>(\n services: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n [...TServices, ...T],\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._services = uniqBy(\n [...this._services, ...services],\n (s) => s.serviceName,\n ) as TServices;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n [...TServices, ...T],\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n logger<T extends Logger>(\n logger: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n T,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._logger = logger as unknown as TLogger;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n T,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n output<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n T,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.outputSchema = schema as unknown as OutSchema;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n T,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n /**\n * Set the auditor storage service for this endpoint.\n * This enables audit functionality and makes `auditor` available in the handler context.\n * The audit action type is automatically inferred from the storage's generic parameter.\n */\n auditor<T extends AuditStorage<any>, TName extends string>(\n storage: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n T,\n TName,\n ExtractStorageAuditAction<T>,\n TDatabase,\n TDatabaseServiceName\n > {\n this._auditorStorage = storage as unknown as Service<\n TAuditStorageServiceName,\n TAuditStorage\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n T,\n TName,\n ExtractStorageAuditAction<T>,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n /**\n * Set the actor extractor function for audit records.\n * The actor is extracted from the request context and attached to all audits.\n */\n actor(\n extractor: ActorExtractor<TServices, TSession, TLogger>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._actorExtractor = extractor;\n return this;\n }\n\n /**\n * Add declarative audit definitions that are processed after the handler executes.\n * Similar to `.event()` for events, but for audits.\n *\n * @example\n * ```typescript\n * .audit<AppAuditAction>([\n * {\n * type: 'user.created',\n * payload: (response) => ({ userId: response.id, email: response.email }),\n * when: (response) => response.active,\n * entityId: (response) => response.id,\n * table: 'users',\n * },\n * ])\n * ```\n */\n audit(audits: MappedAudit<TAuditAction, OutSchema>[]): this {\n this._audits = audits;\n return this;\n }\n\n /**\n * Set the database service for this endpoint.\n * The database will be available in the handler context as `db`.\n * When audit storage is configured and uses the same database,\n * `db` will automatically be the transaction for ACID compliance.\n *\n * @example\n * ```typescript\n * .database(databaseService)\n * .handle(async ({ db }) => {\n * // db is the raw database or transaction (when auditor uses same db)\n * return await db.selectFrom('users').selectAll().execute();\n * })\n * ```\n */\n database<T, TName extends string>(\n service: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n T,\n TName\n > {\n this._databaseService = service as unknown as Service<\n TDatabaseServiceName,\n TDatabase\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n T,\n TName\n >;\n }\n\n /**\n * Configure RLS (Row-Level Security) context for this endpoint.\n * Pass `false` or `RLS_BYPASS` to explicitly bypass RLS for this endpoint.\n *\n * @example\n * ```typescript\n * // Custom RLS config for this endpoint\n * .rls({\n * extractor: ({ session }) => ({\n * user_id: session.userId,\n * tenant_id: session.tenantId,\n * }),\n * prefix: 'app',\n * })\n *\n * // Bypass RLS (for admin endpoints)\n * .rls(false)\n * ```\n */\n rls(\n config: RlsConfig<TServices, TSession, TLogger> | false | RlsBypass,\n ): this {\n if (config === false || config === RLS_BYPASS) {\n this._rlsBypass = true;\n this._rlsConfig = undefined;\n } else {\n this._rlsConfig = config;\n this._rlsBypass = false;\n }\n return this;\n }\n\n /**\n * Explicitly bypass RLS for this endpoint.\n * Useful for admin operations that need unrestricted database access.\n *\n * @example\n * ```typescript\n * .rlsBypass()\n * .handle(async ({ db }) => {\n * // Full access, no RLS filtering\n * return db.selectFrom('orders').selectAll().execute();\n * })\n * ```\n */\n rlsBypass(): this {\n this._rlsBypass = true;\n this._rlsConfig = undefined;\n return this;\n }\n\n // EndpointBuilder doesn't have a generic input method - it uses body, query, params instead\n input(_schema: any): any {\n throw new Error(\n 'EndpointBuilder does not support generic input. Use body(), query(), or params() instead.',\n );\n }\n\n handle(\n fn: EndpointHandler<\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TDatabase,\n TAuditStorage,\n TAuditAction\n >,\n ): Endpoint<\n TRoute,\n TMethod,\n TInput,\n OutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n // Find authorizer metadata if name is set\n // If the authorizer name is set but not in availableAuthorizers, create a simple authorizer object\n let authorizer: Authorizer | undefined;\n if (this._authorizerName) {\n const existingAuthorizer = this._availableAuthorizers.find(\n (a) => a.name === this._authorizerName,\n );\n\n if (existingAuthorizer) {\n authorizer = existingAuthorizer;\n } else {\n // Create authorizer with security scheme if available (built-in or custom)\n const securityScheme = getSecurityScheme(\n this._authorizerName as string,\n this._customSecuritySchemes,\n );\n authorizer = {\n name: this._authorizerName as string,\n securityScheme,\n };\n }\n }\n\n return new Endpoint({\n fn,\n method: this.method,\n route: this.route,\n description: this._description,\n tags: this._tags,\n input: this.schemas,\n output: this.outputSchema,\n services: this._services,\n logger: this._logger,\n timeout: this._timeout,\n memorySize: this._memorySize,\n authorize: this._authorize,\n status: this._status,\n getSession: this._getSession,\n rateLimit: this._rateLimit,\n publisherService: this._publisher,\n events: this._events,\n authorizer,\n auditorStorageService: this._auditorStorage,\n actorExtractor: this._actorExtractor,\n audits: this._audits,\n databaseService: this._databaseService,\n rlsConfig: this._rlsConfig,\n rlsBypass: this._rlsBypass,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ConstructType } from "./Construct-LWeB1rSQ.mjs";
|
|
2
2
|
import { BaseFunctionBuilder } from "./BaseFunctionBuilder-B5gkW0Kt.mjs";
|
|
3
|
-
import { Endpoint } from "./Endpoint-
|
|
3
|
+
import { Endpoint } from "./Endpoint-B70_KKhu.mjs";
|
|
4
|
+
import { getSecurityScheme } from "./Authorizer-r9U3y_ms.mjs";
|
|
5
|
+
import { RLS_BYPASS } from "./rls-Bf3FRwto.mjs";
|
|
4
6
|
import uniqBy from "lodash.uniqby";
|
|
5
7
|
|
|
6
8
|
//#region src/endpoints/EndpointBuilder.ts
|
|
@@ -17,6 +19,9 @@ var EndpointBuilder = class extends BaseFunctionBuilder {
|
|
|
17
19
|
_authorizerName;
|
|
18
20
|
_actorExtractor;
|
|
19
21
|
_audits = [];
|
|
22
|
+
_customSecuritySchemes = {};
|
|
23
|
+
_rlsConfig;
|
|
24
|
+
_rlsBypass;
|
|
20
25
|
constructor(route, method) {
|
|
21
26
|
super(ConstructType.Endpoint);
|
|
22
27
|
this.route = route;
|
|
@@ -156,11 +161,69 @@ var EndpointBuilder = class extends BaseFunctionBuilder {
|
|
|
156
161
|
this._databaseService = service;
|
|
157
162
|
return this;
|
|
158
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Configure RLS (Row-Level Security) context for this endpoint.
|
|
166
|
+
* Pass `false` or `RLS_BYPASS` to explicitly bypass RLS for this endpoint.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* // Custom RLS config for this endpoint
|
|
171
|
+
* .rls({
|
|
172
|
+
* extractor: ({ session }) => ({
|
|
173
|
+
* user_id: session.userId,
|
|
174
|
+
* tenant_id: session.tenantId,
|
|
175
|
+
* }),
|
|
176
|
+
* prefix: 'app',
|
|
177
|
+
* })
|
|
178
|
+
*
|
|
179
|
+
* // Bypass RLS (for admin endpoints)
|
|
180
|
+
* .rls(false)
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
rls(config) {
|
|
184
|
+
if (config === false || config === RLS_BYPASS) {
|
|
185
|
+
this._rlsBypass = true;
|
|
186
|
+
this._rlsConfig = void 0;
|
|
187
|
+
} else {
|
|
188
|
+
this._rlsConfig = config;
|
|
189
|
+
this._rlsBypass = false;
|
|
190
|
+
}
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Explicitly bypass RLS for this endpoint.
|
|
195
|
+
* Useful for admin operations that need unrestricted database access.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* .rlsBypass()
|
|
200
|
+
* .handle(async ({ db }) => {
|
|
201
|
+
* // Full access, no RLS filtering
|
|
202
|
+
* return db.selectFrom('orders').selectAll().execute();
|
|
203
|
+
* })
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
rlsBypass() {
|
|
207
|
+
this._rlsBypass = true;
|
|
208
|
+
this._rlsConfig = void 0;
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
159
211
|
input(_schema) {
|
|
160
212
|
throw new Error("EndpointBuilder does not support generic input. Use body(), query(), or params() instead.");
|
|
161
213
|
}
|
|
162
214
|
handle(fn) {
|
|
163
|
-
|
|
215
|
+
let authorizer;
|
|
216
|
+
if (this._authorizerName) {
|
|
217
|
+
const existingAuthorizer = this._availableAuthorizers.find((a) => a.name === this._authorizerName);
|
|
218
|
+
if (existingAuthorizer) authorizer = existingAuthorizer;
|
|
219
|
+
else {
|
|
220
|
+
const securityScheme = getSecurityScheme(this._authorizerName, this._customSecuritySchemes);
|
|
221
|
+
authorizer = {
|
|
222
|
+
name: this._authorizerName,
|
|
223
|
+
securityScheme
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
164
227
|
return new Endpoint({
|
|
165
228
|
fn,
|
|
166
229
|
method: this.method,
|
|
@@ -183,11 +246,13 @@ var EndpointBuilder = class extends BaseFunctionBuilder {
|
|
|
183
246
|
auditorStorageService: this._auditorStorage,
|
|
184
247
|
actorExtractor: this._actorExtractor,
|
|
185
248
|
audits: this._audits,
|
|
186
|
-
databaseService: this._databaseService
|
|
249
|
+
databaseService: this._databaseService,
|
|
250
|
+
rlsConfig: this._rlsConfig,
|
|
251
|
+
rlsBypass: this._rlsBypass
|
|
187
252
|
});
|
|
188
253
|
}
|
|
189
254
|
};
|
|
190
255
|
|
|
191
256
|
//#endregion
|
|
192
257
|
export { EndpointBuilder };
|
|
193
|
-
//# sourceMappingURL=EndpointBuilder-
|
|
258
|
+
//# sourceMappingURL=EndpointBuilder-FyyoFTJ5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EndpointBuilder-FyyoFTJ5.mjs","names":["route: TRoute","method: TMethod","publisher: Service<TEventPublisherServiceName, TEventPublisher>","storage: Service<TAuditStorageServiceName, TAuditStorage>","service: Service<TDatabaseServiceName, TDatabase>","description: string","status: SuccessStatus","event: TEvent","tags: string[]","memorySize: number","publisher: Service<TName, T>","schema: T","config: RateLimitConfig","name: TAuthorizers[number] | 'none'","services: T","logger: T","storage: Service<TName, T>","extractor: ActorExtractor<TServices, TSession, TLogger>","audits: MappedAudit<TAuditAction, OutSchema>[]","service: Service<TName, T>","config: RlsConfig<TServices, TSession, TLogger> | false | RlsBypass","_schema: any","fn: EndpointHandler<\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TDatabase,\n TAuditStorage,\n TAuditAction\n >","authorizer: Authorizer | undefined"],"sources":["../src/endpoints/EndpointBuilder.ts"],"sourcesContent":["import type {\n AuditStorage,\n AuditableAction,\n ExtractStorageAuditAction,\n} from '@geekmidas/audit';\nimport type { EventPublisher, MappedEvent } from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport type { RateLimitConfig } from '@geekmidas/rate-limit';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport uniqBy from 'lodash.uniqby';\nimport { ConstructType } from '../Construct';\nimport { BaseFunctionBuilder } from '../functions';\nimport type { HttpMethod } from '../types';\nimport type { Authorizer, SecurityScheme } from './Authorizer';\nimport { getSecurityScheme } from './Authorizer';\nimport { Endpoint, type EndpointSchemas } from './Endpoint';\nimport type {\n AuthorizeFn,\n EndpointHandler,\n SessionFn,\n SuccessStatus,\n} from './Endpoint';\nimport type { ActorExtractor, MappedAudit } from './audit';\nimport type { RlsBypass, RlsConfig } from './rls';\nimport { RLS_BYPASS } from './rls';\n\nexport class EndpointBuilder<\n TRoute extends string,\n TMethod extends HttpMethod,\n TInput extends EndpointSchemas = {},\n TServices extends Service[] = [],\n TLogger extends Logger = Logger,\n OutSchema extends StandardSchemaV1 | undefined = undefined,\n TSession = unknown,\n TEventPublisher extends EventPublisher<any> | undefined = undefined,\n TEventPublisherServiceName extends string = string,\n TAuthorizers extends readonly string[] = readonly 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 TDatabase = undefined,\n TDatabaseServiceName extends string = string,\n> extends BaseFunctionBuilder<\n TInput,\n OutSchema,\n TServices,\n TLogger,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TDatabase,\n TDatabaseServiceName\n> {\n protected schemas: TInput = {} as TInput;\n protected _description?: string;\n protected _status?: SuccessStatus;\n protected _tags?: string[];\n protected _memorySize?: number;\n _getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>\n ({}) as TSession;\n _authorize: AuthorizeFn<TServices, TLogger, TSession> = () => true;\n _rateLimit?: RateLimitConfig;\n _availableAuthorizers: Authorizer[] = [];\n _authorizerName?: TAuthorizers[number];\n _actorExtractor?: ActorExtractor<TServices, TSession, TLogger>;\n _audits: MappedAudit<TAuditAction, OutSchema>[] = [];\n _customSecuritySchemes: Record<string, SecurityScheme> = {};\n _rlsConfig?: RlsConfig<TServices, TSession, TLogger>;\n _rlsBypass?: boolean;\n\n constructor(\n readonly route: TRoute,\n readonly method: TMethod,\n ) {\n super(ConstructType.Endpoint);\n }\n\n // Internal setter for EndpointFactory to set default publisher\n _setPublisher(\n publisher: Service<TEventPublisherServiceName, TEventPublisher>,\n ) {\n this._publisher = publisher;\n }\n\n // Internal setter for EndpointFactory to set default auditor storage\n _setAuditorStorage(\n storage: Service<TAuditStorageServiceName, TAuditStorage>,\n ) {\n this._auditorStorage = storage;\n }\n\n // Internal setter for EndpointFactory to set default database service\n _setDatabaseService(service: Service<TDatabaseServiceName, TDatabase>) {\n this._databaseService = service;\n }\n\n description(description: string): this {\n this._description = description;\n return this;\n }\n\n status(status: SuccessStatus): this {\n this._status = status;\n return this;\n }\n\n event<TEvent extends MappedEvent<TEventPublisher, OutSchema>>(\n event: TEvent,\n ): this {\n this._events.push(event);\n return this;\n }\n\n tags(tags: string[]): this {\n this._tags = tags;\n return this;\n }\n\n memorySize(memorySize: number): this {\n this._memorySize = memorySize;\n return this;\n }\n\n publisher<T extends EventPublisher<any>, TName extends string>(\n publisher: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n T,\n TName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._publisher = publisher as unknown as Service<\n TEventPublisherServiceName,\n TEventPublisher\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n T,\n TName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n body<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'body'> & { body: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.body = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n search<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'query'> & { query: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.query = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n query<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'query'> & { query: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n return this.search(schema);\n }\n\n params<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n Omit<TInput, 'params'> & { params: T },\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.schemas.params = schema as unknown as T;\n // @ts-ignore\n return this;\n }\n\n rateLimit(config: RateLimitConfig): this {\n this._rateLimit = config;\n return this;\n }\n\n authorizer(\n name: TAuthorizers[number] | 'none',\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n // Special case: 'none' explicitly marks endpoint as having no authorizer\n if (name === 'none') {\n this._authorizerName = undefined;\n return this;\n }\n\n // Validate that the authorizer exists in available authorizers\n const authorizerExists = this._availableAuthorizers.some(\n (a) => a.name === name,\n );\n if (!authorizerExists && this._availableAuthorizers.length > 0) {\n const available = this._availableAuthorizers\n .map((a) => a.name)\n .join(', ');\n throw new Error(\n `Authorizer \"${name as string}\" not found in available authorizers: ${available}`,\n );\n }\n this._authorizerName = name;\n return this;\n }\n\n services<T extends Service[]>(\n services: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n [...TServices, ...T],\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._services = uniqBy(\n [...this._services, ...services],\n (s) => s.serviceName,\n ) as TServices;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n [...TServices, ...T],\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n logger<T extends Logger>(\n logger: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n T,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._logger = logger as unknown as TLogger;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n T,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n output<T extends StandardSchemaV1>(\n schema: T,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n T,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this.outputSchema = schema as unknown as OutSchema;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n T,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n /**\n * Set the auditor storage service for this endpoint.\n * This enables audit functionality and makes `auditor` available in the handler context.\n * The audit action type is automatically inferred from the storage's generic parameter.\n */\n auditor<T extends AuditStorage<any>, TName extends string>(\n storage: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n T,\n TName,\n ExtractStorageAuditAction<T>,\n TDatabase,\n TDatabaseServiceName\n > {\n this._auditorStorage = storage as unknown as Service<\n TAuditStorageServiceName,\n TAuditStorage\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n T,\n TName,\n ExtractStorageAuditAction<T>,\n TDatabase,\n TDatabaseServiceName\n >;\n }\n\n /**\n * Set the actor extractor function for audit records.\n * The actor is extracted from the request context and attached to all audits.\n */\n actor(\n extractor: ActorExtractor<TServices, TSession, TLogger>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n this._actorExtractor = extractor;\n return this;\n }\n\n /**\n * Add declarative audit definitions that are processed after the handler executes.\n * Similar to `.event()` for events, but for audits.\n *\n * @example\n * ```typescript\n * .audit<AppAuditAction>([\n * {\n * type: 'user.created',\n * payload: (response) => ({ userId: response.id, email: response.email }),\n * when: (response) => response.active,\n * entityId: (response) => response.id,\n * table: 'users',\n * },\n * ])\n * ```\n */\n audit(audits: MappedAudit<TAuditAction, OutSchema>[]): this {\n this._audits = audits;\n return this;\n }\n\n /**\n * Set the database service for this endpoint.\n * The database will be available in the handler context as `db`.\n * When audit storage is configured and uses the same database,\n * `db` will automatically be the transaction for ACID compliance.\n *\n * @example\n * ```typescript\n * .database(databaseService)\n * .handle(async ({ db }) => {\n * // db is the raw database or transaction (when auditor uses same db)\n * return await db.selectFrom('users').selectAll().execute();\n * })\n * ```\n */\n database<T, TName extends string>(\n service: Service<TName, T>,\n ): EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n T,\n TName\n > {\n this._databaseService = service as unknown as Service<\n TDatabaseServiceName,\n TDatabase\n >;\n\n return this as unknown as EndpointBuilder<\n TRoute,\n TMethod,\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuthorizers,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n T,\n TName\n >;\n }\n\n /**\n * Configure RLS (Row-Level Security) context for this endpoint.\n * Pass `false` or `RLS_BYPASS` to explicitly bypass RLS for this endpoint.\n *\n * @example\n * ```typescript\n * // Custom RLS config for this endpoint\n * .rls({\n * extractor: ({ session }) => ({\n * user_id: session.userId,\n * tenant_id: session.tenantId,\n * }),\n * prefix: 'app',\n * })\n *\n * // Bypass RLS (for admin endpoints)\n * .rls(false)\n * ```\n */\n rls(\n config: RlsConfig<TServices, TSession, TLogger> | false | RlsBypass,\n ): this {\n if (config === false || config === RLS_BYPASS) {\n this._rlsBypass = true;\n this._rlsConfig = undefined;\n } else {\n this._rlsConfig = config;\n this._rlsBypass = false;\n }\n return this;\n }\n\n /**\n * Explicitly bypass RLS for this endpoint.\n * Useful for admin operations that need unrestricted database access.\n *\n * @example\n * ```typescript\n * .rlsBypass()\n * .handle(async ({ db }) => {\n * // Full access, no RLS filtering\n * return db.selectFrom('orders').selectAll().execute();\n * })\n * ```\n */\n rlsBypass(): this {\n this._rlsBypass = true;\n this._rlsConfig = undefined;\n return this;\n }\n\n // EndpointBuilder doesn't have a generic input method - it uses body, query, params instead\n input(_schema: any): any {\n throw new Error(\n 'EndpointBuilder does not support generic input. Use body(), query(), or params() instead.',\n );\n }\n\n handle(\n fn: EndpointHandler<\n TInput,\n TServices,\n TLogger,\n OutSchema,\n TSession,\n TDatabase,\n TAuditStorage,\n TAuditAction\n >,\n ): Endpoint<\n TRoute,\n TMethod,\n TInput,\n OutSchema,\n TServices,\n TLogger,\n TSession,\n TEventPublisher,\n TEventPublisherServiceName,\n TAuditStorage,\n TAuditStorageServiceName,\n TAuditAction,\n TDatabase,\n TDatabaseServiceName\n > {\n // Find authorizer metadata if name is set\n // If the authorizer name is set but not in availableAuthorizers, create a simple authorizer object\n let authorizer: Authorizer | undefined;\n if (this._authorizerName) {\n const existingAuthorizer = this._availableAuthorizers.find(\n (a) => a.name === this._authorizerName,\n );\n\n if (existingAuthorizer) {\n authorizer = existingAuthorizer;\n } else {\n // Create authorizer with security scheme if available (built-in or custom)\n const securityScheme = getSecurityScheme(\n this._authorizerName as string,\n this._customSecuritySchemes,\n );\n authorizer = {\n name: this._authorizerName as string,\n securityScheme,\n };\n }\n }\n\n return new Endpoint({\n fn,\n method: this.method,\n route: this.route,\n description: this._description,\n tags: this._tags,\n input: this.schemas,\n output: this.outputSchema,\n services: this._services,\n logger: this._logger,\n timeout: this._timeout,\n memorySize: this._memorySize,\n authorize: this._authorize,\n status: this._status,\n getSession: this._getSession,\n rateLimit: this._rateLimit,\n publisherService: this._publisher,\n events: this._events,\n authorizer,\n auditorStorageService: this._auditorStorage,\n actorExtractor: this._actorExtractor,\n audits: this._audits,\n databaseService: this._databaseService,\n rlsConfig: this._rlsConfig,\n rlsBypass: this._rlsBypass,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HttpMethod } from "./types-Bp9ysFXd.cjs";
|
|
2
2
|
import { BaseFunctionBuilder } from "./BaseFunctionBuilder-DaQA0uKE.cjs";
|
|
3
|
-
import { Authorizer } from "./Authorizer-
|
|
4
|
-
import { ActorExtractor, AuthorizeFn, Endpoint, EndpointHandler, EndpointSchemas, MappedAudit, SessionFn, SuccessStatus } from "./Endpoint-
|
|
3
|
+
import { Authorizer, SecurityScheme } from "./Authorizer-CpSUMTIs.cjs";
|
|
4
|
+
import { ActorExtractor, AuthorizeFn, Endpoint, EndpointHandler, EndpointSchemas, MappedAudit, RlsBypass, RlsConfig, SessionFn, SuccessStatus } from "./Endpoint-CC2RGjkl.cjs";
|
|
5
5
|
import { AuditStorage, AuditableAction, ExtractStorageAuditAction } from "@geekmidas/audit";
|
|
6
6
|
import { EventPublisher, MappedEvent } from "@geekmidas/events";
|
|
7
7
|
import { Logger } from "@geekmidas/logger";
|
|
@@ -10,6 +10,7 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
|
10
10
|
import { RateLimitConfig } from "@geekmidas/rate-limit";
|
|
11
11
|
|
|
12
12
|
//#region src/endpoints/EndpointBuilder.d.ts
|
|
13
|
+
|
|
13
14
|
declare class EndpointBuilder<TRoute extends string, TMethod extends HttpMethod, TInput extends EndpointSchemas = {}, TServices extends Service[] = [], TLogger extends Logger = Logger, OutSchema extends StandardSchemaV1 | undefined = undefined, TSession = unknown, TEventPublisher extends EventPublisher<any> | undefined = undefined, TEventPublisherServiceName extends string = string, TAuthorizers extends readonly string[] = readonly string[], TAuditStorage extends AuditStorage | undefined = undefined, TAuditStorageServiceName extends string = string, TAuditAction extends AuditableAction<string, unknown> = AuditableAction<string, unknown>, TDatabase = undefined, TDatabaseServiceName extends string = string> extends BaseFunctionBuilder<TInput, OutSchema, TServices, TLogger, TEventPublisher, TEventPublisherServiceName, TAuditStorage, TAuditStorageServiceName, TDatabase, TDatabaseServiceName> {
|
|
14
15
|
readonly route: TRoute;
|
|
15
16
|
readonly method: TMethod;
|
|
@@ -25,6 +26,9 @@ declare class EndpointBuilder<TRoute extends string, TMethod extends HttpMethod,
|
|
|
25
26
|
_authorizerName?: TAuthorizers[number];
|
|
26
27
|
_actorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
|
|
27
28
|
_audits: MappedAudit<TAuditAction, OutSchema>[];
|
|
29
|
+
_customSecuritySchemes: Record<string, SecurityScheme>;
|
|
30
|
+
_rlsConfig?: RlsConfig<TServices, TSession, TLogger>;
|
|
31
|
+
_rlsBypass?: boolean;
|
|
28
32
|
constructor(route: TRoute, method: TMethod);
|
|
29
33
|
_setPublisher(publisher: Service<TEventPublisherServiceName, TEventPublisher>): void;
|
|
30
34
|
_setAuditorStorage(storage: Service<TAuditStorageServiceName, TAuditStorage>): void;
|
|
@@ -97,9 +101,43 @@ declare class EndpointBuilder<TRoute extends string, TMethod extends HttpMethod,
|
|
|
97
101
|
* ```
|
|
98
102
|
*/
|
|
99
103
|
database<T, TName extends string>(service: Service<TName, T>): EndpointBuilder<TRoute, TMethod, TInput, TServices, TLogger, OutSchema, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, T, TName>;
|
|
104
|
+
/**
|
|
105
|
+
* Configure RLS (Row-Level Security) context for this endpoint.
|
|
106
|
+
* Pass `false` or `RLS_BYPASS` to explicitly bypass RLS for this endpoint.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // Custom RLS config for this endpoint
|
|
111
|
+
* .rls({
|
|
112
|
+
* extractor: ({ session }) => ({
|
|
113
|
+
* user_id: session.userId,
|
|
114
|
+
* tenant_id: session.tenantId,
|
|
115
|
+
* }),
|
|
116
|
+
* prefix: 'app',
|
|
117
|
+
* })
|
|
118
|
+
*
|
|
119
|
+
* // Bypass RLS (for admin endpoints)
|
|
120
|
+
* .rls(false)
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
rls(config: RlsConfig<TServices, TSession, TLogger> | false | RlsBypass): this;
|
|
124
|
+
/**
|
|
125
|
+
* Explicitly bypass RLS for this endpoint.
|
|
126
|
+
* Useful for admin operations that need unrestricted database access.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* .rlsBypass()
|
|
131
|
+
* .handle(async ({ db }) => {
|
|
132
|
+
* // Full access, no RLS filtering
|
|
133
|
+
* return db.selectFrom('orders').selectAll().execute();
|
|
134
|
+
* })
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
rlsBypass(): this;
|
|
100
138
|
input(_schema: any): any;
|
|
101
139
|
handle(fn: EndpointHandler<TInput, TServices, TLogger, OutSchema, TSession, TDatabase, TAuditStorage, TAuditAction>): Endpoint<TRoute, TMethod, TInput, OutSchema, TServices, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
102
140
|
}
|
|
103
141
|
//#endregion
|
|
104
142
|
export { EndpointBuilder };
|
|
105
|
-
//# sourceMappingURL=EndpointBuilder-
|
|
143
|
+
//# sourceMappingURL=EndpointBuilder-vXk6eIJk.d.cts.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Authorizer } from "./Authorizer-
|
|
2
|
-
import { ActorExtractor, AuthorizeFn, SessionFn } from "./Endpoint-
|
|
3
|
-
import { EndpointBuilder } from "./EndpointBuilder-
|
|
4
|
-
import { Service } from "@geekmidas/services";
|
|
1
|
+
import { Authorizer, BuiltInSecuritySchemeId, SecurityScheme } from "./Authorizer-CpSUMTIs.cjs";
|
|
2
|
+
import { ActorExtractor, AuthorizeFn, RlsConfig, SessionFn } from "./Endpoint-CC2RGjkl.cjs";
|
|
3
|
+
import { EndpointBuilder } from "./EndpointBuilder-vXk6eIJk.cjs";
|
|
5
4
|
import { AuditStorage, AuditableAction, ExtractStorageAuditAction } from "@geekmidas/audit";
|
|
6
5
|
import { EventPublisher, MappedEvent } from "@geekmidas/events";
|
|
7
6
|
import { Logger } from "@geekmidas/logger";
|
|
7
|
+
import { Service } from "@geekmidas/services";
|
|
8
8
|
|
|
9
9
|
//#region src/endpoints/EndpointFactory.d.ts
|
|
10
|
-
declare class EndpointFactory<TServices extends Service[] = [], TBasePath extends string = '', TLogger extends Logger = Logger, TSession = unknown, TEventPublisher extends EventPublisher<any> | undefined = undefined, TEventPublisherServiceName extends string = string, TAuthorizers extends readonly string[] = readonly string[], TAuditStorage extends AuditStorage<any> | undefined = undefined, TAuditStorageServiceName extends string = string, TAuditAction extends AuditableAction<string, unknown> = ExtractStorageAuditAction<NonNullable<TAuditStorage>>, TDatabase = undefined, TDatabaseServiceName extends string = string> {
|
|
10
|
+
declare class EndpointFactory<TServices extends Service[] = [], TBasePath extends string = '', TLogger extends Logger = Logger, TSession = unknown, TEventPublisher extends EventPublisher<any> | undefined = undefined, TEventPublisherServiceName extends string = string, TAuthorizers extends readonly string[] = readonly string[], TAuditStorage extends AuditStorage<any> | undefined = undefined, TAuditStorageServiceName extends string = string, TAuditAction extends AuditableAction<string, unknown> = ExtractStorageAuditAction<NonNullable<TAuditStorage>>, TDatabase = undefined, TDatabaseServiceName extends string = string, TSecuritySchemes extends Record<string, SecurityScheme> = Record<string, SecurityScheme>, TRlsConfig extends RlsConfig<TServices, TSession, TLogger> | undefined = undefined> {
|
|
11
11
|
private defaultServices;
|
|
12
12
|
private basePath;
|
|
13
13
|
private defaultAuthorizeFn?;
|
|
@@ -19,6 +19,8 @@ declare class EndpointFactory<TServices extends Service[] = [], TBasePath extend
|
|
|
19
19
|
private defaultAuditorStorage;
|
|
20
20
|
private defaultDatabaseService;
|
|
21
21
|
private defaultActorExtractor?;
|
|
22
|
+
private customSecuritySchemes;
|
|
23
|
+
private defaultRlsConfig?;
|
|
22
24
|
constructor({
|
|
23
25
|
basePath,
|
|
24
26
|
defaultAuthorizeFn,
|
|
@@ -30,38 +32,81 @@ declare class EndpointFactory<TServices extends Service[] = [], TBasePath extend
|
|
|
30
32
|
defaultAuthorizerName,
|
|
31
33
|
defaultAuditorStorage,
|
|
32
34
|
defaultDatabaseService,
|
|
33
|
-
defaultActorExtractor
|
|
34
|
-
|
|
35
|
+
defaultActorExtractor,
|
|
36
|
+
customSecuritySchemes,
|
|
37
|
+
defaultRlsConfig
|
|
38
|
+
}?: EndpointFactoryOptions<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TDatabase, TDatabaseServiceName, TSecuritySchemes, TRlsConfig>);
|
|
35
39
|
static joinPaths<TBasePath extends string, P extends string>(path: P, basePath?: TBasePath): JoinPaths<TBasePath, P>;
|
|
36
|
-
authorizers<const T extends readonly string[]>(authorizers: T): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, T, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
40
|
+
authorizers<const T extends readonly string[]>(authorizers: T): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, T, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
41
|
+
/**
|
|
42
|
+
* Define custom security schemes for this factory.
|
|
43
|
+
* These extend the built-in schemes (jwt, bearer, apiKey, oauth2, oidc).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const router = e.securitySchemes({
|
|
48
|
+
* awsIamSigV4: {
|
|
49
|
+
* type: 'apiKey',
|
|
50
|
+
* in: 'header',
|
|
51
|
+
* name: 'Authorization',
|
|
52
|
+
* 'x-amazon-apigateway-authtype': 'awsSigv4',
|
|
53
|
+
* },
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
securitySchemes<T extends Record<string, SecurityScheme>>(schemes: T): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes & T>;
|
|
37
58
|
/**
|
|
38
59
|
* Set the default authorizer for all endpoints created from this factory.
|
|
39
60
|
* Individual endpoints can override this by calling `.authorizer()` on the builder.
|
|
40
61
|
* Use `'none'` to explicitly disable authorization for all endpoints.
|
|
62
|
+
*
|
|
63
|
+
* Accepts:
|
|
64
|
+
* - Built-in security scheme names: 'jwt', 'bearer', 'apiKey', 'oauth2', 'oidc'
|
|
65
|
+
* - Custom security scheme names defined via `.securitySchemes()`
|
|
66
|
+
* - 'none' to disable authorization
|
|
41
67
|
*/
|
|
42
|
-
authorizer(name: TAuthorizers[number] | 'none'): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
43
|
-
route<TPath extends string>(path: TPath): EndpointFactory<TServices, JoinPaths<TBasePath, TPath>, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
44
|
-
authorize(fn: AuthorizeFn<TServices, TLogger, TSession>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
45
|
-
services<S extends Service[]>(services: S): EndpointFactory<[...S, ...TServices], TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
46
|
-
logger<L extends Logger>(logger: L): EndpointFactory<TServices, TBasePath, L, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
47
|
-
publisher<T extends EventPublisher<any>, TServiceName extends string = string>(publisher: Service<TServiceName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, T, TServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
48
|
-
session<T>(session: SessionFn<TServices, TLogger, T, TDatabase>): EndpointFactory<TServices, TBasePath, TLogger, T, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
68
|
+
authorizer(name: BuiltInSecuritySchemeId | keyof TSecuritySchemes | TAuthorizers[number] | 'none'): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
69
|
+
route<TPath extends string>(path: TPath): EndpointFactory<TServices, JoinPaths<TBasePath, TPath>, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
70
|
+
authorize(fn: AuthorizeFn<TServices, TLogger, TSession>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
71
|
+
services<S extends Service[]>(services: S): EndpointFactory<[...S, ...TServices], TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
72
|
+
logger<L extends Logger>(logger: L): EndpointFactory<TServices, TBasePath, L, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
73
|
+
publisher<T extends EventPublisher<any>, TServiceName extends string = string>(publisher: Service<TServiceName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, T, TServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
74
|
+
session<T>(session: SessionFn<TServices, TLogger, T, TDatabase>): EndpointFactory<TServices, TBasePath, TLogger, T, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
49
75
|
/**
|
|
50
76
|
* Set the database service for endpoints created from this factory.
|
|
51
77
|
* The database will be available in handler context as `db`.
|
|
52
78
|
*/
|
|
53
|
-
database<T, TName extends string>(service: Service<TName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, T, TName>;
|
|
79
|
+
database<T, TName extends string>(service: Service<TName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, T, TName, TSecuritySchemes>;
|
|
54
80
|
/**
|
|
55
81
|
* Set the auditor storage service for endpoints created from this factory.
|
|
56
82
|
* This enables audit functionality and makes `auditor` available in handler context.
|
|
57
83
|
* The audit action type is automatically inferred from the storage's generic parameter.
|
|
58
84
|
*/
|
|
59
|
-
auditor<T extends AuditStorage<any>, TName extends string>(storage: Service<TName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, T, TName, ExtractStorageAuditAction<T>, TDatabase, TDatabaseServiceName>;
|
|
85
|
+
auditor<T extends AuditStorage<any>, TName extends string>(storage: Service<TName, T>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, T, TName, ExtractStorageAuditAction<T>, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
60
86
|
/**
|
|
61
87
|
* Set the actor extractor function for endpoints created from this factory.
|
|
62
88
|
* The actor is extracted from the request context and attached to all audits.
|
|
63
89
|
*/
|
|
64
|
-
actor(extractor: ActorExtractor<TServices, TSession, TLogger>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
90
|
+
actor(extractor: ActorExtractor<TServices, TSession, TLogger>): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes>;
|
|
91
|
+
/**
|
|
92
|
+
* Set the RLS (Row-Level Security) configuration for endpoints created from this factory.
|
|
93
|
+
* This enables automatic PostgreSQL session variable setting for RLS policies.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const api = new EndpointFactory()
|
|
98
|
+
* .database(databaseService)
|
|
99
|
+
* .session(extractSession)
|
|
100
|
+
* .rls({
|
|
101
|
+
* extractor: ({ session }) => ({
|
|
102
|
+
* user_id: session.userId,
|
|
103
|
+
* tenant_id: session.tenantId,
|
|
104
|
+
* }),
|
|
105
|
+
* prefix: 'app',
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
rls<TConfig extends RlsConfig<TServices, TSession, TLogger>>(config: TConfig): EndpointFactory<TServices, TBasePath, TLogger, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName, TSecuritySchemes, TConfig>;
|
|
65
110
|
private createBuilder;
|
|
66
111
|
post<TPath extends string>(path: TPath): EndpointBuilder<RemoveTrailingSlash<TBasePath extends "" ? TPath : TPath extends "" ? TBasePath : TBasePath extends "/" ? TPath extends `/${string}` ? TPath : `/${TPath}` : TBasePath extends `${infer Base}/` ? TPath extends `/${infer Rest}` ? `${Base}/${Rest}` : `${Base}/${TPath}` : TPath extends `/${infer Rest_1}` ? `${TBasePath}/${Rest_1}` : `${TBasePath}/${TPath}`>, "POST", {}, TServices, TLogger, undefined, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
67
112
|
get<TPath extends string>(path: TPath): EndpointBuilder<RemoveTrailingSlash<TBasePath extends "" ? TPath : TPath extends "" ? TBasePath : TBasePath extends "/" ? TPath extends `/${string}` ? TPath : `/${TPath}` : TBasePath extends `${infer Base}/` ? TPath extends `/${infer Rest}` ? `${Base}/${Rest}` : `${Base}/${TPath}` : TPath extends `/${infer Rest_1}` ? `${TBasePath}/${Rest_1}` : `${TBasePath}/${TPath}`>, "GET", {}, TServices, TLogger, undefined, TSession, TEventPublisher, TEventPublisherServiceName, TAuthorizers, TAuditStorage, TAuditStorageServiceName, TAuditAction, TDatabase, TDatabaseServiceName>;
|
|
@@ -72,7 +117,7 @@ declare class EndpointFactory<TServices extends Service[] = [], TBasePath extend
|
|
|
72
117
|
}
|
|
73
118
|
type RemoveTrailingSlash<T extends string> = T extends `${infer Rest}/` ? Rest extends '' ? T : Rest : T;
|
|
74
119
|
type JoinPaths<TBasePath extends string, TPath extends string> = RemoveTrailingSlash<TBasePath extends '' ? TPath : TPath extends '' ? TBasePath : TBasePath extends '/' ? TPath extends `/${string}` ? TPath : `/${TPath}` : TBasePath extends `${infer Base}/` ? TPath extends `/${infer Rest}` ? `${Base}/${Rest}` : `${Base}/${TPath}` : TPath extends `/${infer Rest}` ? `${TBasePath}/${Rest}` : `${TBasePath}/${TPath}`>;
|
|
75
|
-
interface EndpointFactoryOptions<TServices extends Service[] = [], TBasePath extends string = '', TLogger extends Logger = Logger, TSession = unknown, TEventPublisher extends EventPublisher<any> | undefined = undefined, TEventPublisherServiceName extends string = string, TAuthorizers extends readonly string[] = readonly string[], TAuditStorage extends AuditStorage | undefined = undefined, TAuditStorageServiceName extends string = string, TDatabase = undefined, TDatabaseServiceName extends string = string> {
|
|
120
|
+
interface EndpointFactoryOptions<TServices extends Service[] = [], TBasePath extends string = '', TLogger extends Logger = Logger, TSession = unknown, TEventPublisher extends EventPublisher<any> | undefined = undefined, TEventPublisherServiceName extends string = string, TAuthorizers extends readonly string[] = readonly string[], TAuditStorage extends AuditStorage | undefined = undefined, TAuditStorageServiceName extends string = string, TDatabase = undefined, TDatabaseServiceName extends string = string, TSecuritySchemes extends Record<string, SecurityScheme> = Record<string, SecurityScheme>, TRlsConfig extends RlsConfig<TServices, TSession, TLogger> | undefined = undefined> {
|
|
76
121
|
defaultServices?: TServices;
|
|
77
122
|
basePath?: TBasePath;
|
|
78
123
|
defaultAuthorizeFn?: AuthorizeFn<TServices, TLogger, TSession>;
|
|
@@ -85,8 +130,10 @@ interface EndpointFactoryOptions<TServices extends Service[] = [], TBasePath ext
|
|
|
85
130
|
defaultAuditorStorage?: Service<TAuditStorageServiceName, TAuditStorage>;
|
|
86
131
|
defaultDatabaseService?: Service<TDatabaseServiceName, TDatabase>;
|
|
87
132
|
defaultActorExtractor?: ActorExtractor<TServices, TSession, TLogger>;
|
|
133
|
+
customSecuritySchemes?: TSecuritySchemes;
|
|
134
|
+
defaultRlsConfig?: TRlsConfig;
|
|
88
135
|
}
|
|
89
|
-
declare const e: EndpointFactory<[], "", Logger, unknown, undefined, string, readonly string[], undefined, string, never, undefined, string>;
|
|
136
|
+
declare const e: EndpointFactory<[], "", Logger, unknown, undefined, string, readonly string[], undefined, string, never, undefined, string, Record<string, SecurityScheme>, undefined>;
|
|
90
137
|
//#endregion
|
|
91
138
|
export { EndpointFactory, EndpointFactoryOptions, JoinPaths, RemoveTrailingSlash, e };
|
|
92
|
-
//# sourceMappingURL=EndpointFactory-
|
|
139
|
+
//# sourceMappingURL=EndpointFactory-3g-7Rznt.d.cts.map
|