void 0.26.1 → 0.28.0
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 +3 -1
- package/dist/{account-cmd-CfUXh_nU.mjs → account-cmd-Ci00cncT.mjs} +5 -5
- package/dist/{agents-B_pX_HmQ.mjs → agents-CuNtT0D_.mjs} +5 -2
- package/dist/{application-analysis-DKy02UY0.mjs → application-analysis-D72ZQfMZ.mjs} +118 -135
- package/dist/{application-routing-DQyUh_5S.mjs → application-routing-Dy589Vgn.mjs} +1 -2
- package/dist/atomic-write-Dq6R0BPN.mjs +18 -0
- package/dist/{auth-B5_tZLxT.mjs → auth-B6iOCjKI.mjs} +23 -56
- package/dist/{auth-link-D5RmKnzh.mjs → auth-link-DWr6Afao.mjs} +10 -10
- package/dist/{auth-migrations-BwHgeEsD.mjs → auth-migrations-Cgs0k6lS.mjs} +28 -5
- package/dist/{auth-router-Bap-pvbn.mjs → auth-router-DP14wVkZ.mjs} +4 -4
- package/dist/auth-wn6F8dB8.mjs +2 -0
- package/dist/base64-DVrOndmI.mjs +16 -0
- package/dist/{better-auth-shared-CPvWD3nG.d.mts → better-auth-shared-B74NJIus.d.mts} +8 -13
- package/dist/{better-auth-shared-DPpj8zxc.mjs → better-auth-shared-CMXlZG7W.mjs} +56 -68
- package/dist/{build-cmd-B58c8iS8.mjs → build-cmd-Cr3FJxv0.mjs} +5 -5
- package/dist/{cache-Bo52trKF.mjs → cache-D0Tt28cn.mjs} +5 -5
- package/dist/{cancel-deploy-BZNz3Q26.mjs → cancel-deploy-CJKvk7AN.mjs} +4 -4
- package/dist/{cf-access-TWNzXltp.mjs → cf-access-BM9G0lhO.mjs} +4 -3
- package/dist/{cf-access-ngGqZpHZ.mjs → cf-access-CWP4avfP.mjs} +3 -7
- package/dist/cf-build-output-2u583yJK.mjs +2 -0
- package/dist/{cf-build-output-DjvB_872.mjs → cf-build-output-Bc8i3dzE.mjs} +2 -2
- package/dist/cf-user-agent-ChjQp2MU.mjs +33 -0
- package/dist/cli/cli.mjs +198 -311
- package/dist/cli/cloudflare-operation-process.mjs +46 -14
- package/dist/cli/env-schema-probe.d.mts +5 -43
- package/dist/cli/env-schema-probe.mjs +14 -80
- package/dist/client-C1BjRn3g.mjs +2 -0
- package/dist/{client-C2Prx_Bi.mjs → client-DM9Kcf4e.mjs} +161 -415
- package/dist/{cloudflare-auth-CuxfF6OA.mjs → cloudflare-auth-CqFBDo52.mjs} +12 -39
- package/dist/{cloudflare-cmd-lHqNlJGW.mjs → cloudflare-cmd-CTrn-lXJ.mjs} +6 -5
- package/dist/{cloudflare-config-BmhBv3HV.mjs → cloudflare-config-DV60XFFK.mjs} +16 -28
- package/dist/{cloudflare-connect-2G3rL2rP.mjs → cloudflare-connect-BosmCNlq.mjs} +3 -3
- package/dist/{cloudflare-operations-CwI1bChl.mjs → cloudflare-operations-BKdSfNBN.mjs} +26 -34
- package/dist/{cloudflare-operations-BlYLlowZ.mjs → cloudflare-operations-Ds-lX3Ts.mjs} +1 -1
- package/dist/{cloudflare-process-2-TfIEzB.mjs → cloudflare-process-CeDWJRhj.mjs} +12 -7
- package/dist/collect-NUlJMpLY.mjs +2 -0
- package/dist/{collect-DiTn9yr6.mjs → collect-xjffdCdk.mjs} +1 -1
- package/dist/{config-CSa15FvD.d.mts → config-7qoq2p9v.d.mts} +2 -2
- package/dist/{config-CLYAosnQ.mjs → config-BEm9vRvS.mjs} +11 -5
- package/dist/{config-DiowPT80.mjs → config-Bx_1SpnO.mjs} +87 -177
- package/dist/config-CNnrSMYm.mjs +2 -0
- package/dist/{config-DPByhVck.mjs → config-D0GY5ItR.mjs} +1 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{connect-X0MUA1gk.mjs → connect-nukQSoEO.mjs} +8 -8
- package/dist/{create-project-DxiyW6iX.mjs → create-project-D4APeBwX.mjs} +7 -7
- package/dist/{create-project-iwkbqiBU.mjs → create-project-DL7YXpjj.mjs} +1 -1
- package/dist/{db-XnVMHzoV.mjs → db-27RztQLy.mjs} +173 -263
- package/dist/{delete-esYlMiSJ.mjs → delete-BbsZFZIw.mjs} +5 -5
- package/dist/deploy-B06EQq4t.mjs +6009 -0
- package/dist/deploy-Db2ALnQP.mjs +3 -0
- package/dist/deploy-managed-static-CGswbcay.mjs +2277 -0
- package/dist/deploy-transport-BiicfoQW.mjs +180 -0
- package/dist/deploy.d.mts +10 -0
- package/dist/deploy.mjs +82 -0
- package/dist/dev-inbox-Rd6j_8vM.mjs +217 -0
- package/dist/discover-CTUiSsfG.mjs +2 -0
- package/dist/{discover-CkCYv9T_.mjs → discover-D2PGT63u.mjs} +2 -2
- package/dist/{dist-BVqXeR_h.mjs → dist-ipQi0Q8y.mjs} +2 -3
- package/dist/{domain-CbbBWhWE.mjs → domain-Bfq9n03H.mjs} +7 -22
- package/dist/{dotenv-BfU6eqFt.mjs → dotenv-CNazY3-w.mjs} +4 -16
- package/dist/{email-d_Aux1vM.mjs → email-BcjSyAL0.mjs} +4 -20
- package/dist/{email-CpuT42g7.mjs → email-DIwaQU4P.mjs} +99 -191
- package/dist/email-cloudflare-CH053RxK.mjs +1096 -0
- package/dist/email-protocol-D9nTvhCp.mjs +82 -0
- package/dist/{entry-CMAkqBmU.mjs → entry-ehmBvs5w.mjs} +2 -2
- package/dist/{env-BxocywBB.mjs → env-BJjULvL0.mjs} +2 -2
- package/dist/{env-DMA3cXZt.mjs → env-BhdWMrNy.mjs} +2 -13
- package/dist/{env-w9jOyGZn.mjs → env-C6ipBLp3.mjs} +8 -8
- package/dist/{env-public-DR7ZM6d-.d.mts → env-public-CCdykygU.d.mts} +6 -23
- package/dist/{env-raw-jZpP5n47.mjs → env-raw-Cklzcde3.mjs} +3 -20
- package/dist/{env-types-CwXgeMgL.mjs → env-types-DS2_y4X8.mjs} +2 -2
- package/dist/{env-validation-CrVNjsPm.mjs → env-validation-CTn-HhG1.mjs} +1 -1
- package/dist/env-validation-cE0zcmzO.mjs +486 -0
- package/dist/{gen-DtkQhvQg.mjs → gen-CnN1Xidx.mjs} +131 -253
- package/dist/gen-F8pSZnhc.mjs +2 -0
- package/dist/{generate-GDbL7sUr.mjs → generate-Dat0UTry.mjs} +38 -4
- package/dist/generate-Rii9klHB.mjs +2 -0
- package/dist/generated-wrangler-config-DeWj5F9Y.mjs +18 -0
- package/dist/{github-cmd-D_FsOFxq.mjs → github-cmd-BdkU4Nhe.mjs} +27 -71
- package/dist/{handler-BHAn2fZJ.mjs → handler-BZ1t7-Rv.mjs} +2 -2
- package/dist/{handler-CNAwjRcW.d.mts → handler-_PqY82xe.d.mts} +1 -1
- package/dist/{headers-DlfR78Nu.mjs → headers-Di1FsD3e.mjs} +26 -81
- package/dist/{help-CVFBTmBx.mjs → help-Bug7pyK_.mjs} +18 -10
- package/dist/help-s9q7LTcu.mjs +2 -0
- package/dist/{inbound-PfQDLXc5.mjs → inbound-DmkTQeWp.mjs} +71 -222
- package/dist/{inbound-CH5Mksyy.d.mts → inbound-brj2-TM5.d.mts} +19 -58
- package/dist/index.d.mts +2 -18
- package/dist/index.mjs +200 -496
- package/dist/{info-PYWwkWyt.mjs → info-CujPwtMe.mjs} +5 -5
- package/dist/{init-Bw-fRKGp.mjs → init-ZWOJvc-Z.mjs} +179 -388
- package/dist/isr-config-DPjXM8J2.mjs +194 -0
- package/dist/{link-DlPG8iX3.mjs → link-UEc7bnF4.mjs} +8 -8
- package/dist/{list-2GN7_ueV.mjs → list-CuWeOnzk.mjs} +6 -17
- package/dist/{live-CgQuTpqD.mjs → live-BxLX-JqJ.mjs} +19 -17
- package/dist/{live-Du8jXwOW.d.mts → live-DJONVlQK.d.mts} +1 -1
- package/dist/load-user-env-DD5qveNU.mjs +49 -0
- package/dist/{local-d1-ga5O_idV.mjs → local-d1-BM3p74mm.mjs} +6 -6
- package/dist/{login-D-Q4xw3Q.mjs → login-CZ2Cqa-D.mjs} +11 -11
- package/dist/login-DhK7o1oJ.mjs +2 -0
- package/dist/{logs-rd8J-OFh.mjs → logs-TihRcLTk.mjs} +5 -5
- package/dist/migrate-BgT-hmu8.mjs +2 -0
- package/dist/{migrate-NLsjBbuM.mjs → migrate-uFwojusJ.mjs} +69 -21
- package/dist/migration-handler-Cg0Y4EPu.mjs +470 -0
- package/dist/{migration-handler-DM4clYj5.d.mts → migration-handler-CwlEQUoo.d.mts} +17 -26
- package/dist/{mime-DxCznlJq.mjs → mime-srOklVVv.mjs} +92 -395
- package/dist/{node-DJicPvPj.mjs → node-DoKbo1SZ.mjs} +8 -24
- package/dist/{operator-args-BNsW5gfp.mjs → operator-args-UnE8Y2eK.mjs} +27 -26
- package/dist/{operator-auth-AzVLbrr3.mjs → operator-auth-Cr2zCc-J.mjs} +2 -2
- package/dist/{operator-client-BQtzyG-g.mjs → operator-client-C-ROjk1I.mjs} +4 -4
- package/dist/{operator-cmd-B6f6Cg9Z.mjs → operator-cmd-C5lCctnc.mjs} +8 -8
- package/dist/operator-cmd-Cjk5DiRx.mjs +2 -0
- package/dist/{output-C50ag2r3.mjs → output-FNHKw5Ac.mjs} +36 -5
- package/dist/{package-json-DXfiT1jV.mjs → package-json-BjYqR-So.mjs} +1 -1
- package/dist/pages/client.d.mts +1 -1
- package/dist/pages/client.mjs +91 -5
- package/dist/pages/index.d.mts +1 -2
- package/dist/pages/index.mjs +6 -6
- package/dist/pages/islands-plugin.mjs +5 -83
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +1 -1
- package/dist/pages/serialize.mjs +1 -1
- package/dist/{platform-args-BoZkWQnJ.mjs → platform-args-C6Mb_I3a.mjs} +34 -58
- package/dist/platform-args-Cm7x-fot.mjs +2 -0
- package/dist/{platform-auth-config-n603OANg.mjs → platform-auth-config-CJmNkFT2.mjs} +10 -11
- package/dist/{platform-auth-protection-zxDr0hWW.mjs → platform-auth-protection-D5wvsI-Y.mjs} +36 -26
- package/dist/{platform-auth-recovery-tw9lgtgE.mjs → platform-auth-recovery-D_0I3n-1.mjs} +8 -9
- package/dist/{platform-cmd-C00YM14r.mjs → platform-cmd-Cuj4oUVo.mjs} +1 -1
- package/dist/{platform-cmd-B8-bCb7t.mjs → platform-cmd-DxxZO6e5.mjs} +17 -16
- package/dist/{platform-discovery-BC0HCKYt.mjs → platform-discovery-CHhNs8Nn.mjs} +1 -1
- package/dist/{platform-domain-p0kobLV8.mjs → platform-domain-zLXnW1G_.mjs} +5 -5
- package/dist/{platform-lifecycle-D_QEY32D.mjs → platform-lifecycle-DOW-wLfx.mjs} +1398 -2043
- package/dist/{platform-lifecycle-vFqtNPPa.mjs → platform-lifecycle-_gfnjUBr.mjs} +1 -1
- package/dist/{platform-management-oi-SvI3f.mjs → platform-management-CYrLvTGH.mjs} +1 -1
- package/dist/{platform-management-BdYblvvE.mjs → platform-management-t7HKy4-U.mjs} +632 -124
- package/dist/{platform-plans-config-CjiFv5J4.mjs → platform-plans-config-CNH6zbPX.mjs} +15 -11
- package/dist/{platform-recovery-PvNS9Nl2.mjs → platform-recovery-DeucI7A9.mjs} +6 -9
- package/dist/{platform-registry-P387v42A.mjs → platform-registry-B9mWX9LO.mjs} +18 -19
- package/dist/{platform-setup-DVe42Ws7.mjs → platform-setup-CTf6MMT9.mjs} +19 -26
- package/dist/{plugin-inference-BlQbOL0P.mjs → plugin-inference-DsARdQKE.mjs} +18 -33
- package/dist/{prepare-Dq9hTIbo.mjs → prepare-C4zfwks4.mjs} +3 -3
- package/dist/{prepare-Do96654b.mjs → prepare-CSH9dKTI.mjs} +11 -13
- package/dist/prepare-dr9uxQSV.mjs +2 -0
- package/dist/{prerender-render-Ct20jftc.mjs → prerender-render-Bfsumdkv.mjs} +8 -2
- package/dist/prerender-render.d.mts +2 -0
- package/dist/prerender-render.mjs +2 -2
- package/dist/project-DiiOBZPF.mjs +2 -0
- package/dist/{project-cmd-ti8_yTcA.mjs → project-cmd-Dq75AXzy.mjs} +19 -19
- package/dist/{project-paths-GgcMozYz.mjs → project-paths-DMvEeSau.mjs} +9 -14
- package/dist/{project-DQstYTxO.mjs → project-rqDnVsJN.mjs} +8 -4
- package/dist/{project-team-CDPE1Tsg.mjs → project-team-B3_QcStG.mjs} +6 -6
- package/dist/{project-token-CkZ1cN0Z.mjs → project-token-CvsRvv2I.mjs} +5 -5
- package/dist/{project-tsconfig-CVJhNMxs.mjs → project-tsconfig-bveqhlYA.mjs} +3 -5
- package/dist/{project-zero-trust-DdjLR61k.mjs → project-zero-trust-D1ICiwN_.mjs} +5 -5
- package/dist/{protocol-BPZaNqBo.d.mts → protocol-4H7V_3Os.d.mts} +1 -1
- package/dist/{protocol-CfaUwNs8.mjs → protocol-RNP0u7UY.mjs} +9 -3
- package/dist/{provision-BfaLiWbj.mjs → provision-DDh7ITVS.mjs} +118 -865
- package/dist/{requests-DFAqyYy8.mjs → requests-3CL3BuZh.mjs} +4 -4
- package/dist/resolve-project-B9Hr0D3n.mjs +2 -0
- package/dist/resolve-project-C_Cu7E8a.mjs +48 -0
- package/dist/{rollback-BKYXBduI.mjs → rollback-Ce1d_0J9.mjs} +7 -17
- package/dist/{route-types-CbtsIeFn.mjs → route-types-IrBuwJ7u.mjs} +35 -70
- package/dist/routing-assets-VkrKIbxE.mjs +139 -0
- package/dist/{runner-9wjsSZx-.mjs → runner-B5huK2eC.mjs} +1 -1
- package/dist/{runner-DMBKSrRk.mjs → runner-DcVDrzuR.mjs} +7 -28
- package/dist/{runner-mysql-CEzKtmFb.mjs → runner-mysql-CCtyI0p6.mjs} +4 -3
- package/dist/runner-mysql-CaJq-hd6.mjs +2 -0
- package/dist/runner-pg-BJhFZZG4.mjs +2 -0
- package/dist/{runner-pg-DV8p_zjA.mjs → runner-pg-CPd-CB_F.mjs} +1 -1
- package/dist/runtime/ai.mjs +9 -22
- package/dist/runtime/better-auth-mysql.d.mts +2 -5
- package/dist/runtime/better-auth-mysql.mjs +6 -31
- package/dist/runtime/better-auth-pg.d.mts +2 -5
- package/dist/runtime/better-auth-pg.mjs +6 -32
- package/dist/runtime/better-auth.d.mts +2 -4
- package/dist/runtime/better-auth.mjs +9 -19
- package/dist/runtime/db.mjs +1 -1
- package/dist/runtime/durable.d.mts +16 -0
- package/dist/runtime/durable.mjs +26 -2
- package/dist/runtime/email/testing.d.mts +1 -1
- package/dist/runtime/email/testing.mjs +9 -23
- package/dist/runtime/email-protocol.d.mts +12 -0
- package/dist/runtime/email-protocol.mjs +2 -70
- package/dist/runtime/email.d.mts +1 -1
- package/dist/runtime/email.mjs +79 -221
- package/dist/runtime/env-public.d.mts +1 -1
- package/dist/runtime/env-public.mjs +12 -38
- package/dist/runtime/env.d.mts +1 -12
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/handler.mjs +1 -1
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/kv.mjs +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +1 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/live.mjs +1 -1
- package/dist/runtime/migration-handler-mysql.d.mts +2 -2
- package/dist/runtime/migration-handler-mysql.mjs +3 -2
- package/dist/runtime/migration-handler-pg.d.mts +2 -2
- package/dist/runtime/migration-handler-pg.mjs +1 -1
- package/dist/runtime/migration-handler.d.mts +2 -2
- package/dist/runtime/migration-handler.mjs +2 -470
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/remote/binding-handler.mjs +62 -62
- package/dist/runtime/remote/index.mjs +16 -77
- package/dist/runtime/routing.d.mts +1 -4
- package/dist/runtime/routing.mjs +82 -218
- package/dist/runtime/sandbox-container.d.mts +2 -2
- package/dist/runtime/sandbox-container.mjs +2 -2
- package/dist/runtime/sandbox.d.mts +2 -2
- package/dist/runtime/sandbox.mjs +13 -6
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -3
- package/dist/runtime/ws-server.mjs +6 -28
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/{sandbox-container-Bo0eiFKz.d.mts → sandbox-container-ChQRum-j.d.mts} +3 -1
- package/dist/{sandbox-container-C6ItmVuN.mjs → sandbox-container-DBKIqDEK.mjs} +12 -1
- package/dist/{sandbox-C5LFoJMf.d.mts → sandbox-q3waMc2T.d.mts} +1 -1
- package/dist/{scan-C3uDzz6J.mjs → scan-C0BMdmEd.mjs} +84 -7
- package/dist/{secret-BAt2KMmO.mjs → secret-B5J8bBsI.mjs} +62 -80
- package/dist/{serialize-BPvnNQuA.mjs → serialize-BtQyaYoC.mjs} +10 -4
- package/dist/{skills-BgVMvQdy.mjs → skills-BJsan98C.mjs} +2 -2
- package/dist/{subcommand-prompt-BSlnD1fI.mjs → subcommand-prompt-gQ-NDA-u.mjs} +38 -43
- package/dist/sveltekit.mjs +1 -1
- package/dist/validate-C9xtFOYR.mjs +2 -0
- package/dist/{validate-C9qJArv7.mjs → validate-CheZGRE7.mjs} +4 -8
- package/dist/version-metadata-DIrqEHQo.mjs +73 -0
- package/dist/{wrangler-D9KTuqnv.mjs → wrangler-BYs07Rxy.mjs} +119 -378
- package/dist/{ws-CChrrAU-.d.mts → ws-aKVYB-fA.d.mts} +1 -1
- package/dist/yarn-pnp-DLbEFMT0.mjs +92 -0
- package/docs/guide/auth.md +2 -0
- package/docs/guide/database/postgresql.md +2 -0
- package/docs/guide/database.md +2 -0
- package/docs/guide/deployment.md +2 -2
- package/docs/guide/durable-state.md +24 -0
- package/docs/guide/platform/administration/access.md +5 -1
- package/docs/guide/platform/administration/connected-apps.md +55 -0
- package/docs/guide/platform/installation/credentials.md +3 -1
- package/docs/guide/platform/installation/first-deployment.md +1 -1
- package/docs/guide/project-collaboration.md +1 -1
- package/docs/guide/quickstart.md +2 -0
- package/docs/guide/sandboxes.md +2 -0
- package/docs/reference/api/deploy.md +23 -0
- package/docs/reference/api/pages.md +2 -0
- package/docs/reference/api.md +2 -1
- package/docs/reference/cli/auth.md +1 -1
- package/docs/reference/cli/database.md +9 -3
- package/docs/reference/cli/deploy.md +1 -1
- package/docs/reference/cli/platform-installation.md +1 -1
- package/docs/reference/cli/setup.md +2 -0
- package/package.json +14 -17
- package/skills/void/SKILL.md +4 -2
- package/dist/auth-BgX2qYSY.mjs +0 -2
- package/dist/cf-build-output-H9a97vME.mjs +0 -2
- package/dist/client-By4JjMw_.mjs +0 -2
- package/dist/collect-DLyFDiKW.mjs +0 -2
- package/dist/config-5r-YpMC-.mjs +0 -2
- package/dist/config-B_ggY-IO.mjs +0 -89
- package/dist/config-BtSFvXZx.mjs +0 -2
- package/dist/config-write-AHGesphx.mjs +0 -61
- package/dist/deploy-BsEvnlJl.mjs +0 -10455
- package/dist/deploy-C1d-YTfp.mjs +0 -2
- package/dist/dev-inbox-CK-UuPob.mjs +0 -297
- package/dist/discover-EDUf6JJw.mjs +0 -2
- package/dist/dist-_UUlL6bg.mjs +0 -2
- package/dist/env-validation-Dxdx_5wo.mjs +0 -951
- package/dist/gen-dA9hW7AV.mjs +0 -2
- package/dist/head-client-DzmJGN4C.mjs +0 -90
- package/dist/help-DzKUrQvk.mjs +0 -2
- package/dist/login-Dc-wuTDq.mjs +0 -2
- package/dist/migrate-BHp07yJE.mjs +0 -2
- package/dist/operator-cmd-Cwn50lOV.mjs +0 -2
- package/dist/pages/head-client.d.mts +0 -13
- package/dist/pages/head-client.mjs +0 -2
- package/dist/platform-args-DYgITk0D.mjs +0 -2
- package/dist/prepare-DRUV-g3X.mjs +0 -2
- package/dist/project-BiaPQ7ur.mjs +0 -2
- package/dist/provision-Wu9ZBk9L.mjs +0 -2
- package/dist/resolve-project-BIeYs9Cw.mjs +0 -2
- package/dist/resolve-project-CP8rZs_p.mjs +0 -28
- package/dist/runner-mysql-CkFqZ6CE.mjs +0 -2
- package/dist/runner-pg-BGYRFdRp.mjs +0 -2
- package/dist/runtime/env-helpers.d.mts +0 -2
- package/dist/runtime/env-helpers.mjs +0 -2
- package/dist/validate-BJr9LfXy.mjs +0 -2
- package/dist/yarn-pnp-CUX_iTPA.mjs +0 -188
package/dist/runtime/email.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as
|
|
3
|
-
import { a as
|
|
4
|
-
import {
|
|
1
|
+
import { n as bytesToBase64 } from "../base64-DVrOndmI.mjs";
|
|
2
|
+
import { a as newId, n as MimeError, o as normalizeEmail, r as buildMime } from "../mime-srOklVVv.mjs";
|
|
3
|
+
import { a as DEV_INBOX_ENV_VAR, b as serializeCapturedMessage, c as DEV_INBOX_TOKEN_ENV_VAR, d as captureMessage, h as hasActiveSink, i as DEV_INBOX_CAPTURE_URL, p as dispatchToSinks } from "../dev-inbox-Rd6j_8vM.mjs";
|
|
4
|
+
import { o as withTimeout, r as readBoundedJson } from "../email-protocol-D9nTvhCp.mjs";
|
|
5
|
+
import { a as createMessageProxy, c as isForwardableEmailMessage, d as readProjectSlug, f as replyEmail, i as bytesToReadableStream, l as parseEmail, o as defineEmail, p as tryGetRawRuntimeEnv, r as ParseEmailError, s as enactEmailActions, u as readEnvString } from "../inbound-DmkTQeWp.mjs";
|
|
5
6
|
import { isRecord } from "@void/deploy-core";
|
|
6
7
|
//#region src/runtime/email.ts
|
|
7
|
-
const VALID_SLUG = /^[a-z0-9](?:[a-z0-9-]{0,54}[a-z0-9])?$/;
|
|
8
8
|
function makeError(code, message, cause) {
|
|
9
9
|
return cause === void 0 ? {
|
|
10
10
|
code,
|
|
@@ -15,26 +15,6 @@ function makeError(code, message, cause) {
|
|
|
15
15
|
cause
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
function tryGetRawRuntimeEnv() {
|
|
19
|
-
try {
|
|
20
|
-
return getRawRuntimeEnv();
|
|
21
|
-
} catch {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function readProjectSlug() {
|
|
26
|
-
const raw = tryGetRawRuntimeEnv()?.__VOID_PROJECT_SLUG;
|
|
27
|
-
if (typeof raw !== "string" || raw.length === 0) return;
|
|
28
|
-
return VALID_SLUG.test(raw) ? raw : void 0;
|
|
29
|
-
}
|
|
30
|
-
function readEmailDomain() {
|
|
31
|
-
const raw = tryGetRawRuntimeEnv()?.__VOID_EMAIL_DOMAIN;
|
|
32
|
-
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
33
|
-
}
|
|
34
|
-
function readEmailFrom() {
|
|
35
|
-
const raw = tryGetRawRuntimeEnv()?.__VOID_EMAIL_FROM;
|
|
36
|
-
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
37
|
-
}
|
|
38
18
|
const SEND_EMAIL_BINDING_NAME = "SEND_EMAIL";
|
|
39
19
|
const EMAIL_PROVIDER_DEADLINE_MS = 3e4;
|
|
40
20
|
const PLATFORM_SEND_DEADLINE_MS = 6e4;
|
|
@@ -44,40 +24,16 @@ var EmailBindingTimeoutError = class extends Error {
|
|
|
44
24
|
this.name = "EmailBindingTimeoutError";
|
|
45
25
|
}
|
|
46
26
|
};
|
|
47
|
-
function createBindingSendDeadline() {
|
|
48
|
-
const deadline = Date.now() + PLATFORM_SEND_DEADLINE_MS;
|
|
49
|
-
return {
|
|
50
|
-
expired: () => Date.now() >= deadline,
|
|
51
|
-
async run(submit) {
|
|
52
|
-
const remaining = Math.min(EMAIL_PROVIDER_DEADLINE_MS, deadline - Date.now());
|
|
53
|
-
if (remaining <= 0) throw new EmailBindingTimeoutError();
|
|
54
|
-
const work = submit();
|
|
55
|
-
let timer;
|
|
56
|
-
try {
|
|
57
|
-
return await Promise.race([work, new Promise((_, reject) => {
|
|
58
|
-
timer = setTimeout(() => reject(new EmailBindingTimeoutError()), remaining);
|
|
59
|
-
})]);
|
|
60
|
-
} finally {
|
|
61
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
27
|
function resolveSendEmailBinding(env) {
|
|
67
28
|
const binding = env?.[SEND_EMAIL_BINDING_NAME];
|
|
68
29
|
if (typeof binding !== "object" || binding === null) return;
|
|
69
30
|
return typeof binding.send === "function" ? binding : void 0;
|
|
70
31
|
}
|
|
71
32
|
/**
|
|
72
|
-
* Map
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* throws message-only errors, so the destination-verification phrasing the
|
|
77
|
-
* platform proxy already keys on is kept as a fallback. Anything else is
|
|
78
|
-
* `OUTCOME_UNKNOWN` with the original error as `cause`: once `send()` has
|
|
79
|
-
* started, an undocumented rejection does not prove the provider declined
|
|
80
|
-
* the message before accepting it.
|
|
33
|
+
* Map a `send_email` binding error to a framework code: Email Service `E_*`
|
|
34
|
+
* codes, then the older Email Routing message. Anything else is
|
|
35
|
+
* `OUTCOME_UNKNOWN`: once `send()` started, a rejection does not prove the
|
|
36
|
+
* provider declined the message.
|
|
81
37
|
*/
|
|
82
38
|
function classifyBindingError(e) {
|
|
83
39
|
const message = e instanceof Error ? e.message : String(e);
|
|
@@ -93,11 +49,9 @@ function classifyBindingError(e) {
|
|
|
93
49
|
}
|
|
94
50
|
const UNVERIFIED_DESTINATION_RE = /^[^\n]{0,200}destination address[^\n]{0,200}not (?:yet )?verified/i;
|
|
95
51
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* outcome in either mode. The stream is rebuilt per send because a
|
|
100
|
-
* `ReadableStream` is one-shot.
|
|
52
|
+
* Send one `EmailMessage` per recipient through the worker's own binding,
|
|
53
|
+
* within one bounded batch, reporting `deliveries` as the proxy does. The
|
|
54
|
+
* stream is rebuilt per send: a `ReadableStream` is one-shot.
|
|
101
55
|
*/
|
|
102
56
|
async function sendViaBinding(binding, from, recipients, raw, fallbackId) {
|
|
103
57
|
let EmailMessage;
|
|
@@ -107,10 +61,11 @@ async function sendViaBinding(binding, from, recipients, raw, fallbackId) {
|
|
|
107
61
|
return err("UPSTREAM_ERROR", `email: SEND_EMAIL is bound but cloudflare:email could not be loaded: ${e instanceof Error ? e.message : String(e)}`, e);
|
|
108
62
|
}
|
|
109
63
|
const deliveries = [];
|
|
110
|
-
const deadline =
|
|
64
|
+
const deadline = Date.now() + PLATFORM_SEND_DEADLINE_MS;
|
|
65
|
+
const remaining = () => Math.min(EMAIL_PROVIDER_DEADLINE_MS, deadline - Date.now());
|
|
111
66
|
for (let index = 0; index < recipients.length; index++) {
|
|
112
67
|
const recipient = recipients[index];
|
|
113
|
-
if (
|
|
68
|
+
if (remaining() <= 0) {
|
|
114
69
|
for (const unstarted of recipients.slice(index)) deliveries.push({
|
|
115
70
|
recipient: unstarted,
|
|
116
71
|
ok: false,
|
|
@@ -120,7 +75,7 @@ async function sendViaBinding(binding, from, recipients, raw, fallbackId) {
|
|
|
120
75
|
break;
|
|
121
76
|
}
|
|
122
77
|
try {
|
|
123
|
-
const result = await
|
|
78
|
+
const result = await withTimeout(remaining(), () => binding.send(new EmailMessage(from, recipient, bytesToReadableStream(raw))), () => new EmailBindingTimeoutError());
|
|
124
79
|
const mid = typeof result?.messageId === "string" ? result.messageId : "";
|
|
125
80
|
deliveries.push({
|
|
126
81
|
recipient,
|
|
@@ -150,10 +105,8 @@ async function sendViaBinding(binding, from, recipients, raw, fallbackId) {
|
|
|
150
105
|
};
|
|
151
106
|
}
|
|
152
107
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* is worse than the rare case where a user actually wanted Cc + Bcc to
|
|
156
|
-
* the same address — which doesn't change delivery semantics anyway).
|
|
108
|
+
* Recipients deduplicated by lowercased address: Cloudflare does not
|
|
109
|
+
* collapse duplicate envelopes, and each one costs quota.
|
|
157
110
|
*/
|
|
158
111
|
function uniqueRecipients(normalized) {
|
|
159
112
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -170,23 +123,16 @@ function uniqueRecipients(normalized) {
|
|
|
170
123
|
}
|
|
171
124
|
return recipients;
|
|
172
125
|
}
|
|
173
|
-
function newRequestId() {
|
|
174
|
-
const bytes = /* @__PURE__ */ new Uint8Array(8);
|
|
175
|
-
crypto.getRandomValues(bytes);
|
|
176
|
-
let hex = "";
|
|
177
|
-
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
178
|
-
return `req_${Date.now().toString(36)}${hex}`;
|
|
179
|
-
}
|
|
180
126
|
function resolveDefaultFrom(opts) {
|
|
181
127
|
const supplied = opts.from;
|
|
182
128
|
if (!(supplied === void 0 || supplied === null || typeof supplied === "string" && supplied.trim() === "" || typeof supplied === "object" && supplied !== null && !("email" in supplied))) return opts;
|
|
183
|
-
const configured =
|
|
129
|
+
const configured = readEnvString("__VOID_EMAIL_FROM");
|
|
184
130
|
if (configured) return {
|
|
185
131
|
...opts,
|
|
186
132
|
from: configured
|
|
187
133
|
};
|
|
188
134
|
const slug = readProjectSlug();
|
|
189
|
-
const domain =
|
|
135
|
+
const domain = readEnvString("__VOID_EMAIL_DOMAIN");
|
|
190
136
|
if (!slug || !domain) {
|
|
191
137
|
if (supplied === null) {
|
|
192
138
|
const next = { ...opts };
|
|
@@ -220,11 +166,9 @@ function coerceErrorCode(code) {
|
|
|
220
166
|
].find((knownCode) => knownCode === code) ?? "UPSTREAM_ERROR";
|
|
221
167
|
}
|
|
222
168
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* does not enable email."); `error` is the short code every such refusal
|
|
227
|
-
* carries. `null` when the body is not that shape.
|
|
169
|
+
* Text of the `{ error, message? }` refusal the proxy's middleware sends
|
|
170
|
+
* ahead of the email handler, preferring the human `message`; `null` for any
|
|
171
|
+
* other shape.
|
|
228
172
|
*/
|
|
229
173
|
function readProxyRefusal(body) {
|
|
230
174
|
if (typeof body !== "object" || body === null || Array.isArray(body)) return null;
|
|
@@ -258,10 +202,9 @@ function readProxyResponse(value) {
|
|
|
258
202
|
return null;
|
|
259
203
|
}
|
|
260
204
|
/**
|
|
261
|
-
* Require exactly one valid outcome per requested recipient in
|
|
262
|
-
*
|
|
263
|
-
* trimming it could hide a submission.
|
|
264
|
-
* Diagnostics identify entries by index rather than echoing corrupt addresses.
|
|
205
|
+
* Require exactly one valid outcome per requested recipient, in any order. A
|
|
206
|
+
* missing, duplicate or foreign entry makes the whole result unknown, since
|
|
207
|
+
* trimming it could hide a submission. Diagnostics name entries by index.
|
|
265
208
|
*/
|
|
266
209
|
function readRecipientList(raw, recipients, shape, readEntry) {
|
|
267
210
|
if (raw.length !== recipients.length) return {
|
|
@@ -300,11 +243,8 @@ function readRecipientList(raw, recipients, shape, readEntry) {
|
|
|
300
243
|
};
|
|
301
244
|
}
|
|
302
245
|
/**
|
|
303
|
-
* The `ids`
|
|
304
|
-
*
|
|
305
|
-
* is `{ recipient, messageId }`; the framework's own Message-ID stands in for
|
|
306
|
-
* an empty provider reference. A missing delivery would leave no safe retry
|
|
307
|
-
* decision, so the whole response is rejected as malformed.
|
|
246
|
+
* The `ids` of an `ok: true` response, one accepted outcome per recipient.
|
|
247
|
+
* The framework's Message-ID stands in for an empty provider reference.
|
|
308
248
|
*/
|
|
309
249
|
function readDeliveryList(raw, recipients, fallbackId) {
|
|
310
250
|
return readRecipientList(raw, recipients, "{ recipient: string, messageId: string }", (entry, recipient) => typeof entry.messageId === "string" ? {
|
|
@@ -349,112 +289,47 @@ function readDeliveryState(value) {
|
|
|
349
289
|
].find((state) => state === value);
|
|
350
290
|
}
|
|
351
291
|
const MAX_PROXY_RESPONSE_BYTES = 65536;
|
|
352
|
-
function createPlatformSendDeadline() {
|
|
353
|
-
const controller = new AbortController();
|
|
354
|
-
const deadline = Date.now() + PLATFORM_SEND_DEADLINE_MS;
|
|
355
|
-
return {
|
|
356
|
-
signal: controller.signal,
|
|
357
|
-
async beforeDeadline(run) {
|
|
358
|
-
const remaining = deadline - Date.now();
|
|
359
|
-
if (remaining <= 0) {
|
|
360
|
-
controller.abort();
|
|
361
|
-
throw new Error("email platform send timed out");
|
|
362
|
-
}
|
|
363
|
-
const promise = run();
|
|
364
|
-
let timer;
|
|
365
|
-
try {
|
|
366
|
-
return await Promise.race([promise, new Promise((_, reject) => {
|
|
367
|
-
timer = setTimeout(() => {
|
|
368
|
-
controller.abort();
|
|
369
|
-
reject(/* @__PURE__ */ new Error("email platform send timed out"));
|
|
370
|
-
}, remaining);
|
|
371
|
-
})]);
|
|
372
|
-
} finally {
|
|
373
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
async function readBoundedProxyJson(response, beforeDeadline) {
|
|
379
|
-
const declared = response.headers.get("content-length");
|
|
380
|
-
if (declared !== null && (!/^\d+$/.test(declared) || Number(declared) > MAX_PROXY_RESPONSE_BYTES)) {
|
|
381
|
-
response.body?.cancel().catch(() => {});
|
|
382
|
-
throw new Error("email proxy response too large");
|
|
383
|
-
}
|
|
384
|
-
const reader = response.body?.getReader();
|
|
385
|
-
if (!reader) throw new Error("email proxy response is empty");
|
|
386
|
-
const bytes = new Uint8Array(MAX_PROXY_RESPONSE_BYTES);
|
|
387
|
-
let size = 0;
|
|
388
|
-
try {
|
|
389
|
-
for (;;) {
|
|
390
|
-
const chunk = await beforeDeadline(() => reader.read());
|
|
391
|
-
if (chunk.done) break;
|
|
392
|
-
if (size + chunk.value.byteLength > bytes.byteLength) throw new Error("email proxy response too large");
|
|
393
|
-
bytes.set(chunk.value, size);
|
|
394
|
-
size += chunk.value.byteLength;
|
|
395
|
-
}
|
|
396
|
-
if (declared !== null && size !== Number(declared)) throw new Error("email proxy response length mismatch");
|
|
397
|
-
return JSON.parse(new TextDecoder("utf-8", {
|
|
398
|
-
fatal: true,
|
|
399
|
-
ignoreBOM: false
|
|
400
|
-
}).decode(bytes.subarray(0, size)));
|
|
401
|
-
} finally {
|
|
402
|
-
reader.cancel().catch(() => {});
|
|
403
|
-
try {
|
|
404
|
-
reader.releaseLock();
|
|
405
|
-
} catch {}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
292
|
async function readResponseAsResult(res, recipients, fallbackId, beforeDeadline) {
|
|
293
|
+
let body;
|
|
409
294
|
try {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
ok: true,
|
|
428
|
-
ids: list.entries,
|
|
429
|
-
...operation
|
|
430
|
-
} : malformedList(list.reason);
|
|
431
|
-
}
|
|
432
|
-
if ("deliveries" in response) {
|
|
433
|
-
const list = readFailureDeliveries(response.deliveries, recipients, fallbackId);
|
|
434
|
-
return list.ok ? {
|
|
435
|
-
ok: false,
|
|
436
|
-
deliveries: list.entries,
|
|
437
|
-
...operation
|
|
438
|
-
} : malformedList(list.reason);
|
|
439
|
-
}
|
|
440
|
-
const e = response.error;
|
|
441
|
-
return {
|
|
442
|
-
...err(coerceErrorCode(e.code), typeof e.message === "string" ? e.message : "email: upstream send failed"),
|
|
295
|
+
body = await readBoundedJson(res, MAX_PROXY_RESPONSE_BYTES, beforeDeadline);
|
|
296
|
+
} catch {
|
|
297
|
+
return err("OUTCOME_UNKNOWN", `email: could not establish the send outcome (status ${res.status}); check email logs or repeat the same idempotency key`);
|
|
298
|
+
}
|
|
299
|
+
const response = readProxyResponse(body);
|
|
300
|
+
if (response === null) {
|
|
301
|
+
const refusal = readProxyRefusal(body);
|
|
302
|
+
if (!res.ok && refusal !== null) return err("UPSTREAM_ERROR", `email: proxy returned ${res.status}: ${refusal}`, body);
|
|
303
|
+
return err("OUTCOME_UNKNOWN", `email: proxy returned malformed response (status ${res.status})`, body);
|
|
304
|
+
}
|
|
305
|
+
const malformedList = (reason) => err("OUTCOME_UNKNOWN", `email: proxy returned a malformed delivery list (${reason}); do not retry with a new idempotency key`, body);
|
|
306
|
+
const operation = typeof response.operationId === "string" && response.operationId.length <= 128 ? { operationId: response.operationId } : {};
|
|
307
|
+
if (response.ok === true) {
|
|
308
|
+
const list = readDeliveryList(response.ids, recipients, fallbackId);
|
|
309
|
+
return list.ok ? {
|
|
310
|
+
ok: true,
|
|
311
|
+
ids: list.entries,
|
|
443
312
|
...operation
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
|
|
313
|
+
} : malformedList(list.reason);
|
|
314
|
+
}
|
|
315
|
+
if ("deliveries" in response) {
|
|
316
|
+
const list = readFailureDeliveries(response.deliveries, recipients, fallbackId);
|
|
317
|
+
return list.ok ? {
|
|
318
|
+
ok: false,
|
|
319
|
+
deliveries: list.entries,
|
|
320
|
+
...operation
|
|
321
|
+
} : malformedList(list.reason);
|
|
447
322
|
}
|
|
323
|
+
const e = response.error;
|
|
324
|
+
return {
|
|
325
|
+
...err(coerceErrorCode(e.code), typeof e.message === "string" ? e.message : "email: upstream send failed"),
|
|
326
|
+
...operation
|
|
327
|
+
};
|
|
448
328
|
}
|
|
449
329
|
/**
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
* names the worker's assets binding. In dev, `@cloudflare/vite-plugin` binds
|
|
454
|
-
* that name to a miniflare service whose implementation is the Vite dev
|
|
455
|
-
* server's Node middleware stack, so a fetch through it lands on the inbox
|
|
456
|
-
* middleware in the dev-server process — the only place the buffer exists.
|
|
457
|
-
* In a production build neither the var nor that wiring is present.
|
|
330
|
+
* The loopback into the `void dev` inbox: `DEV_INBOX_ENV_VAR` names the
|
|
331
|
+
* assets binding, which in dev reaches the Vite dev server. Undefined
|
|
332
|
+
* outside dev.
|
|
458
333
|
*/
|
|
459
334
|
function resolveDevInbox(env) {
|
|
460
335
|
const bindingName = env?.[DEV_INBOX_ENV_VAR];
|
|
@@ -473,10 +348,8 @@ const DEV_INBOX_TIMEOUT_MS = 5e3;
|
|
|
473
348
|
const DEV_INBOX_ERROR_EXCERPT_CHARS = 200;
|
|
474
349
|
const DEV_INBOX_ERROR_EXCERPT_TIMEOUT_MS = 1e3;
|
|
475
350
|
/**
|
|
476
|
-
* First line of a refusal, so a 401 names the header it wanted.
|
|
477
|
-
*
|
|
478
|
-
* time the status is known, and a body that never arrives must not turn a
|
|
479
|
-
* clean error into a hung `sendEmail`.
|
|
351
|
+
* First line of a refusal, so a 401 names the header it wanted. One chunk
|
|
352
|
+
* under its own deadline: a stalled body must not hang `sendEmail`.
|
|
480
353
|
*/
|
|
481
354
|
async function readErrorExcerpt(res) {
|
|
482
355
|
let timer;
|
|
@@ -548,22 +421,11 @@ async function postToDevInbox(inbox, captured) {
|
|
|
548
421
|
if (timer !== void 0) clearTimeout(timer);
|
|
549
422
|
}
|
|
550
423
|
}
|
|
551
|
-
/**
|
|
552
|
-
* Shared result shape for both capture paths (in-process sink and dev inbox).
|
|
553
|
-
*
|
|
554
|
-
* `ids` is built from the same deduplicated, lowercased list the two
|
|
555
|
-
* production transports send to, so code written against a captured result
|
|
556
|
-
* sees exactly what a deploy returns: one entry per unique address, keyed the
|
|
557
|
-
* way `sendViaBinding` and the proxy report it. The captured message itself
|
|
558
|
-
* keeps the original fields; the inbox displays what was asked for, the
|
|
559
|
-
* result reports what would be sent.
|
|
560
|
-
*/
|
|
424
|
+
/** A captured send's result: one id per unique recipient, as a deployed send reports. */
|
|
561
425
|
function capturedResult(normalized, captureId) {
|
|
562
|
-
const recipients = uniqueRecipients(normalized);
|
|
563
|
-
if (recipients.length === 0) return err("INVALID_TO", "email: 'to' must include at least one recipient.");
|
|
564
426
|
return {
|
|
565
427
|
ok: true,
|
|
566
|
-
ids:
|
|
428
|
+
ids: uniqueRecipients(normalized).map((recipient) => ({
|
|
567
429
|
recipient,
|
|
568
430
|
messageId: captureId
|
|
569
431
|
}))
|
|
@@ -584,18 +446,11 @@ async function sendEmail(opts) {
|
|
|
584
446
|
if (resolvedOpts.from === void 0) return err("INVALID_FROM", "email: 'from' is required. Set it explicitly or deploy via Void so the platform-injected __VOID_PROJECT_SLUG and __VOID_EMAIL_DOMAIN can default it to <slug>+noreply@<domain>.");
|
|
585
447
|
const optsWithFrom = resolvedOpts;
|
|
586
448
|
let normalized;
|
|
587
|
-
try {
|
|
588
|
-
normalized = await normalizeEmail(optsWithFrom);
|
|
589
|
-
} catch (e) {
|
|
590
|
-
if (e instanceof MimeError) return err(e.code, e.message, e);
|
|
591
|
-
return err("MIME_ERROR", e instanceof Error ? e.message : String(e), e);
|
|
592
|
-
}
|
|
593
449
|
let raw;
|
|
594
450
|
let messageId;
|
|
595
451
|
try {
|
|
596
|
-
|
|
597
|
-
raw =
|
|
598
|
-
messageId = built.messageId;
|
|
452
|
+
normalized = await normalizeEmail(optsWithFrom);
|
|
453
|
+
({raw, messageId} = buildMime(normalized));
|
|
599
454
|
} catch (e) {
|
|
600
455
|
if (e instanceof MimeError) return err(e.code, e.message, e);
|
|
601
456
|
return err("MIME_ERROR", e instanceof Error ? e.message : String(e), e);
|
|
@@ -616,7 +471,6 @@ async function sendEmail(opts) {
|
|
|
616
471
|
return err("UPSTREAM_ERROR", message);
|
|
617
472
|
}
|
|
618
473
|
const recipients = uniqueRecipients(normalized);
|
|
619
|
-
if (recipients.length === 0) return err("INVALID_TO", "email: 'to' must include at least one recipient.");
|
|
620
474
|
const sendBinding = resolveSendEmailBinding(rawEnv);
|
|
621
475
|
if (sendBinding) {
|
|
622
476
|
if (opts.idempotencyKey !== void 0) return err("MIME_ERROR", "email: idempotencyKey requires a Void platform; the native Cloudflare binding cannot deduplicate sends.");
|
|
@@ -627,30 +481,34 @@ async function sendEmail(opts) {
|
|
|
627
481
|
const projectId = env?.__PROJECT_ID;
|
|
628
482
|
const proxyToken = env?.__VOID_PROXY_TOKEN;
|
|
629
483
|
if (!proxy || !projectId || !proxyToken) return err("BINDING_MISSING", "email: neither SEND_EMAIL nor __VOID_PROXY is available, so nothing was sent. Deploy via Void to bind the platform proxy, or set `email.from` in void.json so `void deploy --platform cloudflare` provisions the SEND_EMAIL binding. Under `void dev` messages are captured by the local inbox at /__void/inbox instead — reaching this error there means that path was bypassed (`sendInDev: true`, which does not deliver: `void dev` binds no send transport at all, so there is nothing to fall through to) or unavailable (the worker has no assets binding to reach the dev server through).");
|
|
630
|
-
const requestId = newRequestId();
|
|
631
484
|
const body = {
|
|
632
485
|
projectId,
|
|
633
486
|
aiToken: proxyToken,
|
|
634
487
|
from: normalized.from.email,
|
|
635
488
|
recipients,
|
|
636
489
|
mimeBase64: bytesToBase64(raw),
|
|
637
|
-
requestId,
|
|
490
|
+
requestId: newId("req"),
|
|
638
491
|
...opts.idempotencyKey === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
|
|
639
492
|
};
|
|
640
493
|
const requestBody = JSON.stringify(body);
|
|
641
|
-
const
|
|
494
|
+
const controller = new AbortController();
|
|
495
|
+
const deadline = Date.now() + PLATFORM_SEND_DEADLINE_MS;
|
|
496
|
+
const beforeDeadline = (run) => withTimeout(deadline - Date.now(), run, () => {
|
|
497
|
+
controller.abort();
|
|
498
|
+
return /* @__PURE__ */ new Error("email platform send timed out");
|
|
499
|
+
});
|
|
642
500
|
let res;
|
|
643
501
|
try {
|
|
644
|
-
res = await
|
|
502
|
+
res = await beforeDeadline(() => proxy.fetch("https://email-proxy/email/send", {
|
|
645
503
|
method: "POST",
|
|
646
504
|
headers: { "content-type": "application/json" },
|
|
647
505
|
body: requestBody,
|
|
648
|
-
signal:
|
|
506
|
+
signal: controller.signal
|
|
649
507
|
}));
|
|
650
508
|
} catch (e) {
|
|
651
509
|
return err("OUTCOME_UNKNOWN", `email: send outcome is unknown: ${e instanceof Error ? e.message : String(e)}. Check email logs or repeat the same idempotency key; do not create a new send.`, e);
|
|
652
510
|
}
|
|
653
|
-
return readResponseAsResult(res, recipients, messageId,
|
|
511
|
+
return readResponseAsResult(res, recipients, messageId, beforeDeadline);
|
|
654
512
|
}
|
|
655
513
|
/**
|
|
656
514
|
* Build a normalized email + raw MIME for advanced callers who want to feed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
2
|
import { a as number, c as url, i as json, n as boolean, o as oneOf, r as email, s as string, t as EnvSchema } from "../env-helpers-CyKtOBpj.mjs";
|
|
3
|
-
import { a as _getSchemaDefaults, c as defineEnv, i as _getRegisteredSchema, l as env, n as EnvValidationReport, o as _hasRegisteredSchema, r as ValidatedEnv, s as _validateEnvOnce, t as EnvValidationError, u as validateAllEnv } from "../env-public-
|
|
3
|
+
import { a as _getSchemaDefaults, c as defineEnv, i as _getRegisteredSchema, l as env, n as EnvValidationReport, o as _hasRegisteredSchema, r as ValidatedEnv, s as _validateEnvOnce, t as EnvValidationError, u as validateAllEnv } from "../env-public-CCdykygU.mjs";
|
|
4
4
|
export { type EnvSchema, EnvValidationError, EnvValidationReport, ValidatedEnv, _getRegisteredSchema, _getSchemaDefaults, _hasRegisteredSchema, _validateEnvOnce, boolean, defineEnv, email, env, json, number, oneOf, string, url, validateAllEnv };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as getRawRuntimeEnv } from "../env-raw-
|
|
2
|
-
import { i as isInternalBinding, n as getRuntimeEnv } from "../env-
|
|
1
|
+
import { a as getRawRuntimeEnv } from "../env-raw-Cklzcde3.mjs";
|
|
2
|
+
import { i as isInternalBinding, n as getRuntimeEnv } from "../env-BhdWMrNy.mjs";
|
|
3
3
|
import { a as oneOf, i as number, n as email, o as string, r as json, s as url, t as boolean } from "../env-helpers--wFmQ_5Q.mjs";
|
|
4
4
|
//#region src/shared/env-mask.ts
|
|
5
5
|
/**
|
|
@@ -11,8 +11,7 @@ import { a as oneOf, i as number, n as email, o as string, r as json, s as url,
|
|
|
11
11
|
* it to locate the offending entry).
|
|
12
12
|
*
|
|
13
13
|
* Server env values are production secrets by definition, so validator
|
|
14
|
-
* messages redact the raw input unconditionally.
|
|
15
|
-
* `.public()` masking axis was removed because it did not control storage.
|
|
14
|
+
* messages redact the raw input unconditionally.
|
|
16
15
|
*
|
|
17
16
|
* Users can opt out of the guard for local debugging via
|
|
18
17
|
* `VOID_ENV_UNMASK=1` in the environment; that path prints a one-shot
|
|
@@ -32,7 +31,6 @@ function redactMessage(rawValue, message, options = {}) {
|
|
|
32
31
|
return message.split(rawValue).join(REDACTED);
|
|
33
32
|
}
|
|
34
33
|
let unmaskResolved = null;
|
|
35
|
-
let unmaskNoticeShown = false;
|
|
36
34
|
/**
|
|
37
35
|
* Resolve the effective unmask flag, consulting `process.env` exactly once
|
|
38
36
|
* per process. On the first affirmative read, we print a one-shot notice to
|
|
@@ -40,20 +38,13 @@ let unmaskNoticeShown = false;
|
|
|
40
38
|
*/
|
|
41
39
|
function isUnmaskActive() {
|
|
42
40
|
if (unmaskResolved !== null) return unmaskResolved;
|
|
43
|
-
let active = false;
|
|
44
41
|
try {
|
|
45
|
-
|
|
42
|
+
unmaskResolved = globalThis.process?.env?.[UNMASK_ENV_VAR] === "1";
|
|
46
43
|
} catch {
|
|
47
|
-
|
|
44
|
+
unmaskResolved = false;
|
|
48
45
|
}
|
|
49
|
-
unmaskResolved =
|
|
50
|
-
|
|
51
|
-
unmaskNoticeShown = true;
|
|
52
|
-
try {
|
|
53
|
-
console.error(`[void/env] ${UNMASK_ENV_VAR}=1 is set — env validation errors will include raw values. Unset it before sharing logs.`);
|
|
54
|
-
} catch {}
|
|
55
|
-
}
|
|
56
|
-
return active;
|
|
46
|
+
if (unmaskResolved) console.error(`[void/env] ${UNMASK_ENV_VAR}=1 is set — env validation errors will include raw values. Unset it before sharing logs.`);
|
|
47
|
+
return unmaskResolved;
|
|
57
48
|
}
|
|
58
49
|
//#endregion
|
|
59
50
|
//#region src/runtime/env-public.ts
|
|
@@ -127,21 +118,10 @@ function defineEnv(schema) {
|
|
|
127
118
|
return env;
|
|
128
119
|
}
|
|
129
120
|
/**
|
|
130
|
-
* Internal: validate the
|
|
131
|
-
* the
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* Spliced into the generated worker entry by `compileWorkerEntry`. Cached
|
|
136
|
-
* after the first call so subsequent requests pay no cost.
|
|
137
|
-
*
|
|
138
|
-
* Async lifecycle: this function awaits any async Standard Schema
|
|
139
|
-
* validators (zod `refine`, arktype async narrows, etc.) and seeds the
|
|
140
|
-
* per-key cache with the resolved values. Subsequent reads via `env.X`
|
|
141
|
-
* hit the sync cache — async work only happens here, at boot. If a user
|
|
142
|
-
* accesses `env.X` for a key with an async validator *before* this
|
|
143
|
-
* function has run (e.g. during module-top-level code), the proxy will
|
|
144
|
-
* throw with guidance pointing back to this boot-time pre-validation.
|
|
121
|
+
* Internal: validate the whole schema against the worker env once per isolate,
|
|
122
|
+
* from the generated worker entry. Catches remote-secret values the deploy CLI
|
|
123
|
+
* cannot see. Async validators are awaited here and their values cached, so
|
|
124
|
+
* later synchronous `env.X` reads can serve them.
|
|
145
125
|
*/
|
|
146
126
|
async function _validateEnvOnce(envValues) {
|
|
147
127
|
if (registry.bootValidation) {
|
|
@@ -258,13 +238,7 @@ function readKey(key) {
|
|
|
258
238
|
/**
|
|
259
239
|
* Typed env proxy. Reads from the runtime env, validating declared keys
|
|
260
240
|
* on first access and passing through bindings / unknown keys unchanged.
|
|
261
|
-
*
|
|
262
|
-
* Sync-only: the `get` trap must be synchronous, so validators that return
|
|
263
|
-
* a `Promise` cannot be awaited here. For async Standard Schema validators,
|
|
264
|
-
* `_validateEnvOnce()` pre-resolves them at worker boot and seeds the
|
|
265
|
-
* per-env cache; property reads then serve the cached value synchronously.
|
|
266
|
-
* If an async validator is encountered here without a prior pre-validation,
|
|
267
|
-
* the trap throws with guidance on how to resolve it.
|
|
241
|
+
* Async validators must be resolved first by `_validateEnvOnce()`.
|
|
268
242
|
*/
|
|
269
243
|
const env = new Proxy({}, {
|
|
270
244
|
get(_target, key) {
|
package/dist/runtime/env.d.mts
CHANGED
|
@@ -6,18 +6,7 @@ type RuntimeEnv = Record<string, unknown>;
|
|
|
6
6
|
/** @internal Reuse a resource only within the current runtime request. */
|
|
7
7
|
export declare function getRuntimeRequestResource<T>(key: object, initialize: () => T, outsideScope?: () => T): T;
|
|
8
8
|
export declare function withRuntimeEnv<T>(env: unknown, fn: () => T): T;
|
|
9
|
-
/**
|
|
10
|
-
* Shared internal-binding predicate. A binding is framework-internal — and must
|
|
11
|
-
* never be exposed to user code — when it carries an internal prefix
|
|
12
|
-
* (`__VOID_`, `__PROJECT_`; always hidden) or is an exact-name internal (e.g.
|
|
13
|
-
* `ISR_CACHE`; hidden ONLY while ISR is active for the isolate). `rawEnv` is the
|
|
14
|
-
* unfiltered runtime env, consulted via {@link isIsrActive} to gate the
|
|
15
|
-
* exact-name check so a non-ISR app's own `ISR_CACHE` binding stays visible —
|
|
16
|
-
* matching the build-time `isr` gate on the generated `c.env` filter.
|
|
17
|
-
*
|
|
18
|
-
* Single source of truth for the runtime `env` filter here and the public
|
|
19
|
-
* `void/env` proxy (`env-public.ts`).
|
|
20
|
-
*/
|
|
9
|
+
/** Whether `name` is a framework binding hidden from user code; `rawEnv` is the unfiltered env. */
|
|
21
10
|
export declare function isInternalBinding(name: string, rawEnv: RuntimeEnv): boolean;
|
|
22
11
|
/** Returns the runtime env with internal platform bindings hidden. */
|
|
23
12
|
export declare function getRuntimeEnv(): RuntimeEnv;
|
package/dist/runtime/env.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as requireRuntimeBinding, i as isInternalBinding, n as getRuntimeEnv, o as withRuntimeEnv, r as getRuntimeRequestResource, t as getRuntimeBinding } from "../env-
|
|
1
|
+
import { a as requireRuntimeBinding, i as isInternalBinding, n as getRuntimeEnv, o as withRuntimeEnv, r as getRuntimeRequestResource, t as getRuntimeBinding } from "../env-BhdWMrNy.mjs";
|
|
2
2
|
export { getRuntimeBinding, getRuntimeEnv, getRuntimeRequestResource, isInternalBinding, requireRuntimeBinding, withRuntimeEnv };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, n as CloudBindings, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, w as ValidationError, y as defineScheduled } from "../handler-
|
|
2
|
+
import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, n as CloudBindings, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, w as ValidationError, y as defineScheduled } from "../handler-_PqY82xe.mjs";
|
|
3
3
|
export { BasicAuthOptions, CloudBindings, CloudContext, CloudContextVariables, CloudEnv, type Deferred, type HandlerInput, type InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, type ValidatorSlots, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
package/dist/runtime/handler.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { r as defer, t as ValidationError } from "../validation-error-Dg9Recn1.mjs";
|
|
2
|
-
import { a as defineMiddleware, c as defineScheduled, i as defineHead, n as basicAuth, o as defineQueue, r as defineHandler, s as defineRender, t as VoidAssetRewriteError } from "../handler-
|
|
2
|
+
import { a as defineMiddleware, c as defineScheduled, i as defineHead, n as basicAuth, o as defineQueue, r as defineHandler, s as defineRender, t as VoidAssetRewriteError } from "../handler-BZ1t7-Rv.mjs";
|
|
3
3
|
export { ValidationError, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
package/dist/runtime/isr.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as getRawRuntimeEnv } from "../env-raw-
|
|
1
|
+
import { a as getRawRuntimeEnv } from "../env-raw-Cklzcde3.mjs";
|
|
2
2
|
import { isrEdgeCacheUrlForToken, splitIsrCacheKey } from "@void/isr";
|
|
3
3
|
import { denormalizeIsrPath, isrKey, isrPrefix, isrVariantPrefix, listIsrHosts } from "@void/isr/runtime";
|
|
4
4
|
//#region src/runtime/isr.ts
|
package/dist/runtime/kv.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as eventStream } from "../sse-CMvCgjNk.mjs";
|
|
2
|
-
import { t as __getLiveBindingName } from "../live-
|
|
2
|
+
import { a as connectionInstanceName, c as topicInstanceName, o as internalUrl, s as topicDigest, t as __getLiveBindingName } from "../live-BxLX-JqJ.mjs";
|
|
3
3
|
//#region src/runtime/live-server.ts
|
|
4
4
|
const GENERATION_KEY = "connection:generation";
|
|
5
5
|
const TOPIC_PRUNE_ALARM_DELAY_MS = 6e4;
|
|
@@ -416,20 +416,5 @@ function subscriberPrefix(streamId, topicKey) {
|
|
|
416
416
|
function subscriberKey(row) {
|
|
417
417
|
return `${subscriberPrefix(row.streamId, row.topicKey)}${row.connectionId}:${row.subscriptionId}:${row.generation}:${row.revision}`;
|
|
418
418
|
}
|
|
419
|
-
async function topicDigest(streamId, topic) {
|
|
420
|
-
const bytes = new TextEncoder().encode(`${streamId}\u0000${topic}`);
|
|
421
|
-
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
422
|
-
const binary = String.fromCharCode(...new Uint8Array(digest));
|
|
423
|
-
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
424
|
-
}
|
|
425
|
-
function connectionInstanceName(streamId, connectionId) {
|
|
426
|
-
return `live:${streamId}:connection:${connectionId}`;
|
|
427
|
-
}
|
|
428
|
-
function topicInstanceName(streamId, topicKey) {
|
|
429
|
-
return `live:${streamId}:topic:${topicKey}`;
|
|
430
|
-
}
|
|
431
|
-
function internalUrl(path) {
|
|
432
|
-
return `https://void.live${path}`;
|
|
433
|
-
}
|
|
434
419
|
//#endregion
|
|
435
420
|
export { createLiveDurableObject };
|