@geekmidas/constructs 0.0.1
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 +614 -0
- package/dist/AWSLambdaFunction-CpHFE2m6.d.mts +27 -0
- package/dist/AWSLambdaFunction-CwagvPG3.d.cts +27 -0
- package/dist/AWSLambdaFunction-DWIZYsCy.mjs +79 -0
- package/dist/AWSLambdaFunction-DWIZYsCy.mjs.map +1 -0
- package/dist/AWSLambdaFunction-qA5LqPsv.cjs +85 -0
- package/dist/AWSLambdaFunction-qA5LqPsv.cjs.map +1 -0
- package/dist/AWSLambdaSubscriberAdaptor-C1wQuucQ.d.mts +32 -0
- package/dist/AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs +138 -0
- package/dist/AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs.map +1 -0
- package/dist/AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs +132 -0
- package/dist/AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs.map +1 -0
- package/dist/AWSLambdaSubscriberAdaptor-QKVxR6qh.d.cts +32 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-BoBh7vvD.d.mts +61 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-Cx1oqcqh.mjs +124 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-Cx1oqcqh.mjs.map +1 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-DtzgQ9Vb.d.cts +61 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-i74DEUbc.cjs +130 -0
- package/dist/AmazonApiGatewayEndpointAdaptor-i74DEUbc.cjs.map +1 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-CLmBDYsl.mjs +42 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-CLmBDYsl.mjs.map +1 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-EhMd1YqV.d.mts +21 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-GkMAUPL5.cjs +47 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-GkMAUPL5.cjs.map +1 -0
- package/dist/AmazonApiGatewayV1EndpointAdaptor-Gw-j61qM.d.cts +21 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-3RqegmJC.mjs +41 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-3RqegmJC.mjs.map +1 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-LUlpwmUW.d.cts +21 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-YlFoFSS9.cjs +46 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-YlFoFSS9.cjs.map +1 -0
- package/dist/AmazonApiGatewayV2EndpointAdaptor-zfd1gqXA.d.mts +21 -0
- package/dist/BaseFunctionBuilder-5QCHkchp.d.cts +31 -0
- package/dist/BaseFunctionBuilder-BFPVGnKi.d.mts +31 -0
- package/dist/BaseFunctionBuilder-BPE9JBbT.mjs +56 -0
- package/dist/BaseFunctionBuilder-BPE9JBbT.mjs.map +1 -0
- package/dist/BaseFunctionBuilder-DtO4Nwxm.cjs +62 -0
- package/dist/BaseFunctionBuilder-DtO4Nwxm.cjs.map +1 -0
- package/dist/Construct-BSEs6uwW.cjs +75 -0
- package/dist/Construct-BSEs6uwW.cjs.map +1 -0
- package/dist/Construct-BbKCIPQm.mjs +63 -0
- package/dist/Construct-BbKCIPQm.mjs.map +1 -0
- package/dist/Construct-Bm-PSO2V.d.cts +42 -0
- package/dist/Construct-DIguIyw4.d.mts +42 -0
- package/dist/Construct.cjs +4 -0
- package/dist/Construct.d.cts +2 -0
- package/dist/Construct.d.mts +2 -0
- package/dist/Construct.mjs +3 -0
- package/dist/Cron-Bgs6EQOb.mjs +20 -0
- package/dist/Cron-Bgs6EQOb.mjs.map +1 -0
- package/dist/Cron-DQiCj3ef.cjs +25 -0
- package/dist/Cron-DQiCj3ef.cjs.map +1 -0
- package/dist/Cron-FpAw03k6.d.mts +25 -0
- package/dist/Cron-ztnK6zgU.d.cts +25 -0
- package/dist/CronBuilder-B2clNQSP.d.mts +24 -0
- package/dist/CronBuilder-Cje9K8lZ.d.cts +24 -0
- package/dist/CronBuilder-DIBqJkh_.cjs +60 -0
- package/dist/CronBuilder-DIBqJkh_.cjs.map +1 -0
- package/dist/CronBuilder-DecAvvcn.mjs +54 -0
- package/dist/CronBuilder-DecAvvcn.mjs.map +1 -0
- package/dist/Endpoint-BaHC9y4Z.cjs +291 -0
- package/dist/Endpoint-BaHC9y4Z.cjs.map +1 -0
- package/dist/Endpoint-C7z9YJHK.d.cts +405 -0
- package/dist/Endpoint-DCn53Vd8.d.mts +405 -0
- package/dist/Endpoint-ierdM62O.mjs +279 -0
- package/dist/Endpoint-ierdM62O.mjs.map +1 -0
- package/dist/EndpointBuilder-BHFSpbPR.cjs +107 -0
- package/dist/EndpointBuilder-BHFSpbPR.cjs.map +1 -0
- package/dist/EndpointBuilder-BLUsoK3l.mjs +101 -0
- package/dist/EndpointBuilder-BLUsoK3l.mjs.map +1 -0
- package/dist/EndpointBuilder-Bfnb2oJr.d.mts +49 -0
- package/dist/EndpointBuilder-CP9RGwZH.d.cts +49 -0
- package/dist/EndpointFactory-BYdDVCNj.mjs +127 -0
- package/dist/EndpointFactory-BYdDVCNj.mjs.map +1 -0
- package/dist/EndpointFactory-CNtMXgIh.d.mts +52 -0
- package/dist/EndpointFactory-CXX4E6Gx.cjs +139 -0
- package/dist/EndpointFactory-CXX4E6Gx.cjs.map +1 -0
- package/dist/EndpointFactory-D2zgWbXZ.d.cts +52 -0
- package/dist/Function-BP58p9Mp.d.cts +59 -0
- package/dist/Function-BsBxc2wA.d.mts +59 -0
- package/dist/Function-C5mW-38v.mjs +72 -0
- package/dist/Function-C5mW-38v.mjs.map +1 -0
- package/dist/Function-CbO2NZx-.cjs +84 -0
- package/dist/Function-CbO2NZx-.cjs.map +1 -0
- package/dist/FunctionBuilder-BS1KgxA_.d.cts +24 -0
- package/dist/FunctionBuilder-C-PfPN3r.d.mts +24 -0
- package/dist/FunctionBuilder-CosgPmMl.mjs +53 -0
- package/dist/FunctionBuilder-CosgPmMl.mjs.map +1 -0
- package/dist/FunctionBuilder-DuOeWCAl.cjs +59 -0
- package/dist/FunctionBuilder-DuOeWCAl.cjs.map +1 -0
- package/dist/FunctionExecutionWrapper-Bx-Dl-2a.d.cts +24 -0
- package/dist/FunctionExecutionWrapper-CElXEjPe.cjs +42 -0
- package/dist/FunctionExecutionWrapper-CElXEjPe.cjs.map +1 -0
- package/dist/FunctionExecutionWrapper-DvglBBjE.d.mts +24 -0
- package/dist/FunctionExecutionWrapper-XGrSAAPD.mjs +36 -0
- package/dist/FunctionExecutionWrapper-XGrSAAPD.mjs.map +1 -0
- package/dist/HonoEndpointAdaptor-B0IO1zj2.d.mts +41 -0
- package/dist/HonoEndpointAdaptor-B4snrp7v.cjs +154 -0
- package/dist/HonoEndpointAdaptor-B4snrp7v.cjs.map +1 -0
- package/dist/HonoEndpointAdaptor-B6lW9Q1k.d.cts +41 -0
- package/dist/HonoEndpointAdaptor-D-M4-6Tf.mjs +148 -0
- package/dist/HonoEndpointAdaptor-D-M4-6Tf.mjs.map +1 -0
- package/dist/Subscriber-BoFm12i_.d.cts +33 -0
- package/dist/Subscriber-BwuCaC9G.mjs +28 -0
- package/dist/Subscriber-BwuCaC9G.mjs.map +1 -0
- package/dist/Subscriber-THGsj7Iy.d.mts +33 -0
- package/dist/Subscriber-iMRFG7ba.cjs +34 -0
- package/dist/Subscriber-iMRFG7ba.cjs.map +1 -0
- package/dist/SubscriberBuilder-CiPxgnKT.d.mts +26 -0
- package/dist/SubscriberBuilder-Dhz0C_t-.mjs +54 -0
- package/dist/SubscriberBuilder-Dhz0C_t-.mjs.map +1 -0
- package/dist/SubscriberBuilder-DuIgxuzc.d.cts +26 -0
- package/dist/SubscriberBuilder-wthr-FL9.cjs +60 -0
- package/dist/SubscriberBuilder-wthr-FL9.cjs.map +1 -0
- package/dist/adaptors/aws.cjs +19 -0
- package/dist/adaptors/aws.d.cts +15 -0
- package/dist/adaptors/aws.d.mts +15 -0
- package/dist/adaptors/aws.mjs +16 -0
- package/dist/adaptors/hono.cjs +12 -0
- package/dist/adaptors/hono.d.cts +9 -0
- package/dist/adaptors/hono.d.mts +9 -0
- package/dist/adaptors/hono.mjs +12 -0
- package/dist/chunk-CUT6urMc.cjs +30 -0
- package/dist/crons/Cron.cjs +8 -0
- package/dist/crons/Cron.d.cts +7 -0
- package/dist/crons/Cron.d.mts +7 -0
- package/dist/crons/Cron.mjs +8 -0
- package/dist/crons/CronBuilder.cjs +9 -0
- package/dist/crons/CronBuilder.d.cts +8 -0
- package/dist/crons/CronBuilder.d.mts +8 -0
- package/dist/crons/CronBuilder.mjs +9 -0
- package/dist/crons/index.cjs +16 -0
- package/dist/crons/index.cjs.map +1 -0
- package/dist/crons/index.d.cts +16 -0
- package/dist/crons/index.d.mts +16 -0
- package/dist/crons/index.mjs +14 -0
- package/dist/crons/index.mjs.map +1 -0
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +10 -0
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +9 -0
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +9 -0
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +10 -0
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +12 -0
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +10 -0
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +10 -0
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +12 -0
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +12 -0
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +10 -0
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +10 -0
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +12 -0
- package/dist/endpoints/Endpoint.cjs +9 -0
- package/dist/endpoints/Endpoint.d.cts +8 -0
- package/dist/endpoints/Endpoint.d.mts +8 -0
- package/dist/endpoints/Endpoint.mjs +8 -0
- package/dist/endpoints/EndpointBuilder.cjs +9 -0
- package/dist/endpoints/EndpointBuilder.d.cts +9 -0
- package/dist/endpoints/EndpointBuilder.d.mts +9 -0
- package/dist/endpoints/EndpointBuilder.mjs +9 -0
- package/dist/endpoints/EndpointFactory.cjs +11 -0
- package/dist/endpoints/EndpointFactory.d.cts +10 -0
- package/dist/endpoints/EndpointFactory.d.mts +10 -0
- package/dist/endpoints/EndpointFactory.mjs +10 -0
- package/dist/endpoints/HonoEndpointAdaptor.cjs +12 -0
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +9 -0
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +9 -0
- package/dist/endpoints/HonoEndpointAdaptor.mjs +12 -0
- package/dist/endpoints/TestEndpointAdaptor.cjs +54 -0
- package/dist/endpoints/TestEndpointAdaptor.cjs.map +1 -0
- package/dist/endpoints/TestEndpointAdaptor.d.cts +29 -0
- package/dist/endpoints/TestEndpointAdaptor.d.mts +29 -0
- package/dist/endpoints/TestEndpointAdaptor.mjs +53 -0
- package/dist/endpoints/TestEndpointAdaptor.mjs.map +1 -0
- package/dist/endpoints/helpers.cjs +10 -0
- package/dist/endpoints/helpers.d.cts +58 -0
- package/dist/endpoints/helpers.d.mts +58 -0
- package/dist/endpoints/helpers.mjs +9 -0
- package/dist/endpoints/index.cjs +16 -0
- package/dist/endpoints/index.cjs.map +1 -0
- package/dist/endpoints/index.d.cts +16 -0
- package/dist/endpoints/index.d.mts +16 -0
- package/dist/endpoints/index.mjs +15 -0
- package/dist/endpoints/index.mjs.map +1 -0
- package/dist/endpoints/parseHonoQuery.cjs +3 -0
- package/dist/endpoints/parseHonoQuery.d.cts +12 -0
- package/dist/endpoints/parseHonoQuery.d.mts +12 -0
- package/dist/endpoints/parseHonoQuery.mjs +3 -0
- package/dist/endpoints/parseQueryParams.cjs +3 -0
- package/dist/endpoints/parseQueryParams.d.cts +13 -0
- package/dist/endpoints/parseQueryParams.d.mts +13 -0
- package/dist/endpoints/parseQueryParams.mjs +3 -0
- package/dist/functions/AWSLambdaFunction.cjs +9 -0
- package/dist/functions/AWSLambdaFunction.d.cts +5 -0
- package/dist/functions/AWSLambdaFunction.d.mts +5 -0
- package/dist/functions/AWSLambdaFunction.mjs +9 -0
- package/dist/functions/BaseFunctionBuilder.cjs +4 -0
- package/dist/functions/BaseFunctionBuilder.d.cts +3 -0
- package/dist/functions/BaseFunctionBuilder.d.mts +3 -0
- package/dist/functions/BaseFunctionBuilder.mjs +4 -0
- package/dist/functions/Function.cjs +5 -0
- package/dist/functions/Function.d.cts +3 -0
- package/dist/functions/Function.d.mts +3 -0
- package/dist/functions/Function.mjs +4 -0
- package/dist/functions/FunctionBuilder.cjs +6 -0
- package/dist/functions/FunctionBuilder.d.cts +5 -0
- package/dist/functions/FunctionBuilder.d.mts +5 -0
- package/dist/functions/FunctionBuilder.mjs +6 -0
- package/dist/functions/FunctionExecutionWrapper.cjs +8 -0
- package/dist/functions/FunctionExecutionWrapper.d.cts +4 -0
- package/dist/functions/FunctionExecutionWrapper.d.mts +4 -0
- package/dist/functions/FunctionExecutionWrapper.mjs +8 -0
- package/dist/functions/TestFunctionAdaptor.cjs +38 -0
- package/dist/functions/TestFunctionAdaptor.cjs.map +1 -0
- package/dist/functions/TestFunctionAdaptor.d.cts +26 -0
- package/dist/functions/TestFunctionAdaptor.d.mts +26 -0
- package/dist/functions/TestFunctionAdaptor.mjs +37 -0
- package/dist/functions/TestFunctionAdaptor.mjs.map +1 -0
- package/dist/functions/index.cjs +10 -0
- package/dist/functions/index.d.cts +6 -0
- package/dist/functions/index.d.mts +6 -0
- package/dist/functions/index.mjs +7 -0
- package/dist/functions-DVDb5wEA.cjs +13 -0
- package/dist/functions-DVDb5wEA.cjs.map +1 -0
- package/dist/functions-mM-jcphA.mjs +8 -0
- package/dist/functions-mM-jcphA.mjs.map +1 -0
- package/dist/helpers-BeGM4pP_.cjs +95 -0
- package/dist/helpers-BeGM4pP_.cjs.map +1 -0
- package/dist/helpers-DbpO95aE.mjs +83 -0
- package/dist/helpers-DbpO95aE.mjs.map +1 -0
- package/dist/index-CuGR4L7O.d.mts +9 -0
- package/dist/index-Fg3N3EKD.d.cts +9 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +3 -0
- package/dist/parseHonoQuery-DopC24vB.cjs +37 -0
- package/dist/parseHonoQuery-DopC24vB.cjs.map +1 -0
- package/dist/parseHonoQuery-znDKBhdE.mjs +31 -0
- package/dist/parseHonoQuery-znDKBhdE.mjs.map +1 -0
- package/dist/parseQueryParams-BJaRh3OB.mjs +32 -0
- package/dist/parseQueryParams-BJaRh3OB.mjs.map +1 -0
- package/dist/parseQueryParams-BzPop4I1.cjs +38 -0
- package/dist/parseQueryParams-BzPop4I1.cjs.map +1 -0
- package/dist/publisher-Bw4770Hi.mjs +41 -0
- package/dist/publisher-Bw4770Hi.mjs.map +1 -0
- package/dist/publisher-lFQleddL.cjs +53 -0
- package/dist/publisher-lFQleddL.cjs.map +1 -0
- package/dist/publisher.cjs +4 -0
- package/dist/publisher.d.cts +13 -0
- package/dist/publisher.d.mts +13 -0
- package/dist/publisher.mjs +3 -0
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.cjs +3 -0
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.cts +4 -0
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +4 -0
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.mjs +3 -0
- package/dist/subscribers/Subscriber.cjs +4 -0
- package/dist/subscribers/Subscriber.d.cts +3 -0
- package/dist/subscribers/Subscriber.d.mts +3 -0
- package/dist/subscribers/Subscriber.mjs +4 -0
- package/dist/subscribers/SubscriberBuilder.cjs +5 -0
- package/dist/subscribers/SubscriberBuilder.d.cts +4 -0
- package/dist/subscribers/SubscriberBuilder.d.mts +4 -0
- package/dist/subscribers/SubscriberBuilder.mjs +5 -0
- package/dist/subscribers/index.cjs +12 -0
- package/dist/subscribers/index.cjs.map +1 -0
- package/dist/subscribers/index.d.cts +10 -0
- package/dist/subscribers/index.d.mts +10 -0
- package/dist/subscribers/index.mjs +10 -0
- package/dist/subscribers/index.mjs.map +1 -0
- package/dist/types-Bp9ysFXd.d.cts +7 -0
- package/dist/types-DBKNYvsW.d.mts +7 -0
- package/dist/types.cjs +0 -0
- package/dist/types.d.cts +2 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +0 -0
- package/package.json +91 -0
- package/src/Construct.ts +98 -0
- package/src/__tests__/Construct.environment.spec.ts +360 -0
- package/src/__tests__/publisher.setting.spec.ts +511 -0
- package/src/__tests__/publisher.spec.ts +454 -0
- package/src/adaptors/aws.ts +4 -0
- package/src/adaptors/hono.ts +1 -0
- package/src/crons/Cron.ts +137 -0
- package/src/crons/CronBuilder.ts +192 -0
- package/src/crons/__tests__/Cron.spec.ts +464 -0
- package/src/crons/index.ts +11 -0
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +315 -0
- package/src/endpoints/AmazonApiGatewayV1EndpointAdaptor.ts +101 -0
- package/src/endpoints/AmazonApiGatewayV2EndpointAdaptor.ts +95 -0
- package/src/endpoints/Endpoint.ts +771 -0
- package/src/endpoints/EndpointBuilder.ts +308 -0
- package/src/endpoints/EndpointFactory.ts +329 -0
- package/src/endpoints/HonoEndpointAdaptor.ts +365 -0
- package/src/endpoints/TestEndpointAdaptor.ts +130 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.events.spec.ts +553 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +927 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +721 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.factory-publisher.spec.ts +296 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +441 -0
- package/src/endpoints/__tests__/Endpoint.spec.ts +800 -0
- package/src/endpoints/__tests__/EndpointBuilder.spec.ts +488 -0
- package/src/endpoints/__tests__/EndpointFactory.spec.ts +479 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.events.spec.ts +569 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.openapi.spec.ts +313 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +1078 -0
- package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +236 -0
- package/src/endpoints/__tests__/__snapshots__/HonoEndpointAdaptor.spec.ts.snap +54 -0
- package/src/endpoints/__tests__/endpoint-types.test.ts +88 -0
- package/src/endpoints/helpers.ts +99 -0
- package/src/endpoints/index.ts +5 -0
- package/src/endpoints/parseHonoQuery.ts +51 -0
- package/src/endpoints/parseQueryParams.ts +51 -0
- package/src/functions/AWSLambdaFunction.ts +222 -0
- package/src/functions/BaseFunctionBuilder.ts +110 -0
- package/src/functions/Function.ts +160 -0
- package/src/functions/FunctionBuilder.ts +182 -0
- package/src/functions/FunctionExecutionWrapper.ts +86 -0
- package/src/functions/TestFunctionAdaptor.ts +125 -0
- package/src/functions/__tests__/AWSLambdaFunctionAdaptor.spec.ts +376 -0
- package/src/functions/__tests__/Function.spec.ts +402 -0
- package/src/functions/__tests__/TestFunctionAdaptor.spec.ts +398 -0
- package/src/functions/index.ts +10 -0
- package/src/index.ts +14 -0
- package/src/publisher.ts +83 -0
- package/src/subscribers/AWSLambdaSubscriberAdaptor.ts +269 -0
- package/src/subscribers/Subscriber.ts +112 -0
- package/src/subscribers/SubscriberBuilder.ts +150 -0
- package/src/subscribers/__tests__/AWSLambdaSubscriberAdaptor.spec.ts +623 -0
- package/src/subscribers/__tests__/Subscriber.spec.ts +432 -0
- package/src/subscribers/index.ts +5 -0
- package/src/types.ts +13 -0
- package/tsdown.config.ts +3 -0
|
@@ -0,0 +1,927 @@
|
|
|
1
|
+
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
2
|
+
import {
|
|
3
|
+
BadRequestError,
|
|
4
|
+
ConflictError,
|
|
5
|
+
HttpError,
|
|
6
|
+
InternalServerError,
|
|
7
|
+
NotFoundError,
|
|
8
|
+
UnauthorizedError,
|
|
9
|
+
} from '@geekmidas/errors';
|
|
10
|
+
import type { Logger } from '@geekmidas/logger';
|
|
11
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { Endpoint } from '../Endpoint';
|
|
14
|
+
|
|
15
|
+
import { createMockContext, createMockV1Event } from '@geekmidas/testkit/aws';
|
|
16
|
+
|
|
17
|
+
import { createMockLogger } from '@geekmidas/testkit/logger';
|
|
18
|
+
import { AmazonApiGatewayV1Endpoint } from '../AmazonApiGatewayV1EndpointAdaptor';
|
|
19
|
+
/**
|
|
20
|
+
* Common test event types for AWS adapter testing
|
|
21
|
+
*/
|
|
22
|
+
export type TestEvent =
|
|
23
|
+
| { type: 'user.created'; payload: { userId: string; email: string } }
|
|
24
|
+
| { type: 'user.updated'; payload: { userId: string; changes: string[] } }
|
|
25
|
+
| { type: 'notification.sent'; payload: { userId: string; type: string } };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Mock service for testing
|
|
29
|
+
*/
|
|
30
|
+
export const TestService = {
|
|
31
|
+
serviceName: 'TestService' as const,
|
|
32
|
+
|
|
33
|
+
async register() {
|
|
34
|
+
return this;
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async cleanup() {},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
describe('AmazonApiGatewayV1Endpoint', () => {
|
|
41
|
+
let mockLogger: Logger;
|
|
42
|
+
let envParser: EnvironmentParser<{}>;
|
|
43
|
+
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
vi.clearAllMocks();
|
|
46
|
+
mockLogger = createMockLogger();
|
|
47
|
+
envParser = new EnvironmentParser({});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('handler', () => {
|
|
51
|
+
it('should handle a simple GET request', async () => {
|
|
52
|
+
const endpoint = new Endpoint({
|
|
53
|
+
route: '/test',
|
|
54
|
+
method: 'GET',
|
|
55
|
+
fn: async () => ({ message: 'Hello, World!' }),
|
|
56
|
+
input: {},
|
|
57
|
+
output: z.object({ message: z.string() }),
|
|
58
|
+
services: [],
|
|
59
|
+
logger: mockLogger,
|
|
60
|
+
timeout: undefined,
|
|
61
|
+
status: undefined,
|
|
62
|
+
getSession: undefined,
|
|
63
|
+
authorize: undefined,
|
|
64
|
+
description: 'Test endpoint',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
68
|
+
const handler = adapter.handler;
|
|
69
|
+
|
|
70
|
+
const event = createMockV1Event();
|
|
71
|
+
const context = createMockContext();
|
|
72
|
+
const response = await handler(event, context);
|
|
73
|
+
|
|
74
|
+
expect(response.statusCode).toBe(200);
|
|
75
|
+
expect(response.body).toBe(JSON.stringify({ message: 'Hello, World!' }));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should handle POST request with body', async () => {
|
|
79
|
+
const inputSchema = z.object({ name: z.string() });
|
|
80
|
+
const outputSchema = z.object({ id: z.string(), name: z.string() });
|
|
81
|
+
|
|
82
|
+
const endpoint = new Endpoint({
|
|
83
|
+
route: '/users',
|
|
84
|
+
method: 'POST',
|
|
85
|
+
fn: async ({ body }) => ({ id: '123', name: body.name }),
|
|
86
|
+
input: { body: inputSchema },
|
|
87
|
+
output: outputSchema,
|
|
88
|
+
services: [],
|
|
89
|
+
logger: mockLogger,
|
|
90
|
+
timeout: undefined,
|
|
91
|
+
status: 201,
|
|
92
|
+
getSession: undefined,
|
|
93
|
+
authorize: undefined,
|
|
94
|
+
description: 'Create user endpoint',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
98
|
+
const handler = adapter.handler;
|
|
99
|
+
|
|
100
|
+
const event = createMockV1Event({
|
|
101
|
+
httpMethod: 'POST',
|
|
102
|
+
body: JSON.stringify({ name: 'John Doe' }),
|
|
103
|
+
});
|
|
104
|
+
const context = createMockContext();
|
|
105
|
+
const response = await handler(event, context);
|
|
106
|
+
|
|
107
|
+
expect(response.statusCode).toBe(201);
|
|
108
|
+
expect(response.body).toBe(
|
|
109
|
+
JSON.stringify({ id: '123', name: 'John Doe' }),
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('should handle query parameters', async () => {
|
|
114
|
+
const querySchema = z.object({ page: z.string().transform(Number) });
|
|
115
|
+
const outputSchema = z.object({
|
|
116
|
+
page: z.number(),
|
|
117
|
+
items: z.array(z.string()),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const endpoint = new Endpoint({
|
|
121
|
+
route: '/items',
|
|
122
|
+
method: 'GET',
|
|
123
|
+
fn: async ({ query }) => ({
|
|
124
|
+
page: query.page,
|
|
125
|
+
items: ['item1', 'item2'],
|
|
126
|
+
}),
|
|
127
|
+
input: { query: querySchema },
|
|
128
|
+
output: outputSchema,
|
|
129
|
+
services: [],
|
|
130
|
+
logger: mockLogger,
|
|
131
|
+
timeout: undefined,
|
|
132
|
+
status: undefined,
|
|
133
|
+
getSession: undefined,
|
|
134
|
+
authorize: undefined,
|
|
135
|
+
description: 'List items endpoint',
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
139
|
+
const handler = adapter.handler;
|
|
140
|
+
|
|
141
|
+
const event = createMockV1Event({
|
|
142
|
+
queryStringParameters: { page: '2' },
|
|
143
|
+
});
|
|
144
|
+
const context = createMockContext();
|
|
145
|
+
const response = await handler(event, context);
|
|
146
|
+
|
|
147
|
+
expect(response.statusCode).toBe(200);
|
|
148
|
+
expect(response.body).toBe(
|
|
149
|
+
JSON.stringify({ page: 2, items: ['item1', 'item2'] }),
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should handle path parameters', async () => {
|
|
154
|
+
const paramsSchema = z.object({ id: z.string() });
|
|
155
|
+
const outputSchema = z.object({ id: z.string(), name: z.string() });
|
|
156
|
+
|
|
157
|
+
const endpoint = new Endpoint({
|
|
158
|
+
route: '/users/:id',
|
|
159
|
+
method: 'GET',
|
|
160
|
+
fn: async ({ params }) => ({ id: params.id, name: 'John Doe' }),
|
|
161
|
+
input: { params: paramsSchema },
|
|
162
|
+
output: outputSchema,
|
|
163
|
+
services: [],
|
|
164
|
+
logger: mockLogger,
|
|
165
|
+
timeout: undefined,
|
|
166
|
+
status: undefined,
|
|
167
|
+
getSession: undefined,
|
|
168
|
+
authorize: undefined,
|
|
169
|
+
description: 'Get user endpoint',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
173
|
+
const handler = adapter.handler;
|
|
174
|
+
|
|
175
|
+
const event = createMockV1Event({
|
|
176
|
+
pathParameters: { id: '123' },
|
|
177
|
+
});
|
|
178
|
+
const context = createMockContext();
|
|
179
|
+
const response = await handler(event, context);
|
|
180
|
+
|
|
181
|
+
expect(response.statusCode).toBe(200);
|
|
182
|
+
expect(response.body).toBe(
|
|
183
|
+
JSON.stringify({ id: '123', name: 'John Doe' }),
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should handle endpoint without output', async () => {
|
|
188
|
+
const endpoint = new Endpoint({
|
|
189
|
+
route: '/void',
|
|
190
|
+
method: 'POST',
|
|
191
|
+
fn: async () => {},
|
|
192
|
+
input: {},
|
|
193
|
+
output: undefined,
|
|
194
|
+
services: [],
|
|
195
|
+
logger: mockLogger,
|
|
196
|
+
timeout: undefined,
|
|
197
|
+
status: 204,
|
|
198
|
+
getSession: undefined,
|
|
199
|
+
authorize: undefined,
|
|
200
|
+
description: 'Void endpoint',
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
204
|
+
const handler = adapter.handler;
|
|
205
|
+
|
|
206
|
+
const event = createMockV1Event({ httpMethod: 'POST' });
|
|
207
|
+
const context = createMockContext();
|
|
208
|
+
const response = await handler(event, context);
|
|
209
|
+
|
|
210
|
+
expect(response.statusCode).toBe(204);
|
|
211
|
+
expect(response.body).toBeUndefined();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
describe('middleware', () => {
|
|
216
|
+
it('should inject logger with context', async () => {
|
|
217
|
+
const endpoint = new Endpoint({
|
|
218
|
+
route: '/test',
|
|
219
|
+
method: 'GET',
|
|
220
|
+
fn: async ({ logger }) => {
|
|
221
|
+
logger.info('Test log');
|
|
222
|
+
return { success: true };
|
|
223
|
+
},
|
|
224
|
+
input: {},
|
|
225
|
+
output: z.object({ success: z.boolean() }),
|
|
226
|
+
services: [],
|
|
227
|
+
logger: mockLogger,
|
|
228
|
+
timeout: undefined,
|
|
229
|
+
status: undefined,
|
|
230
|
+
getSession: undefined,
|
|
231
|
+
authorize: undefined,
|
|
232
|
+
description: 'Logger test endpoint',
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
236
|
+
const handler = adapter.handler;
|
|
237
|
+
|
|
238
|
+
const event = createMockV1Event();
|
|
239
|
+
const context = createMockContext();
|
|
240
|
+
await handler(event, context);
|
|
241
|
+
|
|
242
|
+
expect(mockLogger.child).toHaveBeenCalledWith({
|
|
243
|
+
route: '/test',
|
|
244
|
+
host: 'test.example.com',
|
|
245
|
+
method: 'GET',
|
|
246
|
+
fn: {
|
|
247
|
+
name: 'test-function',
|
|
248
|
+
version: '1',
|
|
249
|
+
},
|
|
250
|
+
req: {
|
|
251
|
+
ip: expect.any(String),
|
|
252
|
+
awsRequestId: 'test-request-id',
|
|
253
|
+
id: 'request-id',
|
|
254
|
+
userAgent: 'test-agent',
|
|
255
|
+
path: '/test',
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should handle errors and wrap them', async () => {
|
|
261
|
+
const endpoint = new Endpoint({
|
|
262
|
+
route: '/error',
|
|
263
|
+
method: 'GET',
|
|
264
|
+
fn: async () => {
|
|
265
|
+
throw new Error('Test error');
|
|
266
|
+
},
|
|
267
|
+
input: {},
|
|
268
|
+
output: z.object({ message: z.string() }),
|
|
269
|
+
services: [],
|
|
270
|
+
logger: mockLogger,
|
|
271
|
+
timeout: undefined,
|
|
272
|
+
status: undefined,
|
|
273
|
+
getSession: undefined,
|
|
274
|
+
authorize: undefined,
|
|
275
|
+
description: 'Error test endpoint',
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
279
|
+
const handler = adapter.handler;
|
|
280
|
+
|
|
281
|
+
const event = createMockV1Event();
|
|
282
|
+
const context = createMockContext();
|
|
283
|
+
|
|
284
|
+
const response = await handler(event, context);
|
|
285
|
+
|
|
286
|
+
expect(response.statusCode).toBe(500);
|
|
287
|
+
const body = JSON.parse(response.body!);
|
|
288
|
+
expect(body).toMatchObject({
|
|
289
|
+
message: 'An unknown error occurred',
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should register services', async () => {
|
|
296
|
+
const endpoint = new Endpoint({
|
|
297
|
+
route: '/with-service',
|
|
298
|
+
method: 'GET',
|
|
299
|
+
fn: async ({ services }) => {
|
|
300
|
+
const testService = await services.TestService;
|
|
301
|
+
return { hasService: !!testService };
|
|
302
|
+
},
|
|
303
|
+
input: {},
|
|
304
|
+
output: z.object({ hasService: z.boolean() }),
|
|
305
|
+
services: [TestService],
|
|
306
|
+
logger: mockLogger,
|
|
307
|
+
timeout: undefined,
|
|
308
|
+
status: undefined,
|
|
309
|
+
getSession: undefined,
|
|
310
|
+
authorize: undefined,
|
|
311
|
+
description: 'Service test endpoint',
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
315
|
+
const handler = adapter.handler.bind(adapter);
|
|
316
|
+
|
|
317
|
+
const event = createMockV1Event();
|
|
318
|
+
const context = createMockContext();
|
|
319
|
+
const response = await handler(event, context);
|
|
320
|
+
|
|
321
|
+
expect(response.statusCode).toBe(200);
|
|
322
|
+
expect(response.body).toBe(JSON.stringify({ hasService: true }));
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should handle session', async () => {
|
|
326
|
+
const mockSession = { userId: 'user-123', role: 'admin' };
|
|
327
|
+
|
|
328
|
+
const endpoint = new Endpoint({
|
|
329
|
+
route: '/with-session',
|
|
330
|
+
method: 'GET',
|
|
331
|
+
fn: async ({ session }) => ({ session }),
|
|
332
|
+
input: {},
|
|
333
|
+
output: z.object({ session: z.any() }),
|
|
334
|
+
services: [],
|
|
335
|
+
logger: mockLogger,
|
|
336
|
+
timeout: undefined,
|
|
337
|
+
status: undefined,
|
|
338
|
+
getSession: async () => mockSession,
|
|
339
|
+
authorize: undefined,
|
|
340
|
+
description: 'Session test endpoint',
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
344
|
+
const handler = adapter.handler;
|
|
345
|
+
|
|
346
|
+
const event = createMockV1Event();
|
|
347
|
+
const context = createMockContext();
|
|
348
|
+
const response = await handler(event, context);
|
|
349
|
+
|
|
350
|
+
expect(response.statusCode).toBe(200);
|
|
351
|
+
// Session is currently hardcoded as empty object in the implementation
|
|
352
|
+
expect(response.body).toBe(JSON.stringify({ session: mockSession }));
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
describe('error handling', () => {
|
|
357
|
+
it('should return correct status code for HttpError', async () => {
|
|
358
|
+
const endpoint = new Endpoint({
|
|
359
|
+
route: '/http-error',
|
|
360
|
+
method: 'GET',
|
|
361
|
+
fn: async () => {
|
|
362
|
+
throw new HttpError(403, 'Forbidden', { code: 'FORBIDDEN_ACCESS' });
|
|
363
|
+
},
|
|
364
|
+
input: {},
|
|
365
|
+
output: z.object({ message: z.string() }),
|
|
366
|
+
services: [],
|
|
367
|
+
logger: mockLogger,
|
|
368
|
+
timeout: undefined,
|
|
369
|
+
status: undefined,
|
|
370
|
+
getSession: undefined,
|
|
371
|
+
authorize: undefined,
|
|
372
|
+
description: 'HTTP error test endpoint',
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
376
|
+
const handler = adapter.handler;
|
|
377
|
+
|
|
378
|
+
const event = createMockV1Event();
|
|
379
|
+
const context = createMockContext();
|
|
380
|
+
|
|
381
|
+
const response = await handler(event, context);
|
|
382
|
+
|
|
383
|
+
expect(response.statusCode).toBe(403);
|
|
384
|
+
expect(response.body).toBe(
|
|
385
|
+
JSON.stringify({
|
|
386
|
+
message: 'Forbidden',
|
|
387
|
+
code: 'FORBIDDEN_ACCESS',
|
|
388
|
+
}),
|
|
389
|
+
);
|
|
390
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('should return 500 for non-HttpError errors', async () => {
|
|
394
|
+
const endpoint = new Endpoint({
|
|
395
|
+
route: '/generic-error',
|
|
396
|
+
method: 'GET',
|
|
397
|
+
fn: async () => {
|
|
398
|
+
throw new TypeError('Type mismatch');
|
|
399
|
+
},
|
|
400
|
+
input: {},
|
|
401
|
+
output: z.object({ message: z.string() }),
|
|
402
|
+
services: [],
|
|
403
|
+
logger: mockLogger,
|
|
404
|
+
timeout: undefined,
|
|
405
|
+
status: undefined,
|
|
406
|
+
getSession: undefined,
|
|
407
|
+
authorize: undefined,
|
|
408
|
+
description: 'Generic error test endpoint',
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
412
|
+
const handler = adapter.handler;
|
|
413
|
+
|
|
414
|
+
const event = createMockV1Event();
|
|
415
|
+
const context = createMockContext();
|
|
416
|
+
|
|
417
|
+
const response = await handler(event, context);
|
|
418
|
+
|
|
419
|
+
expect(response.statusCode).toBe(500);
|
|
420
|
+
const body = JSON.parse(response.body!);
|
|
421
|
+
expect(body).toMatchObject({
|
|
422
|
+
message: 'An unknown error occurred',
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('should preserve status codes for various HttpError subclasses', async () => {
|
|
429
|
+
const testCases = [
|
|
430
|
+
{
|
|
431
|
+
ErrorClass: UnauthorizedError,
|
|
432
|
+
statusCode: 401,
|
|
433
|
+
message: 'Unauthorized',
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
ErrorClass: BadRequestError,
|
|
437
|
+
statusCode: 400,
|
|
438
|
+
message: 'Bad Request',
|
|
439
|
+
},
|
|
440
|
+
{ ErrorClass: NotFoundError, statusCode: 404, message: 'Not Found' },
|
|
441
|
+
{ ErrorClass: ConflictError, statusCode: 409, message: 'Conflict' },
|
|
442
|
+
{
|
|
443
|
+
ErrorClass: InternalServerError,
|
|
444
|
+
statusCode: 500,
|
|
445
|
+
message: 'Internal Server Error',
|
|
446
|
+
},
|
|
447
|
+
];
|
|
448
|
+
|
|
449
|
+
for (const { ErrorClass, statusCode, message } of testCases) {
|
|
450
|
+
const endpoint = new Endpoint({
|
|
451
|
+
route: `/error-${statusCode}`,
|
|
452
|
+
method: 'GET',
|
|
453
|
+
fn: async () => {
|
|
454
|
+
throw new ErrorClass(message);
|
|
455
|
+
},
|
|
456
|
+
input: {},
|
|
457
|
+
output: z.object({ message: z.string() }),
|
|
458
|
+
services: [],
|
|
459
|
+
logger: mockLogger,
|
|
460
|
+
timeout: undefined,
|
|
461
|
+
status: undefined,
|
|
462
|
+
getSession: undefined,
|
|
463
|
+
authorize: undefined,
|
|
464
|
+
description: `${statusCode} error test endpoint`,
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
468
|
+
const handler = adapter.handler;
|
|
469
|
+
|
|
470
|
+
const event = createMockV1Event();
|
|
471
|
+
const context = createMockContext();
|
|
472
|
+
|
|
473
|
+
const response = await handler(event, context);
|
|
474
|
+
|
|
475
|
+
expect(response.statusCode).toBe(statusCode);
|
|
476
|
+
expect(response.body).toBe(
|
|
477
|
+
JSON.stringify({
|
|
478
|
+
message,
|
|
479
|
+
code: undefined,
|
|
480
|
+
}),
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it('should return 422 for body validation errors', async () => {
|
|
486
|
+
const bodySchema = z.object({
|
|
487
|
+
name: z.string().min(3),
|
|
488
|
+
age: z.number().positive(),
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
const endpoint = new Endpoint({
|
|
492
|
+
route: '/validation',
|
|
493
|
+
method: 'POST',
|
|
494
|
+
fn: async () => ({ success: true }),
|
|
495
|
+
input: { body: bodySchema },
|
|
496
|
+
output: z.object({ success: z.boolean() }),
|
|
497
|
+
services: [],
|
|
498
|
+
logger: mockLogger,
|
|
499
|
+
timeout: undefined,
|
|
500
|
+
status: undefined,
|
|
501
|
+
getSession: undefined,
|
|
502
|
+
authorize: undefined,
|
|
503
|
+
description: 'Validation test endpoint',
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
507
|
+
const handler = adapter.handler;
|
|
508
|
+
|
|
509
|
+
const event = createMockV1Event({
|
|
510
|
+
httpMethod: 'POST',
|
|
511
|
+
body: JSON.stringify({ name: 'Jo', age: -5 }), // Invalid: name too short, age negative
|
|
512
|
+
});
|
|
513
|
+
const context = createMockContext();
|
|
514
|
+
|
|
515
|
+
const response = await handler(event, context);
|
|
516
|
+
|
|
517
|
+
expect(response.statusCode).toBe(422);
|
|
518
|
+
const body = JSON.parse(response.body!);
|
|
519
|
+
expect(body.message).toBe('Validation failed');
|
|
520
|
+
expect(body.code).toBeUndefined();
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it('should return 422 for query validation errors', async () => {
|
|
524
|
+
const querySchema = z.object({
|
|
525
|
+
page: z.string().transform(Number).pipe(z.number().positive()),
|
|
526
|
+
limit: z.string().transform(Number).pipe(z.number().max(100)),
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
const endpoint = new Endpoint({
|
|
530
|
+
route: '/items',
|
|
531
|
+
method: 'GET',
|
|
532
|
+
fn: async () => ({ items: [] }),
|
|
533
|
+
input: { query: querySchema },
|
|
534
|
+
output: z.object({ items: z.array(z.any()) }),
|
|
535
|
+
services: [],
|
|
536
|
+
logger: mockLogger,
|
|
537
|
+
timeout: undefined,
|
|
538
|
+
status: undefined,
|
|
539
|
+
getSession: undefined,
|
|
540
|
+
authorize: undefined,
|
|
541
|
+
description: 'Query validation test endpoint',
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
545
|
+
const handler = adapter.handler;
|
|
546
|
+
|
|
547
|
+
const event = createMockV1Event({
|
|
548
|
+
queryStringParameters: { page: '0', limit: '200' }, // Invalid: page not positive, limit too high
|
|
549
|
+
});
|
|
550
|
+
const context = createMockContext();
|
|
551
|
+
|
|
552
|
+
const response = await handler(event, context);
|
|
553
|
+
|
|
554
|
+
expect(response.statusCode).toBe(422);
|
|
555
|
+
const body = JSON.parse(response.body!);
|
|
556
|
+
expect(body.message).toBe('Validation failed');
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it('should return 422 for params validation errors', async () => {
|
|
560
|
+
const paramsSchema = z.object({
|
|
561
|
+
id: z.string().uuid(),
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
const endpoint = new Endpoint({
|
|
565
|
+
route: '/users/:id',
|
|
566
|
+
method: 'GET',
|
|
567
|
+
fn: async ({ params }) => ({ id: params.id }),
|
|
568
|
+
input: { params: paramsSchema },
|
|
569
|
+
output: z.object({ id: z.string() }),
|
|
570
|
+
services: [],
|
|
571
|
+
logger: mockLogger,
|
|
572
|
+
timeout: undefined,
|
|
573
|
+
status: undefined,
|
|
574
|
+
getSession: undefined,
|
|
575
|
+
authorize: undefined,
|
|
576
|
+
description: 'Params validation test endpoint',
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
580
|
+
const handler = adapter.handler;
|
|
581
|
+
|
|
582
|
+
const event = createMockV1Event({
|
|
583
|
+
pathParameters: { id: 'not-a-uuid' }, // Invalid: not a valid UUID
|
|
584
|
+
});
|
|
585
|
+
const context = createMockContext();
|
|
586
|
+
|
|
587
|
+
const response = await handler(event, context);
|
|
588
|
+
|
|
589
|
+
expect(response.statusCode).toBe(422);
|
|
590
|
+
const body = JSON.parse(response.body!);
|
|
591
|
+
expect(body.message).toBe('Validation failed');
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
describe('header handling', () => {
|
|
596
|
+
it('should provide header function to handler', async () => {
|
|
597
|
+
const endpoint = new Endpoint({
|
|
598
|
+
route: '/headers',
|
|
599
|
+
method: 'GET',
|
|
600
|
+
fn: async ({ header }) => ({
|
|
601
|
+
authorization: header('authorization'),
|
|
602
|
+
contentType: header('content-type'),
|
|
603
|
+
}),
|
|
604
|
+
input: {},
|
|
605
|
+
output: z.object({
|
|
606
|
+
authorization: z.string().optional(),
|
|
607
|
+
contentType: z.string().optional(),
|
|
608
|
+
}),
|
|
609
|
+
services: [],
|
|
610
|
+
logger: mockLogger,
|
|
611
|
+
timeout: undefined,
|
|
612
|
+
status: undefined,
|
|
613
|
+
getSession: undefined,
|
|
614
|
+
authorize: undefined,
|
|
615
|
+
description: 'Header test endpoint',
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
619
|
+
const handler = adapter.handler;
|
|
620
|
+
|
|
621
|
+
const event = createMockV1Event({
|
|
622
|
+
headers: {
|
|
623
|
+
'content-type': 'application/json',
|
|
624
|
+
authorization: 'Bearer token123',
|
|
625
|
+
},
|
|
626
|
+
});
|
|
627
|
+
const context = createMockContext();
|
|
628
|
+
const response = await handler(event, context);
|
|
629
|
+
|
|
630
|
+
expect(response.statusCode).toBe(200);
|
|
631
|
+
expect(response.body).toBe(
|
|
632
|
+
JSON.stringify({
|
|
633
|
+
authorization: 'Bearer token123',
|
|
634
|
+
contentType: 'application/json',
|
|
635
|
+
}),
|
|
636
|
+
);
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
describe('authorization', () => {
|
|
641
|
+
it('should allow requests when authorize returns true', async () => {
|
|
642
|
+
const endpoint = new Endpoint({
|
|
643
|
+
route: '/protected',
|
|
644
|
+
method: 'GET',
|
|
645
|
+
fn: async () => ({ success: true }),
|
|
646
|
+
input: {},
|
|
647
|
+
output: z.object({ success: z.boolean() }),
|
|
648
|
+
services: [],
|
|
649
|
+
logger: mockLogger,
|
|
650
|
+
timeout: undefined,
|
|
651
|
+
status: undefined,
|
|
652
|
+
getSession: undefined,
|
|
653
|
+
authorize: undefined,
|
|
654
|
+
description: 'Protected endpoint',
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// Set authorize function that returns true
|
|
658
|
+
endpoint.authorize = async () => true;
|
|
659
|
+
|
|
660
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
661
|
+
const handler = adapter.handler;
|
|
662
|
+
|
|
663
|
+
const event = createMockV1Event();
|
|
664
|
+
const context = createMockContext();
|
|
665
|
+
const response = await handler(event, context);
|
|
666
|
+
|
|
667
|
+
expect(response.statusCode).toBe(200);
|
|
668
|
+
expect(response.body).toBe(JSON.stringify({ success: true }));
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
it('should reject requests when authorize returns false', async () => {
|
|
672
|
+
const endpoint = new Endpoint({
|
|
673
|
+
route: '/protected',
|
|
674
|
+
method: 'GET',
|
|
675
|
+
fn: async () => ({ success: true }),
|
|
676
|
+
input: {},
|
|
677
|
+
output: z.object({ success: z.boolean() }),
|
|
678
|
+
services: [],
|
|
679
|
+
logger: mockLogger,
|
|
680
|
+
timeout: undefined,
|
|
681
|
+
status: undefined,
|
|
682
|
+
getSession: undefined,
|
|
683
|
+
authorize: undefined,
|
|
684
|
+
description: 'Protected endpoint',
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// Set authorize function that returns false
|
|
688
|
+
endpoint.authorize = async () => false;
|
|
689
|
+
|
|
690
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
691
|
+
const handler = adapter.handler;
|
|
692
|
+
|
|
693
|
+
const event = createMockV1Event();
|
|
694
|
+
const context = createMockContext();
|
|
695
|
+
|
|
696
|
+
const response = await handler(event, context);
|
|
697
|
+
|
|
698
|
+
expect(response.statusCode).toBe(401);
|
|
699
|
+
const body = JSON.parse(response.body!);
|
|
700
|
+
expect(body).toMatchObject({
|
|
701
|
+
message: 'Unauthorized access to the endpoint',
|
|
702
|
+
});
|
|
703
|
+
expect(mockLogger.warn).toHaveBeenCalledWith(
|
|
704
|
+
'Unauthorized access attempt',
|
|
705
|
+
);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
it('should handle async authorize functions', async () => {
|
|
709
|
+
const endpoint = new Endpoint({
|
|
710
|
+
route: '/protected',
|
|
711
|
+
method: 'GET',
|
|
712
|
+
fn: async () => ({ success: true }),
|
|
713
|
+
input: {},
|
|
714
|
+
output: z.object({ success: z.boolean() }),
|
|
715
|
+
services: [],
|
|
716
|
+
logger: mockLogger,
|
|
717
|
+
timeout: undefined,
|
|
718
|
+
status: undefined,
|
|
719
|
+
getSession: undefined,
|
|
720
|
+
authorize: undefined,
|
|
721
|
+
description: 'Protected endpoint',
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// Set async authorize function with delay
|
|
725
|
+
endpoint.authorize = async ({ header }) => {
|
|
726
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
727
|
+
return header('authorization') === 'Bearer valid-token';
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
731
|
+
const handler = adapter.handler;
|
|
732
|
+
|
|
733
|
+
// Test with valid token
|
|
734
|
+
const validEvent = createMockV1Event({
|
|
735
|
+
headers: {
|
|
736
|
+
authorization: 'Bearer valid-token',
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
const context = createMockContext();
|
|
740
|
+
const response = await handler(validEvent, context);
|
|
741
|
+
|
|
742
|
+
expect(response.statusCode).toBe(200);
|
|
743
|
+
expect(response.body).toBe(JSON.stringify({ success: true }));
|
|
744
|
+
|
|
745
|
+
// Test with invalid token
|
|
746
|
+
const invalidEvent = createMockV1Event({
|
|
747
|
+
headers: {
|
|
748
|
+
authorization: 'Bearer invalid-token',
|
|
749
|
+
},
|
|
750
|
+
});
|
|
751
|
+
const invalidResponse = await handler(invalidEvent, context);
|
|
752
|
+
const invalidResponseBody = JSON.parse(invalidResponse.body!);
|
|
753
|
+
expect(invalidResponse.statusCode).toBe(401);
|
|
754
|
+
expect(invalidResponseBody).toMatchObject({
|
|
755
|
+
message: 'Unauthorized access to the endpoint',
|
|
756
|
+
});
|
|
757
|
+
});
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
describe('combined inputs', () => {
|
|
761
|
+
it('should handle array query parameters', async () => {
|
|
762
|
+
const querySchema = z.object({
|
|
763
|
+
tags: z.array(z.string()),
|
|
764
|
+
page: z.coerce.number().default(1),
|
|
765
|
+
});
|
|
766
|
+
const outputSchema = z.object({
|
|
767
|
+
tags: z.array(z.string()),
|
|
768
|
+
page: z.number(),
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
const endpoint = new Endpoint({
|
|
772
|
+
route: '/items',
|
|
773
|
+
method: 'GET',
|
|
774
|
+
fn: async ({ query }) => ({
|
|
775
|
+
tags: query.tags,
|
|
776
|
+
page: query.page,
|
|
777
|
+
}),
|
|
778
|
+
input: { query: querySchema },
|
|
779
|
+
output: outputSchema,
|
|
780
|
+
services: [],
|
|
781
|
+
logger: mockLogger,
|
|
782
|
+
timeout: undefined,
|
|
783
|
+
authorize: undefined,
|
|
784
|
+
description: 'List items with tags',
|
|
785
|
+
getSession: () => ({}),
|
|
786
|
+
status: 200,
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
790
|
+
const handler = adapter.handler;
|
|
791
|
+
|
|
792
|
+
const event = createMockV1Event({
|
|
793
|
+
queryStringParameters: { tags: 'nodejs', page: '2' },
|
|
794
|
+
multiValueQueryStringParameters: {
|
|
795
|
+
tags: ['nodejs', 'typescript', 'javascript'],
|
|
796
|
+
page: ['2'],
|
|
797
|
+
},
|
|
798
|
+
});
|
|
799
|
+
const context = createMockContext();
|
|
800
|
+
const response = await handler(event, context);
|
|
801
|
+
|
|
802
|
+
expect(response.statusCode).toBe(200);
|
|
803
|
+
const body = JSON.parse(response.body!);
|
|
804
|
+
expect(body).toEqual({
|
|
805
|
+
tags: ['nodejs', 'typescript', 'javascript'],
|
|
806
|
+
page: 2,
|
|
807
|
+
});
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
it('should handle object query parameters with dot notation', async () => {
|
|
811
|
+
const querySchema = z.object({
|
|
812
|
+
filter: z.object({
|
|
813
|
+
name: z.string(),
|
|
814
|
+
status: z.string(),
|
|
815
|
+
priority: z.coerce.number(),
|
|
816
|
+
}),
|
|
817
|
+
sort: z.string().default('name'),
|
|
818
|
+
});
|
|
819
|
+
const outputSchema = z.object({
|
|
820
|
+
filter: z.object({
|
|
821
|
+
name: z.string(),
|
|
822
|
+
status: z.string(),
|
|
823
|
+
priority: z.number(),
|
|
824
|
+
}),
|
|
825
|
+
sort: z.string(),
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
const endpoint = new Endpoint({
|
|
829
|
+
route: '/search',
|
|
830
|
+
method: 'GET',
|
|
831
|
+
fn: async ({ query }) => ({
|
|
832
|
+
filter: query.filter,
|
|
833
|
+
sort: query.sort,
|
|
834
|
+
}),
|
|
835
|
+
input: { query: querySchema },
|
|
836
|
+
output: outputSchema,
|
|
837
|
+
services: [],
|
|
838
|
+
logger: mockLogger,
|
|
839
|
+
timeout: undefined,
|
|
840
|
+
authorize: undefined,
|
|
841
|
+
description: 'Search with filters',
|
|
842
|
+
getSession: () => ({}),
|
|
843
|
+
status: 200,
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
847
|
+
const handler = adapter.handler;
|
|
848
|
+
|
|
849
|
+
const event = createMockV1Event({
|
|
850
|
+
queryStringParameters: {
|
|
851
|
+
'filter.name': 'john',
|
|
852
|
+
'filter.status': 'active',
|
|
853
|
+
'filter.priority': '1',
|
|
854
|
+
sort: 'priority',
|
|
855
|
+
},
|
|
856
|
+
});
|
|
857
|
+
const context = createMockContext();
|
|
858
|
+
const response = await handler(event, context);
|
|
859
|
+
|
|
860
|
+
expect(response.statusCode).toBe(200);
|
|
861
|
+
const body = JSON.parse(response.body!);
|
|
862
|
+
expect(body).toEqual({
|
|
863
|
+
filter: {
|
|
864
|
+
name: 'john',
|
|
865
|
+
status: 'active',
|
|
866
|
+
priority: 1,
|
|
867
|
+
},
|
|
868
|
+
sort: 'priority',
|
|
869
|
+
});
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
it('should handle body, query, and params together', async () => {
|
|
873
|
+
const bodySchema = z.object({ name: z.string() });
|
|
874
|
+
const querySchema = z.object({ filter: z.string() });
|
|
875
|
+
const paramsSchema = z.object({ id: z.string() });
|
|
876
|
+
const outputSchema = z.object({
|
|
877
|
+
id: z.string(),
|
|
878
|
+
name: z.string(),
|
|
879
|
+
filter: z.string(),
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
const endpoint = new Endpoint({
|
|
883
|
+
route: '/complex/:id',
|
|
884
|
+
method: 'PUT',
|
|
885
|
+
fn: async ({ body, query, params }) => ({
|
|
886
|
+
id: params.id,
|
|
887
|
+
name: body.name,
|
|
888
|
+
filter: query.filter,
|
|
889
|
+
}),
|
|
890
|
+
input: {
|
|
891
|
+
body: bodySchema,
|
|
892
|
+
query: querySchema,
|
|
893
|
+
params: paramsSchema,
|
|
894
|
+
},
|
|
895
|
+
output: outputSchema,
|
|
896
|
+
services: [],
|
|
897
|
+
logger: mockLogger,
|
|
898
|
+
timeout: undefined,
|
|
899
|
+
status: undefined,
|
|
900
|
+
getSession: undefined,
|
|
901
|
+
authorize: undefined,
|
|
902
|
+
description: 'Complex input endpoint',
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
const adapter = new AmazonApiGatewayV1Endpoint(envParser, endpoint);
|
|
906
|
+
const handler = adapter.handler;
|
|
907
|
+
|
|
908
|
+
const event = createMockV1Event({
|
|
909
|
+
httpMethod: 'PUT',
|
|
910
|
+
body: JSON.stringify({ name: 'Updated Name' }),
|
|
911
|
+
queryStringParameters: { filter: 'active' },
|
|
912
|
+
pathParameters: { id: '456' },
|
|
913
|
+
});
|
|
914
|
+
const context = createMockContext();
|
|
915
|
+
const response = await handler(event, context);
|
|
916
|
+
|
|
917
|
+
expect(response.statusCode).toBe(200);
|
|
918
|
+
expect(response.body).toBe(
|
|
919
|
+
JSON.stringify({
|
|
920
|
+
id: '456',
|
|
921
|
+
name: 'Updated Name',
|
|
922
|
+
filter: 'active',
|
|
923
|
+
}),
|
|
924
|
+
);
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
});
|