@geekmidas/constructs 3.0.3 → 3.0.6
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/CHANGELOG.md +18 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-jDYqkgFE.cjs → AmazonApiGatewayEndpointAdaptor-BIltcbAc.cjs} +21 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-BIltcbAc.cjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-ciUHVvPX.mjs → AmazonApiGatewayEndpointAdaptor-BpYtYCeW.mjs} +21 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-BpYtYCeW.mjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-D4lAuXA-.d.cts → AmazonApiGatewayEndpointAdaptor-DqNcQGMf.d.cts} +11 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-DqNcQGMf.d.cts.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-B30TqZRX.d.mts → AmazonApiGatewayEndpointAdaptor-Hi8Pbp2d.d.mts} +11 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-Hi8Pbp2d.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-DCfEo-Tu.mjs → AmazonApiGatewayV1EndpointAdaptor-CRwyWT6t.mjs} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-DCfEo-Tu.mjs.map → AmazonApiGatewayV1EndpointAdaptor-CRwyWT6t.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-DwKlAfnb.cjs → AmazonApiGatewayV1EndpointAdaptor-DEETT6Wj.cjs} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-DwKlAfnb.cjs.map → AmazonApiGatewayV1EndpointAdaptor-DEETT6Wj.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-B5xFYauV.d.cts → AmazonApiGatewayV1EndpointAdaptor-DcN2fYsv.d.cts} +3 -3
- package/dist/AmazonApiGatewayV1EndpointAdaptor-DcN2fYsv.d.cts.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CG1UJoAK.d.mts → AmazonApiGatewayV1EndpointAdaptor-cpwJzU4W.d.mts} +3 -3
- package/dist/AmazonApiGatewayV1EndpointAdaptor-cpwJzU4W.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-B126fL6i.cjs → AmazonApiGatewayV2EndpointAdaptor-C2qO8FN6.cjs} +4 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-B126fL6i.cjs.map → AmazonApiGatewayV2EndpointAdaptor-C2qO8FN6.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-OkwjABOz.d.cts → AmazonApiGatewayV2EndpointAdaptor-Cn9UoRgB.d.cts} +3 -3
- package/dist/AmazonApiGatewayV2EndpointAdaptor-Cn9UoRgB.d.cts.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-ofjuxcPV.d.mts → AmazonApiGatewayV2EndpointAdaptor-LzH3hkB-.d.mts} +3 -3
- package/dist/AmazonApiGatewayV2EndpointAdaptor-LzH3hkB-.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-CGMF4lD4.mjs → AmazonApiGatewayV2EndpointAdaptor-m9YKI294.mjs} +4 -3
- package/dist/AmazonApiGatewayV2EndpointAdaptor-m9YKI294.mjs.map +1 -0
- package/dist/{Authorizer-BgjU8-z6.mjs → Authorizer-4unKN3Xn.mjs} +1 -1
- package/dist/{Authorizer-BgjU8-z6.mjs.map → Authorizer-4unKN3Xn.mjs.map} +1 -1
- package/dist/{Authorizer-BXxBee2P.cjs → Authorizer-Dx57psuM.cjs} +1 -1
- package/dist/{Authorizer-BXxBee2P.cjs.map → Authorizer-Dx57psuM.cjs.map} +1 -1
- package/dist/{Cron-BUpUS-0f.mjs → Cron-B3vrGuaD.mjs} +1 -1
- package/dist/{Cron-BUpUS-0f.mjs.map → Cron-B3vrGuaD.mjs.map} +1 -1
- package/dist/{Cron-Bp08dJ4R.cjs → Cron-DEKZg5j4.cjs} +1 -1
- package/dist/{Cron-Bp08dJ4R.cjs.map → Cron-DEKZg5j4.cjs.map} +1 -1
- package/dist/{CronBuilder-CIxJQ1Ps.cjs → CronBuilder-BHpY6w3b.cjs} +2 -2
- package/dist/{CronBuilder-CIxJQ1Ps.cjs.map → CronBuilder-BHpY6w3b.cjs.map} +1 -1
- package/dist/{CronBuilder-DUggbCHc.mjs → CronBuilder-VXpyNfp2.mjs} +2 -2
- package/dist/{CronBuilder-DUggbCHc.mjs.map → CronBuilder-VXpyNfp2.mjs.map} +1 -1
- package/dist/Endpoint-BcxvF4F3.cjs.map +1 -1
- package/dist/{Endpoint-C9N6CmvB.d.cts → Endpoint-CGdCGJkC.d.cts} +6 -6
- package/dist/Endpoint-CGdCGJkC.d.cts.map +1 -0
- package/dist/{Endpoint-BiPM0glm.d.mts → Endpoint-DtFQFL63.d.mts} +6 -6
- package/dist/Endpoint-DtFQFL63.d.mts.map +1 -0
- package/dist/Endpoint-DvY3aqAy.mjs.map +1 -1
- package/dist/{EndpointBuilder-CF-ZWtdu.mjs → EndpointBuilder-CMzbGG2c.mjs} +7 -3
- package/dist/EndpointBuilder-CMzbGG2c.mjs.map +1 -0
- package/dist/{EndpointBuilder-B0Aj5jbB.d.mts → EndpointBuilder-DIAsH97h.d.mts} +4 -3
- package/dist/EndpointBuilder-DIAsH97h.d.mts.map +1 -0
- package/dist/{EndpointBuilder-Bel6RS7W.d.cts → EndpointBuilder-Dzqcm8Yv.d.cts} +4 -3
- package/dist/EndpointBuilder-Dzqcm8Yv.d.cts.map +1 -0
- package/dist/{EndpointBuilder-CyszO0bs.cjs → EndpointBuilder-QdDf3x87.cjs} +7 -3
- package/dist/EndpointBuilder-QdDf3x87.cjs.map +1 -0
- package/dist/{EndpointFactory-B0D6d6t9.cjs → EndpointFactory-AsfUsn-v.cjs} +3 -3
- package/dist/EndpointFactory-AsfUsn-v.cjs.map +1 -0
- package/dist/{EndpointFactory-CXvakOkn.d.cts → EndpointFactory-C1rh407J.d.cts} +5 -5
- package/dist/EndpointFactory-C1rh407J.d.cts.map +1 -0
- package/dist/{EndpointFactory-Do498RmG.mjs → EndpointFactory-CkPaFZA0.mjs} +3 -3
- package/dist/EndpointFactory-CkPaFZA0.mjs.map +1 -0
- package/dist/{EndpointFactory-CWIeWCRG.d.mts → EndpointFactory-pCuCu_1H.d.mts} +5 -5
- package/dist/EndpointFactory-pCuCu_1H.d.mts.map +1 -0
- package/dist/{HonoEndpointAdaptor-CQqQPLHH.cjs → HonoEndpointAdaptor-B5fKdLi7.cjs} +6 -2
- package/dist/HonoEndpointAdaptor-B5fKdLi7.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-DgoeqUX6.d.mts → HonoEndpointAdaptor-BXga7Jqh.d.mts} +4 -4
- package/dist/{HonoEndpointAdaptor-BNHGwpvZ.d.cts.map → HonoEndpointAdaptor-BXga7Jqh.d.mts.map} +1 -1
- package/dist/{HonoEndpointAdaptor-BNHGwpvZ.d.cts → HonoEndpointAdaptor-D3IgM-0B.d.cts} +4 -4
- package/dist/{HonoEndpointAdaptor-DgoeqUX6.d.mts.map → HonoEndpointAdaptor-D3IgM-0B.d.cts.map} +1 -1
- package/dist/{HonoEndpointAdaptor-BvxQreVM.mjs → HonoEndpointAdaptor-DOUODM7n.mjs} +6 -2
- package/dist/HonoEndpointAdaptor-DOUODM7n.mjs.map +1 -0
- package/dist/{Subscriber-DKQK5gLD.mjs → Subscriber-BEhOdNQi.mjs} +1 -1
- package/dist/{Subscriber-DKQK5gLD.mjs.map → Subscriber-BEhOdNQi.mjs.map} +1 -1
- package/dist/{Subscriber-ClqSPbIZ.cjs → Subscriber-Scz7hrV6.cjs} +1 -1
- package/dist/{Subscriber-ClqSPbIZ.cjs.map → Subscriber-Scz7hrV6.cjs.map} +1 -1
- package/dist/{SubscriberBuilder-BS5B_688.cjs → SubscriberBuilder-B82h4v-S.cjs} +2 -2
- package/dist/{SubscriberBuilder-BS5B_688.cjs.map → SubscriberBuilder-B82h4v-S.cjs.map} +1 -1
- package/dist/{SubscriberBuilder-BswTuvUc.mjs → SubscriberBuilder-DlUaG0Ej.mjs} +2 -2
- package/dist/{SubscriberBuilder-BswTuvUc.mjs.map → SubscriberBuilder-DlUaG0Ej.mjs.map} +1 -1
- package/dist/{TestEndpointAdaptor-CCf3Dg0u.d.cts → TestEndpointAdaptor-Clz_L8Xj.d.cts} +2 -2
- package/dist/{TestEndpointAdaptor-CCf3Dg0u.d.cts.map → TestEndpointAdaptor-Clz_L8Xj.d.cts.map} +1 -1
- package/dist/{TestEndpointAdaptor-qSWV8dpS.d.mts → TestEndpointAdaptor-DxXJoBBf.d.mts} +2 -2
- package/dist/{TestEndpointAdaptor-qSWV8dpS.d.mts.map → TestEndpointAdaptor-DxXJoBBf.d.mts.map} +1 -1
- package/dist/{TestEndpointAdaptor-CDOhCmIk.mjs → TestEndpointAdaptor-G2T789bH.mjs} +6 -2
- package/dist/TestEndpointAdaptor-G2T789bH.mjs.map +1 -0
- package/dist/{TestEndpointAdaptor-DjQSuxRq.cjs → TestEndpointAdaptor-YlwOEisx.cjs} +6 -2
- package/dist/TestEndpointAdaptor-YlwOEisx.cjs.map +1 -0
- package/dist/adaptors/aws.cjs +3 -3
- package/dist/adaptors/aws.d.cts +5 -5
- package/dist/adaptors/aws.d.mts +5 -5
- package/dist/adaptors/aws.mjs +3 -3
- package/dist/adaptors/hono.cjs +1 -1
- package/dist/adaptors/hono.d.cts +3 -3
- package/dist/adaptors/hono.d.mts +3 -3
- package/dist/adaptors/hono.mjs +1 -1
- package/dist/adaptors/testing.cjs +1 -1
- package/dist/adaptors/testing.d.cts +3 -3
- package/dist/adaptors/testing.d.mts +3 -3
- package/dist/adaptors/testing.mjs +1 -1
- package/dist/crons/Cron.cjs +1 -1
- package/dist/crons/Cron.d.cts +1 -1
- package/dist/crons/Cron.d.mts +1 -1
- package/dist/crons/Cron.mjs +1 -1
- package/dist/crons/CronBuilder.cjs +2 -2
- package/dist/crons/CronBuilder.d.cts +1 -1
- package/dist/crons/CronBuilder.d.mts +1 -1
- package/dist/crons/CronBuilder.mjs +2 -2
- package/dist/crons/index.cjs +2 -2
- package/dist/crons/index.d.cts +5 -5
- package/dist/crons/index.d.cts.map +1 -1
- package/dist/crons/index.d.mts +5 -5
- package/dist/crons/index.d.mts.map +1 -1
- package/dist/crons/index.mjs +2 -2
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +1 -1
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +3 -3
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +1 -1
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +2 -2
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +2 -2
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +2 -2
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +2 -2
- package/dist/endpoints/Authorizer.cjs +1 -1
- package/dist/endpoints/Authorizer.mjs +1 -1
- package/dist/endpoints/Endpoint.d.cts +2 -2
- package/dist/endpoints/Endpoint.d.mts +2 -2
- package/dist/endpoints/EndpointBuilder.cjs +3 -3
- package/dist/endpoints/EndpointBuilder.d.cts +3 -3
- package/dist/endpoints/EndpointBuilder.d.mts +3 -3
- package/dist/endpoints/EndpointBuilder.mjs +3 -3
- package/dist/endpoints/EndpointFactory.cjs +4 -4
- package/dist/endpoints/EndpointFactory.d.cts +4 -4
- package/dist/endpoints/EndpointFactory.d.mts +4 -4
- package/dist/endpoints/EndpointFactory.mjs +4 -4
- package/dist/endpoints/HonoEndpointAdaptor.cjs +1 -1
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +3 -3
- package/dist/endpoints/HonoEndpointAdaptor.mjs +1 -1
- package/dist/endpoints/TestEndpointAdaptor.cjs +1 -1
- package/dist/endpoints/TestEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/TestEndpointAdaptor.d.mts +3 -3
- package/dist/endpoints/TestEndpointAdaptor.mjs +1 -1
- package/dist/endpoints/audit.d.cts +2 -2
- package/dist/endpoints/audit.d.mts +2 -2
- package/dist/endpoints/helpers.d.cts +2 -2
- package/dist/endpoints/helpers.d.mts +2 -2
- package/dist/endpoints/index.cjs +4 -4
- package/dist/endpoints/index.d.cts +7 -7
- package/dist/endpoints/index.d.mts +7 -7
- package/dist/endpoints/index.mjs +4 -4
- package/dist/endpoints/lazyAccessors.d.cts +3 -3
- package/dist/endpoints/lazyAccessors.d.mts +3 -3
- package/dist/endpoints/processAudits.d.cts +2 -2
- package/dist/endpoints/processAudits.d.mts +2 -2
- package/dist/endpoints/rls.cjs +1 -1
- package/dist/endpoints/rls.d.cts +2 -2
- package/dist/endpoints/rls.d.mts +2 -2
- package/dist/endpoints/rls.mjs +1 -1
- package/dist/functions/index.d.cts +1 -1
- package/dist/functions/index.d.mts +1 -1
- package/dist/index-BfeupgMl.d.cts +12 -0
- package/dist/{index-Br-zTYii.d.mts.map → index-BfeupgMl.d.cts.map} +1 -1
- package/dist/index-DQo_Csy7.d.mts +12 -0
- package/dist/{index-dRNH0dT6.d.cts.map → index-DQo_Csy7.d.mts.map} +1 -1
- package/dist/{lazyAccessors-DXkJpnyX.d.mts → lazyAccessors-Bled3FVc.d.mts} +2 -2
- package/dist/{lazyAccessors-DXkJpnyX.d.mts.map → lazyAccessors-Bled3FVc.d.mts.map} +1 -1
- package/dist/{lazyAccessors-DdZaA716.d.cts → lazyAccessors-C8AF1hNi.d.cts} +2 -2
- package/dist/{lazyAccessors-DdZaA716.d.cts.map → lazyAccessors-C8AF1hNi.d.cts.map} +1 -1
- package/dist/{rls-C0cWOnk4.mjs → rls-7XXX7DvY.mjs} +1 -1
- package/dist/{rls-C0cWOnk4.mjs.map → rls-7XXX7DvY.mjs.map} +1 -1
- package/dist/{rls-BrywnrQb.cjs → rls-DxFqdIA0.cjs} +1 -1
- package/dist/{rls-BrywnrQb.cjs.map → rls-DxFqdIA0.cjs.map} +1 -1
- package/dist/subscribers/Subscriber.cjs +1 -1
- package/dist/subscribers/Subscriber.mjs +1 -1
- package/dist/subscribers/SubscriberBuilder.cjs +2 -2
- 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.cts.map +1 -1
- package/dist/subscribers/index.d.mts +2 -2
- package/dist/subscribers/index.mjs +2 -2
- package/package.json +11 -11
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +35 -1
- package/src/endpoints/AmazonApiGatewayV1EndpointAdaptor.ts +5 -1
- package/src/endpoints/AmazonApiGatewayV2EndpointAdaptor.ts +7 -1
- package/src/endpoints/Endpoint.ts +17 -4
- package/src/endpoints/EndpointBuilder.ts +9 -1
- package/src/endpoints/EndpointFactory.ts +19 -5
- package/src/endpoints/HonoEndpointAdaptor.ts +11 -1
- package/src/endpoints/TestEndpointAdaptor.ts +5 -1
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +112 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +137 -0
- package/src/endpoints/__tests__/EndpointBuilder.spec.ts +35 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +105 -0
- package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +193 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-B30TqZRX.d.mts.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-D4lAuXA-.d.cts.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-ciUHVvPX.mjs.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-jDYqkgFE.cjs.map +0 -1
- package/dist/AmazonApiGatewayV1EndpointAdaptor-B5xFYauV.d.cts.map +0 -1
- package/dist/AmazonApiGatewayV1EndpointAdaptor-CG1UJoAK.d.mts.map +0 -1
- package/dist/AmazonApiGatewayV2EndpointAdaptor-CGMF4lD4.mjs.map +0 -1
- package/dist/AmazonApiGatewayV2EndpointAdaptor-OkwjABOz.d.cts.map +0 -1
- package/dist/AmazonApiGatewayV2EndpointAdaptor-ofjuxcPV.d.mts.map +0 -1
- package/dist/Endpoint-BiPM0glm.d.mts.map +0 -1
- package/dist/Endpoint-C9N6CmvB.d.cts.map +0 -1
- package/dist/EndpointBuilder-B0Aj5jbB.d.mts.map +0 -1
- package/dist/EndpointBuilder-Bel6RS7W.d.cts.map +0 -1
- package/dist/EndpointBuilder-CF-ZWtdu.mjs.map +0 -1
- package/dist/EndpointBuilder-CyszO0bs.cjs.map +0 -1
- package/dist/EndpointFactory-B0D6d6t9.cjs.map +0 -1
- package/dist/EndpointFactory-CWIeWCRG.d.mts.map +0 -1
- package/dist/EndpointFactory-CXvakOkn.d.cts.map +0 -1
- package/dist/EndpointFactory-Do498RmG.mjs.map +0 -1
- package/dist/HonoEndpointAdaptor-BvxQreVM.mjs.map +0 -1
- package/dist/HonoEndpointAdaptor-CQqQPLHH.cjs.map +0 -1
- package/dist/TestEndpointAdaptor-CDOhCmIk.mjs.map +0 -1
- package/dist/TestEndpointAdaptor-DjQSuxRq.cjs.map +0 -1
- package/dist/index-Br-zTYii.d.mts +0 -12
- package/dist/index-dRNH0dT6.d.cts +0 -12
|
@@ -63,7 +63,8 @@ export class EndpointBuilder<
|
|
|
63
63
|
protected _memorySize?: number;
|
|
64
64
|
_getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>
|
|
65
65
|
({}) as TSession;
|
|
66
|
-
_authorize: AuthorizeFn<TServices, TLogger, TSession> =
|
|
66
|
+
_authorize: AuthorizeFn<TServices, TLogger, TSession, TInput, TDatabase> =
|
|
67
|
+
() => true;
|
|
67
68
|
_rateLimit?: RateLimitConfig;
|
|
68
69
|
_availableAuthorizers: Authorizer[] = [];
|
|
69
70
|
_authorizerName?: TAuthorizers[number];
|
|
@@ -263,6 +264,13 @@ export class EndpointBuilder<
|
|
|
263
264
|
return this;
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
authorize(
|
|
268
|
+
fn: AuthorizeFn<TServices, TLogger, TSession, TInput, TDatabase>,
|
|
269
|
+
): this {
|
|
270
|
+
this._authorize = fn;
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
|
|
266
274
|
rateLimit(config: RateLimitConfig): this {
|
|
267
275
|
this._rateLimit = config;
|
|
268
276
|
return this;
|
|
@@ -51,7 +51,13 @@ export class EndpointFactory<
|
|
|
51
51
|
> {
|
|
52
52
|
private defaultServices: TServices = [] as unknown as TServices;
|
|
53
53
|
private basePath: TBasePath = '' as TBasePath;
|
|
54
|
-
private defaultAuthorizeFn?: AuthorizeFn<
|
|
54
|
+
private defaultAuthorizeFn?: AuthorizeFn<
|
|
55
|
+
TServices,
|
|
56
|
+
TLogger,
|
|
57
|
+
TSession,
|
|
58
|
+
undefined,
|
|
59
|
+
TDatabase
|
|
60
|
+
>;
|
|
55
61
|
private defaultEventPublisher:
|
|
56
62
|
| Service<TEventPublisherServiceName, TEventPublisher>
|
|
57
63
|
| undefined;
|
|
@@ -419,7 +425,7 @@ export class EndpointFactory<
|
|
|
419
425
|
|
|
420
426
|
// Create a new factory with authorization
|
|
421
427
|
authorize(
|
|
422
|
-
fn: AuthorizeFn<TServices, TLogger, TSession>,
|
|
428
|
+
fn: AuthorizeFn<TServices, TLogger, TSession, undefined, TDatabase>,
|
|
423
429
|
): EndpointFactory<
|
|
424
430
|
TServices,
|
|
425
431
|
TBasePath,
|
|
@@ -749,7 +755,9 @@ export class EndpointFactory<
|
|
|
749
755
|
>({
|
|
750
756
|
defaultServices: this.defaultServices,
|
|
751
757
|
basePath: this.basePath,
|
|
752
|
-
defaultAuthorizeFn: this.defaultAuthorizeFn
|
|
758
|
+
defaultAuthorizeFn: this.defaultAuthorizeFn as unknown as
|
|
759
|
+
| AuthorizeFn<TServices, TLogger, TSession, undefined, T>
|
|
760
|
+
| undefined,
|
|
753
761
|
defaultLogger: this.defaultLogger,
|
|
754
762
|
// Reset session extractor when database changes - user should call .session() after .database()
|
|
755
763
|
// to get proper type inference for the new database type
|
|
@@ -988,7 +996,7 @@ export class EndpointFactory<
|
|
|
988
996
|
>(fullPath, method);
|
|
989
997
|
|
|
990
998
|
if (this.defaultAuthorizeFn) {
|
|
991
|
-
builder._authorize = this.defaultAuthorizeFn;
|
|
999
|
+
builder._authorize = this.defaultAuthorizeFn as any;
|
|
992
1000
|
}
|
|
993
1001
|
if (this.defaultServices.length) {
|
|
994
1002
|
// Create a copy to avoid sharing references between builders
|
|
@@ -1117,7 +1125,13 @@ export interface EndpointFactoryOptions<
|
|
|
1117
1125
|
> {
|
|
1118
1126
|
defaultServices?: TServices;
|
|
1119
1127
|
basePath?: TBasePath;
|
|
1120
|
-
defaultAuthorizeFn?: AuthorizeFn<
|
|
1128
|
+
defaultAuthorizeFn?: AuthorizeFn<
|
|
1129
|
+
TServices,
|
|
1130
|
+
TLogger,
|
|
1131
|
+
TSession,
|
|
1132
|
+
undefined,
|
|
1133
|
+
TDatabase
|
|
1134
|
+
>;
|
|
1121
1135
|
defaultLogger?: TLogger;
|
|
1122
1136
|
defaultSessionExtractor?: SessionFn<TServices, TLogger, TSession, TDatabase>;
|
|
1123
1137
|
defaultEventPublisher?: Service<TEventPublisherServiceName, TEventPublisher>;
|
|
@@ -393,7 +393,17 @@ export class HonoEndpoint<
|
|
|
393
393
|
services,
|
|
394
394
|
logger,
|
|
395
395
|
session,
|
|
396
|
-
|
|
396
|
+
...(rawDb !== undefined && { db: rawDb }),
|
|
397
|
+
body: features.hasBodyValidation
|
|
398
|
+
? (c.req.valid as any)('json')
|
|
399
|
+
: undefined,
|
|
400
|
+
query: features.hasQueryValidation
|
|
401
|
+
? (c.req.valid as any)('query')
|
|
402
|
+
: undefined,
|
|
403
|
+
params: features.hasParamValidation
|
|
404
|
+
? (c.req.valid as any)('param')
|
|
405
|
+
: undefined,
|
|
406
|
+
} as any);
|
|
397
407
|
|
|
398
408
|
if (!isAuthorized) {
|
|
399
409
|
logger.warn('Unauthorized access attempt');
|
|
@@ -216,7 +216,11 @@ export class TestEndpointAdaptor<
|
|
|
216
216
|
services: ctx.services,
|
|
217
217
|
logger,
|
|
218
218
|
session,
|
|
219
|
-
|
|
219
|
+
...(rawDb !== undefined && { db: rawDb }),
|
|
220
|
+
body,
|
|
221
|
+
query,
|
|
222
|
+
params,
|
|
223
|
+
} as any);
|
|
220
224
|
|
|
221
225
|
if (!isAuthorized) {
|
|
222
226
|
logger.warn('Unauthorized access attempt');
|
|
@@ -45,6 +45,118 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
45
45
|
envParser = new EnvironmentParser({});
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
+
describe('getInput', () => {
|
|
49
|
+
it('should parse JSON body when content-type is application/json', () => {
|
|
50
|
+
const endpoint = new Endpoint({
|
|
51
|
+
route: '/test',
|
|
52
|
+
method: 'GET',
|
|
53
|
+
fn: async () => ({ success: true }),
|
|
54
|
+
input: {},
|
|
55
|
+
output: z.object({ success: z.boolean() }),
|
|
56
|
+
services: [],
|
|
57
|
+
logger: mockLogger,
|
|
58
|
+
timeout: undefined,
|
|
59
|
+
memorySize: undefined,
|
|
60
|
+
status: undefined,
|
|
61
|
+
getSession: undefined,
|
|
62
|
+
authorize: undefined,
|
|
63
|
+
description: 'Test endpoint',
|
|
64
|
+
});
|
|
65
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
66
|
+
|
|
67
|
+
const event = createMockV1Event({
|
|
68
|
+
headers: { 'Content-Type': 'application/json' },
|
|
69
|
+
body: JSON.stringify({ name: 'test' }),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const result = adapter.getInput(event);
|
|
73
|
+
expect(result.body).toEqual({ name: 'test' });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should decode base64-encoded JSON body', () => {
|
|
77
|
+
const endpoint = new Endpoint({
|
|
78
|
+
route: '/test',
|
|
79
|
+
method: 'GET',
|
|
80
|
+
fn: async () => ({ success: true }),
|
|
81
|
+
input: {},
|
|
82
|
+
output: z.object({ success: z.boolean() }),
|
|
83
|
+
services: [],
|
|
84
|
+
logger: mockLogger,
|
|
85
|
+
timeout: undefined,
|
|
86
|
+
memorySize: undefined,
|
|
87
|
+
status: undefined,
|
|
88
|
+
getSession: undefined,
|
|
89
|
+
authorize: undefined,
|
|
90
|
+
description: 'Test endpoint',
|
|
91
|
+
});
|
|
92
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
93
|
+
|
|
94
|
+
const event = createMockV1Event({
|
|
95
|
+
headers: { 'Content-Type': 'application/json' },
|
|
96
|
+
body: Buffer.from(JSON.stringify({ name: 'test' })).toString('base64'),
|
|
97
|
+
isBase64Encoded: true,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const result = adapter.getInput(event);
|
|
101
|
+
expect(result.body).toEqual({ name: 'test' });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should return raw string for non-JSON content-type', () => {
|
|
105
|
+
const endpoint = new Endpoint({
|
|
106
|
+
route: '/test',
|
|
107
|
+
method: 'POST',
|
|
108
|
+
fn: async () => ({ success: true }),
|
|
109
|
+
input: {},
|
|
110
|
+
output: z.object({ success: z.boolean() }),
|
|
111
|
+
services: [],
|
|
112
|
+
logger: mockLogger,
|
|
113
|
+
timeout: undefined,
|
|
114
|
+
memorySize: undefined,
|
|
115
|
+
status: undefined,
|
|
116
|
+
getSession: undefined,
|
|
117
|
+
authorize: undefined,
|
|
118
|
+
description: 'Test endpoint',
|
|
119
|
+
});
|
|
120
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
121
|
+
|
|
122
|
+
const event = createMockV1Event({
|
|
123
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
124
|
+
body: 'amount=100¤cy=ZAR',
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const result = adapter.getInput(event);
|
|
128
|
+
expect(result.body).toBe('amount=100¤cy=ZAR');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should decode base64 and return string for form-urlencoded content', () => {
|
|
132
|
+
const endpoint = new Endpoint({
|
|
133
|
+
route: '/test',
|
|
134
|
+
method: 'POST',
|
|
135
|
+
fn: async () => ({ success: true }),
|
|
136
|
+
input: {},
|
|
137
|
+
output: z.object({ success: z.boolean() }),
|
|
138
|
+
services: [],
|
|
139
|
+
logger: mockLogger,
|
|
140
|
+
timeout: undefined,
|
|
141
|
+
memorySize: undefined,
|
|
142
|
+
status: undefined,
|
|
143
|
+
getSession: undefined,
|
|
144
|
+
authorize: undefined,
|
|
145
|
+
description: 'Test endpoint',
|
|
146
|
+
});
|
|
147
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
148
|
+
|
|
149
|
+
const event = createMockV1Event({
|
|
150
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
151
|
+
body: Buffer.from('amount=100¤cy=ZAR').toString('base64'),
|
|
152
|
+
isBase64Encoded: true,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const result = adapter.getInput(event);
|
|
156
|
+
expect(result.body).toBe('amount=100¤cy=ZAR');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
48
160
|
describe('handler', () => {
|
|
49
161
|
it('should handle a simple GET request', async () => {
|
|
50
162
|
const endpoint = new Endpoint({
|
|
@@ -3,6 +3,7 @@ import { createMockContext, createMockV2Event } from '@geekmidas/testkit/aws';
|
|
|
3
3
|
import type { Context } from 'aws-lambda';
|
|
4
4
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
+
import { AmazonApiGatewayEndpoint } from '../AmazonApiGatewayEndpointAdaptor';
|
|
6
7
|
import { AmazonApiGatewayV2Endpoint } from '../AmazonApiGatewayV2EndpointAdaptor';
|
|
7
8
|
import { e } from '../EndpointFactory';
|
|
8
9
|
|
|
@@ -36,6 +37,78 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
36
37
|
});
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
it('should parse JSON body when content-type is application/json', () => {
|
|
41
|
+
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
42
|
+
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
43
|
+
|
|
44
|
+
const event = createMockV2Event({
|
|
45
|
+
headers: { 'content-type': 'application/json' },
|
|
46
|
+
body: JSON.stringify({ name: 'test' }),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const result = adapter.getInput(event);
|
|
50
|
+
|
|
51
|
+
expect(result.body).toEqual({ name: 'test' });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should decode base64-encoded JSON body', () => {
|
|
55
|
+
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
56
|
+
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
57
|
+
|
|
58
|
+
const event = createMockV2Event({
|
|
59
|
+
headers: { 'content-type': 'application/json' },
|
|
60
|
+
body: Buffer.from(JSON.stringify({ name: 'test' })).toString('base64'),
|
|
61
|
+
isBase64Encoded: true,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const result = adapter.getInput(event);
|
|
65
|
+
|
|
66
|
+
expect(result.body).toEqual({ name: 'test' });
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should return base64-decoded string for non-JSON content-type', () => {
|
|
70
|
+
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
71
|
+
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
72
|
+
|
|
73
|
+
const event = createMockV2Event({
|
|
74
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
75
|
+
body: Buffer.from('amount=100¤cy=ZAR').toString('base64'),
|
|
76
|
+
isBase64Encoded: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const result = adapter.getInput(event);
|
|
80
|
+
|
|
81
|
+
expect(result.body).toBe('amount=100¤cy=ZAR');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should return raw string when content-type is not JSON', () => {
|
|
85
|
+
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
86
|
+
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
87
|
+
|
|
88
|
+
const event = createMockV2Event({
|
|
89
|
+
headers: { 'content-type': 'text/plain' },
|
|
90
|
+
body: 'plain-text-body',
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const result = adapter.getInput(event);
|
|
94
|
+
|
|
95
|
+
expect(result.body).toBe('plain-text-body');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should default to JSON parsing when no content-type header', () => {
|
|
99
|
+
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
100
|
+
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
101
|
+
|
|
102
|
+
const event = createMockV2Event({
|
|
103
|
+
headers: {},
|
|
104
|
+
body: JSON.stringify({ name: 'test' }),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = adapter.getInput(event);
|
|
108
|
+
|
|
109
|
+
expect(result.body).toEqual({ name: 'test' });
|
|
110
|
+
});
|
|
111
|
+
|
|
39
112
|
it('should handle missing body, query, and params', () => {
|
|
40
113
|
const endpoint = e.get('/test').handle(() => ({ success: true }));
|
|
41
114
|
const adapter = new AmazonApiGatewayV2Endpoint(envParser, endpoint);
|
|
@@ -490,3 +563,67 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
490
563
|
});
|
|
491
564
|
});
|
|
492
565
|
});
|
|
566
|
+
|
|
567
|
+
describe('AmazonApiGatewayEndpoint.decodeBody', () => {
|
|
568
|
+
const decodeBody = AmazonApiGatewayEndpoint.decodeBody;
|
|
569
|
+
|
|
570
|
+
it('should return undefined for null/undefined body', () => {
|
|
571
|
+
expect(decodeBody(undefined, false, 'application/json')).toBeUndefined();
|
|
572
|
+
expect(decodeBody(null, false, 'application/json')).toBeUndefined();
|
|
573
|
+
expect(decodeBody('', false, 'application/json')).toBeUndefined();
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it('should JSON.parse when content-type is application/json', () => {
|
|
577
|
+
const result = decodeBody('{"name":"test"}', false, 'application/json');
|
|
578
|
+
expect(result).toEqual({ name: 'test' });
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
it('should JSON.parse when content-type includes application/json with charset', () => {
|
|
582
|
+
const result = decodeBody(
|
|
583
|
+
'{"name":"test"}',
|
|
584
|
+
false,
|
|
585
|
+
'application/json; charset=utf-8',
|
|
586
|
+
);
|
|
587
|
+
expect(result).toEqual({ name: 'test' });
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
it('should decode base64 then JSON.parse for base64-encoded JSON', () => {
|
|
591
|
+
const encoded = Buffer.from('{"name":"test"}').toString('base64');
|
|
592
|
+
const result = decodeBody(encoded, true, 'application/json');
|
|
593
|
+
expect(result).toEqual({ name: 'test' });
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('should return raw string for non-JSON content-type', () => {
|
|
597
|
+
const result = decodeBody(
|
|
598
|
+
'amount=100¤cy=ZAR',
|
|
599
|
+
false,
|
|
600
|
+
'application/x-www-form-urlencoded',
|
|
601
|
+
);
|
|
602
|
+
expect(result).toBe('amount=100¤cy=ZAR');
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
it('should decode base64 and return string for non-JSON content-type', () => {
|
|
606
|
+
const encoded = Buffer.from('amount=100¤cy=ZAR').toString('base64');
|
|
607
|
+
const result = decodeBody(
|
|
608
|
+
encoded,
|
|
609
|
+
true,
|
|
610
|
+
'application/x-www-form-urlencoded',
|
|
611
|
+
);
|
|
612
|
+
expect(result).toBe('amount=100¤cy=ZAR');
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
it('should return raw string for text/plain', () => {
|
|
616
|
+
const result = decodeBody('hello world', false, 'text/plain');
|
|
617
|
+
expect(result).toBe('hello world');
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
it('should default to JSON parsing when content-type is undefined', () => {
|
|
621
|
+
const result = decodeBody('{"name":"test"}', false, undefined);
|
|
622
|
+
expect(result).toEqual({ name: 'test' });
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('should not JSON.parse a string that happens to be valid JSON when content-type is not JSON', () => {
|
|
626
|
+
const result = decodeBody('{"looks":"like json"}', false, 'text/plain');
|
|
627
|
+
expect(result).toBe('{"looks":"like json"}');
|
|
628
|
+
});
|
|
629
|
+
});
|
|
@@ -379,6 +379,41 @@ describe('EndpointBuilder', () => {
|
|
|
379
379
|
expect(endpoint.authorize).toBe(customAuth);
|
|
380
380
|
});
|
|
381
381
|
|
|
382
|
+
it('should set authorize via .authorize() method', () => {
|
|
383
|
+
const authFn = () => true;
|
|
384
|
+
const builder = new EndpointBuilder('/test', 'GET');
|
|
385
|
+
const result = builder.authorize(authFn);
|
|
386
|
+
|
|
387
|
+
expect(result).toBe(builder);
|
|
388
|
+
expect((builder as any)._authorize).toBe(authFn);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('should pass .authorize() function to endpoint', () => {
|
|
392
|
+
const authFn = async () => false;
|
|
393
|
+
const endpoint = new EndpointBuilder('/test', 'POST')
|
|
394
|
+
.authorize(authFn)
|
|
395
|
+
.handle(async () => ({}));
|
|
396
|
+
|
|
397
|
+
expect(endpoint.authorize).toBe(authFn);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('should chain .authorize() with body, query, and params', () => {
|
|
401
|
+
const endpoint = new EndpointBuilder('/users/:id', 'POST')
|
|
402
|
+
.body(z.object({ role: z.string() }))
|
|
403
|
+
.query(z.object({ verbose: z.string() }))
|
|
404
|
+
.params(z.object({ id: z.string() }))
|
|
405
|
+
.authorize(({ body, query, params }) => {
|
|
406
|
+
return (
|
|
407
|
+
body.role === 'admin' &&
|
|
408
|
+
params.id !== '' &&
|
|
409
|
+
query.verbose === 'true'
|
|
410
|
+
);
|
|
411
|
+
})
|
|
412
|
+
.handle(async () => ({}));
|
|
413
|
+
|
|
414
|
+
expect(endpoint.authorize).toBeDefined();
|
|
415
|
+
});
|
|
416
|
+
|
|
382
417
|
it('should allow setting custom session extractor', () => {
|
|
383
418
|
const customSession = async () => ({ userId: '123', role: 'admin' });
|
|
384
419
|
const builder = new EndpointBuilder('/test', 'GET');
|
|
@@ -996,6 +996,111 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
996
996
|
const response = await app.request('/protected');
|
|
997
997
|
expect(response.status).toBe(500);
|
|
998
998
|
});
|
|
999
|
+
|
|
1000
|
+
it('should pass body to authorize function', async () => {
|
|
1001
|
+
const authorizeSpy = vi.fn(() => true);
|
|
1002
|
+
const bodySchema = z.object({ role: z.string() });
|
|
1003
|
+
|
|
1004
|
+
const endpoint = new Endpoint({
|
|
1005
|
+
route: '/protected',
|
|
1006
|
+
method: 'POST',
|
|
1007
|
+
fn: async () => ({ success: true }),
|
|
1008
|
+
input: { body: bodySchema },
|
|
1009
|
+
output: z.object({ success: z.boolean() }),
|
|
1010
|
+
services: [],
|
|
1011
|
+
logger: mockLogger,
|
|
1012
|
+
timeout: undefined,
|
|
1013
|
+
memorySize: undefined,
|
|
1014
|
+
status: undefined,
|
|
1015
|
+
getSession: undefined,
|
|
1016
|
+
authorize: authorizeSpy,
|
|
1017
|
+
description: undefined,
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
1021
|
+
const app = new Hono();
|
|
1022
|
+
|
|
1023
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
1024
|
+
|
|
1025
|
+
const response = await app.request('/protected', {
|
|
1026
|
+
method: 'POST',
|
|
1027
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1028
|
+
body: JSON.stringify({ role: 'admin' }),
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1031
|
+
expect(response.status).toBe(200);
|
|
1032
|
+
expect(authorizeSpy).toHaveBeenCalledTimes(1);
|
|
1033
|
+
expect(authorizeSpy.mock.calls[0][0]).toMatchObject({
|
|
1034
|
+
body: { role: 'admin' },
|
|
1035
|
+
});
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
it('should pass params to authorize function', async () => {
|
|
1039
|
+
const authorizeSpy = vi.fn(() => true);
|
|
1040
|
+
const paramsSchema = z.object({ id: z.string() });
|
|
1041
|
+
|
|
1042
|
+
const endpoint = new Endpoint({
|
|
1043
|
+
route: '/resources/:id',
|
|
1044
|
+
method: 'GET',
|
|
1045
|
+
fn: async () => ({ success: true }),
|
|
1046
|
+
input: { params: paramsSchema },
|
|
1047
|
+
output: z.object({ success: z.boolean() }),
|
|
1048
|
+
services: [],
|
|
1049
|
+
logger: mockLogger,
|
|
1050
|
+
timeout: undefined,
|
|
1051
|
+
memorySize: undefined,
|
|
1052
|
+
status: undefined,
|
|
1053
|
+
getSession: undefined,
|
|
1054
|
+
authorize: authorizeSpy,
|
|
1055
|
+
description: undefined,
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
1059
|
+
const app = new Hono();
|
|
1060
|
+
|
|
1061
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
1062
|
+
|
|
1063
|
+
const response = await app.request('/resources/res-42');
|
|
1064
|
+
|
|
1065
|
+
expect(response.status).toBe(200);
|
|
1066
|
+
expect(authorizeSpy).toHaveBeenCalledTimes(1);
|
|
1067
|
+
expect(authorizeSpy.mock.calls[0][0]).toMatchObject({
|
|
1068
|
+
params: { id: 'res-42' },
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
it('should deny request when authorize uses body to reject', async () => {
|
|
1073
|
+
const bodySchema = z.object({ role: z.string() });
|
|
1074
|
+
|
|
1075
|
+
const endpoint = new Endpoint({
|
|
1076
|
+
route: '/admin',
|
|
1077
|
+
method: 'POST',
|
|
1078
|
+
fn: async () => ({ success: true }),
|
|
1079
|
+
input: { body: bodySchema },
|
|
1080
|
+
output: z.object({ success: z.boolean() }),
|
|
1081
|
+
services: [],
|
|
1082
|
+
logger: mockLogger,
|
|
1083
|
+
timeout: undefined,
|
|
1084
|
+
memorySize: undefined,
|
|
1085
|
+
status: undefined,
|
|
1086
|
+
getSession: undefined,
|
|
1087
|
+
authorize: ({ body }: any) => body?.role === 'admin',
|
|
1088
|
+
description: undefined,
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
1092
|
+
const app = new Hono();
|
|
1093
|
+
|
|
1094
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
1095
|
+
|
|
1096
|
+
const response = await app.request('/admin', {
|
|
1097
|
+
method: 'POST',
|
|
1098
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1099
|
+
body: JSON.stringify({ role: 'viewer' }),
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
expect(response.status).toBe(401);
|
|
1103
|
+
});
|
|
999
1104
|
});
|
|
1000
1105
|
|
|
1001
1106
|
describe('output validation', () => {
|