@geekmidas/constructs 0.0.11 → 0.0.13
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-DcI_77u8.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-BTSGYZSx.mjs → AWSLambdaFunction-H65WfXLt.mjs} +28 -5
- package/dist/AWSLambdaFunction-H65WfXLt.mjs.map +1 -0
- package/dist/{AWSLambdaSubscriberAdaptor-mLOpS63x.d.mts → AWSLambdaSubscriberAdaptor-Cknp_nn1.d.cts} +4 -4
- package/dist/{AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs → AWSLambdaSubscriberAdaptor-CyFh7MN8.mjs} +1 -1
- package/dist/{AWSLambdaSubscriberAdaptor-G8y3YkWj.mjs.map → AWSLambdaSubscriberAdaptor-CyFh7MN8.mjs.map} +1 -1
- package/dist/{AWSLambdaSubscriberAdaptor-DX5NFdWf.d.cts → AWSLambdaSubscriberAdaptor-DpHzp-AM.d.mts} +4 -4
- package/dist/{AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs → AWSLambdaSubscriberAdaptor-Dum5bkw3.cjs} +1 -1
- package/dist/{AWSLambdaSubscriberAdaptor-CmPZ10JF.cjs.map → AWSLambdaSubscriberAdaptor-Dum5bkw3.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayEndpointAdaptor-CATWBIJo.d.mts → AmazonApiGatewayEndpointAdaptor-4hPy5vty.d.mts} +9 -8
- package/dist/{AmazonApiGatewayEndpointAdaptor-vi0D3dWg.mjs → AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs} +51 -16
- package/dist/AmazonApiGatewayEndpointAdaptor-C6Jk5HSy.mjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-BTqB3c1_.cjs → AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs} +51 -16
- package/dist/AmazonApiGatewayEndpointAdaptor-CI9L7Ucn.cjs.map +1 -0
- package/dist/{AmazonApiGatewayEndpointAdaptor-BwtDtS-i.d.cts → AmazonApiGatewayEndpointAdaptor-ro0RMLzr.d.cts} +8 -7
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-D2_u_zR6.mjs → AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-D2_u_zR6.mjs.map → AmazonApiGatewayV1EndpointAdaptor-BMy8DdNJ.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-B1AVk2MM.d.cts → AmazonApiGatewayV1EndpointAdaptor-BWJWKqQT.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-nwrtG5L9.cjs → AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs} +3 -3
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-nwrtG5L9.cjs.map → AmazonApiGatewayV1EndpointAdaptor-DYL1bCBS.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV1EndpointAdaptor-2Rd0LLz4.d.mts → AmazonApiGatewayV1EndpointAdaptor-hyR-WwyP.d.mts} +4 -4
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DoWAJ9oN.mjs → AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DoWAJ9oN.mjs.map → AmazonApiGatewayV2EndpointAdaptor-BU5wQMOe.mjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-FSIdXYV6.cjs → AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-FSIdXYV6.cjs.map → AmazonApiGatewayV2EndpointAdaptor-CPLCMeaN.cjs.map} +1 -1
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-DmY_QfjO.d.cts → AmazonApiGatewayV2EndpointAdaptor-D1Irdggp.d.cts} +3 -3
- package/dist/{AmazonApiGatewayV2EndpointAdaptor-cBDfwdBx.d.mts → AmazonApiGatewayV2EndpointAdaptor-DX3SuI5S.d.mts} +4 -4
- package/dist/{Authorizer-Bbk9ziuG.d.mts → Authorizer-BTmly8ps.d.cts} +1 -1
- package/dist/{Authorizer-iXsSB600.d.cts → Authorizer-pmPvIVgv.d.mts} +1 -1
- package/dist/{BaseFunctionBuilder-DSqF1r3a.mjs → BaseFunctionBuilder-B5gkW0Kt.mjs} +16 -2
- package/dist/BaseFunctionBuilder-B5gkW0Kt.mjs.map +1 -0
- package/dist/{BaseFunctionBuilder-bTDKP7bd.cjs → BaseFunctionBuilder-C5Se7pdL.cjs} +16 -2
- package/dist/BaseFunctionBuilder-C5Se7pdL.cjs.map +1 -0
- package/dist/{BaseFunctionBuilder-DOcm1heZ.d.mts → BaseFunctionBuilder-CbDnPZpD.d.mts} +13 -4
- package/dist/{BaseFunctionBuilder-hWNVKXQB.d.cts → BaseFunctionBuilder-DUZMbEr3.d.cts} +13 -4
- package/dist/{Construct-XCGKof_O.cjs → Construct-BYSPikVm.cjs} +8 -3
- package/dist/Construct-BYSPikVm.cjs.map +1 -0
- package/dist/{Construct-rZQg2yus.mjs → Construct-LWeB1rSQ.mjs} +8 -3
- package/dist/Construct-LWeB1rSQ.mjs.map +1 -0
- package/dist/{Construct-iDmbkZ3o.d.mts → Construct-ZPqE0vhn.d.mts} +5 -3
- package/dist/{Construct-zc8BkRSp.d.cts → Construct-dI_rgdSp.d.cts} +5 -3
- package/dist/Construct.cjs +1 -1
- package/dist/Construct.d.cts +1 -1
- package/dist/Construct.d.mts +1 -1
- package/dist/Construct.mjs +1 -1
- package/dist/{Cron-CYIhd0VE.cjs → Cron-Bi3QOge_.cjs} +5 -5
- package/dist/Cron-Bi3QOge_.cjs.map +1 -0
- package/dist/{Cron-D5HGEt6g.d.mts → Cron-COdfP0Jd.d.cts} +5 -5
- package/dist/{Cron-DbJNPTbP.d.cts → Cron-D8cn_ahj.d.mts} +5 -5
- package/dist/{Cron-BnO1uXhh.mjs → Cron-Dy_HW2Vv.mjs} +5 -5
- package/dist/Cron-Dy_HW2Vv.mjs.map +1 -0
- package/dist/{CronBuilder-BxKwHCdJ.mjs → CronBuilder-Bl3A2Zp4.mjs} +15 -6
- package/dist/CronBuilder-Bl3A2Zp4.mjs.map +1 -0
- package/dist/{CronBuilder-D-546XtP.d.cts → CronBuilder-DntF6H3A.d.cts} +17 -12
- package/dist/{CronBuilder-vRiZb1_N.d.mts → CronBuilder-DoMnSs_0.d.mts} +17 -12
- package/dist/{CronBuilder-D_3AiPFO.cjs → CronBuilder-Dv_w7Yri.cjs} +15 -6
- package/dist/CronBuilder-Dv_w7Yri.cjs.map +1 -0
- package/dist/{Endpoint-DqZkc6ft.d.mts → Endpoint-Bbs_sFvg.d.mts} +120 -23
- package/dist/{Endpoint-BpTSQn7W.d.cts → Endpoint-Bu8Phz6y.d.cts} +120 -23
- package/dist/{Endpoint-BdIGWw1H.cjs → Endpoint-DDpF7NO1.cjs} +22 -10
- package/dist/Endpoint-DDpF7NO1.cjs.map +1 -0
- package/dist/{Endpoint-ChzcIFdV.mjs → Endpoint-S6Yh2_PN.mjs} +22 -10
- package/dist/Endpoint-S6Yh2_PN.mjs.map +1 -0
- package/dist/EndpointBuilder-CPxmF_w7.d.cts +103 -0
- package/dist/EndpointBuilder-Csfyfjd7.d.mts +103 -0
- package/dist/{EndpointBuilder-dmMiNRm9.cjs → EndpointBuilder-DpGmObMb.cjs} +68 -5
- package/dist/EndpointBuilder-DpGmObMb.cjs.map +1 -0
- package/dist/{EndpointBuilder-yo40Qkf_.mjs → EndpointBuilder-aE2E6WTx.mjs} +68 -5
- package/dist/EndpointBuilder-aE2E6WTx.mjs.map +1 -0
- package/dist/{EndpointFactory-D_mmO7Gu.d.mts → EndpointFactory-Bf9JSWzI.d.cts} +12 -11
- package/dist/{EndpointFactory-CNbcr8u_.cjs → EndpointFactory-BfH6mjJ3.cjs} +3 -3
- package/dist/EndpointFactory-BfH6mjJ3.cjs.map +1 -0
- package/dist/{EndpointFactory-JPhk0Qom.d.cts → EndpointFactory-Cgk1R0oO.d.mts} +12 -11
- package/dist/{EndpointFactory-LD3upVQK.mjs → EndpointFactory-D4leYk1N.mjs} +3 -3
- package/dist/EndpointFactory-D4leYk1N.mjs.map +1 -0
- package/dist/{Function-DDaSfL_E.cjs → Function-DagDbeXo.cjs} +7 -6
- package/dist/Function-DagDbeXo.cjs.map +1 -0
- package/dist/{Function-Cl9fiR3a.mjs → Function-DfKsM5Kx.mjs} +7 -6
- package/dist/Function-DfKsM5Kx.mjs.map +1 -0
- package/dist/{Function-C-5_23Wi.d.mts → Function-V9M9UVHp.d.mts} +25 -7
- package/dist/{Function-CW-WcZTu.d.cts → Function-VI1TB3Mh.d.cts} +25 -7
- package/dist/{FunctionBuilder-vW12WFOw.mjs → FunctionBuilder-CVT7bG2o.mjs} +27 -6
- package/dist/FunctionBuilder-CVT7bG2o.mjs.map +1 -0
- package/dist/FunctionBuilder-CjVEFTYC.d.cts +38 -0
- package/dist/FunctionBuilder-D1ofSeMd.d.mts +38 -0
- package/dist/{FunctionBuilder-LQuBiqRc.cjs → FunctionBuilder-DXvG_XD-.cjs} +27 -6
- 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-BVQtyvna.d.cts → HonoEndpointAdaptor-B34kNobH.d.cts} +8 -7
- package/dist/{HonoEndpointAdaptor-W-disJnm.d.mts → HonoEndpointAdaptor-BDpi32mH.d.mts} +9 -8
- package/dist/{HonoEndpointAdaptor-Bc61IS6Q.cjs → HonoEndpointAdaptor-CfLRHHFw.cjs} +55 -20
- package/dist/HonoEndpointAdaptor-CfLRHHFw.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-NR3h5gml.mjs → HonoEndpointAdaptor-DuyE06nH.mjs} +55 -20
- package/dist/HonoEndpointAdaptor-DuyE06nH.mjs.map +1 -0
- package/dist/{Subscriber-C2OPATI8.cjs → Subscriber-Bdh8rMSL.cjs} +2 -2
- package/dist/{Subscriber-C2OPATI8.cjs.map → Subscriber-Bdh8rMSL.cjs.map} +1 -1
- package/dist/{Subscriber-BVq3ST4C.d.cts → Subscriber-BhzqUzs-.d.cts} +2 -2
- package/dist/{Subscriber-BKftCzwT.mjs → Subscriber-CJOWwaw1.mjs} +2 -2
- package/dist/{Subscriber-BKftCzwT.mjs.map → Subscriber-CJOWwaw1.mjs.map} +1 -1
- package/dist/{Subscriber-BuHaqWo4.d.mts → Subscriber-s6yfjeOc.d.mts} +2 -2
- package/dist/{SubscriberBuilder-2asHtGbl.d.mts → SubscriberBuilder-BCVkp-ga.d.cts} +3 -3
- package/dist/{SubscriberBuilder-yDfpHPZE.mjs → SubscriberBuilder-BWQmiYd8.mjs} +2 -2
- package/dist/{SubscriberBuilder-yDfpHPZE.mjs.map → SubscriberBuilder-BWQmiYd8.mjs.map} +1 -1
- package/dist/{SubscriberBuilder-yikoQ8ND.cjs → SubscriberBuilder-DieD_60p.cjs} +2 -2
- package/dist/{SubscriberBuilder-yikoQ8ND.cjs.map → SubscriberBuilder-DieD_60p.cjs.map} +1 -1
- package/dist/{SubscriberBuilder-CHIRyNjy.d.cts → SubscriberBuilder-aCua5_wA.d.mts} +3 -3
- package/dist/{TestEndpointAdaptor-DpmNXp7G.mjs → TestEndpointAdaptor-BEyZa0Yg.mjs} +51 -18
- package/dist/TestEndpointAdaptor-BEyZa0Yg.mjs.map +1 -0
- package/dist/{TestEndpointAdaptor-DA1D6l-U.cjs → TestEndpointAdaptor-C8425RJ0.cjs} +51 -18
- package/dist/TestEndpointAdaptor-C8425RJ0.cjs.map +1 -0
- package/dist/{TestEndpointAdaptor-BrE5Rs4U.d.cts → TestEndpointAdaptor-H5To8PH7.d.cts} +6 -5
- package/dist/{TestEndpointAdaptor-B10J-cI-.d.mts → TestEndpointAdaptor-jxn68ayg.d.mts} +7 -6
- package/dist/adaptors/aws.cjs +14 -13
- package/dist/adaptors/aws.d.cts +14 -14
- package/dist/adaptors/aws.d.mts +15 -15
- package/dist/adaptors/aws.mjs +14 -13
- package/dist/adaptors/hono.cjs +10 -9
- package/dist/adaptors/hono.d.cts +8 -8
- package/dist/adaptors/hono.d.mts +9 -9
- package/dist/adaptors/hono.mjs +10 -9
- package/dist/adaptors/testing.cjs +8 -7
- package/dist/adaptors/testing.d.cts +8 -8
- package/dist/adaptors/testing.d.mts +9 -9
- package/dist/adaptors/testing.mjs +8 -7
- package/dist/crons/Cron.cjs +6 -6
- package/dist/crons/Cron.d.cts +6 -6
- package/dist/crons/Cron.d.mts +6 -6
- package/dist/crons/Cron.mjs +6 -6
- package/dist/crons/CronBuilder.cjs +7 -7
- package/dist/crons/CronBuilder.d.cts +7 -7
- package/dist/crons/CronBuilder.d.mts +7 -7
- package/dist/crons/CronBuilder.mjs +7 -7
- package/dist/crons/index.cjs +7 -7
- package/dist/crons/index.d.cts +11 -11
- package/dist/crons/index.d.mts +8 -8
- package/dist/crons/index.mjs +7 -7
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.cjs +8 -7
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.cts +8 -8
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/AmazonApiGatewayEndpointAdaptor.mjs +8 -7
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.cjs +10 -9
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.cts +9 -9
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.d.mts +10 -10
- package/dist/endpoints/AmazonApiGatewayV1EndpointAdaptor.mjs +10 -9
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.cjs +10 -9
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.cts +9 -9
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.d.mts +10 -10
- package/dist/endpoints/AmazonApiGatewayV2EndpointAdaptor.mjs +10 -9
- package/dist/endpoints/Authorizer.d.cts +1 -1
- package/dist/endpoints/Authorizer.d.mts +1 -1
- package/dist/endpoints/Endpoint.cjs +6 -6
- package/dist/endpoints/Endpoint.d.cts +7 -7
- package/dist/endpoints/Endpoint.d.mts +8 -8
- package/dist/endpoints/Endpoint.mjs +6 -6
- package/dist/endpoints/EndpointBuilder.cjs +7 -7
- package/dist/endpoints/EndpointBuilder.d.cts +8 -8
- package/dist/endpoints/EndpointBuilder.d.mts +9 -9
- package/dist/endpoints/EndpointBuilder.mjs +7 -7
- package/dist/endpoints/EndpointFactory.cjs +8 -8
- package/dist/endpoints/EndpointFactory.d.cts +9 -9
- package/dist/endpoints/EndpointFactory.d.mts +10 -10
- package/dist/endpoints/EndpointFactory.mjs +8 -8
- package/dist/endpoints/HonoEndpointAdaptor.cjs +10 -9
- package/dist/endpoints/HonoEndpointAdaptor.d.cts +8 -8
- package/dist/endpoints/HonoEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/HonoEndpointAdaptor.mjs +10 -9
- package/dist/endpoints/TestEndpointAdaptor.cjs +8 -7
- package/dist/endpoints/TestEndpointAdaptor.d.cts +8 -8
- package/dist/endpoints/TestEndpointAdaptor.d.mts +9 -9
- package/dist/endpoints/TestEndpointAdaptor.mjs +8 -7
- package/dist/endpoints/audit.cjs +0 -0
- package/dist/endpoints/audit.d.cts +9 -0
- package/dist/endpoints/audit.d.mts +9 -0
- package/dist/endpoints/audit.mjs +0 -0
- package/dist/endpoints/helpers.cjs +7 -7
- package/dist/endpoints/helpers.d.cts +7 -7
- package/dist/endpoints/helpers.d.mts +8 -8
- package/dist/endpoints/helpers.mjs +7 -7
- package/dist/endpoints/index.cjs +8 -8
- package/dist/endpoints/index.cjs.map +1 -1
- package/dist/endpoints/index.d.cts +12 -12
- package/dist/endpoints/index.d.mts +13 -13
- package/dist/endpoints/index.mjs +8 -8
- package/dist/endpoints/index.mjs.map +1 -1
- package/dist/endpoints/parseHonoQuery.cjs +1 -1
- package/dist/endpoints/parseHonoQuery.mjs +1 -1
- package/dist/endpoints/parseQueryParams.cjs +1 -1
- package/dist/endpoints/parseQueryParams.mjs +1 -1
- package/dist/endpoints/processAudits.cjs +5 -0
- package/dist/endpoints/processAudits.d.cts +74 -0
- package/dist/endpoints/processAudits.d.mts +74 -0
- package/dist/endpoints/processAudits.mjs +3 -0
- package/dist/functions/AWSLambdaFunction.cjs +6 -6
- package/dist/functions/AWSLambdaFunction.d.cts +4 -4
- package/dist/functions/AWSLambdaFunction.d.mts +4 -4
- package/dist/functions/AWSLambdaFunction.mjs +6 -6
- package/dist/functions/BaseFunctionBuilder.cjs +2 -2
- package/dist/functions/BaseFunctionBuilder.d.cts +2 -2
- package/dist/functions/BaseFunctionBuilder.d.mts +2 -2
- package/dist/functions/BaseFunctionBuilder.mjs +2 -2
- package/dist/functions/Function.cjs +2 -2
- package/dist/functions/Function.d.cts +2 -2
- package/dist/functions/Function.d.mts +2 -2
- package/dist/functions/Function.mjs +2 -2
- package/dist/functions/FunctionBuilder.cjs +4 -4
- package/dist/functions/FunctionBuilder.d.cts +4 -4
- package/dist/functions/FunctionBuilder.d.mts +4 -4
- package/dist/functions/FunctionBuilder.mjs +4 -4
- package/dist/functions/FunctionExecutionWrapper.cjs +5 -5
- package/dist/functions/FunctionExecutionWrapper.d.cts +3 -3
- package/dist/functions/FunctionExecutionWrapper.d.mts +3 -3
- package/dist/functions/FunctionExecutionWrapper.mjs +5 -5
- package/dist/functions/TestFunctionAdaptor.cjs +38 -5
- package/dist/functions/TestFunctionAdaptor.cjs.map +1 -1
- package/dist/functions/TestFunctionAdaptor.d.cts +10 -7
- package/dist/functions/TestFunctionAdaptor.d.mts +10 -7
- package/dist/functions/TestFunctionAdaptor.mjs +38 -5
- package/dist/functions/TestFunctionAdaptor.mjs.map +1 -1
- package/dist/functions/index.cjs +5 -5
- package/dist/functions/index.d.cts +5 -5
- package/dist/functions/index.d.mts +5 -5
- package/dist/functions/index.mjs +5 -5
- package/dist/{functions-yg097ymU.cjs → functions-FCb-wWFC.cjs} +2 -2
- package/dist/{functions-yg097ymU.cjs.map → functions-FCb-wWFC.cjs.map} +1 -1
- package/dist/functions-JhRsNoAZ.mjs +8 -0
- package/dist/{functions-HCoZ4YKF.mjs.map → functions-JhRsNoAZ.mjs.map} +1 -1
- package/dist/{helpers-CHsIWAEx.mjs → helpers-2CLKTnRm.mjs} +2 -2
- package/dist/{helpers-CHsIWAEx.mjs.map → helpers-2CLKTnRm.mjs.map} +1 -1
- package/dist/{helpers-Cq6wjo7s.cjs → helpers-Khuhi_Qx.cjs} +2 -2
- package/dist/{helpers-Cq6wjo7s.cjs.map → helpers-Khuhi_Qx.cjs.map} +1 -1
- package/dist/index-Bomy7R9z.d.mts +10 -0
- package/dist/index-DRYfZHb3.d.cts +10 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{parseHonoQuery-DopC24vB.cjs → parseHonoQuery-CT8Cvin-.cjs} +1 -1
- package/dist/{parseHonoQuery-DopC24vB.cjs.map → parseHonoQuery-CT8Cvin-.cjs.map} +1 -1
- package/dist/{parseHonoQuery-znDKBhdE.mjs → parseHonoQuery-CwFKw2ua.mjs} +1 -1
- package/dist/{parseHonoQuery-znDKBhdE.mjs.map → parseHonoQuery-CwFKw2ua.mjs.map} +1 -1
- package/dist/{parseQueryParams-BJaRh3OB.mjs → parseQueryParams-CHINupbZ.mjs} +1 -1
- package/dist/{parseQueryParams-BJaRh3OB.mjs.map → parseQueryParams-CHINupbZ.mjs.map} +1 -1
- package/dist/{parseQueryParams-BzPop4I1.cjs → parseQueryParams-CwvXXwkW.cjs} +1 -1
- package/dist/{parseQueryParams-BzPop4I1.cjs.map → parseQueryParams-CwvXXwkW.cjs.map} +1 -1
- package/dist/processAudits-BFokHhCO.cjs +174 -0
- package/dist/processAudits-BFokHhCO.cjs.map +1 -0
- package/dist/processAudits-DfcB-X-4.mjs +156 -0
- package/dist/processAudits-DfcB-X-4.mjs.map +1 -0
- package/dist/publisher-Bw4770Hi.mjs.map +1 -1
- package/dist/publisher-lFQleddL.cjs.map +1 -1
- package/dist/publisher.d.cts +3 -2
- package/dist/publisher.d.mts +3 -2
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.cjs +1 -1
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.cts +3 -3
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.d.mts +3 -3
- package/dist/subscribers/AWSLambdaSubscriberAdaptor.mjs +1 -1
- package/dist/subscribers/Subscriber.cjs +2 -2
- package/dist/subscribers/Subscriber.d.cts +2 -2
- package/dist/subscribers/Subscriber.d.mts +2 -2
- package/dist/subscribers/Subscriber.mjs +2 -2
- package/dist/subscribers/SubscriberBuilder.cjs +3 -3
- package/dist/subscribers/SubscriberBuilder.d.cts +3 -3
- package/dist/subscribers/SubscriberBuilder.d.mts +3 -3
- package/dist/subscribers/SubscriberBuilder.mjs +3 -3
- package/dist/subscribers/index.cjs +3 -3
- package/dist/subscribers/index.d.cts +5 -5
- package/dist/subscribers/index.d.mts +5 -5
- package/dist/subscribers/index.mjs +3 -3
- package/dist/{types-CVq20-fE.d.mts → types-DKf0juBf.d.mts} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +15 -11
- package/src/Construct.ts +8 -0
- 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 +112 -20
- package/src/endpoints/Endpoint.ts +208 -39
- package/src/endpoints/EndpointBuilder.ts +291 -21
- package/src/endpoints/EndpointFactory.ts +5 -1
- package/src/endpoints/HonoEndpointAdaptor.ts +144 -33
- package/src/endpoints/TestEndpointAdaptor.ts +116 -21
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.events.spec.ts +8 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +29 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.audits.spec.ts +626 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +9 -0
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.kysely-audit.integration.spec.ts +757 -0
- package/src/endpoints/__tests__/Endpoint.cookies.spec.ts +3 -1
- package/src/endpoints/__tests__/Endpoint.manifest.spec.ts +1 -1
- package/src/endpoints/__tests__/Endpoint.spec.ts +19 -0
- package/src/endpoints/__tests__/EndpointBuilder.audit.spec.ts +448 -0
- 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 +703 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.audits.spec.ts +632 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.events.spec.ts +8 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.kysely-audit.integration.spec.ts +1063 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.openapi.spec.ts +4 -0
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +25 -0
- package/src/endpoints/audit.ts +87 -0
- package/src/endpoints/index.ts +1 -0
- package/src/endpoints/processAudits.ts +348 -0
- package/src/functions/AWSLambdaFunction.ts +125 -12
- package/src/functions/BaseFunctionBuilder.ts +98 -7
- package/src/functions/Function.ts +83 -15
- package/src/functions/FunctionBuilder.ts +217 -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 +54 -7
- package/src/publisher.ts +12 -1
- package/dist/AWSLambdaFunction-BTSGYZSx.mjs.map +0 -1
- package/dist/AWSLambdaFunction-Bel0NFTl.d.mts +0 -27
- package/dist/AWSLambdaFunction-DcI_77u8.cjs.map +0 -1
- package/dist/AWSLambdaFunction-xyCenuD7.d.cts +0 -27
- package/dist/AmazonApiGatewayEndpointAdaptor-BTqB3c1_.cjs.map +0 -1
- package/dist/AmazonApiGatewayEndpointAdaptor-vi0D3dWg.mjs.map +0 -1
- package/dist/BaseFunctionBuilder-DSqF1r3a.mjs.map +0 -1
- package/dist/BaseFunctionBuilder-bTDKP7bd.cjs.map +0 -1
- package/dist/Construct-XCGKof_O.cjs.map +0 -1
- package/dist/Construct-rZQg2yus.mjs.map +0 -1
- package/dist/Cron-BnO1uXhh.mjs.map +0 -1
- package/dist/Cron-CYIhd0VE.cjs.map +0 -1
- package/dist/CronBuilder-BxKwHCdJ.mjs.map +0 -1
- package/dist/CronBuilder-D_3AiPFO.cjs.map +0 -1
- package/dist/Endpoint-BdIGWw1H.cjs.map +0 -1
- package/dist/Endpoint-ChzcIFdV.mjs.map +0 -1
- package/dist/EndpointBuilder-Cx6pUcCn.d.mts +0 -55
- package/dist/EndpointBuilder-Xka8ULR1.d.cts +0 -55
- package/dist/EndpointBuilder-dmMiNRm9.cjs.map +0 -1
- package/dist/EndpointBuilder-yo40Qkf_.mjs.map +0 -1
- package/dist/EndpointFactory-CNbcr8u_.cjs.map +0 -1
- package/dist/EndpointFactory-LD3upVQK.mjs.map +0 -1
- package/dist/Function-Cl9fiR3a.mjs.map +0 -1
- package/dist/Function-DDaSfL_E.cjs.map +0 -1
- package/dist/FunctionBuilder-LQuBiqRc.cjs.map +0 -1
- package/dist/FunctionBuilder-fU1H7tFN.d.cts +0 -26
- package/dist/FunctionBuilder-udObIGV0.d.mts +0 -26
- package/dist/FunctionBuilder-vW12WFOw.mjs.map +0 -1
- package/dist/FunctionExecutionWrapper-BBIoHUt6.cjs +0 -42
- package/dist/FunctionExecutionWrapper-BBIoHUt6.cjs.map +0 -1
- package/dist/FunctionExecutionWrapper-DYBy9OP3.d.mts +0 -24
- package/dist/FunctionExecutionWrapper-Dtyhid1Q.mjs +0 -36
- package/dist/FunctionExecutionWrapper-Dtyhid1Q.mjs.map +0 -1
- package/dist/FunctionExecutionWrapper-Dwr2ZKzC.d.cts +0 -24
- package/dist/HonoEndpointAdaptor-Bc61IS6Q.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-NR3h5gml.mjs.map +0 -1
- package/dist/TestEndpointAdaptor-DA1D6l-U.cjs.map +0 -1
- package/dist/TestEndpointAdaptor-DpmNXp7G.mjs.map +0 -1
- package/dist/functions-HCoZ4YKF.mjs +0 -8
- package/dist/index-RtxMVjUZ.d.mts +0 -9
- package/dist/index-fiIGH95t.d.cts +0 -9
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AuditRecord,
|
|
3
|
+
AuditStorage,
|
|
4
|
+
AuditableAction,
|
|
5
|
+
} from '@geekmidas/audit';
|
|
6
|
+
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
7
|
+
import type { Logger } from '@geekmidas/logger';
|
|
8
|
+
import type { Service } from '@geekmidas/services';
|
|
9
|
+
import { ServiceDiscovery } from '@geekmidas/services';
|
|
10
|
+
import { Hono } from 'hono';
|
|
11
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { Endpoint, type EndpointContext } from '../Endpoint';
|
|
14
|
+
import { HonoEndpoint } from '../HonoEndpointAdaptor';
|
|
15
|
+
import type { MappedAudit } from '../audit';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mock transaction that simulates Kysely Transaction behavior.
|
|
19
|
+
*/
|
|
20
|
+
class MockTransaction {
|
|
21
|
+
isTransaction = true as const;
|
|
22
|
+
|
|
23
|
+
constructor(private db: MockDatabase) {}
|
|
24
|
+
|
|
25
|
+
insert(table: string, data: unknown) {
|
|
26
|
+
this.db.pendingOperations.push({ type: `insert:${table}`, data });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Required by Kysely interface - nested transactions just return self
|
|
30
|
+
transaction() {
|
|
31
|
+
return this.db.transaction();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Mock database that simulates Kysely-like transaction behavior.
|
|
37
|
+
* Tracks all operations and can simulate rollbacks.
|
|
38
|
+
*/
|
|
39
|
+
class MockDatabase {
|
|
40
|
+
pendingOperations: Array<{ type: string; data: unknown }> = [];
|
|
41
|
+
committedOperations: Array<{ type: string; data: unknown }> = [];
|
|
42
|
+
isTransaction = false as const;
|
|
43
|
+
shouldFailOnCommit = false;
|
|
44
|
+
|
|
45
|
+
// Simulates db.transaction() returning a builder
|
|
46
|
+
transaction() {
|
|
47
|
+
const self = this;
|
|
48
|
+
return {
|
|
49
|
+
setIsolationLevel(_level: string) {
|
|
50
|
+
return this;
|
|
51
|
+
},
|
|
52
|
+
async execute<T>(cb: (trx: MockTransaction) => Promise<T>): Promise<T> {
|
|
53
|
+
const trx = new MockTransaction(self);
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const result = await cb(trx);
|
|
57
|
+
|
|
58
|
+
if (self.shouldFailOnCommit) {
|
|
59
|
+
throw new Error('Simulated commit failure');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Commit: move pending operations to committed
|
|
63
|
+
self.committedOperations.push(...self.pendingOperations);
|
|
64
|
+
self.pendingOperations = [];
|
|
65
|
+
return result;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
// Rollback: discard pending operations
|
|
68
|
+
self.pendingOperations = [];
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
insert(table: string, data: unknown) {
|
|
76
|
+
this.pendingOperations.push({ type: `insert:${table}`, data });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
reset() {
|
|
80
|
+
this.pendingOperations = [];
|
|
81
|
+
this.committedOperations = [];
|
|
82
|
+
this.shouldFailOnCommit = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Audit storage that uses a mock database for transactional writes.
|
|
88
|
+
* Can be configured to fail on write to test rollback behavior.
|
|
89
|
+
*/
|
|
90
|
+
class TransactionalAuditStorage implements AuditStorage {
|
|
91
|
+
records: AuditRecord[] = [];
|
|
92
|
+
shouldFailOnWrite = false;
|
|
93
|
+
writeAttempts = 0;
|
|
94
|
+
|
|
95
|
+
constructor(private db: MockDatabase) {}
|
|
96
|
+
|
|
97
|
+
async write(records: AuditRecord[], trx?: unknown): Promise<void> {
|
|
98
|
+
this.writeAttempts++;
|
|
99
|
+
|
|
100
|
+
if (this.shouldFailOnWrite) {
|
|
101
|
+
throw new Error('Simulated audit write failure');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// If we have a transaction, use it
|
|
105
|
+
if (trx) {
|
|
106
|
+
const mockTrx = trx as MockTransaction;
|
|
107
|
+
for (const record of records) {
|
|
108
|
+
mockTrx.insert('audit_logs', record);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.records.push(...records);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async query(): Promise<AuditRecord[]> {
|
|
116
|
+
return this.records;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getDatabase(): MockDatabase {
|
|
120
|
+
return this.db;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
reset() {
|
|
124
|
+
this.records = [];
|
|
125
|
+
this.shouldFailOnWrite = false;
|
|
126
|
+
this.writeAttempts = 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Test audit action types
|
|
131
|
+
type TestAuditAction =
|
|
132
|
+
| AuditableAction<'user.created', { userId: string; email: string }>
|
|
133
|
+
| AuditableAction<'user.updated', { userId: string; changes: string[] }>;
|
|
134
|
+
|
|
135
|
+
describe('HonoEndpoint Audit Transactions', () => {
|
|
136
|
+
let mockDb: MockDatabase;
|
|
137
|
+
let auditStorage: TransactionalAuditStorage;
|
|
138
|
+
let mockLogger: Logger;
|
|
139
|
+
|
|
140
|
+
const createMockLogger = (): Logger => ({
|
|
141
|
+
debug: vi.fn(),
|
|
142
|
+
info: vi.fn(),
|
|
143
|
+
warn: vi.fn(),
|
|
144
|
+
error: vi.fn(),
|
|
145
|
+
fatal: vi.fn(),
|
|
146
|
+
trace: vi.fn(),
|
|
147
|
+
child: vi.fn(function (this: Logger) {
|
|
148
|
+
return this;
|
|
149
|
+
}),
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const createServiceDiscovery = (logger: Logger) => {
|
|
153
|
+
const envParser = new EnvironmentParser({});
|
|
154
|
+
ServiceDiscovery.reset();
|
|
155
|
+
return ServiceDiscovery.getInstance(logger, envParser);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
mockDb = new MockDatabase();
|
|
160
|
+
auditStorage = new TransactionalAuditStorage(mockDb);
|
|
161
|
+
mockLogger = createMockLogger();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('successful transactions', () => {
|
|
165
|
+
it('should commit both handler operations and audits on success', async () => {
|
|
166
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
167
|
+
|
|
168
|
+
const auditStorageService: Service<
|
|
169
|
+
'auditStorage',
|
|
170
|
+
TransactionalAuditStorage
|
|
171
|
+
> = {
|
|
172
|
+
serviceName: 'auditStorage' as const,
|
|
173
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
177
|
+
|
|
178
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [
|
|
179
|
+
{
|
|
180
|
+
type: 'user.created',
|
|
181
|
+
payload: (response) => ({
|
|
182
|
+
userId: response.id,
|
|
183
|
+
email: response.email,
|
|
184
|
+
}),
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
|
|
188
|
+
const endpoint = new Endpoint({
|
|
189
|
+
route: '/users',
|
|
190
|
+
method: 'POST',
|
|
191
|
+
fn: async () => {
|
|
192
|
+
// Simulate handler database operation
|
|
193
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
194
|
+
return { id: '123', email: 'test@example.com' };
|
|
195
|
+
},
|
|
196
|
+
input: undefined,
|
|
197
|
+
output: outputSchema,
|
|
198
|
+
services: [],
|
|
199
|
+
logger: mockLogger,
|
|
200
|
+
timeout: undefined,
|
|
201
|
+
memorySize: undefined,
|
|
202
|
+
status: 201,
|
|
203
|
+
getSession: undefined,
|
|
204
|
+
authorize: undefined,
|
|
205
|
+
description: undefined,
|
|
206
|
+
events: [],
|
|
207
|
+
publisherService: undefined,
|
|
208
|
+
auditorStorageService: auditStorageService,
|
|
209
|
+
audits,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
213
|
+
const app = new Hono();
|
|
214
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
215
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
216
|
+
|
|
217
|
+
const response = await app.request('/users', {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
body: JSON.stringify({}),
|
|
220
|
+
headers: { 'Content-Type': 'application/json' },
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
expect(response.status).toBe(201);
|
|
224
|
+
|
|
225
|
+
// Both handler operations and audits should be committed
|
|
226
|
+
expect(auditStorage.records).toHaveLength(1);
|
|
227
|
+
expect(auditStorage.records[0].type).toBe('user.created');
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe('handler failure rollback', () => {
|
|
232
|
+
it('should not write audits when handler throws an error', async () => {
|
|
233
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
234
|
+
|
|
235
|
+
const auditStorageService: Service<
|
|
236
|
+
'auditStorage',
|
|
237
|
+
TransactionalAuditStorage
|
|
238
|
+
> = {
|
|
239
|
+
serviceName: 'auditStorage' as const,
|
|
240
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
244
|
+
|
|
245
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [
|
|
246
|
+
{
|
|
247
|
+
type: 'user.created',
|
|
248
|
+
payload: (response) => ({
|
|
249
|
+
userId: response.id,
|
|
250
|
+
email: response.email,
|
|
251
|
+
}),
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
const endpoint = new Endpoint({
|
|
256
|
+
route: '/users',
|
|
257
|
+
method: 'POST',
|
|
258
|
+
fn: async () => {
|
|
259
|
+
// Simulate handler database operation before failure
|
|
260
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
261
|
+
throw new Error('Handler failed after database operation');
|
|
262
|
+
},
|
|
263
|
+
input: undefined,
|
|
264
|
+
output: outputSchema,
|
|
265
|
+
services: [],
|
|
266
|
+
logger: mockLogger,
|
|
267
|
+
timeout: undefined,
|
|
268
|
+
memorySize: undefined,
|
|
269
|
+
status: 201,
|
|
270
|
+
getSession: undefined,
|
|
271
|
+
authorize: undefined,
|
|
272
|
+
description: undefined,
|
|
273
|
+
events: [],
|
|
274
|
+
publisherService: undefined,
|
|
275
|
+
auditorStorageService: auditStorageService,
|
|
276
|
+
audits,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
280
|
+
const app = new Hono();
|
|
281
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
282
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
283
|
+
|
|
284
|
+
const response = await app.request('/users', {
|
|
285
|
+
method: 'POST',
|
|
286
|
+
body: JSON.stringify({}),
|
|
287
|
+
headers: { 'Content-Type': 'application/json' },
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Handler error should result in 500
|
|
291
|
+
expect(response.status).toBe(500);
|
|
292
|
+
|
|
293
|
+
// No audits should be written when handler fails
|
|
294
|
+
expect(auditStorage.records).toHaveLength(0);
|
|
295
|
+
|
|
296
|
+
// Database operations should not be committed (rolled back)
|
|
297
|
+
expect(mockDb.committedOperations).toHaveLength(0);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should not write audits when handler validation fails', async () => {
|
|
301
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
302
|
+
|
|
303
|
+
const auditStorageService: Service<
|
|
304
|
+
'auditStorage',
|
|
305
|
+
TransactionalAuditStorage
|
|
306
|
+
> = {
|
|
307
|
+
serviceName: 'auditStorage' as const,
|
|
308
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const outputSchema = z.object({
|
|
312
|
+
id: z.string().min(10), // Will fail validation
|
|
313
|
+
email: z.string().email(),
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [
|
|
317
|
+
{
|
|
318
|
+
type: 'user.created',
|
|
319
|
+
payload: (response) => ({
|
|
320
|
+
userId: response.id,
|
|
321
|
+
email: response.email,
|
|
322
|
+
}),
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
|
|
326
|
+
const endpoint = new Endpoint({
|
|
327
|
+
route: '/users',
|
|
328
|
+
method: 'POST',
|
|
329
|
+
fn: async () => {
|
|
330
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
331
|
+
// Return value that fails output validation (id too short)
|
|
332
|
+
return { id: '123', email: 'test@example.com' };
|
|
333
|
+
},
|
|
334
|
+
input: undefined,
|
|
335
|
+
output: outputSchema,
|
|
336
|
+
services: [],
|
|
337
|
+
logger: mockLogger,
|
|
338
|
+
timeout: undefined,
|
|
339
|
+
memorySize: undefined,
|
|
340
|
+
status: 201,
|
|
341
|
+
getSession: undefined,
|
|
342
|
+
authorize: undefined,
|
|
343
|
+
description: undefined,
|
|
344
|
+
events: [],
|
|
345
|
+
publisherService: undefined,
|
|
346
|
+
auditorStorageService: auditStorageService,
|
|
347
|
+
audits,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
351
|
+
const app = new Hono();
|
|
352
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
353
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
354
|
+
|
|
355
|
+
const response = await app.request('/users', {
|
|
356
|
+
method: 'POST',
|
|
357
|
+
body: JSON.stringify({}),
|
|
358
|
+
headers: { 'Content-Type': 'application/json' },
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Output validation error should result in 422
|
|
362
|
+
expect(response.status).toBe(422);
|
|
363
|
+
|
|
364
|
+
// No audits should be written when output validation fails
|
|
365
|
+
expect(auditStorage.records).toHaveLength(0);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
describe('audit failure rollback', () => {
|
|
370
|
+
it('should rollback handler operations when audit write fails', async () => {
|
|
371
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
372
|
+
|
|
373
|
+
// Configure audit storage to fail
|
|
374
|
+
auditStorage.shouldFailOnWrite = true;
|
|
375
|
+
|
|
376
|
+
const auditStorageService: Service<
|
|
377
|
+
'auditStorage',
|
|
378
|
+
TransactionalAuditStorage
|
|
379
|
+
> = {
|
|
380
|
+
serviceName: 'auditStorage' as const,
|
|
381
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
385
|
+
|
|
386
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [
|
|
387
|
+
{
|
|
388
|
+
type: 'user.created',
|
|
389
|
+
payload: (response) => ({
|
|
390
|
+
userId: response.id,
|
|
391
|
+
email: response.email,
|
|
392
|
+
}),
|
|
393
|
+
},
|
|
394
|
+
];
|
|
395
|
+
|
|
396
|
+
const endpoint = new Endpoint({
|
|
397
|
+
route: '/users',
|
|
398
|
+
method: 'POST',
|
|
399
|
+
fn: async () => {
|
|
400
|
+
// This operation should be rolled back when audit fails
|
|
401
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
402
|
+
return { id: '123', email: 'test@example.com' };
|
|
403
|
+
},
|
|
404
|
+
input: undefined,
|
|
405
|
+
output: outputSchema,
|
|
406
|
+
services: [],
|
|
407
|
+
logger: mockLogger,
|
|
408
|
+
timeout: undefined,
|
|
409
|
+
memorySize: undefined,
|
|
410
|
+
status: 201,
|
|
411
|
+
getSession: undefined,
|
|
412
|
+
authorize: undefined,
|
|
413
|
+
description: undefined,
|
|
414
|
+
events: [],
|
|
415
|
+
publisherService: undefined,
|
|
416
|
+
auditorStorageService: auditStorageService,
|
|
417
|
+
audits,
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
421
|
+
const app = new Hono();
|
|
422
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
423
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
424
|
+
|
|
425
|
+
const response = await app.request('/users', {
|
|
426
|
+
method: 'POST',
|
|
427
|
+
body: JSON.stringify({}),
|
|
428
|
+
headers: { 'Content-Type': 'application/json' },
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// Audit failure should result in error response
|
|
432
|
+
expect(response.status).toBe(500);
|
|
433
|
+
|
|
434
|
+
// Audit write should have been attempted
|
|
435
|
+
expect(auditStorage.writeAttempts).toBe(1);
|
|
436
|
+
|
|
437
|
+
// No audits should be persisted
|
|
438
|
+
expect(auditStorage.records).toHaveLength(0);
|
|
439
|
+
|
|
440
|
+
// Handler database operations should not be committed (rolled back)
|
|
441
|
+
expect(mockDb.committedOperations).toHaveLength(0);
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
describe('manual audits in handler', () => {
|
|
446
|
+
it('should include manual audits from handler in transaction', async () => {
|
|
447
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
448
|
+
|
|
449
|
+
const registerFn = vi.fn().mockResolvedValue(auditStorage);
|
|
450
|
+
const auditStorageService: Service<
|
|
451
|
+
'auditStorage',
|
|
452
|
+
TransactionalAuditStorage
|
|
453
|
+
> = {
|
|
454
|
+
serviceName: 'auditStorage' as const,
|
|
455
|
+
register: registerFn,
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
459
|
+
|
|
460
|
+
// No declarative audits - we'll use manual audits in the handler
|
|
461
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [];
|
|
462
|
+
|
|
463
|
+
let auditorWasAvailable = false;
|
|
464
|
+
let receivedCtxKeys: string[] = [];
|
|
465
|
+
|
|
466
|
+
const endpoint = new Endpoint({
|
|
467
|
+
route: '/users',
|
|
468
|
+
method: 'POST',
|
|
469
|
+
fn: async (
|
|
470
|
+
ctx: EndpointContext<
|
|
471
|
+
undefined,
|
|
472
|
+
[],
|
|
473
|
+
Logger,
|
|
474
|
+
unknown,
|
|
475
|
+
TestAuditAction,
|
|
476
|
+
undefined,
|
|
477
|
+
TransactionalAuditStorage
|
|
478
|
+
>,
|
|
479
|
+
) => {
|
|
480
|
+
receivedCtxKeys = Object.keys(ctx);
|
|
481
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
482
|
+
|
|
483
|
+
// Manual audit via auditor in context - auditor is guaranteed to exist
|
|
484
|
+
auditorWasAvailable = true;
|
|
485
|
+
ctx.auditor.audit('user.created', {
|
|
486
|
+
userId: '123',
|
|
487
|
+
email: 'test@example.com',
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
return { id: '123', email: 'test@example.com' };
|
|
491
|
+
},
|
|
492
|
+
input: undefined,
|
|
493
|
+
output: outputSchema,
|
|
494
|
+
services: [],
|
|
495
|
+
logger: mockLogger,
|
|
496
|
+
timeout: undefined,
|
|
497
|
+
memorySize: undefined,
|
|
498
|
+
status: 201,
|
|
499
|
+
getSession: undefined,
|
|
500
|
+
authorize: undefined,
|
|
501
|
+
description: undefined,
|
|
502
|
+
events: [],
|
|
503
|
+
publisherService: undefined,
|
|
504
|
+
auditorStorageService: auditStorageService,
|
|
505
|
+
audits,
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
// Verify endpoint has auditorStorageService
|
|
509
|
+
expect(endpoint.auditorStorageService).toBe(auditStorageService);
|
|
510
|
+
|
|
511
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
512
|
+
const app = new Hono();
|
|
513
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
514
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
515
|
+
|
|
516
|
+
const response = await app.request('/users', {
|
|
517
|
+
method: 'POST',
|
|
518
|
+
body: JSON.stringify({}),
|
|
519
|
+
headers: { 'Content-Type': 'application/json' },
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
expect(response.status).toBe(201);
|
|
523
|
+
|
|
524
|
+
// Verify service was registered
|
|
525
|
+
expect(registerFn).toHaveBeenCalled();
|
|
526
|
+
|
|
527
|
+
// Verify auditor key is in context
|
|
528
|
+
expect(receivedCtxKeys).toContain('auditor');
|
|
529
|
+
|
|
530
|
+
// Verify auditor was available in handler
|
|
531
|
+
expect(auditorWasAvailable).toBe(true);
|
|
532
|
+
|
|
533
|
+
// Manual audit should be written
|
|
534
|
+
expect(auditStorage.records).toHaveLength(1);
|
|
535
|
+
expect(auditStorage.records[0].type).toBe('user.created');
|
|
536
|
+
expect(auditStorage.records[0].payload).toEqual({
|
|
537
|
+
userId: '123',
|
|
538
|
+
email: 'test@example.com',
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('should rollback manual audits when handler fails after audit call', async () => {
|
|
543
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
544
|
+
|
|
545
|
+
const auditStorageService: Service<
|
|
546
|
+
'auditStorage',
|
|
547
|
+
TransactionalAuditStorage
|
|
548
|
+
> = {
|
|
549
|
+
serviceName: 'auditStorage' as const,
|
|
550
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
554
|
+
|
|
555
|
+
const endpoint = new Endpoint({
|
|
556
|
+
route: '/users',
|
|
557
|
+
method: 'POST',
|
|
558
|
+
fn: async (
|
|
559
|
+
ctx: EndpointContext<
|
|
560
|
+
undefined,
|
|
561
|
+
[],
|
|
562
|
+
Logger,
|
|
563
|
+
unknown,
|
|
564
|
+
TestAuditAction,
|
|
565
|
+
undefined,
|
|
566
|
+
TransactionalAuditStorage
|
|
567
|
+
>,
|
|
568
|
+
) => {
|
|
569
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
570
|
+
|
|
571
|
+
// Manual audit before failure - auditor is guaranteed to exist
|
|
572
|
+
ctx.auditor.audit('user.created', {
|
|
573
|
+
userId: '123',
|
|
574
|
+
email: 'test@example.com',
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
// Fail after audit was recorded (but not yet flushed)
|
|
578
|
+
throw new Error('Handler failed after recording audit');
|
|
579
|
+
},
|
|
580
|
+
input: undefined,
|
|
581
|
+
output: outputSchema,
|
|
582
|
+
services: [],
|
|
583
|
+
logger: mockLogger,
|
|
584
|
+
timeout: undefined,
|
|
585
|
+
memorySize: undefined,
|
|
586
|
+
status: 201,
|
|
587
|
+
getSession: undefined,
|
|
588
|
+
authorize: undefined,
|
|
589
|
+
description: undefined,
|
|
590
|
+
events: [],
|
|
591
|
+
publisherService: undefined,
|
|
592
|
+
auditorStorageService: auditStorageService,
|
|
593
|
+
audits: [],
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
597
|
+
const app = new Hono();
|
|
598
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
599
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
600
|
+
|
|
601
|
+
const response = await app.request('/users', {
|
|
602
|
+
method: 'POST',
|
|
603
|
+
body: JSON.stringify({}),
|
|
604
|
+
headers: { 'Content-Type': 'application/json' },
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
expect(response.status).toBe(500);
|
|
608
|
+
|
|
609
|
+
// Manual audit should NOT be written because handler failed
|
|
610
|
+
expect(auditStorage.records).toHaveLength(0);
|
|
611
|
+
|
|
612
|
+
// Database operations should be rolled back
|
|
613
|
+
expect(mockDb.committedOperations).toHaveLength(0);
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
describe('combined declarative and manual audits', () => {
|
|
618
|
+
it('should process both declarative and manual audits in same transaction', async () => {
|
|
619
|
+
const serviceDiscovery = createServiceDiscovery(mockLogger);
|
|
620
|
+
|
|
621
|
+
const auditStorageService: Service<
|
|
622
|
+
'auditStorage',
|
|
623
|
+
TransactionalAuditStorage
|
|
624
|
+
> = {
|
|
625
|
+
serviceName: 'auditStorage' as const,
|
|
626
|
+
register: vi.fn().mockResolvedValue(auditStorage),
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
const outputSchema = z.object({ id: z.string(), email: z.string() });
|
|
630
|
+
|
|
631
|
+
// Declarative audit
|
|
632
|
+
const audits: MappedAudit<TestAuditAction, typeof outputSchema>[] = [
|
|
633
|
+
{
|
|
634
|
+
type: 'user.created',
|
|
635
|
+
payload: (response) => ({
|
|
636
|
+
userId: response.id,
|
|
637
|
+
email: response.email,
|
|
638
|
+
}),
|
|
639
|
+
},
|
|
640
|
+
];
|
|
641
|
+
|
|
642
|
+
const endpoint = new Endpoint({
|
|
643
|
+
route: '/users',
|
|
644
|
+
method: 'POST',
|
|
645
|
+
fn: async (
|
|
646
|
+
ctx: EndpointContext<
|
|
647
|
+
undefined,
|
|
648
|
+
[],
|
|
649
|
+
Logger,
|
|
650
|
+
unknown,
|
|
651
|
+
TestAuditAction,
|
|
652
|
+
undefined,
|
|
653
|
+
TransactionalAuditStorage
|
|
654
|
+
>,
|
|
655
|
+
) => {
|
|
656
|
+
mockDb.insert('users', { id: '123', email: 'test@example.com' });
|
|
657
|
+
|
|
658
|
+
// Also add a manual audit - auditor is guaranteed to exist
|
|
659
|
+
ctx.auditor.audit('user.updated', {
|
|
660
|
+
userId: '123',
|
|
661
|
+
changes: ['email_verified'],
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
return { id: '123', email: 'test@example.com' };
|
|
665
|
+
},
|
|
666
|
+
input: undefined,
|
|
667
|
+
output: outputSchema,
|
|
668
|
+
services: [],
|
|
669
|
+
logger: mockLogger,
|
|
670
|
+
timeout: undefined,
|
|
671
|
+
memorySize: undefined,
|
|
672
|
+
status: 201,
|
|
673
|
+
getSession: undefined,
|
|
674
|
+
authorize: undefined,
|
|
675
|
+
description: undefined,
|
|
676
|
+
events: [],
|
|
677
|
+
publisherService: undefined,
|
|
678
|
+
auditorStorageService: auditStorageService,
|
|
679
|
+
audits,
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
const adaptor = new HonoEndpoint(endpoint);
|
|
683
|
+
const app = new Hono();
|
|
684
|
+
HonoEndpoint.applyEventMiddleware(app, serviceDiscovery);
|
|
685
|
+
adaptor.addRoute(serviceDiscovery, app);
|
|
686
|
+
|
|
687
|
+
const response = await app.request('/users', {
|
|
688
|
+
method: 'POST',
|
|
689
|
+
body: JSON.stringify({}),
|
|
690
|
+
headers: { 'Content-Type': 'application/json' },
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
expect(response.status).toBe(201);
|
|
694
|
+
|
|
695
|
+
// Both manual and declarative audits should be written
|
|
696
|
+
expect(auditStorage.records).toHaveLength(2);
|
|
697
|
+
|
|
698
|
+
const auditTypes = auditStorage.records.map((r) => r.type);
|
|
699
|
+
expect(auditTypes).toContain('user.created'); // declarative
|
|
700
|
+
expect(auditTypes).toContain('user.updated'); // manual
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
});
|