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
package/dist/index.mjs
CHANGED
|
@@ -1,52 +1,55 @@
|
|
|
1
1
|
import { n as __toESM } from "./rolldown-runtime-DXIUcv95.mjs";
|
|
2
|
-
import { a as join,
|
|
2
|
+
import { a as join, c as resolve, n as dirname, o as normalize, s as relative } from "./dist-ipQi0Q8y.mjs";
|
|
3
3
|
import { t as require_picocolors } from "./picocolors-BTps1_gs.mjs";
|
|
4
|
-
import { d as
|
|
5
|
-
import { n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-
|
|
6
|
-
import { n as loadVoidAuthConfig } from "./config-
|
|
7
|
-
import {
|
|
4
|
+
import { d as walk, l as inferBindingsFromSource, m as applyBindingOverrides, n as FRAMEWORK_SCAN_DIRS, t as DEFAULT_SCAN_DIRS, u as staticModuleReferences } from "./plugin-inference-DsARdQKE.mjs";
|
|
5
|
+
import { n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-DMvEeSau.mjs";
|
|
6
|
+
import { n as loadVoidAuthConfig } from "./config-D0GY5ItR.mjs";
|
|
7
|
+
import { c as isNodeTarget, d as readConfig, s as getDatabaseDialect } from "./config-Bx_1SpnO.mjs";
|
|
8
8
|
import { i as isMemberExpression, n as isIdentifier, r as isLiteral } from "./ast-CPGPjb0V.mjs";
|
|
9
9
|
import { t as isRouteEnabledForEnvironment } from "./parse-filename-CUbj-1MP.mjs";
|
|
10
|
-
import { r as
|
|
11
|
-
import { a as validateSsrEntries, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS } from "./entry-
|
|
12
|
-
import { r as hasEmailHandlers } from "./email-
|
|
13
|
-
import { i as resolveLayoutIds } from "./scan-C3uDzz6J.mjs";
|
|
14
|
-
import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, n as DEFAULT_SANDBOX_CLASS_NAME, r as SANDBOX_MIGRATION_TAG } from "./config-B_ggY-IO.mjs";
|
|
15
|
-
import { G as hasRevalidate, R as CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV, U as collectPages, W as collectRevalidate, _t as hasApiRoutes, et as resolveDistDir, gt as generateQueueResolverSource, it as resolveWorkerDirName, o as prerenderPages, s as prerenderPagesNode, u as SEND_EMAIL_BINDING, vt as hasDocumentRoutes, yt as resolveAssetRoutingPolicy, z as selectNativeVersionMetadataBinding } from "./deploy-Bqe1PYBw.mjs";
|
|
16
|
-
import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-vqY3pqwI.mjs";
|
|
17
|
-
import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-DlfR78Nu.mjs";
|
|
18
|
-
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-BAm2aB6Q.mjs";
|
|
19
|
-
import { a as restoreCloudflarePreviewPointer, r as materializeCloudflareConfig, s as stashCloudflareDeployPointer } from "./cloudflare-config-BmhBv3HV.mjs";
|
|
20
|
-
import { D as syncWranglerBindings, E as resolveLiveBindingConfig, O as syncWranglerDurableObjects, T as readWranglerWebSocketTombstones, a as LIVE_MIGRATION_TAG, d as ensureWranglerCompatibilityDate, f as ensureWranglerNodejsAlsFlag, g as normalizeWranglerCompatibilityFlags, h as nextDurableObjectMigrationTag, k as syncWranglerWebSockets, m as hasDurableObjectSqliteMigration, p as findBindingNameOwner, u as ensureWranglerCompat, v as readExistingLiveBindingConfig, x as readWranglerCompat } from "./wrangler-D9KTuqnv.mjs";
|
|
21
|
-
import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-ga5O_idV.mjs";
|
|
22
|
-
import { n as scopedAccessCredentials } from "./cf-access-TWNzXltp.mjs";
|
|
23
|
-
import { r as ensurePlatformProxyAccess } from "./cf-access-BcIBSKqG.mjs";
|
|
24
|
-
import { a as getApiUrl, c as getToken, o as getProxyUrl } from "./auth-Dn2vw-SG.mjs";
|
|
25
|
-
import { d as printSuccess } from "./output-C50ag2r3.mjs";
|
|
26
|
-
import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-CVJhNMxs.mjs";
|
|
27
|
-
import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-CbtsIeFn.mjs";
|
|
28
|
-
import { t as discoverSchema } from "./discover-CkCYv9T_.mjs";
|
|
29
|
-
import { _ as listDevMessages, a as DEV_INBOX_ENV_VAR, b as registerEmailSink, c as DEV_INBOX_TOKEN_ENV_VAR, h as findDevMessage, l as DEV_INBOX_TOKEN_HEADER, n as DEV_INBOX_ACK_VALUE, o as DEV_INBOX_MAX_CAPTURE_BYTES, p as clearDevBuffer, s as DEV_INBOX_PREFIX, t as DEV_INBOX_ACK_HEADER, u as DEV_INBOX_TOKEN_QUERY, v as parseCapturedMessage, y as pushToDevBuffer } from "./dev-inbox-CK-UuPob.mjs";
|
|
10
|
+
import { a as hasSandboxSqliteMigration, c as sandboxContainerConfig, i as assertSandboxNamespaceConfig, n as DEFAULT_SANDBOX_CLASS_NAME, p as scanJobsSync, r as SANDBOX_MIGRATION_TAG, s as resolveSandboxConfig, t as analyzeApplicationSync, u as scanQueuesSync } from "./application-analysis-AB_YYWgH.mjs";
|
|
11
|
+
import { a as validateSsrEntries, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS } from "./entry-ehmBvs5w.mjs";
|
|
12
|
+
import { r as hasEmailHandlers } from "./email-BcjSyAL0.mjs";
|
|
30
13
|
import { t as MagicString } from "./dist-Cegxq8gs.mjs";
|
|
31
|
-
import {
|
|
32
|
-
import { a as
|
|
33
|
-
import { n as
|
|
34
|
-
import {
|
|
35
|
-
import { n as
|
|
36
|
-
import {
|
|
14
|
+
import { i as resolveLayoutIds } from "./scan-C0BMdmEd.mjs";
|
|
15
|
+
import { a as resolveDistDir, c as hasDocumentRoutes, n as collectRevalidate, o as resolveWorkerDirName, r as hasRevalidate, s as hasApiRoutes, t as collectPages, u as resolveAssetRoutingPolicy } from "./isr-config-fZaJJ8t7.mjs";
|
|
16
|
+
import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-vqY3pqwI.mjs";
|
|
17
|
+
import { n as mergeRoutingRules, t as lintRoutingPhases } from "./headers-Di1FsD3e.mjs";
|
|
18
|
+
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
19
|
+
import { a as restoreCloudflarePreviewPointer, r as materializeCloudflareConfig, s as stashCloudflareDeployPointer } from "./cloudflare-config-DV60XFFK.mjs";
|
|
20
|
+
import { D as syncWranglerBindings, E as resolveLiveBindingConfig, O as syncWranglerDurableObjects, T as readWranglerWebSocketTombstones, a as LIVE_MIGRATION_TAG, d as ensureWranglerCompatibilityDate, f as ensureWranglerNodejsAlsFlag, g as normalizeWranglerCompatibilityFlags, h as nextDurableObjectMigrationTag, k as syncWranglerWebSockets, m as hasDurableObjectSqliteMigration, p as findBindingNameOwner, u as ensureWranglerCompat, v as readExistingLiveBindingConfig, x as readWranglerCompat } from "./wrangler-BYs07Rxy.mjs";
|
|
21
|
+
import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-BxvQYEFi.mjs";
|
|
22
|
+
import { n as scopedAccessCredentials } from "./cf-access-BM9G0lhO.mjs";
|
|
23
|
+
import { n as ensurePlatformProxyAccess } from "./cf-access-CWP4avfP.mjs";
|
|
24
|
+
import { a as getApiUrl, c as getToken, o as getProxyUrl } from "./auth-B6iOCjKI.mjs";
|
|
25
|
+
import { m as printSuccess } from "./output-Ba6ZbrzY.mjs";
|
|
26
|
+
import { r as writeFileIfChanged } from "./project-tsconfig-bveqhlYA.mjs";
|
|
27
|
+
import { n as drizzlePlugin, t as generateQueueResolverSource } from "./dispatch-DrTTk8Xg.mjs";
|
|
28
|
+
import { _ as parseCapturedMessage, a as DEV_INBOX_ENV_VAR, c as DEV_INBOX_TOKEN_ENV_VAR, f as clearDevBuffer, g as listDevMessages, l as DEV_INBOX_TOKEN_HEADER, m as findDevMessage, n as DEV_INBOX_ACK_VALUE, o as DEV_INBOX_MAX_CAPTURE_BYTES, s as DEV_INBOX_PREFIX, t as DEV_INBOX_ACK_HEADER, u as DEV_INBOX_TOKEN_QUERY, v as pushToDevBuffer } from "./dev-inbox-Rd6j_8vM.mjs";
|
|
29
|
+
import { n as scanWranglerDotenvKeys } from "./dotenv-CNazY3-w.mjs";
|
|
30
|
+
import { a as isClientEnvKey, c as resolveRemoteMode, i as findReservedEnvKeys, n as LOCAL_ENV_FILE, o as loadLocalEnv, r as findLegacyEnvFiles, s as reservedEnvKeysMessage } from "./env-BJjULvL0.mjs";
|
|
31
|
+
import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-DS2_y4X8.mjs";
|
|
32
|
+
import { t as loadUserEnvFile } from "./load-user-env-DD5qveNU.mjs";
|
|
33
|
+
import { n as INTERNAL_BINDING_PREFIXES, t as INTERNAL_BINDING_EXACT_NAMES } from "./env-raw-D74P4ebM.mjs";
|
|
34
|
+
import { t as ASSET_EXTENSIONS } from "./routing-assets-VkrKIbxE.mjs";
|
|
35
|
+
import { r as selectNativeVersionMetadataBinding, t as CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV } from "./version-metadata-DIrqEHQo.mjs";
|
|
36
|
+
import { f as prerenderPages, n as SEND_EMAIL_BINDING, p as prerenderPagesNode } from "./email-cloudflare-DfG6UEMm.mjs";
|
|
37
37
|
import { r as defer } from "./validation-error-Dg9Recn1.mjs";
|
|
38
|
-
import { i as safeJsonStringify } from "./protocol-
|
|
38
|
+
import { i as safeJsonStringify } from "./protocol-RNP0u7UY.mjs";
|
|
39
|
+
import { n as completeApplicationAnalysis } from "./application-routing-L7V-TFhZ.mjs";
|
|
39
40
|
import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-CF84FOVM.mjs";
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
41
|
+
import { n as generateQueueTypes, t as generateRouteTypes } from "./route-types-BZi26DVS.mjs";
|
|
42
|
+
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";
|
|
43
|
+
import module, { builtinModules, createRequire } from "node:module";
|
|
44
|
+
import { chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
|
|
42
45
|
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
43
46
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
44
|
-
import { loadEnv, normalizePath, parseSync, resolveEnvPrefix } from "vite";
|
|
47
|
+
import { defaultServerConditions, loadEnv, normalizePath, parseSync, resolveEnvPrefix } from "vite";
|
|
45
48
|
import { appendSqliteClassMigration } from "@void/deploy-core";
|
|
46
49
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
47
50
|
import { homedir } from "node:os";
|
|
48
51
|
import { isDeepStrictEqual, parseEnv } from "node:util";
|
|
49
|
-
import { compilePattern } from "@void/edge";
|
|
52
|
+
import { compilePattern, matchPattern } from "@void/edge";
|
|
50
53
|
//#region src/pages/dev-css-assets.ts
|
|
51
54
|
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
52
55
|
const DEV_CSS_ASSET_MODULE_ID = "virtual:void-pages-dev-assets";
|
|
@@ -139,11 +142,6 @@ function createOrderedEdgeStore(root) {
|
|
|
139
142
|
version++;
|
|
140
143
|
for (const key of aliasesForId(importer)) byKey.set(key, edges);
|
|
141
144
|
},
|
|
142
|
-
deleteForId(id) {
|
|
143
|
-
let deleted = false;
|
|
144
|
-
for (const key of aliasesForId(id)) deleted = byKey.delete(key) || deleted;
|
|
145
|
-
if (deleted) version++;
|
|
146
|
-
},
|
|
147
145
|
getForNode(node) {
|
|
148
146
|
const keys = [node.url, node.id].filter((value) => typeof value === "string");
|
|
149
147
|
for (const key of keys) {
|
|
@@ -491,11 +489,11 @@ function readVoidDevCredentials(root) {
|
|
|
491
489
|
* block the server. On completion, writes project.json and restarts the server.
|
|
492
490
|
*/
|
|
493
491
|
async function runAiSetupPrompt(root, token, apiUrl, server) {
|
|
494
|
-
const { select, text, isCancel, log } = await import("./dist-
|
|
495
|
-
const { PlatformClient } = await import("./client-
|
|
496
|
-
const { attachSelectedPlatform, writeProjectConfig } = await import("./project-
|
|
497
|
-
const { inferDefaultSlug } = await import("./resolve-project-
|
|
498
|
-
const client = new PlatformClient(token, apiUrl);
|
|
492
|
+
const { select, text, isCancel, log } = await import("./dist-CfgIkieS.mjs");
|
|
493
|
+
const { PlatformClient } = await import("./client-B60PwCC4.mjs");
|
|
494
|
+
const { attachSelectedPlatform, writeProjectConfig } = await import("./project-zdB3fs9G.mjs");
|
|
495
|
+
const { inferDefaultSlug } = await import("./resolve-project-PnhzMtY6.mjs");
|
|
496
|
+
const client = new PlatformClient(token, { apiUrl });
|
|
499
497
|
let projects;
|
|
500
498
|
try {
|
|
501
499
|
projects = await client.listProjects();
|
|
@@ -520,8 +518,8 @@ async function runAiSetupPrompt(root, token, apiUrl, server) {
|
|
|
520
518
|
let projectId;
|
|
521
519
|
let slug;
|
|
522
520
|
if (result === "__create__") {
|
|
523
|
-
const { validateProjectSlug } = await import("./project-slug-
|
|
524
|
-
const { createProjectWithSlugRetry } = await import("./create-project-
|
|
521
|
+
const { validateProjectSlug } = await import("./project-slug-6cyz8E7k.mjs");
|
|
522
|
+
const { createProjectWithSlugRetry } = await import("./create-project-B-ewF_Af.mjs");
|
|
525
523
|
let created;
|
|
526
524
|
try {
|
|
527
525
|
created = await createProjectWithSlugRetry(client, inferDefaultSlug(root), async (defaultSlug) => {
|
|
@@ -546,7 +544,7 @@ async function runAiSetupPrompt(root, token, apiUrl, server) {
|
|
|
546
544
|
projectId = project.id;
|
|
547
545
|
slug = project.slug;
|
|
548
546
|
}
|
|
549
|
-
writeProjectConfig(root, attachSelectedPlatform(
|
|
547
|
+
writeProjectConfig(root, attachSelectedPlatform({
|
|
550
548
|
projectId,
|
|
551
549
|
slug
|
|
552
550
|
}, client.apiUrl));
|
|
@@ -555,7 +553,7 @@ async function runAiSetupPrompt(root, token, apiUrl, server) {
|
|
|
555
553
|
}
|
|
556
554
|
//#endregion
|
|
557
555
|
//#region src/plugin-binding-runtime.ts
|
|
558
|
-
const envModuleResolved
|
|
556
|
+
const envModuleResolved = fileURLToPath(import.meta.resolve("#self/_env"));
|
|
559
557
|
const kvModuleResolved = fileURLToPath(import.meta.resolve("void/kv"));
|
|
560
558
|
const storageModuleResolved = fileURLToPath(import.meta.resolve("void/storage"));
|
|
561
559
|
const VIRTUAL_KV_ID = "\0virtual:void-kv";
|
|
@@ -576,7 +574,7 @@ function bindingRuntimePlugin(bindingNames) {
|
|
|
576
574
|
filter: { id: /^\0virtual:void-(?:kv|storage)$/ },
|
|
577
575
|
handler(id) {
|
|
578
576
|
if (id === VIRTUAL_KV_ID) return `
|
|
579
|
-
import { requireRuntimeBinding } from ${JSON.stringify(envModuleResolved
|
|
577
|
+
import { requireRuntimeBinding } from ${JSON.stringify(envModuleResolved)};
|
|
580
578
|
import { createKV } from ${JSON.stringify(kvModuleResolved)};
|
|
581
579
|
|
|
582
580
|
const namespace = new Proxy({}, {
|
|
@@ -591,7 +589,7 @@ export { createKV };
|
|
|
591
589
|
export const kv = createKV(namespace);
|
|
592
590
|
`;
|
|
593
591
|
if (id === VIRTUAL_STORAGE_ID) return `
|
|
594
|
-
import { requireRuntimeBinding } from ${JSON.stringify(envModuleResolved
|
|
592
|
+
import { requireRuntimeBinding } from ${JSON.stringify(envModuleResolved)};
|
|
595
593
|
export { createStorage } from ${JSON.stringify(storageModuleResolved)};
|
|
596
594
|
|
|
597
595
|
export const storage = new Proxy({}, {
|
|
@@ -699,6 +697,19 @@ function isViteBuildOrPreview() {
|
|
|
699
697
|
const subcommand = process.argv[2];
|
|
700
698
|
return subcommand === "build" || subcommand === "preview";
|
|
701
699
|
}
|
|
700
|
+
/**
|
|
701
|
+
* Point Cloudflare remote bindings opened in this process at the login from
|
|
702
|
+
* `void connect` and `void cloudflare login`. The Cloudflare Vite plugin and
|
|
703
|
+
* Wrangler's platform proxy authenticate remote bindings here, in dev, preview
|
|
704
|
+
* and build prerendering. They read cf's login only when `CLOUDFLARE_CF_AUTH`
|
|
705
|
+
* is present (any value), and Wrangler's separate login otherwise. The keyring
|
|
706
|
+
* flag selects the encrypted cf profile that Void's login writes. Environment
|
|
707
|
+
* API tokens still take precedence, and the OAuth token stays in the store.
|
|
708
|
+
*/
|
|
709
|
+
function selectVoidCloudflareLogin() {
|
|
710
|
+
process.env.CLOUDFLARE_CF_AUTH = "true";
|
|
711
|
+
process.env.CLOUDFLARE_AUTH_USE_KEYRING = "true";
|
|
712
|
+
}
|
|
702
713
|
const DEV_TRIGGER_TOKEN_FILE_MODE = 384;
|
|
703
714
|
/**
|
|
704
715
|
* Persist the dev-trigger token at `<root>/.void/dev-trigger-token` so
|
|
@@ -832,15 +843,14 @@ function warnIfPackageJsonIsNotEsm(root) {
|
|
|
832
843
|
* and framework mode (SvelteKit, Nuxt, Analog, Astro, TanStack Start, React
|
|
833
844
|
* Router, vinext) expose `/__void/scheduled` and `/__void/queue`.
|
|
834
845
|
*/
|
|
835
|
-
function devTriggersHintPlugin(root,
|
|
836
|
-
const { devTriggerToken } = options;
|
|
846
|
+
function devTriggersHintPlugin(root, devTriggerToken) {
|
|
837
847
|
return {
|
|
838
848
|
name: "void:dev-triggers-hint",
|
|
839
849
|
apply: "serve",
|
|
840
850
|
configureServer(server) {
|
|
841
851
|
const paths = readProjectPaths(root);
|
|
842
|
-
const jobs = scanJobsSync(
|
|
843
|
-
const queues = scanQueuesSync(
|
|
852
|
+
const jobs = scanJobsSync(paths.cronsDir);
|
|
853
|
+
const queues = scanQueuesSync(paths.queuesDir);
|
|
844
854
|
if (jobs.length === 0 && queues.length === 0) return;
|
|
845
855
|
afterServerReady(server, () => {
|
|
846
856
|
const address = server.httpServer?.address();
|
|
@@ -866,206 +876,6 @@ function devTriggersHintPlugin(root, options) {
|
|
|
866
876
|
};
|
|
867
877
|
}
|
|
868
878
|
//#endregion
|
|
869
|
-
//#region src/plugin-drizzle.ts
|
|
870
|
-
const drizzleD1Resolved = fileURLToPath(import.meta.resolve("drizzle-orm/d1"));
|
|
871
|
-
const drizzleOrmResolved = fileURLToPath(import.meta.resolve("drizzle-orm"));
|
|
872
|
-
const envModuleResolved = fileURLToPath(import.meta.resolve("#self/_env"));
|
|
873
|
-
const drizzleNodePgResolved = fileURLToPath(import.meta.resolve("drizzle-orm/node-postgres"));
|
|
874
|
-
const drizzleMysql2Resolved = fileURLToPath(import.meta.resolve("drizzle-orm/mysql2"));
|
|
875
|
-
const pgResolved = fileURLToPath(import.meta.resolve("pg"));
|
|
876
|
-
const mysql2Resolved = fileURLToPath(import.meta.resolve("mysql2"));
|
|
877
|
-
const VIRTUAL_DB_ID = "\0virtual:void-db";
|
|
878
|
-
const VIRTUAL_SCHEMA_DB_ID = "\0virtual:void-db-schema";
|
|
879
|
-
/**
|
|
880
|
-
* Vite plugin for Drizzle integration.
|
|
881
|
-
*
|
|
882
|
-
* - Intercepts `void/db` imports in SSR/worker environments and serves
|
|
883
|
-
* a virtual module that creates a Drizzle DB instance, using the user's
|
|
884
|
-
* schema when present.
|
|
885
|
-
* - Generates `.void/db.d.ts` with proper Drizzle types.
|
|
886
|
-
* - Sets up `@schema` Vite alias for convenient imports when a schema exists.
|
|
887
|
-
* - Updates `.void/tsconfig.json` with TypeScript paths.
|
|
888
|
-
*/
|
|
889
|
-
function drizzlePlugin(root, hasRouteTypes, dialect = "sqlite", options = {}) {
|
|
890
|
-
const outDir = join(root, ".void");
|
|
891
|
-
const paths = readProjectPaths(root);
|
|
892
|
-
const schema = discoverSchema(root, paths);
|
|
893
|
-
const hasDbRuntime = schema != null || options.forceVirtualDb === true;
|
|
894
|
-
const d1BindingName = options.d1BindingName ?? "DB";
|
|
895
|
-
ensureProjectTsconfig(root, hasRouteTypes, hasDbRuntime, schema != null, {
|
|
896
|
-
redirectDbModule: options.redirectDbTypePaths,
|
|
897
|
-
paths
|
|
898
|
-
});
|
|
899
|
-
if (hasDbRuntime) generateDbDts(outDir, schema ?? null, dialect);
|
|
900
|
-
let isBuild = false;
|
|
901
|
-
return {
|
|
902
|
-
name: "void:drizzle",
|
|
903
|
-
enforce: "pre",
|
|
904
|
-
config(_, env) {
|
|
905
|
-
isBuild = env.command === "build";
|
|
906
|
-
if (!schema) return;
|
|
907
|
-
return { resolve: { alias: { "@schema": schema.path } } };
|
|
908
|
-
},
|
|
909
|
-
resolveId: {
|
|
910
|
-
filter: { id: /^(void\/db|@schema|pg$)/ },
|
|
911
|
-
handler(id, importer) {
|
|
912
|
-
if (id === "pg" && isBuild && dialect === "postgresql" && importer === VIRTUAL_DB_ID) return pgResolved;
|
|
913
|
-
if (id === "void/db" && this.environment?.name !== "client") {
|
|
914
|
-
if (!hasDbRuntime) return;
|
|
915
|
-
if (schema && importer) {
|
|
916
|
-
const normalizedImporter = normalizePath(importer);
|
|
917
|
-
const normalizedSchemaPath = normalizePath(schema.path);
|
|
918
|
-
if (schema.type === "file" && normalizedImporter === normalizedSchemaPath) return VIRTUAL_SCHEMA_DB_ID;
|
|
919
|
-
if (schema.type === "directory" && normalizedImporter.startsWith(normalizedSchemaPath)) return VIRTUAL_SCHEMA_DB_ID;
|
|
920
|
-
}
|
|
921
|
-
return VIRTUAL_DB_ID;
|
|
922
|
-
}
|
|
923
|
-
if (schema && (id === "@schema" || id.startsWith("@schema/"))) {
|
|
924
|
-
if (id === "@schema") return schema.path;
|
|
925
|
-
return join(schema.path, id.slice(8));
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
},
|
|
929
|
-
load: {
|
|
930
|
-
filter: { id: /^\0virtual:void-db(?:-schema)?$/ },
|
|
931
|
-
handler(id) {
|
|
932
|
-
if (id === VIRTUAL_SCHEMA_DB_ID) return `
|
|
933
|
-
export { ${DRIZZLE_OPERATORS} } from ${JSON.stringify(drizzleOrmResolved)};
|
|
934
|
-
export const db = {};
|
|
935
|
-
export function createDb() {
|
|
936
|
-
throw new Error("db: createDb() is unavailable when importing void/db from a schema file.");
|
|
937
|
-
}
|
|
938
|
-
`;
|
|
939
|
-
const schemaImport = schema ? `import * as schema from ${JSON.stringify(schema.path)};` : "";
|
|
940
|
-
const drizzleConfig = schema ? dialect === "mysql" ? ", { schema, mode: \"default\" }" : ", { schema }" : "";
|
|
941
|
-
if (dialect === "mysql") return `
|
|
942
|
-
import { drizzle } from ${JSON.stringify(drizzleMysql2Resolved)};
|
|
943
|
-
import { createPool } from ${JSON.stringify(mysql2Resolved)};
|
|
944
|
-
import { getRuntimeBinding, getRuntimeRequestResource } from ${JSON.stringify(envModuleResolved)};
|
|
945
|
-
${schemaImport}
|
|
946
|
-
export { ${DRIZZLE_OPERATORS} } from ${JSON.stringify(drizzleOrmResolved)};
|
|
947
|
-
|
|
948
|
-
const _requestResourceKey = {};
|
|
949
|
-
|
|
950
|
-
function getConnectionString() {
|
|
951
|
-
const url = getRuntimeBinding("DATABASE_URL");
|
|
952
|
-
if (url) return url;
|
|
953
|
-
const hd = getRuntimeBinding("HYPERDRIVE");
|
|
954
|
-
if (hd?.connectionString) return hd.connectionString;
|
|
955
|
-
throw new Error("db: MySQL is not configured. Add DATABASE_URL to .env for local dev, or configure Hyperdrive for production.");
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
function getInstance() {
|
|
959
|
-
return getRuntimeRequestResource(_requestResourceKey, () => {
|
|
960
|
-
const pool = createPool({
|
|
961
|
-
uri: getConnectionString(),
|
|
962
|
-
connectionLimit: 1,
|
|
963
|
-
maxIdle: 1,
|
|
964
|
-
idleTimeout: 1000,
|
|
965
|
-
});
|
|
966
|
-
return drizzle(pool${drizzleConfig});
|
|
967
|
-
});
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
export const db = new Proxy({}, {
|
|
971
|
-
get(_, prop) {
|
|
972
|
-
return Reflect.get(getInstance(), prop);
|
|
973
|
-
},
|
|
974
|
-
});
|
|
975
|
-
|
|
976
|
-
export function createDb(connectionString) {
|
|
977
|
-
return drizzle(connectionString${drizzleConfig});
|
|
978
|
-
}
|
|
979
|
-
`;
|
|
980
|
-
if (dialect === "postgresql") return `
|
|
981
|
-
import { drizzle } from ${JSON.stringify(drizzleNodePgResolved)};
|
|
982
|
-
import pg from "pg";
|
|
983
|
-
import { getRuntimeBinding, getRuntimeRequestResource } from ${JSON.stringify(envModuleResolved)};
|
|
984
|
-
${schemaImport}
|
|
985
|
-
export { ${DRIZZLE_OPERATORS} } from ${JSON.stringify(drizzleOrmResolved)};
|
|
986
|
-
|
|
987
|
-
const _requestResourceKey = {};
|
|
988
|
-
|
|
989
|
-
function getConnectionString() {
|
|
990
|
-
const url = getRuntimeBinding("DATABASE_URL");
|
|
991
|
-
if (url) return url;
|
|
992
|
-
const hd = getRuntimeBinding("HYPERDRIVE");
|
|
993
|
-
if (hd?.connectionString) return hd.connectionString;
|
|
994
|
-
throw new Error("db: PostgreSQL is not configured. Add DATABASE_URL to .env for local dev, or configure Hyperdrive for production.");
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
function getInstance() {
|
|
998
|
-
return getRuntimeRequestResource(_requestResourceKey, () => {
|
|
999
|
-
const pool = new pg.Pool({
|
|
1000
|
-
connectionString: getConnectionString(),
|
|
1001
|
-
max: 1,
|
|
1002
|
-
idleTimeoutMillis: 1000,
|
|
1003
|
-
});
|
|
1004
|
-
return drizzle(pool${drizzleConfig});
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
export const db = new Proxy({}, {
|
|
1009
|
-
get(_, prop) {
|
|
1010
|
-
return Reflect.get(getInstance(), prop);
|
|
1011
|
-
},
|
|
1012
|
-
});
|
|
1013
|
-
|
|
1014
|
-
export function createDb(connectionString) {
|
|
1015
|
-
return drizzle(connectionString${drizzleConfig});
|
|
1016
|
-
}
|
|
1017
|
-
`;
|
|
1018
|
-
return `
|
|
1019
|
-
import { drizzle } from ${JSON.stringify(drizzleD1Resolved)};
|
|
1020
|
-
import { getRuntimeRequestResource, requireRuntimeBinding } from ${JSON.stringify(envModuleResolved)};
|
|
1021
|
-
${schemaImport}
|
|
1022
|
-
export { ${DRIZZLE_OPERATORS} } from ${JSON.stringify(drizzleOrmResolved)};
|
|
1023
|
-
|
|
1024
|
-
const _requestResourceKey = {};
|
|
1025
|
-
|
|
1026
|
-
export const db = new Proxy({}, {
|
|
1027
|
-
get(_, prop) {
|
|
1028
|
-
const instance = getRuntimeRequestResource(
|
|
1029
|
-
_requestResourceKey,
|
|
1030
|
-
() => createDb(requireRuntimeBinding(${JSON.stringify(d1BindingName)})),
|
|
1031
|
-
() => createPrimaryDb(requireRuntimeBinding(${JSON.stringify(d1BindingName)}))
|
|
1032
|
-
);
|
|
1033
|
-
return Reflect.get(instance, prop);
|
|
1034
|
-
},
|
|
1035
|
-
});
|
|
1036
|
-
|
|
1037
|
-
export function createDb(d1) {
|
|
1038
|
-
return drizzle(d1.withSession("first-unconstrained")${drizzleConfig});
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
function createPrimaryDb(d1) {
|
|
1042
|
-
return drizzle(d1.withSession("first-primary")${drizzleConfig});
|
|
1043
|
-
}
|
|
1044
|
-
`;
|
|
1045
|
-
}
|
|
1046
|
-
},
|
|
1047
|
-
async configureServer(server) {
|
|
1048
|
-
if (!schema) return;
|
|
1049
|
-
const migrationsDir = paths.migrationsDir;
|
|
1050
|
-
if (!(existsSync(migrationsDir) && readdirSync(migrationsDir).some((f) => f.endsWith(".sql")))) {
|
|
1051
|
-
if (dialect === "sqlite") {
|
|
1052
|
-
const { getApplicationTables, getMiniflareDatabasePath } = await import("./runner-9wjsSZx-.mjs");
|
|
1053
|
-
if ((await getApplicationTables(getMiniflareDatabasePath(options.localD1PersistRoot ?? join(root, ".void"), options.localD1DatabaseId ?? "local")).catch(() => [])).length > 0) return;
|
|
1054
|
-
}
|
|
1055
|
-
voidWarn(`Schema found but no migrations in ${paths.sourceRelative("db/migrations")}/.\n \`void db push\` syncs the schema to your local DB without creating migration files.
|
|
1056
|
-
Run \`void db generate\` to create migration files for dev startup and deploy.`);
|
|
1057
|
-
}
|
|
1058
|
-
const watchPath = schema.path;
|
|
1059
|
-
const regenerate = (path) => {
|
|
1060
|
-
if (path === watchPath || schema.type === "directory" && path.startsWith(watchPath)) generateDbDts(outDir, schema, dialect);
|
|
1061
|
-
};
|
|
1062
|
-
server.watcher.on("change", regenerate);
|
|
1063
|
-
server.watcher.on("add", regenerate);
|
|
1064
|
-
server.watcher.on("unlink", regenerate);
|
|
1065
|
-
}
|
|
1066
|
-
};
|
|
1067
|
-
}
|
|
1068
|
-
//#endregion
|
|
1069
879
|
//#region src/plugin-email-dev-inbox.ts
|
|
1070
880
|
const SECURITY_HEADERS = {
|
|
1071
881
|
"Cache-Control": "no-store",
|
|
@@ -1076,22 +886,11 @@ const SECURITY_HEADERS = {
|
|
|
1076
886
|
};
|
|
1077
887
|
function emailDevInboxPlugin(options) {
|
|
1078
888
|
const { devTriggerToken } = options;
|
|
1079
|
-
let unregister;
|
|
1080
889
|
/** `href` for an inbox path that keeps the browser session authorized. */
|
|
1081
890
|
const inboxHref = (path) => `${DEV_INBOX_PREFIX}${path}?${DEV_INBOX_TOKEN_QUERY}=${encodeURIComponent(devTriggerToken)}`;
|
|
1082
891
|
return {
|
|
1083
892
|
name: "void:email-dev-inbox",
|
|
1084
893
|
apply: "serve",
|
|
1085
|
-
buildStart() {
|
|
1086
|
-
if (unregister) return;
|
|
1087
|
-
unregister = registerEmailSink((m) => pushToDevBuffer(m));
|
|
1088
|
-
},
|
|
1089
|
-
buildEnd() {
|
|
1090
|
-
if (unregister) {
|
|
1091
|
-
unregister();
|
|
1092
|
-
unregister = void 0;
|
|
1093
|
-
}
|
|
1094
|
-
},
|
|
1095
894
|
configureServer(server) {
|
|
1096
895
|
const printInboxUrl = () => {
|
|
1097
896
|
const address = server.httpServer?.address();
|
|
@@ -1099,7 +898,7 @@ function emailDevInboxPlugin(options) {
|
|
|
1099
898
|
if (port == null) return;
|
|
1100
899
|
voidLog(`Email inbox: http://localhost:${port}${inboxHref("")}`);
|
|
1101
900
|
};
|
|
1102
|
-
|
|
901
|
+
afterServerReady(server, printInboxUrl);
|
|
1103
902
|
server.middlewares.use(DEV_INBOX_PREFIX, (req, res) => {
|
|
1104
903
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
1105
904
|
const path = url.pathname;
|
|
@@ -1537,38 +1336,24 @@ function pushHit(node, hits) {
|
|
|
1537
1336
|
* • Only folds static member access: `env.FOO` and `env["FOO"]`.
|
|
1538
1337
|
* Dynamic access, destructuring, and reassignment fall through to the
|
|
1539
1338
|
* runtime Proxy.
|
|
1540
|
-
* • Only folds keys with a known build-time value (build shell or schema
|
|
1541
|
-
* `.default(...)`). Unknown keys are left as-is
|
|
1339
|
+
* • Only folds keys with a known build-time value (build shell, or a schema
|
|
1340
|
+
* `.default(...)` that the env-schema plugin adds). Unknown keys are left as-is
|
|
1542
1341
|
* and the Proxy handles them at runtime — no "undefined" shoved in.
|
|
1543
1342
|
* • Build-only (`apply: 'build'`). Dev runs through the Proxy so local
|
|
1544
1343
|
* `.env` edits take effect without a full rebuild.
|
|
1545
1344
|
*/
|
|
1546
1345
|
function envClientFoldPlugin() {
|
|
1547
1346
|
let loadedEnv = {};
|
|
1548
|
-
const schemaDefaults = {};
|
|
1549
|
-
/** The merged view the transform consults for each key. */
|
|
1550
|
-
function resolveValue(key) {
|
|
1551
|
-
if (key in loadedEnv) return loadedEnv[key];
|
|
1552
|
-
if (key in schemaDefaults) return schemaDefaults[key];
|
|
1553
|
-
}
|
|
1554
1347
|
return {
|
|
1555
1348
|
name: "void:env-client-fold",
|
|
1556
1349
|
apply: "build",
|
|
1557
1350
|
enforce: "post",
|
|
1558
|
-
|
|
1351
|
+
configResolved(config) {
|
|
1559
1352
|
loadedEnv = config.env ?? {};
|
|
1560
|
-
try {
|
|
1561
|
-
const mod = await loadEnvPublic();
|
|
1562
|
-
if (mod._hasRegisteredSchema()) {
|
|
1563
|
-
const defaults = mod._getSchemaDefaults();
|
|
1564
|
-
for (const [key, value] of Object.entries(defaults)) if (isClientEnvKey(key) && !(key in loadedEnv)) schemaDefaults[key] = value;
|
|
1565
|
-
}
|
|
1566
|
-
} catch {}
|
|
1567
1353
|
},
|
|
1568
1354
|
async transform(code, id) {
|
|
1569
1355
|
if (this.environment?.name !== "client") return;
|
|
1570
1356
|
if (!isVoidEnvScriptCandidate(id, code)) return;
|
|
1571
|
-
if (Object.keys(loadedEnv).length === 0 && Object.keys(schemaDefaults).length === 0) return;
|
|
1572
1357
|
let parsed;
|
|
1573
1358
|
try {
|
|
1574
1359
|
parsed = parseSync(id, code);
|
|
@@ -1583,7 +1368,7 @@ function envClientFoldPlugin() {
|
|
|
1583
1368
|
let ms = null;
|
|
1584
1369
|
for (const hit of hits) {
|
|
1585
1370
|
if (!isClientEnvKey(hit.property)) continue;
|
|
1586
|
-
const value =
|
|
1371
|
+
const value = loadedEnv[hit.property];
|
|
1587
1372
|
if (value === void 0) continue;
|
|
1588
1373
|
if (!ms) ms = new MagicString(code);
|
|
1589
1374
|
ms.overwrite(hit.start, hit.end, JSON.stringify(value));
|
|
@@ -1791,7 +1576,6 @@ function envSchemaPlugin(root, options = {}) {
|
|
|
1791
1576
|
},
|
|
1792
1577
|
async configResolved(config) {
|
|
1793
1578
|
command = config.command;
|
|
1794
|
-
await emitSchemaFacts();
|
|
1795
1579
|
if (command === "build") stripLocalClientEnv(root, config, processEnvCopiesBefore);
|
|
1796
1580
|
await applyClientValuesToViteEnv(config);
|
|
1797
1581
|
if (command === "build" && envFile) {
|
|
@@ -1813,7 +1597,6 @@ function envSchemaPlugin(root, options = {}) {
|
|
|
1813
1597
|
},
|
|
1814
1598
|
async configureServer(server) {
|
|
1815
1599
|
if (!envFile) return;
|
|
1816
|
-
await importUserEnv();
|
|
1817
1600
|
afterServerReady(server, () => {
|
|
1818
1601
|
validateAndWarn();
|
|
1819
1602
|
});
|
|
@@ -1850,8 +1633,8 @@ function frameworkTriggersDispatchPath(root) {
|
|
|
1850
1633
|
*/
|
|
1851
1634
|
function writeFrameworkTriggersDispatch(root, devTriggerToken) {
|
|
1852
1635
|
const paths = readProjectPaths(root);
|
|
1853
|
-
const jobs = scanJobsSync(
|
|
1854
|
-
const queues = scanQueuesSync(
|
|
1636
|
+
const jobs = scanJobsSync(paths.cronsDir);
|
|
1637
|
+
const queues = scanQueuesSync(paths.queuesDir);
|
|
1855
1638
|
const target = frameworkTriggersDispatchPath(root);
|
|
1856
1639
|
mkdirSync(dirname(target), { recursive: true });
|
|
1857
1640
|
writeFileSync(target, generateModule(paths.cronsDir, paths.queuesDir, jobs, queues, devTriggerToken), { mode: DISPATCH_FILE_MODE });
|
|
@@ -2026,16 +1809,26 @@ export async function handleDevTrigger(request, env, ctx) {
|
|
|
2026
1809
|
}
|
|
2027
1810
|
`;
|
|
2028
1811
|
}
|
|
2029
|
-
/** Append any missing `lines` to the project's `.gitignore
|
|
1812
|
+
/** Append any missing `lines` to the project's `.gitignore` and return the appended ones. */
|
|
2030
1813
|
function ensureGitignoreLines(root, lines) {
|
|
2031
1814
|
const gitignorePath = join(root, ".gitignore");
|
|
2032
1815
|
let contents = "";
|
|
2033
1816
|
if (existsSync(gitignorePath)) contents = readFileSync(gitignorePath, "utf-8");
|
|
2034
1817
|
const existing = new Set(contents.split("\n").map((line) => line.trim()));
|
|
2035
1818
|
const missing = lines.filter((line) => !existing.has(line));
|
|
2036
|
-
if (missing.length === 0) return;
|
|
1819
|
+
if (missing.length === 0) return [];
|
|
2037
1820
|
const sep = contents.length === 0 || contents.endsWith("\n") ? "" : "\n";
|
|
2038
1821
|
writeFileSync(gitignorePath, `${contents}${sep}${missing.join("\n")}\n`);
|
|
1822
|
+
return missing;
|
|
1823
|
+
}
|
|
1824
|
+
/** Remove `lines` from the project's `.gitignore`, if it still exists. */
|
|
1825
|
+
function removeGitignoreLines(root, lines) {
|
|
1826
|
+
const gitignorePath = join(root, ".gitignore");
|
|
1827
|
+
if (lines.length === 0 || !existsSync(gitignorePath)) return;
|
|
1828
|
+
const contents = readFileSync(gitignorePath, "utf-8");
|
|
1829
|
+
const remove = new Set(lines);
|
|
1830
|
+
const next = contents.split("\n").filter((line) => !remove.has(line.trim())).join("\n");
|
|
1831
|
+
if (next !== contents) writeFileSync(gitignorePath, next);
|
|
2039
1832
|
}
|
|
2040
1833
|
const NITRO_MIDDLEWARE_FILENAME = "__void-dev-trigger.ts";
|
|
2041
1834
|
function nitroMiddlewareSource(dispatchPath) {
|
|
@@ -2236,6 +2029,17 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
2236
2029
|
});
|
|
2237
2030
|
`;
|
|
2238
2031
|
}
|
|
2032
|
+
const ASTRO_MIDDLEWARE_CLAIMS = Symbol.for("void.astroDevMiddleware.v1");
|
|
2033
|
+
/**
|
|
2034
|
+
* The dev servers in this process that use the middleware Void wrote, by file path. Astro restarts
|
|
2035
|
+
* the dev server in the same process with a fresh config, so a new plugin instance (from a new
|
|
2036
|
+
* copy of this module, too) is set up before the old server closes. Kept on `globalThis` so both
|
|
2037
|
+
* see the same claim.
|
|
2038
|
+
*/
|
|
2039
|
+
function astroMiddlewareClaims() {
|
|
2040
|
+
const store = globalThis;
|
|
2041
|
+
return store[ASTRO_MIDDLEWARE_CLAIMS] ??= /* @__PURE__ */ new Map();
|
|
2042
|
+
}
|
|
2239
2043
|
/**
|
|
2240
2044
|
* Writes a tiny Astro middleware to the user's project so
|
|
2241
2045
|
* `/__void/scheduled` and `/__void/queue` are intercepted inside Astro's
|
|
@@ -2245,31 +2049,54 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
2245
2049
|
* already has `src/middleware.ts` we don't overwrite it — instead we log a
|
|
2246
2050
|
* one-shot snippet they can paste into their existing middleware.
|
|
2247
2051
|
*
|
|
2248
|
-
* If we wrote the file we remove it
|
|
2249
|
-
* source tree stays clean.
|
|
2052
|
+
* If we wrote the file we remove it when the last dev server using it closes,
|
|
2053
|
+
* so the user's source tree stays clean. `src/middleware.ts` belongs to the
|
|
2054
|
+
* user, so the `.gitignore` line we add for it is removed too; otherwise a
|
|
2055
|
+
* middleware they write later would be silently left out of git.
|
|
2250
2056
|
*/
|
|
2251
2057
|
function astroDevTriggerInjectPlugin(root) {
|
|
2252
2058
|
const middlewarePath = join(root, ASTRO_MIDDLEWARE_RELATIVE);
|
|
2253
2059
|
const middlewareDirIndexPath = join(root, "src", "middleware", "index.ts");
|
|
2254
|
-
|
|
2060
|
+
const claims = astroMiddlewareClaims();
|
|
2061
|
+
/** Whether the dev server being set up now holds the middleware Void wrote. */
|
|
2255
2062
|
const ensureFile = () => {
|
|
2063
|
+
const claim = claims.get(middlewarePath);
|
|
2064
|
+
if (claim && existsSync(middlewarePath)) {
|
|
2065
|
+
claim.servers++;
|
|
2066
|
+
return true;
|
|
2067
|
+
}
|
|
2256
2068
|
if (existsSync(middlewarePath) || existsSync(middlewareDirIndexPath)) {
|
|
2257
2069
|
voidWarn("Astro middleware already exists. To enable /__void/scheduled and /__void/queue,\n add the Void dev-trigger middleware to your existing onRequest sequence.\n See https://void.cloud/guide/jobs#local-development.");
|
|
2258
|
-
return;
|
|
2070
|
+
return false;
|
|
2259
2071
|
}
|
|
2260
2072
|
mkdirSync(dirname(middlewarePath), { recursive: true });
|
|
2261
2073
|
writeFileSync(middlewarePath, astroMiddlewareSource(frameworkTriggersDispatchPath(root)));
|
|
2262
|
-
|
|
2074
|
+
if (claim) claim.servers++;
|
|
2075
|
+
else claims.set(middlewarePath, {
|
|
2076
|
+
servers: 1,
|
|
2077
|
+
gitignoreLines: ensureGitignoreLines(root, [ASTRO_MIDDLEWARE_RELATIVE])
|
|
2078
|
+
});
|
|
2079
|
+
return true;
|
|
2263
2080
|
};
|
|
2264
|
-
const
|
|
2265
|
-
|
|
2081
|
+
const release = () => {
|
|
2082
|
+
const claim = claims.get(middlewarePath);
|
|
2083
|
+
if (!claim || --claim.servers > 0) return;
|
|
2084
|
+
claims.delete(middlewarePath);
|
|
2085
|
+
rmSync(middlewarePath, { force: true });
|
|
2086
|
+
removeGitignoreLines(root, claim.gitignoreLines);
|
|
2266
2087
|
};
|
|
2267
2088
|
return {
|
|
2268
2089
|
name: "void:astro-dev-trigger-inject",
|
|
2269
2090
|
apply: "serve",
|
|
2270
2091
|
configureServer(server) {
|
|
2271
|
-
ensureFile();
|
|
2272
|
-
|
|
2092
|
+
if (!ensureFile()) return;
|
|
2093
|
+
let held = true;
|
|
2094
|
+
const cleanup = () => {
|
|
2095
|
+
if (held) {
|
|
2096
|
+
held = false;
|
|
2097
|
+
release();
|
|
2098
|
+
}
|
|
2099
|
+
};
|
|
2273
2100
|
server.httpServer?.once("close", cleanup);
|
|
2274
2101
|
process.once("exit", cleanup);
|
|
2275
2102
|
}
|
|
@@ -2285,7 +2112,6 @@ function pushDefaultErrorPageHelpers(lines, options) {
|
|
|
2285
2112
|
projectRoot: options.projectRoot,
|
|
2286
2113
|
homeDir: options.homeDir
|
|
2287
2114
|
})});`);
|
|
2288
|
-
lines.push("const serveCustomErrorPage = __errorRenderer.serveCustomPage;");
|
|
2289
2115
|
lines.push("app.onError(__errorRenderer.onError);");
|
|
2290
2116
|
}
|
|
2291
2117
|
/**
|
|
@@ -2312,8 +2138,8 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2312
2138
|
];
|
|
2313
2139
|
if (webSockets.length > 0) authImports.push("resolveVoidAuthState as __resolveVoidAuthStateRuntime");
|
|
2314
2140
|
lines.push(`import { ${authImports.join(", ")} } from ${JSON.stringify(auth.authRuntimePath)};`);
|
|
2315
|
-
|
|
2316
|
-
|
|
2141
|
+
lines.push(`import { __voidAuthDatabase } from ${JSON.stringify(auth.authDatabasePath)};`);
|
|
2142
|
+
lines.push(`import { migrationSchema as __voidAuthMigrationSchema } from ${JSON.stringify(auth.authSchemaPath)};`);
|
|
2317
2143
|
if (auth.authConfigPath) lines.push(`import __voidAuthConfig from ${JSON.stringify(auth.authConfigPath)};`);
|
|
2318
2144
|
}
|
|
2319
2145
|
if ((webSockets.length > 0 || options.webSocketTombstones?.length) && options.webSocketRuntimePath) lines.push(`import { createWebSocketDurableObject as __createWebSocketDurableObject, createWebSocketTombstoneDurableObject as __createWebSocketTombstoneDurableObject, forwardWebSocketRequest as __forwardWebSocketRequest } from ${JSON.stringify(options.webSocketRuntimePath)};`);
|
|
@@ -2330,39 +2156,10 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2330
2156
|
lines.push("");
|
|
2331
2157
|
if (auth) {
|
|
2332
2158
|
lines.push(`const __voidAuthOptions = { dialect: ${JSON.stringify(auth.dialect)}, providers: ${JSON.stringify(auth.providers)}, userConfig: ${auth.authConfigPath ? "__voidAuthConfig" : "undefined"}, dev: ${JSON.stringify(options.dev === true)} };`);
|
|
2333
|
-
if (webSockets.length > 0) lines.push(
|
|
2159
|
+
if (webSockets.length > 0) lines.push("const __resolveVoidAuthState = (request, env, runtime) => __resolveVoidAuthStateRuntime(request, env, runtime, __voidAuthDatabase);");
|
|
2334
2160
|
lines.push("");
|
|
2335
2161
|
}
|
|
2336
2162
|
lines.push(`const app = new Hono();`);
|
|
2337
|
-
const ASSET_EXTENSIONS = [
|
|
2338
|
-
"png",
|
|
2339
|
-
"jpg",
|
|
2340
|
-
"jpeg",
|
|
2341
|
-
"gif",
|
|
2342
|
-
"webp",
|
|
2343
|
-
"avif",
|
|
2344
|
-
"svg",
|
|
2345
|
-
"ico",
|
|
2346
|
-
"css",
|
|
2347
|
-
"js",
|
|
2348
|
-
"mjs",
|
|
2349
|
-
"cjs",
|
|
2350
|
-
"woff",
|
|
2351
|
-
"woff2",
|
|
2352
|
-
"ttf",
|
|
2353
|
-
"otf",
|
|
2354
|
-
"eot",
|
|
2355
|
-
"mp4",
|
|
2356
|
-
"webm",
|
|
2357
|
-
"mp3",
|
|
2358
|
-
"wav",
|
|
2359
|
-
"pdf",
|
|
2360
|
-
"txt",
|
|
2361
|
-
"xml",
|
|
2362
|
-
"json",
|
|
2363
|
-
"wasm",
|
|
2364
|
-
"map"
|
|
2365
|
-
];
|
|
2366
2163
|
const routePatterns = [];
|
|
2367
2164
|
for (const r of scan.routes) routePatterns.push(r.pattern);
|
|
2368
2165
|
if (pages && scan.pages.pages.length > 0) for (const p of scan.pages.pages) routePatterns.push(p.pattern);
|
|
@@ -2383,11 +2180,12 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2383
2180
|
lines.push("app.use(__routingRuntime.requestMiddleware);");
|
|
2384
2181
|
lines.push("");
|
|
2385
2182
|
const emitEdgeRules = !managedDispatch;
|
|
2183
|
+
const fallbackRulesJson = JSON.stringify(emitEdgeRules && options.fallbackRules?.length ? options.dev ? options.fallbackRules : stripOriginForProd(options.fallbackRules) : void 0);
|
|
2386
2184
|
if (emitEdgeRules && options.redirectRules?.length) compileRoutingRulesMiddleware(lines, options.redirectRules, options.dev === true);
|
|
2387
2185
|
if (emitEdgeRules && options.headerRules?.length) compileHeaderMiddleware(lines, options.headerRules);
|
|
2388
2186
|
if (auth) {
|
|
2389
2187
|
lines.push("app.use(async (c, next) => {");
|
|
2390
|
-
lines.push(
|
|
2188
|
+
lines.push(" return runVoidAuthMiddleware(c, next, __voidAuthOptions, __voidAuthDatabase);");
|
|
2391
2189
|
lines.push("});");
|
|
2392
2190
|
lines.push("");
|
|
2393
2191
|
}
|
|
@@ -2403,11 +2201,11 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2403
2201
|
if (webSockets.length > 0) lines.push("");
|
|
2404
2202
|
if (auth) {
|
|
2405
2203
|
lines.push("app.all(\"/api/auth\", async (c) => {");
|
|
2406
|
-
lines.push(
|
|
2204
|
+
lines.push(" return handleVoidAuthRequest(c, __voidAuthOptions, __voidAuthDatabase);");
|
|
2407
2205
|
lines.push("});");
|
|
2408
2206
|
lines.push("");
|
|
2409
2207
|
lines.push("app.all(\"/api/auth/*\", async (c) => {");
|
|
2410
|
-
lines.push(
|
|
2208
|
+
lines.push(" return handleVoidAuthRequest(c, __voidAuthOptions, __voidAuthDatabase);");
|
|
2411
2209
|
lines.push("});");
|
|
2412
2210
|
lines.push("");
|
|
2413
2211
|
}
|
|
@@ -2457,7 +2255,7 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2457
2255
|
if (pages && scan.pages.pages.length > 0) compilePageRoutes(lines, scan, pages, options);
|
|
2458
2256
|
for (let i = 0; i < webSockets.length; i++) lines.push(`app.all(${JSON.stringify(webSockets[i].pattern)}, (c) => __forwardWebSocketRequest(c.req.raw, c.env, __voidWebSocketRoutes[${i}]));`);
|
|
2459
2257
|
if (webSockets.length > 0) lines.push("");
|
|
2460
|
-
if (pages && scan.pages.pages.length > 0) lines.push(`app.notFound(__createPagesFallback({ routing: __routingRuntime, errors: __errorRenderer, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${
|
|
2258
|
+
if (pages && scan.pages.pages.length > 0) lines.push(`app.notFound(__createPagesFallback({ routing: __routingRuntime, errors: __errorRenderer, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${fallbackRulesJson} }));`);
|
|
2461
2259
|
compilePrerenderCollector(lines, scan, ssr, options);
|
|
2462
2260
|
if (ssr) {
|
|
2463
2261
|
lines.push(`const getClientAssetTags = __createClientAssetTags(${JSON.stringify({
|
|
@@ -2467,8 +2265,8 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2467
2265
|
dev: options.dev === true,
|
|
2468
2266
|
reactRefresh: options.reactRefresh
|
|
2469
2267
|
})});`);
|
|
2470
|
-
lines.push(`app.notFound(__createSsrFallback({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${
|
|
2471
|
-
} else if (emitEdgeRules && (options.fallbackRules?.length || !options.nodeTarget && options.headerRules?.length) && !(pages && scan.pages.pages.length > 0)) lines.push(`app.notFound(__createAssetNotFound({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${
|
|
2268
|
+
lines.push(`app.notFound(__createSsrFallback({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${fallbackRulesJson}, load: () => import(${JSON.stringify(ssr.serverEntryPath)}), assets: getClientAssetTags }));`);
|
|
2269
|
+
} else if (emitEdgeRules && (options.fallbackRules?.length || !options.nodeTarget && options.headerRules?.length) && !(pages && scan.pages.pages.length > 0)) lines.push(`app.notFound(__createAssetNotFound({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${fallbackRulesJson} }));`);
|
|
2472
2270
|
if (scan.jobs.length > 0) {
|
|
2473
2271
|
for (let i = 0; i < scan.jobs.length; i++) {
|
|
2474
2272
|
const job = scan.jobs[i];
|
|
@@ -2502,14 +2300,18 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2502
2300
|
lines.push("export async function scheduled() {}");
|
|
2503
2301
|
lines.push("");
|
|
2504
2302
|
}
|
|
2505
|
-
if (scan.jobs.length > 0) {
|
|
2506
|
-
lines.push("
|
|
2303
|
+
if (scan.jobs.length > 0 || scan.queues.length > 0) {
|
|
2304
|
+
lines.push("function __voidTriggerUnauthorized(c) {");
|
|
2507
2305
|
lines.push(" const __token = c.req.header(\"x-void-internal\");");
|
|
2508
2306
|
lines.push(" const __expected = __getRawEnv()?.__VOID_PROXY_TOKEN;");
|
|
2509
2307
|
lines.push(" const __devToken = c.req.header(\"x-void-dev-trigger\");");
|
|
2510
|
-
lines.push("
|
|
2511
|
-
lines.push("
|
|
2512
|
-
lines.push("
|
|
2308
|
+
lines.push(" return __VOID_SERVE ? __devToken !== __VOID_DEV_TRIGGER_TOKEN : __expected ? __token !== __expected : __token !== __VOID_BUILD_KEY;");
|
|
2309
|
+
lines.push("}");
|
|
2310
|
+
lines.push("");
|
|
2311
|
+
}
|
|
2312
|
+
if (scan.jobs.length > 0) {
|
|
2313
|
+
lines.push("const __scheduledHandler = async (c) => {");
|
|
2314
|
+
lines.push(" if (__voidTriggerUnauthorized(c)) return c.json({ error: \"unauthorized\" }, 401);");
|
|
2513
2315
|
lines.push(" const { cron, scheduledTime } = await c.req.json();");
|
|
2514
2316
|
lines.push(" const controller = { cron, scheduledTime, noRetry() {} };");
|
|
2515
2317
|
lines.push(" await scheduled(controller, c.env, c.executionCtx);");
|
|
@@ -2560,12 +2362,7 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2560
2362
|
lines.push("}");
|
|
2561
2363
|
lines.push("");
|
|
2562
2364
|
lines.push("const __queueHandler = async (c) => {");
|
|
2563
|
-
lines.push("
|
|
2564
|
-
lines.push(" const __expected = __getRawEnv()?.__VOID_PROXY_TOKEN;");
|
|
2565
|
-
lines.push(" const __devToken = c.req.header(\"x-void-dev-trigger\");");
|
|
2566
|
-
lines.push(" if (__VOID_SERVE ? __devToken !== __VOID_DEV_TRIGGER_TOKEN : __expected ? __token !== __expected : __token !== __VOID_BUILD_KEY) {");
|
|
2567
|
-
lines.push(" return c.json({ error: \"unauthorized\" }, 401);");
|
|
2568
|
-
lines.push(" }");
|
|
2365
|
+
lines.push(" if (__voidTriggerUnauthorized(c)) return c.json({ error: \"unauthorized\" }, 401);");
|
|
2569
2366
|
lines.push(" const payload = await c.req.json();");
|
|
2570
2367
|
lines.push(" const result = await __processQueue(payload, c.env);");
|
|
2571
2368
|
lines.push(" return c.json(result);");
|
|
@@ -2635,19 +2432,17 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2635
2432
|
lines.push(`import { createMigrationHandler as __createMigrationHandler } from ${JSON.stringify(options.migrationHandlerPath)};`);
|
|
2636
2433
|
lines.push(`const __migrations = ${JSON.stringify(options.migrations)};`);
|
|
2637
2434
|
lines.push(`const __migrationPlanBundle = ${JSON.stringify(options.migrationPlanBundle)};`);
|
|
2638
|
-
lines.push(`const __migrationDialect = ${JSON.stringify(options.migrationDialect ?? "sqlite")};`);
|
|
2639
2435
|
if (d1BindingName) lines.push(`function __voidGetMigrationEnv() {
|
|
2640
2436
|
const env = __getRawEnv();
|
|
2641
2437
|
if (!env || env[${JSON.stringify(d1BindingName)}] == null) return env;
|
|
2642
2438
|
return { ...env, DB: env[${JSON.stringify(d1BindingName)}] };
|
|
2643
2439
|
}`);
|
|
2644
2440
|
else lines.push("function __voidGetMigrationEnv() { return __getRawEnv(); }");
|
|
2645
|
-
lines.push("function __voidCreateMigrationRequestHandler(
|
|
2441
|
+
lines.push("function __voidCreateMigrationRequestHandler(includeAuthMigrations, includePlanBundle) {");
|
|
2646
2442
|
lines.push(" return __createMigrationHandler(");
|
|
2647
2443
|
lines.push(" __voidGetMigrationEnv(),");
|
|
2648
2444
|
lines.push(" __migrations,");
|
|
2649
|
-
lines.push("
|
|
2650
|
-
if (auth) lines.push(` includeAuthMigrations ? () => runVoidAuthMigrations(new Request(request.url), __voidGetMigrationEnv(), __voidAuthOptions${auth.authSchemaPath ? ", __voidAuthMigrationSchema" : ""}) : undefined,`);
|
|
2445
|
+
if (auth) lines.push(" includeAuthMigrations ? () => runVoidAuthMigrations(__voidGetMigrationEnv(), __voidAuthOptions, __voidAuthMigrationSchema) : undefined,");
|
|
2651
2446
|
else lines.push(" undefined,");
|
|
2652
2447
|
lines.push(" includePlanBundle ? __migrationPlanBundle : undefined,");
|
|
2653
2448
|
lines.push(" );");
|
|
@@ -2655,77 +2450,29 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
|
|
|
2655
2450
|
lines.push("export async function __voidHandleInternalRoute(request) {");
|
|
2656
2451
|
lines.push(" const url = new URL(request.url);");
|
|
2657
2452
|
lines.push(" if (request.method === \"POST\" && url.pathname === \"/__void/migrate\") {");
|
|
2658
|
-
lines.push(` return __voidCreateMigrationRequestHandler(
|
|
2453
|
+
lines.push(` return __voidCreateMigrationRequestHandler(${auth ? "true" : "false"}, false)(request);`);
|
|
2659
2454
|
lines.push(" }");
|
|
2660
2455
|
lines.push(" if (request.method === \"GET\" && url.pathname === \"/__void/migrate/capabilities\") {");
|
|
2661
|
-
lines.push(` return __voidCreateMigrationRequestHandler(
|
|
2456
|
+
lines.push(` return __voidCreateMigrationRequestHandler(${auth ? "true" : "false"}, true)(request);`);
|
|
2662
2457
|
lines.push(" }");
|
|
2663
2458
|
lines.push(" if (request.method === \"POST\" && url.pathname === \"/__void/migrate/app\") {");
|
|
2664
|
-
lines.push(" return __voidCreateMigrationRequestHandler(
|
|
2459
|
+
lines.push(" return __voidCreateMigrationRequestHandler(false, true)(request);");
|
|
2665
2460
|
lines.push(" }");
|
|
2666
2461
|
lines.push(" if (request.method === \"GET\" && url.pathname.startsWith(\"/__void/migrate/app/attempt/\")) {");
|
|
2667
|
-
lines.push(" return __voidCreateMigrationRequestHandler(
|
|
2462
|
+
lines.push(" return __voidCreateMigrationRequestHandler(false, true)(request);");
|
|
2668
2463
|
lines.push(" }");
|
|
2669
2464
|
if (auth) {
|
|
2670
2465
|
lines.push(" if (request.method === \"POST\" && url.pathname === \"/__void/migrate/auth\") {");
|
|
2671
|
-
lines.push(" return __voidCreateMigrationRequestHandler(
|
|
2466
|
+
lines.push(" return __voidCreateMigrationRequestHandler(true, true)(request);");
|
|
2672
2467
|
lines.push(" }");
|
|
2673
2468
|
}
|
|
2674
2469
|
lines.push(" return null;");
|
|
2675
2470
|
lines.push("}");
|
|
2676
|
-
lines.push(
|
|
2677
|
-
lines.push("
|
|
2678
|
-
lines.push("
|
|
2679
|
-
lines.push("
|
|
2680
|
-
lines.push("
|
|
2681
|
-
if (auth) lines.push(` () => runVoidAuthMigrations(new Request(c.req.url), __voidGetMigrationEnv(), __voidAuthOptions${auth.authSchemaPath ? ", __voidAuthMigrationSchema" : ""}),`);
|
|
2682
|
-
else lines.push(" undefined,");
|
|
2683
|
-
lines.push(" );");
|
|
2684
|
-
lines.push(" return __voidMigrationHandler(c.req.raw);");
|
|
2685
|
-
lines.push("});");
|
|
2686
|
-
lines.push("app.get(\"/__void/migrate/capabilities\", async (c) => {");
|
|
2687
|
-
lines.push(" const __voidMigrationHandler = __createMigrationHandler(");
|
|
2688
|
-
lines.push(" __voidGetMigrationEnv(),");
|
|
2689
|
-
lines.push(" __migrations,");
|
|
2690
|
-
lines.push(" __migrationDialect,");
|
|
2691
|
-
if (auth) lines.push(` () => runVoidAuthMigrations(new Request(c.req.url), __voidGetMigrationEnv(), __voidAuthOptions${auth.authSchemaPath ? ", __voidAuthMigrationSchema" : ""}),`);
|
|
2692
|
-
else lines.push(" undefined,");
|
|
2693
|
-
lines.push(" __migrationPlanBundle,");
|
|
2694
|
-
lines.push(" );");
|
|
2695
|
-
lines.push(" return __voidMigrationHandler(c.req.raw);");
|
|
2696
|
-
lines.push("});");
|
|
2697
|
-
lines.push("app.post(\"/__void/migrate/app\", async (c) => {");
|
|
2698
|
-
lines.push(" const __voidMigrationHandler = __createMigrationHandler(");
|
|
2699
|
-
lines.push(" __voidGetMigrationEnv(),");
|
|
2700
|
-
lines.push(" __migrations,");
|
|
2701
|
-
lines.push(" __migrationDialect,");
|
|
2702
|
-
lines.push(" undefined,");
|
|
2703
|
-
lines.push(" __migrationPlanBundle,");
|
|
2704
|
-
lines.push(" );");
|
|
2705
|
-
lines.push(" return __voidMigrationHandler(c.req.raw);");
|
|
2706
|
-
lines.push("});");
|
|
2707
|
-
lines.push("app.get(\"/__void/migrate/app/attempt/:attemptId\", async (c) => {");
|
|
2708
|
-
lines.push(" const __voidMigrationHandler = __createMigrationHandler(");
|
|
2709
|
-
lines.push(" __voidGetMigrationEnv(),");
|
|
2710
|
-
lines.push(" __migrations,");
|
|
2711
|
-
lines.push(" __migrationDialect,");
|
|
2712
|
-
lines.push(" undefined,");
|
|
2713
|
-
lines.push(" __migrationPlanBundle,");
|
|
2714
|
-
lines.push(" );");
|
|
2715
|
-
lines.push(" return __voidMigrationHandler(c.req.raw);");
|
|
2716
|
-
lines.push("});");
|
|
2717
|
-
if (auth) {
|
|
2718
|
-
lines.push("app.post(\"/__void/migrate/auth\", async (c) => {");
|
|
2719
|
-
lines.push(" const __voidMigrationHandler = __createMigrationHandler(");
|
|
2720
|
-
lines.push(" __voidGetMigrationEnv(),");
|
|
2721
|
-
lines.push(" __migrations,");
|
|
2722
|
-
lines.push(" __migrationDialect,");
|
|
2723
|
-
lines.push(` () => runVoidAuthMigrations(new Request(c.req.url), __voidGetMigrationEnv(), __voidAuthOptions${auth.authSchemaPath ? ", __voidAuthMigrationSchema" : ""}),`);
|
|
2724
|
-
lines.push(" __migrationPlanBundle,");
|
|
2725
|
-
lines.push(" );");
|
|
2726
|
-
lines.push(" return __voidMigrationHandler(c.req.raw);");
|
|
2727
|
-
lines.push("});");
|
|
2728
|
-
}
|
|
2471
|
+
lines.push(`app.post("/__void/migrate", (c) => __voidCreateMigrationRequestHandler(${auth ? "true" : "false"}, false)(c.req.raw));`);
|
|
2472
|
+
lines.push(`app.get("/__void/migrate/capabilities", (c) => __voidCreateMigrationRequestHandler(${auth ? "true" : "false"}, true)(c.req.raw));`);
|
|
2473
|
+
lines.push("app.post(\"/__void/migrate/app\", (c) => __voidCreateMigrationRequestHandler(false, true)(c.req.raw));");
|
|
2474
|
+
lines.push("app.get(\"/__void/migrate/app/attempt/:attemptId\", (c) => __voidCreateMigrationRequestHandler(false, true)(c.req.raw));");
|
|
2475
|
+
if (auth) lines.push("app.post(\"/__void/migrate/auth\", (c) => __voidCreateMigrationRequestHandler(true, true)(c.req.raw));");
|
|
2729
2476
|
lines.push("");
|
|
2730
2477
|
} else {
|
|
2731
2478
|
lines.push("export async function __voidHandleInternalRoute() { return null; }");
|
|
@@ -2905,22 +2652,7 @@ function compilePageRoutes(lines, scan, pages, options) {
|
|
|
2905
2652
|
}
|
|
2906
2653
|
lines.push("");
|
|
2907
2654
|
}
|
|
2908
|
-
/**
|
|
2909
|
-
* Generate the asset fallthrough helper shared by native Void workers and
|
|
2910
|
-
* Class A framework wrappers. If the app returns 404, check ASSETS binding
|
|
2911
|
-
* for static files and set cache headers. Edge caching of hashed assets
|
|
2912
|
-
* happens at the dispatch layer (see design doc 0042).
|
|
2913
|
-
*
|
|
2914
|
-
* `notFound` is the RESOLVED `assetConfig.not_found_handling` for this build
|
|
2915
|
-
* (`resolveAssetRoutingPolicy`), and it decides what happens once the asset
|
|
2916
|
-
* binding has also answered 404. It is a separate argument from
|
|
2917
|
-
* `serveSpaFallback` because the two are not derived from each other: the
|
|
2918
|
-
* common worker-first app runs with `not_found_handling: 'none'` and STILL
|
|
2919
|
-
* wants the worker-side shell fallback (that is the whole reason the flag
|
|
2920
|
-
* exists). They are mutually exclusive in practice — `resolveAssetRoutingPolicy`
|
|
2921
|
-
* clears `workerSpaFallback` whenever an explicit `routing.notFound` asks for
|
|
2922
|
-
* anything other than the SPA shell.
|
|
2923
|
-
*/
|
|
2655
|
+
/** Asset fallthrough shared by native Void workers and Class A framework wrappers. */
|
|
2924
2656
|
function compileAssetFallbackHelper(assetsDir = "assets", serveSpaFallback = false, notFound = "none") {
|
|
2925
2657
|
return `import { createAssetFallback as __createAssetFallback } from ${JSON.stringify(ROUTING_RUNTIME_PATH)};
|
|
2926
2658
|
const serveWithAssets = __createAssetFallback(${JSON.stringify({
|
|
@@ -2930,9 +2662,6 @@ const serveWithAssets = __createAssetFallback(${JSON.stringify({
|
|
|
2930
2662
|
})});
|
|
2931
2663
|
`;
|
|
2932
2664
|
}
|
|
2933
|
-
function deriveEmailRuntimePath(runtimeEnvPath) {
|
|
2934
|
-
return runtimeEnvPath.replace(/_?env(\.[^/]+)?$/, (_m, ext) => "email" + (ext ?? ""));
|
|
2935
|
-
}
|
|
2936
2665
|
/**
|
|
2937
2666
|
* Generate the Worker entry module code.
|
|
2938
2667
|
* Re-exports the Hono app from the virtual module with an asset-serving
|
|
@@ -2948,7 +2677,7 @@ function deriveEmailRuntimePath(runtimeEnvPath) {
|
|
|
2948
2677
|
* proxy-backed versions.
|
|
2949
2678
|
*/
|
|
2950
2679
|
function compileWorkerEntry(options = {}) {
|
|
2951
|
-
const { hasQueues = false, versionMetadataBinding, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", runtimeEmailPath, envSchemaModule, sandbox, serveSpaFallback = false, hasEmail = false, live, dev = false, isr, notFound = "none", durableObjects = [] } = options;
|
|
2680
|
+
const { hasQueues = false, versionMetadataBinding, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", runtimeEmailPath = "void/email", envSchemaModule, sandbox, serveSpaFallback = false, hasEmail = false, live, dev = false, isr, notFound = "none", durableObjects = [] } = options;
|
|
2952
2681
|
const remotePath = remote?.remotePath;
|
|
2953
2682
|
const remoteBindingNames = JSON.stringify(remote?.bindingNames);
|
|
2954
2683
|
const createRemoteEnvCall = `createRemoteEnv(env${remote?.bindingNames ? `, ${remoteBindingNames}` : ""})`;
|
|
@@ -2986,29 +2715,15 @@ const __filterInternalBindings = (env) => __filterBindings(env, ${JSON.stringify
|
|
|
2986
2715
|
internalRoute: __voidHandleInternalRoute,
|
|
2987
2716
|
collectPrerenderPaths: __voidCollectPrerenderPaths${versionMetadataBinding ? ", versionMetadataBinding: " + JSON.stringify(versionMetadataBinding) : ""}${envSchemaModule ? ", validateEnv: _validateEnvOnce" : ""}${remotePath ? ", remoteEnv: (env) => " + createRemoteEnvCall : ""}${hasEmail ? ", emailReceipt: __handleEmailReceipt" : ""}${isr ? ", isr: { deploymentId: __VOID_ISR_DEPLOYMENT_ID, handle: (request, env, ctx, render) => handleIsr(request, env, ctx, { revalidate: __VOID_ISR_REVALIDATE, pages: __VOID_ISR_PAGES, pathRevalidate: __VOID_ISR_PATH_REVALIDATE, deploymentId: __VOID_ISR_DEPLOYMENT_ID, queryAllowlist: " + JSON.stringify(isr.queryAllowlist) + " }, render) }" : ""}
|
|
2988
2717
|
})`;
|
|
2989
|
-
const
|
|
2990
|
-
|
|
2991
|
-
${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
|
|
2992
|
-
return withRuntimeEnv(env, () => scheduled(controller, userEnv, ctx));
|
|
2993
|
-
}` : `async function handleScheduled(controller, env, ctx) {
|
|
2994
|
-
${envValidateCall}${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
|
|
2718
|
+
const remoteEnvSwap = remotePath ? ` if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};\n` : "";
|
|
2719
|
+
const scheduledHandler = `async function handleScheduled(controller, env, ctx) {
|
|
2720
|
+
${envValidateCall}${remoteEnvSwap}${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
|
|
2995
2721
|
return withRuntimeEnv(env, () => scheduled(controller, userEnv, ctx));
|
|
2996
2722
|
}`;
|
|
2997
2723
|
const emailImport = hasEmail ? ", __emailHandler" : "";
|
|
2998
|
-
const
|
|
2999
|
-
const
|
|
3000
|
-
|
|
3001
|
-
${envValidateCall} if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};
|
|
3002
|
-
const userEnv = __filterInternalBindings(env);
|
|
3003
|
-
const __relayed = typeof envelope.viaDomain === "string" && envelope.viaDomain.length > 0;
|
|
3004
|
-
const __slug = __relayed ? undefined : (typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined);
|
|
3005
|
-
const { message, getActions } = __createMessageProxy(envelope, { slug: __slug });
|
|
3006
|
-
await __withRawEnv(env, () => withRuntimeEnv(env, () => __emailHandler(message, userEnv, ctx, { slug: __slug })));
|
|
3007
|
-
const __actions = getActions();
|
|
3008
|
-
if (__isForwardableEmailMessage(envelope)) await __enactEmailActions(envelope, __actions);
|
|
3009
|
-
return __actions;
|
|
3010
|
-
}` : `async function handleEmail(envelope, env, ctx) {
|
|
3011
|
-
${envValidateCall} const userEnv = __filterInternalBindings(env);
|
|
2724
|
+
const emailProxyImport = hasEmail ? `import { createMessageProxy as __createMessageProxy, enactEmailActions as __enactEmailActions, isForwardableEmailMessage as __isForwardableEmailMessage } from ${JSON.stringify(runtimeEmailPath)};\nimport { EMAIL_PROTOCOL_VERSION as __EMAIL_PROTOCOL_VERSION, encodeEmailActions as __encodeEmailActions, readEmailEnvelope as __readEmailEnvelope, verifyEmailReceiptThroughProxy as __verifyEmailReceiptThroughProxy } from "void/_email-protocol";\n` : "";
|
|
2725
|
+
const emailHandler = hasEmail ? `async function handleEmail(envelope, env, ctx) {
|
|
2726
|
+
${envValidateCall}${remoteEnvSwap} const userEnv = __filterInternalBindings(env);
|
|
3012
2727
|
const __relayed = typeof envelope.viaDomain === "string" && envelope.viaDomain.length > 0;
|
|
3013
2728
|
const __slug = __relayed ? undefined : (typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined);
|
|
3014
2729
|
const { message, getActions } = __createMessageProxy(envelope, { slug: __slug });
|
|
@@ -3051,14 +2766,9 @@ ${hasQueues ? ` async queue(batch) { return __voidQueue(batch, this.env, this.c
|
|
|
3051
2766
|
}
|
|
3052
2767
|
await handleEmail(message, this.env, this.ctx);
|
|
3053
2768
|
}\n` : ""}}`;
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
${
|
|
3057
|
-
${scheduledHandler}
|
|
3058
|
-
${emailHandler}
|
|
3059
|
-
${emailReceiptHandler}
|
|
3060
|
-
async function __voidQueue(batch, env, ctx) {
|
|
3061
|
-
${envValidateCall}${remotePath ? ` if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};\n` : ""}${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
|
|
2769
|
+
const queueImport = hasQueues ? ", __processQueue" : "";
|
|
2770
|
+
const queueFunction = hasQueues ? `async function __voidQueue(batch, env, ctx) {
|
|
2771
|
+
${envValidateCall}${remoteEnvSwap}${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
|
|
3062
2772
|
const messages = [...batch.messages].map(m => ({
|
|
3063
2773
|
id: m.id, timestamp: m.timestamp.toISOString(),
|
|
3064
2774
|
body: m.body, attempts: m.attempts,
|
|
@@ -3078,18 +2788,14 @@ ${envValidateCall}${remotePath ? ` if (env.__VOID_REMOTE === "1") env = ${creat
|
|
|
3078
2788
|
if (!__qr.ok) throw new Error("queue: Handler failed.");
|
|
3079
2789
|
}
|
|
3080
2790
|
|
|
3081
|
-
|
|
3082
|
-
${
|
|
3083
|
-
${sandboxExport}
|
|
3084
|
-
${durableObjectExports}
|
|
3085
|
-
${entryClass}`;
|
|
3086
|
-
return `${sandboxImport}${entryImport}${liveRuntimeImport}import app, { scheduled, __voidCollectPrerenderPaths, __voidHandleInternalRoute, __withRawEnv${emailImport}${webSocketClasses.length > 0 ? `, ${webSocketClasses.join(", ")}` : ""}${liveRouteImport} } from 'virtual:void-routes';
|
|
2791
|
+
` : "";
|
|
2792
|
+
return `${sandboxImport}${entryImport}${liveRuntimeImport}import app, { scheduled, __voidCollectPrerenderPaths, __voidHandleInternalRoute, __withRawEnv${queueImport}${emailImport}${webSocketClasses.length > 0 ? `, ${webSocketClasses.join(", ")}` : ""}${liveRouteImport} } from 'virtual:void-routes';
|
|
3087
2793
|
${durableObjectImports}\n${runtimeEnvImport}${emailProxyImport}${envSchemaImport}${remoteImport}${isrImport}${filterBindingsHelper}${assetHelper}
|
|
3088
2794
|
${fetchDeclaration}
|
|
3089
2795
|
${scheduledHandler}
|
|
3090
2796
|
${emailHandler}
|
|
3091
2797
|
${emailReceiptHandler}
|
|
3092
|
-
${webSocketClasses.map((name) => `export { ${name} };`).join("\n")}
|
|
2798
|
+
${queueFunction}${webSocketClasses.map((name) => `export { ${name} };`).join("\n")}
|
|
3093
2799
|
${liveExport}
|
|
3094
2800
|
${sandboxExport}
|
|
3095
2801
|
${durableObjectExports}
|
|
@@ -3098,13 +2804,6 @@ ${entryClass}`;
|
|
|
3098
2804
|
/**
|
|
3099
2805
|
* Generate the app module — exports the Hono app with static asset serving.
|
|
3100
2806
|
* This is the entry imported by `vite preview` and can be used programmatically.
|
|
3101
|
-
*
|
|
3102
|
-
* When `envSchemaModule` is provided, splices boot-time env validation so it
|
|
3103
|
-
* runs on the first request (including the prerender child process spawned
|
|
3104
|
-
* by `prerenderPagesNode`). Mirrors `compileWorkerEntry`: a side-effect import
|
|
3105
|
-
* registers the schema, and `_validateEnvOnce` throws `EnvValidationError` on
|
|
3106
|
-
* bad values. Env source on Node/Bun is `process.env`; on Deno it's
|
|
3107
|
-
* `Deno.env.toObject()`.
|
|
3108
2807
|
*/
|
|
3109
2808
|
function compileNodeApp(target, honoPath, envSchemaModule) {
|
|
3110
2809
|
const staticImport = target === "bun" ? `import { serveStatic } from "hono/bun";` : target === "deno" ? `import { serveStatic } from "hono/deno";` : `import { serveStatic } from "@hono/node-server/serve-static";`;
|
|
@@ -3158,74 +2857,6 @@ function compileBrowserClient(authClientPath, fetchPath, fetchStreamPath) {
|
|
|
3158
2857
|
export { fetchStream, StreamError } from ${JSON.stringify(fetchStreamPath)};
|
|
3159
2858
|
export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};`;
|
|
3160
2859
|
}
|
|
3161
|
-
/**
|
|
3162
|
-
* Generate the server-side fetch client module for non-CF targets.
|
|
3163
|
-
* Same as compileWorkerClient but without cloudflare:workers dependency.
|
|
3164
|
-
* Calls app.fetch() directly (no HTTP round-trip) with ALS context forwarding.
|
|
3165
|
-
*/
|
|
3166
|
-
function compileNodeClient(authClientPath) {
|
|
3167
|
-
return `import app, { requestContext } from "virtual:void-routes";
|
|
3168
|
-
import { interpolateRouteParams } from ${JSON.stringify(ROUTE_URL_PATH)};
|
|
3169
|
-
export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};
|
|
3170
|
-
|
|
3171
|
-
export class FetchError extends Error {
|
|
3172
|
-
constructor(status, statusText, data) {
|
|
3173
|
-
super(\`fetch: Request failed with status \${status}.\`);
|
|
3174
|
-
this.name = "FetchError";
|
|
3175
|
-
this.status = status;
|
|
3176
|
-
this.statusText = statusText;
|
|
3177
|
-
this.data = data;
|
|
3178
|
-
}
|
|
3179
|
-
}
|
|
3180
|
-
|
|
3181
|
-
export async function fetch(path, options) {
|
|
3182
|
-
let url = interpolateRouteParams(path, options?.params);
|
|
3183
|
-
|
|
3184
|
-
if (options?.query) {
|
|
3185
|
-
const qs = new URLSearchParams(options.query).toString();
|
|
3186
|
-
if (qs) url += "?" + qs;
|
|
3187
|
-
}
|
|
3188
|
-
|
|
3189
|
-
const method = options?.method ?? "GET";
|
|
3190
|
-
const headers = new Headers(options?.headers);
|
|
3191
|
-
|
|
3192
|
-
const store = requestContext.getStore();
|
|
3193
|
-
if (store?.request) {
|
|
3194
|
-
const outerReq = store.request;
|
|
3195
|
-
if (!headers.has("cookie")) {
|
|
3196
|
-
const cookie = outerReq.headers.get("cookie");
|
|
3197
|
-
if (cookie) headers.set("cookie", cookie);
|
|
3198
|
-
}
|
|
3199
|
-
if (!headers.has("authorization")) {
|
|
3200
|
-
const auth = outerReq.headers.get("authorization");
|
|
3201
|
-
if (auth) headers.set("authorization", auth);
|
|
3202
|
-
}
|
|
3203
|
-
}
|
|
3204
|
-
|
|
3205
|
-
if (options?.body != null && !headers.has("content-type")) {
|
|
3206
|
-
headers.set("content-type", "application/json");
|
|
3207
|
-
}
|
|
3208
|
-
|
|
3209
|
-
const request = new Request("http://localhost" + url, {
|
|
3210
|
-
method,
|
|
3211
|
-
headers,
|
|
3212
|
-
body: options?.body != null ? JSON.stringify(options.body) : undefined,
|
|
3213
|
-
});
|
|
3214
|
-
|
|
3215
|
-
const response = await app.fetch(request);
|
|
3216
|
-
|
|
3217
|
-
if (response.status === 204) return undefined;
|
|
3218
|
-
|
|
3219
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
3220
|
-
const data = contentType.includes("application/json") ? await response.json() : await response.text();
|
|
3221
|
-
|
|
3222
|
-
if (!response.ok) {
|
|
3223
|
-
throw new FetchError(response.status, response.statusText, data);
|
|
3224
|
-
}
|
|
3225
|
-
|
|
3226
|
-
return data;
|
|
3227
|
-
}`;
|
|
3228
|
-
}
|
|
3229
2860
|
function stripOriginForProd(rules) {
|
|
3230
2861
|
return rules.map(({ origin: _origin, ...rest }) => rest);
|
|
3231
2862
|
}
|
|
@@ -3239,11 +2870,13 @@ function compileHeaderMiddleware(lines, rules) {
|
|
|
3239
2870
|
lines.push(`const __headerRules = ${JSON.stringify(rules)};`);
|
|
3240
2871
|
lines.push("app.use(\"*\", __routingRuntime.headerMiddleware(__headerRules));");
|
|
3241
2872
|
}
|
|
3242
|
-
|
|
2873
|
+
/** Generate the server-side fetch client, which calls `app.fetch()` with the current request's credentials. */
|
|
2874
|
+
function compileWorkerClient(authClientPath, nodeTarget = false) {
|
|
2875
|
+
const envImport = nodeTarget ? "" : "import { env } from \"cloudflare:workers\";\n";
|
|
2876
|
+
const dispatch = nodeTarget ? "const response = await app.fetch(request);" : "const executionCtx = store?.executionCtx ?? { waitUntil() {}, passThroughOnException() {} };\n const response = await app.fetch(request, env, executionCtx);";
|
|
3243
2877
|
return `import app, { requestContext } from "virtual:void-routes";
|
|
3244
2878
|
import { interpolateRouteParams } from ${JSON.stringify(ROUTE_URL_PATH)};
|
|
3245
|
-
|
|
3246
|
-
export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};
|
|
2879
|
+
${envImport}export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};
|
|
3247
2880
|
|
|
3248
2881
|
export class FetchError extends Error {
|
|
3249
2882
|
constructor(status, statusText, data) {
|
|
@@ -3266,7 +2899,6 @@ export async function fetch(path, options) {
|
|
|
3266
2899
|
const method = options?.method ?? "GET";
|
|
3267
2900
|
const headers = new Headers(options?.headers);
|
|
3268
2901
|
|
|
3269
|
-
// Auto-forward cookie and authorization from the outer request via ALS
|
|
3270
2902
|
const store = requestContext.getStore();
|
|
3271
2903
|
if (store?.request) {
|
|
3272
2904
|
const outerReq = store.request;
|
|
@@ -3284,15 +2916,13 @@ export async function fetch(path, options) {
|
|
|
3284
2916
|
headers.set("content-type", "application/json");
|
|
3285
2917
|
}
|
|
3286
2918
|
|
|
3287
|
-
const request = new Request("http://worker.local" + url, {
|
|
2919
|
+
const request = new Request("${nodeTarget ? "http://localhost" : "http://worker.local"}" + url, {
|
|
3288
2920
|
method,
|
|
3289
2921
|
headers,
|
|
3290
2922
|
body: options?.body != null ? JSON.stringify(options.body) : undefined,
|
|
3291
2923
|
});
|
|
3292
2924
|
|
|
3293
|
-
|
|
3294
|
-
const executionCtx = store?.executionCtx ?? { waitUntil() {}, passThroughOnException() {} };
|
|
3295
|
-
const response = await app.fetch(request, env, executionCtx);
|
|
2925
|
+
${dispatch}
|
|
3296
2926
|
|
|
3297
2927
|
if (response.status === 204) return undefined;
|
|
3298
2928
|
|
|
@@ -3317,10 +2947,10 @@ export async function fetch(path, options) {
|
|
|
3317
2947
|
* (see `generateClassATriggerWrapper`). Production deploys go through
|
|
3318
2948
|
* `cli/wrapper.ts` instead.
|
|
3319
2949
|
*/
|
|
3320
|
-
function getFrameworkEntry(framework, root, devTriggerToken, notFound) {
|
|
2950
|
+
function getFrameworkEntry(framework, root, devTriggerToken, dialect, notFound) {
|
|
3321
2951
|
const isBuild = isViteBuildOrPreview();
|
|
3322
2952
|
if (!isBuild) writeFrameworkTriggersDispatch(root, devTriggerToken);
|
|
3323
|
-
return generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), isBuild, void 0, notFound);
|
|
2953
|
+
return generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), isBuild, dialect, void 0, notFound);
|
|
3324
2954
|
}
|
|
3325
2955
|
/** The framework's own server entry, before our trigger wrapper. */
|
|
3326
2956
|
function getOriginalFrameworkEntry(framework, root) {
|
|
@@ -3337,6 +2967,11 @@ function getOriginalFrameworkEntry(framework, root) {
|
|
|
3337
2967
|
* first, dispatches `/__void/{scheduled,queue}` if it matches, and otherwise
|
|
3338
2968
|
* delegates to the framework's original entry.
|
|
3339
2969
|
*
|
|
2970
|
+
* For PostgreSQL and MySQL, both shapes run the framework inside Void's request scope
|
|
2971
|
+
* (`withRuntimeEnv`), as Void's own handlers do, so void/db keeps one client per request. D1 apps
|
|
2972
|
+
* keep the framework's own fetch: in a request scope, void/db reads D1 through a replica-capable
|
|
2973
|
+
* session instead of the primary.
|
|
2974
|
+
*
|
|
3340
2975
|
* We emit two shapes of the wrapper depending on the Vite command:
|
|
3341
2976
|
*
|
|
3342
2977
|
* - Serve: dispatch is dynamically imported and gets a chance to handle
|
|
@@ -3349,27 +2984,11 @@ function getOriginalFrameworkEntry(framework, root) {
|
|
|
3349
2984
|
* dispatch file (and its transitive user-cron/queue imports + dev token)
|
|
3350
2985
|
* would still ship in the production bundle.
|
|
3351
2986
|
*/
|
|
3352
|
-
function generateClassATriggerWrapper(root, framework, original, isBuild, assetsDir = "assets", notFound) {
|
|
2987
|
+
function generateClassATriggerWrapper(root, framework, original, isBuild, dialect, assetsDir = "assets", notFound) {
|
|
3353
2988
|
const outDir = join(root, ".void");
|
|
3354
2989
|
mkdirSync(outDir, { recursive: true });
|
|
3355
2990
|
const wrapperPath = join(outDir, `${framework}-trigger-wrapper.ts`);
|
|
3356
|
-
const
|
|
3357
|
-
import original from ${JSON.stringify(original)};
|
|
3358
|
-
|
|
3359
|
-
export default {
|
|
3360
|
-
...original,
|
|
3361
|
-
async fetch(request, env, ctx) {
|
|
3362
|
-
return serveWithAssets(request, env, await original.fetch(request, env, ctx));
|
|
3363
|
-
},
|
|
3364
|
-
};
|
|
3365
|
-
${compileAssetFallbackHelper(assetsDir, false, notFound)}
|
|
3366
|
-
` : `// @ts-nocheck — Auto-generated by Void in dev. Do NOT edit.
|
|
3367
|
-
import original from ${JSON.stringify(original)};
|
|
3368
|
-
|
|
3369
|
-
export default {
|
|
3370
|
-
...original,
|
|
3371
|
-
async fetch(request, env, ctx) {
|
|
3372
|
-
if (request.method === "POST") {
|
|
2991
|
+
const fetchBody = isBuild ? ` return serveWithAssets(request, env, await original.fetch(request, env, ctx));` : ` if (request.method === "POST") {
|
|
3373
2992
|
const pathname = new URL(request.url).pathname;
|
|
3374
2993
|
if (pathname === "/__void/scheduled" || pathname === "/__void/queue") {
|
|
3375
2994
|
const { handleDevTrigger } = await import(${JSON.stringify(frameworkTriggersDispatchPath(root))});
|
|
@@ -3377,10 +2996,23 @@ export default {
|
|
|
3377
2996
|
if (response) return response;
|
|
3378
2997
|
}
|
|
3379
2998
|
}
|
|
3380
|
-
return original.fetch(request, env, ctx)
|
|
3381
|
-
|
|
2999
|
+
return original.fetch(request, env, ctx);`;
|
|
3000
|
+
const scoped = dialect !== "sqlite";
|
|
3001
|
+
const fetchMethod = scoped ? ` fetch(request, env, ctx) {
|
|
3002
|
+
return withRuntimeEnv(env, async () => {
|
|
3003
|
+
${fetchBody.replace(/^/gm, " ")}
|
|
3004
|
+
});
|
|
3005
|
+
},` : ` async fetch(request, env, ctx) {
|
|
3006
|
+
${fetchBody}
|
|
3007
|
+
},`;
|
|
3008
|
+
const body = `// @ts-nocheck — Auto-generated by Void ${isBuild ? "for vite build" : "in dev"}. Do NOT edit.
|
|
3009
|
+
import original from ${JSON.stringify(original)};
|
|
3010
|
+
${scoped ? "import { withRuntimeEnv } from \"void/_env\";\n" : ""}
|
|
3011
|
+
export default {
|
|
3012
|
+
...original,
|
|
3013
|
+
${fetchMethod}
|
|
3382
3014
|
};
|
|
3383
|
-
`;
|
|
3015
|
+
${isBuild ? `${compileAssetFallbackHelper(assetsDir, false, notFound)}\n` : ""}`;
|
|
3384
3016
|
writeFileIfChanged(wrapperPath, body);
|
|
3385
3017
|
return wrapperPath;
|
|
3386
3018
|
}
|
|
@@ -3433,10 +3065,207 @@ export default {
|
|
|
3433
3065
|
return entryPath;
|
|
3434
3066
|
}
|
|
3435
3067
|
//#endregion
|
|
3068
|
+
//#region src/installed-packages.ts
|
|
3069
|
+
function readManifest(dir) {
|
|
3070
|
+
try {
|
|
3071
|
+
return JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
3072
|
+
} catch {
|
|
3073
|
+
return;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
/** The directory Node loads `name` from for code in `fromDir`. Ignores `exports`. */
|
|
3077
|
+
function findInstalledPackage(name, fromDir) {
|
|
3078
|
+
const pnp = module.findPnpApi?.(fromDir);
|
|
3079
|
+
if (pnp) try {
|
|
3080
|
+
const manifest = pnp.resolveToUnqualified(`${name}/package.json`, `${fromDir}/`);
|
|
3081
|
+
return manifest ? dirname(manifest) : void 0;
|
|
3082
|
+
} catch {
|
|
3083
|
+
return;
|
|
3084
|
+
}
|
|
3085
|
+
for (let dir = fromDir;; dir = dirname(dir)) {
|
|
3086
|
+
const candidate = join(dir, "node_modules", name);
|
|
3087
|
+
if (existsSync(join(candidate, "package.json"))) return realpathSync(candidate);
|
|
3088
|
+
if (dirname(dir) === dir) return;
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
function isVoidPackage(name) {
|
|
3092
|
+
return name === "void" || name.startsWith("@void/");
|
|
3093
|
+
}
|
|
3094
|
+
/** The `exports` conditions that an import matches in Vite's SSR graph. */
|
|
3095
|
+
const IMPORT_CONDITIONS = /* @__PURE__ */ new Set([
|
|
3096
|
+
"node",
|
|
3097
|
+
"import",
|
|
3098
|
+
"module",
|
|
3099
|
+
"default"
|
|
3100
|
+
]);
|
|
3101
|
+
/**
|
|
3102
|
+
* Vite's SSR graph also matches `production` or `development`, as NODE_ENV says. Vite sets
|
|
3103
|
+
* NODE_ENV before it runs the plugin hooks that call this.
|
|
3104
|
+
*/
|
|
3105
|
+
function matchesImport(condition) {
|
|
3106
|
+
const mode = process.env.NODE_ENV === "production" ? "production" : "development";
|
|
3107
|
+
return IMPORT_CONDITIONS.has(condition) || condition === mode;
|
|
3108
|
+
}
|
|
3109
|
+
/** The target an import picks from an `exports` value: its first matching key, as in Node. */
|
|
3110
|
+
function importTarget(value) {
|
|
3111
|
+
if (typeof value === "string") return value;
|
|
3112
|
+
if (Array.isArray(value)) {
|
|
3113
|
+
for (const item of value) {
|
|
3114
|
+
const target = importTarget(item);
|
|
3115
|
+
if (target) return target;
|
|
3116
|
+
}
|
|
3117
|
+
return;
|
|
3118
|
+
}
|
|
3119
|
+
if (!value || typeof value !== "object") return;
|
|
3120
|
+
for (const [key, item] of Object.entries(value)) {
|
|
3121
|
+
const target = matchesImport(key) ? importTarget(item) : void 0;
|
|
3122
|
+
if (target) return target;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
function isFile(path) {
|
|
3126
|
+
try {
|
|
3127
|
+
return statSync(path).isFile();
|
|
3128
|
+
} catch {
|
|
3129
|
+
return false;
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
/** The file an import of the package loads: `exports` ".", then `module`, then `main`. */
|
|
3133
|
+
function findImportEntry(dir, manifest) {
|
|
3134
|
+
const exports = manifest.exports;
|
|
3135
|
+
const entry = importTarget(exports && typeof exports === "object" && Object.keys(exports).some((key) => key.startsWith(".")) ? exports["."] : exports) ?? (typeof manifest.module === "string" ? manifest.module : void 0) ?? (typeof manifest.main === "string" ? manifest.main : "index.js");
|
|
3136
|
+
for (const candidate of [
|
|
3137
|
+
entry,
|
|
3138
|
+
`${entry}.js`,
|
|
3139
|
+
`${entry}/index.js`
|
|
3140
|
+
]) {
|
|
3141
|
+
const file = join(dir, candidate);
|
|
3142
|
+
if (isFile(file)) return file;
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
/** Whether Node loads a `.mjs` or `.js` file in the package as an ES module. */
|
|
3146
|
+
function isEsmFile(file, dir, manifest) {
|
|
3147
|
+
if (file.endsWith(".mjs")) return true;
|
|
3148
|
+
if (!file.endsWith(".js")) return false;
|
|
3149
|
+
for (let scope = dirname(file); scope.startsWith(`${dir}/`); scope = dirname(scope)) {
|
|
3150
|
+
const nested = readManifest(scope);
|
|
3151
|
+
if (nested) return nested.type === "module";
|
|
3152
|
+
}
|
|
3153
|
+
return manifest.type === "module";
|
|
3154
|
+
}
|
|
3155
|
+
/** A dynamic `import()` argument that is a single string literal naming a relative file. */
|
|
3156
|
+
const RELATIVE_LITERAL = /^(["'])(\.{1,2}\/[^"']*)\1$/;
|
|
3157
|
+
/** The relative files that a module's imports, re-exports and `import()` calls name. */
|
|
3158
|
+
function relativeImports(code, parsed) {
|
|
3159
|
+
const specifiers = staticModuleReferences(parsed, code).map((reference) => reference.source);
|
|
3160
|
+
for (const { moduleRequest } of parsed.module.dynamicImports) {
|
|
3161
|
+
const literal = RELATIVE_LITERAL.exec(code.slice(moduleRequest.start, moduleRequest.end));
|
|
3162
|
+
if (literal) specifiers.push(literal[2]);
|
|
3163
|
+
}
|
|
3164
|
+
return specifiers.filter((specifier) => /^\.{1,2}\//.test(specifier));
|
|
3165
|
+
}
|
|
3166
|
+
/** The most files of one package that the check reads. A package with more stays with Node. */
|
|
3167
|
+
const MAX_PACKAGE_MODULES = 2e3;
|
|
3168
|
+
/**
|
|
3169
|
+
* Vite's SSR module runner evaluates an inlined package as ES modules. The package's import
|
|
3170
|
+
* entry and every file it reaches through relative imports must be one. So the ES module
|
|
3171
|
+
* wrapper in Node's dual-package guide, or any ES module of the package that imports a
|
|
3172
|
+
* CommonJS file, keeps the package with Node.
|
|
3173
|
+
*/
|
|
3174
|
+
function shipsEsm(packageDir, manifest) {
|
|
3175
|
+
const dir = normalize(packageDir);
|
|
3176
|
+
const entry = findImportEntry(dir, manifest);
|
|
3177
|
+
if (!entry) return false;
|
|
3178
|
+
const files = [entry];
|
|
3179
|
+
const seen = new Set(files);
|
|
3180
|
+
for (const file of files) {
|
|
3181
|
+
if (!isEsmFile(file, dir, manifest)) return false;
|
|
3182
|
+
let code;
|
|
3183
|
+
try {
|
|
3184
|
+
code = readFileSync(file, "utf8");
|
|
3185
|
+
} catch {
|
|
3186
|
+
return false;
|
|
3187
|
+
}
|
|
3188
|
+
const parsed = parseSync(file, code, {
|
|
3189
|
+
lang: "js",
|
|
3190
|
+
sourceType: "module"
|
|
3191
|
+
});
|
|
3192
|
+
if (parsed.errors.length > 0) return false;
|
|
3193
|
+
for (const specifier of relativeImports(code, parsed)) {
|
|
3194
|
+
const next = join(dirname(file), specifier);
|
|
3195
|
+
if (/\.[cm]?js$/.test(next) && !seen.has(next)) {
|
|
3196
|
+
if (seen.size >= MAX_PACKAGE_MODULES) return false;
|
|
3197
|
+
seen.add(next);
|
|
3198
|
+
files.push(next);
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
return true;
|
|
3203
|
+
}
|
|
3204
|
+
/**
|
|
3205
|
+
* Installed ES module packages that list `void` or an `@void/` package as a dependency, among
|
|
3206
|
+
* the app's own dependencies and, through them, the packages they depend on (the rule
|
|
3207
|
+
* vite-plugin-svelte applies to Svelte libraries). Vite leaves a package in node_modules to Node,
|
|
3208
|
+
* whose `void/*` imports then skip Void's plugins: the generated `void/db` and the Node target's
|
|
3209
|
+
* guard. Listing these packages in `ssr.noExternal` keeps them in Vite's graph.
|
|
3210
|
+
*/
|
|
3211
|
+
function findVoidDependentPackages(root) {
|
|
3212
|
+
const app = readManifest(root);
|
|
3213
|
+
if (!app) return [];
|
|
3214
|
+
const found = /* @__PURE__ */ new Set();
|
|
3215
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3216
|
+
const visit = (names, fromDir) => {
|
|
3217
|
+
for (const name of names) {
|
|
3218
|
+
if (isVoidPackage(name)) continue;
|
|
3219
|
+
const dir = findInstalledPackage(name, fromDir);
|
|
3220
|
+
if (!dir || seen.has(dir)) continue;
|
|
3221
|
+
seen.add(dir);
|
|
3222
|
+
const manifest = readManifest(dir);
|
|
3223
|
+
const dependencies = {
|
|
3224
|
+
...manifest?.dependencies,
|
|
3225
|
+
...manifest?.optionalDependencies
|
|
3226
|
+
};
|
|
3227
|
+
if (!manifest || !Object.keys({
|
|
3228
|
+
...dependencies,
|
|
3229
|
+
...manifest.peerDependencies
|
|
3230
|
+
}).some(isVoidPackage) || !shipsEsm(dir, manifest)) continue;
|
|
3231
|
+
found.add(name);
|
|
3232
|
+
visit(Object.keys(dependencies), dir);
|
|
3233
|
+
}
|
|
3234
|
+
};
|
|
3235
|
+
visit(Object.keys({
|
|
3236
|
+
...app.dependencies,
|
|
3237
|
+
...app.devDependencies,
|
|
3238
|
+
...app.optionalDependencies
|
|
3239
|
+
}), root);
|
|
3240
|
+
return [...found].sort();
|
|
3241
|
+
}
|
|
3242
|
+
/** `name` and every package it depends on, as installed for code in `fromDir`. */
|
|
3243
|
+
function findDependencyClosure(name, fromDir) {
|
|
3244
|
+
const found = /* @__PURE__ */ new Set();
|
|
3245
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3246
|
+
const visit = (dependency, from) => {
|
|
3247
|
+
const dir = findInstalledPackage(dependency, from);
|
|
3248
|
+
if (!dir || seen.has(dir)) return;
|
|
3249
|
+
seen.add(dir);
|
|
3250
|
+
found.add(dependency);
|
|
3251
|
+
const manifest = readManifest(dir);
|
|
3252
|
+
for (const next of Object.keys({
|
|
3253
|
+
...manifest?.dependencies,
|
|
3254
|
+
...manifest?.optionalDependencies
|
|
3255
|
+
})) visit(next, dir);
|
|
3256
|
+
};
|
|
3257
|
+
visit(name, fromDir);
|
|
3258
|
+
return [...found].sort();
|
|
3259
|
+
}
|
|
3260
|
+
//#endregion
|
|
3436
3261
|
//#region src/plugin-migration.ts
|
|
3437
3262
|
function readDatabaseUrl(root) {
|
|
3438
3263
|
return loadLocalEnv(root).DATABASE_URL;
|
|
3439
3264
|
}
|
|
3265
|
+
/** DATABASE_URL as Better Auth's local migrations read it: the shell before `.env`. */
|
|
3266
|
+
function readAuthDatabaseUrl(root) {
|
|
3267
|
+
return (process.env.DATABASE_URL ?? readDatabaseUrl(root)) || void 0;
|
|
3268
|
+
}
|
|
3440
3269
|
/**
|
|
3441
3270
|
* Vite plugin that runs local migrations on dev server startup.
|
|
3442
3271
|
* For SQLite/D1: applies migrations to the local miniflare database.
|
|
@@ -3450,33 +3279,53 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
|
|
|
3450
3279
|
const migrationsDir = readProjectPaths(root).migrationsDir;
|
|
3451
3280
|
const hasSqlMigrations = existsSync(migrationsDir);
|
|
3452
3281
|
if (!hasSqlMigrations && !auth?.enabled) return;
|
|
3282
|
+
const migrateAuth = async (databaseUrl) => {
|
|
3283
|
+
const { runLocalVoidAuthMigrations } = await import("./node-cPadMgUO.mjs");
|
|
3284
|
+
await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth?.configPath, databaseUrl);
|
|
3285
|
+
};
|
|
3286
|
+
const mysqlAuth = dialect === "mysql" && auth?.enabled === true;
|
|
3287
|
+
const logApplied = (applied) => {
|
|
3288
|
+
if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
|
|
3289
|
+
};
|
|
3453
3290
|
try {
|
|
3454
|
-
if (
|
|
3455
|
-
const
|
|
3456
|
-
|
|
3291
|
+
if (dialect !== "sqlite") {
|
|
3292
|
+
const { collectMigrations } = await import("./collect-Cae8A7Zr.mjs");
|
|
3293
|
+
const allMigrations = collectMigrations(migrationsDir);
|
|
3294
|
+
const runFiles = dialect === "mysql" ? allMigrations.length > 0 : hasSqlMigrations;
|
|
3295
|
+
const url = runFiles ? readDatabaseUrl(root) : void 0;
|
|
3296
|
+
const authUrl = mysqlAuth ? readAuthDatabaseUrl(root) : void 0;
|
|
3297
|
+
if (runFiles && !url || mysqlAuth && !authUrl) {
|
|
3457
3298
|
afterServerReady(server, () => {
|
|
3458
3299
|
console.log();
|
|
3459
3300
|
voidError(`DATABASE_URL not found in .env — skipping ${dialect === "mysql" ? "MySQL" : "PostgreSQL"} migrations.`);
|
|
3460
3301
|
});
|
|
3461
3302
|
return;
|
|
3462
3303
|
}
|
|
3463
|
-
const
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3304
|
+
const authWithFiles = authUrl !== void 0 && authUrl === url;
|
|
3305
|
+
if (url) {
|
|
3306
|
+
const { validateMigrations } = await import("./validate-BQFdf0Pi.mjs");
|
|
3307
|
+
const appliedNames = dialect === "mysql" ? await import("./runner-mysql-DWwE8jKi.mjs").then((runner) => runner.getMySqlAppliedMigrations(url)) : await import("./runner-pg-_Xncr3H5.mjs").then((runner) => runner.getPgAppliedMigrations(url));
|
|
3308
|
+
const appliedSet = new Set(appliedNames);
|
|
3309
|
+
const pending = allMigrations.filter((migration) => !appliedSet.has(migration.name));
|
|
3310
|
+
if (pending.length > 0) try {
|
|
3311
|
+
validateMigrations(pending);
|
|
3312
|
+
} catch (err) {
|
|
3313
|
+
voidWarn(err instanceof Error ? err.message : String(err));
|
|
3314
|
+
}
|
|
3315
|
+
const applied = dialect === "mysql" ? await import("./runner-mysql-DWwE8jKi.mjs").then((runner) => runner.runMySqlMigrations(migrationsDir, url, authWithFiles ? async (names) => {
|
|
3316
|
+
logApplied(names);
|
|
3317
|
+
await migrateAuth(url);
|
|
3318
|
+
} : void 0)) : await import("./runner-pg-_Xncr3H5.mjs").then((runner) => runner.runPgMigrations(migrationsDir, url));
|
|
3319
|
+
if (!authWithFiles) logApplied(applied);
|
|
3320
|
+
}
|
|
3321
|
+
if (authUrl && !authWithFiles) {
|
|
3322
|
+
const { withMySqlMigrationLockAt } = await import("./runner-mysql-DWwE8jKi.mjs");
|
|
3323
|
+
await withMySqlMigrationLockAt(authUrl, () => migrateAuth(authUrl));
|
|
3473
3324
|
}
|
|
3474
|
-
const applied = dialect === "mysql" ? await import("./runner-mysql-CkFqZ6CE.mjs").then((runner) => runner.runMySqlMigrations(migrationsDir, url)) : await import("./runner-pg-BGYRFdRp.mjs").then((runner) => runner.runPgMigrations(migrationsDir, url));
|
|
3475
|
-
if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
|
|
3476
3325
|
} else if (hasSqlMigrations) {
|
|
3477
|
-
const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./runner-
|
|
3478
|
-
const { collectMigrations } = await import("./collect-
|
|
3479
|
-
const { validateMigrations } = await import("./validate-
|
|
3326
|
+
const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./runner-So9mYfcm.mjs");
|
|
3327
|
+
const { collectMigrations } = await import("./collect-Cae8A7Zr.mjs");
|
|
3328
|
+
const { validateMigrations } = await import("./validate-BQFdf0Pi.mjs");
|
|
3480
3329
|
const dbPath = getMiniflareDatabasePath(persistRoot, databaseId);
|
|
3481
3330
|
const allMigrations = collectMigrations(migrationsDir);
|
|
3482
3331
|
const appliedRows = await getAppliedMigrations(dbPath);
|
|
@@ -3491,8 +3340,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
|
|
|
3491
3340
|
if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
|
|
3492
3341
|
}
|
|
3493
3342
|
if (auth?.enabled) {
|
|
3494
|
-
|
|
3495
|
-
await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth.configPath);
|
|
3343
|
+
if (!mysqlAuth) await migrateAuth();
|
|
3496
3344
|
voidLog("Applied Better Auth migrations");
|
|
3497
3345
|
}
|
|
3498
3346
|
} catch (err) {
|
|
@@ -3529,6 +3377,26 @@ function createCloudflareBuiltinsExternalPlugin() {
|
|
|
3529
3377
|
}
|
|
3530
3378
|
};
|
|
3531
3379
|
}
|
|
3380
|
+
/**
|
|
3381
|
+
* Send a bare `void` import in server code to the handler helpers (`defineScheduled`,
|
|
3382
|
+
* `defineQueue`, ...), as Void apps and the cron/queue deploy bundles do. The package entry is the
|
|
3383
|
+
* Vite plugin: loaded in a worker environment, it pulls Wrangler into the dependency optimizer.
|
|
3384
|
+
*/
|
|
3385
|
+
function createBareVoidRedirectPlugin() {
|
|
3386
|
+
let handlerFile;
|
|
3387
|
+
return {
|
|
3388
|
+
name: "void:bare-void-redirect",
|
|
3389
|
+
resolveId: {
|
|
3390
|
+
order: "pre",
|
|
3391
|
+
filter: { id: /^void$/ },
|
|
3392
|
+
handler() {
|
|
3393
|
+
if (this.environment?.config.consumer === "client") return;
|
|
3394
|
+
handlerFile ??= fileURLToPath(import.meta.resolve("#self/handler"));
|
|
3395
|
+
return handlerFile;
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
};
|
|
3399
|
+
}
|
|
3532
3400
|
function createDefaultWorkerEnvironmentPlugin() {
|
|
3533
3401
|
return {
|
|
3534
3402
|
name: "void:default-worker-environment",
|
|
@@ -3589,11 +3457,58 @@ function createWranglerCompatPersistPlugin(root, config) {
|
|
|
3589
3457
|
}
|
|
3590
3458
|
};
|
|
3591
3459
|
}
|
|
3592
|
-
|
|
3460
|
+
const DATABASE_DRIVER_DEPS = {
|
|
3461
|
+
sqlite: [],
|
|
3462
|
+
postgresql: ["void > pg"],
|
|
3463
|
+
mysql: ["void > mysql2"]
|
|
3464
|
+
};
|
|
3465
|
+
const NODE_BUILTIN = new RegExp(`^(?:node:)?(?:${builtinModules.join("|")})$`);
|
|
3466
|
+
const NODE_BUILTIN_REQUIRE_PREFIX = "\0void:node-require:";
|
|
3467
|
+
/**
|
|
3468
|
+
* The Node built-ins that workerd provides for the given compatibility settings, from the preset
|
|
3469
|
+
* the Cloudflare plugin builds Workers with (a dependency of `@cloudflare/vite-plugin`). Before
|
|
3470
|
+
* 2025-09-15 the preset fills in parts of `node:process` instead of listing it, but workerd
|
|
3471
|
+
* provides that module at every date.
|
|
3472
|
+
*/
|
|
3473
|
+
async function readWorkerdNodeBuiltins(compat) {
|
|
3474
|
+
const vitePlugin = fileURLToPath(import.meta.resolve("@cloudflare/vite-plugin"));
|
|
3475
|
+
const manifestPath = createRequire(vitePlugin).resolve("@cloudflare/unenv-preset/package.json");
|
|
3476
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
3477
|
+
const { getCloudflarePreset } = await import(pathToFileURL(join(dirname(manifestPath), manifest.exports["."].import)).href);
|
|
3478
|
+
const { external } = getCloudflarePreset({
|
|
3479
|
+
compatibilityDate: compat.compatibilityDate,
|
|
3480
|
+
compatibilityFlags: compat.compatibilityFlags ?? []
|
|
3481
|
+
});
|
|
3482
|
+
return /* @__PURE__ */ new Set([...external.map((name) => name.replace(/^node:/, "")), "process"]);
|
|
3483
|
+
}
|
|
3484
|
+
function createServerRuntimeOptimizerPlugin(dialect, readCompat) {
|
|
3485
|
+
let workerdNodeBuiltins;
|
|
3593
3486
|
return {
|
|
3594
3487
|
name: "void:server-runtime-optimizer",
|
|
3595
|
-
configEnvironment(name) {
|
|
3596
|
-
if (name
|
|
3488
|
+
configEnvironment(name, environment) {
|
|
3489
|
+
if (name === "client") return;
|
|
3490
|
+
if (!environment.resolve?.conditions?.includes("workerd")) return { optimizeDeps: { exclude: ["void"] } };
|
|
3491
|
+
return { optimizeDeps: {
|
|
3492
|
+
exclude: ["void"],
|
|
3493
|
+
include: ["void > email-validator", ...DATABASE_DRIVER_DEPS[dialect]]
|
|
3494
|
+
} };
|
|
3495
|
+
},
|
|
3496
|
+
resolveId: {
|
|
3497
|
+
order: "pre",
|
|
3498
|
+
filter: { id: NODE_BUILTIN },
|
|
3499
|
+
async handler(id, _importer, options) {
|
|
3500
|
+
if (dialect === "sqlite" || options.kind !== "require-call" || this.environment?.mode !== "build" || !this.environment.config.resolve.conditions.includes("workerd")) return;
|
|
3501
|
+
const name = id.replace(/^node:/, "");
|
|
3502
|
+
workerdNodeBuiltins ??= readWorkerdNodeBuiltins(readCompat());
|
|
3503
|
+
if (!(await workerdNodeBuiltins).has(name)) return;
|
|
3504
|
+
return `${NODE_BUILTIN_REQUIRE_PREFIX}${name}`;
|
|
3505
|
+
}
|
|
3506
|
+
},
|
|
3507
|
+
load: {
|
|
3508
|
+
filter: { id: /^\0void:node-require:/ },
|
|
3509
|
+
handler(id) {
|
|
3510
|
+
return `import builtin from "node:${id.slice(19)}";\nexport { builtin as "module.exports" };\n`;
|
|
3511
|
+
}
|
|
3597
3512
|
}
|
|
3598
3513
|
};
|
|
3599
3514
|
}
|
|
@@ -3601,6 +3516,17 @@ function createServerRuntimeOptimizerPlugin() {
|
|
|
3601
3516
|
//#region src/sveltekit-hooks-transform.ts
|
|
3602
3517
|
/** Add Void's dev bindings to SvelteKit's generated get_hooks function. */
|
|
3603
3518
|
function injectSvelteKitHooks(code, id, dispatchPath) {
|
|
3519
|
+
return editGetHooks(code, id, `\n const { withRuntimeEnv } = await import("void/_env");\n const { handleDevTrigger } = await import(${JSON.stringify(dispatchPath)});`, "const __origHandle = handle ?? (({ event, resolve }) => resolve(event));\n handle = async ({ event, resolve }) => {\n const __voidEnv = event.platform?.env ?? (await import('cloudflare:workers')).env;\n return withRuntimeEnv(__voidEnv, async () => {\n const __triggerResp = await handleDevTrigger(event.request, __voidEnv, undefined);\n if (__triggerResp) return __triggerResp;\n return __origHandle({ event, resolve });\n });\n };\n ");
|
|
3520
|
+
}
|
|
3521
|
+
/**
|
|
3522
|
+
* Run each request of a SvelteKit build in Void's request scope. `envModule` is the env module
|
|
3523
|
+
* void/db imports. Kit prerenders in Node, where `cloudflare:workers` does not load and Kit 3
|
|
3524
|
+
* passes no platform, so those requests run outside the scope.
|
|
3525
|
+
*/
|
|
3526
|
+
function injectSvelteKitBuildHooks(code, id, envModule) {
|
|
3527
|
+
return editGetHooks(code, id, `\n const { withRuntimeEnv } = await import(${JSON.stringify(envModule)});`, "const __origHandle = handle ?? (({ event, resolve }) => resolve(event));\n handle = async ({ event, resolve }) => {\n const __voidEnv = event.platform?.env ??\n (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers'\n ? (await import('cloudflare:workers')).env\n : undefined);\n return withRuntimeEnv(__voidEnv, () => __origHandle({ event, resolve }));\n };\n ");
|
|
3528
|
+
}
|
|
3529
|
+
function editGetHooks(code, id, prologue, handleWrapper) {
|
|
3604
3530
|
if (!code.includes("get_hooks")) return;
|
|
3605
3531
|
const hooks = (parseSync(id, code).program.body ?? []).filter((node) => node.type === "ExportNamedDeclaration").map((node) => node.declaration).filter((node) => {
|
|
3606
3532
|
const name = node?.id;
|
|
@@ -3611,8 +3537,8 @@ function injectSvelteKitHooks(code, id, dispatchPath) {
|
|
|
3611
3537
|
const returns = (body?.body)?.filter((node) => node.type === "ReturnStatement" && node.argument?.type === "ObjectExpression") ?? [];
|
|
3612
3538
|
if (body?.type !== "BlockStatement" || body.start === void 0 || returns.length !== 1 || returns[0]?.start === void 0) throw new Error("sveltekit: Expected one object return in generated get_hooks.");
|
|
3613
3539
|
const ms = new MagicString(code);
|
|
3614
|
-
ms.appendLeft(body.start + 1,
|
|
3615
|
-
ms.appendLeft(returns[0].start,
|
|
3540
|
+
ms.appendLeft(body.start + 1, prologue);
|
|
3541
|
+
ms.appendLeft(returns[0].start, handleWrapper);
|
|
3616
3542
|
return {
|
|
3617
3543
|
code: ms.toString(),
|
|
3618
3544
|
map: ms.generateMap({ hires: true })
|
|
@@ -3620,8 +3546,13 @@ function injectSvelteKitHooks(code, id, dispatchPath) {
|
|
|
3620
3546
|
}
|
|
3621
3547
|
//#endregion
|
|
3622
3548
|
//#region src/plugin-framework.ts
|
|
3549
|
+
const handlerFile = fileURLToPath(import.meta.resolve("#self/handler"));
|
|
3550
|
+
const envModuleFile = fileURLToPath(import.meta.resolve("#self/_env"));
|
|
3551
|
+
const voidDir = dirname(fileURLToPath(import.meta.url));
|
|
3552
|
+
const ASTRO_SERVER_ENTRY = "@astrojs/cloudflare/entrypoints/server";
|
|
3553
|
+
const ASTRO_SCOPED_SERVER_ENTRY = "\0void:astro-server-entry";
|
|
3623
3554
|
function createFrameworkPlugins(input) {
|
|
3624
|
-
const { localD1, root, directCloudflareDestination, bindings, config, dialect, application, bindingNames, websocketRoutes,
|
|
3555
|
+
const { localD1, root, directCloudflareDestination, bindings, config, dialect, application, bindingNames, websocketRoutes, liveConfig, detected, clientStubsPlugin, serverRuntimeOptimizerPlugin, devTriggerToken, implicitDeployGuard } = input;
|
|
3625
3556
|
const frameworkPersistRoot = localD1.persistRoot;
|
|
3626
3557
|
const syncFrameworkCompat = (compat) => {
|
|
3627
3558
|
if (ensureWranglerCompatibilityDate(root, compat.compatibilityDate)) voidLog("Synced compatibility_date to Cloudflare config");
|
|
@@ -3630,7 +3561,6 @@ function createFrameworkPlugins(input) {
|
|
|
3630
3561
|
name: "void:wrangler-compat",
|
|
3631
3562
|
enforce: "pre",
|
|
3632
3563
|
config(_, env) {
|
|
3633
|
-
if (env.command === "serve" && directCloudflareDestination && bindings.needsAI) process.env.CLOUDFLARE_AUTH_USE_KEYRING = "true";
|
|
3634
3564
|
syncFrameworkCompat(ensureWranglerCompat(root, config));
|
|
3635
3565
|
if (env.command !== "serve") return;
|
|
3636
3566
|
if (ensureWranglerNodejsAlsFlag(root)) voidLog("Synced nodejs_als to Cloudflare config");
|
|
@@ -3651,7 +3581,6 @@ function createFrameworkPlugins(input) {
|
|
|
3651
3581
|
bindingNames,
|
|
3652
3582
|
...directCloudflareDestination && bindings.needsAI ? { directCloudflareAi: { gateway: config.ai?.gateway } } : {},
|
|
3653
3583
|
websockets: websocketRoutes,
|
|
3654
|
-
sandbox: sandboxConfig,
|
|
3655
3584
|
live: liveConfig
|
|
3656
3585
|
})) voidLog("Synced bindings to Cloudflare config");
|
|
3657
3586
|
};
|
|
@@ -3684,19 +3613,90 @@ function createFrameworkPlugins(input) {
|
|
|
3684
3613
|
const svelteKitHooksInjectPlugin = {
|
|
3685
3614
|
name: "void:sveltekit-hooks-inject",
|
|
3686
3615
|
apply: "serve",
|
|
3616
|
+
config() {
|
|
3617
|
+
if (detected.class !== "b") return;
|
|
3618
|
+
return { ssr: { noExternal: ["void", ...dialect === "sqlite" ? [] : findVoidDependentPackages(root)] } };
|
|
3619
|
+
},
|
|
3620
|
+
resolveId: {
|
|
3621
|
+
order: "pre",
|
|
3622
|
+
filter: { id: /^void$/ },
|
|
3623
|
+
handler() {
|
|
3624
|
+
if (detected.class !== "b" || this.environment?.name === "client") return;
|
|
3625
|
+
return handlerFile;
|
|
3626
|
+
}
|
|
3627
|
+
},
|
|
3687
3628
|
transform(code, id) {
|
|
3688
3629
|
if (detected.class !== "b") return;
|
|
3689
3630
|
if (!id.includes(".svelte-kit/generated/server/internal") && !id.includes(".svelte-kit/generated/dev/server.js")) return;
|
|
3690
3631
|
return injectSvelteKitHooks(code, id, frameworkTriggersDispatchPath(root));
|
|
3691
3632
|
}
|
|
3692
3633
|
};
|
|
3634
|
+
const astroRequestScopePlugin = detected.name === "astro" && dialect !== "sqlite" ? {
|
|
3635
|
+
name: "void:astro-request-scope",
|
|
3636
|
+
enforce: "pre",
|
|
3637
|
+
resolveId: {
|
|
3638
|
+
filter: { id: /^@astrojs\/cloudflare\/entrypoints\/server(?:\.js)?$/ },
|
|
3639
|
+
handler(_id, importer) {
|
|
3640
|
+
if (importer === ASTRO_SCOPED_SERVER_ENTRY || this.environment?.name === "client") return;
|
|
3641
|
+
return ASTRO_SCOPED_SERVER_ENTRY;
|
|
3642
|
+
}
|
|
3643
|
+
},
|
|
3644
|
+
load: {
|
|
3645
|
+
filter: { id: /^\0void:astro-server-entry$/ },
|
|
3646
|
+
handler() {
|
|
3647
|
+
return `import original from ${JSON.stringify(ASTRO_SERVER_ENTRY)};
|
|
3648
|
+
import { withRuntimeEnv } from ${JSON.stringify(envModuleFile)};
|
|
3649
|
+
export * from ${JSON.stringify(ASTRO_SERVER_ENTRY)};
|
|
3650
|
+
|
|
3651
|
+
export default {
|
|
3652
|
+
...original,
|
|
3653
|
+
fetch(request, env, ctx) {
|
|
3654
|
+
return withRuntimeEnv(env, () => original.fetch(request, env, ctx));
|
|
3655
|
+
},
|
|
3656
|
+
};
|
|
3657
|
+
`;
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
} : void 0;
|
|
3661
|
+
const svelteKitWorkerBuildPlugin = detected.class === "b" && dialect !== "sqlite" ? {
|
|
3662
|
+
name: "void:sveltekit-worker-build",
|
|
3663
|
+
apply: "build",
|
|
3664
|
+
enforce: "pre",
|
|
3665
|
+
configEnvironment(name, environment) {
|
|
3666
|
+
if (name !== "ssr") return;
|
|
3667
|
+
return {
|
|
3668
|
+
resolve: {
|
|
3669
|
+
conditions: environment.resolve?.conditions ? ["workerd", "worker"] : [
|
|
3670
|
+
"workerd",
|
|
3671
|
+
"worker",
|
|
3672
|
+
...defaultServerConditions
|
|
3673
|
+
],
|
|
3674
|
+
noExternal: [
|
|
3675
|
+
"void",
|
|
3676
|
+
"drizzle-orm",
|
|
3677
|
+
dialect === "mysql" ? "mysql2" : "pg",
|
|
3678
|
+
...findDependencyClosure("drizzle-orm", voidDir),
|
|
3679
|
+
...findDependencyClosure(dialect === "mysql" ? "mysql2" : "pg", voidDir),
|
|
3680
|
+
...findVoidDependentPackages(root)
|
|
3681
|
+
]
|
|
3682
|
+
},
|
|
3683
|
+
build: { rolldownOptions: { platform: "neutral" } }
|
|
3684
|
+
};
|
|
3685
|
+
},
|
|
3686
|
+
transform(code, id) {
|
|
3687
|
+
if (!id.includes(".svelte-kit/generated/server/internal") && !id.includes(".svelte-kit/generated/build/server.js")) return;
|
|
3688
|
+
return injectSvelteKitBuildHooks(code, id, envModuleFile);
|
|
3689
|
+
}
|
|
3690
|
+
} : void 0;
|
|
3693
3691
|
return [
|
|
3694
3692
|
devTriggerSecretGuardPlugin(),
|
|
3695
3693
|
createCloudflareBuiltinsExternalPlugin(),
|
|
3696
3694
|
wranglerCompatPlugin,
|
|
3697
3695
|
wranglerSyncPlugin,
|
|
3698
3696
|
...nuxtVite8WebSocketCompatPlugin ? [nuxtVite8WebSocketCompatPlugin] : [],
|
|
3697
|
+
...astroRequestScopePlugin ? [astroRequestScopePlugin] : [],
|
|
3699
3698
|
svelteKitHooksInjectPlugin,
|
|
3699
|
+
...svelteKitWorkerBuildPlugin ? [svelteKitWorkerBuildPlugin] : [],
|
|
3700
3700
|
clientStubsPlugin,
|
|
3701
3701
|
serverRuntimeOptimizerPlugin,
|
|
3702
3702
|
bindingRuntimePlugin(bindingNames),
|
|
@@ -3705,19 +3705,17 @@ function createFrameworkPlugins(input) {
|
|
|
3705
3705
|
envClientFoldPlugin(),
|
|
3706
3706
|
drizzlePlugin(root, false, dialect, {
|
|
3707
3707
|
d1BindingName: bindingNames?.d1,
|
|
3708
|
-
forceVirtualDb:
|
|
3708
|
+
forceVirtualDb: bindingNames?.d1 !== void 0,
|
|
3709
3709
|
localD1DatabaseId: localD1.databaseId,
|
|
3710
|
-
localD1PersistRoot: frameworkPersistRoot
|
|
3710
|
+
localD1PersistRoot: frameworkPersistRoot,
|
|
3711
|
+
nitroBundlesServer: detected.name === "nuxt" || detected.name === "analog"
|
|
3711
3712
|
}),
|
|
3712
3713
|
migrationPlugin(root, dialect, localD1.databaseId, frameworkPersistRoot, { enabled: false }),
|
|
3713
|
-
devTriggersHintPlugin(root,
|
|
3714
|
-
framework: true,
|
|
3715
|
-
devTriggerToken
|
|
3716
|
-
}),
|
|
3714
|
+
devTriggersHintPlugin(root, devTriggerToken),
|
|
3717
3715
|
frameworkTriggersPlugin(root, { devTriggerToken }),
|
|
3718
3716
|
...detected.name === "nuxt" ? [nitroDevTriggerInjectPlugin(root, { serverDir: "server" })] : [],
|
|
3719
3717
|
...detected.name === "analog" ? [analogDevTriggerInjectPlugin(root)] : [],
|
|
3720
|
-
...detected.name === "astro" ? [astroDevTriggerInjectPlugin(root)] : [],
|
|
3718
|
+
...detected.name === "astro" ? [createBareVoidRedirectPlugin(), astroDevTriggerInjectPlugin(root)] : [],
|
|
3721
3719
|
implicitDeployGuard
|
|
3722
3720
|
];
|
|
3723
3721
|
}
|
|
@@ -3790,13 +3788,17 @@ function honoMiddleware(getApp) {
|
|
|
3790
3788
|
* single SSR build for API-only apps
|
|
3791
3789
|
*/
|
|
3792
3790
|
function nodeTargetPlugin(target) {
|
|
3791
|
+
const unavailable = (id, root, importer) => {
|
|
3792
|
+
const source = importer ? ` Imported by ${relative(root, importer)}.` : "";
|
|
3793
|
+
return /* @__PURE__ */ new Error(`target: '${id}' is not available with target '${target}'. CF bindings require target: "cloudflare".${source}`);
|
|
3794
|
+
};
|
|
3793
3795
|
return [{
|
|
3794
3796
|
name: "void:node-target",
|
|
3795
3797
|
enforce: "pre",
|
|
3796
3798
|
resolveId: {
|
|
3797
3799
|
filter: { id: CF_ONLY_REGEX },
|
|
3798
|
-
handler(id) {
|
|
3799
|
-
throw
|
|
3800
|
+
handler(id, importer) {
|
|
3801
|
+
throw unavailable(id, this.environment.config.root, importer);
|
|
3800
3802
|
}
|
|
3801
3803
|
},
|
|
3802
3804
|
renderChunk(code, chunk) {
|
|
@@ -3808,8 +3810,13 @@ function nodeTargetPlugin(target) {
|
|
|
3808
3810
|
};
|
|
3809
3811
|
},
|
|
3810
3812
|
config(_, { command }) {
|
|
3811
|
-
if (command !== "build") return;
|
|
3812
3813
|
const root = process.cwd();
|
|
3814
|
+
const ssr = { noExternal: [
|
|
3815
|
+
"void",
|
|
3816
|
+
/^@void\//,
|
|
3817
|
+
...findVoidDependentPackages(root)
|
|
3818
|
+
] };
|
|
3819
|
+
if (command !== "build") return { ssr };
|
|
3813
3820
|
const voidDir = join(root, ".void");
|
|
3814
3821
|
const ssrBuildOptions = {
|
|
3815
3822
|
outDir: "dist/ssr",
|
|
@@ -3826,18 +3833,22 @@ function nodeTargetPlugin(target) {
|
|
|
3826
3833
|
}
|
|
3827
3834
|
};
|
|
3828
3835
|
if (existsSync(readProjectPaths(root).pagesDir)) return {
|
|
3836
|
+
ssr,
|
|
3829
3837
|
build: { outDir: "dist/client" },
|
|
3830
3838
|
environments: { ssr: { build: ssrBuildOptions } },
|
|
3831
3839
|
builder: {}
|
|
3832
3840
|
};
|
|
3833
|
-
return {
|
|
3834
|
-
ssr
|
|
3835
|
-
|
|
3836
|
-
|
|
3841
|
+
return {
|
|
3842
|
+
ssr,
|
|
3843
|
+
build: {
|
|
3844
|
+
ssr: true,
|
|
3845
|
+
...ssrBuildOptions
|
|
3846
|
+
}
|
|
3847
|
+
};
|
|
3837
3848
|
},
|
|
3838
3849
|
async buildApp(builder) {
|
|
3839
3850
|
await builder.build(builder.environments.ssr);
|
|
3840
|
-
await builder.build(builder.environments.client);
|
|
3851
|
+
if (builder.environments.client) await builder.build(builder.environments.client);
|
|
3841
3852
|
},
|
|
3842
3853
|
configureServer(server) {
|
|
3843
3854
|
server.middlewares.use(honoMiddleware(async () => {
|
|
@@ -3855,6 +3866,20 @@ function nodeTargetPlugin(target) {
|
|
|
3855
3866
|
return appPromise;
|
|
3856
3867
|
}));
|
|
3857
3868
|
}
|
|
3869
|
+
}, {
|
|
3870
|
+
name: "void:node-target-cloudflare-modules",
|
|
3871
|
+
apply: "build",
|
|
3872
|
+
enforce: "pre",
|
|
3873
|
+
resolveId: {
|
|
3874
|
+
filter: { id: /^cloudflare:/ },
|
|
3875
|
+
handler(id, importer, options) {
|
|
3876
|
+
if (options.kind === "dynamic-import") return {
|
|
3877
|
+
id,
|
|
3878
|
+
external: true
|
|
3879
|
+
};
|
|
3880
|
+
throw unavailable(id, this.environment.config.root, importer);
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3858
3883
|
}];
|
|
3859
3884
|
}
|
|
3860
3885
|
//#endregion
|
|
@@ -4096,9 +4121,10 @@ function stampClientAssetCachePolicy(bundle, manifestPath, headerRules = []) {
|
|
|
4096
4121
|
const asset = bundle[manifestPath];
|
|
4097
4122
|
if (asset?.type !== "asset") return;
|
|
4098
4123
|
const fingerprinted = /* @__PURE__ */ new Set();
|
|
4099
|
-
const authoredCachePatterns = headerRules.filter((rule) => rule.headers.some(([name]) => name.toLowerCase() === "cache-control")).map((rule) =>
|
|
4124
|
+
const authoredCachePatterns = headerRules.filter((rule) => rule.headers.some(([name]) => name.toLowerCase() === "cache-control")).map((rule) => rule.pattern);
|
|
4125
|
+
for (const pattern of authoredCachePatterns) compilePattern(pattern);
|
|
4100
4126
|
for (const item of Object.values(bundle)) if (item.type === "chunk" && typeof item.preliminaryFileName === "string" && item.preliminaryFileName !== item.fileName) {
|
|
4101
|
-
if (!authoredCachePatterns.some((pattern) => pattern
|
|
4127
|
+
if (!authoredCachePatterns.some((pattern) => matchPattern(pattern, "/" + item.fileName))) fingerprinted.add(item.fileName);
|
|
4102
4128
|
}
|
|
4103
4129
|
const manifest = JSON.parse(String(asset.source));
|
|
4104
4130
|
for (const entry of Object.values(manifest)) if (entry.file && fingerprinted.has(entry.file)) entry.immutableFiles = [entry.file];
|
|
@@ -4148,7 +4174,6 @@ function routingPlugin(root, options) {
|
|
|
4148
4174
|
const normalizedQueuesDir = normalizePath(queuesDir);
|
|
4149
4175
|
const normalizedEmailDir = normalizePath(emailDir);
|
|
4150
4176
|
const normalizedPagesDir = normalizePath(pagesDir);
|
|
4151
|
-
const normalizedSsrDir = normalizePath(ssrDir);
|
|
4152
4177
|
const ssrEntryAbsPaths = new Set([...SSR_SERVER_ENTRY_RELATIVE_PATHS, ...SSR_CLIENT_ENTRY_RELATIVE_PATHS].map((path) => normalizePath(join(ssrDir, path.split("/").pop()))));
|
|
4153
4178
|
function hasEmailHandlers() {
|
|
4154
4179
|
const email = scan?.email;
|
|
@@ -4168,17 +4193,7 @@ function routingPlugin(root, options) {
|
|
|
4168
4193
|
writeFileIfChanged(join(outDir, "queues.d.ts"), dts);
|
|
4169
4194
|
}
|
|
4170
4195
|
async function rescan(refresh = false) {
|
|
4171
|
-
|
|
4172
|
-
if (!analysis) {
|
|
4173
|
-
const config = readConfig(root);
|
|
4174
|
-
analysis = analyzeApplicationSync(root, {
|
|
4175
|
-
config: {
|
|
4176
|
-
...config,
|
|
4177
|
-
output: options.output ?? config.output
|
|
4178
|
-
},
|
|
4179
|
-
environment: routeEnvironment
|
|
4180
|
-
});
|
|
4181
|
-
}
|
|
4196
|
+
const analysis = options.getApplicationAnalysis(routeEnvironment, refresh);
|
|
4182
4197
|
scan = (await completeApplicationAnalysis(analysis)).scan;
|
|
4183
4198
|
authConfigPath = analysis.authConfigPath;
|
|
4184
4199
|
const entries = validateSsrEntries(root, paths);
|
|
@@ -4203,8 +4218,7 @@ function routingPlugin(root, options) {
|
|
|
4203
4218
|
};
|
|
4204
4219
|
const remote = options.remoteMode ? {
|
|
4205
4220
|
bindingNames: options.bindingNames,
|
|
4206
|
-
remotePath: resolveFile("#self/remote")
|
|
4207
|
-
envPath: resolveFile("#self/_env")
|
|
4221
|
+
remotePath: resolveFile("#self/remote")
|
|
4208
4222
|
} : void 0;
|
|
4209
4223
|
function getEnvSchemaModule() {
|
|
4210
4224
|
const envFile = findEnvFileForPaths(root, paths);
|
|
@@ -4214,10 +4228,10 @@ function routingPlugin(root, options) {
|
|
|
4214
4228
|
helperPath: resolveFile("#self/env")
|
|
4215
4229
|
};
|
|
4216
4230
|
}
|
|
4231
|
+
const runtimeEmailPath = resolveFile("#self/email");
|
|
4217
4232
|
const compileOptions = {
|
|
4218
4233
|
honoPath: resolveFile("hono"),
|
|
4219
4234
|
runtimeEnvPath: resolveFile("#self/_env"),
|
|
4220
|
-
runtimeEmailPath: resolveFile("#self/email"),
|
|
4221
4235
|
emailDir,
|
|
4222
4236
|
projectRoot: root,
|
|
4223
4237
|
homeDir: homedir(),
|
|
@@ -4241,10 +4255,7 @@ function routingPlugin(root, options) {
|
|
|
4241
4255
|
dir: publicDir,
|
|
4242
4256
|
routing: options.routing
|
|
4243
4257
|
});
|
|
4244
|
-
|
|
4245
|
-
lintDuplicateSources(merged.fallbackRules, "fallbacks (post-asset)");
|
|
4246
|
-
lintDestinationSplats(merged.redirectRules, "redirects/rewrites (pre-asset)");
|
|
4247
|
-
lintDestinationSplats(merged.fallbackRules, "fallbacks (post-asset)");
|
|
4258
|
+
lintRoutingPhases(merged);
|
|
4248
4259
|
compileOptions.headerRules = merged.headerRules.length > 0 ? merged.headerRules : void 0;
|
|
4249
4260
|
compileOptions.redirectRules = merged.redirectRules.length > 0 ? merged.redirectRules : void 0;
|
|
4250
4261
|
compileOptions.fallbackRules = merged.fallbackRules;
|
|
@@ -4260,8 +4271,8 @@ function routingPlugin(root, options) {
|
|
|
4260
4271
|
compileOptions.auth = {
|
|
4261
4272
|
authRuntimePath: dialect === "postgresql" ? join(runtimeDir, "better-auth-pg.mjs") : dialect === "mysql" ? join(runtimeDir, "better-auth-mysql.mjs") : join(runtimeDir, "better-auth.mjs"),
|
|
4262
4273
|
authConfigPath,
|
|
4263
|
-
authDatabasePath:
|
|
4264
|
-
authSchemaPath:
|
|
4274
|
+
authDatabasePath: join(outDir, "better-auth-db.ts"),
|
|
4275
|
+
authSchemaPath: join(outDir, "better-auth-schema.ts"),
|
|
4265
4276
|
dialect,
|
|
4266
4277
|
providers: config.auth?.providers ?? null
|
|
4267
4278
|
};
|
|
@@ -4277,16 +4288,13 @@ function routingPlugin(root, options) {
|
|
|
4277
4288
|
...resolvedConfig?.command === "serve" ? loadLocalEnv(root) : {},
|
|
4278
4289
|
...process.env
|
|
4279
4290
|
};
|
|
4280
|
-
const
|
|
4281
|
-
|
|
4282
|
-
writeFileIfChanged(
|
|
4283
|
-
writeFileIfChanged(databasePath, generateVoidAuthDatabaseModule({
|
|
4291
|
+
const { authSchemaPath, authDatabasePath } = compileOptions.auth;
|
|
4292
|
+
writeFileIfChanged(authSchemaPath, generateVoidAuthDrizzleSchema(authRuntime, env));
|
|
4293
|
+
writeFileIfChanged(authDatabasePath, generateVoidAuthDatabaseModule({
|
|
4284
4294
|
dialect: compileOptions.auth.dialect,
|
|
4285
|
-
schemaImportPath:
|
|
4295
|
+
schemaImportPath: authSchemaPath,
|
|
4286
4296
|
drizzleAdapterPath
|
|
4287
4297
|
}));
|
|
4288
|
-
compileOptions.auth.authSchemaPath = schemaPath;
|
|
4289
|
-
compileOptions.auth.authDatabasePath = databasePath;
|
|
4290
4298
|
}
|
|
4291
4299
|
let resolvedConfig = null;
|
|
4292
4300
|
let isrRevalidate;
|
|
@@ -4328,38 +4336,15 @@ function routingPlugin(root, options) {
|
|
|
4328
4336
|
headConfig: options.headConfig
|
|
4329
4337
|
};
|
|
4330
4338
|
}
|
|
4331
|
-
function shouldServeSpaFallback() {
|
|
4332
|
-
if (!scan) return false;
|
|
4333
|
-
return resolveCurrentAssetRoutingPolicy().workerSpaFallback;
|
|
4334
|
-
}
|
|
4335
|
-
/**
|
|
4336
|
-
* The `not_found_handling` the generated worker entry must agree with. Read
|
|
4337
|
-
* off the SAME resolved policy that produces the wrangler asset config, so
|
|
4338
|
-
* the emitted `serveWithAssets` can never disagree with the platform switch
|
|
4339
|
-
* it is standing in for.
|
|
4340
|
-
*/
|
|
4341
|
-
function currentNotFoundHandling() {
|
|
4342
|
-
return resolveCurrentAssetRoutingPolicy().assetConfig.not_found_handling ?? "none";
|
|
4343
|
-
}
|
|
4344
4339
|
function resolveCurrentAssetRoutingPolicy() {
|
|
4345
|
-
|
|
4346
|
-
isSsr: Boolean(ssr),
|
|
4347
|
-
hasPages: false,
|
|
4348
|
-
hasApiRoutes: compileOptions.auth !== null,
|
|
4349
|
-
hasDocumentRoutes: false,
|
|
4350
|
-
hasMiddleware: false,
|
|
4351
|
-
hasWebSockets: false,
|
|
4352
|
-
authEnabled: compileOptions.auth !== null,
|
|
4353
|
-
liveEnabled: options.live !== void 0,
|
|
4354
|
-
notFound: options.routing?.notFound
|
|
4355
|
-
});
|
|
4340
|
+
const { pages, routes, websockets = [], middleware } = scan;
|
|
4356
4341
|
return resolveAssetRoutingPolicy({
|
|
4357
4342
|
isSsr: Boolean(ssr),
|
|
4358
|
-
hasPages:
|
|
4359
|
-
hasApiRoutes: hasApiRoutes(
|
|
4360
|
-
hasDocumentRoutes: hasDocumentRoutes(
|
|
4361
|
-
hasMiddleware:
|
|
4362
|
-
hasWebSockets: hasDocumentRoutes(
|
|
4343
|
+
hasPages: pages.pages.length > 0,
|
|
4344
|
+
hasApiRoutes: hasApiRoutes(routes) || hasApiRoutes(websockets) || compileOptions.auth !== null,
|
|
4345
|
+
hasDocumentRoutes: hasDocumentRoutes(routes),
|
|
4346
|
+
hasMiddleware: middleware.length > 0,
|
|
4347
|
+
hasWebSockets: hasDocumentRoutes(websockets),
|
|
4363
4348
|
authEnabled: compileOptions.auth !== null,
|
|
4364
4349
|
liveEnabled: options.live !== void 0,
|
|
4365
4350
|
notFound: options.routing?.notFound
|
|
@@ -4377,6 +4362,7 @@ function routingPlugin(root, options) {
|
|
|
4377
4362
|
}
|
|
4378
4363
|
/** Write the Cloudflare worker entry from the completed scan. */
|
|
4379
4364
|
function writeWorkerEntry(isr) {
|
|
4365
|
+
const policy = resolveCurrentAssetRoutingPolicy();
|
|
4380
4366
|
writeFileIfChanged(join(outDir, "entry.ts"), compileWorkerEntry({
|
|
4381
4367
|
versionMetadataBinding: options.getVersionMetadataBinding?.(),
|
|
4382
4368
|
hasQueues: scan.queues.length > 0,
|
|
@@ -4384,15 +4370,15 @@ function routingPlugin(root, options) {
|
|
|
4384
4370
|
assetsDir: resolvedConfig?.build.assetsDir,
|
|
4385
4371
|
webSocketClasses: [...(scan.websockets ?? []).map((route) => route.className), ...options.websocketTombstones ?? []],
|
|
4386
4372
|
runtimeEnvPath: compileOptions.runtimeEnvPath,
|
|
4387
|
-
runtimeEmailPath
|
|
4373
|
+
runtimeEmailPath,
|
|
4388
4374
|
envSchemaModule: getEnvSchemaModule(),
|
|
4389
4375
|
sandbox: sandboxEntry,
|
|
4390
4376
|
hasEmail: hasEmailHandlers(),
|
|
4391
|
-
serveSpaFallback:
|
|
4377
|
+
serveSpaFallback: policy.workerSpaFallback,
|
|
4392
4378
|
live: options.live,
|
|
4393
4379
|
dev: compileOptions.dev,
|
|
4394
4380
|
isr,
|
|
4395
|
-
notFound:
|
|
4381
|
+
notFound: policy.assetConfig.not_found_handling ?? "none",
|
|
4396
4382
|
durableObjects: options.durableObjects
|
|
4397
4383
|
}));
|
|
4398
4384
|
}
|
|
@@ -4404,7 +4390,7 @@ function routingPlugin(root, options) {
|
|
|
4404
4390
|
remote,
|
|
4405
4391
|
webSocketClasses: options.websocketTombstones,
|
|
4406
4392
|
runtimeEnvPath: compileOptions.runtimeEnvPath,
|
|
4407
|
-
runtimeEmailPath
|
|
4393
|
+
runtimeEmailPath,
|
|
4408
4394
|
envSchemaModule: getEnvSchemaModule(),
|
|
4409
4395
|
sandbox: sandboxEntry,
|
|
4410
4396
|
live: options.live,
|
|
@@ -4470,14 +4456,13 @@ function routingPlugin(root, options) {
|
|
|
4470
4456
|
if (!options.target) {
|
|
4471
4457
|
const migrationsDir = paths.migrationsDir;
|
|
4472
4458
|
if (existsSync(migrationsDir) || compileOptions.auth) {
|
|
4473
|
-
const { collectMigrations } = await import("./collect-
|
|
4474
|
-
const { buildMigrationPlanBundle } = await import("./plan-
|
|
4459
|
+
const { collectMigrations } = await import("./collect-Cae8A7Zr.mjs");
|
|
4460
|
+
const { buildMigrationPlanBundle } = await import("./plan-CKX_jWnD.mjs");
|
|
4475
4461
|
const migrations = existsSync(migrationsDir) ? collectMigrations(migrationsDir) : [];
|
|
4476
4462
|
const dialect = getDatabaseDialect(readConfig(root));
|
|
4477
4463
|
compileOptions.migrationHandlerPath = resolveFile(dialect === "postgresql" ? "#self/runtime/migration-handler-pg" : dialect === "mysql" ? "#self/runtime/migration-handler-mysql" : "#self/runtime/migration-handler");
|
|
4478
4464
|
compileOptions.migrations = migrations;
|
|
4479
4465
|
compileOptions.migrationPlanBundle = dialect === "sqlite" ? buildMigrationPlanBundle(migrations) : void 0;
|
|
4480
|
-
compileOptions.migrationDialect = dialect;
|
|
4481
4466
|
}
|
|
4482
4467
|
}
|
|
4483
4468
|
if (options.target) writeNodeEntries(options.target);
|
|
@@ -4511,10 +4496,7 @@ function routingPlugin(root, options) {
|
|
|
4511
4496
|
async handler(id) {
|
|
4512
4497
|
const virtualClient = VIRTUAL_CLIENT_RE.exec(id);
|
|
4513
4498
|
if (virtualClient?.[1] === "browser") return compileBrowserClient(getClientAuthPath(id), fetchPath, fetchStreamPath);
|
|
4514
|
-
if (virtualClient?.[1] === "worker")
|
|
4515
|
-
if (options.target) return compileNodeClient(getClientAuthPath(id));
|
|
4516
|
-
return compileWorkerClient(getClientAuthPath(id));
|
|
4517
|
-
}
|
|
4499
|
+
if (virtualClient?.[1] === "worker") return compileWorkerClient(getClientAuthPath(id), Boolean(options.target));
|
|
4518
4500
|
if (id !== VIRTUAL_ROUTES_ID) return;
|
|
4519
4501
|
if (this?.environment?.name === "client") throw new Error(`${VIRTUAL_ROUTES_ID} is server-only and cannot be loaded by client code.`);
|
|
4520
4502
|
if (!scan) await rescan();
|
|
@@ -4525,9 +4507,7 @@ function routingPlugin(root, options) {
|
|
|
4525
4507
|
const watcher = devServer.watcher;
|
|
4526
4508
|
const handleFileChange = async (path, event) => {
|
|
4527
4509
|
const normalizedPath = normalizePath(path);
|
|
4528
|
-
|
|
4529
|
-
if (!sourceConventionChanged && !isInDirectory(normalizedPath, normalizedSsrDir)) return;
|
|
4530
|
-
if (!sourceConventionChanged && isInDirectory(normalizedPath, normalizedSsrDir) && !ssrEntryAbsPaths.has(normalizedPath)) return;
|
|
4510
|
+
if (!(isInDirectory(normalizedPath, normalizedRoutesDir) || isInDirectory(normalizedPath, normalizedMiddlewareDir) || isInDirectory(normalizedPath, normalizedJobsDir) || isInDirectory(normalizedPath, normalizedQueuesDir) || isInDirectory(normalizedPath, normalizedEmailDir) || isInDirectory(normalizedPath, normalizedPagesDir) || isPotentialAuthConfigPath(normalizedPath) || isPotentialEnvFilePath(normalizedPath)) && !ssrEntryAbsPaths.has(normalizedPath)) return;
|
|
4531
4511
|
await rescan(true);
|
|
4532
4512
|
resolveAuthCompileOptions();
|
|
4533
4513
|
if (event !== "change" && options.onDevAssetRoutingPolicyChange?.(resolveCurrentAssetRoutingPolicy()) === true) {
|
|
@@ -4720,13 +4700,12 @@ function mergeWorkerBindings(resolved, input) {
|
|
|
4720
4700
|
bucket_name: "default"
|
|
4721
4701
|
}];
|
|
4722
4702
|
const resolvedAi = resolved.ai;
|
|
4723
|
-
const resultAi = result.ai;
|
|
4724
4703
|
const aiBindingName = resolveWorkersAiBindingName(resolvedAi, bindingNames?.ai);
|
|
4725
|
-
if (viteCommand === "serve" && bindings.needsAI && directCloudflareDestination &&
|
|
4704
|
+
if (viteCommand === "serve" && bindings.needsAI && directCloudflareDestination && typeof resolvedAi === "object" && resolvedAi !== null && "binding" in resolvedAi && typeof resolvedAi.binding === "string") result.ai = {
|
|
4726
4705
|
...resolvedAi,
|
|
4727
4706
|
remote: true
|
|
4728
4707
|
};
|
|
4729
|
-
else if (shouldBindWorkersAi(viteCommand, bindings.needsAI, resolvedAi,
|
|
4708
|
+
else if (shouldBindWorkersAi(viteCommand, bindings.needsAI, resolvedAi, result.ai, directCloudflareDestination)) result.ai = {
|
|
4730
4709
|
binding: aiBindingName,
|
|
4731
4710
|
...viteCommand === "serve" && { remote: true }
|
|
4732
4711
|
};
|
|
@@ -4856,14 +4835,14 @@ function mergeWorkerBindings(resolved, input) {
|
|
|
4856
4835
|
result.vars = vars;
|
|
4857
4836
|
}
|
|
4858
4837
|
}
|
|
4859
|
-
|
|
4838
|
+
const versionMetadataBinding = selectNativeVersionMetadataBinding(resolved, {
|
|
4860
4839
|
nativeBuild: viteCommand === "build" && process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] === "1",
|
|
4861
4840
|
preserveBindings: process.env[CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV] === "1"
|
|
4862
4841
|
});
|
|
4863
|
-
if (
|
|
4864
|
-
const owner = findBindingNameOwner(result, "version_metadata",
|
|
4865
|
-
if (owner) throw new Error(`Cloudflare version metadata binding ${
|
|
4866
|
-
if (!resolved.version_metadata) result.version_metadata = { binding:
|
|
4842
|
+
if (versionMetadataBinding) {
|
|
4843
|
+
const owner = findBindingNameOwner(result, "version_metadata", versionMetadataBinding);
|
|
4844
|
+
if (owner) throw new Error(`Cloudflare version metadata binding ${versionMetadataBinding} conflicts with ${owner}.`);
|
|
4845
|
+
if (!resolved.version_metadata) result.version_metadata = { binding: versionMetadataBinding };
|
|
4867
4846
|
}
|
|
4868
4847
|
finalizeDurableObjectPatch(resolved, result, [
|
|
4869
4848
|
...environmentWebsocketRoutes.map((route) => ({
|
|
@@ -4883,51 +4862,41 @@ function mergeWorkerBindings(resolved, input) {
|
|
|
4883
4862
|
class_name: liveConfig.className
|
|
4884
4863
|
}] : []
|
|
4885
4864
|
]);
|
|
4886
|
-
return
|
|
4865
|
+
return {
|
|
4866
|
+
patch: result,
|
|
4867
|
+
versionMetadataBinding
|
|
4868
|
+
};
|
|
4887
4869
|
}
|
|
4888
4870
|
//#endregion
|
|
4889
4871
|
//#region src/index.ts
|
|
4890
4872
|
const scheduledPointerCleanups = /* @__PURE__ */ new Set();
|
|
4891
4873
|
const scheduledPreviewPointerCleanups = /* @__PURE__ */ new Set();
|
|
4892
|
-
/**
|
|
4893
|
-
* Void plugin — the main entry point.
|
|
4894
|
-
*
|
|
4895
|
-
* Composes:
|
|
4896
|
-
* 1. Routing plugin (file-based routing from routes/ and middleware/)
|
|
4897
|
-
* 2. Migration plugin (auto-apply .sql migrations on dev startup)
|
|
4898
|
-
* 3. @cloudflare/vite-plugin (workerd runtime, HMR, builds)
|
|
4899
|
-
*
|
|
4900
|
-
* Binding inference runs synchronously here so results are available
|
|
4901
|
-
* before the Cloudflare plugin initializes.
|
|
4902
|
-
*
|
|
4903
|
-
* The Cloudflare plugin reads Void's generated config and provides it to our
|
|
4904
|
-
* config function. Bindings already defined there (with real IDs for
|
|
4905
|
-
* production deployment) are preserved — we only add inferred bindings
|
|
4906
|
-
* that are missing. This allows `vite build && wrangler deploy` to work
|
|
4907
|
-
* for deploying directly to Cloudflare without the Void platform.
|
|
4908
|
-
*/
|
|
4874
|
+
/** Returns the Vite plugins that build and serve a Void app for its configured target. */
|
|
4909
4875
|
function voidPlugin(options) {
|
|
4910
4876
|
const root = process.cwd();
|
|
4911
4877
|
const directCloudflareDestination = readDeploymentPlatform(root) === "cloudflare";
|
|
4878
|
+
if (directCloudflareDestination) selectVoidCloudflareLogin();
|
|
4912
4879
|
warnIfPackageJsonIsNotEsm(root);
|
|
4913
4880
|
const devTriggerToken = isViteBuildOrPreview() ? crypto.randomUUID() : getOrCreateDevTriggerToken(root);
|
|
4914
4881
|
const config = readConfig(root);
|
|
4915
4882
|
const projectCloudflareConfigPath = !isNodeTarget(config.target) ? materializeCloudflareConfig(root) : void 0;
|
|
4916
4883
|
const cloudflareConfigPath = projectCloudflareConfigPath && existsSync(projectCloudflareConfigPath) ? projectCloudflareConfigPath : void 0;
|
|
4917
4884
|
let previewing = false;
|
|
4885
|
+
const restorePreviewPointer = () => {
|
|
4886
|
+
if (!existsSync(join(root, "void.config.ts"))) return;
|
|
4887
|
+
if (restoreCloudflarePreviewPointer(root) && !scheduledPreviewPointerCleanups.has(root)) {
|
|
4888
|
+
scheduledPreviewPointerCleanups.add(root);
|
|
4889
|
+
process.once("exit", () => {
|
|
4890
|
+
rmSync(join(root, ".wrangler", "deploy", "config.json"), { force: true });
|
|
4891
|
+
});
|
|
4892
|
+
}
|
|
4893
|
+
};
|
|
4918
4894
|
const implicitDeployGuard = {
|
|
4919
4895
|
name: "void:remove-implicit-cloudflare-deploy-pointer",
|
|
4920
4896
|
enforce: "pre",
|
|
4921
4897
|
config(_config, environment) {
|
|
4922
4898
|
previewing = environment.isPreview === true;
|
|
4923
|
-
if (previewing
|
|
4924
|
-
if (restoreCloudflarePreviewPointer(root) && !scheduledPreviewPointerCleanups.has(root)) {
|
|
4925
|
-
scheduledPreviewPointerCleanups.add(root);
|
|
4926
|
-
process.once("exit", () => {
|
|
4927
|
-
rmSync(join(root, ".wrangler", "deploy", "config.json"), { force: true });
|
|
4928
|
-
});
|
|
4929
|
-
}
|
|
4930
|
-
}
|
|
4899
|
+
if (previewing) restorePreviewPointer();
|
|
4931
4900
|
},
|
|
4932
4901
|
closeBundle() {
|
|
4933
4902
|
if (!previewing && existsSync(join(root, "void.config.ts")) && process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] !== "1") {
|
|
@@ -4943,7 +4912,7 @@ function voidPlugin(options) {
|
|
|
4943
4912
|
};
|
|
4944
4913
|
let application = analyzeApplicationSync(root, { config });
|
|
4945
4914
|
const { paths, dialect, bindingNames, authConfigPath } = application;
|
|
4946
|
-
const analyses = /* @__PURE__ */ new Map(
|
|
4915
|
+
const analyses = /* @__PURE__ */ new Map();
|
|
4947
4916
|
const getApplicationAnalysis = (environment, refresh = false) => {
|
|
4948
4917
|
let result = refresh ? void 0 : analyses.get(environment);
|
|
4949
4918
|
if (!result) {
|
|
@@ -4960,6 +4929,7 @@ function voidPlugin(options) {
|
|
|
4960
4929
|
assertNoRootSourceConventionConflicts(paths);
|
|
4961
4930
|
const detected = application.framework;
|
|
4962
4931
|
const framework = detected?.class === "a" ? detected.name : void 0;
|
|
4932
|
+
if (detected?.name === "astro" && process.argv[2] === "preview") restorePreviewPointer();
|
|
4963
4933
|
const scanDirs = config.inference?.scanDirs ?? (detected ? FRAMEWORK_SCAN_DIRS : void 0);
|
|
4964
4934
|
const frameworkOwnsCloudflareRuntime = detected !== void 0 && (detected.class === "b" || detected.class === "c");
|
|
4965
4935
|
const localD1PersistRoot = frameworkOwnsCloudflareRuntime ? join(root, ".wrangler", "state") : options?.persistTo ?? join(root, ".void");
|
|
@@ -4977,7 +4947,7 @@ function voidPlugin(options) {
|
|
|
4977
4947
|
const hasInboundEmail = hasEmailHandlers(application.email);
|
|
4978
4948
|
if (detected && hasInboundEmail) throw new Error("email: inbound email handlers are only supported in Void apps. Remove the email/ directory — `sendEmail` from void/email keeps working.");
|
|
4979
4949
|
const clientStubsPlugin = createClientStubsPlugin();
|
|
4980
|
-
const serverRuntimeOptimizerPlugin = createServerRuntimeOptimizerPlugin();
|
|
4950
|
+
const serverRuntimeOptimizerPlugin = createServerRuntimeOptimizerPlugin(dialect, () => readWranglerCompat(root, config));
|
|
4981
4951
|
const queues = framework ? [] : application.queues;
|
|
4982
4952
|
const websocketRoutes = framework ? [] : application.allWebsockets;
|
|
4983
4953
|
const durableObjects = application.durableObjects;
|
|
@@ -5014,12 +4984,10 @@ function voidPlugin(options) {
|
|
|
5014
4984
|
application,
|
|
5015
4985
|
bindingNames,
|
|
5016
4986
|
websocketRoutes,
|
|
5017
|
-
sandboxConfig,
|
|
5018
4987
|
liveConfig,
|
|
5019
4988
|
detected,
|
|
5020
4989
|
clientStubsPlugin,
|
|
5021
4990
|
serverRuntimeOptimizerPlugin,
|
|
5022
|
-
authEnabled,
|
|
5023
4991
|
devTriggerToken,
|
|
5024
4992
|
implicitDeployGuard
|
|
5025
4993
|
});
|
|
@@ -5044,7 +5012,7 @@ function voidPlugin(options) {
|
|
|
5044
5012
|
const outDir = join(root, ".void");
|
|
5045
5013
|
mkdirSync(outDir, { recursive: true });
|
|
5046
5014
|
function mergeBindings(resolved) {
|
|
5047
|
-
|
|
5015
|
+
const merged = mergeWorkerBindings(resolved, {
|
|
5048
5016
|
websocketRoutes,
|
|
5049
5017
|
routeEnvironment,
|
|
5050
5018
|
workerConfig,
|
|
@@ -5064,14 +5032,10 @@ function voidPlugin(options) {
|
|
|
5064
5032
|
shouldEmitLive,
|
|
5065
5033
|
liveConfig,
|
|
5066
5034
|
root,
|
|
5067
|
-
remoteMode
|
|
5068
|
-
get versionMetadataBinding() {
|
|
5069
|
-
return versionMetadataBinding;
|
|
5070
|
-
},
|
|
5071
|
-
set versionMetadataBinding(value) {
|
|
5072
|
-
versionMetadataBinding = value;
|
|
5073
|
-
}
|
|
5035
|
+
remoteMode
|
|
5074
5036
|
});
|
|
5037
|
+
versionMetadataBinding = merged.versionMetadataBinding;
|
|
5038
|
+
return merged.patch;
|
|
5075
5039
|
}
|
|
5076
5040
|
function applyEnvSchema(facts) {
|
|
5077
5041
|
envSchemaFacts = facts;
|
|
@@ -5084,7 +5048,6 @@ function voidPlugin(options) {
|
|
|
5084
5048
|
application = getApplicationAnalysis(routeEnvironment);
|
|
5085
5049
|
bindings = application.bindings;
|
|
5086
5050
|
authEnabled = application.authEnabled;
|
|
5087
|
-
if (command === "serve" && directCloudflareDestination && bindings.needsAI) process.env.CLOUDFLARE_AUTH_USE_KEYRING = "true";
|
|
5088
5051
|
if (!framework && !isNodeTarget(config.target)) {
|
|
5089
5052
|
managedCloudflareBuild = command === "build" && Boolean(process.env.VOID_DEPLOY_PROJECT_ID);
|
|
5090
5053
|
assetRoutingPublicDir = userConfig.publicDir === false ? null : typeof userConfig.publicDir === "string" ? resolve(root, userConfig.publicDir) : join(root, "public");
|
|
@@ -5115,27 +5078,23 @@ function voidPlugin(options) {
|
|
|
5115
5078
|
return watchConfig;
|
|
5116
5079
|
},
|
|
5117
5080
|
configureServer(server) {
|
|
5118
|
-
const afterReady = (fn) => {
|
|
5119
|
-
if (server.httpServer) server.httpServer.once("listening", () => setTimeout(fn, 100));
|
|
5120
|
-
else fn();
|
|
5121
|
-
};
|
|
5122
5081
|
if (remoteMode && (bindings.needsD1 || bindings.needsKV || bindings.needsR2)) {
|
|
5123
5082
|
const credentials = readVoidDevCredentials(root);
|
|
5124
5083
|
if (credentials.status === "ok") {
|
|
5125
5084
|
const lines = [import_picocolors.default.blue("Remote bindings active")];
|
|
5126
|
-
if (bindings.needsD1) lines.push(
|
|
5127
|
-
if (bindings.needsKV) lines.push(
|
|
5128
|
-
if (bindings.needsR2) lines.push(
|
|
5129
|
-
|
|
5085
|
+
if (bindings.needsD1) lines.push(` DB ${import_picocolors.default.dim("→ remote D1")}`);
|
|
5086
|
+
if (bindings.needsKV) lines.push(` KV ${import_picocolors.default.dim("→ remote KV")}`);
|
|
5087
|
+
if (bindings.needsR2) lines.push(` STORAGE ${import_picocolors.default.dim("→ remote R2")}`);
|
|
5088
|
+
afterServerReady(server, () => {
|
|
5130
5089
|
console.log();
|
|
5131
5090
|
voidLog(lines.join("\n "));
|
|
5132
5091
|
});
|
|
5133
|
-
} else if (credentials.status === "no-token")
|
|
5092
|
+
} else if (credentials.status === "no-token") afterServerReady(server, () => {
|
|
5134
5093
|
console.log();
|
|
5135
5094
|
voidWarn("Remote mode requires authentication. Run `void account login`, then restart.");
|
|
5136
5095
|
voidWarn("Falling back to local bindings.");
|
|
5137
5096
|
});
|
|
5138
|
-
else
|
|
5097
|
+
else afterServerReady(server, () => {
|
|
5139
5098
|
console.log();
|
|
5140
5099
|
voidWarn("Remote mode requires a linked project. Run `void project link` first.");
|
|
5141
5100
|
voidWarn("Falling back to local bindings.");
|
|
@@ -5143,16 +5102,16 @@ function voidPlugin(options) {
|
|
|
5143
5102
|
}
|
|
5144
5103
|
if (bindings.needsAI && !directCloudflareDestination) {
|
|
5145
5104
|
const credentials = readVoidDevCredentials(root);
|
|
5146
|
-
if (credentials.status === "no-token")
|
|
5105
|
+
if (credentials.status === "no-token") afterServerReady(server, () => {
|
|
5147
5106
|
console.log();
|
|
5148
5107
|
voidWarn("AI requires authentication. Run `void account login`, then restart the dev server.");
|
|
5149
5108
|
});
|
|
5150
5109
|
else if (credentials.status === "no-project") {
|
|
5151
|
-
if (process.stdin.isTTY)
|
|
5110
|
+
if (process.stdin.isTTY) afterServerReady(server, () => {
|
|
5152
5111
|
console.log();
|
|
5153
5112
|
runAiSetupPrompt(root, credentials.token, credentials.apiUrl, server);
|
|
5154
5113
|
});
|
|
5155
|
-
else
|
|
5114
|
+
else afterServerReady(server, () => {
|
|
5156
5115
|
console.log();
|
|
5157
5116
|
voidWarn("AI requires a linked project. Run `void project link` to set one up.");
|
|
5158
5117
|
});
|
|
@@ -5204,7 +5163,7 @@ function voidPlugin(options) {
|
|
|
5204
5163
|
}
|
|
5205
5164
|
};
|
|
5206
5165
|
if (framework) {
|
|
5207
|
-
workerConfig.main = getFrameworkEntry(framework, root, devTriggerToken, config.routing?.notFound);
|
|
5166
|
+
workerConfig.main = getFrameworkEntry(framework, root, devTriggerToken, dialect, config.routing?.notFound);
|
|
5208
5167
|
let notFoundIgnoredWarned = false;
|
|
5209
5168
|
const frameworkBuildWrapperPlugin = {
|
|
5210
5169
|
name: "void:framework-build-wrapper",
|
|
@@ -5214,7 +5173,7 @@ function voidPlugin(options) {
|
|
|
5214
5173
|
notFoundIgnoredWarned = true;
|
|
5215
5174
|
voidWarn(`Void generates no asset routing policy for a ${framework} build, so "routing.notFound" in void.config.ts is not written to the built worker config. During a self-hosted build and direct Cloudflare deployment, it takes effect only if your own Cloudflare config declares a complete \`assets\` policy (\`binding\`, \`directory\`, \`not_found_handling\`, \`run_worker_first\`); otherwise Cloudflare's default applies. Managed \`void deploy\` supplies the policy for you.`);
|
|
5216
5175
|
}
|
|
5217
|
-
generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), true, resolved.build.assetsDir, config.routing?.notFound);
|
|
5176
|
+
generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), true, dialect, resolved.build.assetsDir, config.routing?.notFound);
|
|
5218
5177
|
}
|
|
5219
5178
|
};
|
|
5220
5179
|
const existingFlags = workerConfig.compatibility_flags ?? [];
|
|
@@ -5249,6 +5208,7 @@ function voidPlugin(options) {
|
|
|
5249
5208
|
} : void 0;
|
|
5250
5209
|
return [
|
|
5251
5210
|
createCloudflareBuiltinsExternalPlugin(),
|
|
5211
|
+
createBareVoidRedirectPlugin(),
|
|
5252
5212
|
createWorkerEnvironmentSanitizerPlugin([viteEnvironment.name, ...viteEnvironment.childEnvironments ?? []]),
|
|
5253
5213
|
createWranglerCompatPersistPlugin(root, config),
|
|
5254
5214
|
devTriggerSecretGuardPlugin(),
|
|
@@ -5274,10 +5234,7 @@ function voidPlugin(options) {
|
|
|
5274
5234
|
...vinextWorkerEntry ? [vinextWorkerEntry] : [],
|
|
5275
5235
|
frameworkBuildWrapperPlugin,
|
|
5276
5236
|
frameworkTriggersPlugin(root, { devTriggerToken }),
|
|
5277
|
-
devTriggersHintPlugin(root,
|
|
5278
|
-
framework: true,
|
|
5279
|
-
devTriggerToken
|
|
5280
|
-
}),
|
|
5237
|
+
devTriggersHintPlugin(root, devTriggerToken),
|
|
5281
5238
|
...cloudflare({
|
|
5282
5239
|
configPath: cloudflareConfigPath,
|
|
5283
5240
|
...inspectorPortOption,
|
|
@@ -5311,7 +5268,6 @@ function voidPlugin(options) {
|
|
|
5311
5268
|
isAuthEnabled: () => false,
|
|
5312
5269
|
devTriggerToken,
|
|
5313
5270
|
headConfig: config.head,
|
|
5314
|
-
output: config.output,
|
|
5315
5271
|
prerenderPaths: config.routing?.prerender,
|
|
5316
5272
|
target: config.target,
|
|
5317
5273
|
routing: config.routing,
|
|
@@ -5396,7 +5352,6 @@ function voidPlugin(options) {
|
|
|
5396
5352
|
getVersionMetadataBinding: () => versionMetadataBinding,
|
|
5397
5353
|
devTriggerToken,
|
|
5398
5354
|
headConfig: config.head,
|
|
5399
|
-
output: config.output,
|
|
5400
5355
|
prerenderPaths: config.routing?.prerender,
|
|
5401
5356
|
remoteMode,
|
|
5402
5357
|
routing: config.routing,
|
|
@@ -5425,10 +5380,7 @@ function voidPlugin(options) {
|
|
|
5425
5380
|
configPath: authConfigPath
|
|
5426
5381
|
}),
|
|
5427
5382
|
prerenderPlugin(root, config),
|
|
5428
|
-
devTriggersHintPlugin(root,
|
|
5429
|
-
framework: false,
|
|
5430
|
-
devTriggerToken
|
|
5431
|
-
}),
|
|
5383
|
+
devTriggersHintPlugin(root, devTriggerToken),
|
|
5432
5384
|
...cloudflare({
|
|
5433
5385
|
configPath: cloudflareConfigPath,
|
|
5434
5386
|
...inspectorPortOption,
|