void 1.1.0 → 1.1.12
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/dist/{account-cmd-BTcUzv9L.mjs → account-cmd-Cj6sCMTk.mjs} +4 -4
- package/dist/{application-analysis-AB_YYWgH.mjs → application-analysis-D7nNmNJb.mjs} +6 -6
- package/dist/{application-routing-L7V-TFhZ.mjs → application-routing-CZH66gXn.mjs} +1 -1
- package/dist/{auth-link-DUJuvRx5.mjs → auth-link-Dj7lAC_K.mjs} +4 -4
- package/dist/{auth-migrations-Cgs0k6lS.mjs → auth-migrations-BO27GDNr.mjs} +38 -2
- package/dist/{auth-router-CIxiMG7i.mjs → auth-router-CNsMOFCa.mjs} +5 -4
- package/dist/{better-auth-shared-B74NJIus.d.mts → better-auth-shared-Bv18bB-l.d.mts} +2 -0
- package/dist/{better-auth-shared-CMXlZG7W.mjs → better-auth-shared-D-6z0q0f.mjs} +28 -1
- package/dist/{build-cmd-BkIv25PA.mjs → build-cmd-ByhegwRC.mjs} +2 -2
- package/dist/{cache-Ctzfig-W.mjs → cache-CEFb5ban.mjs} +2 -2
- package/dist/{cancel-deploy-CD9o-SsC.mjs → cancel-deploy-CaARY26n.mjs} +2 -2
- package/dist/{cf-build-output-Bc8i3dzE.mjs → cf-build-output-ChEKWan2.mjs} +71 -7
- package/dist/cf-build-output-Dcmxa-Zm.mjs +1 -0
- package/dist/{cf-user-agent-ChjQp2MU.mjs → cf-command-values-b8OqDoo9.mjs} +5 -16
- package/dist/cf-user-agent-BkEHPDLA.mjs +16 -0
- package/dist/cli/cli.mjs +180 -57
- package/dist/cli/cloudflare-operation-process.mjs +46 -9
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/{client-DM9Kcf4e.mjs → client-BdzxubTS.mjs} +58 -13
- package/dist/client-DAnfyMe9.mjs +1 -0
- package/dist/{cloudflare-auth-CqFBDo52.mjs → cloudflare-auth-DSvBc1Gu.mjs} +1 -1
- package/dist/{cloudflare-cmd-BIAF_BIY.mjs → cloudflare-cmd-D_2-Q-_i.mjs} +4 -4
- package/dist/{cloudflare-config-DV60XFFK.mjs → cloudflare-config-rdFOys4X.mjs} +2 -2
- package/dist/{cloudflare-connect-WjwnVOJA.mjs → cloudflare-connect-BN-k2kD-.mjs} +2 -2
- package/dist/{cloudflare-operations-CrSUFRzJ.mjs → cloudflare-operations-BFLCpUCV.mjs} +1 -1
- package/dist/{cloudflare-operations-B42EZeJy.mjs → cloudflare-operations-D5PLrOqD.mjs} +18 -8
- package/dist/{cloudflare-process-CeDWJRhj.mjs → cloudflare-process-CZJ4viYl.mjs} +2 -2
- package/dist/collect-BWhkgtAn.mjs +1 -0
- package/dist/{collect-xjffdCdk.mjs → collect-Dew86qce.mjs} +4 -3
- package/dist/{config-D0GY5ItR.mjs → config-CyUJzi3q.mjs} +1 -1
- package/dist/{config-Bx_1SpnO.mjs → config-D26zcdKy.mjs} +2 -2
- package/dist/{config-BEm9vRvS.mjs → config-DC5llZaI.mjs} +2 -2
- package/dist/{config-QrJWu0IX.mjs → config-DYJV8aEH.mjs} +1 -1
- package/dist/{connect-CKtk-EZe.mjs → connect-C4_m2moF.mjs} +5 -5
- package/dist/{create-project-B-ewF_Af.mjs → create-project-CvuYDD-l.mjs} +1 -1
- package/dist/{create-project-yInGo72M.mjs → create-project-D8jQTwVQ.mjs} +2 -2
- package/dist/database-provider.d.mts +6 -0
- package/dist/{db-7I_gfdVq.mjs → db-BsiOAa0A.mjs} +306 -111
- package/dist/{db-types-Bb4WBWIs.mjs → db-types-NGxPwnlt.mjs} +1 -1
- package/dist/{delete-Cy-M1u-r.mjs → delete-CAma7nFi.mjs} +2 -2
- package/dist/{deploy-BYYlnsiy.mjs → deploy-D1gIPiAq.mjs} +148 -64
- package/dist/deploy-Dc0XsCQj.mjs +2 -0
- package/dist/{deploy-managed-static-Ca4TFdmx.mjs → deploy-managed-static-B9KVxY3X.mjs} +80 -34
- package/dist/{deploy-transport-DWlWBe6M.mjs → deploy-transport-B3mtEi_q.mjs} +2 -2
- package/dist/deploy.d.mts +22 -1
- package/dist/deploy.mjs +49 -8
- package/dist/discover-D4TPKo57.mjs +1 -0
- package/dist/{discover-D2PGT63u.mjs → discover-LaV0tbIu.mjs} +1 -1
- package/dist/{dispatch-DrTTk8Xg.mjs → dispatch-BAbbn3jg.mjs} +6 -6
- package/dist/{domain-CZGxPv9u.mjs → domain-BAdwm-QS.mjs} +3 -3
- package/dist/{drizzle-CF84FOVM.mjs → drizzle-BQfyvQKX.mjs} +13 -2
- package/dist/{email-DzyNVuoU.mjs → email-MwjA7kaL.mjs} +11 -12
- package/dist/{email-cloudflare-DfG6UEMm.mjs → email-cloudflare-etpKiITL.mjs} +7 -10
- package/dist/{entry-ehmBvs5w.mjs → entry-B_0IhV64.mjs} +1 -1
- package/dist/{env-Nx3yf50r.mjs → env-B163-G1s.mjs} +5 -5
- package/dist/{env-types-DS2_y4X8.mjs → env-types-GRchm5dw.mjs} +1 -1
- package/dist/{env-validation-BT7z-qpQ.mjs → env-validation-CuGfWRJd.mjs} +1 -1
- package/dist/{env-validation-DYxjz_Wo.mjs → env-validation-D_KyMdab.mjs} +2 -2
- package/dist/{fetch-BPCYVi3H.d.mts → fetch-CUX0tB78.d.mts} +16 -3
- package/dist/fetch-CtESUYWd.mjs +26 -0
- package/dist/{fetch-error-Dj3crt0e.mjs → fetch-error-Bw0n-IY-.mjs} +1 -1
- package/dist/{fetch-stream-PGgz4uGz.mjs → fetch-stream-BspOeTAI.mjs} +1 -1
- package/dist/{fetch-stream-obvZ7fvO.d.mts → fetch-stream-DfkAzZf-.d.mts} +1 -1
- package/dist/{gen-CufHEf42.mjs → gen-CYN3wiov.mjs} +26 -20
- package/dist/gen-Cf-RBVg4.mjs +1 -0
- package/dist/{generate-Dat0UTry.mjs → generate-B1m4Cm4n.mjs} +1 -1
- package/dist/{generate-ClI89brV.mjs → generate-DkEb9rL-.mjs} +1 -1
- package/dist/{github-cmd-FU8EjFyU.mjs → github-cmd-C8QsnJQs.mjs} +2 -2
- package/dist/{handler-_PqY82xe.d.mts → handler-D5K_yP6T.d.mts} +1 -1
- package/dist/{headers-Di1FsD3e.mjs → headers-Bi4bOAwp.mjs} +1 -1
- package/dist/{help-BT2hovNI.mjs → help-B2sFwn9b.mjs} +60 -15
- package/dist/help-w-xlx_kq.mjs +1 -0
- package/dist/{inbound-brj2-TM5.d.mts → inbound-Da7XsjH3.d.mts} +6 -12
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +139 -126
- package/dist/{info-l249eUdH.mjs → info-Bxunp14X.mjs} +4 -4
- package/dist/{init-D0A6M64Q.mjs → init-DGFQMnbk.mjs} +51 -28
- package/dist/{link-WMoJFf4i.mjs → link-CwrfpjIM.mjs} +3 -3
- package/dist/{list-CQ2EQEHL.mjs → list-hKoW5z-b.mjs} +3 -3
- package/dist/{live-DJONVlQK.d.mts → live-JheIDZKc.d.mts} +1 -1
- package/dist/{local-d1-BxvQYEFi.mjs → local-d1-CpaPbd_L.mjs} +5 -5
- package/dist/login-08mBwZfI.mjs +1 -0
- package/dist/{login-C2T1oVG-.mjs → login-f2eu2TQh.mjs} +3 -3
- package/dist/{logs-DnC1d7xB.mjs → logs-CEWqD-_B.mjs} +3 -3
- package/dist/{migrate-BDIprOYd.mjs → migrate-DYfdWBXt.mjs} +5 -5
- package/dist/migrate-Di-4EuoE.mjs +1 -0
- package/dist/{neon-n74ta1Pr.mjs → neon-DTZr7Bu7.mjs} +0 -1
- package/dist/nitro.mjs +3 -3
- package/dist/{node-cPadMgUO.mjs → node-uN8_zxJr.mjs} +15 -9
- package/dist/operator-cmd-Bv20yLu2.mjs +1 -0
- package/dist/{operator-cmd-DHieWtFp.mjs → operator-cmd-DCr_QGMH.mjs} +4 -4
- package/dist/{output-Ba6ZbrzY.mjs → output-CKguMgr7.mjs} +13 -1
- package/dist/pages/client.d.mts +2 -2
- package/dist/pages/client.mjs +18 -5
- package/dist/pages/index.d.mts +2 -2
- package/dist/pages/index.mjs +5 -5
- package/dist/pages/islands-plugin.d.mts +44 -6
- package/dist/pages/islands-plugin.mjs +99 -28
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +1 -1
- package/dist/pages/serialize.d.mts +2 -2
- package/dist/pages/serialize.mjs +1 -1
- package/dist/{platform-args-CaCL_1Ch.mjs → platform-args-B7ke06up.mjs} +1 -4
- package/dist/platform-args-B_LrqEZB.mjs +1 -0
- package/dist/{platform-auth-config-Z16-I8nT.mjs → platform-auth-config-qGvEuns3.mjs} +5 -5
- package/dist/{platform-auth-protection-BXwZiJSF.mjs → platform-auth-protection-CyLcD6ot.mjs} +3 -3
- package/dist/{platform-auth-recovery-CXjfqyOv.mjs → platform-auth-recovery-B2LKI8V2.mjs} +3 -3
- package/dist/{platform-cmd-PT4YwMLM.mjs → platform-cmd-B2ec5eFg.mjs} +1 -1
- package/dist/{platform-cmd-DaAOiWTl.mjs → platform-cmd-CX7phm7V.mjs} +6 -6
- package/dist/{platform-domain-CxpvUeo0.mjs → platform-domain-DDNK2y-4.mjs} +3 -3
- package/dist/{platform-lifecycle-DBiS0cJd.mjs → platform-lifecycle-3CR98Tg2.mjs} +399 -40
- package/dist/{platform-lifecycle-u9pMOvxC.mjs → platform-lifecycle-CWc5gr6c.mjs} +1 -1
- package/dist/{platform-management-DvBS83rC.mjs → platform-management-DAE6g2QU.mjs} +1 -1
- package/dist/{platform-management-DhEFdQAf.mjs → platform-management-o3LCCeE4.mjs} +40 -4
- package/dist/{platform-plans-config-BWn1S2Rv.mjs → platform-plans-config-CBMZxCep.mjs} +1 -1
- package/dist/{platform-recovery-BUGOB4RC.mjs → platform-recovery-Dmsg7lWA.mjs} +2 -2
- package/dist/{platform-setup-YvN9VQXV.mjs → platform-setup-hFbnWAVQ.mjs} +1 -1
- package/dist/{plugin-inference-DsARdQKE.mjs → plugin-inference-Bekzjuqw.mjs} +2 -2
- package/dist/{prepare-DEB5SeVJ.mjs → prepare-DepAGBcV.mjs} +9 -9
- package/dist/prepare-EVEbQ9n2.mjs +1 -0
- package/dist/{prepare-PQCgsny0.mjs → prepare-HKo7Rh5V.mjs} +2 -2
- package/dist/{project-cmd-DVatD8Ev.mjs → project-cmd-8ylYGx-O.mjs} +18 -18
- package/dist/{project-paths-DMvEeSau.mjs → project-paths-DGu_QZ_Q.mjs} +1 -1
- package/dist/{project-team-DJrWEAG1.mjs → project-team-Bvpl78we.mjs} +2 -2
- package/dist/{project-token-CBgLBuL6.mjs → project-token-QWHoJH2t.mjs} +2 -2
- package/dist/{project-tsconfig-bveqhlYA.mjs → project-tsconfig-Itv1f4WC.mjs} +1 -1
- package/dist/{project-zero-trust-92gLtZ25.mjs → project-zero-trust-8tJ-RFvu.mjs} +2 -2
- package/dist/{protocol-4H7V_3Os.d.mts → protocol-Ssc_LhHj.d.mts} +2 -2
- package/dist/{protocol-RNP0u7UY.mjs → protocol-bAUUkx70.mjs} +1 -1
- package/dist/{providers-BXuhmuub.mjs → providers-BUHwJlmM.mjs} +10 -1
- package/dist/provision-BgXFDv0d.mjs +1 -0
- package/dist/{provision-BnSSkiED.mjs → provision-DZKYCEJg.mjs} +66 -66
- package/dist/r2-conditions-B8xUgJRc.mjs +61 -0
- package/dist/{requests-7W1Pygt2.mjs → requests-Vk5Zyhcy.mjs} +2 -2
- package/dist/{rollback-BcASVnwP.mjs → rollback-CH4yMQys.mjs} +9 -8
- package/dist/{runner-CabsQ-iM.mjs → runner-3uGC-oLF.mjs} +9 -7
- package/dist/{runner-So9mYfcm.mjs → runner-WCdfeI0q.mjs} +1 -1
- package/dist/{runner-mysql-BhRaONkO.mjs → runner-mysql-BWmbk5IE.mjs} +1 -1
- package/dist/{runner-mysql-DWwE8jKi.mjs → runner-mysql-BcHnLUuM.mjs} +1 -1
- package/dist/{runner-pg-_Xncr3H5.mjs → runner-pg-Cgp-cr_p.mjs} +1 -1
- package/dist/{runner-pg-BRemq_GX.mjs → runner-pg-Cr3qrqi4.mjs} +1 -1
- package/dist/runtime/ai.d.mts +4 -0
- package/dist/runtime/ai.mjs +2 -37
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +2 -2
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +2 -2
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +2 -2
- package/dist/runtime/client-react.d.mts +2 -2
- package/dist/runtime/client-react.mjs +3 -3
- package/dist/runtime/client-solid.d.mts +2 -2
- package/dist/runtime/client-solid.mjs +3 -3
- package/dist/runtime/client-svelte.d.mts +2 -2
- package/dist/runtime/client-svelte.mjs +3 -3
- package/dist/runtime/client-vue.d.mts +2 -2
- package/dist/runtime/client-vue.mjs +3 -3
- package/dist/runtime/client.d.mts +2 -2
- package/dist/runtime/client.mjs +3 -3
- package/dist/runtime/email/testing.d.mts +1 -1
- package/dist/runtime/email.d.mts +2 -3
- package/dist/runtime/email.mjs +2 -3
- package/dist/runtime/fetch-server.d.mts +8 -0
- package/dist/runtime/fetch-server.mjs +30 -0
- package/dist/runtime/fetch-stream.d.mts +2 -2
- package/dist/runtime/fetch-stream.mjs +2 -2
- package/dist/runtime/fetch.d.mts +2 -2
- package/dist/runtime/fetch.mjs +3 -3
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/migration-handler-mysql.mjs +4 -4
- package/dist/runtime/migration-handler-pg.mjs +9 -1
- package/dist/runtime/remote/binding-handler.mjs +25 -25
- package/dist/runtime/remote/index.d.mts +3 -0
- package/dist/runtime/remote/index.mjs +86 -23
- package/dist/runtime/routing.d.mts +2 -2
- package/dist/runtime/routing.mjs +1 -1
- package/dist/runtime/sse-client.d.mts +4 -0
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -2
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/{scan-C0BMdmEd.mjs → scan-D2-FcLHs.mjs} +13 -5
- package/dist/{secret-bg73f1Ge.mjs → secret-wr6Sn4Xa.mjs} +4 -4
- package/dist/serialize-DtR8Vwa_.d.mts +18 -0
- package/dist/serialize-YHvlcG3Q.mjs +31 -0
- package/dist/{subcommand-prompt-Bm3ZlYgA.mjs → subcommand-prompt-CNZc4XUd.mjs} +1 -1
- package/dist/{types-BAp5AEBU.d.mts → types-7AIz0OZu.d.mts} +1 -1
- package/dist/{validate-CheZGRE7.mjs → validate-CnZPMq4q.mjs} +22 -17
- package/dist/validate-D7Wn8PUX.mjs +1 -0
- package/dist/{version-metadata-DIrqEHQo.mjs → version-metadata-B1Bm2wSq.mjs} +1 -1
- package/dist/{wrangler-BYs07Rxy.mjs → wrangler-C9XSzrju.mjs} +3 -3
- package/dist/wrangler-DAdxHEzh.mjs +1 -0
- package/dist/{wrapper-CwhpNWtH.mjs → wrapper-DGsYwNi6.mjs} +6 -4
- package/dist/{ws-aKVYB-fA.d.mts → ws-nnFnAyQb.d.mts} +6 -1
- package/docs/guide/auth.md +1 -1
- package/docs/guide/database/d1.md +2 -2
- package/docs/guide/database/mysql.md +1 -1
- package/docs/guide/deployment.md +2 -0
- package/docs/guide/edge/headers.md +10 -2
- package/docs/guide/edge/revalidation.md +2 -0
- package/docs/guide/email/receiving.md +1 -1
- package/docs/guide/email/sending.md +3 -3
- package/docs/guide/pages-routing/islands.md +2 -2
- package/docs/guide/pages-routing/markdown.md +3 -1
- package/docs/guide/platform/administration/connected-apps.md +18 -2
- package/docs/guide/platform/administration/email.md +7 -1
- package/docs/guide/platform/installation/ci.md +2 -0
- package/docs/guide/platform/installation/credentials.md +23 -5
- package/docs/guide/platform/installation/maintenance.md +32 -2
- package/docs/guide/platform/installation/setup.md +1 -1
- package/docs/guide/remote-dev.md +2 -0
- package/docs/guide/typed-fetch.md +1 -1
- package/docs/guide/websockets.md +2 -2
- package/docs/index.md +78 -22
- package/docs/integrations/cloudflare.md +1 -1
- package/docs/integrations/frameworks/tanstack-start.md +25 -0
- package/docs/reference/api/deploy.md +35 -3
- package/docs/reference/api/pages.md +7 -5
- package/docs/reference/api.md +2 -0
- package/docs/reference/cli/database.md +22 -5
- package/docs/reference/cli/deploy.md +12 -10
- package/docs/reference/cli/email.md +1 -1
- package/docs/reference/cli/generate.md +1 -1
- package/docs/reference/cli/platform-installation.md +4 -2
- package/docs/reference/cli/project.md +8 -4
- package/docs/reference/cli.md +2 -1
- package/docs/reference/config.md +12 -2
- package/package.json +8 -7
- package/dist/cf-build-output-BU3hqdHu.mjs +0 -1
- package/dist/client-B60PwCC4.mjs +0 -1
- package/dist/collect-Cae8A7Zr.mjs +0 -1
- package/dist/deploy-9lgfhrXS.mjs +0 -2
- package/dist/discover-ClzFSwns.mjs +0 -1
- package/dist/fetch-sAcwjzLO.mjs +0 -18
- package/dist/gen-sXyp5DFO.mjs +0 -1
- package/dist/help-i2YGGnTH.mjs +0 -1
- package/dist/login-XD844Xs-.mjs +0 -1
- package/dist/migrate-BRwU-blY.mjs +0 -1
- package/dist/operator-cmd-D6gnZsnK.mjs +0 -1
- package/dist/platform-args-B0HeTh0C.mjs +0 -1
- package/dist/prepare-CYT6tAzD.mjs +0 -1
- package/dist/r2-conditions-D1Wk8i7b.mjs +0 -30
- package/dist/serialize-BtQyaYoC.mjs +0 -20
- package/dist/serialize-CfSwWfF2.d.mts +0 -10
- package/dist/validate-BQFdf0Pi.mjs +0 -1
|
@@ -33,9 +33,17 @@ For hashed assets, you can add headers, but the platform keeps control of cachin
|
|
|
33
33
|
|
|
34
34
|
Header rules do not apply to ISR cache responses.
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### Cookie headers
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
On a [Void platform](../deployment.md#deploy-to-a-team-platform), apps usually share an application domain, such as `apps.example.com`. Header rules on a platform deploy change two headers on all hostnames of the app, including custom domains:
|
|
39
|
+
|
|
40
|
+
- Void ignores `Set-Cookie` in header rules.
|
|
41
|
+
- Void removes the `"cookies"` directive from `Clear-Site-Data` in header rules. Other directives, such as `"cache"` and `"storage"`, still apply.
|
|
42
|
+
- Void ignores the full value of a `Clear-Site-Data` rule that includes `"*"`. The response then keeps the `Clear-Site-Data` value from your app's response, without `"cookies"`. If that value also includes `"*"`, the response has no `Clear-Site-Data`.
|
|
43
|
+
|
|
44
|
+
This stops a header rule from setting or clearing cookies for other apps on the same domain. These limits apply only to header rules. Your app's own response can set cookies and send `Clear-Site-Data`, and on a shared domain those can affect other apps. See [Domains and Resources](../platform/installation/domains.md#adding-a-domain).
|
|
45
|
+
|
|
46
|
+
During local development, with `void deploy --platform cloudflare`, and on [other runtimes](../deployment.md#other-runtimes), header rules apply both headers as written.
|
|
39
47
|
|
|
40
48
|
## Framework `_headers` files
|
|
41
49
|
|
|
@@ -63,6 +63,8 @@ export const loader = defineHandler(async (c) => {
|
|
|
63
63
|
|
|
64
64
|
Per-page values take precedence over `void.config.ts` patterns.
|
|
65
65
|
|
|
66
|
+
A page's `revalidate` export also applies to `routes/` handlers whose URLs match the page pattern. For example, if `pages/[...slug].server.ts` exports `revalidate`, Void can also cache the `GET` response of `routes/now.ts`. Void never caches paths under `/api`. To keep a route handler's response out of the cache, set `x-revalidate: 0` on it. See [Per-response TTL override](#per-response-ttl-override).
|
|
67
|
+
|
|
66
68
|
## Precedence
|
|
67
69
|
|
|
68
70
|
When multiple sources set a revalidate TTL, the most specific wins:
|
|
@@ -96,7 +96,7 @@ to check current provider routing and any remaining setup steps.
|
|
|
96
96
|
|
|
97
97
|
For direct deployments, follow [Your own Cloudflare account](./domains.md#your-own-cloudflare-account) to configure inbound addresses.
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
The local dev server provides the outbound email inbox but has no inbound email trigger. Test inbound handlers with `createInboundTestHarness` below.
|
|
100
100
|
|
|
101
101
|
## Testing inbound handlers {#testing-inbound-handlers}
|
|
102
102
|
|
|
@@ -34,7 +34,7 @@ Check both failure shapes: `result.error` reports a request failure, while `resu
|
|
|
34
34
|
|
|
35
35
|
## Setup {#setup}
|
|
36
36
|
|
|
37
|
-
On a platform with email enabled, deploy without additional email configuration. Ask your administrator for its shared mail domain. Administrators [enable email during installation or upgrade](/guide/platform/installation/credentials#
|
|
37
|
+
On a platform with email enabled, deploy without additional email configuration. Ask your administrator for its shared mail domain. Administrators [enable email during installation or upgrade](/guide/platform/installation/credentials#enable-email).
|
|
38
38
|
|
|
39
39
|
Each project on an email-enabled platform has:
|
|
40
40
|
|
|
@@ -171,7 +171,7 @@ The default platform allowance is 200 recipient attempts per UTC month and 10 pe
|
|
|
171
171
|
|
|
172
172
|
## Local development {#local-development}
|
|
173
173
|
|
|
174
|
-
During
|
|
174
|
+
During local development, sends are captured to an in-memory inbox instead of going to Cloudflare. The dev server prints the inbox URL when it starts:
|
|
175
175
|
|
|
176
176
|
```
|
|
177
177
|
[void] Email inbox: http://localhost:5173/__void/inbox?token=<printed-token>
|
|
@@ -195,7 +195,7 @@ The inbox keeps the most recent 100 messages through HMR and clears on a full se
|
|
|
195
195
|
|
|
196
196
|
The dev inbox works in native Void apps, TanStack Start, and React Router. It is unavailable in SvelteKit, Nuxt, Analog, and Astro; sends from those apps return `BINDING_MISSING`. Use `createEmailTestHarness` from `void/email/testing` to capture sends in tests. If a configured inbox cannot be reached, `sendEmail` returns `UPSTREAM_ERROR` without sending.
|
|
197
197
|
|
|
198
|
-
`sendInDev
|
|
198
|
+
`sendInDev` is deprecated. During local development it skips the inbox and returns `BINDING_MISSING`, so it never delivers. Remove it, and deploy the app to test real delivery.
|
|
199
199
|
|
|
200
200
|
## Testing {#testing}
|
|
201
201
|
|
|
@@ -209,7 +209,7 @@ After a successful action, an island page reloads or redirects through `window.l
|
|
|
209
209
|
|
|
210
210
|
## Forms
|
|
211
211
|
|
|
212
|
-
Island pages cannot use `useForm` because it depends on the Void Router. Use `useIslandForm` instead. It has the same
|
|
212
|
+
Island pages cannot use `useForm` because it depends on the Void Router. Use `useIslandForm` instead. It has the same form state, but its submit helpers take the action URL and use `fetch()` directly:
|
|
213
213
|
|
|
214
214
|
::: code-group
|
|
215
215
|
|
|
@@ -344,7 +344,7 @@ export default function PostForm() {
|
|
|
344
344
|
|
|
345
345
|
:::
|
|
346
346
|
|
|
347
|
-
`useIslandForm` provides the same state
|
|
347
|
+
`useIslandForm` provides the same form state as [`useForm`](./actions-and-forms#useform). Pass the action URL to `post`, `put`, `patch`, or `delete` to submit.
|
|
348
348
|
|
|
349
349
|
Successful submissions reload the page; redirects navigate to their destination. A `422` response populates `errors` from `{ errors: { field: "message" } }`. Submit helpers return `Promise<void>`.
|
|
350
350
|
|
|
@@ -137,7 +137,7 @@ Welcome to Void. Here's an interactive demo:
|
|
|
137
137
|
```
|
|
138
138
|
|
|
139
139
|
- **`<script>` block:** extracted before markdown compilation. Island imports use `with { island: "..." }` syntax (see [islands](./islands)). Any other code in the block becomes a [client script](#client-scripts) that runs in the browser.
|
|
140
|
-
- **Frontmatter:** YAML metadata between `---` fences. Layouts can read it through [`useFrontmatter()`](#frontmatter-access).
|
|
140
|
+
- **Frontmatter:** YAML metadata between `---` fences. Layouts and islands can read it through [`useFrontmatter()`](#frontmatter-access).
|
|
141
141
|
- **Body:** standard markdown plus GFM. Uppercase tags such as `<Counter />` reference imported components and render as islands.
|
|
142
142
|
|
|
143
143
|
## Client Scripts
|
|
@@ -230,6 +230,8 @@ export default function DocsLayout(props) {
|
|
|
230
230
|
|
|
231
231
|
:::
|
|
232
232
|
|
|
233
|
+
Island components on a Markdown page can call `useFrontmatter()` too. A page with islands includes its frontmatter in the HTML for them to read in the browser. Keep private values out of the frontmatter of those pages.
|
|
234
|
+
|
|
233
235
|
## Pages Virtual Module
|
|
234
236
|
|
|
235
237
|
Import `@void/md/pages` to get metadata for all markdown pages at build time. Use it to build sidebars, navigation, or search indexes:
|
|
@@ -4,7 +4,7 @@ A connected app is a separate application registered as an OAuth client on your
|
|
|
4
4
|
|
|
5
5
|
## Register an application
|
|
6
6
|
|
|
7
|
-
Open **Admin → Connected apps**. Enter the app name, its operator, and each exact HTTPS callback URL on a separate line. Wildcards and callback query strings are not supported. Enable individual publish approvals if the app builds and deploys projects.
|
|
7
|
+
Open **Admin → Connected apps**. Enter the app name, its operator, and each exact HTTPS callback URL on a separate line. Wildcards and callback query strings are not supported. Enable individual publish approvals if the app builds and deploys projects. Enable private previews to run checkpoints before publishing. Existing clients have an **Enable private previews** button; users must connect again to consent to that permission.
|
|
8
8
|
|
|
9
9
|
Save the returned client ID and secret on the app's server. Void shows the secret once. The client secret authenticates that application; it does not grant access to users' accounts. Register a new client if you need replacement credentials, then disable the old one.
|
|
10
10
|
|
|
@@ -18,6 +18,22 @@ The app sends users to Void's authorization page, where Void displays its regist
|
|
|
18
18
|
|
|
19
19
|
Users can disconnect applications at `<platform API URL>/oauth/connections`. Grants also expire after an hour and become invalid when their platform login session is revoked or their account is suspended. Applications must request a new sign-in when access expires.
|
|
20
20
|
|
|
21
|
+
## Private previews
|
|
22
|
+
|
|
23
|
+
Sign-in can request `scope=profile preview:deploy` when the administrator has enabled it. After user consent, the app can build private previews without approval for each checkpoint. Production publishing still requires individual approval.
|
|
24
|
+
|
|
25
|
+
Use the granted bearer token to:
|
|
26
|
+
|
|
27
|
+
1. POST `{ workspace: externalWorkspaceId }` to `/oauth/previews`. The response contains a stable `project_id` and preview `url` for that client, owner and workspace.
|
|
28
|
+
2. POST `{ project_id, checkpoint, artifact: prepared.artifact }` to `/oauth/preview-deployment-requests`. Use its `access_token` and `approval_id` with the same asset upload and deployment protocol as publishing.
|
|
29
|
+
3. Once deployment finishes, POST to `/oauth/previews/:id/launch` and open the returned URL. Launch URLs expire after one minute and can be used once. Reload the preview's origin after opening it.
|
|
30
|
+
|
|
31
|
+
Each workspace has a separate preview origin and resources, with no production secrets. Previews support HTTP apps with isolated D1, KV, R2, AI and native Durable Objects. Authentication, external databases, email, schedules, queues and containers require production publishing. Viewing requires the current user grant; disconnecting or disabling the app denies subsequent requests. Preview writes must originate from that preview's own origin.
|
|
32
|
+
|
|
33
|
+
Account Access policies must allow requests to generated preview origins to reach Void. A policy that blocks new Workers hostnames also blocks previews. Void still requires a valid preview grant when the hostname is reachable.
|
|
34
|
+
|
|
35
|
+
Each owner can have ten preview workspaces. Each workspace permits sixty builds per hour and shares the owner's platform resource and usage limits. Inactive previews expire after seven days and Void removes their resources. Opening the workspace through `/oauth/previews` renews that expiry. Disabling preview permission expires its previews.
|
|
36
|
+
|
|
21
37
|
## Approve a publish
|
|
22
38
|
|
|
23
39
|
The app builds first, then sends the user to Void with the prepared artifact. Void displays the project name, checkpoint label, resources, manifest, and artifact digest. The user must explicitly approve on Void.
|
|
@@ -30,7 +46,7 @@ Disabling the app or disconnecting its grant stops authorization for subsequent
|
|
|
30
46
|
|
|
31
47
|
## Build an OAuth client
|
|
32
48
|
|
|
33
|
-
Discover endpoints at `/.well-known/oauth-authorization-server` on the platform API origin. Use authorization code flow with `scope=profile`, a random `state`, and S256 PKCE. Authenticate token exchanges using HTTP Basic client authentication. Send access tokens as Bearer credentials to `/oauth/userinfo`; its response contains `sub` and `
|
|
49
|
+
Discover endpoints at `/.well-known/oauth-authorization-server` on the platform API origin. Use authorization code flow with `scope=profile`, a random `state`, and S256 PKCE. Authenticate token exchanges using HTTP Basic client authentication. Send access tokens as Bearer credentials to `/oauth/userinfo`; its response contains `sub`, `preferred_username`, and the consented `scope`.
|
|
34
50
|
|
|
35
51
|
For publishing, package the built app with [`prepareDeployArtifact`](/reference/api/deploy). POST to `/oauth/deployment-requests` using the profile token:
|
|
36
52
|
|
|
@@ -27,6 +27,12 @@ reconciliation verifies delivery afterward; a deleting project stays closed
|
|
|
27
27
|
and its deletion can be retried. See [operator email commands](../../../reference/cli/platform-email.md#operator-email)
|
|
28
28
|
for the recovery requirements.
|
|
29
29
|
|
|
30
|
+
### Mail that the platform sends {#platform-sender}
|
|
31
|
+
|
|
32
|
+
The platform sends its own mail, for example invitations, welcome mail, failed-deploy notices, and error alerts. This mail comes from `noreply@<mail domain>`, and the sender name is the platform's display name. Void sets this sender, so you do not need to configure one. Do not set a different sender on the platform Workers in the Cloudflare dashboard. That change stops the next `upgrade`, `repair`, `enable`, or `rollback` until you let Void replace it. See [Platform Workers changed outside Void](/guide/platform/installation/maintenance#workers-changed-outside-void).
|
|
33
|
+
|
|
34
|
+
Mail to an address that is not verified needs Cloudflare Email Sending onboarding and [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans).
|
|
35
|
+
|
|
30
36
|
### Deciding who mail may reach
|
|
31
37
|
|
|
32
38
|
By default, mail from the shared sender reaches only the recipients each project has verified. For a team whose applications mainly mail colleagues, widen that once for the whole installation:
|
|
@@ -114,7 +120,7 @@ Use the apex of the selected Cloudflare zone. Platform-managed custom inbound em
|
|
|
114
120
|
void platform email domain-add other.example --project hr-portal --token-stdin --yes < token.txt
|
|
115
121
|
```
|
|
116
122
|
|
|
117
|
-
Project owners see administrator-registered domains in `void email domain list` and `status`; `status` names the `void platform email` command for any step they cannot take themselves, and `sync` and `remove` point them at `domain-sync` and `domain-remove`. A domain an owner registered before you switched to `admin` stays theirs to renew, sync and remove. The runtime token needs the email permissions
|
|
123
|
+
Project owners see administrator-registered domains in `void email domain list` and `status`; `status` names the `void platform email` command for any step they cannot take themselves, and `sync` and `remove` point them at `domain-sync` and `domain-remove`. A domain an owner registered before you switched to `admin` stays theirs to renew, sync and remove. The runtime token needs the [email permissions](/guide/platform/installation/credentials#enable-email) for this to work.
|
|
118
124
|
|
|
119
125
|
A permission refusal leaves setup blocked. After correcting it, run `domain-sync`
|
|
120
126
|
to resume that same setup operation; repeat `domain-rotate-secret` to resume a
|
|
@@ -51,6 +51,8 @@ void platform install \
|
|
|
51
51
|
|
|
52
52
|
Mutations require `--yes` in CI; a read-only `--plan` does not. Custom runtimes also require `--runtime <directory>`. For a new installation, run `--plan` with the same account, name, and domain options as the unattended install. If you use `--auth-config`, pass the same file to both commands. Register `<platform-api-url>/auth/callback` when creating a login provider's OAuth or OIDC client manually; automatic Access setup manages its own application. A custom API hostname is optional.
|
|
53
53
|
|
|
54
|
+
In CI, `upgrade`, `repair`, `enable`, `rollback`, and `install --resume` stop before they change a platform Worker or pause traffic when a platform Worker was changed in the Cloudflare dashboard or with the Cloudflare API, or has an active version without a Void deployment record. See [Platform Workers changed outside Void](/guide/platform/installation/maintenance#workers-changed-outside-void).
|
|
55
|
+
|
|
54
56
|
:::
|
|
55
57
|
|
|
56
58
|
## Customize the Platform
|
|
@@ -68,7 +68,25 @@ Void checks access before provisioning. If it reports a missing permission, upda
|
|
|
68
68
|
|
|
69
69
|
## Enable Email {#enable-email}
|
|
70
70
|
|
|
71
|
-
Choose a shared sender domain and its Cloudflare zone ID. The mail zone may differ from the application zone, but it must belong to the platform's Cloudflare account.
|
|
71
|
+
Choose a shared sender domain and its Cloudflare zone ID. The mail zone may differ from the application zone, but it must belong to the platform's Cloudflare account.
|
|
72
|
+
|
|
73
|
+
Before you enable email, enable [Cloudflare Email Routing](https://developers.cloudflare.com/email-service/get-started/route-emails/) for the exact shared sender domain and confirm that its MX records point to Cloudflare. For a subdomain, add that name under the zone's **Email Routing → Settings → Subdomains**. Cloudflare adds the required MX and SPF records. The installer's shared-mail bootstrap verifies those records; it does not add them. Keep existing mail-provider records on other domain names in place.
|
|
74
|
+
|
|
75
|
+
Enabling email lets administrators [register email domains for projects](/guide/platform/administration/email#registering-email-domains-for-projects) and lets projects register destination addresses through the runtime token. The runtime token needs these permissions:
|
|
76
|
+
|
|
77
|
+
| Scope | Permission | Access |
|
|
78
|
+
| ------- | ----------------------- | ------ |
|
|
79
|
+
| Account | Email Routing Addresses | Edit |
|
|
80
|
+
| Account | Email Sending | Edit |
|
|
81
|
+
| Zone | Zone | Read |
|
|
82
|
+
| Zone | Zone Settings | Edit |
|
|
83
|
+
| Zone | Email Routing Rules | Edit |
|
|
84
|
+
|
|
85
|
+
The zone permissions must include each zone that will carry mail, including the mail zone. Email Sending onboarding for arbitrary recipients needs Workers Paid.
|
|
86
|
+
|
|
87
|
+
For a new installation, set `VOID_EMAIL_SENDER_DOMAIN` and `VOID_EMAIL_SHARED_ZONE_ID` before `void platform install`. The runtime-token link then preselects these permissions.
|
|
88
|
+
|
|
89
|
+
For an existing installation, add the permissions to its runtime token first. Edit the token in the Cloudflare dashboard. The token value stays the same. Or set `VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN` to a new token that has all runtime permissions. Then run:
|
|
72
90
|
|
|
73
91
|
```sh
|
|
74
92
|
VOID_EMAIL_SENDER_DOMAIN=mail.example.com \
|
|
@@ -76,13 +94,13 @@ VOID_EMAIL_SHARED_ZONE_ID=your-zone-id \
|
|
|
76
94
|
void platform upgrade your-installation-id
|
|
77
95
|
```
|
|
78
96
|
|
|
79
|
-
|
|
97
|
+
Void records the domain and zone for later upgrades; an ordinary upgrade cannot replace them.
|
|
80
98
|
|
|
81
|
-
Before
|
|
99
|
+
Before the CLI changes anything or pauses traffic, it checks that the runtime token can read the mail zone and its Email Routing settings, rules, and addresses. If Cloudflare denies a request, the command stops and names each missing permission. Void keeps a saved runtime token, so you can add the permission to the same token and run the command again. The check cannot confirm Edit access or Email Sending, so select those permissions as the table shows.
|
|
82
100
|
|
|
83
|
-
|
|
101
|
+
Without `VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN`, `upgrade`, `repair`, `enable`, and `rollback` check the runtime token saved on this machine. The platform can use a newer token, for example one set from another machine. If Cloudflare does not accept the saved token, the CLI shows a warning and continues without the check. To check the token that the platform uses, set `VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN` to it.
|
|
84
102
|
|
|
85
|
-
The installer deploys the email gateway, prepares the shared mail route, and verifies inbound readiness before opening platform traffic. If setup fails,
|
|
103
|
+
The installer deploys the email gateway, prepares the shared mail route, and verifies inbound readiness before opening platform traffic. If setup fails, fix the problem that the error names, for example a missing permission, the exact-domain MX records, or a routing conflict. Then run the same install or upgrade command again. A fresh install resumes with `void platform install --resume --name <installation-id>`; it continues the recorded email operation after the configuration is corrected.
|
|
86
104
|
|
|
87
105
|
## R2 Upload Credentials
|
|
88
106
|
|
|
@@ -113,9 +113,13 @@ An upgrade validates the runtime, applies supported pending migrations, deploys
|
|
|
113
113
|
|
|
114
114
|
Before starting, Void checks access to the installation's Cloudflare account, Workers, and existing R2 buckets. If credentials are rejected, set `CLOUDFLARE_API_TOKEN` to a management token scoped to that account and retry. This overrides the installation's saved management token.
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Some upgrades pause application traffic during the cutover to the new version. Traffic resumes after the new version passes its health checks. If an upgrade or another lifecycle command fails after it paused traffic, traffic stays paused until a later run succeeds. To resume:
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
1. Run `void platform status <id>` to see the saved progress.
|
|
119
|
+
2. Fix the problem that the error names.
|
|
120
|
+
3. Run the resume command that the CLI printed. It is the same command, with the same runtime.
|
|
121
|
+
|
|
122
|
+
::: details Migration safety, credential rotation, and rollback
|
|
119
123
|
|
|
120
124
|
To update the runtime Cloudflare token, GitHub OAuth credentials when GitHub login is enabled, or R2 credentials,
|
|
121
125
|
provide their `VOID_PLATFORM_*` environment variables when running the upgrade.
|
|
@@ -141,6 +145,32 @@ Let running rotations finish before you roll back. If an older proxy runs next t
|
|
|
141
145
|
|
|
142
146
|
:::
|
|
143
147
|
|
|
148
|
+
### Platform Workers changed outside Void {#workers-changed-outside-void}
|
|
149
|
+
|
|
150
|
+
Void manages the platform's own Workers. Do not change them in the Cloudflare dashboard or with the Cloudflare API. To change the platform, use the Void commands on this page.
|
|
151
|
+
|
|
152
|
+
`upgrade`, `repair`, `enable`, `rollback`, and `install --resume` deploy the platform Workers again. Before they change a platform Worker or pause traffic, Void finds each platform Worker that:
|
|
153
|
+
|
|
154
|
+
- was changed in the Cloudflare dashboard or with the Cloudflare API.
|
|
155
|
+
- has an active version without a Void deployment record. This can occur when an earlier run replaced a change made outside Void, and then stopped or failed. If that run stopped during the cutover to the new version, the command first makes the earlier versions active again. Void checks those earlier versions too. A version that an older Void release deployed can also have no record.
|
|
156
|
+
|
|
157
|
+
The `--plan` preview of `upgrade`, `repair`, `enable`, and `rollback` shows the same list as a warning.
|
|
158
|
+
|
|
159
|
+
In a terminal, Void lists these Workers and asks **Replace the configuration of these Workers?** The default answer is No.
|
|
160
|
+
|
|
161
|
+
- If you answer No, the command stops. No platform Worker changed, and the command did not pause traffic.
|
|
162
|
+
- If you answer Yes, the command continues. First, Void prepares the platform resources and the database. Then, before it pauses traffic or deploys a Worker, the Cloudflare CLI asks you again for each Worker changed in the dashboard or with the API. For a dashboard change, it shows the differences. Void uploads a new version of each of these Workers and does not deploy it yet. For a Worker that has an active version without a Void deployment record, the Cloudflare CLI does not ask again.
|
|
163
|
+
|
|
164
|
+
If you refuse in the Cloudflare CLI, the command stops. Void does not undo the resource and database changes. No deployment changed, and the command did not pause traffic.
|
|
165
|
+
|
|
166
|
+
The replacement removes values that Void does not set, for example an `EMAIL_FROM` variable that you added. It also resets values that Void sets, for example `AUTH_REDIRECT_URI`.
|
|
167
|
+
|
|
168
|
+
Without a terminal, for example in CI, or with `--yes`, the command stops before it changes a platform Worker, and it does not pause traffic. Run the command that Void prints once in a terminal, and answer the questions there. After that run completes, the command works in CI again.
|
|
169
|
+
|
|
170
|
+
If Void cannot read a platform Worker, the command also stops before it changes a platform Worker or pauses traffic. Run the command again. If a platform Worker has no single version that gets 100% of traffic, for example after a gradual deployment, deploy one version of it to 100% of traffic in the Cloudflare dashboard. Then run the command once in a terminal, so that you can approve the dashboard change.
|
|
171
|
+
|
|
172
|
+
If an earlier run failed after it paused traffic, traffic stays paused after these stops. To resume traffic, see [Upgrade the platform](#upgrade-the-platform).
|
|
173
|
+
|
|
144
174
|
### Follow upgrade and rollback progress
|
|
145
175
|
|
|
146
176
|
Watching progress is optional: a running upgrade or rollback proceeds through
|
|
@@ -260,6 +260,6 @@ You can also rerun `void platform install` and choose **Continue setup** for an
|
|
|
260
260
|
|
|
261
261
|
Resume restores your selected Hyperdrive. If that selection is missing from the saved checkpoint, add `--hyperdrive <existing-id>` when resuming, using the same configuration you originally selected.
|
|
262
262
|
|
|
263
|
-
If Cloudflare rejects a saved runtime token during continued credential setup, Void opens the token page and asks for a replacement in the same run. Network or service failures do not discard saved tokens. Tokens supplied through the environment must be corrected there instead.
|
|
263
|
+
If Cloudflare rejects a saved runtime token during continued credential setup, Void opens the token page and asks for a replacement in the same run. A missing [email permission](/guide/platform/installation/credentials#enable-email) does not discard the saved token: add the permission to the same token, then resume. Network or service failures do not discard saved tokens. Tokens supplied through the environment must be corrected there instead.
|
|
264
264
|
|
|
265
265
|
:::
|
package/docs/guide/remote-dev.md
CHANGED
|
@@ -59,6 +59,8 @@ When the dev server starts with remote mode active, it prints:
|
|
|
59
59
|
|
|
60
60
|
- **Network latency:** each binding call makes a network request, so responses may be slower than local development.
|
|
61
61
|
- **R2 multipart uploads:** `createMultipartUpload()` and `resumeMultipartUpload()` are not supported in remote mode.
|
|
62
|
+
- **R2 range and conditional reads:** in remote mode, `get()` ignores request headers passed as `range` or `onlyIf` and returns the whole object. For example, `get(key, { range: request.headers, onlyIf: request.headers })` returns the whole object when the request has a `Range` or `If-None-Match` header. `get()` throws when `range` or `onlyIf` is an object that asks for a byte range or a condition, such as `{ offset: 0, length: 100 }` or `{ etagMatches: etag }`.
|
|
62
63
|
- **R2 conditional writes:** `put(..., { onlyIf })` requires an updated platform and project deployment. Failed preconditions return `null`.
|
|
64
|
+
- **R2 metadata and list options:** custom metadata, HTTP metadata, and `list()` with `delimiter`, `startAfter`, or `include` require an updated project deployment. Without one, `list()` with these options and `put()` with metadata other than `contentType` throw an error.
|
|
63
65
|
- **D1 dump:** `db.dump()` is not supported in remote mode.
|
|
64
66
|
- **D1 batches:** `db.batch()` requires an updated platform and project deployment.
|
|
@@ -106,4 +106,4 @@ export default defineRender(async (c, assetTags) => {
|
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
Server-side calls forward the incoming request's `cookie` and `authorization` headers. Explicit headers take precedence.
|
|
109
|
+
Server-side calls to your app forward the incoming request's `cookie` and `authorization` headers. Explicit headers take precedence. Calls to an external `baseURL` use HTTP and do not inherit these headers.
|
package/docs/guide/websockets.md
CHANGED
|
@@ -151,7 +151,7 @@ Messages are JSON events. Raw string and binary messages are not supported.
|
|
|
151
151
|
|
|
152
152
|
When Void auth is enabled, every WebSocket hook receives the current user as `ctx.user`, or `null` for an anonymous connection. Use `onBeforeConnect` to reject unauthenticated clients.
|
|
153
153
|
|
|
154
|
-
Connections from another origin are anonymous unless that origin is in your auth `trustedOrigins`. If you read your own cookies from `ctx.request`, check its `Origin` header yourself.
|
|
154
|
+
Connections from another origin are anonymous unless that origin is in your auth `trustedOrigins`. If you read your own cookies from `ctx.request` in `onBeforeConnect`, check its `Origin` header yourself.
|
|
155
155
|
|
|
156
156
|
`ctx.user` is resolved when the socket connects and stays the same for that connection, even if the user later signs out or the session is revoked. For actions that must respect a ban or role change, re-check your own records in `onMessage` and close the connection with `ctx.connection.close()` in rooms or `ctx.socket.close()` in `defineWebSocket()`.
|
|
157
157
|
|
|
@@ -173,7 +173,7 @@ Every hook receives a context with:
|
|
|
173
173
|
- `ctx.id`: deterministic route instance id
|
|
174
174
|
- `ctx.params`: matched route params
|
|
175
175
|
- `ctx.user`: resolved auth user or `null`
|
|
176
|
-
- `ctx.request`
|
|
176
|
+
- `ctx.request`: the HTTP request in `onBeforeConnect`, `onConnect`, and `onRequest`. In `onMessage` and `onClose`, it is a placeholder without headers, cookies, or query. To keep request data, save it in `onConnect` with `ctx.connection.setState()` in rooms or `ctx.socket.setState()` in `defineWebSocket()`. Read it later from `ctx.connection.state` or `ctx.socket.state`.
|
|
177
177
|
- `ctx.env`
|
|
178
178
|
- `ctx.storage`
|
|
179
179
|
|
package/docs/index.md
CHANGED
|
@@ -4,36 +4,92 @@ theme: dark
|
|
|
4
4
|
|
|
5
5
|
hero:
|
|
6
6
|
name: Void
|
|
7
|
-
text:
|
|
8
|
-
tagline:
|
|
7
|
+
text: Build with Vite. Deploy with Void.
|
|
8
|
+
tagline: Void is a CLI, platform, and full-stack SDK that unifies building & deploying apps.
|
|
9
9
|
actions:
|
|
10
10
|
- theme: brand
|
|
11
11
|
text: Get Started
|
|
12
12
|
link: ./guide/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
- theme: alt
|
|
14
|
+
text: View on GitHub
|
|
15
|
+
link: https://github.com/voidzero-dev/void
|
|
16
|
+
- theme: alt
|
|
17
|
+
text: Read the Announcement
|
|
18
|
+
link: https://blog.cloudflare.com/deploy-with-void
|
|
17
19
|
features:
|
|
18
|
-
- iconify: lucide:terminal
|
|
19
|
-
title: Deploy with One Command
|
|
20
|
-
details: '`void deploy` builds your app, provisions resources, applies migrations, and deploys it.'
|
|
21
20
|
- iconify: lucide:layers
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
visual: stack
|
|
22
|
+
title: Full-Stack, Inferred
|
|
23
|
+
details: Import what you need. Void provides local resources and provisions them on deploy.
|
|
24
|
+
highlights:
|
|
25
|
+
- Server routes and authentication
|
|
26
|
+
- Databases, storage, and AI
|
|
27
|
+
- Queues and scheduled jobs
|
|
28
|
+
guide:
|
|
29
|
+
text: Explore the SDK
|
|
30
|
+
link: /guide/
|
|
24
31
|
- iconify: lucide:wand-sparkles
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
visual: resources
|
|
33
|
+
title: Typed from Database to UI
|
|
34
|
+
details: Share types across your database, server loaders, and page components.
|
|
35
|
+
highlights:
|
|
36
|
+
- Types from your database schema
|
|
37
|
+
- Typed loaders, actions, and APIs
|
|
38
|
+
- Server code stays on the server
|
|
39
|
+
guide:
|
|
40
|
+
text: Explore Type Safety
|
|
41
|
+
link: /guide/type-safety
|
|
30
42
|
- iconify: lucide:blocks
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
visual: frameworks
|
|
44
|
+
title: Use Your Favorite Framework
|
|
45
|
+
details: Build with Void's adapters or keep your existing Vite framework.
|
|
46
|
+
highlights:
|
|
47
|
+
- Ships with adapters for Async React, Vue, Svelte, and Solid
|
|
48
|
+
- Supports TanStack Start, SvelteKit, Nuxt, and more
|
|
49
|
+
- Build APIs, SPAs, or server-rendered pages
|
|
50
|
+
guide:
|
|
51
|
+
text: Explore Frameworks
|
|
52
|
+
link: /integrations/frameworks/overview
|
|
53
|
+
platform_features:
|
|
54
|
+
- id: platform-ai-coding
|
|
55
|
+
iconify: lucide:bot
|
|
56
|
+
title: Secure Vibe Coding for Your Team
|
|
57
|
+
details: Let your team build and deploy with coding agents while admins retain control of Cloudflare access.
|
|
58
|
+
highlights:
|
|
59
|
+
- Enable non-technical teammates to build their own apps
|
|
60
|
+
- Keep Cloudflare credentials with your admin team
|
|
61
|
+
- Deploy prototypes fast and share apps for feedback
|
|
62
|
+
guide:
|
|
63
|
+
text: Explore team deployments
|
|
64
|
+
link: /guide/self-hosted-platform
|
|
65
|
+
visual: rive
|
|
66
|
+
image_alt: Animated illustration of apps being built for a team
|
|
67
|
+
- id: platform-control-plane
|
|
68
|
+
iconify: lucide:panels-top-left
|
|
69
|
+
visual: resources
|
|
70
|
+
title: Control Plane for Managing Apps
|
|
71
|
+
details: Manage users, projects, deployments, and platform health from the admin UI or CLI.
|
|
72
|
+
highlights:
|
|
73
|
+
- Manage users and project access & resources
|
|
74
|
+
- Inspect deployments, logs, and rollbacks
|
|
75
|
+
- Monitor platform health and usage
|
|
76
|
+
guide:
|
|
77
|
+
text: Platform administration
|
|
78
|
+
link: /guide/platform-administration
|
|
79
|
+
image_alt: List of Void platform commands for access, builds, invitations, and administration
|
|
80
|
+
- id: platform-security
|
|
81
|
+
iconify: lucide:shield-check
|
|
82
|
+
title: Bring your Own Security
|
|
83
|
+
details: Fork and customize your own Void platform based on your team's security standards.
|
|
84
|
+
highlights:
|
|
85
|
+
- Manage access through Cloudflare Access, Google, GitHub, or OIDC
|
|
86
|
+
- Control who can sign in and deploy
|
|
87
|
+
- Protect projects with your access policies
|
|
88
|
+
guide:
|
|
89
|
+
text: Configure platform access
|
|
90
|
+
link: /guide/platform/administration/access
|
|
91
|
+
visual: rive
|
|
92
|
+
image_alt: Animated illustration of self-hosted platform security
|
|
37
93
|
footer_heading: Build with Vite. Deploy with Void.
|
|
38
94
|
footer_subheading: Server code, resources, and deployment in one workflow.
|
|
39
95
|
---
|
|
@@ -183,7 +183,7 @@ void project status
|
|
|
183
183
|
void project rollback [version]
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
Void restores recorded triggers along with the code. Versions without a complete trigger snapshot keep current routes and schedules. Rollback does not reverse database migrations.
|
|
186
|
+
Void restores recorded triggers along with the code. Versions without a complete trigger snapshot keep current routes and schedules. Rollback does not reverse database migrations. To undo D1 migrations, run [`void db restore`](../reference/cli/database.md#void-db-restore) with the restore point that deploy printed before it applied them, within 7 days on Workers Free or 30 days on Workers Paid.
|
|
187
187
|
|
|
188
188
|
#### Scope and limitations
|
|
189
189
|
|
|
@@ -71,6 +71,31 @@ Use [KV](../../guide/kv.md), [object storage](../../guide/storage.md), and [AI](
|
|
|
71
71
|
|
|
72
72
|
Declare variables in `env.ts` and read them with `import { env } from "void/env"`. See [Environment Variables](../../guide/env-vars.md) for local values, production secrets, and public `VITE_*` values.
|
|
73
73
|
|
|
74
|
+
## Custom Worker Entry
|
|
75
|
+
|
|
76
|
+
Set `cloudflare.main` in `void.config.ts` when your Worker needs its own entry module, for example to export a Durable Object class:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { defineConfig } from 'void/config';
|
|
80
|
+
|
|
81
|
+
export default defineConfig({
|
|
82
|
+
cloudflare: { main: './server.ts' },
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The path is relative to your app root. Default-export the TanStack request handler and add your named exports in that module:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import handler from '@tanstack/react-start/server-entry';
|
|
90
|
+
|
|
91
|
+
export { Counter } from './counter';
|
|
92
|
+
export default handler;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Void preserves these named exports in development, production builds, and deploys. Without `cloudflare.main`, Void uses TanStack's default server entry. A package entry such as `@tanstack/react-start/server-entry` is resolved as a module.
|
|
96
|
+
|
|
97
|
+
Bind an exported Durable Object or Workflow class under `cloudflare` as well, for example in `cloudflare.durable_objects`. These settings apply when you deploy with `void deploy --platform cloudflare`. On a Void platform, use [Durable State](../../guide/durable-state.md) instead.
|
|
98
|
+
|
|
74
99
|
## Accessing Bindings Directly
|
|
75
100
|
|
|
76
101
|
You can also access Cloudflare bindings via the `cloudflare:workers` module:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Deployment artifacts
|
|
2
2
|
|
|
3
|
-
Use `void/deploy` from Node.js to prepare a built Void app for a managed platform deployment without platform credentials.
|
|
3
|
+
Use `void/deploy` from Node.js to prepare a built Void app, SPA, or static site for a managed platform deployment without platform credentials.
|
|
4
4
|
|
|
5
5
|
Build the app in managed mode inside its isolated environment:
|
|
6
6
|
|
|
@@ -16,8 +16,40 @@ import { prepareDeployArtifact } from 'void/deploy';
|
|
|
16
16
|
const { artifact, assets } = await prepareDeployArtifact('/path/to/app');
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
`artifact` contains the deployment manifest, content-addressed asset metadata, and base64 Worker modules. `assets` maps asset URL paths to base64 bytes. Keep this result immutable while requesting [publish approval](/guide/platform/administration/connected-apps).
|
|
19
|
+
`artifact` contains the deployment manifest, content-addressed asset metadata, and base64 Worker modules when the app needs a Worker. SPAs and static sites contain only assets, using the same app detection, output directory and routing configuration as `void deploy`. `assets` maps asset URL paths to base64 bytes. Keep this result immutable while requesting [publish approval](/guide/platform/administration/connected-apps).
|
|
20
20
|
|
|
21
|
-
Preparation packages existing build output; it does not build, contact a platform, provision resources, or deploy. It supports Void Cloudflare Worker builds. Node targets,
|
|
21
|
+
Preparation packages existing build output; it does not build, contact a platform, provision resources, or deploy. It supports Void Cloudflare Worker builds, SPAs, and static sites. Node targets, Pages `output: 'static'`, remote data, deploy-time prerendering, Sandbox, and Live resources require the normal `void deploy` workflow instead.
|
|
22
22
|
|
|
23
23
|
Run preparation inside the same isolated environment as the app build. App configuration and build plugins execute project code; keep platform credentials on the publishing server.
|
|
24
|
+
|
|
25
|
+
## Cloudflare Build Output
|
|
26
|
+
|
|
27
|
+
::: warning Experimental
|
|
28
|
+
`prepareCfBuildOutput` follows Cloudflare's draft Build Output format. Its options and the prepared directory can change between Void releases.
|
|
29
|
+
:::
|
|
30
|
+
|
|
31
|
+
Use `prepareCfBuildOutput` to convert an existing Cloudflare Worker build into a disposable Cloudflare Build Output directory:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { prepareCfBuildOutput } from 'void/deploy';
|
|
35
|
+
|
|
36
|
+
const prepared = await prepareCfBuildOutput('/path/to/app/dist/server', { mode: 'staging' });
|
|
37
|
+
if (!prepared) {
|
|
38
|
+
throw new Error('The Worker build could not be prepared.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
// Inspect or pass prepared.directory to your Cloudflare publication workflow.
|
|
43
|
+
} finally {
|
|
44
|
+
await prepared.dispose();
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Pass the Worker output directory that contains a generated `wrangler.json`, such as `dist/ssr`, `dist/rsc`, or `dist/server`. When Cloudflare's build tooling built the app, pass the project root that contains its native Build Output at `.cloudflare/output/v0` instead. Preparation copies modules and assets without changing that input. Native output keeps its module types, auxiliary Workers, Container declarations, and build metadata. Preparation does not provision resources, upload a Worker, or activate a deployment. Container images built from a local Dockerfile exist only in the Docker environment that built them, so publish from that environment.
|
|
49
|
+
|
|
50
|
+
| Option | Description |
|
|
51
|
+
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `accountId` | Cloudflare account the build must target. A different account in the build returns `null`. When omitted, the build's account is kept or left unset. |
|
|
53
|
+
| `mode` | Vite build mode. Native output keeps the mode it was built with, and a different value returns `null`. For other output it defaults to `production`. |
|
|
54
|
+
|
|
55
|
+
The result contains `directory`, an optional `assetsDirectory` pointing to the input assets, and an asynchronous `dispose()` method. Always dispose the result after use. Unsupported build configuration returns `null`. A directory without a Worker build, a missing or invalid Worker module, or an asset symlink outside the asset directory throws an error.
|