@geekmidas/constructs 0.0.12 → 0.0.14
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 +448 -0
- package/dist/AWSLambdaFunction-B-Oxr8qt.d.cts +30 -0
- package/dist/{AWSLambdaFunction-DMxScuaw.cjs → AWSLambdaFunction-C-fuCLA3.cjs} +28 -5
- package/dist/AWSLambdaFunction-C-fuCLA3.cjs.map +1 -0
- package/dist/AWSLambdaFunction-CAm9r5ZX.d.mts +30 -0
- package/dist/{AWSLambdaFunction-cL8A169J.mjs → AWSLambdaFunction-H65WfXLt.mjs} +28 -5
- package/dist/AWSLambdaFunction-H65WfXLt.mjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-eDQgPNLH.d.mts → AmazonApiGatewayEndpointAdaptor-4hPy5vty.d.mts} +4 -4
- package/dist/{AmazonApiGatewayEndpointAdaptor-CIEhW1TQ.mjs → AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs} +6 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-H8YvtfQm.cjs → AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs} +6 -2
- package/dist/AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-CwItKPz2.d.cts → AmazonApiGatewayEndpointAdaptor-ro0RMLzr.d.cts} +4 -4
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-B36zXLJ7.mjs → AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs} +2 -2
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-B36zXLJ7.mjs.map → AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-DaCvUL6y.d.cts → AmazonApiGatewayV1EndpointAdaptor-BWJWKqQT.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-0n71d3gq.cjs → AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs} +2 -2
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-0n71d3gq.cjs.map → AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-CnGVpA38.d.mts → AmazonApiGatewayV1EndpointAdaptor-hyR-WwyP.d.mts} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-CE3wZEb8.mjs → AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs} +2 -2
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-CE3wZEb8.mjs.map → AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DtU3Cb8F.cjs → AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs} +2 -2
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DtU3Cb8F.cjs.map → AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DA1PH0nc.d.cts → AmazonApiGatewayV2EndpointAdaptor-D1Irdggp.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-BELz2ijs.d.mts → AmazonApiGatewayV2EndpointAdaptor-DX3SuI5S.d.mts} +3 -3
- package/dist/{Authorizer-BRCVPz_O.d.mts → Authorizer-BTmly8ps.d.cts} +1 -1
- package/dist/{Authorizer-DG54w1m2.d.cts → Authorizer-pmPvIVgv.d.mts} +1 -1
- package/dist/{BaseFunctionBuilder-CT7p10K1.mjs → BaseFunctionBuilder-B5gkW0Kt.mjs} +10 -1
- package/dist/BaseFunctionBuilder-B5gkW0Kt.mjs.map +1 -0
- package/dist/{BaseFunctionBuilder-B8rT07QR.cjs → BaseFunctionBuilder-C5Se7pdL.cjs} +10 -1
- package/dist/BaseFunctionBuilder-C5Se7pdL.cjs.map +1 -0
- package/dist/{BaseFunctionBuilder-DilipY1y.d.mts → BaseFunctionBuilder-CbDnPZpD.d.mts} +10 -4
- package/dist/{BaseFunctionBuilder-Cf0op65o.d.cts → BaseFunctionBuilder-DUZMbEr3.d.cts} +10 -4
- package/dist/{Cron-Bnd-2pgE.cjs → Cron-Bi3QOge_.cjs} +4 -4
- package/dist/Cron-Bi3QOge_.cjs.map +1 -0
- package/dist/{Cron-6lOgKqSA.d.cts → Cron-COdfP0Jd.d.cts} +4 -4
- package/dist/{Cron-BH_07atD.d.mts → Cron-D8cn_ahj.d.mts} +4 -4
- package/dist/{Cron-DNRjf2cp.mjs → Cron-Dy_HW2Vv.mjs} +4 -4
- package/dist/Cron-Dy_HW2Vv.mjs.map +1 -0
- package/dist/{CronBuilder-DdR2TuQa.mjs → CronBuilder-Bl3A2Zp4.mjs} +13 -4
- package/dist/CronBuilder-Bl3A2Zp4.mjs.map +1 -0
- package/dist/{CronBuilder-5oK2AL2n.d.cts → CronBuilder-DntF6H3A.d.cts} +17 -12
- package/dist/{CronBuilder-D2b4zY4l.d.mts → CronBuilder-DoMnSs_0.d.mts} +17 -12
- package/dist/{CronBuilder-dtw4ZyH6.cjs → CronBuilder-Dv_w7Yri.cjs} +13 -4
- package/dist/CronBuilder-Dv_w7Yri.cjs.map +1 -0
- package/dist/{Endpoint-DuZlyjd4.d.mts → Endpoint-Bbs_sFvg.d.mts} +49 -20
- package/dist/{Endpoint-Cs-MsYlY.d.cts → Endpoint-Bu8Phz6y.d.cts} +49 -20
- package/dist/{Endpoint-B9PryZES.cjs → Endpoint-DDpF7NO1.cjs} +11 -6
- package/dist/Endpoint-DDpF7NO1.cjs.map +1 -0
- package/dist/{Endpoint-B69TqESg.mjs → Endpoint-S6Yh2_PN.mjs} +11 -6
- package/dist/Endpoint-S6Yh2_PN.mjs.map +1 -0
- package/dist/{EndpointBuilder-C-PHInEW.d.cts → EndpointBuilder-CPxmF_w7.d.cts} +30 -13
- package/dist/{EndpointBuilder-BrB-K1jO.d.mts → EndpointBuilder-Csfyfjd7.d.mts} +30 -13
- package/dist/{EndpointBuilder-DofwCnWJ.cjs → EndpointBuilder-DpGmObMb.cjs} +25 -4
- package/dist/EndpointBuilder-DpGmObMb.cjs.map +1 -0
- package/dist/{EndpointBuilder-DnVL-EU_.mjs → EndpointBuilder-aE2E6WTx.mjs} +25 -4
- package/dist/EndpointBuilder-aE2E6WTx.mjs.map +1 -0
- package/dist/{EndpointFactory-6zNpVSYp.d.mts → EndpointFactory-BU_R-9LH.d.mts} +10 -10
- package/dist/{EndpointFactory-Ba9mx9MU.cjs → EndpointFactory-BfH6mjJ3.cjs} +2 -2
- package/dist/EndpointFactory-BfH6mjJ3.cjs.map +1 -0
- package/dist/{EndpointFactory-e5WYVR6t.d.cts → EndpointFactory-D0Ql2Ofm.d.cts} +11 -11
- package/dist/{EndpointFactory-pPaIGFHV.mjs → EndpointFactory-D4leYk1N.mjs} +2 -2
- package/dist/EndpointFactory-D4leYk1N.mjs.map +1 -0
- package/dist/{Function-CO-s2pB8.cjs → Function-DagDbeXo.cjs} +3 -2
- package/dist/Function-DagDbeXo.cjs.map +1 -0
- package/dist/{Function-COnc-tWM.mjs → Function-DfKsM5Kx.mjs} +3 -2
- package/dist/Function-DfKsM5Kx.mjs.map +1 -0
- package/dist/{Function-G3JPHMaY.d.mts → Function-V9M9UVHp.d.mts} +24 -7
- package/dist/{Function-6EWabl_X.d.cts → Function-VI1TB3Mh.d.cts} +24 -7
- package/dist/{FunctionBuilder-CMhLQ4dt.mjs → FunctionBuilder-CVT7bG2o.mjs} +20 -4
- package/dist/FunctionBuilder-CVT7bG2o.mjs.map +1 -0
- package/dist/{FunctionBuilder-B3fpp3hA.d.cts → FunctionBuilder-CjVEFTYC.d.cts} +22 -12
- package/dist/{FunctionBuilder-ByaB_LQ4.d.mts → FunctionBuilder-D1ofSeMd.d.mts} +22 -12
- package/dist/{FunctionBuilder-_hMwZUof.cjs → FunctionBuilder-DXvG_XD-.cjs} +20 -4
- package/dist/FunctionBuilder-DXvG_XD-.cjs.map +1 -0
- package/dist/FunctionExecutionWrapper-Bubnr0zA.mjs +101 -0
- package/dist/FunctionExecutionWrapper-Bubnr0zA.mjs.map +1 -0
- package/dist/FunctionExecutionWrapper-CwtwYozd.d.cts +48 -0
- package/dist/FunctionExecutionWrapper-DkNycmOh.cjs +107 -0
- package/dist/FunctionExecutionWrapper-DkNycmOh.cjs.map +1 -0
- package/dist/FunctionExecutionWrapper-rhbIYT0Q.d.mts +48 -0
- package/dist/{HonoEndpointAdaptor-Cw2if5cG.cjs → HonoEndpointAdaptor-CfLRHHFw.cjs} +8 -4
- package/dist/HonoEndpointAdaptor-CfLRHHFw.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-BElil8O5.d.mts → HonoEndpointAdaptor-DANYfDu9.d.mts} +7 -7
- package/dist/{HonoEndpointAdaptor-DAfnTFVS.mjs → HonoEndpointAdaptor-DuyE06nH.mjs} +8 -4
- package/dist/HonoEndpointAdaptor-DuyE06nH.mjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-DSHl8ZCY.d.cts → HonoEndpointAdaptor-_uLz8Bak.d.cts} +7 -7
- package/dist/{Subscriber-D-FPWts6.cjs → Subscriber-Bdh8rMSL.cjs} +1 -1
- package/dist/{Subscriber-D-FPWts6.cjs.map → Subscriber-Bdh8rMSL.cjs.map} +1 -1
- package/dist/{Subscriber-CGb8LjZa.mjs → Subscriber-CJOWwaw1.mjs} +1 -1
- package/dist/{Subscriber-CGb8LjZa.mjs.map → Subscriber-CJOWwaw1.mjs.map} +1 -1
- package/dist/{SubscriberBuilder-BcAspHv9.mjs → SubscriberBuilder-BWQmiYd8.mjs} +2 -2
- package/dist/{SubscriberBuilder-BcAspHv9.mjs.map → SubscriberBuilder-BWQmiYd8.mjs.map} +1 -1
- package/dist/{SubscriberBuilder-BfE2cL1q.cjs → SubscriberBuilder-DieD_60p.cjs} +2 -2
- package/dist/{SubscriberBuilder-BfE2cL1q.cjs.map → SubscriberBuilder-DieD_60p.cjs.map} +1 -1
- package/dist/{TestEndpointAdaptor-DubQOJk_.mjs → TestEndpointAdaptor-BEyZa0Yg.mjs} +7 -3
- package/dist/TestEndpointAdaptor-BEyZa0Yg.mjs.map +1 -0
- package/dist/{TestEndpointAdaptor-Bn1WRFph.cjs → TestEndpointAdaptor-C8425RJ0.cjs} +7 -3
- package/dist/TestEndpointAdaptor-C8425RJ0.cjs.map +1 -0
- package/dist/{TestEndpointAdaptor-o-xtSyQ3.d.cts → TestEndpointAdaptor-H5To8PH7.d.cts} +2 -2
- package/dist/{TestEndpointAdaptor-DnlAA_rm.d.mts → TestEndpointAdaptor-jxn68ayg.d.mts} +2 -2
- package/dist/adaptors/aws.cjs +10 -10
- package/dist/adaptors/aws.d.cts +11 -11
- package/dist/adaptors/aws.d.mts +11 -11
- package/dist/adaptors/aws.mjs +10 -10
- package/dist/adaptors/hono.cjs +7 -7
- package/dist/adaptors/hono.d.cts +7 -7
- package/dist/adaptors/hono.d.mts +7 -7
- package/dist/adaptors/hono.mjs +7 -7
- package/dist/adaptors/testing.cjs +6 -6
- package/dist/adaptors/testing.d.cts +7 -7
- package/dist/adaptors/testing.d.mts +7 -7
- package/dist/adaptors/testing.mjs +6 -6
- package/dist/crons/Cron.cjs +5 -5
- package/dist/crons/Cron.d.cts +5 -5
- package/dist/crons/Cron.d.mts +5 -5
- package/dist/crons/Cron.mjs +5 -5
- package/dist/crons/CronBuilder.cjs +6 -6
- package/dist/crons/CronBuilder.d.cts +6 -6
- package/dist/crons/CronBuilder.d.mts +6 -6
- package/dist/crons/CronBuilder.mjs +6 -6
- package/dist/crons/index.cjs +6 -6
- package/dist/crons/index.d.cts +10 -10
- package/dist/crons/index.d.mts +10 -10
- package/dist/crons/index.mjs +6 -6
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +6 -6
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +7 -7
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +7 -7
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +6 -6
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +7 -7
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +8 -8
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +8 -8
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +7 -7
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +7 -7
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +8 -8
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +8 -8
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +7 -7
- package/dist/endpoints/Authorizer.d.cts +1 -1
- package/dist/endpoints/Authorizer.d.mts +1 -1
- package/dist/endpoints/Endpoint.cjs +5 -5
- package/dist/endpoints/Endpoint.d.cts +6 -6
- package/dist/endpoints/Endpoint.d.mts +6 -6
- package/dist/endpoints/Endpoint.mjs +5 -5
- package/dist/endpoints/EndpointBuilder.cjs +6 -6
- package/dist/endpoints/EndpointBuilder.d.cts +7 -7
- package/dist/endpoints/EndpointBuilder.d.mts +7 -7
- package/dist/endpoints/EndpointBuilder.mjs +6 -6
- package/dist/endpoints/EndpointFactory.cjs +7 -7
- package/dist/endpoints/EndpointFactory.d.cts +8 -8
- package/dist/endpoints/EndpointFactory.d.mts +8 -8
- package/dist/endpoints/EndpointFactory.mjs +7 -7
- package/dist/endpoints/HonoEndpointAdaptor.cjs +7 -7
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +7 -7
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +7 -7
- package/dist/endpoints/HonoEndpointAdaptor.mjs +7 -7
- package/dist/endpoints/TestEndpointAdaptor.cjs +6 -6
- package/dist/endpoints/TestEndpointAdaptor.d.cts +7 -7
- package/dist/endpoints/TestEndpointAdaptor.d.mts +7 -7
- package/dist/endpoints/TestEndpointAdaptor.mjs +6 -6
- package/dist/endpoints/audit.d.cts +6 -6
- package/dist/endpoints/audit.d.mts +6 -6
- package/dist/endpoints/helpers.cjs +6 -6
- package/dist/endpoints/helpers.d.cts +6 -6
- package/dist/endpoints/helpers.d.mts +6 -6
- package/dist/endpoints/helpers.mjs +6 -6
- package/dist/endpoints/index.cjs +7 -7
- package/dist/endpoints/index.d.cts +10 -10
- package/dist/endpoints/index.d.mts +10 -10
- package/dist/endpoints/index.mjs +7 -7
- package/dist/endpoints/processAudits.d.cts +7 -7
- package/dist/endpoints/processAudits.d.mts +7 -7
- package/dist/functions/AWSLambdaFunction.cjs +5 -5
- package/dist/functions/AWSLambdaFunction.d.cts +3 -3
- package/dist/functions/AWSLambdaFunction.d.mts +3 -3
- package/dist/functions/AWSLambdaFunction.mjs +5 -5
- package/dist/functions/BaseFunctionBuilder.cjs +1 -1
- package/dist/functions/BaseFunctionBuilder.d.cts +1 -1
- package/dist/functions/BaseFunctionBuilder.d.mts +1 -1
- package/dist/functions/BaseFunctionBuilder.mjs +1 -1
- package/dist/functions/Function.cjs +1 -1
- package/dist/functions/Function.d.cts +1 -1
- package/dist/functions/Function.d.mts +1 -1
- package/dist/functions/Function.mjs +1 -1
- package/dist/functions/FunctionBuilder.cjs +3 -3
- package/dist/functions/FunctionBuilder.d.cts +3 -3
- package/dist/functions/FunctionBuilder.d.mts +3 -3
- package/dist/functions/FunctionBuilder.mjs +3 -3
- package/dist/functions/FunctionExecutionWrapper.cjs +4 -4
- package/dist/functions/FunctionExecutionWrapper.d.cts +2 -2
- package/dist/functions/FunctionExecutionWrapper.d.mts +2 -2
- package/dist/functions/FunctionExecutionWrapper.mjs +4 -4
- package/dist/functions/TestFunctionAdaptor.cjs +37 -4
- package/dist/functions/TestFunctionAdaptor.cjs.map +1 -1
- package/dist/functions/TestFunctionAdaptor.d.cts +9 -6
- package/dist/functions/TestFunctionAdaptor.d.mts +9 -6
- package/dist/functions/TestFunctionAdaptor.mjs +37 -4
- package/dist/functions/TestFunctionAdaptor.mjs.map +1 -1
- package/dist/functions/index.cjs +4 -4
- package/dist/functions/index.d.cts +4 -4
- package/dist/functions/index.d.mts +4 -4
- package/dist/functions/index.mjs +4 -4
- package/dist/{functions-D03lqK-r.cjs → functions-FCb-wWFC.cjs} +2 -2
- package/dist/{functions-D03lqK-r.cjs.map → functions-FCb-wWFC.cjs.map} +1 -1
- package/dist/functions-JhRsNoAZ.mjs +8 -0
- package/dist/{functions-BYqZAob8.mjs.map → functions-JhRsNoAZ.mjs.map} +1 -1
- package/dist/{helpers-BPDogwac.mjs → helpers-2CLKTnRm.mjs} +2 -2
- package/dist/{helpers-BPDogwac.mjs.map → helpers-2CLKTnRm.mjs.map} +1 -1
- package/dist/{helpers-BApRyhly.cjs → helpers-Khuhi_Qx.cjs} +2 -2
- package/dist/{helpers-BApRyhly.cjs.map → helpers-Khuhi_Qx.cjs.map} +1 -1
- package/dist/{index-CUg_hSq-.d.cts → index-DRf5AP3P.d.mts} +4 -3
- package/dist/index-twsdbZWU.d.cts +10 -0
- package/dist/processAudits-BFokHhCO.cjs.map +1 -1
- package/dist/processAudits-DfcB-X-4.mjs.map +1 -1
- package/dist/publisher-Bw4770Hi.mjs.map +1 -1
- package/dist/publisher-lFQleddL.cjs.map +1 -1
- package/dist/publisher.d.cts +2 -1
- package/dist/publisher.d.mts +2 -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.mts +2 -2
- package/dist/subscribers/index.mjs +2 -2
- package/package.json +7 -7
- package/src/crons/Cron.ts +12 -3
- package/src/crons/CronBuilder.ts +85 -13
- package/src/crons/__tests__/CronBuilder.state-isolation.spec.ts +2 -2
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +29 -6
- package/src/endpoints/Endpoint.ts +156 -40
- package/src/endpoints/EndpointBuilder.ts +123 -17
- package/src/endpoints/EndpointFactory.ts +5 -1
- package/src/endpoints/HonoEndpointAdaptor.ts +35 -5
- package/src/endpoints/TestEndpointAdaptor.ts +22 -2
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +1 -1
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.audits.spec.ts +2 -2
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +9 -9
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.kysely-audit.integration.spec.ts +79 -40
- package/src/endpoints/__tests__/Endpoint.cookies.spec.ts +3 -1
- package/src/endpoints/__tests__/Endpoint.manifest.spec.ts +1 -1
- package/src/endpoints/__tests__/EndpointBuilder.audit.spec.ts +35 -11
- package/src/endpoints/__tests__/EndpointFactory.authorizers.spec.ts +51 -14
- package/src/endpoints/__tests__/EndpointFactory.reference-audit.spec.ts +8 -8
- package/src/endpoints/__tests__/EndpointFactory.state-isolation.spec.ts +11 -11
- package/src/endpoints/__tests__/HonoEndpointAdaptor.audit-transactions.spec.ts +44 -26
- package/src/endpoints/__tests__/HonoEndpointAdaptor.audits.spec.ts +10 -10
- package/src/endpoints/__tests__/HonoEndpointAdaptor.events.spec.ts +8 -8
- package/src/endpoints/__tests__/HonoEndpointAdaptor.kysely-audit.integration.spec.ts +446 -61
- package/src/endpoints/__tests__/HonoEndpointAdaptor.openapi.spec.ts +4 -4
- package/src/endpoints/audit.ts +1 -1
- package/src/endpoints/processAudits.ts +32 -23
- package/src/functions/AWSLambdaFunction.ts +125 -12
- package/src/functions/BaseFunctionBuilder.ts +51 -3
- package/src/functions/Function.ts +73 -9
- package/src/functions/FunctionBuilder.ts +153 -17
- package/src/functions/FunctionExecutionWrapper.ts +133 -2
- package/src/functions/TestFunctionAdaptor.ts +94 -8
- package/src/functions/__tests__/AWSLambdaFunctionAdaptor.spec.ts +82 -0
- package/src/functions/__tests__/Function.audits.spec.ts +393 -0
- package/src/functions/__tests__/Function.spec.ts +76 -0
- package/src/functions/__tests__/FunctionBuilder.state-isolation.spec.ts +11 -5
- package/src/publisher.ts +12 -1
- package/dist/AWSLambdaFunction-DMxScuaw.cjs.map +0 -1
- package/dist/AWSLambdaFunction-DSB2oaFG.d.mts +0 -27
- package/dist/AWSLambdaFunction-cL8A169J.mjs.map +0 -1
- package/dist/AWSLambdaFunction-t6q2o8EL.d.cts +0 -27
- package/dist/AmazonApiGatewayEndpointAdaptor-CIEhW1TQ.mjs.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-H8YvtfQm.cjs.map +0 -1
- package/dist/BaseFunctionBuilder-B8rT07QR.cjs.map +0 -1
- package/dist/BaseFunctionBuilder-CT7p10K1.mjs.map +0 -1
- package/dist/Cron-Bnd-2pgE.cjs.map +0 -1
- package/dist/Cron-DNRjf2cp.mjs.map +0 -1
- package/dist/CronBuilder-DdR2TuQa.mjs.map +0 -1
- package/dist/CronBuilder-dtw4ZyH6.cjs.map +0 -1
- package/dist/Endpoint-B69TqESg.mjs.map +0 -1
- package/dist/Endpoint-B9PryZES.cjs.map +0 -1
- package/dist/EndpointBuilder-DnVL-EU_.mjs.map +0 -1
- package/dist/EndpointBuilder-DofwCnWJ.cjs.map +0 -1
- package/dist/EndpointFactory-Ba9mx9MU.cjs.map +0 -1
- package/dist/EndpointFactory-pPaIGFHV.mjs.map +0 -1
- package/dist/Function-CO-s2pB8.cjs.map +0 -1
- package/dist/Function-COnc-tWM.mjs.map +0 -1
- package/dist/FunctionBuilder-CMhLQ4dt.mjs.map +0 -1
- package/dist/FunctionBuilder-_hMwZUof.cjs.map +0 -1
- package/dist/FunctionExecutionWrapper-Ci-ookJG.d.cts +0 -24
- package/dist/FunctionExecutionWrapper-DHFMLrOl.d.mts +0 -24
- package/dist/FunctionExecutionWrapper-i9v5L3Av.mjs +0 -36
- package/dist/FunctionExecutionWrapper-i9v5L3Av.mjs.map +0 -1
- package/dist/FunctionExecutionWrapper-sxJNTpuc.cjs +0 -42
- package/dist/FunctionExecutionWrapper-sxJNTpuc.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-Cw2if5cG.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-DAfnTFVS.mjs.map +0 -1
- package/dist/TestEndpointAdaptor-Bn1WRFph.cjs.map +0 -1
- package/dist/TestEndpointAdaptor-DubQOJk_.mjs.map +0 -1
- package/dist/functions-BYqZAob8.mjs +0 -8
- package/dist/index-D-a7e2gv.d.mts +0 -9
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AuditableAction } from '@geekmidas/audit';
|
|
2
2
|
import {
|
|
3
|
-
KyselyAuditStorage,
|
|
4
3
|
type AuditLogTable,
|
|
4
|
+
KyselyAuditStorage,
|
|
5
5
|
} from '@geekmidas/audit/kysely';
|
|
6
6
|
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
7
7
|
import type { Logger } from '@geekmidas/logger';
|
|
@@ -193,10 +193,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
193
193
|
expect(response.status).toBe(201);
|
|
194
194
|
|
|
195
195
|
// Verify audit was written to the real database
|
|
196
|
-
const auditsInDb = await db
|
|
197
|
-
.selectFrom('auditLogs')
|
|
198
|
-
.selectAll()
|
|
199
|
-
.execute();
|
|
196
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
200
197
|
|
|
201
198
|
expect(auditsInDb).toHaveLength(1);
|
|
202
199
|
expect(auditsInDb[0].type).toBe('user.created');
|
|
@@ -265,10 +262,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
265
262
|
expect(response.status).toBe(500);
|
|
266
263
|
|
|
267
264
|
// Verify no audit was written
|
|
268
|
-
const auditsInDb = await db
|
|
269
|
-
.selectFrom('auditLogs')
|
|
270
|
-
.selectAll()
|
|
271
|
-
.execute();
|
|
265
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
272
266
|
|
|
273
267
|
expect(auditsInDb).toHaveLength(0);
|
|
274
268
|
});
|
|
@@ -292,15 +286,21 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
292
286
|
route: '/users',
|
|
293
287
|
method: 'POST',
|
|
294
288
|
fn: async (
|
|
295
|
-
ctx: EndpointContext<
|
|
289
|
+
ctx: EndpointContext<
|
|
290
|
+
undefined,
|
|
291
|
+
[],
|
|
292
|
+
Logger,
|
|
293
|
+
unknown,
|
|
294
|
+
TestAuditAction,
|
|
295
|
+
undefined,
|
|
296
|
+
KyselyAuditStorage<TestDatabase>
|
|
297
|
+
>,
|
|
296
298
|
) => {
|
|
297
|
-
// Manual audit in handler
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
});
|
|
303
|
-
}
|
|
299
|
+
// Manual audit in handler - auditor is guaranteed to exist when TAuditStorage is configured
|
|
300
|
+
ctx.auditor.audit('user.created', {
|
|
301
|
+
userId: 42,
|
|
302
|
+
email: 'manual@example.com',
|
|
303
|
+
});
|
|
304
304
|
|
|
305
305
|
return { id: 42, email: 'manual@example.com' };
|
|
306
306
|
},
|
|
@@ -334,10 +334,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
334
334
|
expect(response.status).toBe(201);
|
|
335
335
|
|
|
336
336
|
// Verify manual audit was written
|
|
337
|
-
const auditsInDb = await db
|
|
338
|
-
.selectFrom('auditLogs')
|
|
339
|
-
.selectAll()
|
|
340
|
-
.execute();
|
|
337
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
341
338
|
|
|
342
339
|
expect(auditsInDb).toHaveLength(1);
|
|
343
340
|
expect(auditsInDb[0].type).toBe('user.created');
|
|
@@ -364,15 +361,21 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
364
361
|
route: '/users',
|
|
365
362
|
method: 'POST',
|
|
366
363
|
fn: async (
|
|
367
|
-
ctx: EndpointContext<
|
|
364
|
+
ctx: EndpointContext<
|
|
365
|
+
undefined,
|
|
366
|
+
[],
|
|
367
|
+
Logger,
|
|
368
|
+
unknown,
|
|
369
|
+
TestAuditAction,
|
|
370
|
+
undefined,
|
|
371
|
+
KyselyAuditStorage<TestDatabase>
|
|
372
|
+
>,
|
|
368
373
|
) => {
|
|
369
|
-
// Manual audit before failure
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
});
|
|
375
|
-
}
|
|
374
|
+
// Manual audit before failure - auditor is guaranteed to exist
|
|
375
|
+
ctx.auditor.audit('user.created', {
|
|
376
|
+
userId: 99,
|
|
377
|
+
email: 'shouldnotexist@example.com',
|
|
378
|
+
});
|
|
376
379
|
|
|
377
380
|
// Fail after audit
|
|
378
381
|
throw new Error('Handler failed after audit');
|
|
@@ -407,10 +410,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
407
410
|
expect(response.status).toBe(500);
|
|
408
411
|
|
|
409
412
|
// Verify no audit was written (transaction rolled back)
|
|
410
|
-
const auditsInDb = await db
|
|
411
|
-
.selectFrom('auditLogs')
|
|
412
|
-
.selectAll()
|
|
413
|
-
.execute();
|
|
413
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
414
414
|
|
|
415
415
|
expect(auditsInDb).toHaveLength(0);
|
|
416
416
|
});
|
|
@@ -444,7 +444,9 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
444
444
|
[typeof databaseService],
|
|
445
445
|
Logger,
|
|
446
446
|
unknown,
|
|
447
|
-
TestAuditAction
|
|
447
|
+
TestAuditAction,
|
|
448
|
+
undefined,
|
|
449
|
+
KyselyAuditStorage<TestDatabase>
|
|
448
450
|
>,
|
|
449
451
|
) => {
|
|
450
452
|
const database = ctx.services.database;
|
|
@@ -456,13 +458,11 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
456
458
|
.returningAll()
|
|
457
459
|
.executeTakeFirstOrThrow();
|
|
458
460
|
|
|
459
|
-
// Record audit
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
});
|
|
465
|
-
}
|
|
461
|
+
// Record audit - auditor is guaranteed to exist
|
|
462
|
+
ctx.auditor.audit('user.created', {
|
|
463
|
+
userId: user.id,
|
|
464
|
+
email: user.email,
|
|
465
|
+
});
|
|
466
466
|
|
|
467
467
|
return { id: user.id, email: user.email };
|
|
468
468
|
},
|
|
@@ -501,10 +501,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
501
501
|
expect(usersInDb[0].email).toBe('success@example.com');
|
|
502
502
|
|
|
503
503
|
// Verify audit was written
|
|
504
|
-
const auditsInDb = await db
|
|
505
|
-
.selectFrom('auditLogs')
|
|
506
|
-
.selectAll()
|
|
507
|
-
.execute();
|
|
504
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
508
505
|
expect(auditsInDb).toHaveLength(1);
|
|
509
506
|
expect(auditsInDb[0].type).toBe('user.created');
|
|
510
507
|
expect(auditsInDb[0].payload).toEqual({
|
|
@@ -541,15 +538,21 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
541
538
|
route: '/users',
|
|
542
539
|
method: 'POST',
|
|
543
540
|
fn: async (
|
|
544
|
-
ctx: EndpointContext<
|
|
541
|
+
ctx: EndpointContext<
|
|
542
|
+
undefined,
|
|
543
|
+
[],
|
|
544
|
+
Logger,
|
|
545
|
+
unknown,
|
|
546
|
+
TestAuditAction,
|
|
547
|
+
undefined,
|
|
548
|
+
KyselyAuditStorage<TestDatabase>
|
|
549
|
+
>,
|
|
545
550
|
) => {
|
|
546
|
-
// Manual audit
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
});
|
|
552
|
-
}
|
|
551
|
+
// Manual audit - auditor is guaranteed to exist
|
|
552
|
+
ctx.auditor.audit('user.updated', {
|
|
553
|
+
userId: 100,
|
|
554
|
+
changes: ['verified'],
|
|
555
|
+
});
|
|
553
556
|
|
|
554
557
|
return { id: 100, email: 'combined@example.com' };
|
|
555
558
|
},
|
|
@@ -583,10 +586,7 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
583
586
|
expect(response.status).toBe(201);
|
|
584
587
|
|
|
585
588
|
// Verify both audits were written
|
|
586
|
-
const auditsInDb = await db
|
|
587
|
-
.selectFrom('auditLogs')
|
|
588
|
-
.selectAll()
|
|
589
|
-
.execute();
|
|
589
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
590
590
|
|
|
591
591
|
expect(auditsInDb).toHaveLength(2);
|
|
592
592
|
|
|
@@ -665,14 +665,399 @@ describe('HonoEndpoint Kysely Audit Integration', () => {
|
|
|
665
665
|
expect(response.status).toBe(201);
|
|
666
666
|
|
|
667
667
|
// Verify actor was included in audit
|
|
668
|
-
const auditsInDb = await db
|
|
669
|
-
.selectFrom('auditLogs')
|
|
670
|
-
.selectAll()
|
|
671
|
-
.execute();
|
|
668
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
672
669
|
|
|
673
670
|
expect(auditsInDb).toHaveLength(1);
|
|
674
671
|
expect(auditsInDb[0].actorId).toBe('user-123');
|
|
675
672
|
expect(auditsInDb[0].actorType).toBe('user');
|
|
676
673
|
});
|
|
677
674
|
});
|
|
675
|
+
|
|
676
|
+
describe('database service name matching', () => {
|
|
677
|
+
it('should use audit transaction as db when databaseServiceName matches', async () => {
|
|
678
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
679
|
+
|
|
680
|
+
// Create audit storage WITH databaseServiceName
|
|
681
|
+
const auditStorageWithServiceName = new KyselyAuditStorage({
|
|
682
|
+
db,
|
|
683
|
+
tableName: 'auditLogs',
|
|
684
|
+
databaseServiceName: 'database', // Matches the database service
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
const databaseService: Service<'database', Kysely<TestDatabase>> = {
|
|
688
|
+
serviceName: 'database' as const,
|
|
689
|
+
register: vi.fn().mockResolvedValue(db),
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
const auditStorageService: Service<
|
|
693
|
+
'auditStorage',
|
|
694
|
+
KyselyAuditStorage<TestDatabase>
|
|
695
|
+
> = {
|
|
696
|
+
serviceName: 'auditStorage' as const,
|
|
697
|
+
register: vi.fn().mockResolvedValue(auditStorageWithServiceName),
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
const outputSchema = z.object({ id: z.number(), email: z.string() });
|
|
701
|
+
|
|
702
|
+
let receivedDbIsTransaction = false;
|
|
703
|
+
|
|
704
|
+
const endpoint = new Endpoint({
|
|
705
|
+
route: '/users',
|
|
706
|
+
method: 'POST',
|
|
707
|
+
fn: async (
|
|
708
|
+
ctx: EndpointContext<
|
|
709
|
+
undefined,
|
|
710
|
+
[typeof databaseService],
|
|
711
|
+
Logger,
|
|
712
|
+
unknown,
|
|
713
|
+
TestAuditAction,
|
|
714
|
+
Kysely<TestDatabase>,
|
|
715
|
+
KyselyAuditStorage<TestDatabase>
|
|
716
|
+
>,
|
|
717
|
+
) => {
|
|
718
|
+
// Check if db is a transaction (has isTransaction property from Kysely)
|
|
719
|
+
// When databaseServiceName matches, db should be the transaction
|
|
720
|
+
receivedDbIsTransaction = (ctx.db as any)?.isTransaction === true;
|
|
721
|
+
|
|
722
|
+
// Insert user using ctx.db (should be the transaction)
|
|
723
|
+
const user = await ctx.db
|
|
724
|
+
.insertInto('users')
|
|
725
|
+
.values({ name: 'Transaction User', email: 'trx@example.com' })
|
|
726
|
+
.returningAll()
|
|
727
|
+
.executeTakeFirstOrThrow();
|
|
728
|
+
|
|
729
|
+
// Record audit
|
|
730
|
+
ctx.auditor.audit('user.created', {
|
|
731
|
+
userId: user.id,
|
|
732
|
+
email: user.email,
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
return { id: user.id, email: user.email };
|
|
736
|
+
},
|
|
737
|
+
input: undefined,
|
|
738
|
+
output: outputSchema,
|
|
739
|
+
services: [databaseService],
|
|
740
|
+
logger: mockLogger,
|
|
741
|
+
timeout: undefined,
|
|
742
|
+
memorySize: undefined,
|
|
743
|
+
status: 201,
|
|
744
|
+
getSession: undefined,
|
|
745
|
+
authorize: undefined,
|
|
746
|
+
description: undefined,
|
|
747
|
+
events: [],
|
|
748
|
+
publisherService: undefined,
|
|
749
|
+
auditorStorageService: auditStorageService,
|
|
750
|
+
audits: [],
|
|
751
|
+
databaseService,
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
755
|
+
const app = new Hono();
|
|
756
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
757
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
758
|
+
|
|
759
|
+
const response = await app.request('/users', {
|
|
760
|
+
method: 'POST',
|
|
761
|
+
body: JSON.stringify({}),
|
|
762
|
+
headers: { 'Content-Type': 'application/json' },
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
expect(response.status).toBe(201);
|
|
766
|
+
expect(receivedDbIsTransaction).toBe(true);
|
|
767
|
+
|
|
768
|
+
// Verify both user and audit were committed
|
|
769
|
+
const usersInDb = await db.selectFrom('users').selectAll().execute();
|
|
770
|
+
expect(usersInDb).toHaveLength(1);
|
|
771
|
+
expect(usersInDb[0].email).toBe('trx@example.com');
|
|
772
|
+
|
|
773
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
774
|
+
expect(auditsInDb).toHaveLength(1);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
it('should use raw db when databaseServiceName does not match', async () => {
|
|
778
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
779
|
+
|
|
780
|
+
// Create audit storage with DIFFERENT databaseServiceName
|
|
781
|
+
const auditStorageWithDifferentServiceName = new KyselyAuditStorage({
|
|
782
|
+
db,
|
|
783
|
+
tableName: 'auditLogs',
|
|
784
|
+
databaseServiceName: 'auditDatabase', // Different from 'database'
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
const databaseService: Service<'database', Kysely<TestDatabase>> = {
|
|
788
|
+
serviceName: 'database' as const,
|
|
789
|
+
register: vi.fn().mockResolvedValue(db),
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const auditStorageService: Service<
|
|
793
|
+
'auditStorage',
|
|
794
|
+
KyselyAuditStorage<TestDatabase>
|
|
795
|
+
> = {
|
|
796
|
+
serviceName: 'auditStorage' as const,
|
|
797
|
+
register: vi
|
|
798
|
+
.fn()
|
|
799
|
+
.mockResolvedValue(auditStorageWithDifferentServiceName),
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
const outputSchema = z.object({ id: z.number(), email: z.string() });
|
|
803
|
+
|
|
804
|
+
let receivedDbIsTransaction = false;
|
|
805
|
+
|
|
806
|
+
const endpoint = new Endpoint({
|
|
807
|
+
route: '/users',
|
|
808
|
+
method: 'POST',
|
|
809
|
+
fn: async (
|
|
810
|
+
ctx: EndpointContext<
|
|
811
|
+
undefined,
|
|
812
|
+
[typeof databaseService],
|
|
813
|
+
Logger,
|
|
814
|
+
unknown,
|
|
815
|
+
TestAuditAction,
|
|
816
|
+
Kysely<TestDatabase>,
|
|
817
|
+
KyselyAuditStorage<TestDatabase>
|
|
818
|
+
>,
|
|
819
|
+
) => {
|
|
820
|
+
// When databaseServiceName doesn't match, db should be raw (not a transaction)
|
|
821
|
+
receivedDbIsTransaction = (ctx.db as any)?.isTransaction === true;
|
|
822
|
+
|
|
823
|
+
// Insert user using ctx.db (should be raw db, not transaction)
|
|
824
|
+
const user = await ctx.db
|
|
825
|
+
.insertInto('users')
|
|
826
|
+
.values({ name: 'Raw DB User', email: 'raw@example.com' })
|
|
827
|
+
.returningAll()
|
|
828
|
+
.executeTakeFirstOrThrow();
|
|
829
|
+
|
|
830
|
+
// Record audit
|
|
831
|
+
ctx.auditor.audit('user.created', {
|
|
832
|
+
userId: user.id,
|
|
833
|
+
email: user.email,
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
return { id: user.id, email: user.email };
|
|
837
|
+
},
|
|
838
|
+
input: undefined,
|
|
839
|
+
output: outputSchema,
|
|
840
|
+
services: [databaseService],
|
|
841
|
+
logger: mockLogger,
|
|
842
|
+
timeout: undefined,
|
|
843
|
+
memorySize: undefined,
|
|
844
|
+
status: 201,
|
|
845
|
+
getSession: undefined,
|
|
846
|
+
authorize: undefined,
|
|
847
|
+
description: undefined,
|
|
848
|
+
events: [],
|
|
849
|
+
publisherService: undefined,
|
|
850
|
+
auditorStorageService: auditStorageService,
|
|
851
|
+
audits: [],
|
|
852
|
+
databaseService,
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
856
|
+
const app = new Hono();
|
|
857
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
858
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
859
|
+
|
|
860
|
+
const response = await app.request('/users', {
|
|
861
|
+
method: 'POST',
|
|
862
|
+
body: JSON.stringify({}),
|
|
863
|
+
headers: { 'Content-Type': 'application/json' },
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
expect(response.status).toBe(201);
|
|
867
|
+
// db should NOT be a transaction since service names don't match
|
|
868
|
+
expect(receivedDbIsTransaction).toBe(false);
|
|
869
|
+
|
|
870
|
+
// Both should still be committed (but not in the same transaction)
|
|
871
|
+
const usersInDb = await db.selectFrom('users').selectAll().execute();
|
|
872
|
+
expect(usersInDb).toHaveLength(1);
|
|
873
|
+
|
|
874
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
875
|
+
expect(auditsInDb).toHaveLength(1);
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
it('should use raw db when databaseServiceName is not set on audit storage', async () => {
|
|
879
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
880
|
+
|
|
881
|
+
// Create audit storage WITHOUT databaseServiceName (uses default auditStorage from beforeAll)
|
|
882
|
+
const databaseService: Service<'database', Kysely<TestDatabase>> = {
|
|
883
|
+
serviceName: 'database' as const,
|
|
884
|
+
register: vi.fn().mockResolvedValue(db),
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
const auditStorageService: Service<
|
|
888
|
+
'auditStorage',
|
|
889
|
+
KyselyAuditStorage<TestDatabase>
|
|
890
|
+
> = {
|
|
891
|
+
serviceName: 'auditStorage' as const,
|
|
892
|
+
register: vi.fn().mockResolvedValue(auditStorage), // No databaseServiceName set
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
const outputSchema = z.object({ id: z.number(), email: z.string() });
|
|
896
|
+
|
|
897
|
+
let receivedDbIsTransaction = false;
|
|
898
|
+
|
|
899
|
+
const endpoint = new Endpoint({
|
|
900
|
+
route: '/users',
|
|
901
|
+
method: 'POST',
|
|
902
|
+
fn: async (
|
|
903
|
+
ctx: EndpointContext<
|
|
904
|
+
undefined,
|
|
905
|
+
[typeof databaseService],
|
|
906
|
+
Logger,
|
|
907
|
+
unknown,
|
|
908
|
+
TestAuditAction,
|
|
909
|
+
Kysely<TestDatabase>,
|
|
910
|
+
KyselyAuditStorage<TestDatabase>
|
|
911
|
+
>,
|
|
912
|
+
) => {
|
|
913
|
+
// When databaseServiceName is not set, db should be raw
|
|
914
|
+
receivedDbIsTransaction = (ctx.db as any)?.isTransaction === true;
|
|
915
|
+
|
|
916
|
+
const user = await ctx.db
|
|
917
|
+
.insertInto('users')
|
|
918
|
+
.values({
|
|
919
|
+
name: 'No ServiceName User',
|
|
920
|
+
email: 'noname@example.com',
|
|
921
|
+
})
|
|
922
|
+
.returningAll()
|
|
923
|
+
.executeTakeFirstOrThrow();
|
|
924
|
+
|
|
925
|
+
ctx.auditor.audit('user.created', {
|
|
926
|
+
userId: user.id,
|
|
927
|
+
email: user.email,
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
return { id: user.id, email: user.email };
|
|
931
|
+
},
|
|
932
|
+
input: undefined,
|
|
933
|
+
output: outputSchema,
|
|
934
|
+
services: [databaseService],
|
|
935
|
+
logger: mockLogger,
|
|
936
|
+
timeout: undefined,
|
|
937
|
+
memorySize: undefined,
|
|
938
|
+
status: 201,
|
|
939
|
+
getSession: undefined,
|
|
940
|
+
authorize: undefined,
|
|
941
|
+
description: undefined,
|
|
942
|
+
events: [],
|
|
943
|
+
publisherService: undefined,
|
|
944
|
+
auditorStorageService: auditStorageService,
|
|
945
|
+
audits: [],
|
|
946
|
+
databaseService,
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
950
|
+
const app = new Hono();
|
|
951
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
952
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
953
|
+
|
|
954
|
+
const response = await app.request('/users', {
|
|
955
|
+
method: 'POST',
|
|
956
|
+
body: JSON.stringify({}),
|
|
957
|
+
headers: { 'Content-Type': 'application/json' },
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
expect(response.status).toBe(201);
|
|
961
|
+
expect(receivedDbIsTransaction).toBe(false);
|
|
962
|
+
|
|
963
|
+
const usersInDb = await db.selectFrom('users').selectAll().execute();
|
|
964
|
+
expect(usersInDb).toHaveLength(1);
|
|
965
|
+
|
|
966
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
967
|
+
expect(auditsInDb).toHaveLength(1);
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
it('should rollback both user insert and audit when handler fails with matching databaseServiceName', async () => {
|
|
971
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
972
|
+
|
|
973
|
+
// Create audit storage WITH databaseServiceName
|
|
974
|
+
const auditStorageWithServiceName = new KyselyAuditStorage({
|
|
975
|
+
db,
|
|
976
|
+
tableName: 'auditLogs',
|
|
977
|
+
databaseServiceName: 'database',
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
const databaseService: Service<'database', Kysely<TestDatabase>> = {
|
|
981
|
+
serviceName: 'database' as const,
|
|
982
|
+
register: vi.fn().mockResolvedValue(db),
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
const auditStorageService: Service<
|
|
986
|
+
'auditStorage',
|
|
987
|
+
KyselyAuditStorage<TestDatabase>
|
|
988
|
+
> = {
|
|
989
|
+
serviceName: 'auditStorage' as const,
|
|
990
|
+
register: vi.fn().mockResolvedValue(auditStorageWithServiceName),
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
const outputSchema = z.object({ id: z.number(), email: z.string() });
|
|
994
|
+
|
|
995
|
+
const endpoint = new Endpoint({
|
|
996
|
+
route: '/users',
|
|
997
|
+
method: 'POST',
|
|
998
|
+
fn: async (
|
|
999
|
+
ctx: EndpointContext<
|
|
1000
|
+
undefined,
|
|
1001
|
+
[typeof databaseService],
|
|
1002
|
+
Logger,
|
|
1003
|
+
unknown,
|
|
1004
|
+
TestAuditAction,
|
|
1005
|
+
Kysely<TestDatabase>,
|
|
1006
|
+
KyselyAuditStorage<TestDatabase>
|
|
1007
|
+
>,
|
|
1008
|
+
) => {
|
|
1009
|
+
// Insert user (should be rolled back)
|
|
1010
|
+
const user = await ctx.db
|
|
1011
|
+
.insertInto('users')
|
|
1012
|
+
.values({ name: 'Rollback User', email: 'rollback@example.com' })
|
|
1013
|
+
.returningAll()
|
|
1014
|
+
.executeTakeFirstOrThrow();
|
|
1015
|
+
|
|
1016
|
+
// Record audit (should also be rolled back)
|
|
1017
|
+
ctx.auditor.audit('user.created', {
|
|
1018
|
+
userId: user.id,
|
|
1019
|
+
email: user.email,
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
// Fail after both operations
|
|
1023
|
+
throw new Error('Simulated failure');
|
|
1024
|
+
},
|
|
1025
|
+
input: undefined,
|
|
1026
|
+
output: outputSchema,
|
|
1027
|
+
services: [databaseService],
|
|
1028
|
+
logger: mockLogger,
|
|
1029
|
+
timeout: undefined,
|
|
1030
|
+
memorySize: undefined,
|
|
1031
|
+
status: 201,
|
|
1032
|
+
getSession: undefined,
|
|
1033
|
+
authorize: undefined,
|
|
1034
|
+
description: undefined,
|
|
1035
|
+
events: [],
|
|
1036
|
+
publisherService: undefined,
|
|
1037
|
+
auditorStorageService: auditStorageService,
|
|
1038
|
+
audits: [],
|
|
1039
|
+
databaseService,
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
1043
|
+
const app = new Hono();
|
|
1044
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
1045
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
1046
|
+
|
|
1047
|
+
const response = await app.request('/users', {
|
|
1048
|
+
method: 'POST',
|
|
1049
|
+
body: JSON.stringify({}),
|
|
1050
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1053
|
+
expect(response.status).toBe(500);
|
|
1054
|
+
|
|
1055
|
+
// Both should be rolled back since they're in the same transaction
|
|
1056
|
+
const usersInDb = await db.selectFrom('users').selectAll().execute();
|
|
1057
|
+
expect(usersInDb).toHaveLength(0);
|
|
1058
|
+
|
|
1059
|
+
const auditsInDb = await db.selectFrom('auditLogs').selectAll().execute();
|
|
1060
|
+
expect(auditsInDb).toHaveLength(0);
|
|
1061
|
+
});
|
|
1062
|
+
});
|
|
678
1063
|
});
|
|
@@ -36,7 +36,7 @@ describe('HonoEndpoint OpenAPI Documentation', () => {
|
|
|
36
36
|
services: [],
|
|
37
37
|
logger,
|
|
38
38
|
timeout: undefined,
|
|
39
|
-
|
|
39
|
+
memorySize: undefined,
|
|
40
40
|
authorize: undefined,
|
|
41
41
|
getSession: undefined,
|
|
42
42
|
status: undefined,
|
|
@@ -141,7 +141,7 @@ describe('HonoEndpoint OpenAPI Documentation', () => {
|
|
|
141
141
|
services: [],
|
|
142
142
|
logger,
|
|
143
143
|
timeout: undefined,
|
|
144
|
-
|
|
144
|
+
memorySize: undefined,
|
|
145
145
|
authorize: undefined,
|
|
146
146
|
getSession: undefined,
|
|
147
147
|
status: undefined,
|
|
@@ -182,7 +182,7 @@ describe('HonoEndpoint OpenAPI Documentation', () => {
|
|
|
182
182
|
services: [],
|
|
183
183
|
logger,
|
|
184
184
|
timeout: undefined,
|
|
185
|
-
|
|
185
|
+
memorySize: undefined,
|
|
186
186
|
authorize: undefined,
|
|
187
187
|
getSession: undefined,
|
|
188
188
|
status: undefined,
|
|
@@ -221,7 +221,7 @@ describe('HonoEndpoint OpenAPI Documentation', () => {
|
|
|
221
221
|
services: [],
|
|
222
222
|
logger,
|
|
223
223
|
timeout: undefined,
|
|
224
|
-
|
|
224
|
+
memorySize: undefined,
|
|
225
225
|
authorize: undefined,
|
|
226
226
|
getSession: undefined,
|
|
227
227
|
status: undefined,
|