@geekmidas/constructs 10.0.0-alpha.3 → 10.0.0-alpha.30
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 +52 -3
- package/dist/{Construct-Ct8nalEi.d.mts → Construct-DTqYvkPG.d.cts} +11 -13
- package/dist/Construct-DTqYvkPG.d.cts.map +1 -0
- package/dist/{Construct-BD5neF7w.mjs → Construct-Detz65RA.mjs} +31 -29
- package/dist/Construct-Detz65RA.mjs.map +1 -0
- package/dist/{Construct-C0ijr2qp.d.cts → Construct-pVadmURD.d.mts} +10 -12
- package/dist/Construct-pVadmURD.d.mts.map +1 -0
- package/dist/{Construct-CyS3RpTL.cjs → Construct-yG9Sw-5p.cjs} +51 -43
- package/dist/Construct-yG9Sw-5p.cjs.map +1 -0
- package/dist/{Cron-ByxdOfpE.d.mts → Cron-B_iuyNxr.d.mts} +17 -6
- package/dist/Cron-B_iuyNxr.d.mts.map +1 -0
- package/dist/{Cron-Wqh464aO.d.cts → Cron-CA2oa2nC.d.cts} +16 -5
- package/dist/Cron-CA2oa2nC.d.cts.map +1 -0
- package/dist/{CronBuilder-BL0AP6fs.d.mts → CronBuilder-BIKCLWu7.d.mts} +7 -10
- package/dist/CronBuilder-BIKCLWu7.d.mts.map +1 -0
- package/dist/{CronBuilder-BmABazzH.mjs → CronBuilder-BRkzUOAs.mjs} +35 -17
- package/dist/CronBuilder-BRkzUOAs.mjs.map +1 -0
- package/dist/{CronBuilder-BqpEzMPQ.d.cts → CronBuilder-B_KqaodP.d.cts} +6 -9
- package/dist/CronBuilder-B_KqaodP.d.cts.map +1 -0
- package/dist/{CronBuilder-CkXPJiGO.cjs → CronBuilder-BbnT7tqo.cjs} +45 -27
- package/dist/CronBuilder-BbnT7tqo.cjs.map +1 -0
- package/dist/{Endpoint-2Wg7T7Cq.d.mts → Endpoint-BojvdQoh.d.mts} +63 -84
- package/dist/Endpoint-BojvdQoh.d.mts.map +1 -0
- package/dist/{Endpoint-VIOpSo0S.mjs → Endpoint-DO332Dnm.mjs} +117 -109
- package/dist/Endpoint-DO332Dnm.mjs.map +1 -0
- package/dist/{Endpoint-BiaaMEn_.cjs → Endpoint-QKuFg5gs.cjs} +145 -131
- package/dist/Endpoint-QKuFg5gs.cjs.map +1 -0
- package/dist/{Endpoint-CH9Fn1AD.d.cts → Endpoint-xNGuv2Fq.d.cts} +61 -82
- package/dist/Endpoint-xNGuv2Fq.d.cts.map +1 -0
- package/dist/{EndpointFactory-DTTCkGEL.mjs → EndpointFactory-B9HAjDAP.mjs} +26 -32
- package/dist/EndpointFactory-B9HAjDAP.mjs.map +1 -0
- package/dist/{EndpointFactory-ChxLZllA.cjs → EndpointFactory-BmO0WnXE.cjs} +63 -69
- package/dist/EndpointFactory-BmO0WnXE.cjs.map +1 -0
- package/dist/{index-BxHDdy6a.d.mts → EndpointFactory-CaYTrUOO.d.mts} +12 -92
- package/dist/EndpointFactory-CaYTrUOO.d.mts.map +1 -0
- package/dist/{index-V2nksZIJ.d.cts → EndpointFactory-DyT1yOJL.d.cts} +10 -90
- package/dist/EndpointFactory-DyT1yOJL.d.cts.map +1 -0
- package/dist/{HonoEndpointAdaptor-NKQQQbBY.mjs → HonoEndpointAdaptor-CiqAZ5Mt.mjs} +40 -47
- package/dist/{HonoEndpointAdaptor-D233Jvpk.cjs.map → HonoEndpointAdaptor-CiqAZ5Mt.mjs.map} +1 -1
- package/dist/{HonoEndpointAdaptor-D233Jvpk.cjs → HonoEndpointAdaptor-DoEQdC3r.cjs} +48 -52
- package/dist/HonoEndpointAdaptor-DoEQdC3r.cjs.map +1 -0
- package/dist/Queue-B7yRXQmL.cjs +124 -0
- package/dist/Queue-B7yRXQmL.cjs.map +1 -0
- package/dist/{Queue-D7ZuwBhy.d.cts → Queue-Bhzi2WQC.d.cts} +8 -9
- package/dist/Queue-Bhzi2WQC.d.cts.map +1 -0
- package/dist/{Queue-gVGfi2Yk.d.mts → Queue-BoUA-e83.d.mts} +9 -10
- package/dist/Queue-BoUA-e83.d.mts.map +1 -0
- package/dist/Queue-DpKTLl6E.mjs +119 -0
- package/dist/Queue-DpKTLl6E.mjs.map +1 -0
- package/dist/{Subscriber-2mEi0ImH.d.cts → Subscriber-CIO3pwji.d.mts} +7 -8
- package/dist/Subscriber-CIO3pwji.d.mts.map +1 -0
- package/dist/{Subscriber-xTJ9ayPN.d.mts → Subscriber-DQCaiOXF.d.cts} +7 -8
- package/dist/Subscriber-DQCaiOXF.d.cts.map +1 -0
- package/dist/{SubscriberBuilder-BjkbeT9l.mjs → SubscriberBuilder-B4YRTBng.mjs} +16 -10
- package/dist/SubscriberBuilder-B4YRTBng.mjs.map +1 -0
- package/dist/{SubscriberBuilder-Dptmo-1A.d.mts → SubscriberBuilder-C2FRfd26.d.mts} +8 -11
- package/dist/SubscriberBuilder-C2FRfd26.d.mts.map +1 -0
- package/dist/{SubscriberBuilder-4OPehf2R.cjs → SubscriberBuilder-C2bCOuPT.cjs} +28 -23
- package/dist/SubscriberBuilder-C2bCOuPT.cjs.map +1 -0
- package/dist/{SubscriberBuilder-waNhzjSM.d.cts → SubscriberBuilder-CjDGSTZc.d.cts} +7 -10
- package/dist/SubscriberBuilder-CjDGSTZc.d.cts.map +1 -0
- package/dist/Topic-Ct3Le8Wt.mjs +103 -0
- package/dist/Topic-Ct3Le8Wt.mjs.map +1 -0
- package/dist/Topic-D5rlM9wS.cjs +108 -0
- package/dist/Topic-D5rlM9wS.cjs.map +1 -0
- package/dist/{Topic-19QeHBIR.d.cts → Topic-D6blllEn.d.cts} +5 -7
- package/dist/Topic-D6blllEn.d.cts.map +1 -0
- package/dist/{Topic-DuFeqkBh.d.mts → Topic-DVvheJ_-.d.mts} +6 -8
- package/dist/Topic-DVvheJ_-.d.mts.map +1 -0
- package/dist/adaptors/aws.cjs +87 -106
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +14 -27
- package/dist/adaptors/aws.d.cts.map +1 -1
- package/dist/adaptors/aws.d.mts +16 -29
- package/dist/adaptors/aws.d.mts.map +1 -1
- package/dist/adaptors/aws.mjs +60 -81
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/adaptors/hono.cjs +3 -10
- package/dist/adaptors/hono.d.cts +5 -13
- package/dist/adaptors/hono.d.cts.map +1 -1
- package/dist/adaptors/hono.d.mts +7 -15
- package/dist/adaptors/hono.d.mts.map +1 -1
- package/dist/adaptors/hono.mjs +2 -10
- package/dist/adaptors/testing.cjs +396 -82
- package/dist/adaptors/testing.cjs.map +1 -1
- package/dist/adaptors/testing.d.cts +150 -33
- package/dist/adaptors/testing.d.cts.map +1 -1
- package/dist/adaptors/testing.d.mts +151 -34
- package/dist/adaptors/testing.d.mts.map +1 -1
- package/dist/adaptors/testing.mjs +368 -63
- package/dist/adaptors/testing.mjs.map +1 -1
- package/dist/auth-Bmo1wSQF.d.cts +177 -0
- package/dist/auth-Bmo1wSQF.d.cts.map +1 -0
- package/dist/auth-CJ5dp7T7.d.mts +177 -0
- package/dist/auth-CJ5dp7T7.d.mts.map +1 -0
- package/dist/auth.cjs +113 -28
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +2 -108
- package/dist/auth.d.mts +2 -108
- package/dist/auth.mjs +103 -20
- package/dist/auth.mjs.map +1 -1
- package/dist/{cache-BrRz3fEB.d.mts → cache-B2s0b-ss.d.mts} +3 -6
- package/dist/cache-B2s0b-ss.d.mts.map +1 -0
- package/dist/{cache-BtZY_tHe.d.cts → cache-CYe2Kzjc.d.cts} +3 -6
- package/dist/cache-CYe2Kzjc.d.cts.map +1 -0
- package/dist/cache.cjs +68 -2
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.cts +1 -2
- package/dist/cache.d.mts +1 -2
- package/dist/cache.mjs +67 -2
- package/dist/cache.mjs.map +1 -0
- package/dist/{clone-DblgEZZa.mjs → clone-EKNovYHu.mjs} +3 -3
- package/dist/clone-EKNovYHu.mjs.map +1 -0
- package/dist/{clone-Dy0cR2SZ.cjs → clone-UGJpvQnL.cjs} +7 -8
- package/dist/clone-UGJpvQnL.cjs.map +1 -0
- package/dist/{construct-interface-g5GM5pwR.d.mts → construct-interface-D2gesxos.d.mts} +28 -10
- package/dist/construct-interface-D2gesxos.d.mts.map +1 -0
- package/dist/{construct-interface-D9d4Gm4p.d.cts → construct-interface-DPusCUSQ.d.cts} +28 -10
- package/dist/construct-interface-DPusCUSQ.d.cts.map +1 -0
- package/dist/construct-interface.cjs +116 -7
- package/dist/construct-interface.cjs.map +1 -0
- package/dist/construct-interface.d.cts +2 -2
- package/dist/construct-interface.d.mts +2 -2
- package/dist/construct-interface.mjs +108 -2
- package/dist/construct-interface.mjs.map +1 -0
- package/dist/credential.cjs +43 -9
- package/dist/credential.cjs.map +1 -1
- package/dist/credential.d.cts +5 -8
- package/dist/credential.d.cts.map +1 -1
- package/dist/credential.d.mts +5 -8
- package/dist/credential.d.mts.map +1 -1
- package/dist/credential.mjs +36 -2
- package/dist/credential.mjs.map +1 -1
- package/dist/crons/index.cjs +68 -10
- package/dist/crons/index.cjs.map +1 -1
- package/dist/crons/index.d.cts +32 -14
- package/dist/crons/index.d.cts.map +1 -1
- package/dist/crons/index.d.mts +32 -14
- package/dist/crons/index.d.mts.map +1 -1
- package/dist/crons/index.mjs +66 -10
- package/dist/crons/index.mjs.map +1 -1
- package/dist/database/kysely.cjs +40 -15
- package/dist/database/kysely.cjs.map +1 -1
- package/dist/database/kysely.d.cts +2 -152
- package/dist/database/kysely.d.mts +2 -152
- package/dist/database/kysely.mjs +28 -5
- package/dist/database/kysely.mjs.map +1 -1
- package/dist/email.cjs +25 -12
- package/dist/email.cjs.map +1 -1
- package/dist/email.d.cts +3 -7
- package/dist/email.d.cts.map +1 -1
- package/dist/email.d.mts +3 -7
- package/dist/email.d.mts.map +1 -1
- package/dist/email.mjs +16 -3
- package/dist/email.mjs.map +1 -1
- package/dist/endpoints/index.cjs +7 -10
- package/dist/endpoints/index.d.cts +60 -7
- package/dist/endpoints/index.d.cts.map +1 -0
- package/dist/endpoints/index.d.mts +60 -7
- package/dist/endpoints/index.d.mts.map +1 -0
- package/dist/endpoints/index.mjs +5 -10
- package/dist/file-server.cjs +42 -10
- package/dist/file-server.cjs.map +1 -1
- package/dist/file-server.d.cts +6 -10
- package/dist/file-server.d.cts.map +1 -1
- package/dist/file-server.d.mts +6 -10
- package/dist/file-server.d.mts.map +1 -1
- package/dist/file-server.mjs +34 -2
- package/dist/file-server.mjs.map +1 -1
- package/dist/functions/index.cjs +2 -6
- package/dist/functions/index.d.cts +2 -4
- package/dist/functions/index.d.mts +2 -4
- package/dist/functions/index.mjs +2 -6
- package/dist/{functions-Bd3TPxid.cjs → functions-DKN6aQWJ.cjs} +325 -268
- package/dist/functions-DKN6aQWJ.cjs.map +1 -0
- package/dist/{functions-Cxbo-pEd.mjs → functions-DlFm8HmH.mjs} +298 -238
- package/dist/functions-DlFm8HmH.mjs.map +1 -0
- package/dist/{index-JSf9xNIJ.d.cts → index-BI23K3wy.d.cts} +17 -22
- package/dist/index-BI23K3wy.d.cts.map +1 -0
- package/dist/index-CeEtxDmK.d.cts +79 -0
- package/dist/index-CeEtxDmK.d.cts.map +1 -0
- package/dist/index-CeEtxDmK.d.mts +79 -0
- package/dist/index-CeEtxDmK.d.mts.map +1 -0
- package/dist/index-fnpjXiA-.d.mts +26 -0
- package/dist/index-fnpjXiA-.d.mts.map +1 -0
- package/dist/index-tE_119SX.d.cts +26 -0
- package/dist/index-tE_119SX.d.cts.map +1 -0
- package/dist/{index-CubPzHd9.d.mts → index-yb3fXNyH.d.mts} +18 -23
- package/dist/index-yb3fXNyH.d.mts.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -3
- package/dist/kysely-CEVXacPN.d.cts +159 -0
- package/dist/kysely-CEVXacPN.d.cts.map +1 -0
- package/dist/kysely-mcTdPNhl.d.mts +159 -0
- package/dist/kysely-mcTdPNhl.d.mts.map +1 -0
- package/dist/{lazyAccessors-BoJN3SMd.mjs → lazyAccessors-BHtcqgz2.mjs} +22 -25
- package/dist/lazyAccessors-BHtcqgz2.mjs.map +1 -0
- package/dist/{lazyAccessors-e3j2oE2m.cjs → lazyAccessors-Dx9NLwJZ.cjs} +72 -76
- package/dist/lazyAccessors-Dx9NLwJZ.cjs.map +1 -0
- package/dist/object-storage.cjs +18 -10
- package/dist/object-storage.cjs.map +1 -1
- package/dist/object-storage.d.cts +3 -7
- package/dist/object-storage.d.cts.map +1 -1
- package/dist/object-storage.d.mts +3 -7
- package/dist/object-storage.d.mts.map +1 -1
- package/dist/object-storage.mjs +11 -3
- package/dist/object-storage.mjs.map +1 -1
- package/dist/{processAudits-Dmts9H_b.mjs → processAudits-BpRlPQMW.mjs} +16 -19
- package/dist/processAudits-BpRlPQMW.mjs.map +1 -0
- package/dist/{processAudits-CGqttuXm.cjs → processAudits-D_2W5x8k.cjs} +26 -30
- package/dist/processAudits-D_2W5x8k.cjs.map +1 -0
- package/dist/queue/index.cjs +9 -118
- package/dist/queue/index.cjs.map +1 -1
- package/dist/queue/index.d.cts +8 -15
- package/dist/queue/index.d.cts.map +1 -1
- package/dist/queue/index.d.mts +8 -15
- package/dist/queue/index.d.mts.map +1 -1
- package/dist/queue/index.mjs +5 -114
- package/dist/queue/index.mjs.map +1 -1
- package/dist/rest-api.cjs +88 -62
- package/dist/rest-api.cjs.map +1 -1
- package/dist/rest-api.d.cts +62 -60
- package/dist/rest-api.d.cts.map +1 -1
- package/dist/rest-api.d.mts +62 -60
- package/dist/rest-api.d.mts.map +1 -1
- package/dist/rest-api.mjs +80 -54
- package/dist/rest-api.mjs.map +1 -1
- package/dist/{chunk-DWy1uDak.cjs → rolldown-runtime-y5ARvAq5.cjs} +14 -18
- package/dist/site.cjs +33 -9
- package/dist/site.cjs.map +1 -1
- package/dist/site.d.cts +11 -22
- package/dist/site.d.cts.map +1 -1
- package/dist/site.d.mts +11 -22
- package/dist/site.d.mts.map +1 -1
- package/dist/site.mjs +29 -5
- package/dist/site.mjs.map +1 -1
- package/dist/subscribers/index.cjs +2 -11
- package/dist/subscribers/index.d.cts +3 -14
- package/dist/subscribers/index.d.mts +3 -14
- package/dist/subscribers/index.mjs +2 -11
- package/dist/surfaceEnv-CNimK76p.cjs +56 -0
- package/dist/surfaceEnv-CNimK76p.cjs.map +1 -0
- package/dist/surfaceEnv-wMT5QzgZ.mjs +45 -0
- package/dist/surfaceEnv-wMT5QzgZ.mjs.map +1 -0
- package/dist/{telemetry-C3L0iS28.d.cts → telemetry-DGcFlVpB.d.cts} +2 -5
- package/dist/telemetry-DGcFlVpB.d.cts.map +1 -0
- package/dist/{telemetry-D7bVFLGi.d.mts → telemetry-DGcFlVpB.d.mts} +2 -5
- package/dist/telemetry-DGcFlVpB.d.mts.map +1 -0
- package/dist/topic/index.cjs +8 -107
- package/dist/topic/index.cjs.map +1 -1
- package/dist/topic/index.d.cts +3 -32
- package/dist/topic/index.d.mts +3 -32
- package/dist/topic/index.mjs +4 -103
- package/dist/topic/index.mjs.map +1 -1
- package/dist/{types-BlAkSuGI.d.cts → types-DMuSQeLL.d.cts} +3 -5
- package/dist/types-DMuSQeLL.d.cts.map +1 -0
- package/dist/{types-aKksMEWL.d.mts → types-DMuSQeLL.d.mts} +3 -5
- package/dist/types-DMuSQeLL.d.mts.map +1 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.mjs +1 -0
- package/dist/worker.cjs +109 -35
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +87 -42
- package/dist/worker.d.cts.map +1 -1
- package/dist/worker.d.mts +87 -42
- package/dist/worker.d.mts.map +1 -1
- package/dist/worker.mjs +104 -30
- package/dist/worker.mjs.map +1 -1
- package/package.json +59 -55
- package/dist/Construct-BD5neF7w.mjs.map +0 -1
- package/dist/Construct-C0ijr2qp.d.cts.map +0 -1
- package/dist/Construct-Ct8nalEi.d.mts.map +0 -1
- package/dist/Construct-CyS3RpTL.cjs.map +0 -1
- package/dist/Cron-ByxdOfpE.d.mts.map +0 -1
- package/dist/Cron-Wqh464aO.d.cts.map +0 -1
- package/dist/CronBuilder-BL0AP6fs.d.mts.map +0 -1
- package/dist/CronBuilder-BmABazzH.mjs.map +0 -1
- package/dist/CronBuilder-BqpEzMPQ.d.cts.map +0 -1
- package/dist/CronBuilder-CkXPJiGO.cjs.map +0 -1
- package/dist/Endpoint-2Wg7T7Cq.d.mts.map +0 -1
- package/dist/Endpoint-BiaaMEn_.cjs.map +0 -1
- package/dist/Endpoint-CH9Fn1AD.d.cts.map +0 -1
- package/dist/Endpoint-VIOpSo0S.mjs.map +0 -1
- package/dist/EndpointFactory-ChxLZllA.cjs.map +0 -1
- package/dist/EndpointFactory-DTTCkGEL.mjs.map +0 -1
- package/dist/HonoEndpointAdaptor-NKQQQbBY.mjs.map +0 -1
- package/dist/Queue-D7ZuwBhy.d.cts.map +0 -1
- package/dist/Queue-gVGfi2Yk.d.mts.map +0 -1
- package/dist/Subscriber-2mEi0ImH.d.cts.map +0 -1
- package/dist/Subscriber-xTJ9ayPN.d.mts.map +0 -1
- package/dist/SubscriberBuilder-4OPehf2R.cjs.map +0 -1
- package/dist/SubscriberBuilder-BjkbeT9l.mjs.map +0 -1
- package/dist/SubscriberBuilder-Dptmo-1A.d.mts.map +0 -1
- package/dist/SubscriberBuilder-waNhzjSM.d.cts.map +0 -1
- package/dist/Topic-19QeHBIR.d.cts.map +0 -1
- package/dist/Topic-DuFeqkBh.d.mts.map +0 -1
- package/dist/auth.d.cts.map +0 -1
- package/dist/auth.d.mts.map +0 -1
- package/dist/cache-0ANvRQnD.mjs +0 -51
- package/dist/cache-0ANvRQnD.mjs.map +0 -1
- package/dist/cache-3WSvAulx.cjs +0 -57
- package/dist/cache-3WSvAulx.cjs.map +0 -1
- package/dist/cache-BrRz3fEB.d.mts.map +0 -1
- package/dist/cache-BtZY_tHe.d.cts.map +0 -1
- package/dist/clone-DblgEZZa.mjs.map +0 -1
- package/dist/clone-Dy0cR2SZ.cjs.map +0 -1
- package/dist/construct-interface-BfjcOD_E.cjs +0 -117
- package/dist/construct-interface-BfjcOD_E.cjs.map +0 -1
- package/dist/construct-interface-D9d4Gm4p.d.cts.map +0 -1
- package/dist/construct-interface-Z4CpS8tK.mjs +0 -81
- package/dist/construct-interface-Z4CpS8tK.mjs.map +0 -1
- package/dist/construct-interface-g5GM5pwR.d.mts.map +0 -1
- package/dist/database/kysely.d.cts.map +0 -1
- package/dist/database/kysely.d.mts.map +0 -1
- package/dist/functions-Bd3TPxid.cjs.map +0 -1
- package/dist/functions-Cxbo-pEd.mjs.map +0 -1
- package/dist/index-BxHDdy6a.d.mts.map +0 -1
- package/dist/index-CubPzHd9.d.mts.map +0 -1
- package/dist/index-JSf9xNIJ.d.cts.map +0 -1
- package/dist/index-V2nksZIJ.d.cts.map +0 -1
- package/dist/lazyAccessors-BoJN3SMd.mjs.map +0 -1
- package/dist/lazyAccessors-e3j2oE2m.cjs.map +0 -1
- package/dist/processAudits-CGqttuXm.cjs.map +0 -1
- package/dist/processAudits-Dmts9H_b.mjs.map +0 -1
- package/dist/subscribers/index.cjs.map +0 -1
- package/dist/subscribers/index.d.cts.map +0 -1
- package/dist/subscribers/index.d.mts.map +0 -1
- package/dist/subscribers/index.mjs.map +0 -1
- package/dist/surfaceEnv-BFXEms2f.cjs +0 -39
- package/dist/surfaceEnv-BFXEms2f.cjs.map +0 -1
- package/dist/surfaceEnv-C3Ktahea.mjs +0 -27
- package/dist/surfaceEnv-C3Ktahea.mjs.map +0 -1
- package/dist/telemetry-C3L0iS28.d.cts.map +0 -1
- package/dist/telemetry-D7bVFLGi.d.mts.map +0 -1
- package/dist/topic/index.d.cts.map +0 -1
- package/dist/topic/index.d.mts.map +0 -1
- package/dist/types-BlAkSuGI.d.cts.map +0 -1
- package/dist/types-aKksMEWL.d.mts.map +0 -1
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import "../
|
|
3
|
-
import {
|
|
4
|
-
import "../
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { BetterAuth } from "../auth.mjs";
|
|
2
|
+
import { t as FunctionBuilder } from "../functions-DlFm8HmH.mjs";
|
|
3
|
+
import { n as ResponseBuilder, t as Endpoint } from "../Endpoint-DO332Dnm.mjs";
|
|
4
|
+
import { Email } from "../email.mjs";
|
|
5
|
+
import { KyselyDatabase } from "../database/kysely.mjs";
|
|
6
|
+
import { c as createObjectHeaders, l as publishConstructEvents, r as createCookieHeaderAccessor, u as publishEvents } from "../lazyAccessors-BHtcqgz2.mjs";
|
|
7
|
+
import { t as Queue } from "../Queue-DpKTLl6E.mjs";
|
|
8
|
+
import { t as Topic } from "../Topic-Ct3Le8Wt.mjs";
|
|
9
|
+
import { t as HonoEndpoint } from "../HonoEndpointAdaptor-CiqAZ5Mt.mjs";
|
|
10
|
+
import { n as executeWithAuditTransaction } from "../processAudits-BpRlPQMW.mjs";
|
|
11
|
+
import { provideKey } from "@geekmidas/manifest";
|
|
9
12
|
import { ForbiddenError } from "@geekmidas/errors";
|
|
10
13
|
import { EnvironmentParser } from "@geekmidas/envkit";
|
|
11
|
-
import { ServiceDiscovery, runWithRequestContext } from "@geekmidas/services";
|
|
12
|
-
import { DefaultAuditor } from "@geekmidas/audit";
|
|
14
|
+
import { ServiceDiscovery, runWithRequestContext, serviceContext } from "@geekmidas/services";
|
|
13
15
|
import { Hono } from "hono";
|
|
16
|
+
import { DefaultAuditor } from "@geekmidas/audit";
|
|
17
|
+
import { TEST_CONTEXT_HEADER, currentTestContext, installContextFetch, runAsServer, runInTestContext, testContextOf } from "@geekmidas/testkit/context";
|
|
14
18
|
import { http } from "msw";
|
|
15
|
-
|
|
19
|
+
import { randomUUID } from "node:crypto";
|
|
20
|
+
import { Browser } from "@geekmidas/testkit/browser";
|
|
21
|
+
import { createMailbox } from "@geekmidas/testkit/mailbox";
|
|
22
|
+
import { TransactionRegistry } from "@geekmidas/testkit/transactions";
|
|
23
|
+
import { setupServer } from "msw/node";
|
|
24
|
+
import { afterAll, beforeAll, test } from "vitest";
|
|
25
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
26
|
+
import tls from "node:tls";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
16
28
|
//#region src/endpoints/MswEndpointAdaptor.ts
|
|
17
|
-
/**
|
|
18
|
-
* Header used to identify which test context a request belongs to.
|
|
19
|
-
* Each concurrent test registers its own context (services, db transaction, etc.)
|
|
20
|
-
* and the MSW handler looks it up by this header value.
|
|
21
|
-
*/
|
|
22
|
-
const TEST_CONTEXT_HEADER = "x-test-context-id";
|
|
23
29
|
const MSW_HTTP_METHODS = [
|
|
24
30
|
"get",
|
|
25
31
|
"post",
|
|
@@ -111,7 +117,6 @@ function createMswHandlers(endpoints, options) {
|
|
|
111
117
|
registerContext
|
|
112
118
|
};
|
|
113
119
|
}
|
|
114
|
-
|
|
115
120
|
//#endregion
|
|
116
121
|
//#region src/endpoints/TestEndpointAdaptor.ts
|
|
117
122
|
/**
|
|
@@ -131,6 +136,8 @@ function serializeCookie(name, value, options) {
|
|
|
131
136
|
return cookieString;
|
|
132
137
|
}
|
|
133
138
|
var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
139
|
+
endpoint;
|
|
140
|
+
serviceDiscovery;
|
|
134
141
|
static getDefaultServiceDiscover(_endpoint) {
|
|
135
142
|
return ServiceDiscovery.getInstance(new EnvironmentParser({}));
|
|
136
143
|
}
|
|
@@ -165,7 +172,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
|
165
172
|
cookie,
|
|
166
173
|
...rawDb !== void 0 && { db: rawDb }
|
|
167
174
|
});
|
|
168
|
-
|
|
175
|
+
if (!await this.endpoint.authorize({
|
|
169
176
|
header,
|
|
170
177
|
cookie,
|
|
171
178
|
services: ctx.services,
|
|
@@ -175,8 +182,7 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
|
175
182
|
body,
|
|
176
183
|
query,
|
|
177
184
|
params
|
|
178
|
-
})
|
|
179
|
-
if (!isAuthorized) {
|
|
185
|
+
})) {
|
|
180
186
|
logger.warn("Forbidden access attempt");
|
|
181
187
|
throw new ForbiddenError("Forbidden access to the endpoint", "You do not have permission to access this resource.");
|
|
182
188
|
}
|
|
@@ -198,24 +204,22 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
|
198
204
|
} catch (error) {
|
|
199
205
|
logger.error(error, "Failed to extract actor for audits");
|
|
200
206
|
}
|
|
201
|
-
const auditor = new DefaultAuditor({
|
|
202
|
-
actor,
|
|
203
|
-
storage: auditorStorage,
|
|
204
|
-
metadata: {
|
|
205
|
-
endpoint: this.endpoint.route,
|
|
206
|
-
method: this.endpoint.method
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
207
|
auditContext = {
|
|
210
|
-
auditor
|
|
208
|
+
auditor: new DefaultAuditor({
|
|
209
|
+
actor,
|
|
210
|
+
storage: auditorStorage,
|
|
211
|
+
metadata: {
|
|
212
|
+
endpoint: this.endpoint.route,
|
|
213
|
+
method: this.endpoint.method
|
|
214
|
+
}
|
|
215
|
+
}),
|
|
211
216
|
storage: auditorStorage
|
|
212
217
|
};
|
|
213
218
|
}
|
|
214
219
|
const audits = this.endpoint.audits;
|
|
215
220
|
if (!auditContext && audits?.length) logger.warn("No auditor storage service available");
|
|
216
|
-
const
|
|
217
|
-
const
|
|
218
|
-
const db = trx ?? rawDb;
|
|
221
|
+
const { output, metadata } = await executeWithAuditTransaction(auditContext, async (auditor) => {
|
|
222
|
+
const db = auditor?.getTransaction?.() ?? rawDb;
|
|
219
223
|
const responseBuilder = new ResponseBuilder();
|
|
220
224
|
const response = await this.endpoint.handler({
|
|
221
225
|
body,
|
|
@@ -230,36 +234,34 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
|
230
234
|
db
|
|
231
235
|
}, responseBuilder);
|
|
232
236
|
let data = response;
|
|
233
|
-
let metadata
|
|
237
|
+
let metadata = responseBuilder.getMetadata();
|
|
234
238
|
if (Endpoint.hasMetadata(response)) {
|
|
235
239
|
data = response.data;
|
|
236
|
-
metadata
|
|
240
|
+
metadata = response.metadata;
|
|
237
241
|
}
|
|
238
|
-
const output$1 = await this.endpoint.parseOutput(data);
|
|
239
242
|
return {
|
|
240
|
-
output:
|
|
241
|
-
metadata
|
|
243
|
+
output: await this.endpoint.parseOutput(data),
|
|
244
|
+
metadata,
|
|
242
245
|
responseBuilder
|
|
243
246
|
};
|
|
244
|
-
}, async (result
|
|
247
|
+
}, async (result, auditor) => {
|
|
245
248
|
if (!audits?.length) return;
|
|
246
249
|
for (const audit of audits) {
|
|
247
|
-
if (audit.when && !audit.when(result
|
|
248
|
-
const payload = audit.payload(result
|
|
249
|
-
const entityId = audit.entityId?.(result
|
|
250
|
+
if (audit.when && !audit.when(result.output)) continue;
|
|
251
|
+
const payload = audit.payload(result.output);
|
|
252
|
+
const entityId = audit.entityId?.(result.output);
|
|
250
253
|
auditor.audit(audit.type, payload, {
|
|
251
254
|
table: audit.table,
|
|
252
255
|
entityId
|
|
253
256
|
});
|
|
254
257
|
}
|
|
255
258
|
}, { db: rawDb });
|
|
256
|
-
const { output, metadata } = result;
|
|
257
259
|
ctx.publisher && await this.serviceDiscovery.register([ctx.publisher]);
|
|
258
260
|
await publishConstructEvents(this.endpoint, output, this.serviceDiscovery);
|
|
259
261
|
const headers = { ...metadata.headers || {} };
|
|
260
262
|
if (metadata.cookies && metadata.cookies.size > 0) {
|
|
261
263
|
const setCookieValues = [];
|
|
262
|
-
for (const [name, cookie
|
|
264
|
+
for (const [name, cookie] of metadata.cookies.entries()) setCookieValues.push(serializeCookie(name, cookie.value, cookie.options));
|
|
263
265
|
headers["set-cookie"] = setCookieValues;
|
|
264
266
|
}
|
|
265
267
|
return {
|
|
@@ -270,14 +272,14 @@ var TestEndpointAdaptor = class TestEndpointAdaptor {
|
|
|
270
272
|
});
|
|
271
273
|
}
|
|
272
274
|
async request(ctx) {
|
|
273
|
-
|
|
274
|
-
return response.body;
|
|
275
|
+
return (await this.fullRequest(ctx)).body;
|
|
275
276
|
}
|
|
276
277
|
};
|
|
277
|
-
|
|
278
278
|
//#endregion
|
|
279
279
|
//#region src/functions/TestFunctionAdaptor.ts
|
|
280
280
|
var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
281
|
+
fn;
|
|
282
|
+
serviceDiscovery;
|
|
281
283
|
static getDefaultServiceDiscovery(_fn) {
|
|
282
284
|
return ServiceDiscovery.getInstance(new EnvironmentParser({}));
|
|
283
285
|
}
|
|
@@ -293,15 +295,11 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
|
293
295
|
else services = await this.serviceDiscovery.register(this.fn.services);
|
|
294
296
|
let db;
|
|
295
297
|
if ("db" in ctx && ctx.db !== void 0) db = ctx.db;
|
|
296
|
-
else if (this.fn.databaseService)
|
|
297
|
-
const dbServices = await this.serviceDiscovery.register([this.fn.databaseService]);
|
|
298
|
-
db = dbServices[this.fn.databaseService.serviceName];
|
|
299
|
-
}
|
|
298
|
+
else if (this.fn.databaseService) db = (await this.serviceDiscovery.register([this.fn.databaseService]))[this.fn.databaseService.serviceName];
|
|
300
299
|
let auditor;
|
|
301
300
|
if ("auditor" in ctx && ctx.auditor !== void 0) auditor = ctx.auditor;
|
|
302
301
|
else if (this.fn.auditorStorageService) {
|
|
303
|
-
const
|
|
304
|
-
const storage = auditServices[this.fn.auditorStorageService.serviceName];
|
|
302
|
+
const storage = (await this.serviceDiscovery.register([this.fn.auditorStorageService]))[this.fn.auditorStorageService.serviceName];
|
|
305
303
|
auditor = new DefaultAuditor({
|
|
306
304
|
actor: {
|
|
307
305
|
id: "system",
|
|
@@ -315,11 +313,10 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
|
315
313
|
});
|
|
316
314
|
}
|
|
317
315
|
const requestId = `test-${Date.now()}`;
|
|
318
|
-
const startTime = Date.now();
|
|
319
316
|
return runWithRequestContext({
|
|
320
317
|
logger,
|
|
321
318
|
requestId,
|
|
322
|
-
startTime
|
|
319
|
+
startTime: Date.now()
|
|
323
320
|
}, async () => {
|
|
324
321
|
const response = await this.fn.fn({
|
|
325
322
|
input: parsedInput,
|
|
@@ -341,7 +338,6 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
|
341
338
|
});
|
|
342
339
|
}
|
|
343
340
|
};
|
|
344
|
-
|
|
345
341
|
//#endregion
|
|
346
342
|
//#region src/queue/TestQueueAdaptor.ts
|
|
347
343
|
/**
|
|
@@ -354,6 +350,8 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
|
354
350
|
* await adapter.invoke({ messages: [{ orderId: '123' }] });
|
|
355
351
|
*/
|
|
356
352
|
var TestQueueAdaptor = class TestQueueAdaptor {
|
|
353
|
+
queue;
|
|
354
|
+
serviceDiscovery;
|
|
357
355
|
static getDefaultServiceDiscovery() {
|
|
358
356
|
return ServiceDiscovery.getInstance(new EnvironmentParser({}));
|
|
359
357
|
}
|
|
@@ -365,11 +363,10 @@ var TestQueueAdaptor = class TestQueueAdaptor {
|
|
|
365
363
|
const logger = this.queue.logger.child({ test: true });
|
|
366
364
|
const services = request.services ?? await this.serviceDiscovery.register(this.queue.services);
|
|
367
365
|
const requestId = `test-${Date.now()}`;
|
|
368
|
-
const startTime = Date.now();
|
|
369
366
|
return runWithRequestContext({
|
|
370
367
|
logger,
|
|
371
368
|
requestId,
|
|
372
|
-
startTime
|
|
369
|
+
startTime: Date.now()
|
|
373
370
|
}, () => this.queue.handler({
|
|
374
371
|
messages: request.messages,
|
|
375
372
|
services,
|
|
@@ -377,10 +374,11 @@ var TestQueueAdaptor = class TestQueueAdaptor {
|
|
|
377
374
|
}));
|
|
378
375
|
}
|
|
379
376
|
};
|
|
380
|
-
|
|
381
377
|
//#endregion
|
|
382
378
|
//#region src/subscribers/TestSubscriberAdaptor.ts
|
|
383
379
|
var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
380
|
+
subscriber;
|
|
381
|
+
serviceDiscovery;
|
|
384
382
|
static getDefaultServiceDiscovery() {
|
|
385
383
|
return ServiceDiscovery.getInstance(new EnvironmentParser({}));
|
|
386
384
|
}
|
|
@@ -396,11 +394,10 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
|
396
394
|
const filteredEvents = this.filterEvents(request.events);
|
|
397
395
|
if (filteredEvents.length === 0) return { batchItemFailures: [] };
|
|
398
396
|
const requestId = `test-${Date.now()}`;
|
|
399
|
-
const startTime = Date.now();
|
|
400
397
|
return runWithRequestContext({
|
|
401
398
|
logger,
|
|
402
399
|
requestId,
|
|
403
|
-
startTime
|
|
400
|
+
startTime: Date.now()
|
|
404
401
|
}, async () => {
|
|
405
402
|
const result = await this.subscriber.handler({
|
|
406
403
|
events: filteredEvents,
|
|
@@ -422,7 +419,315 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
|
422
419
|
return events.filter((event) => this.subscriber.subscribedEvents.includes(event.type));
|
|
423
420
|
}
|
|
424
421
|
};
|
|
425
|
-
|
|
426
422
|
//#endregion
|
|
427
|
-
|
|
423
|
+
//#region src/testing/manifest.ts
|
|
424
|
+
/**
|
|
425
|
+
* The test manifest: what `gkm test` knows about an app, written down for the
|
|
426
|
+
* suite it starts.
|
|
427
|
+
*
|
|
428
|
+
* `gkm test` discovers the constructs, reconciles the test stage and resolves
|
|
429
|
+
* its environment — then, until this existed, threw all of it away and left a
|
|
430
|
+
* test to declare it again by hand. The manifest keeps it: which construct and
|
|
431
|
+
* endpoint is exported where, and the environment the test stage resolved,
|
|
432
|
+
* under the keys the constructs themselves derive. A feature test is built from
|
|
433
|
+
* it, so nothing a test says can drift from what the app declares.
|
|
434
|
+
*/
|
|
435
|
+
/** The environment variable `gkm test` names the manifest in. */
|
|
436
|
+
const TEST_MANIFEST_ENV = "GKM_TEST_MANIFEST";
|
|
437
|
+
/**
|
|
438
|
+
* Read a test manifest: from a path, a `file:` URL, or — given nothing — the
|
|
439
|
+
* one `gkm test` named in `GKM_TEST_MANIFEST`.
|
|
440
|
+
*/
|
|
441
|
+
function loadTestManifest(from) {
|
|
442
|
+
const location = from ?? process.env["GKM_TEST_MANIFEST"];
|
|
443
|
+
if (!location) throw new NoTestManifest();
|
|
444
|
+
trustLocalEdge();
|
|
445
|
+
const path = location instanceof URL || location.startsWith("file:") ? fileURLToPath(location) : location;
|
|
446
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
447
|
+
}
|
|
448
|
+
let trusted = false;
|
|
449
|
+
/**
|
|
450
|
+
* Trust the local edge's certificate authority in this thread.
|
|
451
|
+
*
|
|
452
|
+
* `NODE_EXTRA_CA_CERTS` does it for a process started with it — which a
|
|
453
|
+
* suite started by `gkm test` is, and one started by plain `vitest` or an
|
|
454
|
+
* editor is not: its setup only learns the path once Vitest is running, and a
|
|
455
|
+
* worker *thread* shares that process and keeps a TLS store of its own. Every
|
|
456
|
+
* feature test loads the manifest, so this is the one place each worker passes
|
|
457
|
+
* through.
|
|
458
|
+
*/
|
|
459
|
+
function trustLocalEdge() {
|
|
460
|
+
const certificate = process.env.NODE_EXTRA_CA_CERTS;
|
|
461
|
+
if (trusted || !certificate || !existsSync(certificate)) return;
|
|
462
|
+
trusted = true;
|
|
463
|
+
tls.setDefaultCACertificates([...tls.getCACertificates("default"), readFileSync(certificate, "utf-8")]);
|
|
464
|
+
}
|
|
465
|
+
/** A feature test ran without a manifest to build itself from. */
|
|
466
|
+
var NoTestManifest = class extends Error {
|
|
467
|
+
constructor() {
|
|
468
|
+
super(`No test manifest: run the suite with \`gkm test\`, or add \`globalSetup: ['@geekmidas/cli/vitest']\` to the root vitest config — either writes one and names it in ${TEST_MANIFEST_ENV}.`);
|
|
469
|
+
this.name = "NoTestManifest";
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/testing/featureTest.ts
|
|
474
|
+
/**
|
|
475
|
+
* `featureTest`: an app, driven the way it runs deployed.
|
|
476
|
+
*
|
|
477
|
+
* A browser signs in and calls the API; the API calls the auth server; each
|
|
478
|
+
* over its URL, each database in its own transaction. Nothing runs as a server:
|
|
479
|
+
* every URL an app's constructs answer on is served in-process through MSW,
|
|
480
|
+
* from the real handler, for the test that made the request. Everything else
|
|
481
|
+
* with a real local equivalent — Postgres, Mailpit, MinIO — is used directly.
|
|
482
|
+
*
|
|
483
|
+
* It is built from the test manifest `gkm test` writes — the constructs and
|
|
484
|
+
* endpoints the app exports, and the environment the test stage resolved — so
|
|
485
|
+
* a test declares none of it. `gkm test` also generates the configured `it`
|
|
486
|
+
* and a `Browser` with a typed client per surface:
|
|
487
|
+
*
|
|
488
|
+
* ```ts
|
|
489
|
+
* import { it } from '#test';
|
|
490
|
+
*
|
|
491
|
+
* it('shows the signed-in user their profile', async ({ browser, mailbox }) => {
|
|
492
|
+
* await browser.auth.signIn.magicLink({ email: 'ada@shop.test' });
|
|
493
|
+
* await browser.visit((await mailbox('ada@shop.test').last()).link!);
|
|
494
|
+
* expect(await browser.api.get('/profile')).toMatchObject({ email: 'ada@shop.test' });
|
|
495
|
+
* });
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
/** Every test in flight in this process, by id. */
|
|
499
|
+
const contexts = /* @__PURE__ */ new Map();
|
|
500
|
+
/** Databases already resolving to test transactions — patched once each. */
|
|
501
|
+
const bound = /* @__PURE__ */ new WeakSet();
|
|
502
|
+
function featureTest(options = {}) {
|
|
503
|
+
const manifest = options.manifest ?? loadTestManifest();
|
|
504
|
+
const BrowserClass = options.browser ?? Browser;
|
|
505
|
+
let app;
|
|
506
|
+
let network;
|
|
507
|
+
let restoreFetch = () => {};
|
|
508
|
+
beforeAll(async () => {
|
|
509
|
+
app = await load(manifest, options.database, options.modules ?? {});
|
|
510
|
+
for (const database of app.databases) bindToTests(database);
|
|
511
|
+
network = setupServer(...surfaceHandlers(app.endpoints, manifest.env), ...app.auths.map((auth) => authHandler(auth, manifest.env, app.envParser)));
|
|
512
|
+
network.listen({ onUnhandledRequest(request, print) {
|
|
513
|
+
if (isLocal(new URL(request.url))) return;
|
|
514
|
+
print.error();
|
|
515
|
+
} });
|
|
516
|
+
restoreFetch = installContextFetch();
|
|
517
|
+
});
|
|
518
|
+
afterAll(() => {
|
|
519
|
+
restoreFetch();
|
|
520
|
+
network?.close();
|
|
521
|
+
});
|
|
522
|
+
const run = (fn) => async () => {
|
|
523
|
+
const id = randomUUID();
|
|
524
|
+
const state = {
|
|
525
|
+
transactions: new TransactionRegistry(),
|
|
526
|
+
discovery: new ServiceDiscovery(app.envParser),
|
|
527
|
+
surfaces: /* @__PURE__ */ new Map(),
|
|
528
|
+
auth: /* @__PURE__ */ new Map(),
|
|
529
|
+
addresses: /* @__PURE__ */ new Set(),
|
|
530
|
+
published: /* @__PURE__ */ new Map()
|
|
531
|
+
};
|
|
532
|
+
contexts.set(id, state);
|
|
533
|
+
await state.discovery.register(recorders(app.channels, state));
|
|
534
|
+
try {
|
|
535
|
+
await runInTestContext(id, async () => {
|
|
536
|
+
const browser = new BrowserClass();
|
|
537
|
+
const restore = browser.install();
|
|
538
|
+
try {
|
|
539
|
+
await fn({
|
|
540
|
+
browser,
|
|
541
|
+
db: app.database ? await state.transactions.get(app.database.id, urlOf(app.database, app.envParser), app.database.clientConfig) : void 0,
|
|
542
|
+
mailbox: (address) => {
|
|
543
|
+
if (!app.readMail) throw new NoInbox();
|
|
544
|
+
state.addresses.add(address);
|
|
545
|
+
return app.readMail(address);
|
|
546
|
+
},
|
|
547
|
+
published: (channel) => [...state.published.get(channel.id) ?? []],
|
|
548
|
+
subscriber: (subscriber) => new TestSubscriberAdaptor(subscriber, state.discovery),
|
|
549
|
+
queue: (queue) => new TestQueueAdaptor(queue, state.discovery)
|
|
550
|
+
});
|
|
551
|
+
} finally {
|
|
552
|
+
restore();
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
} finally {
|
|
556
|
+
contexts.delete(id);
|
|
557
|
+
await Promise.all([state.transactions.rollbackAll(), ...[...state.addresses].map((address) => app.readMail?.(address).clear())]);
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
const it = ((name, fn, timeout) => test(name, run(fn), timeout));
|
|
561
|
+
it.only = (name, fn, timeout) => test.only(name, run(fn), timeout);
|
|
562
|
+
it.skip = (name, fn, timeout) => test.skip(name, run(fn), timeout);
|
|
563
|
+
return it;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Import what the manifest points at.
|
|
567
|
+
*
|
|
568
|
+
* The same modules the app runs, so a construct here *is* the app's construct —
|
|
569
|
+
* the one its endpoints were built from — never a copy declared again.
|
|
570
|
+
*/
|
|
571
|
+
async function load(manifest, database, modules) {
|
|
572
|
+
const envParser = new EnvironmentParser({ ...manifest.env });
|
|
573
|
+
const imported = async ({ file, export: name }) => (modules[file] ?? await import(file))[name];
|
|
574
|
+
const constructs = await Promise.all(Object.values(manifest.constructs).map(({ source }) => imported(source)));
|
|
575
|
+
const endpoints = (await Promise.all(manifest.endpoints.map(({ source }) => imported(source)))).filter((value) => Endpoint.isEndpoint(value));
|
|
576
|
+
const unique = (values) => [...new Set(values)];
|
|
577
|
+
const databases = unique(constructs.filter((value) => value instanceof KyselyDatabase));
|
|
578
|
+
const auths = unique(constructs.filter((value) => value instanceof BetterAuth));
|
|
579
|
+
const emails = unique(constructs.filter((value) => value instanceof Email));
|
|
580
|
+
const channels = unique(constructs.filter((value) => value instanceof Topic || value instanceof Queue));
|
|
581
|
+
const inbox = emails.map((email) => manifest.env[provideKey(email.id, "inboxUrl")]).find(Boolean);
|
|
582
|
+
return {
|
|
583
|
+
envParser,
|
|
584
|
+
endpoints,
|
|
585
|
+
databases,
|
|
586
|
+
auths,
|
|
587
|
+
emails,
|
|
588
|
+
channels,
|
|
589
|
+
database: databaseOf(databases, endpoints, database),
|
|
590
|
+
...inbox ? { readMail: createMailbox({ inbox }) } : {}
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* A publisher that records rather than sends, under every name a topic or
|
|
595
|
+
* queue is injected by — `users`, and the older `usersPublisher`.
|
|
596
|
+
*/
|
|
597
|
+
function recorders(channels, state) {
|
|
598
|
+
return channels.flatMap((channel) => {
|
|
599
|
+
const publisher = { async publish(messages) {
|
|
600
|
+
state.published.set(channel.id, [...state.published.get(channel.id) ?? [], ...messages.map(({ type, payload }) => ({
|
|
601
|
+
type,
|
|
602
|
+
payload
|
|
603
|
+
}))]);
|
|
604
|
+
} };
|
|
605
|
+
return [channel.service.serviceName, channel.publisher.serviceName].map((serviceName) => ({
|
|
606
|
+
serviceName,
|
|
607
|
+
register: () => publisher
|
|
608
|
+
}));
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* The database a test sees as `db`: the one named, or else the one the
|
|
613
|
+
* endpoints were given with `.database()` — found by the service they hold,
|
|
614
|
+
* which is the construct's own.
|
|
615
|
+
*/
|
|
616
|
+
function databaseOf(databases, endpoints, named) {
|
|
617
|
+
if (named) {
|
|
618
|
+
const found = databases.find(({ id }) => id === named);
|
|
619
|
+
if (!found) throw new UnknownDatabase(named, databases.map(({ id }) => id));
|
|
620
|
+
return found;
|
|
621
|
+
}
|
|
622
|
+
const services = new Set(endpoints.map((e) => e.databaseService).filter(Boolean));
|
|
623
|
+
return databases.find((database) => services.has(database.service));
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Make a database resolve, inside a test, to that test's transaction.
|
|
627
|
+
*
|
|
628
|
+
* Everything reaches a database through its service — an endpoint through
|
|
629
|
+
* service discovery, the auth server through its tenant directly — so this is
|
|
630
|
+
* the one place a test's connection can be handed over. Outside a test it is
|
|
631
|
+
* the database it always was.
|
|
632
|
+
*/
|
|
633
|
+
function bindToTests(database) {
|
|
634
|
+
if (bound.has(database)) return;
|
|
635
|
+
bound.add(database);
|
|
636
|
+
const service = database.service;
|
|
637
|
+
const register = service.register;
|
|
638
|
+
service.register = (options) => {
|
|
639
|
+
const context = currentTestContext();
|
|
640
|
+
const state = context && contexts.get(context.id);
|
|
641
|
+
if (!state) return register(options);
|
|
642
|
+
return state.transactions.get(database.id, urlOf(database, options.envParser), database.clientConfig);
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
function urlOf(database, envParser) {
|
|
646
|
+
return envParser.create((get) => ({ url: get(provideKey(database.id, "url")).string() })).parse().url;
|
|
647
|
+
}
|
|
648
|
+
/** Each surface's endpoints, served at its URL for the test that asked. */
|
|
649
|
+
function surfaceHandlers(endpoints, env) {
|
|
650
|
+
const bySurface = /* @__PURE__ */ new Map();
|
|
651
|
+
for (const endpoint of endpoints) {
|
|
652
|
+
const surface = endpoint.surface?.id;
|
|
653
|
+
if (!surface) continue;
|
|
654
|
+
bySurface.set(surface, [...bySurface.get(surface) ?? [], endpoint]);
|
|
655
|
+
}
|
|
656
|
+
return [...bySurface].flatMap(([surface, served]) => {
|
|
657
|
+
const base = env[provideKey(surface, "url")];
|
|
658
|
+
if (!base) return [];
|
|
659
|
+
return http.all(`${trim(base)}/*`, ({ request }) => serve(request, async (state) => {
|
|
660
|
+
let app = state.surfaces.get(surface);
|
|
661
|
+
if (!app) {
|
|
662
|
+
app = Promise.resolve().then(() => {
|
|
663
|
+
const hono = new Hono();
|
|
664
|
+
HonoEndpoint.addRoutes(served, state.discovery, hono);
|
|
665
|
+
return hono;
|
|
666
|
+
});
|
|
667
|
+
state.surfaces.set(surface, app);
|
|
668
|
+
}
|
|
669
|
+
return (await app).fetch(request);
|
|
670
|
+
}));
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
/** An auth server, served at its URL, on the transaction of the test that asked. */
|
|
674
|
+
function authHandler(auth, env, envParser) {
|
|
675
|
+
const base = trim(env[provideKey(auth.id, "url")] ?? "");
|
|
676
|
+
return http.all(`${base}/*`, ({ request }) => serve(request, async (state) => {
|
|
677
|
+
let app = state.auth.get(auth);
|
|
678
|
+
if (!app) {
|
|
679
|
+
app = auth.server({
|
|
680
|
+
envParser,
|
|
681
|
+
context: serviceContext
|
|
682
|
+
}).then(({ app }) => app);
|
|
683
|
+
state.auth.set(auth, app);
|
|
684
|
+
}
|
|
685
|
+
return (await app).fetch(request);
|
|
686
|
+
}));
|
|
687
|
+
}
|
|
688
|
+
/** Handle a request as the server side of the test it was made for. */
|
|
689
|
+
async function serve(request, handle) {
|
|
690
|
+
const id = testContextOf(request);
|
|
691
|
+
const state = id ? contexts.get(id) : void 0;
|
|
692
|
+
if (!id || !state) throw new UnknownTestContext(request.url, id);
|
|
693
|
+
return runAsServer(id, () => handle(state));
|
|
694
|
+
}
|
|
695
|
+
function trim(url) {
|
|
696
|
+
return url.replace(/\/$/, "");
|
|
697
|
+
}
|
|
698
|
+
function isLocal(url) {
|
|
699
|
+
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname.endsWith(".localhost");
|
|
700
|
+
}
|
|
701
|
+
/** A request reached an in-process server without a test to belong to. */
|
|
702
|
+
var UnknownTestContext = class extends Error {
|
|
703
|
+
url;
|
|
704
|
+
id;
|
|
705
|
+
constructor(url, id) {
|
|
706
|
+
super(id ? `${url} was requested for test ${id}, which is not running. A request that outlives its test — an un-awaited call — lands here.` : `${url} was requested outside any test. Make the request inside a featureTest, so it reaches that test's transactions.`);
|
|
707
|
+
this.url = url;
|
|
708
|
+
this.id = id;
|
|
709
|
+
this.name = "UnknownTestContext";
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
/** `mailbox` was used in an app that declares no Email construct. */
|
|
713
|
+
var NoInbox = class extends Error {
|
|
714
|
+
constructor() {
|
|
715
|
+
super("mailbox() reads the inbox of the app's Email construct, and none was found in featureTest's modules — or `gkm test` did not inject its <ID>_INBOX_URL.");
|
|
716
|
+
this.name = "NoInbox";
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
/** `featureTest({ database })` named a database the app does not declare. */
|
|
720
|
+
var UnknownDatabase = class extends Error {
|
|
721
|
+
id;
|
|
722
|
+
declared;
|
|
723
|
+
constructor(id, declared) {
|
|
724
|
+
super(`featureTest was asked for the database '${id}', and the app declares ${declared.length ? declared.map((d) => `'${d}'`).join(", ") : "none"}.`);
|
|
725
|
+
this.id = id;
|
|
726
|
+
this.declared = declared;
|
|
727
|
+
this.name = "UnknownDatabase";
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
//#endregion
|
|
731
|
+
export { NoInbox, NoTestManifest, TEST_CONTEXT_HEADER, TEST_MANIFEST_ENV, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, UnknownDatabase, UnknownTestContext, createMswHandlers, featureTest, loadTestManifest };
|
|
732
|
+
|
|
428
733
|
//# sourceMappingURL=testing.mjs.map
|