@geekmidas/constructs 3.0.2 → 3.0.5
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-B30TqZRX.d.mts → AmazonApiGatewayEndpointAdaptor-CS-m4WZy.d.mts} +11 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-CS-m4WZy.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-ciUHVvPX.mjs → AmazonApiGatewayEndpointAdaptor-Cmm9d_Po.mjs} +20 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-Cmm9d_Po.mjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-jDYqkgFE.cjs → AmazonApiGatewayEndpointAdaptor-D7mhDtSL.cjs} +20 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-D7mhDtSL.cjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-D4lAuXA-.d.cts → AmazonApiGatewayEndpointAdaptor-DisDeEF0.d.cts} +11 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-DisDeEF0.d.cts.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-B5xFYauV.d.cts → AmazonApiGatewayV1EndpointAdaptor-D6wNqjth.d.cts} +3 -3
- package/dist/AmazonApiGatewayV1EndpointAdaptor-D6wNqjth.d.cts.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CG1UJoAK.d.mts → AmazonApiGatewayV1EndpointAdaptor-DSMe7dZ4.d.mts} +3 -3
- package/dist/AmazonApiGatewayV1EndpointAdaptor-DSMe7dZ4.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CW0BCUkm.cjs → AmazonApiGatewayV1EndpointAdaptor-DstIoQBv.cjs} +4 -4
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CW0BCUkm.cjs.map → AmazonApiGatewayV1EndpointAdaptor-DstIoQBv.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-COLHHAsd.mjs → AmazonApiGatewayV1EndpointAdaptor-zrlehWUG.mjs} +4 -4
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-COLHHAsd.mjs.map → AmazonApiGatewayV1EndpointAdaptor-zrlehWUG.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-ofjuxcPV.d.mts → AmazonApiGatewayV2EndpointAdaptor-ByljgCnY.d.mts} +3 -3
- package/dist/AmazonApiGatewayV2EndpointAdaptor-ByljgCnY.d.mts.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-C7ZrwcTX.cjs → AmazonApiGatewayV2EndpointAdaptor-DaAHSnqs.cjs} +7 -9
- package/dist/AmazonApiGatewayV2EndpointAdaptor-DaAHSnqs.cjs.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-Cl9ERGyi.mjs → AmazonApiGatewayV2EndpointAdaptor-Dj5v-I6S.mjs} +6 -9
- package/dist/AmazonApiGatewayV2EndpointAdaptor-Dj5v-I6S.mjs.map +1 -0
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-OkwjABOz.d.cts → AmazonApiGatewayV2EndpointAdaptor-PcMFUEF9.d.cts} +3 -3
- package/dist/AmazonApiGatewayV2EndpointAdaptor-PcMFUEF9.d.cts.map +1 -0
- package/dist/{Endpoint-BiPM0glm.d.mts → Endpoint-BIvS-rKH.d.mts} +6 -6
- package/dist/Endpoint-BIvS-rKH.d.mts.map +1 -0
- package/dist/{Endpoint-C9N6CmvB.d.cts → Endpoint-BPh52sXZ.d.cts} +6 -6
- package/dist/Endpoint-BPh52sXZ.d.cts.map +1 -0
- package/dist/Endpoint-BcxvF4F3.cjs.map +1 -1
- package/dist/Endpoint-DvY3aqAy.mjs.map +1 -1
- package/dist/{EndpointBuilder-B0Aj5jbB.d.mts → EndpointBuilder-3xH8Gllw.d.mts} +4 -3
- package/dist/EndpointBuilder-3xH8Gllw.d.mts.map +1 -0
- package/dist/{EndpointBuilder-Bel6RS7W.d.cts → EndpointBuilder-BmVTFp1A.d.cts} +4 -3
- package/dist/EndpointBuilder-BmVTFp1A.d.cts.map +1 -0
- package/dist/{EndpointBuilder-D1RtrBu1.mjs → EndpointBuilder-CMzbGG2c.mjs} +5 -1
- package/dist/{EndpointBuilder-D1RtrBu1.mjs.map → EndpointBuilder-CMzbGG2c.mjs.map} +1 -1
- package/dist/{EndpointBuilder-fXmTxRyW.cjs → EndpointBuilder-QdDf3x87.cjs} +5 -1
- package/dist/{EndpointBuilder-fXmTxRyW.cjs.map → EndpointBuilder-QdDf3x87.cjs.map} +1 -1
- package/dist/{EndpointFactory-DBfTbSTX.cjs → EndpointFactory-AsfUsn-v.cjs} +2 -2
- package/dist/{EndpointFactory-DBfTbSTX.cjs.map → EndpointFactory-AsfUsn-v.cjs.map} +1 -1
- package/dist/{EndpointFactory-DkB8yxdQ.mjs → EndpointFactory-CkPaFZA0.mjs} +2 -2
- package/dist/{EndpointFactory-DkB8yxdQ.mjs.map → EndpointFactory-CkPaFZA0.mjs.map} +1 -1
- package/dist/{EndpointFactory-CWIeWCRG.d.mts → EndpointFactory-DKHnUYl8.d.mts} +3 -3
- package/dist/{EndpointFactory-CXvakOkn.d.cts.map → EndpointFactory-DKHnUYl8.d.mts.map} +1 -1
- package/dist/{EndpointFactory-CXvakOkn.d.cts → EndpointFactory-DaDXPRAg.d.cts} +3 -3
- package/dist/{EndpointFactory-CWIeWCRG.d.mts.map → EndpointFactory-DaDXPRAg.d.cts.map} +1 -1
- package/dist/{HonoEndpointAdaptor-C3AdQ0xS.d.mts → HonoEndpointAdaptor-Cb45sqM9.d.mts} +4 -4
- package/dist/{HonoEndpointAdaptor-BCql3gLP.d.cts.map → HonoEndpointAdaptor-Cb45sqM9.d.mts.map} +1 -1
- package/dist/{HonoEndpointAdaptor-y9fCIxaz.mjs → HonoEndpointAdaptor-D7N5oiO0.mjs} +6 -3
- package/dist/HonoEndpointAdaptor-D7N5oiO0.mjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-CavBd6P2.cjs → HonoEndpointAdaptor-Jbptyuxv.cjs} +6 -3
- package/dist/HonoEndpointAdaptor-Jbptyuxv.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-BCql3gLP.d.cts → HonoEndpointAdaptor-VStaYQHr.d.cts} +2 -2
- package/dist/{HonoEndpointAdaptor-C3AdQ0xS.d.mts.map → HonoEndpointAdaptor-VStaYQHr.d.cts.map} +1 -1
- package/dist/{TestEndpointAdaptor-DjQSuxRq.cjs → TestEndpointAdaptor-BKoJpTGT.cjs} +5 -2
- package/dist/TestEndpointAdaptor-BKoJpTGT.cjs.map +1 -0
- package/dist/{TestEndpointAdaptor-qSWV8dpS.d.mts → TestEndpointAdaptor-Bt-uW6SC.d.mts} +2 -2
- package/dist/{TestEndpointAdaptor-CCf3Dg0u.d.cts.map → TestEndpointAdaptor-Bt-uW6SC.d.mts.map} +1 -1
- package/dist/{TestEndpointAdaptor-CDOhCmIk.mjs → TestEndpointAdaptor-DHVaHmhw.mjs} +5 -2
- package/dist/TestEndpointAdaptor-DHVaHmhw.mjs.map +1 -0
- package/dist/{TestEndpointAdaptor-CCf3Dg0u.d.cts → TestEndpointAdaptor-UKhHj1RR.d.cts} +2 -2
- package/dist/{TestEndpointAdaptor-qSWV8dpS.d.mts.map → TestEndpointAdaptor-UKhHj1RR.d.cts.map} +1 -1
- package/dist/adaptors/aws.cjs +4 -4
- package/dist/adaptors/aws.d.cts +5 -5
- package/dist/adaptors/aws.d.mts +5 -5
- package/dist/adaptors/aws.mjs +4 -4
- package/dist/adaptors/hono.cjs +2 -2
- package/dist/adaptors/hono.d.cts +3 -3
- package/dist/adaptors/hono.d.mts +3 -3
- package/dist/adaptors/hono.mjs +2 -2
- 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.d.cts +1 -1
- package/dist/crons/Cron.d.mts +1 -1
- package/dist/crons/CronBuilder.d.cts +1 -1
- package/dist/crons/CronBuilder.d.mts +1 -1
- package/dist/crons/index.d.cts +5 -5
- package/dist/crons/index.d.mts +5 -5
- 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 +3 -3
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +4 -4
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +3 -3
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +2 -3
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +4 -4
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +2 -3
- package/dist/endpoints/Endpoint.d.cts +2 -2
- package/dist/endpoints/Endpoint.d.mts +2 -2
- package/dist/endpoints/EndpointBuilder.cjs +1 -1
- package/dist/endpoints/EndpointBuilder.d.cts +3 -3
- package/dist/endpoints/EndpointBuilder.d.mts +3 -3
- package/dist/endpoints/EndpointBuilder.mjs +1 -1
- package/dist/endpoints/EndpointFactory.cjs +2 -2
- package/dist/endpoints/EndpointFactory.d.cts +4 -4
- package/dist/endpoints/EndpointFactory.d.mts +4 -4
- package/dist/endpoints/EndpointFactory.mjs +2 -2
- package/dist/endpoints/HonoEndpointAdaptor.cjs +2 -2
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +3 -3
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +3 -3
- package/dist/endpoints/HonoEndpointAdaptor.mjs +2 -2
- 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 +2 -2
- package/dist/endpoints/index.d.cts +7 -7
- package/dist/endpoints/index.d.mts +7 -7
- package/dist/endpoints/index.mjs +2 -2
- package/dist/endpoints/lazyAccessors.d.cts +3 -3
- package/dist/endpoints/lazyAccessors.d.mts +3 -3
- package/dist/endpoints/parseHonoQuery.cjs +1 -1
- package/dist/endpoints/parseHonoQuery.d.cts +2 -2
- package/dist/endpoints/parseHonoQuery.d.cts.map +1 -1
- package/dist/endpoints/parseHonoQuery.d.mts +2 -2
- package/dist/endpoints/parseHonoQuery.d.mts.map +1 -1
- package/dist/endpoints/parseHonoQuery.mjs +1 -1
- package/dist/endpoints/parseQueryParams.cjs +1 -1
- package/dist/endpoints/parseQueryParams.d.cts +2 -2
- package/dist/endpoints/parseQueryParams.d.cts.map +1 -1
- package/dist/endpoints/parseQueryParams.d.mts +2 -2
- package/dist/endpoints/parseQueryParams.d.mts.map +1 -1
- package/dist/endpoints/parseQueryParams.mjs +1 -1
- package/dist/endpoints/processAudits.d.cts +2 -2
- package/dist/endpoints/processAudits.d.mts +2 -2
- package/dist/endpoints/rls.d.cts +2 -2
- package/dist/endpoints/rls.d.mts +2 -2
- 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-BRoc67OX.d.cts.map → index-BfeupgMl.d.cts.map} +1 -1
- package/dist/index-CtMNRkV7.d.mts +12 -0
- package/dist/{index-_5DYCNAt.d.mts.map → index-CtMNRkV7.d.mts.map} +1 -1
- package/dist/{lazyAccessors-DXkJpnyX.d.mts → lazyAccessors-Ba8HxeIC.d.cts} +2 -2
- package/dist/{lazyAccessors-DXkJpnyX.d.mts.map → lazyAccessors-Ba8HxeIC.d.cts.map} +1 -1
- package/dist/{lazyAccessors-DdZaA716.d.cts → lazyAccessors-D9tzUZaz.d.mts} +2 -2
- package/dist/{lazyAccessors-DdZaA716.d.cts.map → lazyAccessors-D9tzUZaz.d.mts.map} +1 -1
- package/dist/parseHonoQuery-BBs8CX-H.cjs +24 -0
- package/dist/parseHonoQuery-BBs8CX-H.cjs.map +1 -0
- package/dist/parseHonoQuery-Cp8CII0P.mjs +18 -0
- package/dist/parseHonoQuery-Cp8CII0P.mjs.map +1 -0
- package/dist/parseQueryParams-B4RK1za3.cjs +31 -0
- package/dist/parseQueryParams-B4RK1za3.cjs.map +1 -0
- package/dist/parseQueryParams-DS3Qmrbd.mjs +25 -0
- package/dist/parseQueryParams-DS3Qmrbd.mjs.map +1 -0
- package/dist/subscribers/index.d.cts +2 -2
- package/dist/subscribers/index.d.mts +2 -2
- package/dist/subscribers/index.d.mts.map +1 -1
- package/package.json +15 -13
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +32 -1
- package/src/endpoints/AmazonApiGatewayV1EndpointAdaptor.ts +5 -1
- package/src/endpoints/AmazonApiGatewayV2EndpointAdaptor.ts +8 -18
- package/src/endpoints/Endpoint.ts +7 -4
- package/src/endpoints/EndpointBuilder.ts +6 -1
- package/src/endpoints/EndpointFactory.ts +1 -1
- package/src/endpoints/HonoEndpointAdaptor.ts +9 -0
- package/src/endpoints/TestEndpointAdaptor.ts +3 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +119 -7
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +4 -2
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +146 -7
- package/src/endpoints/__tests__/EndpointBuilder.spec.ts +35 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +109 -4
- package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +139 -0
- package/src/endpoints/parseHonoQuery.ts +9 -46
- package/src/endpoints/parseQueryParams.ts +12 -33
- 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-C7ZrwcTX.cjs.map +0 -1
- package/dist/AmazonApiGatewayV2EndpointAdaptor-Cl9ERGyi.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/HonoEndpointAdaptor-CavBd6P2.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-y9fCIxaz.mjs.map +0 -1
- package/dist/TestEndpointAdaptor-CDOhCmIk.mjs.map +0 -1
- package/dist/TestEndpointAdaptor-DjQSuxRq.cjs.map +0 -1
- package/dist/index-BRoc67OX.d.cts +0 -12
- package/dist/index-_5DYCNAt.d.mts +0 -12
- package/dist/parseHonoQuery-D4MhxTRc.cjs +0 -39
- package/dist/parseHonoQuery-D4MhxTRc.cjs.map +0 -1
- package/dist/parseHonoQuery-DpK3sGPc.mjs +0 -33
- package/dist/parseHonoQuery-DpK3sGPc.mjs.map +0 -1
- package/dist/parseQueryParams-BSNkjmZ9.cjs +0 -40
- package/dist/parseQueryParams-BSNkjmZ9.cjs.map +0 -1
- package/dist/parseQueryParams-UMTRnRrW.mjs +0 -34
- package/dist/parseQueryParams-UMTRnRrW.mjs.map +0 -1
|
@@ -59,7 +59,11 @@ export class AmazonApiGatewayV1Endpoint<
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
return {
|
|
62
|
-
body:
|
|
62
|
+
body: AmazonApiGatewayEndpoint.decodeBody(
|
|
63
|
+
e.body,
|
|
64
|
+
e.isBase64Encoded,
|
|
65
|
+
e.headers?.['Content-Type'] ?? e.headers?.['content-type'],
|
|
66
|
+
),
|
|
63
67
|
query: parseQueryParams(mergedParams),
|
|
64
68
|
params: e.pathParameters || {},
|
|
65
69
|
};
|
|
@@ -4,6 +4,7 @@ import type { Logger } from '@geekmidas/logger';
|
|
|
4
4
|
import type { Service } from '@geekmidas/services';
|
|
5
5
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
6
|
import type { APIGatewayProxyEventV2, Context } from 'aws-lambda';
|
|
7
|
+
import qs from 'qs';
|
|
7
8
|
import type { HttpMethod } from '../types';
|
|
8
9
|
import {
|
|
9
10
|
AmazonApiGatewayEndpoint,
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
} from './AmazonApiGatewayEndpointAdaptor';
|
|
15
16
|
import type { CookieFn, Endpoint, EndpointSchemas } from './Endpoint';
|
|
16
17
|
import { createApiGatewayCookies } from './lazyAccessors';
|
|
17
|
-
import { parseQueryParams } from './parseQueryParams';
|
|
18
18
|
|
|
19
19
|
export class AmazonApiGatewayV2Endpoint<
|
|
20
20
|
TRoute extends string,
|
|
@@ -45,25 +45,15 @@ export class AmazonApiGatewayV2Endpoint<
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
override getInput(e: APIGatewayProxyEventV2): GetInputResponse {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (value !== undefined) {
|
|
54
|
-
// Check if value contains comma and could be an array
|
|
55
|
-
// Be careful not to split values that legitimately contain commas
|
|
56
|
-
if (value.includes(',') && !value.includes('"')) {
|
|
57
|
-
processedParams[key] = value.split(',').map((v) => v.trim());
|
|
58
|
-
} else {
|
|
59
|
-
processedParams[key] = value;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
48
|
+
const raw = AmazonApiGatewayEndpoint.decodeBody(
|
|
49
|
+
e.body,
|
|
50
|
+
e.isBase64Encoded,
|
|
51
|
+
e.headers?.['content-type'],
|
|
52
|
+
);
|
|
63
53
|
|
|
64
54
|
return {
|
|
65
|
-
body:
|
|
66
|
-
query:
|
|
55
|
+
body: raw,
|
|
56
|
+
query: qs.parse(e.rawQueryString) as Record<string, any>,
|
|
67
57
|
params: e.pathParameters || {},
|
|
68
58
|
};
|
|
69
59
|
}
|
|
@@ -113,7 +113,8 @@ export class Endpoint<
|
|
|
113
113
|
public getSession: SessionFn<TServices, TLogger, TSession, TDatabase> = () =>
|
|
114
114
|
({}) as TSession;
|
|
115
115
|
/** Function to determine if the request is authorized */
|
|
116
|
-
public authorize: AuthorizeFn<TServices, TLogger, TSession> = () =>
|
|
116
|
+
public authorize: AuthorizeFn<TServices, TLogger, TSession, TInput> = () =>
|
|
117
|
+
true;
|
|
117
118
|
/** Optional rate limiting configuration */
|
|
118
119
|
public rateLimit?: RateLimitConfig;
|
|
119
120
|
/** Optional authorizer for this endpoint */
|
|
@@ -749,7 +750,7 @@ export interface EndpointOptions<
|
|
|
749
750
|
TAuditAction
|
|
750
751
|
>;
|
|
751
752
|
/** Optional authorization check function */
|
|
752
|
-
authorize: AuthorizeFn<TServices, TLogger, TSession> | undefined;
|
|
753
|
+
authorize: AuthorizeFn<TServices, TLogger, TSession, TInput> | undefined;
|
|
753
754
|
/** Optional description for documentation */
|
|
754
755
|
description: string | undefined;
|
|
755
756
|
/** Optional tags for OpenAPI documentation */
|
|
@@ -813,13 +814,14 @@ export type AuthorizeContext<
|
|
|
813
814
|
TServices extends Service[] = [],
|
|
814
815
|
TLogger extends Logger = Logger,
|
|
815
816
|
TSession = unknown,
|
|
817
|
+
TInput extends EndpointSchemas | undefined = undefined,
|
|
816
818
|
> = {
|
|
817
819
|
services: ServiceRecord<TServices>;
|
|
818
820
|
logger: TLogger;
|
|
819
821
|
header: HeaderFn;
|
|
820
822
|
cookie: CookieFn;
|
|
821
823
|
session: TSession;
|
|
822
|
-
}
|
|
824
|
+
} & InferComposableStandardSchema<TInput>;
|
|
823
825
|
/**
|
|
824
826
|
* Function type for endpoint authorization checks.
|
|
825
827
|
*
|
|
@@ -841,8 +843,9 @@ export type AuthorizeFn<
|
|
|
841
843
|
TServices extends Service[] = [],
|
|
842
844
|
TLogger extends Logger = Logger,
|
|
843
845
|
TSession = unknown,
|
|
846
|
+
TInput extends EndpointSchemas | undefined = undefined,
|
|
844
847
|
> = (
|
|
845
|
-
ctx: AuthorizeContext<TServices, TLogger, TSession>,
|
|
848
|
+
ctx: AuthorizeContext<TServices, TLogger, TSession, TInput>,
|
|
846
849
|
) => Promise<boolean> | boolean;
|
|
847
850
|
|
|
848
851
|
/**
|
|
@@ -63,7 +63,7 @@ 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> = () => true;
|
|
66
|
+
_authorize: AuthorizeFn<TServices, TLogger, TSession, TInput> = () => true;
|
|
67
67
|
_rateLimit?: RateLimitConfig;
|
|
68
68
|
_availableAuthorizers: Authorizer[] = [];
|
|
69
69
|
_authorizerName?: TAuthorizers[number];
|
|
@@ -263,6 +263,11 @@ export class EndpointBuilder<
|
|
|
263
263
|
return this;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
authorize(fn: AuthorizeFn<TServices, TLogger, TSession, TInput>): this {
|
|
267
|
+
this._authorize = fn;
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
|
|
266
271
|
rateLimit(config: RateLimitConfig): this {
|
|
267
272
|
this._rateLimit = config;
|
|
268
273
|
return this;
|
|
@@ -988,7 +988,7 @@ export class EndpointFactory<
|
|
|
988
988
|
>(fullPath, method);
|
|
989
989
|
|
|
990
990
|
if (this.defaultAuthorizeFn) {
|
|
991
|
-
builder._authorize = this.defaultAuthorizeFn;
|
|
991
|
+
builder._authorize = this.defaultAuthorizeFn as any;
|
|
992
992
|
}
|
|
993
993
|
if (this.defaultServices.length) {
|
|
994
994
|
// Create a copy to avoid sharing references between builders
|
|
@@ -393,6 +393,15 @@ export class HonoEndpoint<
|
|
|
393
393
|
services,
|
|
394
394
|
logger,
|
|
395
395
|
session,
|
|
396
|
+
body: features.hasBodyValidation
|
|
397
|
+
? (c.req.valid as any)('json')
|
|
398
|
+
: undefined,
|
|
399
|
+
query: features.hasQueryValidation
|
|
400
|
+
? (c.req.valid as any)('query')
|
|
401
|
+
: undefined,
|
|
402
|
+
params: features.hasParamValidation
|
|
403
|
+
? (c.req.valid as any)('param')
|
|
404
|
+
: undefined,
|
|
396
405
|
});
|
|
397
406
|
|
|
398
407
|
if (!isAuthorized) {
|
|
@@ -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({
|
|
@@ -775,7 +887,7 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
775
887
|
});
|
|
776
888
|
|
|
777
889
|
describe('combined inputs', () => {
|
|
778
|
-
it('should handle array query parameters', async () => {
|
|
890
|
+
it('should handle array query parameters with bracket notation', async () => {
|
|
779
891
|
const querySchema = z.object({
|
|
780
892
|
tags: z.array(z.string()),
|
|
781
893
|
page: z.coerce.number().default(1),
|
|
@@ -808,9 +920,9 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
808
920
|
const handler = adapter.handler;
|
|
809
921
|
|
|
810
922
|
const event = createMockV1Event({
|
|
811
|
-
queryStringParameters: { tags: 'nodejs', page: '2' },
|
|
923
|
+
queryStringParameters: { 'tags[]': 'nodejs', page: '2' },
|
|
812
924
|
multiValueQueryStringParameters: {
|
|
813
|
-
tags: ['nodejs', 'typescript', 'javascript'],
|
|
925
|
+
'tags[]': ['nodejs', 'typescript', 'javascript'],
|
|
814
926
|
page: ['2'],
|
|
815
927
|
},
|
|
816
928
|
});
|
|
@@ -825,7 +937,7 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
825
937
|
});
|
|
826
938
|
});
|
|
827
939
|
|
|
828
|
-
it('should handle object query parameters with
|
|
940
|
+
it('should handle object query parameters with bracket notation', async () => {
|
|
829
941
|
const querySchema = z.object({
|
|
830
942
|
filter: z.object({
|
|
831
943
|
name: z.string(),
|
|
@@ -867,9 +979,9 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
867
979
|
|
|
868
980
|
const event = createMockV1Event({
|
|
869
981
|
queryStringParameters: {
|
|
870
|
-
'filter
|
|
871
|
-
'filter
|
|
872
|
-
'filter
|
|
982
|
+
'filter[name]': 'john',
|
|
983
|
+
'filter[status]': 'active',
|
|
984
|
+
'filter[priority]': '1',
|
|
873
985
|
sort: 'priority',
|
|
874
986
|
},
|
|
875
987
|
});
|
|
@@ -635,7 +635,7 @@ describe('AmazonApiGatewayV2Endpoint Events', () => {
|
|
|
635
635
|
expect(mockPublisher.publish).not.toHaveBeenCalled();
|
|
636
636
|
});
|
|
637
637
|
|
|
638
|
-
it('should handle
|
|
638
|
+
it('should handle bracket notation array query parameters', async () => {
|
|
639
639
|
const mockPublisher: EventPublisher<TestEvent> = {
|
|
640
640
|
publish: vi.fn().mockResolvedValue(undefined),
|
|
641
641
|
};
|
|
@@ -702,8 +702,10 @@ describe('AmazonApiGatewayV2Endpoint Events', () => {
|
|
|
702
702
|
},
|
|
703
703
|
},
|
|
704
704
|
pathParameters: { id: '123' },
|
|
705
|
+
rawQueryString:
|
|
706
|
+
'tags%5B%5D=javascript&tags%5B%5D=typescript&tags%5B%5D=nodejs',
|
|
705
707
|
queryStringParameters: {
|
|
706
|
-
tags: 'javascript,
|
|
708
|
+
'tags[]': 'javascript,typescript,nodejs',
|
|
707
709
|
},
|
|
708
710
|
});
|
|
709
711
|
const context = createMockContext();
|
|
@@ -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);
|
|
@@ -139,7 +212,7 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
139
212
|
});
|
|
140
213
|
});
|
|
141
214
|
|
|
142
|
-
it('should handle array query parameters
|
|
215
|
+
it('should handle array query parameters with bracket notation', async () => {
|
|
143
216
|
const endpoint = e
|
|
144
217
|
.get('/search')
|
|
145
218
|
.query(
|
|
@@ -164,9 +237,10 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
164
237
|
const event = createMockV2Event({
|
|
165
238
|
routeKey: 'GET /search',
|
|
166
239
|
rawPath: '/search',
|
|
167
|
-
rawQueryString:
|
|
240
|
+
rawQueryString:
|
|
241
|
+
'tags%5B%5D=nodejs&tags%5B%5D=typescript&tags%5B%5D=javascript&limit=20',
|
|
168
242
|
queryStringParameters: {
|
|
169
|
-
tags: 'nodejs,typescript,javascript',
|
|
243
|
+
'tags[]': 'nodejs,typescript,javascript',
|
|
170
244
|
limit: '20',
|
|
171
245
|
},
|
|
172
246
|
});
|
|
@@ -182,7 +256,7 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
182
256
|
});
|
|
183
257
|
});
|
|
184
258
|
|
|
185
|
-
it('should handle object query parameters with
|
|
259
|
+
it('should handle object query parameters with bracket notation', async () => {
|
|
186
260
|
const endpoint = e
|
|
187
261
|
.get('/search')
|
|
188
262
|
.query(
|
|
@@ -210,10 +284,11 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
210
284
|
const event = createMockV2Event({
|
|
211
285
|
routeKey: 'GET /search',
|
|
212
286
|
rawPath: '/search',
|
|
213
|
-
rawQueryString:
|
|
287
|
+
rawQueryString:
|
|
288
|
+
'filter%5Bcategory%5D=electronics&filter%5Bactive%5D=true',
|
|
214
289
|
queryStringParameters: {
|
|
215
|
-
'filter
|
|
216
|
-
'filter
|
|
290
|
+
'filter[category]': 'electronics',
|
|
291
|
+
'filter[active]': 'true',
|
|
217
292
|
},
|
|
218
293
|
});
|
|
219
294
|
|
|
@@ -488,3 +563,67 @@ describe('AmazonApiGatewayV2Endpoint', () => {
|
|
|
488
563
|
});
|
|
489
564
|
});
|
|
490
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');
|