void 0.27.0 → 1.0.3
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-l-FM7Ioq.mjs → account-cmd-BTcUzv9L.mjs} +6 -6
- package/dist/{agents-B_pX_HmQ.mjs → agents-CuNtT0D_.mjs} +5 -2
- package/dist/{application-analysis-DKy02UY0.mjs → application-analysis-AB_YYWgH.mjs} +118 -135
- package/dist/{application-routing-DQyUh_5S.mjs → application-routing-L7V-TFhZ.mjs} +1 -2
- package/dist/atomic-write-Dq6R0BPN.mjs +18 -0
- package/dist/{auth-Dn2vw-SG.mjs → auth-B6iOCjKI.mjs} +23 -56
- package/dist/auth-Cbqi1iVX.mjs +1 -0
- package/dist/{auth-link-vz9Z2kmG.mjs → auth-link-DUJuvRx5.mjs} +11 -11
- package/dist/{auth-migrations-BwHgeEsD.mjs → auth-migrations-Cgs0k6lS.mjs} +28 -5
- package/dist/{auth-router-DvsCUVw4.mjs → auth-router-CIxiMG7i.mjs} +5 -5
- 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-D6we0VjO.mjs → build-cmd-BkIv25PA.mjs} +6 -6
- package/dist/{cache-CZRdzKx1.mjs → cache-Ctzfig-W.mjs} +6 -6
- package/dist/{cancel-deploy-CQ3NnMvf.mjs → cancel-deploy-CD9o-SsC.mjs} +5 -5
- package/dist/{cf-access-TWNzXltp.mjs → cf-access-BM9G0lhO.mjs} +4 -3
- package/dist/{cf-access-BcIBSKqG.mjs → cf-access-CWP4avfP.mjs} +3 -7
- package/dist/cf-build-output-BU3hqdHu.mjs +1 -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 +199 -312
- package/dist/cli/cloudflare-operation-process.mjs +41 -15
- package/dist/cli/env-schema-probe.d.mts +7 -44
- package/dist/cli/env-schema-probe.mjs +14 -80
- package/dist/client-B60PwCC4.mjs +1 -0
- package/dist/{client-DlDJuY0s.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-BIAF_BIY.mjs} +7 -6
- package/dist/{cloudflare-config-BmhBv3HV.mjs → cloudflare-config-DV60XFFK.mjs} +16 -28
- package/dist/{cloudflare-connect-2G3rL2rP.mjs → cloudflare-connect-WjwnVOJA.mjs} +4 -4
- package/dist/{cloudflare-operations-CwI1bChl.mjs → cloudflare-operations-B42EZeJy.mjs} +26 -34
- package/dist/cloudflare-operations-CrSUFRzJ.mjs +1 -0
- package/dist/{cloudflare-process-2-TfIEzB.mjs → cloudflare-process-CeDWJRhj.mjs} +12 -7
- package/dist/collect-Cae8A7Zr.mjs +1 -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-DPByhVck.mjs → config-D0GY5ItR.mjs} +1 -1
- package/dist/config-QrJWu0IX.mjs +1 -0
- package/dist/config-entry.d.mts +1 -1
- package/dist/{connect-BfPBHHm-.mjs → connect-CKtk-EZe.mjs} +9 -9
- package/dist/create-project-B-ewF_Af.mjs +1 -0
- package/dist/{create-project-BdXEFKal.mjs → create-project-yInGo72M.mjs} +8 -8
- package/dist/database-provider.mjs +1 -2
- package/dist/{db-Xs80hcaA.mjs → db-7I_gfdVq.mjs} +177 -268
- package/dist/db-types-Bb4WBWIs.mjs +49 -0
- package/dist/{delete-d2vuou3j.mjs → delete-Cy-M1u-r.mjs} +6 -6
- package/dist/deploy-9lgfhrXS.mjs +2 -0
- package/dist/deploy-BYYlnsiy.mjs +6164 -0
- package/dist/deploy-managed-static-Ca4TFdmx.mjs +1595 -0
- package/dist/deploy-transport-DWlWBe6M.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-ClzFSwns.mjs +1 -0
- package/dist/{discover-CkCYv9T_.mjs → discover-D2PGT63u.mjs} +2 -2
- package/dist/dispatch-DrTTk8Xg.mjs +431 -0
- package/dist/{dist-D3m88sjf.mjs → dist-BVdsO7Py.mjs} +5 -6
- package/dist/dist-CfgIkieS.mjs +1 -0
- package/dist/{dist-BVqXeR_h.mjs → dist-ipQi0Q8y.mjs} +2 -3
- package/dist/{domain-BsDUBAvt.mjs → domain-CZGxPv9u.mjs} +8 -23
- package/dist/{dotenv-BfU6eqFt.mjs → dotenv-CNazY3-w.mjs} +4 -16
- package/dist/edge.mjs +1 -2
- package/dist/{email-d_Aux1vM.mjs → email-BcjSyAL0.mjs} +4 -20
- package/dist/{email-_lGAHOhp.mjs → email-DzyNVuoU.mjs} +100 -192
- package/dist/email-cloudflare-DfG6UEMm.mjs +1096 -0
- package/dist/email-protocol-D9nTvhCp.mjs +82 -0
- package/dist/{entry-CMAkqBmU.mjs → entry-ehmBvs5w.mjs} +2 -2
- package/dist/{env-DMA3cXZt.mjs → env-0jrMQJI_.mjs} +6 -14
- package/dist/{env-BxocywBB.mjs → env-BJjULvL0.mjs} +2 -2
- package/dist/{env-C74QepDE.mjs → env-Nx3yf50r.mjs} +9 -9
- package/dist/{env-public-DR7ZM6d-.d.mts → env-public-CCdykygU.d.mts} +6 -23
- package/dist/{env-raw-jZpP5n47.mjs → env-raw-D74P4ebM.mjs} +15 -21
- package/dist/{env-types-CwXgeMgL.mjs → env-types-DS2_y4X8.mjs} +2 -2
- package/dist/env-validation-BT7z-qpQ.mjs +1 -0
- package/dist/env-validation-DYxjz_Wo.mjs +488 -0
- package/dist/{gen-DtkQhvQg.mjs → gen-CufHEf42.mjs} +132 -254
- package/dist/gen-sXyp5DFO.mjs +1 -0
- package/dist/generate-ClI89brV.mjs +1 -0
- package/dist/{generate-GDbL7sUr.mjs → generate-Dat0UTry.mjs} +38 -4
- package/dist/generated-wrangler-config-DeWj5F9Y.mjs +18 -0
- package/dist/{github-cmd-DaDdBbSS.mjs → github-cmd-FU8EjFyU.mjs} +28 -72
- 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-0bTe_lID.mjs → help-BT2hovNI.mjs} +26 -14
- package/dist/help-i2YGGnTH.mjs +1 -0
- package/dist/{inbound-PfQDLXc5.mjs → inbound-BuTfm11U.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 +714 -762
- package/dist/{info-PYWwkWyt.mjs → info-l249eUdH.mjs} +5 -5
- package/dist/{init-DaBGmaXC.mjs → init-D0A6M64Q.mjs} +229 -392
- package/dist/isr-config-fZaJJ8t7.mjs +165 -0
- package/dist/{link-C6fjafep.mjs → link-WMoJFf4i.mjs} +9 -9
- package/dist/{list-BTFBlqKl.mjs → list-CQ2EQEHL.mjs} +7 -18
- package/dist/{live-CgQuTpqD.mjs → live-BcHoTDFe.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-BxvQYEFi.mjs} +6 -6
- package/dist/{login-GKcNUmtI.mjs → login-C2T1oVG-.mjs} +12 -12
- package/dist/login-XD844Xs-.mjs +1 -0
- package/dist/{logs-BiMSULmc.mjs → logs-DnC1d7xB.mjs} +6 -6
- package/dist/{migrate-NLsjBbuM.mjs → migrate-BDIprOYd.mjs} +70 -22
- package/dist/migrate-BRwU-blY.mjs +1 -0
- 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/mysql-migration-sql-BIS5vbNk.mjs +241 -0
- package/dist/nitro.d.mts +30 -0
- package/dist/nitro.mjs +88 -0
- package/dist/{node-DJicPvPj.mjs → node-cPadMgUO.mjs} +9 -25
- package/dist/{operator-args-DOBhIaIg.mjs → operator-args-UnE8Y2eK.mjs} +27 -26
- package/dist/{operator-auth-BEZ_u0Cz.mjs → operator-auth-Cr2zCc-J.mjs} +2 -2
- package/dist/{operator-client-DbDv4vtE.mjs → operator-client-C-ROjk1I.mjs} +4 -4
- package/dist/operator-cmd-D6gnZsnK.mjs +1 -0
- package/dist/{operator-cmd-BT4hgavL.mjs → operator-cmd-DHieWtFp.mjs} +8 -8
- package/dist/{output-C50ag2r3.mjs → output-Ba6ZbrzY.mjs} +37 -6
- 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/head.mjs +1 -2
- 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/prefetch.mjs +1 -2
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +1 -1
- package/dist/pages/serialize.mjs +1 -2
- package/dist/plan-CKX_jWnD.mjs +1 -0
- package/dist/platform-args-B0HeTh0C.mjs +1 -0
- package/dist/{platform-args-DUeXY9Om.mjs → platform-args-CaCL_1Ch.mjs} +43 -60
- package/dist/{platform-auth-config-CkSx3usH.mjs → platform-auth-config-Z16-I8nT.mjs} +11 -12
- package/dist/{platform-auth-protection-BJimB_p9.mjs → platform-auth-protection-BXwZiJSF.mjs} +37 -27
- package/dist/{platform-auth-recovery-BU6izFAU.mjs → platform-auth-recovery-CXjfqyOv.mjs} +9 -10
- package/dist/{platform-cmd-BbY1dWiM.mjs → platform-cmd-DaAOiWTl.mjs} +16 -16
- package/dist/platform-cmd-PT4YwMLM.mjs +1 -0
- package/dist/{platform-discovery-DIYz8V63.mjs → platform-discovery-CHhNs8Nn.mjs} +1 -1
- package/dist/{platform-domain-CHVS6cV0.mjs → platform-domain-CxpvUeo0.mjs} +6 -6
- package/dist/{platform-lifecycle-DzCwqhFq.mjs → platform-lifecycle-DBiS0cJd.mjs} +1693 -2120
- package/dist/platform-lifecycle-u9pMOvxC.mjs +1 -0
- package/dist/{platform-management-CuuVDhyt.mjs → platform-management-DhEFdQAf.mjs} +696 -130
- package/dist/platform-management-DvBS83rC.mjs +1 -0
- package/dist/{platform-plans-config-CN-heS4q.mjs → platform-plans-config-BWn1S2Rv.mjs} +16 -12
- package/dist/{platform-recovery-CskSJgLh.mjs → platform-recovery-BUGOB4RC.mjs} +6 -9
- package/dist/{platform-registry-Cjv2Qf0r.mjs → platform-registry-B9mWX9LO.mjs} +13 -18
- package/dist/{platform-setup-BBxRxmFC.mjs → platform-setup-YvN9VQXV.mjs} +21 -28
- package/dist/{plugin-inference-BlQbOL0P.mjs → plugin-inference-DsARdQKE.mjs} +18 -33
- package/dist/prepare-CYT6tAzD.mjs +1 -0
- package/dist/{prepare-Do96654b.mjs → prepare-DEB5SeVJ.mjs} +12 -13
- package/dist/{prepare-Dq9hTIbo.mjs → prepare-PQCgsny0.mjs} +4 -4
- 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 +1 -2
- package/dist/{project-cmd-DaoRrn-8.mjs → project-cmd-DVatD8Ev.mjs} +20 -20
- package/dist/{project-paths-GgcMozYz.mjs → project-paths-DMvEeSau.mjs} +9 -14
- package/dist/{project-BAm2aB6Q.mjs → project-rqDnVsJN.mjs} +8 -4
- package/dist/project-slug-6cyz8E7k.mjs +1 -0
- package/dist/{project-team-Q_lCA7Io.mjs → project-team-DJrWEAG1.mjs} +7 -7
- package/dist/{project-token-BArgK9o1.mjs → project-token-CBgLBuL6.mjs} +6 -6
- package/dist/{project-tsconfig-CVJhNMxs.mjs → project-tsconfig-bveqhlYA.mjs} +3 -5
- package/dist/project-zdB3fs9G.mjs +1 -0
- package/dist/{project-zero-trust-KO9Hu2Pq.mjs → project-zero-trust-92gLtZ25.mjs} +6 -6
- 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-BnSSkiED.mjs} +119 -866
- package/dist/{requests-C7Oeoh5u.mjs → requests-7W1Pygt2.mjs} +5 -5
- package/dist/resolve-project-PnhzMtY6.mjs +1 -0
- package/dist/resolve-project-WpwkCB_c.mjs +48 -0
- package/dist/{rollback-DVAtrLAl.mjs → rollback-BcASVnwP.mjs} +8 -18
- package/dist/{route-types-CbtsIeFn.mjs → route-types-BZi26DVS.mjs} +9 -91
- package/dist/routing-assets-VkrKIbxE.mjs +139 -0
- package/dist/{runner-DMBKSrRk.mjs → runner-CabsQ-iM.mjs} +22 -34
- package/dist/runner-So9mYfcm.mjs +1 -0
- package/dist/runner-mysql-BhRaONkO.mjs +146 -0
- package/dist/runner-mysql-DWwE8jKi.mjs +1 -0
- package/dist/{runner-pg-DV8p_zjA.mjs → runner-pg-BRemq_GX.mjs} +3 -3
- package/dist/runner-pg-_Xncr3H5.mjs +1 -0
- package/dist/runtime/ai.mjs +23 -25
- package/dist/runtime/auth-client-react.mjs +1 -2
- package/dist/runtime/auth-client-solid.mjs +1 -2
- package/dist/runtime/auth-client-svelte.mjs +1 -2
- package/dist/runtime/auth-client-vue.mjs +1 -2
- package/dist/runtime/auth-client.mjs +1 -2
- package/dist/runtime/auth.mjs +1 -2
- package/dist/runtime/better-auth-mysql.d.mts +2 -5
- package/dist/runtime/better-auth-mysql.mjs +9 -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 +6 -2
- package/dist/runtime/durable.d.mts +18 -1
- 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 +1 -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 -2
- 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/limits.mjs +1 -2
- package/dist/runtime/live-client.d.mts +3 -2
- package/dist/runtime/live-server.d.mts +2 -1
- package/dist/runtime/live-server.mjs +1 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/live.mjs +1 -2
- package/dist/runtime/log.d.mts +2 -1
- package/dist/runtime/migration-handler-mysql.d.mts +2 -2
- package/dist/runtime/migration-handler-mysql.mjs +39 -8
- 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 +1 -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/response.mjs +1 -2
- package/dist/runtime/route-url.mjs +1 -2
- package/dist/runtime/routing.d.mts +3 -5
- package/dist/runtime/routing.mjs +82 -218
- package/dist/runtime/sandbox-container.d.mts +2 -2
- package/dist/runtime/sandbox-container.mjs +1 -2
- package/dist/runtime/sandbox.d.mts +2 -2
- package/dist/runtime/sandbox.mjs +13 -6
- package/dist/runtime/seed.d.mts +2 -1
- package/dist/runtime/sse.mjs +1 -2
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/validator.mjs +1 -2
- package/dist/runtime/ws-server.d.mts +4 -4
- 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-a9LRUtii.mjs} +13 -2
- 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-BvtB7IjY.mjs → secret-bg73f1Ge.mjs} +63 -81
- package/dist/{serialize-BPvnNQuA.mjs → serialize-BtQyaYoC.mjs} +10 -4
- package/dist/{skills-BgVMvQdy.mjs → skills-C_yRTg0g.mjs} +3 -3
- package/dist/{subcommand-prompt-BSlnD1fI.mjs → subcommand-prompt-Bm3ZlYgA.mjs} +39 -44
- package/dist/sveltekit.d.mts +2 -1
- package/dist/sveltekit.mjs +1 -1
- package/dist/validate-BQFdf0Pi.mjs +1 -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/wrapper-CwhpNWtH.mjs +663 -0
- package/dist/{ws-CChrrAU-.d.mts → ws-aKVYB-fA.d.mts} +1 -1
- package/dist/yarn-pnp-DLbEFMT0.mjs +92 -0
- package/docs/guide/ai.md +8 -2
- package/docs/guide/auth.md +2 -0
- package/docs/guide/database/mysql.md +14 -3
- package/docs/guide/database/postgresql.md +2 -0
- package/docs/guide/database.md +3 -5
- package/docs/guide/durable-state.md +32 -4
- package/docs/guide/platform/administration/access.md +4 -0
- package/docs/guide/platform/administration/connected-apps.md +55 -0
- package/docs/guide/platform/installation/credentials.md +21 -3
- package/docs/guide/platform/installation/domains.md +1 -1
- package/docs/guide/platform/installation/maintenance.md +38 -1
- package/docs/guide/platform/installation/prerequisites.md +6 -2
- package/docs/guide/platform/installation/setup.md +23 -1
- package/docs/guide/platform/installation/uninstall.md +6 -1
- package/docs/guide/quickstart.md +2 -0
- package/docs/guide/sandboxes.md +3 -1
- package/docs/guide/self-hosted-platform.md +1 -1
- package/docs/integrations/cloudflare.md +2 -2
- package/docs/integrations/frameworks/analog.md +3 -11
- package/docs/integrations/frameworks/nuxt.md +7 -10
- package/docs/integrations/nodejs-bun-deno.md +2 -0
- package/docs/reference/api/deploy.md +23 -0
- package/docs/reference/api/pages.md +2 -0
- package/docs/reference/api.md +3 -1
- package/docs/reference/cli/database.md +9 -3
- package/docs/reference/cli/platform-installation.md +19 -7
- package/docs/reference/cli/setup.md +2 -0
- package/docs/reference/config.md +2 -0
- package/package.json +39 -36
- package/sandbox.Dockerfile +1 -1
- package/skills/void/SKILL.md +2 -1
- package/dist/auth-LMJcNESe.mjs +0 -2
- package/dist/cf-build-output-H9a97vME.mjs +0 -2
- package/dist/cf-user-agent-lKblH3zU.mjs +0 -17
- package/dist/client-tso2OfcG.mjs +0 -2
- package/dist/cloudflare-operations-BlYLlowZ.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/create-project-qFDC45zg.mjs +0 -2
- package/dist/deploy-Bqe1PYBw.mjs +0 -10458
- package/dist/deploy-VsWsVQkw.mjs +0 -2
- package/dist/dev-inbox-CK-UuPob.mjs +0 -297
- package/dist/discover-EDUf6JJw.mjs +0 -2
- package/dist/dist-Bx1z6Eva.mjs +0 -2
- package/dist/dist-_UUlL6bg.mjs +0 -2
- package/dist/env-validation-CrVNjsPm.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-DfQYVfGY.mjs +0 -2
- package/dist/login-mx_ydhmp.mjs +0 -2
- package/dist/migrate-BHp07yJE.mjs +0 -2
- package/dist/operator-cmd-CwBB-1yb.mjs +0 -2
- package/dist/pages/head-client.d.mts +0 -13
- package/dist/pages/head-client.mjs +0 -2
- package/dist/plan-CH2G51je.mjs +0 -2
- package/dist/platform-args-D4E1PjVw.mjs +0 -2
- package/dist/platform-cmd-BbmJiq5O.mjs +0 -2
- package/dist/platform-lifecycle-ByAlpkhV.mjs +0 -2
- package/dist/platform-management-CBOT4BSM.mjs +0 -2
- package/dist/prepare-DRUV-g3X.mjs +0 -2
- package/dist/project-DedqCp59.mjs +0 -2
- package/dist/project-slug-DofjTFd-.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-9wjsSZx-.mjs +0 -2
- package/dist/runner-mysql-CEzKtmFb.mjs +0 -54
- 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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as bytesToBase64 } from "./base64-DVrOndmI.mjs";
|
|
1
2
|
import { validate } from "email-validator";
|
|
2
3
|
//#region src/runtime/email/mime.ts
|
|
3
4
|
/**
|
|
@@ -10,29 +11,10 @@ import { validate } from "email-validator";
|
|
|
10
11
|
/** Encoded outbound MIME ceiling, separate from the 10 MiB inbound limit. */
|
|
11
12
|
const MAX_MESSAGE_BYTES = 5242880;
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* check at the end of `buildMime` no matter how small everything else is.
|
|
18
|
-
* `buildMime` remains the authority on the final size — this bound only stops
|
|
19
|
-
* `normalizeEmail` from materializing, and then expanding, bytes already known
|
|
20
|
-
* not to fit.
|
|
21
|
-
*
|
|
22
|
-
* It has to be charged here because that final check comes far too late to
|
|
23
|
-
* help. Measured peak live memory is about 10x the attachment bytes (8 MiB in
|
|
24
|
-
* gives 83 MiB live) once the normalized copy, the base64 binary string, the
|
|
25
|
-
* 76-column slices, the joins, `rawText` and its `TextEncoder.encode` are all
|
|
26
|
-
* resident at once. Against a 128 MB isolate ceiling, a set over roughly
|
|
27
|
-
* 12 MiB terminates the isolate rather than returning the `MIME_ERROR` the
|
|
28
|
-
* docs promise for an oversize payload.
|
|
29
|
-
*
|
|
30
|
-
* This is a developer-experience guardrail, NOT the security boundary.
|
|
31
|
-
* Attachments come from the app's own code, never from a remote sender, and
|
|
32
|
-
* the platform proxy already caps the base64 length before decoding and the
|
|
33
|
-
* raw length after. What this buys is a precise, catchable failure at the call
|
|
34
|
-
* that went wrong, instead of a dead isolate with nothing a caller could act
|
|
35
|
-
* on.
|
|
14
|
+
* Total attachment bytes `normalizeEmail` will materialize: base64 of more
|
|
15
|
+
* than 3/4 of `MAX_MESSAGE_BYTES` cannot fit. Charged before each copy so an
|
|
16
|
+
* oversize set fails with `MIME_ERROR` instead of exhausting the isolate;
|
|
17
|
+
* `buildMime`'s final size check stays authoritative.
|
|
36
18
|
*/
|
|
37
19
|
const MAX_ATTACHMENT_BYTES_TOTAL = Math.floor(MAX_MESSAGE_BYTES * 3 / 4);
|
|
38
20
|
/** Maximum serialized size of app-defined top-level MIME fields. */
|
|
@@ -47,33 +29,24 @@ function rejectCRLF(field, value) {
|
|
|
47
29
|
}
|
|
48
30
|
}
|
|
49
31
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* `rejectCRLF` is enough for a value `encodeWord` renders (the subject, a
|
|
53
|
-
* custom header value, a display name): anything outside printable ASCII
|
|
54
|
-
* sends the whole value into base64, so a control never reaches the wire.
|
|
55
|
-
* These three go through `quoteParam` or straight into the line, so a
|
|
56
|
-
* control would reach the wire for the receiving MTA to refuse.
|
|
57
|
-
*
|
|
58
|
-
* RFC 5322 §3.2.4 `qtext` is printable US-ASCII less `"` and `\`; a
|
|
59
|
-
* control inside a quoted-string is `obs-qtext`, which §4 says MUST NOT be
|
|
60
|
-
* generated. HTAB is deliberately NOT refused: `quoted-string` is
|
|
61
|
-
* `DQUOTE *([FWS] qcontent) [FWS] DQUOTE` and `FWS` is built from `WSP`
|
|
62
|
-
* (SP / HTAB), so a tab between characters is folding white space exactly
|
|
63
|
-
* as a space is — and `obs-NO-WS-CTL`, the RFC's own list of the controls
|
|
64
|
-
* that used to be `qtext`, leaves %d9 out. The same set is illegal in an
|
|
65
|
-
* RFC 2045 §5.1 `token` (no CTLs) and an RFC 5322 §3.6.4 `msg-id`
|
|
66
|
-
* (`dot-atom-text`), so one rule serves the media type and the Content-ID.
|
|
67
|
-
*
|
|
68
|
-
* The message names the code point and never echoes the value, as
|
|
69
|
-
* `validateAddressParts` does. Runs AFTER the filename's length bound, so
|
|
70
|
-
* the scan is over a value already known to fit a line.
|
|
32
|
+
* Index of the first C0 control other than HTAB, or DEL; -1 when there is
|
|
33
|
+
* none. HTAB is folding whitespace (RFC 5322 §3.2.2).
|
|
71
34
|
*/
|
|
72
|
-
function
|
|
35
|
+
function indexOfControl(value) {
|
|
73
36
|
for (let i = 0; i < value.length; i++) {
|
|
74
37
|
const c = value.charCodeAt(i);
|
|
75
|
-
if (c < 32 && c !== 9 || c === 127)
|
|
38
|
+
if (c < 32 && c !== 9 || c === 127) return i;
|
|
76
39
|
}
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Refuse a control in a value rendered verbatim into a header (an
|
|
44
|
+
* attachment's filename, media type and Content-ID). Names the code point,
|
|
45
|
+
* never the value.
|
|
46
|
+
*/
|
|
47
|
+
function rejectControls(field, value) {
|
|
48
|
+
const i = indexOfControl(value);
|
|
49
|
+
if (i !== -1) throw new MimeError("MIME_ERROR", `${field} contains a control character (U+${value.charCodeAt(i).toString(16).toUpperCase().padStart(4, "0")}).`);
|
|
77
50
|
}
|
|
78
51
|
/** RFC 2045 §5.1 `tspecials`: what a `token` may not contain besides SPACE and CTLs. */
|
|
79
52
|
const TSPECIALS = "()<>@,;:\\\"/[]?=";
|
|
@@ -82,33 +55,10 @@ function isTokenChar(c) {
|
|
|
82
55
|
return c > 32 && c < 127 && !TSPECIALS.includes(String.fromCharCode(c));
|
|
83
56
|
}
|
|
84
57
|
/**
|
|
85
|
-
* Refuse
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* `
|
|
89
|
-
* the value verbatim ahead of its own `; name="…"`, so an unterminated
|
|
90
|
-
* quote such as `text/plain; x="` would swallow the builder's `name`
|
|
91
|
-
* parameter as the value of `x`.
|
|
92
|
-
*
|
|
93
|
-
* The grammar is the RFC's, read as a generator: a `token` is printable
|
|
94
|
-
* US-ASCII less SPACE and `tspecials`; a `value` is a `token` or a
|
|
95
|
-
* quoted-string, whose content is anything but a bare `"` or `\` (the same
|
|
96
|
-
* rule `quoteParam` renders `name="…"` by, so a caller's quoted value may
|
|
97
|
-
* carry what the builder's own already does). Optional WSP is admitted on
|
|
98
|
-
* either side of `;` — the RFC 822 implicit LWSP every parser accepts and
|
|
99
|
-
* the form HTTP's `Content-Type` writes — and nowhere else: `text/ plain`,
|
|
100
|
-
* a trailing `;`, and an RFC 822 comment are refused rather than repaired.
|
|
101
|
-
* Two parameters are also refused on their meaning: a `name`, because the
|
|
102
|
-
* builder appends `name="<filename>"` and RFC 6838 §4.3 makes it "an error
|
|
103
|
-
* for a specific parameter to be specified more than once"; and by that
|
|
104
|
-
* same sentence any attribute given twice, compared case-insensitively as
|
|
105
|
-
* §5.1 says attributes match. Type and subtype are kept as given — matching
|
|
106
|
-
* is case-insensitive, so `TEXT/PLAIN` is legal and renders unchanged.
|
|
107
|
-
*
|
|
108
|
-
* One pass, no backtracking, and the only allocation is one lower-cased
|
|
109
|
-
* attribute per parameter for the duplicate check, which is why this runs
|
|
110
|
-
* AFTER the value's length bound. The message names the rule and never
|
|
111
|
-
* echoes the value.
|
|
58
|
+
* Refuse a media type that is not RFC 2045 §5.1 `type "/" subtype *(";"
|
|
59
|
+
* parameter)`: it is written verbatim before the builder's `name=`, so an
|
|
60
|
+
* unterminated quote would swallow it. WSP is allowed only around `;`. A
|
|
61
|
+
* `name` parameter or a repeated attribute is refused (RFC 6838 §4.3).
|
|
112
62
|
*/
|
|
113
63
|
function validateMediaType(field, value) {
|
|
114
64
|
const syntax = () => new MimeError("MIME_ERROR", `${field} is not a valid media type (RFC 2045 §5.1: type/subtype, then ; attribute=value parameters).`);
|
|
@@ -160,34 +110,9 @@ function isAtext(c) {
|
|
|
160
110
|
return c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || ATEXT_SYMBOLS.includes(String.fromCharCode(c));
|
|
161
111
|
}
|
|
162
112
|
/**
|
|
163
|
-
* Refuse
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* `rejectControls` answers only for CTLs, and `buildAttachmentPart` writes
|
|
167
|
-
* the value verbatim — adding `<` and `>` unless the value already starts
|
|
168
|
-
* with `<` — so a malformed id would reach the receiver and break the
|
|
169
|
-
* `cid:` reference.
|
|
170
|
-
*
|
|
171
|
-
* The grammar is the RFC's, read as a generator, with two deliberate
|
|
172
|
-
* differences. An `msg-id` is `"<" id-left "@" id-right ">"`, each side a
|
|
173
|
-
* `dot-atom-text` (§3.2.3: `1*atext *("." 1*atext)`, so no leading,
|
|
174
|
-
* trailing or doubled dot — the strict form; `obs-id-left`/`obs-id-right`
|
|
175
|
-
* are §4 obsolete syntax, which MUST NOT be generated); `no-fold-literal`
|
|
176
|
-
* (`[…]` for `id-right`) is left out. First difference: the `@` and its
|
|
177
|
-
* right side are OPTIONAL. RFC 2392 §2 resolves a `cid:` URL by wrapping
|
|
178
|
-
* its body in `<` `>` and matching that against `Content-ID`, so an id
|
|
179
|
-
* without `@` — the documented `contentId: 'logo'` + `cid:logo` — is what
|
|
180
|
-
* every client already resolves, and the domain that would make it a
|
|
181
|
-
* proper `msg-id` adds nothing a reference could use. Second: the angle
|
|
182
|
-
* brackets are optional too, because the builder has always added them
|
|
183
|
-
* around a bare id; given, they must be one pair around the whole value.
|
|
184
|
-
*
|
|
185
|
-
* Refused, then: whitespace of any kind, a second `@`, `<` or `>` anywhere
|
|
186
|
-
* but as that one pair, `"`, `(`, `)`, `,`, `;`, `:`, `\`, `[`, `]`,
|
|
187
|
-
* anything non-ASCII, and the empty string.
|
|
188
|
-
*
|
|
189
|
-
* One pass, no allocation, which is why this runs AFTER the value's length
|
|
190
|
-
* bound. The message names the rule and never echoes the value.
|
|
113
|
+
* Refuse a Content-ID that would not render as an RFC 5322 §3.6.4 `msg-id`
|
|
114
|
+
* of strict `dot-atom-text`. Unlike `msg-id`, the `@` part and the angle
|
|
115
|
+
* brackets are optional: `cid:logo` resolves against `<logo>` (RFC 2392).
|
|
191
116
|
*/
|
|
192
117
|
function validateContentId(field, value) {
|
|
193
118
|
const syntax = () => new MimeError("MIME_ERROR", `${field} is not a valid Content-ID (RFC 5322 §3.6.4 msg-id: an identifier of atext, "." and "@", optionally in one pair of angle brackets).`);
|
|
@@ -255,37 +180,10 @@ function fieldErrorCode(field) {
|
|
|
255
180
|
return "MIME_ERROR";
|
|
256
181
|
}
|
|
257
182
|
/**
|
|
258
|
-
* Validate one parsed address
|
|
259
|
-
*
|
|
260
|
-
* the
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
* The address rule is `email-validator`, and nothing else. It is also the
|
|
264
|
-
* platform router's rule (`isValidEmailAddress` in the proxy's
|
|
265
|
-
* `email-router.ts`), so there is exactly ONE address syntax in the tree:
|
|
266
|
-
* an action the framework records is never dropped by the router for its
|
|
267
|
-
* shape, and a test harness never captures as a success what the managed
|
|
268
|
-
* deployment would lose.
|
|
269
|
-
*
|
|
270
|
-
* What it enforces: at most 254 characters in total; an ASCII dot-atom
|
|
271
|
-
* local part of at most 64 characters (RFC 5322 §3.2.3 `atext`, dots only
|
|
272
|
-
* between atoms — no quoted local part, no whitespace, no control, no
|
|
273
|
-
* special); a dotted domain of ASCII labels of at most 63 characters each,
|
|
274
|
-
* with a TLD that starts with a letter and has at least two characters; so
|
|
275
|
-
* `user@localhost`, `x@y` and a raw IDN or SMTPUTF8 address are refused
|
|
276
|
-
* (an IDN domain is accepted as punycode, `xn--…`). ASCII-only makes
|
|
277
|
-
* octets and characters the same thing, so the RFC 5321 §4.5.3.1 octet
|
|
278
|
-
* limits are the package's length checks; the 64 is also what caps the
|
|
279
|
-
* default `<slug>+noreply@` sender (`VALID_SLUG` in `runtime/email.ts`,
|
|
280
|
-
* `MAX_SLUG_LENGTH` = `64 - 8` in `cli/project-slug.ts` and the API). One
|
|
281
|
-
* known quirk, pinned in the tests rather than worked around: the FIRST
|
|
282
|
-
* character of the local part may not be a backtick, while any later one
|
|
283
|
-
* may.
|
|
284
|
-
*
|
|
285
|
-
* `MAX_ADDRESS_LENGTH` still runs first, on the raw string, so the scan is
|
|
286
|
-
* bounded before anything reads the address; the package's own 254 check
|
|
287
|
-
* runs before its regex for the same reason. The message never echoes the
|
|
288
|
-
* address: it may hold a control character, and naming the rule is enough.
|
|
183
|
+
* Validate one parsed address and optional display name, throwing a
|
|
184
|
+
* `MimeError` for `field`. The address rule is `email-validator`, the one
|
|
185
|
+
* the platform router applies, so a recorded action is never dropped for its
|
|
186
|
+
* shape. The message never echoes the address.
|
|
289
187
|
*/
|
|
290
188
|
function validateAddressParts(field, email, name) {
|
|
291
189
|
if (email.length > 320) throw new MimeError(fieldErrorCode(field), `${field}: address is ${email.length} characters, over the 320-character limit.`);
|
|
@@ -297,25 +195,9 @@ function validateAddressParts(field, email, name) {
|
|
|
297
195
|
}
|
|
298
196
|
}
|
|
299
197
|
/**
|
|
300
|
-
* Undo
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
* the RAW text `formatAddress` will quote and escape again, so leaving the
|
|
304
|
-
* pairs in place would escape them twice. Only the quoted branch
|
|
305
|
-
* of `parseAddress` calls this; a backslash in an unquoted name is a
|
|
306
|
-
* character like any other, as it is in the object form.
|
|
307
|
-
*
|
|
308
|
-
* NOT `text.replace(/\\(.)/g, '$1')`: a global-regex replacement holds one
|
|
309
|
-
* part per match before it builds the result, about 60 bytes each, and
|
|
310
|
-
* nothing bounds this name before it runs — the quoted-string line guard
|
|
311
|
-
* in `validateAddressParts` needs the DECODED name, and a non-ASCII name is
|
|
312
|
-
* never bounded at all. Measured, 10 MiB of `\"` pairs peaked at 307 MB of
|
|
313
|
-
* heap that way and terminated a 128 MB isolate; this shape peaks at 49 MB.
|
|
314
|
-
* Same discipline as `to7bitBody`: one counting pass, a buffer of exactly
|
|
315
|
-
* the output size, one fill, and one chunked `codeUnitsToString`.
|
|
316
|
-
* The common case — no backslash at all — is one scan and no allocation.
|
|
317
|
-
* The regex that admits the text guarantees every backslash is followed by
|
|
318
|
-
* a character, so the fill never reads past the end.
|
|
198
|
+
* Undo quoted-pairs (`\x` → `x`) in a quoted display name so `formatAddress`
|
|
199
|
+
* escapes it once. A counting pass and an exact buffer, not a global-regex
|
|
200
|
+
* replace, which allocates per match on an unbounded name.
|
|
319
201
|
*/
|
|
320
202
|
function unquotePairs(text) {
|
|
321
203
|
const first = text.indexOf("\\");
|
|
@@ -372,22 +254,14 @@ function countRecipients(value) {
|
|
|
372
254
|
if (!value) return 0;
|
|
373
255
|
return Array.isArray(value) ? value.length : 1;
|
|
374
256
|
}
|
|
375
|
-
/**
|
|
376
|
-
* Keeps the `exceeds Cloudflare limit of <N> bytes` tail that `buildMime`'s
|
|
377
|
-
* own size error already uses, so the documented shape — and any caller
|
|
378
|
-
* matching on it — holds for both paths.
|
|
379
|
-
*/
|
|
257
|
+
/** Same `exceeds Cloudflare limit of <N> bytes` tail as `buildMime`'s size error. */
|
|
380
258
|
function attachmentsTooLargeError(bytes) {
|
|
381
259
|
return new MimeError("MIME_ERROR", `email: attachment size ${bytes} bytes exceeds Cloudflare limit of ${MAX_ATTACHMENT_BYTES_TOTAL} bytes.`);
|
|
382
260
|
}
|
|
383
261
|
/**
|
|
384
|
-
* Size of `content`
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
* UTF-8 byte length — every code unit encodes to at least one byte — so this
|
|
388
|
-
* can never reject a string that would have fit; the exact length is charged
|
|
389
|
-
* after the encode. Anything else reports 0 and is left to `toBytes` to reject
|
|
390
|
-
* by type.
|
|
262
|
+
* Size of `content` without materializing it. A string's `length` is a lower
|
|
263
|
+
* bound on its UTF-8 size; an unsupported type reports 0 for `toBytes` to
|
|
264
|
+
* reject.
|
|
391
265
|
*/
|
|
392
266
|
function declaredSize(content) {
|
|
393
267
|
if (content instanceof Uint8Array) return content.byteLength;
|
|
@@ -493,22 +367,13 @@ async function normalizeEmail(opts) {
|
|
|
493
367
|
};
|
|
494
368
|
}
|
|
495
369
|
/**
|
|
496
|
-
* RFC 2047 §2
|
|
497
|
-
*
|
|
498
|
-
* characters of base64, and base64 spends 4 characters per 3 input
|
|
499
|
-
* bytes, so 45 source bytes is the largest payload that fits — 48 would
|
|
500
|
-
* need 64.
|
|
370
|
+
* RFC 2047 §2: a 75-character encoded-word less `=?UTF-8?B?` and `?=` leaves
|
|
371
|
+
* 63 characters of base64, so 45 source bytes.
|
|
501
372
|
*/
|
|
502
373
|
const ENCODED_WORD_PAYLOAD_BYTES = 45;
|
|
503
374
|
/**
|
|
504
|
-
* RFC 2047 encoded-
|
|
505
|
-
*
|
|
506
|
-
* Text longer than one word's payload becomes several encoded-words
|
|
507
|
-
* separated by a space, which `foldHeader` turns into CRLF + SPACE
|
|
508
|
-
* wherever a line would otherwise overrun (RFC 2047 §6.2: whitespace
|
|
509
|
-
* between adjacent encoded-words is dropped on decode either way). This
|
|
510
|
-
* keeps each word under §2's 75-character ceiling and a long subject or
|
|
511
|
-
* display name under RFC 5322 §2.1.1's 998-octet line limit.
|
|
375
|
+
* RFC 2047 B encoded-words for non-ASCII header text, space-separated so
|
|
376
|
+
* `foldHeader` can fold between them.
|
|
512
377
|
*/
|
|
513
378
|
function encodeWord(text) {
|
|
514
379
|
if (ASCII_PRINTABLE.test(text)) return text;
|
|
@@ -518,7 +383,7 @@ function encodeWord(text) {
|
|
|
518
383
|
const words = [];
|
|
519
384
|
const flush = () => {
|
|
520
385
|
if (length > 0) {
|
|
521
|
-
words.push(`=?UTF-8?B?${
|
|
386
|
+
words.push(`=?UTF-8?B?${bytesToBase64(pending.subarray(0, length))}?=`);
|
|
522
387
|
length = 0;
|
|
523
388
|
}
|
|
524
389
|
};
|
|
@@ -532,17 +397,8 @@ function encodeWord(text) {
|
|
|
532
397
|
return words.join(" ");
|
|
533
398
|
}
|
|
534
399
|
/**
|
|
535
|
-
* RFC 5322 §3.2.3
|
|
536
|
-
*
|
|
537
|
-
* specials = "(" / ")" / "<" / ">" / "[" / "]" / ":" / ";" / "@" /
|
|
538
|
-
* "\" / "," / "." / DQUOTE
|
|
539
|
-
*
|
|
540
|
-
* A display name is a §3.2.5 `phrase = 1*word`, `word = atom /
|
|
541
|
-
* quoted-string`, and `atext` is everything printable EXCEPT these, so an
|
|
542
|
-
* ASCII name containing any of them must be rendered as one quoted-string.
|
|
543
|
-
* The class below lists the thirteen in the RFC's order so it can be checked
|
|
544
|
-
* against the production by eye. `.` matters: an unquoted `Dr. Smith` is
|
|
545
|
-
* `obs-phrase` (§4.1), which §4 says MUST NOT be generated.
|
|
400
|
+
* RFC 5322 §3.2.3 `specials`, in the RFC's order: an ASCII display name with
|
|
401
|
+
* any of them must be quoted (an unquoted `Dr. Smith` is obsolete syntax).
|
|
546
402
|
*/
|
|
547
403
|
const RFC5322_SPECIALS = /[()<>[\]:;@\\,."]/;
|
|
548
404
|
function formatAddress(addr) {
|
|
@@ -555,25 +411,10 @@ function formatAddressList(addrs) {
|
|
|
555
411
|
return addrs.map(formatAddress).join(", ");
|
|
556
412
|
}
|
|
557
413
|
/**
|
|
558
|
-
* Soft-fold a
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
* between whole parts is not enough — one recipient carrying a long encoded
|
|
563
|
-
* display name, or a `References:` run of message IDs, is a single part
|
|
564
|
-
* that can blow past RFC 5322 §2.1.1's 998-octet hard limit on its own.
|
|
565
|
-
*
|
|
566
|
-
* RFC 2047 §2 limits any header line carrying an encoded-word to 76
|
|
567
|
-
* characters; RFC 5322 §2.1.1 makes 78 a SHOULD and 998 a MUST. Folding at
|
|
568
|
-
* 76 satisfies all three. A comma always stays on the line it terminates.
|
|
569
|
-
* A token longer than the budget still gets its own line, which is the
|
|
570
|
-
* best a WSP-only fold rule allows (§3.2.2 permits folding only at WSP).
|
|
571
|
-
*
|
|
572
|
-
* One pass, and the only thing kept per input character is the folded
|
|
573
|
-
* output itself: each finished line is one flat string in `lines`. Any
|
|
574
|
-
* per-token allocation (a slice array, token objects, `out +=`) costs about
|
|
575
|
-
* 130 bytes of heap per token, so a legal 3 MB subject of one-letter words
|
|
576
|
-
* would terminate a 128 MB isolate even though the message fits.
|
|
414
|
+
* Soft-fold a header at 76 columns (RFC 2047 §2): at `, ` outside quotes
|
|
415
|
+
* first, then at unquoted whitespace. A token longer than a line keeps its
|
|
416
|
+
* own line, since RFC 5322 folds only at WSP. One pass that keeps only the
|
|
417
|
+
* output; per-token allocation would exhaust the isolate on a large subject.
|
|
577
418
|
*/
|
|
578
419
|
function foldHeader(name, value) {
|
|
579
420
|
const line = `${name}: ${value}`;
|
|
@@ -653,40 +494,20 @@ const MAX_LINE_OCTETS = 998;
|
|
|
653
494
|
/** ` filename="` + `"`: the shortest line a quoted filename parameter can fold onto. */
|
|
654
495
|
const QUOTED_FILENAME_LINE_OVERHEAD = 12;
|
|
655
496
|
/**
|
|
656
|
-
* ` ` + `;`: the shortest line
|
|
657
|
-
*
|
|
658
|
-
* of several parameters at their spaces, so this bound is exact for the
|
|
659
|
-
* one-token media type every attachment carries in practice and
|
|
660
|
-
* conservative for a run of parameters that together pass the line
|
|
661
|
-
* limit; that is accepted, because the alternative — find the fold points
|
|
662
|
-
* first — is the scan this bound exists to run ahead of.
|
|
497
|
+
* ` ` + `;`: the shortest line the media type can fold onto as one token
|
|
498
|
+
* (conservative for several parameters).
|
|
663
499
|
*/
|
|
664
500
|
const CONTENT_TYPE_LINE_OVERHEAD = 2;
|
|
665
|
-
/**
|
|
666
|
-
* `Content-ID: `: the only line an attachment's Content-ID can sit on. The
|
|
667
|
-
* value is one token — `<id>` — so `foldHeader` cannot fold it onto a
|
|
668
|
-
* continuation line the way it can a media type, and the field name is
|
|
669
|
-
* part of what the id must fit beside. Exact, not conservative: the `<`
|
|
670
|
-
* and `>` the builder adds around a bare id are charged at the call.
|
|
671
|
-
*/
|
|
501
|
+
/** `Content-ID: `: the id is one token and cannot fold off this line. */
|
|
672
502
|
const CONTENT_ID_LINE_OVERHEAD = 12;
|
|
673
503
|
/** ` "` + `"`: the shortest line a quoted display name can fold onto. */
|
|
674
504
|
const QUOTED_NAME_LINE_OVERHEAD = 3;
|
|
675
505
|
/** `:` alone: the shortest line a header name can sit on, its value folded onto the next. */
|
|
676
506
|
const HEADER_NAME_LINE_OVERHEAD = 1;
|
|
677
507
|
/**
|
|
678
|
-
* First line
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
* own headers (`Content-Disposition: …; filename="…"`) live inside the body
|
|
682
|
-
* and are just as unfoldable. Body content cannot trip this — text is
|
|
683
|
-
* quoted-printable re-encoded above 990 octets and base64 is emitted at a
|
|
684
|
-
* fixed width — so a hit is always a header.
|
|
685
|
-
*
|
|
686
|
-
* One pass over the string, counting UTF-8 octets per CRLF-delimited line,
|
|
687
|
-
* with NO allocation: a `split(CRLF)` would hold one substring per line, and
|
|
688
|
-
* a legal body of pasted logs is millions of lines. Only a CRLF pair ends a
|
|
689
|
-
* line; a bare CR or LF is content.
|
|
508
|
+
* First CRLF-delimited line over the octet limit, counted in UTF-8 without
|
|
509
|
+
* allocating. Every line is scanned because part headers live in the body;
|
|
510
|
+
* encoded body content never trips it.
|
|
690
511
|
*/
|
|
691
512
|
function findOverlongLine(text) {
|
|
692
513
|
let index = 0;
|
|
@@ -716,24 +537,20 @@ function findOverlongLine(text) {
|
|
|
716
537
|
octets
|
|
717
538
|
} : void 0;
|
|
718
539
|
}
|
|
719
|
-
/**
|
|
720
|
-
* Escape a value for a quoted-string parameter (RFC 2045 §5.1 value, whose
|
|
721
|
-
* quoted-string comes from RFC 5322 §3.2.4).
|
|
722
|
-
*
|
|
723
|
-
* `qtext` excludes both `\\` and `"`, so each may appear only as a
|
|
724
|
-
* quoted-pair: a raw trailing backslash would escape the closing quote, and
|
|
725
|
-
* a conformant parser drops every other raw backslash.
|
|
726
|
-
*
|
|
727
|
-
* Backslash first, then quote — the other order would double-escape.
|
|
728
|
-
*/
|
|
540
|
+
/** Escape `\` and `"` as quoted-pairs (RFC 5322 §3.2.4), backslash first. */
|
|
729
541
|
function quoteParam(value) {
|
|
730
542
|
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
731
543
|
}
|
|
732
|
-
|
|
733
|
-
|
|
544
|
+
/** `<prefix>_<base36 time><16 random hex>`. */
|
|
545
|
+
function newId(prefix) {
|
|
546
|
+
const bytes = /* @__PURE__ */ new Uint8Array(8);
|
|
547
|
+
crypto.getRandomValues(bytes);
|
|
548
|
+
let hex = "";
|
|
549
|
+
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
550
|
+
return `${prefix}_${Date.now().toString(36)}${hex}`;
|
|
734
551
|
}
|
|
735
552
|
function base64Wrapped(bytes) {
|
|
736
|
-
const encoded =
|
|
553
|
+
const encoded = bytesToBase64(bytes);
|
|
737
554
|
const lines = [];
|
|
738
555
|
for (let i = 0; i < encoded.length; i += 76) lines.push(encoded.slice(i, i + 76));
|
|
739
556
|
return lines.join(CRLF);
|
|
@@ -797,14 +614,9 @@ function codeUnitsToString(units) {
|
|
|
797
614
|
return s;
|
|
798
615
|
}
|
|
799
616
|
/**
|
|
800
|
-
* Whether a body
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
* is a control character like any other and forces the encoding.
|
|
804
|
-
*
|
|
805
|
-
* One pass over the string with NO allocation: a `replace`/`split` shape
|
|
806
|
-
* holds a copy of the body plus one substring per line, and a legal 6 MB
|
|
807
|
-
* body of millions of two-character lines needed about 100 MB that way.
|
|
617
|
+
* Whether a body needs quoted-printable: anything outside printable ASCII
|
|
618
|
+
* (a bare CR included) or a line over 990 characters. One pass without
|
|
619
|
+
* allocation.
|
|
808
620
|
*/
|
|
809
621
|
function needsQuotedPrintable(text) {
|
|
810
622
|
let lineLen = 0;
|
|
@@ -825,18 +637,9 @@ function needsQuotedPrintable(text) {
|
|
|
825
637
|
return false;
|
|
826
638
|
}
|
|
827
639
|
/**
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
* and a byte buffer is exact.
|
|
832
|
-
*
|
|
833
|
-
* NOT `text.replace(/\r?\n/g, CRLF)`: V8 builds a global-regex replacement
|
|
834
|
-
* from a parts array that holds two or three slots per match, grown by
|
|
835
|
-
* doubling, so that one line cost 144 MB of heap on a legal 6 MB body of
|
|
836
|
-
* 3M lines and terminated a 128 MB isolate — the largest single allocation
|
|
837
|
-
* in the whole build, for a body that renders to 9 MB. The buffer here is
|
|
838
|
-
* the output size, known up front from one counting pass. A body that is
|
|
839
|
-
* already CRLF-only (or has no line breaks) is returned as-is.
|
|
640
|
+
* `text` with each bare LF widened to CRLF. Called only when every character
|
|
641
|
+
* is one byte, so a counting pass sizes the buffer exactly; a global-regex
|
|
642
|
+
* replace would allocate per line.
|
|
840
643
|
*/
|
|
841
644
|
function to7bitBody(text) {
|
|
842
645
|
let bare = 0;
|
|
@@ -852,16 +655,8 @@ function to7bitBody(text) {
|
|
|
852
655
|
return codeUnitsToString(out);
|
|
853
656
|
}
|
|
854
657
|
/**
|
|
855
|
-
* Lower bound on
|
|
856
|
-
*
|
|
857
|
-
* least one octet on either body path — the 7bit path copies bytes and only
|
|
858
|
-
* ever widens a bare LF to CRLF; the quoted-printable path emits each
|
|
859
|
-
* non-ASCII byte as `=XX` (3 octets) and every other byte as itself, and its
|
|
860
|
-
* soft breaks only add. So `ascii + 3 * nonAscii` can never overshoot the
|
|
861
|
-
* real size, which keeps a false rejection impossible; `buildMime`'s final
|
|
862
|
-
* check remains the authority. `TextEncoder.encode` would give the same count
|
|
863
|
-
* but at the price of a full copy, which is exactly the allocation this
|
|
864
|
-
* bound exists to avoid.
|
|
658
|
+
* Lower bound on `text`'s rendered octets, without allocating: ASCII is at
|
|
659
|
+
* least 1 octet and each non-ASCII UTF-8 byte is `=XX`.
|
|
865
660
|
*/
|
|
866
661
|
function minBodyOctets(text) {
|
|
867
662
|
let octets = 0;
|
|
@@ -913,7 +708,7 @@ function buildAttachmentPart(att) {
|
|
|
913
708
|
function makeBoundary(prefix) {
|
|
914
709
|
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
915
710
|
crypto.getRandomValues(bytes);
|
|
916
|
-
return `=_void_${prefix}_${
|
|
711
|
+
return `=_void_${prefix}_${bytesToBase64(bytes).replace(/[+/=]/g, "")}`;
|
|
917
712
|
}
|
|
918
713
|
function wrapMultipart(type, parts) {
|
|
919
714
|
const boundary = makeBoundary(type);
|
|
@@ -939,29 +734,10 @@ const RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
|
939
734
|
"content-disposition"
|
|
940
735
|
]);
|
|
941
736
|
/**
|
|
942
|
-
* Lower bound on
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
* `encodeWord` leaves a value alone when every character is printable ASCII
|
|
947
|
-
* and otherwise B-encodes ALL of it, so the two paths need different terms:
|
|
948
|
-
*
|
|
949
|
-
* - Plain: every character is at least one octet, EXCEPT whitespace.
|
|
950
|
-
* `foldHeader` re-joins a long value from its non-WSP tokens, so a run of
|
|
951
|
-
* spaces or tabs collapses to one, and a bound that charged them could
|
|
952
|
-
* reject a message that fits. Only the non-WSP characters count.
|
|
953
|
-
* - Encoded: each RFC 2047 word carries at most `ENCODED_WORD_PAYLOAD_BYTES`
|
|
954
|
-
* (45) UTF-8 bytes as base64 — `ceil(n / 3) * 4 >= 4n / 3` octets — inside
|
|
955
|
-
* 12 octets of `=?UTF-8?B?` and `?=`, so there are at least `floor(n / 45)`
|
|
956
|
-
* words' worth of framing. Whitespace inside the value is base64 like any
|
|
957
|
-
* other byte; only the single separators between words fold.
|
|
958
|
-
*
|
|
959
|
-
* Folding (`foldHeader`) can only ADD octets beyond that — a `CRLF SP` per
|
|
960
|
-
* line — and quoting a display name (`formatAddress`) adds the quotes and
|
|
961
|
-
* escapes, so neither path can render fewer octets than this returns.
|
|
962
|
-
* Measured, the encoded bound is 96% of the rendered size for CJK, where the
|
|
963
|
-
* real cost is 5 octets per character; a UTF-16 `length` would have counted
|
|
964
|
-
* 1 and let the isolate die on a header five times over the limit.
|
|
737
|
+
* Lower bound on one rendered header value, without allocating. Printable
|
|
738
|
+
* ASCII counts its non-WSP characters (folding may collapse WSP runs);
|
|
739
|
+
* anything else is B-encoded whole, at least 4/3 of its UTF-8 bytes plus 12
|
|
740
|
+
* octets of framing per 45-byte word.
|
|
965
741
|
*/
|
|
966
742
|
function minHeaderValueOctets(value) {
|
|
967
743
|
let utf8 = 0;
|
|
@@ -996,18 +772,9 @@ function minAddressOctets(addr) {
|
|
|
996
772
|
return addr.email.length + (addr.name ? minHeaderValueOctets(addr.name) : 0);
|
|
997
773
|
}
|
|
998
774
|
/**
|
|
999
|
-
* Lower bound on
|
|
1000
|
-
*
|
|
1001
|
-
*
|
|
1002
|
-
* `Content-ID`. Every non-WSP UTF-16 code unit is at least one octet of
|
|
1003
|
-
* UTF-8; a WSP run may collapse to a single space when the line folds, so
|
|
1004
|
-
* none is charged. The `<>` around a Content-ID and the fold's `CRLF SP`
|
|
1005
|
-
* only add.
|
|
1006
|
-
*
|
|
1007
|
-
* `minHeaderValueOctets` cannot stand in here: a non-ASCII value sends it
|
|
1008
|
-
* down the encoded-word formula (4.8 octets per CJK character) while these
|
|
1009
|
-
* values render as raw UTF-8 (3), so it would overshoot and could reject a
|
|
1010
|
-
* message that fits.
|
|
775
|
+
* Lower bound on a value rendered verbatim (threading ids, media type,
|
|
776
|
+
* Content-ID): one octet per non-WSP code unit. `minHeaderValueOctets` would
|
|
777
|
+
* overshoot, since these are raw UTF-8, not encoded-words.
|
|
1011
778
|
*/
|
|
1012
779
|
function minVerbatimOctets(value) {
|
|
1013
780
|
let octets = 0;
|
|
@@ -1018,94 +785,24 @@ function minVerbatimOctets(value) {
|
|
|
1018
785
|
return octets;
|
|
1019
786
|
}
|
|
1020
787
|
/**
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
1023
|
-
* whose filename, media type, disposition and content are all empty. Each
|
|
1024
|
-
* term is emitted verbatim on every path — `foldHeader` returns a short
|
|
1025
|
-
* line as-is and re-joins a long one from its tokens with at least one
|
|
1026
|
-
* space between them, so the space after `Name:` and the one after `;` are
|
|
1027
|
-
* floors, not counts — and a fold's `CRLF SP` only adds. The boundary's
|
|
1028
|
-
* random suffix is left out: `makeBoundary` strips `+`, `/` and `=`, so it
|
|
1029
|
-
* has no provable minimum, and `mixed` is the shortest prefix an attachment
|
|
1030
|
-
* part can sit under.
|
|
788
|
+
* Framing every attachment part costs with empty values. The random boundary
|
|
789
|
+
* suffix has no provable minimum, so it is not counted.
|
|
1031
790
|
*/
|
|
1032
791
|
const ATTACHMENT_PART_MIN_OCTETS = 117;
|
|
1033
792
|
/**
|
|
1034
|
-
* Cap on the attachment
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
* Every part costs at least `ATTACHMENT_PART_MIN_OCTETS` of framing plus
|
|
1038
|
-
* its filename twice, and `normalizeAttachment` refuses an empty filename,
|
|
1039
|
-
* so the size projection in `buildMime` charges a part at least 119 octets
|
|
1040
|
-
* and refuses one more part than this whatever else the message holds.
|
|
1041
|
-
* That projection runs only after `normalizeEmail` has normalized EVERY
|
|
1042
|
-
* entry, and `MAX_ATTACHMENT_BYTES_TOTAL` cannot bound that loop for a
|
|
1043
|
-
* zero-byte attachment — its running total never advances — while the
|
|
1044
|
-
* normalized copy (the object, a fresh `Uint8Array`, the `TextEncoder`
|
|
1045
|
-
* that made it) costs about 275 bytes of live heap per entry. Measured, 2M
|
|
1046
|
-
* empty attachments terminated a 128 MB isolate in 0.3 s instead of
|
|
1047
|
-
* returning `MIME_ERROR`; this many normalize in 24 MB and are then refused
|
|
1048
|
-
* by the post-render size check under the same ceiling.
|
|
1049
|
-
*
|
|
1050
|
-
* Derived, not chosen: it is exactly the largest count the projection can
|
|
1051
|
-
* admit, so this cannot reject a message that would have been accepted, and
|
|
1052
|
-
* `buildMime` remains the authority on the final size. Same class as
|
|
1053
|
-
* `MAX_ATTACHMENT_BYTES_TOTAL` — a developer-experience guardrail on the
|
|
1054
|
-
* app's own input, not the security boundary.
|
|
793
|
+
* Cap on the attachment count, checked before any entry is normalized:
|
|
794
|
+
* zero-byte entries never advance the byte total. It is the most parts
|
|
795
|
+
* `buildMime`'s size projection can admit, so it refuses nothing that fits.
|
|
1055
796
|
*/
|
|
1056
797
|
const MAX_ATTACHMENTS = Math.floor(MAX_MESSAGE_BYTES / 119);
|
|
1057
|
-
/**
|
|
1058
|
-
* Octets every custom header costs around its value: the `: ` after the
|
|
1059
|
-
* name and the CRLF that ends its line. Exact, not a floor, once the name
|
|
1060
|
-
* is counted: `buildMime` renders each non-reserved custom header through
|
|
1061
|
-
* `foldHeader`, which emits the name verbatim, then `: ` — or, when the
|
|
1062
|
-
* value's first token does not fit beside the name, `:` CRLF SP, which is
|
|
1063
|
-
* more — and `join(CRLF)` ends every header line, a custom header never
|
|
1064
|
-
* being the last of the block (the body part's own headers follow it).
|
|
1065
|
-
*/
|
|
798
|
+
/** `: ` and the CRLF around a custom header value; exact once the name is counted. */
|
|
1066
799
|
const CUSTOM_HEADER_FRAMING_OCTETS = 4;
|
|
1067
800
|
/**
|
|
1068
|
-
* Lower bound on
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
* and — twice, once per header it is rendered into — filename. `Bcc` is
|
|
1074
|
-
* never rendered and a reserved custom header is dropped, so neither is
|
|
1075
|
-
* counted — charging either could reject a message that fits. The fixed
|
|
1076
|
-
* `Name: ` and `CRLF` of the headers `buildMime` itself names — `Subject`,
|
|
1077
|
-
* the address lists, the threading pair — are omitted for the same reason
|
|
1078
|
-
* a lower bound may omit any term. They are NOT omitted where the caller
|
|
1079
|
-
* controls the name or the count, because there they can be the whole
|
|
1080
|
-
* message:
|
|
1081
|
-
*
|
|
1082
|
-
* - A custom header's name is rendered verbatim, and `normalizeEmail`
|
|
1083
|
-
* bounds ONE name at under a kilobyte, not the sum, nor the count. With
|
|
1084
|
-
* empty values the names and the `: ` CRLF around each are the entire
|
|
1085
|
-
* size, and the framing is exact once the name is counted (see
|
|
1086
|
-
* `CUSTOM_HEADER_FRAMING_OCTETS`), so charging both cannot reject a
|
|
1087
|
-
* message that fits. Uncharged, 60k empty headers with 500-character
|
|
1088
|
-
* names (a 30 MB message) would project to zero.
|
|
1089
|
-
* - An attachment part: `normalizeAttachment` bounds ONE filename at under
|
|
1090
|
-
* a kilobyte, not the sum, and a message is free to carry any number of
|
|
1091
|
-
* parts, so the filename and the framing every part is wrapped in are
|
|
1092
|
-
* the whole size of a message of empty attachments. Measured, 50k
|
|
1093
|
-
* zero-byte attachments with legal 986-character filenames rendered to
|
|
1094
|
-
* 106 MB — held three to four times over between the parts, their join,
|
|
1095
|
-
* `rawText` and `raw` — and terminated a 128 MB isolate before the final
|
|
1096
|
-
* size check could return `MIME_ERROR`.
|
|
1097
|
-
*
|
|
1098
|
-
* The header COUNT is deliberately not bounded here. Each header costs
|
|
1099
|
-
* at least five octets (a one-character name, `: `, CRLF), so the count
|
|
1100
|
-
* the projection can admit is finite, and past a few hundred thousand keys
|
|
1101
|
-
* the caller's own object — measured at about 74 bytes per key, before
|
|
1102
|
-
* `sendEmail` is called — is the dominant cost, which no check inside this
|
|
1103
|
-
* module can pre-empt. Rendering does add live heap per header (about
|
|
1104
|
-
* 150 bytes: two `Object.entries`, the `topHeaders` pair, the folded line),
|
|
1105
|
-
* so a legal message of 500k four-character headers still does not fit a
|
|
1106
|
-
* 128 MB isolate while one of 400k does; a bound on that would be the
|
|
1107
|
-
* framework's own number — the platform proxy bounds bytes, not headers —
|
|
1108
|
-
* and is left as a product decision rather than invented here.
|
|
801
|
+
* Lower bound on every header rendered from caller values. Bcc and reserved
|
|
802
|
+
* custom headers never render, and the fixed framing of Void's own headers
|
|
803
|
+
* is omitted. A custom header's name and framing, and each attachment part's
|
|
804
|
+
* framing and filename (twice), are charged: a message of many empty headers
|
|
805
|
+
* or attachments is all framing.
|
|
1109
806
|
*/
|
|
1110
807
|
function minHeaderOctets(email) {
|
|
1111
808
|
let octets = minHeaderValueOctets(email.subject);
|
|
@@ -1127,7 +824,7 @@ function generateMessageId(fromEmail) {
|
|
|
1127
824
|
const domain = fromEmail.split("@")[1] ?? "localhost";
|
|
1128
825
|
const bytes = /* @__PURE__ */ new Uint8Array(12);
|
|
1129
826
|
crypto.getRandomValues(bytes);
|
|
1130
|
-
return `<${
|
|
827
|
+
return `<${bytesToBase64(bytes).replace(/[+/=]/g, "")}@${domain}>`;
|
|
1131
828
|
}
|
|
1132
829
|
/**
|
|
1133
830
|
* Build the raw RFC 5322 message body. Returns the message bytes plus the
|
|
@@ -1177,4 +874,4 @@ function buildMime(email) {
|
|
|
1177
874
|
};
|
|
1178
875
|
}
|
|
1179
876
|
//#endregion
|
|
1180
|
-
export {
|
|
877
|
+
export { newId as a, validateAddressParts as c, indexOfControl as i, MimeError as n, normalizeEmail as o, buildMime as r, parseAddress as s, MAX_MESSAGE_BYTES as t };
|