void 0.26.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{account-cmd-CfUXh_nU.mjs → account-cmd-Ci00cncT.mjs} +5 -5
- package/dist/{agents-B_pX_HmQ.mjs → agents-CuNtT0D_.mjs} +5 -2
- package/dist/{application-analysis-DKy02UY0.mjs → application-analysis-D72ZQfMZ.mjs} +118 -135
- package/dist/{application-routing-DQyUh_5S.mjs → application-routing-Dy589Vgn.mjs} +1 -2
- package/dist/atomic-write-Dq6R0BPN.mjs +18 -0
- package/dist/{auth-B5_tZLxT.mjs → auth-B6iOCjKI.mjs} +23 -56
- package/dist/{auth-link-D5RmKnzh.mjs → auth-link-DWr6Afao.mjs} +10 -10
- package/dist/{auth-migrations-BwHgeEsD.mjs → auth-migrations-Cgs0k6lS.mjs} +28 -5
- package/dist/{auth-router-Bap-pvbn.mjs → auth-router-DP14wVkZ.mjs} +4 -4
- package/dist/auth-wn6F8dB8.mjs +2 -0
- package/dist/base64-DVrOndmI.mjs +16 -0
- package/dist/{better-auth-shared-CPvWD3nG.d.mts → better-auth-shared-B74NJIus.d.mts} +8 -13
- package/dist/{better-auth-shared-DPpj8zxc.mjs → better-auth-shared-CMXlZG7W.mjs} +56 -68
- package/dist/{build-cmd-B58c8iS8.mjs → build-cmd-Cr3FJxv0.mjs} +5 -5
- package/dist/{cache-Bo52trKF.mjs → cache-D0Tt28cn.mjs} +5 -5
- package/dist/{cancel-deploy-BZNz3Q26.mjs → cancel-deploy-CJKvk7AN.mjs} +4 -4
- package/dist/{cf-access-TWNzXltp.mjs → cf-access-BM9G0lhO.mjs} +4 -3
- package/dist/{cf-access-ngGqZpHZ.mjs → cf-access-CWP4avfP.mjs} +3 -7
- package/dist/cf-build-output-2u583yJK.mjs +2 -0
- package/dist/{cf-build-output-DjvB_872.mjs → cf-build-output-Bc8i3dzE.mjs} +2 -2
- package/dist/cf-user-agent-ChjQp2MU.mjs +33 -0
- package/dist/cli/cli.mjs +198 -311
- package/dist/cli/cloudflare-operation-process.mjs +46 -14
- package/dist/cli/env-schema-probe.d.mts +5 -43
- package/dist/cli/env-schema-probe.mjs +14 -80
- package/dist/client-C1BjRn3g.mjs +2 -0
- package/dist/{client-C2Prx_Bi.mjs → client-DM9Kcf4e.mjs} +161 -415
- package/dist/{cloudflare-auth-CuxfF6OA.mjs → cloudflare-auth-CqFBDo52.mjs} +12 -39
- package/dist/{cloudflare-cmd-lHqNlJGW.mjs → cloudflare-cmd-CTrn-lXJ.mjs} +6 -5
- package/dist/{cloudflare-config-BmhBv3HV.mjs → cloudflare-config-DV60XFFK.mjs} +16 -28
- package/dist/{cloudflare-connect-2G3rL2rP.mjs → cloudflare-connect-BosmCNlq.mjs} +3 -3
- package/dist/{cloudflare-operations-CwI1bChl.mjs → cloudflare-operations-BKdSfNBN.mjs} +26 -34
- package/dist/{cloudflare-operations-BlYLlowZ.mjs → cloudflare-operations-Ds-lX3Ts.mjs} +1 -1
- package/dist/{cloudflare-process-2-TfIEzB.mjs → cloudflare-process-CeDWJRhj.mjs} +12 -7
- package/dist/collect-NUlJMpLY.mjs +2 -0
- package/dist/{collect-DiTn9yr6.mjs → collect-xjffdCdk.mjs} +1 -1
- package/dist/{config-CSa15FvD.d.mts → config-7qoq2p9v.d.mts} +2 -2
- package/dist/{config-CLYAosnQ.mjs → config-BEm9vRvS.mjs} +11 -5
- package/dist/{config-DiowPT80.mjs → config-Bx_1SpnO.mjs} +87 -177
- package/dist/config-CNnrSMYm.mjs +2 -0
- package/dist/{config-DPByhVck.mjs → config-D0GY5ItR.mjs} +1 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{connect-X0MUA1gk.mjs → connect-nukQSoEO.mjs} +8 -8
- package/dist/{create-project-DxiyW6iX.mjs → create-project-D4APeBwX.mjs} +7 -7
- package/dist/{create-project-iwkbqiBU.mjs → create-project-DL7YXpjj.mjs} +1 -1
- package/dist/{db-XnVMHzoV.mjs → db-27RztQLy.mjs} +173 -263
- package/dist/{delete-esYlMiSJ.mjs → delete-BbsZFZIw.mjs} +5 -5
- package/dist/deploy-B06EQq4t.mjs +6009 -0
- package/dist/deploy-Db2ALnQP.mjs +3 -0
- package/dist/deploy-managed-static-CGswbcay.mjs +2277 -0
- package/dist/deploy-transport-BiicfoQW.mjs +180 -0
- package/dist/deploy.d.mts +10 -0
- package/dist/deploy.mjs +82 -0
- package/dist/dev-inbox-Rd6j_8vM.mjs +217 -0
- package/dist/discover-CTUiSsfG.mjs +2 -0
- package/dist/{discover-CkCYv9T_.mjs → discover-D2PGT63u.mjs} +2 -2
- package/dist/{dist-BVqXeR_h.mjs → dist-ipQi0Q8y.mjs} +2 -3
- package/dist/{domain-CbbBWhWE.mjs → domain-Bfq9n03H.mjs} +7 -22
- package/dist/{dotenv-BfU6eqFt.mjs → dotenv-CNazY3-w.mjs} +4 -16
- package/dist/{email-d_Aux1vM.mjs → email-BcjSyAL0.mjs} +4 -20
- package/dist/{email-CpuT42g7.mjs → email-DIwaQU4P.mjs} +99 -191
- package/dist/email-cloudflare-CH053RxK.mjs +1096 -0
- package/dist/email-protocol-D9nTvhCp.mjs +82 -0
- package/dist/{entry-CMAkqBmU.mjs → entry-ehmBvs5w.mjs} +2 -2
- package/dist/{env-BxocywBB.mjs → env-BJjULvL0.mjs} +2 -2
- package/dist/{env-DMA3cXZt.mjs → env-BhdWMrNy.mjs} +2 -13
- package/dist/{env-w9jOyGZn.mjs → env-C6ipBLp3.mjs} +8 -8
- package/dist/{env-public-DR7ZM6d-.d.mts → env-public-CCdykygU.d.mts} +6 -23
- package/dist/{env-raw-jZpP5n47.mjs → env-raw-Cklzcde3.mjs} +3 -20
- package/dist/{env-types-CwXgeMgL.mjs → env-types-DS2_y4X8.mjs} +2 -2
- package/dist/{env-validation-CrVNjsPm.mjs → env-validation-CTn-HhG1.mjs} +1 -1
- package/dist/env-validation-cE0zcmzO.mjs +486 -0
- package/dist/{gen-DtkQhvQg.mjs → gen-CnN1Xidx.mjs} +131 -253
- package/dist/gen-F8pSZnhc.mjs +2 -0
- package/dist/{generate-GDbL7sUr.mjs → generate-Dat0UTry.mjs} +38 -4
- package/dist/generate-Rii9klHB.mjs +2 -0
- package/dist/generated-wrangler-config-DeWj5F9Y.mjs +18 -0
- package/dist/{github-cmd-D_FsOFxq.mjs → github-cmd-BdkU4Nhe.mjs} +27 -71
- package/dist/{handler-BHAn2fZJ.mjs → handler-BZ1t7-Rv.mjs} +2 -2
- package/dist/{handler-CNAwjRcW.d.mts → handler-_PqY82xe.d.mts} +1 -1
- package/dist/{headers-DlfR78Nu.mjs → headers-Di1FsD3e.mjs} +26 -81
- package/dist/{help-CVFBTmBx.mjs → help-Bug7pyK_.mjs} +18 -10
- package/dist/help-s9q7LTcu.mjs +2 -0
- package/dist/{inbound-PfQDLXc5.mjs → inbound-DmkTQeWp.mjs} +71 -222
- package/dist/{inbound-CH5Mksyy.d.mts → inbound-brj2-TM5.d.mts} +19 -58
- package/dist/index.d.mts +2 -18
- package/dist/index.mjs +200 -496
- package/dist/{info-PYWwkWyt.mjs → info-CujPwtMe.mjs} +5 -5
- package/dist/{init-Bw-fRKGp.mjs → init-ZWOJvc-Z.mjs} +179 -388
- package/dist/isr-config-DPjXM8J2.mjs +194 -0
- package/dist/{link-DlPG8iX3.mjs → link-UEc7bnF4.mjs} +8 -8
- package/dist/{list-2GN7_ueV.mjs → list-CuWeOnzk.mjs} +6 -17
- package/dist/{live-CgQuTpqD.mjs → live-BxLX-JqJ.mjs} +19 -17
- package/dist/{live-Du8jXwOW.d.mts → live-DJONVlQK.d.mts} +1 -1
- package/dist/load-user-env-DD5qveNU.mjs +49 -0
- package/dist/{local-d1-ga5O_idV.mjs → local-d1-BM3p74mm.mjs} +6 -6
- package/dist/{login-D-Q4xw3Q.mjs → login-CZ2Cqa-D.mjs} +11 -11
- package/dist/login-DhK7o1oJ.mjs +2 -0
- package/dist/{logs-rd8J-OFh.mjs → logs-TihRcLTk.mjs} +5 -5
- package/dist/migrate-BgT-hmu8.mjs +2 -0
- package/dist/{migrate-NLsjBbuM.mjs → migrate-uFwojusJ.mjs} +69 -21
- package/dist/migration-handler-Cg0Y4EPu.mjs +470 -0
- package/dist/{migration-handler-DM4clYj5.d.mts → migration-handler-CwlEQUoo.d.mts} +17 -26
- package/dist/{mime-DxCznlJq.mjs → mime-srOklVVv.mjs} +92 -395
- package/dist/{node-DJicPvPj.mjs → node-DoKbo1SZ.mjs} +8 -24
- package/dist/{operator-args-BNsW5gfp.mjs → operator-args-UnE8Y2eK.mjs} +27 -26
- package/dist/{operator-auth-AzVLbrr3.mjs → operator-auth-Cr2zCc-J.mjs} +2 -2
- package/dist/{operator-client-BQtzyG-g.mjs → operator-client-C-ROjk1I.mjs} +4 -4
- package/dist/{operator-cmd-B6f6Cg9Z.mjs → operator-cmd-C5lCctnc.mjs} +8 -8
- package/dist/operator-cmd-Cjk5DiRx.mjs +2 -0
- package/dist/{output-C50ag2r3.mjs → output-FNHKw5Ac.mjs} +36 -5
- package/dist/{package-json-DXfiT1jV.mjs → package-json-BjYqR-So.mjs} +1 -1
- package/dist/pages/client.d.mts +1 -1
- package/dist/pages/client.mjs +91 -5
- package/dist/pages/index.d.mts +1 -2
- package/dist/pages/index.mjs +6 -6
- package/dist/pages/islands-plugin.mjs +5 -83
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +1 -1
- package/dist/pages/serialize.mjs +1 -1
- package/dist/{platform-args-BoZkWQnJ.mjs → platform-args-C6Mb_I3a.mjs} +34 -58
- package/dist/platform-args-Cm7x-fot.mjs +2 -0
- package/dist/{platform-auth-config-n603OANg.mjs → platform-auth-config-CJmNkFT2.mjs} +10 -11
- package/dist/{platform-auth-protection-zxDr0hWW.mjs → platform-auth-protection-D5wvsI-Y.mjs} +36 -26
- package/dist/{platform-auth-recovery-tw9lgtgE.mjs → platform-auth-recovery-D_0I3n-1.mjs} +8 -9
- package/dist/{platform-cmd-C00YM14r.mjs → platform-cmd-Cuj4oUVo.mjs} +1 -1
- package/dist/{platform-cmd-B8-bCb7t.mjs → platform-cmd-DxxZO6e5.mjs} +17 -16
- package/dist/{platform-discovery-BC0HCKYt.mjs → platform-discovery-CHhNs8Nn.mjs} +1 -1
- package/dist/{platform-domain-p0kobLV8.mjs → platform-domain-zLXnW1G_.mjs} +5 -5
- package/dist/{platform-lifecycle-D_QEY32D.mjs → platform-lifecycle-DOW-wLfx.mjs} +1398 -2043
- package/dist/{platform-lifecycle-vFqtNPPa.mjs → platform-lifecycle-_gfnjUBr.mjs} +1 -1
- package/dist/{platform-management-oi-SvI3f.mjs → platform-management-CYrLvTGH.mjs} +1 -1
- package/dist/{platform-management-BdYblvvE.mjs → platform-management-t7HKy4-U.mjs} +632 -124
- package/dist/{platform-plans-config-CjiFv5J4.mjs → platform-plans-config-CNH6zbPX.mjs} +15 -11
- package/dist/{platform-recovery-PvNS9Nl2.mjs → platform-recovery-DeucI7A9.mjs} +6 -9
- package/dist/{platform-registry-P387v42A.mjs → platform-registry-B9mWX9LO.mjs} +18 -19
- package/dist/{platform-setup-DVe42Ws7.mjs → platform-setup-CTf6MMT9.mjs} +19 -26
- package/dist/{plugin-inference-BlQbOL0P.mjs → plugin-inference-DsARdQKE.mjs} +18 -33
- package/dist/{prepare-Dq9hTIbo.mjs → prepare-C4zfwks4.mjs} +3 -3
- package/dist/{prepare-Do96654b.mjs → prepare-CSH9dKTI.mjs} +11 -13
- package/dist/prepare-dr9uxQSV.mjs +2 -0
- package/dist/{prerender-render-Ct20jftc.mjs → prerender-render-Bfsumdkv.mjs} +8 -2
- package/dist/prerender-render.d.mts +2 -0
- package/dist/prerender-render.mjs +2 -2
- package/dist/project-DiiOBZPF.mjs +2 -0
- package/dist/{project-cmd-ti8_yTcA.mjs → project-cmd-Dq75AXzy.mjs} +19 -19
- package/dist/{project-paths-GgcMozYz.mjs → project-paths-DMvEeSau.mjs} +9 -14
- package/dist/{project-DQstYTxO.mjs → project-rqDnVsJN.mjs} +8 -4
- package/dist/{project-team-CDPE1Tsg.mjs → project-team-B3_QcStG.mjs} +6 -6
- package/dist/{project-token-CkZ1cN0Z.mjs → project-token-CvsRvv2I.mjs} +5 -5
- package/dist/{project-tsconfig-CVJhNMxs.mjs → project-tsconfig-bveqhlYA.mjs} +3 -5
- package/dist/{project-zero-trust-DdjLR61k.mjs → project-zero-trust-D1ICiwN_.mjs} +5 -5
- package/dist/{protocol-BPZaNqBo.d.mts → protocol-4H7V_3Os.d.mts} +1 -1
- package/dist/{protocol-CfaUwNs8.mjs → protocol-RNP0u7UY.mjs} +9 -3
- package/dist/{provision-BfaLiWbj.mjs → provision-DDh7ITVS.mjs} +118 -865
- package/dist/{requests-DFAqyYy8.mjs → requests-3CL3BuZh.mjs} +4 -4
- package/dist/resolve-project-B9Hr0D3n.mjs +2 -0
- package/dist/resolve-project-C_Cu7E8a.mjs +48 -0
- package/dist/{rollback-BKYXBduI.mjs → rollback-Ce1d_0J9.mjs} +7 -17
- package/dist/{route-types-CbtsIeFn.mjs → route-types-IrBuwJ7u.mjs} +35 -70
- package/dist/routing-assets-VkrKIbxE.mjs +139 -0
- package/dist/{runner-9wjsSZx-.mjs → runner-B5huK2eC.mjs} +1 -1
- package/dist/{runner-DMBKSrRk.mjs → runner-DcVDrzuR.mjs} +7 -28
- package/dist/{runner-mysql-CEzKtmFb.mjs → runner-mysql-CCtyI0p6.mjs} +4 -3
- package/dist/runner-mysql-CaJq-hd6.mjs +2 -0
- package/dist/runner-pg-BJhFZZG4.mjs +2 -0
- package/dist/{runner-pg-DV8p_zjA.mjs → runner-pg-CPd-CB_F.mjs} +1 -1
- package/dist/runtime/ai.mjs +9 -22
- package/dist/runtime/better-auth-mysql.d.mts +2 -5
- package/dist/runtime/better-auth-mysql.mjs +6 -31
- package/dist/runtime/better-auth-pg.d.mts +2 -5
- package/dist/runtime/better-auth-pg.mjs +6 -32
- package/dist/runtime/better-auth.d.mts +2 -4
- package/dist/runtime/better-auth.mjs +9 -19
- package/dist/runtime/db.mjs +1 -1
- package/dist/runtime/durable.d.mts +16 -0
- package/dist/runtime/durable.mjs +26 -2
- package/dist/runtime/email/testing.d.mts +1 -1
- package/dist/runtime/email/testing.mjs +9 -23
- package/dist/runtime/email-protocol.d.mts +12 -0
- package/dist/runtime/email-protocol.mjs +2 -70
- package/dist/runtime/email.d.mts +1 -1
- package/dist/runtime/email.mjs +79 -221
- package/dist/runtime/env-public.d.mts +1 -1
- package/dist/runtime/env-public.mjs +12 -38
- package/dist/runtime/env.d.mts +1 -12
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/handler.mjs +1 -1
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/kv.mjs +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +1 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/live.mjs +1 -1
- package/dist/runtime/migration-handler-mysql.d.mts +2 -2
- package/dist/runtime/migration-handler-mysql.mjs +3 -2
- package/dist/runtime/migration-handler-pg.d.mts +2 -2
- package/dist/runtime/migration-handler-pg.mjs +1 -1
- package/dist/runtime/migration-handler.d.mts +2 -2
- package/dist/runtime/migration-handler.mjs +2 -470
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/remote/binding-handler.mjs +62 -62
- package/dist/runtime/remote/index.mjs +16 -77
- package/dist/runtime/routing.d.mts +1 -4
- package/dist/runtime/routing.mjs +82 -218
- package/dist/runtime/sandbox-container.d.mts +2 -2
- package/dist/runtime/sandbox-container.mjs +2 -2
- package/dist/runtime/sandbox.d.mts +2 -2
- package/dist/runtime/sandbox.mjs +13 -6
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -3
- package/dist/runtime/ws-server.mjs +6 -28
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/{sandbox-container-Bo0eiFKz.d.mts → sandbox-container-ChQRum-j.d.mts} +3 -1
- package/dist/{sandbox-container-C6ItmVuN.mjs → sandbox-container-DBKIqDEK.mjs} +12 -1
- package/dist/{sandbox-C5LFoJMf.d.mts → sandbox-q3waMc2T.d.mts} +1 -1
- package/dist/{scan-C3uDzz6J.mjs → scan-C0BMdmEd.mjs} +84 -7
- package/dist/{secret-BAt2KMmO.mjs → secret-B5J8bBsI.mjs} +62 -80
- package/dist/{serialize-BPvnNQuA.mjs → serialize-BtQyaYoC.mjs} +10 -4
- package/dist/{skills-BgVMvQdy.mjs → skills-BJsan98C.mjs} +2 -2
- package/dist/{subcommand-prompt-BSlnD1fI.mjs → subcommand-prompt-gQ-NDA-u.mjs} +38 -43
- package/dist/sveltekit.mjs +1 -1
- package/dist/validate-C9xtFOYR.mjs +2 -0
- package/dist/{validate-C9qJArv7.mjs → validate-CheZGRE7.mjs} +4 -8
- package/dist/version-metadata-DIrqEHQo.mjs +73 -0
- package/dist/{wrangler-D9KTuqnv.mjs → wrangler-BYs07Rxy.mjs} +119 -378
- package/dist/{ws-CChrrAU-.d.mts → ws-aKVYB-fA.d.mts} +1 -1
- package/dist/yarn-pnp-DLbEFMT0.mjs +92 -0
- package/docs/guide/auth.md +2 -0
- package/docs/guide/database/postgresql.md +2 -0
- package/docs/guide/database.md +2 -0
- package/docs/guide/deployment.md +2 -2
- package/docs/guide/durable-state.md +24 -0
- package/docs/guide/platform/administration/access.md +5 -1
- package/docs/guide/platform/administration/connected-apps.md +55 -0
- package/docs/guide/platform/installation/credentials.md +3 -1
- package/docs/guide/platform/installation/first-deployment.md +1 -1
- package/docs/guide/project-collaboration.md +1 -1
- package/docs/guide/quickstart.md +2 -0
- package/docs/guide/sandboxes.md +2 -0
- package/docs/reference/api/deploy.md +23 -0
- package/docs/reference/api/pages.md +2 -0
- package/docs/reference/api.md +2 -1
- package/docs/reference/cli/auth.md +1 -1
- package/docs/reference/cli/database.md +9 -3
- package/docs/reference/cli/deploy.md +1 -1
- package/docs/reference/cli/platform-installation.md +1 -1
- package/docs/reference/cli/setup.md +2 -0
- package/package.json +14 -17
- package/skills/void/SKILL.md +4 -2
- package/dist/auth-BgX2qYSY.mjs +0 -2
- package/dist/cf-build-output-H9a97vME.mjs +0 -2
- package/dist/client-By4JjMw_.mjs +0 -2
- package/dist/collect-DLyFDiKW.mjs +0 -2
- package/dist/config-5r-YpMC-.mjs +0 -2
- package/dist/config-B_ggY-IO.mjs +0 -89
- package/dist/config-BtSFvXZx.mjs +0 -2
- package/dist/config-write-AHGesphx.mjs +0 -61
- package/dist/deploy-BsEvnlJl.mjs +0 -10455
- package/dist/deploy-C1d-YTfp.mjs +0 -2
- package/dist/dev-inbox-CK-UuPob.mjs +0 -297
- package/dist/discover-EDUf6JJw.mjs +0 -2
- package/dist/dist-_UUlL6bg.mjs +0 -2
- package/dist/env-validation-Dxdx_5wo.mjs +0 -951
- package/dist/gen-dA9hW7AV.mjs +0 -2
- package/dist/head-client-DzmJGN4C.mjs +0 -90
- package/dist/help-DzKUrQvk.mjs +0 -2
- package/dist/login-Dc-wuTDq.mjs +0 -2
- package/dist/migrate-BHp07yJE.mjs +0 -2
- package/dist/operator-cmd-Cwn50lOV.mjs +0 -2
- package/dist/pages/head-client.d.mts +0 -13
- package/dist/pages/head-client.mjs +0 -2
- package/dist/platform-args-DYgITk0D.mjs +0 -2
- package/dist/prepare-DRUV-g3X.mjs +0 -2
- package/dist/project-BiaPQ7ur.mjs +0 -2
- package/dist/provision-Wu9ZBk9L.mjs +0 -2
- package/dist/resolve-project-BIeYs9Cw.mjs +0 -2
- package/dist/resolve-project-CP8rZs_p.mjs +0 -28
- package/dist/runner-mysql-CkFqZ6CE.mjs +0 -2
- package/dist/runner-pg-BGYRFdRp.mjs +0 -2
- package/dist/runtime/env-helpers.d.mts +0 -2
- package/dist/runtime/env-helpers.mjs +0 -2
- package/dist/validate-BJr9LfXy.mjs +0 -2
- package/dist/yarn-pnp-CUX_iTPA.mjs +0 -188
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as join, n as dirname, o as normalize, t as basename } from "./dist-
|
|
2
|
-
import "./project-paths-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-BmhBv3HV.mjs";
|
|
1
|
+
import { a as join, n as dirname, o as normalize, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
2
|
+
import "./project-paths-DMvEeSau.mjs";
|
|
3
|
+
import { d as readConfig } from "./config-Bx_1SpnO.mjs";
|
|
4
|
+
import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-DV60XFFK.mjs";
|
|
6
5
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
6
|
import { appendSqliteClassMigration, isRecord } from "@void/deploy-core";
|
|
8
7
|
import { createHash } from "node:crypto";
|
|
8
|
+
import { isDeepStrictEqual } from "node:util";
|
|
9
9
|
import { SyntaxKind, applyEdits, createScanner, findNodeAtLocation, modify, parse, parseTree } from "jsonc-parser";
|
|
10
10
|
//#region src/cli/wrangler.ts
|
|
11
11
|
const COMPAT_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -163,27 +163,14 @@ function resolveGeneratedName(base, used, kind) {
|
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
/**
|
|
166
|
-
* Read compatibility settings
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* This function is read-only: when no explicit `compatibility_date` exists, it
|
|
171
|
-
* returns the latest known-good date without writing it anywhere. Use
|
|
172
|
-
* `ensureWranglerCompat()` when the caller is in a real dev/build/deploy
|
|
173
|
-
* lifecycle and wants to persist the default in `void.json`.
|
|
174
|
-
*
|
|
175
|
-
* @param buildOutputDir - Optional path to the build output directory (e.g.
|
|
176
|
-
* `dist/ssr`) which may contain a plugin-generated `wrangler.json` with the
|
|
177
|
-
* correct compat settings for the built worker.
|
|
166
|
+
* Read compatibility settings with priority: Void config > project Wrangler config >
|
|
167
|
+
* `<buildOutputDir>/wrangler.json` > latest known-good date. Read-only; use
|
|
168
|
+
* `ensureWranglerCompat()` to pin the default date.
|
|
178
169
|
*/
|
|
179
170
|
function readWranglerCompat(root, config, buildOutputDir) {
|
|
180
171
|
return resolveWranglerCompat(readWranglerCompatFields(root, config, buildOutputDir));
|
|
181
172
|
}
|
|
182
|
-
/**
|
|
183
|
-
* Read compatibility settings and ensure the default date is pinned in
|
|
184
|
-
* `void.json` when no explicit date exists in void.json, wrangler config, or
|
|
185
|
-
* build output.
|
|
186
|
-
*/
|
|
173
|
+
/** Like `readWranglerCompat()`, but pins the default date when no source sets one. */
|
|
187
174
|
function ensureWranglerCompat(root, config, buildOutputDir) {
|
|
188
175
|
const fields = readWranglerCompatFields(root, config, buildOutputDir);
|
|
189
176
|
const defaultDate = fields.voidDate ?? fields.wranglerDate ?? fields.buildDate ? void 0 : ensureVoidCompatibilityDate(root, fields.voidConfig);
|
|
@@ -217,13 +204,10 @@ function readWranglerCompatFields(root, config, buildOutputDir) {
|
|
|
217
204
|
}
|
|
218
205
|
if (Array.isArray(buildParsed.compatibility_flags) && buildParsed.compatibility_flags.every((f) => typeof f === "string")) buildFlags = buildParsed.compatibility_flags;
|
|
219
206
|
} catch {}
|
|
220
|
-
const voidDate = voidConfig?.worker?.compatibility_date;
|
|
221
|
-
const voidFlags = voidConfig?.worker?.compatibility_flags;
|
|
222
|
-
if (voidDate !== void 0) validateCompatDate(voidDate, "void.json worker config");
|
|
223
207
|
return {
|
|
224
208
|
voidConfig,
|
|
225
|
-
voidDate,
|
|
226
|
-
voidFlags,
|
|
209
|
+
voidDate: voidConfig?.worker?.compatibility_date,
|
|
210
|
+
voidFlags: voidConfig?.worker?.compatibility_flags,
|
|
227
211
|
wranglerDate,
|
|
228
212
|
wranglerFlags,
|
|
229
213
|
buildDate,
|
|
@@ -266,9 +250,8 @@ function ensureVoidCompatibilityDate(root, config) {
|
|
|
266
250
|
return LATEST_KNOWN_COMPAT_DATE;
|
|
267
251
|
}
|
|
268
252
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* Returns true if the file was modified.
|
|
253
|
+
* Add missing inferred bindings to the project Wrangler config for local dev; existing
|
|
254
|
+
* bindings are kept. Returns true if the file was written.
|
|
272
255
|
*/
|
|
273
256
|
function syncWranglerBindings(root, bindings, options) {
|
|
274
257
|
const { configPath, parsed, created } = readOrCreateProjectWranglerConfig(root);
|
|
@@ -357,67 +340,12 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
357
340
|
modified = true;
|
|
358
341
|
}
|
|
359
342
|
}
|
|
360
|
-
if (options?.durableObjects && options.durableObjects.length > 0) {
|
|
361
|
-
const existingBindings = durableObjectBindingsOf(parsed);
|
|
362
|
-
for (const module of options.durableObjects) {
|
|
363
|
-
const conflict = existingBindings.find((binding) => binding.name === module.bindingName && binding.class_name !== module.className);
|
|
364
|
-
if (conflict) throw new Error(`durable: binding '${module.bindingName}' is already configured for class '${conflict.class_name}', but durable-objects/ requires '${module.className}'.`);
|
|
365
|
-
}
|
|
366
|
-
const additions = options.durableObjects.filter((module) => !existingBindings.some((binding) => binding.name === module.bindingName)).map((module) => ({
|
|
367
|
-
name: module.bindingName,
|
|
368
|
-
class_name: module.className
|
|
369
|
-
}));
|
|
370
|
-
if (additions.length > 0) {
|
|
371
|
-
parsed.durable_objects = { bindings: [...existingBindings, ...additions] };
|
|
372
|
-
modified = true;
|
|
373
|
-
}
|
|
374
|
-
const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
|
|
375
|
-
for (const module of options.durableObjects) {
|
|
376
|
-
if (migrations.find((migration) => migration.tag === module.migrationTag && !migration.new_sqlite_classes?.includes(module.className))) throw new Error(`durable: migration tag '${module.migrationTag}' is already used by another Durable Object migration.`);
|
|
377
|
-
if (!hasDurableObjectSqliteMigration(migrations, module.className)) {
|
|
378
|
-
migrations.push({
|
|
379
|
-
tag: module.migrationTag,
|
|
380
|
-
new_sqlite_classes: [module.className]
|
|
381
|
-
});
|
|
382
|
-
modified = true;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
if (modified) parsed.migrations = migrations;
|
|
386
|
-
}
|
|
387
|
-
if (bindings.needsSandbox) {
|
|
388
|
-
const sandbox = options?.sandbox ?? resolveSandboxConfig({ sandbox: true }, root);
|
|
389
|
-
const bindingName = options?.bindingNames?.sandbox ?? sandbox?.binding ?? "SANDBOX";
|
|
390
|
-
const className = sandbox.className;
|
|
391
|
-
assertSandboxNamespaceConfig(parsed, sandbox);
|
|
392
|
-
const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
|
|
393
|
-
if (!existingDurableObjectBindings.some((binding) => binding.name === bindingName)) {
|
|
394
|
-
parsed.durable_objects = { bindings: [...existingDurableObjectBindings, {
|
|
395
|
-
name: bindingName,
|
|
396
|
-
class_name: className
|
|
397
|
-
}] };
|
|
398
|
-
modified = true;
|
|
399
|
-
}
|
|
400
|
-
const existingContainers = parsed.containers ?? [];
|
|
401
|
-
const containers = [...existingContainers.filter((container) => container.class_name !== className), sandboxContainerConfig(sandbox)];
|
|
402
|
-
if (JSON.stringify(containers) !== JSON.stringify(existingContainers)) {
|
|
403
|
-
parsed.containers = containers;
|
|
404
|
-
modified = true;
|
|
405
|
-
}
|
|
406
|
-
const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
|
|
407
|
-
if (!hasSandboxSqliteMigration(migrations, className)) {
|
|
408
|
-
parsed.migrations = [...migrations, {
|
|
409
|
-
tag: SANDBOX_MIGRATION_TAG,
|
|
410
|
-
new_sqlite_classes: [className]
|
|
411
|
-
}];
|
|
412
|
-
modified = true;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
343
|
if (bindings.needsLive || options?.live) {
|
|
416
344
|
const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
|
|
417
345
|
const liveConfig = typeof options?.live === "object" ? options.live : resolveLiveBindingConfig(root, {
|
|
418
346
|
existingBindings: existingDurableObjectBindings,
|
|
419
347
|
reservedBindings: options?.websockets?.map((route) => route.bindingName),
|
|
420
|
-
reservedClasses:
|
|
348
|
+
reservedClasses: options?.websockets?.map((route) => route.className)
|
|
421
349
|
});
|
|
422
350
|
if (!existingDurableObjectBindings.some((binding) => binding.name === liveConfig.bindingName)) {
|
|
423
351
|
parsed.durable_objects = { bindings: [...existingDurableObjectBindings, {
|
|
@@ -438,20 +366,38 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
438
366
|
if (created || modified) writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
439
367
|
return created || modified;
|
|
440
368
|
}
|
|
441
|
-
const NO_INFERRED_BINDINGS = {
|
|
442
|
-
needsD1: false,
|
|
443
|
-
needsKV: false,
|
|
444
|
-
needsR2: false,
|
|
445
|
-
needsAuth: false,
|
|
446
|
-
needsQueues: false,
|
|
447
|
-
needsAI: false,
|
|
448
|
-
needsSandbox: false,
|
|
449
|
-
needsLive: false
|
|
450
|
-
};
|
|
451
369
|
/** Persist convention-derived Durable Object bindings and append-only migration history. */
|
|
452
370
|
function syncWranglerDurableObjects(root, durableObjects) {
|
|
453
371
|
if (durableObjects.length === 0) return false;
|
|
454
|
-
|
|
372
|
+
const { configPath, parsed, created } = readOrCreateProjectWranglerConfig(root);
|
|
373
|
+
let modified = false;
|
|
374
|
+
const existingBindings = durableObjectBindingsOf(parsed);
|
|
375
|
+
for (const module of durableObjects) {
|
|
376
|
+
const conflict = existingBindings.find((binding) => binding.name === module.bindingName && binding.class_name !== module.className);
|
|
377
|
+
if (conflict) throw new Error(`durable: binding '${module.bindingName}' is already configured for class '${conflict.class_name}', but durable-objects/ requires '${module.className}'.`);
|
|
378
|
+
}
|
|
379
|
+
const additions = durableObjects.filter((module) => !existingBindings.some((binding) => binding.name === module.bindingName)).map((module) => ({
|
|
380
|
+
name: module.bindingName,
|
|
381
|
+
class_name: module.className
|
|
382
|
+
}));
|
|
383
|
+
if (additions.length > 0) {
|
|
384
|
+
parsed.durable_objects = { bindings: [...existingBindings, ...additions] };
|
|
385
|
+
modified = true;
|
|
386
|
+
}
|
|
387
|
+
const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
|
|
388
|
+
for (const module of durableObjects) {
|
|
389
|
+
if (migrations.find((migration) => migration.tag === module.migrationTag && !migration.new_sqlite_classes?.includes(module.className))) throw new Error(`durable: migration tag '${module.migrationTag}' is already used by another Durable Object migration.`);
|
|
390
|
+
if (!hasDurableObjectSqliteMigration(migrations, module.className)) {
|
|
391
|
+
migrations.push({
|
|
392
|
+
tag: module.migrationTag,
|
|
393
|
+
new_sqlite_classes: [module.className]
|
|
394
|
+
});
|
|
395
|
+
modified = true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (modified) parsed.migrations = migrations;
|
|
399
|
+
if (created || modified) writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
400
|
+
return created || modified;
|
|
455
401
|
}
|
|
456
402
|
/** Persist WebSocket Durable Object bindings and SQLite migration history. */
|
|
457
403
|
function syncWranglerWebSockets(root, websockets) {
|
|
@@ -459,10 +405,8 @@ function syncWranglerWebSockets(root, websockets) {
|
|
|
459
405
|
return writeProvisionedWranglerConfig(root, { webSockets: websockets }).modified;
|
|
460
406
|
}
|
|
461
407
|
/**
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
* in Wrangler configuration. Arbitrary user Durable Objects are excluded by
|
|
465
|
-
* requiring provenance from Void's WebSocket migration tag.
|
|
408
|
+
* Registered WebSocket classes without a source route. They stay exported while their
|
|
409
|
+
* bindings remain; only classes created by Void's WebSocket migration tag count.
|
|
466
410
|
*/
|
|
467
411
|
function readWranglerWebSocketTombstones(root, websockets) {
|
|
468
412
|
const configPath = projectWranglerPaths(root).find((path) => existsSync(path));
|
|
@@ -474,23 +418,15 @@ function readWranglerWebSocketTombstones(root, websockets) {
|
|
|
474
418
|
const bindings = parsed.durable_objects?.bindings;
|
|
475
419
|
return [...new Set((Array.isArray(bindings) ? bindings : []).flatMap((binding) => typeof binding.class_name === "string" && historicalClasses.has(binding.class_name) && !currentClasses.has(binding.class_name) ? [binding.class_name] : []))].sort();
|
|
476
420
|
}
|
|
477
|
-
/**
|
|
478
|
-
* Ensure a wrangler config has an explicit compatibility date.
|
|
479
|
-
* Used when `worker.compatibility_date` is configured in void.json but the
|
|
480
|
-
* active framework reads Cloudflare settings from wrangler.jsonc/json.
|
|
481
|
-
*/
|
|
421
|
+
/** Write the resolved compatibility date for frameworks that read the Wrangler config. */
|
|
482
422
|
function ensureWranglerCompatibilityDate(root, compatibilityDate) {
|
|
483
|
-
validateCompatDate(compatibilityDate, "void.json worker config");
|
|
484
423
|
const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
|
|
485
424
|
if (parsed.compatibility_date === compatibilityDate) return false;
|
|
486
425
|
parsed.compatibility_date = compatibilityDate;
|
|
487
426
|
writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
488
427
|
return true;
|
|
489
428
|
}
|
|
490
|
-
/**
|
|
491
|
-
* Ensure the `nodejs_als` compatibility flag exists in wrangler config.
|
|
492
|
-
* Returns true if the config file was modified.
|
|
493
|
-
*/
|
|
429
|
+
/** Add the `nodejs_als` compatibility flag. Returns true if the file was written. */
|
|
494
430
|
function ensureWranglerNodejsAlsFlag(root) {
|
|
495
431
|
const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
|
|
496
432
|
const compatibilityFlags = Array.isArray(parsed.compatibility_flags) ? parsed.compatibility_flags : [];
|
|
@@ -539,11 +475,8 @@ function writeManagedQueueProvenance(text, provenance) {
|
|
|
539
475
|
return `${marker}${text.includes("\r\n") ? "\r\n" : "\n"}${text}`;
|
|
540
476
|
}
|
|
541
477
|
/**
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
* Current managed consumers are included for schema-1 upgrades; the activation layer subtracts
|
|
545
|
-
* consumers still present in the desired config. Pending removals survive failed deploys so a
|
|
546
|
-
* later retry can finish cleanup without inferring ownership from queue naming conventions.
|
|
478
|
+
* Void-owned consumer queues that may need remote cleanup: current managed consumers (the
|
|
479
|
+
* caller subtracts desired ones) and pending removals, which survive failed deploys.
|
|
547
480
|
*/
|
|
548
481
|
function readWranglerManagedQueueCleanupCandidates(configPath) {
|
|
549
482
|
if (!existsSync(configPath)) return [];
|
|
@@ -567,14 +500,8 @@ function acknowledgeWranglerManagedQueueRemovals(configPath, removedQueues) {
|
|
|
567
500
|
if (finalText !== raw) writeProjectWranglerFile(configPath, finalText);
|
|
568
501
|
}
|
|
569
502
|
/**
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
* (`send_email`, `addresses`, `vars`) that have no Wrangler command.
|
|
573
|
-
*
|
|
574
|
-
* Comment-preserving: uses `jsonc-parser` `modify()` + `applyEdits()` so
|
|
575
|
-
* comments and unrelated content survive (unlike `syncWranglerBindings`, which
|
|
576
|
-
* round-trips through `JSON.stringify` and strips comments). Every edit is an
|
|
577
|
-
* idempotent upsert — running twice produces byte-identical output.
|
|
503
|
+
* Apply a {@link ProvisionedWranglerPatch} to the root Wrangler config. Edits keep comments
|
|
504
|
+
* and unrelated content, and a second run produces the same bytes.
|
|
578
505
|
*/
|
|
579
506
|
function writeProvisionedWranglerConfig(root, patch, options) {
|
|
580
507
|
const configPath = options?.configPath ?? discoverWranglerConfigPath(root);
|
|
@@ -676,7 +603,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
|
|
|
676
603
|
if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — cannot adopt ${JSON.stringify(binding)} into "${field}" because that binding name is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this would make the config undeployable. Rename the conflicting binding and retry.`);
|
|
677
604
|
if (matches.length === 1) {
|
|
678
605
|
const { index, entry: existing } = matches[0];
|
|
679
|
-
for (const [key, value] of Object.entries(properties)) if (!
|
|
606
|
+
for (const [key, value] of Object.entries(properties)) if (!isDeepStrictEqual(existing[key], value)) set([
|
|
680
607
|
field,
|
|
681
608
|
index,
|
|
682
609
|
key
|
|
@@ -753,7 +680,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
|
|
|
753
680
|
const existing = currentList[index];
|
|
754
681
|
for (const [key, value] of Object.entries(entry)) {
|
|
755
682
|
if (value === void 0) continue;
|
|
756
|
-
if (!
|
|
683
|
+
if (!isDeepStrictEqual(existing[key], value)) set([
|
|
757
684
|
"queues",
|
|
758
685
|
section,
|
|
759
686
|
index,
|
|
@@ -829,13 +756,13 @@ function writeProvisionedWranglerConfig(root, patch, options) {
|
|
|
829
756
|
for (const [key, value] of Object.entries(patch.vars)) {
|
|
830
757
|
const owner = owners.get(key);
|
|
831
758
|
if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — cannot write var ${JSON.stringify(key)} because that binding name is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this would make the config undeployable. Rename the conflicting binding and retry.`);
|
|
832
|
-
if (!
|
|
759
|
+
if (!isDeepStrictEqual(currentVars[key], value)) set(["vars", key], value);
|
|
833
760
|
}
|
|
834
761
|
}
|
|
835
762
|
if (patch.addresses !== void 0) {
|
|
836
763
|
const currentAddresses = parseJsonc(text).addresses;
|
|
837
764
|
if (patch.addresses === null) text = removeMember(text, ["addresses"], { formattingOptions });
|
|
838
|
-
else if (!
|
|
765
|
+
else if (!isDeepStrictEqual(currentAddresses, patch.addresses)) text = applyMemberEdit(text, ["addresses"], patch.addresses, { formattingOptions });
|
|
839
766
|
}
|
|
840
767
|
const droppedComment = findDroppedComment(extractCommentTokens(original), extractCommentTokens(text));
|
|
841
768
|
if (droppedComment !== void 0) {
|
|
@@ -957,12 +884,7 @@ function parseCustomDomains(value, configPath) {
|
|
|
957
884
|
}
|
|
958
885
|
return domains;
|
|
959
886
|
}
|
|
960
|
-
/**
|
|
961
|
-
* Extract the multiset of comment TOKENS (line + block) from JSONC source using
|
|
962
|
-
* jsonc-parser's scanner — exact by construction, no regex. Each token is its
|
|
963
|
-
* verbatim source slice, so a relocated comment keeps identical text (its
|
|
964
|
-
* multiset entry is unchanged) while a dropped comment removes one.
|
|
965
|
-
*/
|
|
887
|
+
/** Every line and block comment in JSONC source, verbatim, in order. */
|
|
966
888
|
function extractCommentTokens(text) {
|
|
967
889
|
const scanner = createScanner(text, false);
|
|
968
890
|
const tokens = [];
|
|
@@ -976,12 +898,7 @@ function extractCommentTokens(text) {
|
|
|
976
898
|
}
|
|
977
899
|
return tokens;
|
|
978
900
|
}
|
|
979
|
-
/**
|
|
980
|
-
* Multiset-subset check: return the first comment token present in `before` but
|
|
981
|
-
* missing (accounting for repeats) from `after`, or `undefined` when `after` is
|
|
982
|
-
* a superset of `before`. The final gate uses this to prove no comment TEXT was
|
|
983
|
-
* dropped by the edits.
|
|
984
|
-
*/
|
|
901
|
+
/** The first comment in `before` missing from `after`, counting repeats, if any. */
|
|
985
902
|
function findDroppedComment(before, after) {
|
|
986
903
|
const counts = /* @__PURE__ */ new Map();
|
|
987
904
|
for (const token of after) counts.set(token, (counts.get(token) ?? 0) + 1);
|
|
@@ -991,10 +908,7 @@ function findDroppedComment(before, after) {
|
|
|
991
908
|
counts.set(token, remaining - 1);
|
|
992
909
|
}
|
|
993
910
|
}
|
|
994
|
-
/**
|
|
995
|
-
* Detect indentation from an existing config so `jsonc-parser` formats inserted
|
|
996
|
-
* content to match. Falls back to two-space indentation (the repo default).
|
|
997
|
-
*/
|
|
911
|
+
/** Match inserted content to the file's indentation; two spaces by default. */
|
|
998
912
|
function detectFormattingOptions(text) {
|
|
999
913
|
const match = text.match(/^([ \t]+)\S/m);
|
|
1000
914
|
if (match) {
|
|
@@ -1015,27 +929,15 @@ function detectFormattingOptions(text) {
|
|
|
1015
929
|
}
|
|
1016
930
|
function parseJsonc(text) {
|
|
1017
931
|
const errors = [];
|
|
1018
|
-
const
|
|
932
|
+
const source = text.startsWith(UTF8_BOM) ? text.slice(1) : text;
|
|
933
|
+
const result = parse(source, errors, { allowTrailingComma: true });
|
|
1019
934
|
if (errors.length > 0) throw new SyntaxError("Failed to parse JSONC");
|
|
1020
935
|
return result;
|
|
1021
936
|
}
|
|
1022
937
|
/**
|
|
1023
|
-
* `modify()` + `applyEdits()
|
|
1024
|
-
*
|
|
1025
|
-
* the sibling
|
|
1026
|
-
*
|
|
1027
|
-
* jsonc-parser's formatting `modify()` reflows the whole enclosing member/entry
|
|
1028
|
-
* region and re-emits a trailing inline comment at the END of that region — so
|
|
1029
|
-
* inserting `migrations_dir` after `"database_id": "id" // production db` (or
|
|
1030
|
-
* appending a queue entry after `{ … } // jobs producer`) silently reassociates
|
|
1031
|
-
* the comment onto the NEWLY inserted member. That violates the writer's
|
|
1032
|
-
* comment-preservation contract. Here we detect that exact case, run the
|
|
1033
|
-
* (comment-free) formatting edit on a stripped copy, then splice the comment
|
|
1034
|
-
* back right after the sibling's separating comma so it stays put.
|
|
1035
|
-
*
|
|
1036
|
-
* Every other edit (value replacement, append after a comment-free sibling,
|
|
1037
|
-
* first insertion into a missing container) falls through to the plain path, so
|
|
1038
|
-
* behavior is byte-identical to before outside the trailing-comment case.
|
|
938
|
+
* `modify()` + `applyEdits()` that keeps a trailing inline comment on the sibling it
|
|
939
|
+
* documented. When a member is appended, `modify()` moves that comment after the new
|
|
940
|
+
* member, so edit a copy without it and splice it back after the sibling's comma.
|
|
1039
941
|
*/
|
|
1040
942
|
function applyMemberEdit(text, path, value, options) {
|
|
1041
943
|
const plain = () => applyEdits(text, modify(text, path, value, options));
|
|
@@ -1070,26 +972,15 @@ function applyMemberEdit(text, path, value, options) {
|
|
|
1070
972
|
} catch {
|
|
1071
973
|
return plainResult;
|
|
1072
974
|
}
|
|
1073
|
-
if (!
|
|
975
|
+
if (!isDeepStrictEqual(relocatedParsed, parseJsonc(plainResult))) return plainResult;
|
|
1074
976
|
return relocated;
|
|
1075
977
|
}
|
|
1076
978
|
/**
|
|
1077
|
-
* Remove
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1082
|
-
* trailing comment all vanish (measured on 4.x). The final comment gate would
|
|
1083
|
-
* then refuse the write for the common `"name": "app", // worker` shape. Here
|
|
1084
|
-
* the property node's exact source range is spliced out instead, plus ONE
|
|
1085
|
-
* separating comma (the following one when present, else the preceding one so
|
|
1086
|
-
* a strict `.json` file never gains a trailing comma) and the now-blank line it
|
|
1087
|
-
* sat on. Comments are never inside those ranges, so they all stay put; a
|
|
1088
|
-
* comment that was attached to the removed member is left orphaned on its line.
|
|
1089
|
-
*
|
|
1090
|
-
* Validate-before-return backstop: the spliced text must parse and equal the
|
|
1091
|
-
* plain `modify()` result's data; otherwise the plain edit is returned and the
|
|
1092
|
-
* final gate decides. An absent member is a no-op.
|
|
979
|
+
* Remove the object member at `path`, keeping every comment. `modify(…, undefined)` also
|
|
980
|
+
* deletes the comments between the previous member and this one, so splice out the
|
|
981
|
+
* property, one separating comma (the following one, else the preceding one, so strict
|
|
982
|
+
* JSON gains no trailing comma) and its blank line. Falls back to `modify()` when the
|
|
983
|
+
* result's data differs.
|
|
1093
984
|
*/
|
|
1094
985
|
function removeMember(text, path, options) {
|
|
1095
986
|
const root = parseTree(text, void 0, { allowTrailingComma: true });
|
|
@@ -1136,20 +1027,12 @@ function removeMember(text, path, options) {
|
|
|
1136
1027
|
} catch {
|
|
1137
1028
|
return plainResult;
|
|
1138
1029
|
}
|
|
1139
|
-
if (!
|
|
1030
|
+
if (!isDeepStrictEqual(splicedParsed, parseJsonc(plainResult))) return plainResult;
|
|
1140
1031
|
return spliced;
|
|
1141
1032
|
}
|
|
1142
1033
|
/**
|
|
1143
|
-
*
|
|
1144
|
-
*
|
|
1145
|
-
* separator comma may sit between the sibling's value and the comment — so both
|
|
1146
|
-
* `"id": "x" // c` and `"id": "x", // c` (a JSONC trailing comma, or the
|
|
1147
|
-
* separator once a sibling follows) are recognized. A `//` line comment or a
|
|
1148
|
-
* single-line `/* *\/` block comment counts; a newline or closing bracket first
|
|
1149
|
-
* means there is no trailing comment (returns undefined). `offset` points just
|
|
1150
|
-
* past the sibling's value, and the sibling is always its container's LAST
|
|
1151
|
-
* member, so any comma here is a trailing/separator comma — never a boundary to
|
|
1152
|
-
* an existing following member.
|
|
1034
|
+
* The `//` or single-line block comment on the same line after `offset` (just past the
|
|
1035
|
+
* last member's value), allowing one comma before it.
|
|
1153
1036
|
*/
|
|
1154
1037
|
function readTrailingComment(text, offset) {
|
|
1155
1038
|
let i = offset;
|
|
@@ -1178,12 +1061,7 @@ function readTrailingComment(text, offset) {
|
|
|
1178
1061
|
};
|
|
1179
1062
|
}
|
|
1180
1063
|
}
|
|
1181
|
-
/**
|
|
1182
|
-
* Throw (without writing) if any object in the config declares the same member
|
|
1183
|
-
* name twice. See the call site for why a duplicate makes property-level upserts
|
|
1184
|
-
* silently ineffective. Walks the jsonc AST so nested objects (queue consumers,
|
|
1185
|
-
* D1 entries, …) are covered, not just the top level.
|
|
1186
|
-
*/
|
|
1064
|
+
/** Throw if any object in the config, at any depth, declares the same key twice. */
|
|
1187
1065
|
function assertNoDuplicateMembers(text, configPath) {
|
|
1188
1066
|
const root = parseTree(text, void 0, { allowTrailingComma: true });
|
|
1189
1067
|
if (!root) return;
|
|
@@ -1205,7 +1083,7 @@ function assertNoDuplicateMembers(text, configPath) {
|
|
|
1205
1083
|
};
|
|
1206
1084
|
walk(root);
|
|
1207
1085
|
}
|
|
1208
|
-
/** 1-based line
|
|
1086
|
+
/** 1-based line and column of an offset. */
|
|
1209
1087
|
function offsetToLineColumn(text, offset) {
|
|
1210
1088
|
let line = 1;
|
|
1211
1089
|
let column = 1;
|
|
@@ -1243,19 +1121,9 @@ function validateDurableObjectMigrations(value, configPath) {
|
|
|
1243
1121
|
return value;
|
|
1244
1122
|
}
|
|
1245
1123
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1249
|
-
* name. Drives the owner name in the worker-wide producer-collision error.
|
|
1250
|
-
*
|
|
1251
|
-
* This is a 1:1 copy of wrangler's `friendlyBindingNames` EXCEPT `queues`, which
|
|
1252
|
-
* is intentionally ABSENT: wrangler folds in `queues.producers`, but here producer
|
|
1253
|
-
* identity is handled by the upsert's own binding-match logic (and consumers carry
|
|
1254
|
-
* no binding), so including it would flag the very producer we are about to append
|
|
1255
|
-
* as a self-collision. Every OTHER field wrangler enumerates is present (including
|
|
1256
|
-
* `unsafe_hello_world`). `secrets.required` — which wrangler folds in separately
|
|
1257
|
-
* under the label "Secret", not via this map — is handled in
|
|
1258
|
-
* `collectWorkerBindingNames`.
|
|
1124
|
+
* Wrangler's `friendlyBindingNames`: the fields `validateBindingsHaveUniqueNames` reads, with
|
|
1125
|
+
* their labels. `queues` is left out because the producer upsert matches its own entries;
|
|
1126
|
+
* including it would make a producer collide with itself.
|
|
1259
1127
|
*/
|
|
1260
1128
|
const FRIENDLY_BINDING_NAMES = {
|
|
1261
1129
|
data_blobs: "Data Blob",
|
|
@@ -1297,15 +1165,7 @@ const FRIENDLY_BINDING_NAMES = {
|
|
|
1297
1165
|
vpc_services: "VPC Service",
|
|
1298
1166
|
vpc_networks: "VPC Network"
|
|
1299
1167
|
};
|
|
1300
|
-
/**
|
|
1301
|
-
* Collect every binding NAME already used across the worker config, mapped to
|
|
1302
|
-
* wrangler's friendly owner label (first writer wins on ties). Mirrors the exact
|
|
1303
|
-
* name set `validateBindingsHaveUniqueNames` builds in `wrangler-dist/cli.js`:
|
|
1304
|
-
* `getBindingNames(config[field])` for every `friendlyBindingNames` field, PLUS
|
|
1305
|
-
* `config.secrets.required` under the label "Secret" — minus `queues` (see
|
|
1306
|
-
* FRIENDLY_BINDING_NAMES for why). Used to fail closed before appending a queue
|
|
1307
|
-
* producer whose binding collides with any other worker-wide binding.
|
|
1308
|
-
*/
|
|
1168
|
+
/** Every binding name in the config, mapped to its owner's label (first one wins). */
|
|
1309
1169
|
function collectWorkerBindingNames(config) {
|
|
1310
1170
|
const owners = /* @__PURE__ */ new Map();
|
|
1311
1171
|
const claim = (name, friendly) => {
|
|
@@ -1316,26 +1176,18 @@ function collectWorkerBindingNames(config) {
|
|
|
1316
1176
|
if (secrets && secrets.required !== void 0) {
|
|
1317
1177
|
if (!Array.isArray(secrets.required)) throw new Error("deploy: cannot verify binding-name uniqueness — \"secrets.required\" must be an array of secret names. Fix the wrangler config and retry.");
|
|
1318
1178
|
secrets.required.forEach((name, index) => {
|
|
1319
|
-
if (typeof name !== "string" || name.length === 0) throw
|
|
1179
|
+
if (typeof name !== "string" || name.length === 0) throw bindingSetError(`"secrets.required" contains a malformed entry at index ${index} (expected a non-empty string)`, "dropped entry");
|
|
1320
1180
|
claim(name, "Secret");
|
|
1321
1181
|
});
|
|
1322
1182
|
}
|
|
1323
1183
|
return owners;
|
|
1324
1184
|
}
|
|
1325
|
-
/** A shallow copy of `config`
|
|
1185
|
+
/** A shallow copy of `config` without `field`. */
|
|
1326
1186
|
function configWithoutField(config, field) {
|
|
1327
1187
|
const { [field]: _omit, ...rest } = config;
|
|
1328
1188
|
return rest;
|
|
1329
1189
|
}
|
|
1330
|
-
/**
|
|
1331
|
-
* Add every `queues.producers[].binding` to an existing worker-binding owner map,
|
|
1332
|
-
* under the friendly label "Queue" (first-writer-wins). The base
|
|
1333
|
-
* `collectWorkerBindingNames` deliberately OMITS queues so the producer-append
|
|
1334
|
-
* path does not flag the producer it is adding as a self-collision — but for the
|
|
1335
|
-
* ADOPT path a producer binding sharing the adopted binding IS a real cross-type
|
|
1336
|
-
* collision wrangler rejects at deploy, so the adopt guard layers producers on
|
|
1337
|
-
* top of the reused collector.
|
|
1338
|
-
*/
|
|
1190
|
+
/** Add queue producer bindings (label "Queue"), which the base collector leaves out. */
|
|
1339
1191
|
function addQueueProducerOwners(owners, config) {
|
|
1340
1192
|
const queues = assertObjectContainer(config.queues, "queues");
|
|
1341
1193
|
if (!queues || queues.producers === void 0) return;
|
|
@@ -1345,47 +1197,26 @@ function addQueueProducerOwners(owners, config) {
|
|
|
1345
1197
|
}
|
|
1346
1198
|
}
|
|
1347
1199
|
/**
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1350
|
-
* otherwise clones the list and silently skips non-record members, committing a new
|
|
1351
|
-
* producer beside a corrupt list). A non-array, or any member that is not a record with
|
|
1352
|
-
* a non-empty string `binding`, THROWS (fail closed) rather than being dropped — a
|
|
1353
|
-
* dropped/hidden producer could mask a real binding collision. Returns the validated
|
|
1354
|
-
* producer records (each guaranteed to carry a non-empty string `binding`).
|
|
1200
|
+
* Validate `queues.producers`: every member needs a non-empty string `binding`. A skipped
|
|
1201
|
+
* member could hide a binding collision, so a malformed one throws.
|
|
1355
1202
|
*/
|
|
1356
1203
|
function assertValidQueueProducers(producers) {
|
|
1357
1204
|
if (producers === void 0) return [];
|
|
1358
1205
|
if (!Array.isArray(producers)) throw new Error("deploy: cannot verify binding-name uniqueness — \"queues.producers\" must be an array. Fix the wrangler config and retry.");
|
|
1359
1206
|
return producers.map((producer, index) => {
|
|
1360
|
-
if (!isRecord(producer) || typeof producer.binding !== "string" || producer.binding.length === 0) throw
|
|
1207
|
+
if (!isRecord(producer) || typeof producer.binding !== "string" || producer.binding.length === 0) throw bindingSetError(`"queues.producers" contains a malformed entry at index ${index} (missing a non-empty string "binding")`, "dropped producer");
|
|
1361
1208
|
return producer;
|
|
1362
1209
|
});
|
|
1363
1210
|
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Validate the OUTER shape of a wrangler container field that wrangler 4.131
|
|
1366
|
-
* requires to be an OBJECT (`queues`, `secrets`). A PRESENT-but-non-object container
|
|
1367
|
-
* (array/string/number/null) is malformed for wrangler AND would bypass the binding
|
|
1368
|
-
* collectors, HIDING a real cross-type binding collision — so it THROWS (fail closed).
|
|
1369
|
-
* An ABSENT container (undefined) returns undefined (a no-op, NOT an error).
|
|
1370
|
-
* Returns the container as a record when present-and-object.
|
|
1371
|
-
*
|
|
1372
|
-
* NOTE: `null` is `typeof 'object'` but `isRecord(null)` is false, so `secrets: null` /
|
|
1373
|
-
* `queues: null` (present but null) THROWS — correct (wrangler requires an object).
|
|
1374
|
-
* Absent (`undefined`) is the only no-op.
|
|
1375
|
-
*/
|
|
1211
|
+
/** An object-valued container field (`queues`, `secrets`); any other present value throws. */
|
|
1376
1212
|
function assertObjectContainer(value, field) {
|
|
1377
1213
|
if (value === void 0) return;
|
|
1378
|
-
if (!isRecord(value)) throw
|
|
1214
|
+
if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object`, "wrong-shaped container");
|
|
1379
1215
|
return value;
|
|
1380
1216
|
}
|
|
1381
1217
|
/**
|
|
1382
|
-
* The
|
|
1383
|
-
*
|
|
1384
|
-
* looks `name` up among every OTHER binding type — `queues.producers` included — and
|
|
1385
|
-
* returns wrangler's friendly label for the owner, or `undefined` when the name is free
|
|
1386
|
-
* (or held only by `field` itself). Lets a caller refuse a doomed write BEFORE side
|
|
1387
|
-
* effects the write would otherwise follow (the Mode B email step). Reuses the ONE
|
|
1388
|
-
* collector — never fork it.
|
|
1218
|
+
* The label of another binding type that already uses `name`, or undefined when only
|
|
1219
|
+
* `field` (or nothing) does. Lets a caller refuse a write before its side effects.
|
|
1389
1220
|
*/
|
|
1390
1221
|
function findBindingNameOwner(config, field, name) {
|
|
1391
1222
|
bindingNamesForField(field, config[field]);
|
|
@@ -1394,20 +1225,9 @@ function findBindingNameOwner(config, field, name) {
|
|
|
1394
1225
|
return owners.get(name);
|
|
1395
1226
|
}
|
|
1396
1227
|
/**
|
|
1397
|
-
* The
|
|
1398
|
-
*
|
|
1399
|
-
*
|
|
1400
|
-
* silently picked among duplicates, and bypassed the worker-wide collision check, so a
|
|
1401
|
-
* duplicate/cross-type-collision config could be reported `reused` or pass a create
|
|
1402
|
-
* postcondition though it is undeployable. Fails closed on:
|
|
1403
|
-
* 1. a malformed TARGET field (reuses {@link bindingNamesForField}: a non-array outer
|
|
1404
|
-
* shape, or any member without a non-empty string `binding`, throws);
|
|
1405
|
-
* 2. MORE THAN ONE entry in the target field sharing `binding` (ambiguous identity —
|
|
1406
|
-
* wrangler also rejects duplicate binding names);
|
|
1407
|
-
* 3. a worker-wide CROSS-TYPE collision — `binding` is ALSO owned by any OTHER binding
|
|
1408
|
-
* type (reuses the {@link collectWorkerBindingNames} collector, EXCLUDING the
|
|
1409
|
-
* target field so the entry never self-collides, and INCLUDING `queues.producers`).
|
|
1410
|
-
* Returns the single matching entry, or `undefined` when the binding is absent.
|
|
1228
|
+
* The one entry in `field` (`d1_databases`, `kv_namespaces`, …) with this binding, or
|
|
1229
|
+
* undefined. Throws on a malformed field, a duplicate entry, or a name another binding
|
|
1230
|
+
* type also uses.
|
|
1411
1231
|
*/
|
|
1412
1232
|
function readProvisionedBindingEntry(config, field, binding, configPath) {
|
|
1413
1233
|
bindingNamesForField(field, config[field]);
|
|
@@ -1420,12 +1240,7 @@ function readProvisionedBindingEntry(config, field, binding, configPath) {
|
|
|
1420
1240
|
if (owner !== void 0) throw new Error(`provision: cannot read "${configPath}" — binding ${JSON.stringify(binding)} in "${field}" is also used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this config is undeployable. Rename the conflicting binding and retry.`);
|
|
1421
1241
|
return matches[0];
|
|
1422
1242
|
}
|
|
1423
|
-
/**
|
|
1424
|
-
* Explicit per-field shape metadata (see {@link BindingFieldShape}), transcribed
|
|
1425
|
-
* from wrangler 4.131's config schema. Any `FRIENDLY_BINDING_NAMES` field absent here is
|
|
1426
|
-
* a `namespace-array` (`[{ binding }]`) — the shape wrangler's `getBindingNames` reads
|
|
1427
|
-
* via its `isNamespaceList` branch.
|
|
1428
|
-
*/
|
|
1243
|
+
/** Fields that are not a `namespace-array`. */
|
|
1429
1244
|
const BINDING_FIELD_SHAPES = {
|
|
1430
1245
|
vars: { kind: "key-map" },
|
|
1431
1246
|
wasm_modules: { kind: "key-map" },
|
|
@@ -1480,32 +1295,16 @@ const BINDING_FIELD_SHAPES = {
|
|
|
1480
1295
|
}
|
|
1481
1296
|
};
|
|
1482
1297
|
/**
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1485
|
-
* any malformed/missing REQUIRED identity or wrong outer shape — never content-guessing.
|
|
1486
|
-
* wrangler is lenient and would silently drop such a member, letting the worker-wide
|
|
1487
|
-
* uniqueness guard miss (or invent) a collision.
|
|
1488
|
-
*
|
|
1489
|
-
* Exported so the deploy orchestrator's pass-through assert-set check reads a resource field's
|
|
1490
|
-
* per-entry identity keys through the SAME wrangler-schema shapes (handling `send_email` /
|
|
1491
|
-
* `ratelimits` name-keying and `logfwdr`'s nested `.bindings`, among others).
|
|
1298
|
+
* Binding names in one config field, read by the field's known shape. Throws on a wrong
|
|
1299
|
+
* shape or a missing required name, which Wrangler would drop silently.
|
|
1492
1300
|
*/
|
|
1493
1301
|
function bindingNamesForField(field, value) {
|
|
1494
1302
|
if (BINDING_FIELD_SHAPES[field]?.kind === "key-map") return keyMapBindingNames(field, value);
|
|
1495
1303
|
return bindingEntriesForField(field, value).map((entry) => entry.name);
|
|
1496
1304
|
}
|
|
1497
1305
|
/**
|
|
1498
|
-
*
|
|
1499
|
-
*
|
|
1500
|
-
* caller can compare not just WHICH bindings a field declares but the TARGET each one points
|
|
1501
|
-
* at (a `services` binding's `service`, an `unsafe` binding's `type`, …). Same fail-closed
|
|
1502
|
-
* philosophy as {@link bindingNamesForField} — a malformed/missing REQUIRED identity or wrong
|
|
1503
|
-
* outer shape THROWS. {@link bindingNamesForField} is this reader's `.name` projection for every
|
|
1504
|
-
* non-key-map field.
|
|
1505
|
-
*
|
|
1506
|
-
* Exported so the deploy orchestrator's pass-through assert-set check can pin a legitimately
|
|
1507
|
-
* hand-declared binding's ENTRY pre-build and reject a build that KEEPS the name but REWRITES
|
|
1508
|
-
* the target.
|
|
1306
|
+
* Like {@link bindingNamesForField}, but pairs each name with its config entry so a caller
|
|
1307
|
+
* can also compare what the binding points at.
|
|
1509
1308
|
*/
|
|
1510
1309
|
function bindingEntriesForField(field, value) {
|
|
1511
1310
|
const shape = BINDING_FIELD_SHAPES[field] ?? { kind: "namespace-array" };
|
|
@@ -1518,136 +1317,78 @@ function bindingEntriesForField(field, value) {
|
|
|
1518
1317
|
case "whole-object": return [];
|
|
1519
1318
|
}
|
|
1520
1319
|
}
|
|
1521
|
-
/**
|
|
1522
|
-
* Entry-shaped reader for a KEY-MAP field. Key-map fields (vars/wasm_modules/text_blobs/
|
|
1523
|
-
* data_blobs) carry no per-binding config ENTRY object — the binding name is the KEY and the
|
|
1524
|
-
* VALUE is arbitrary content — and all four are excluded from the pass-through assert-set, so
|
|
1525
|
-
* this branch is never reached in the normal flow. It THROWS the same wrong-shape message the
|
|
1526
|
-
* name reader raises, so a FUTURE misclassification that routed a key-map field here fails
|
|
1527
|
-
* CLOSED rather than silently reading no entries.
|
|
1528
|
-
*/
|
|
1320
|
+
/** Key-map fields have no entry objects; callers never route them here. */
|
|
1529
1321
|
function keyMapBindingEntries(field) {
|
|
1530
|
-
throw
|
|
1322
|
+
throw bindingSetError(`"${field}" must be an object mapping names to values`, "wrong-shaped field");
|
|
1531
1323
|
}
|
|
1532
|
-
/**
|
|
1533
|
-
* Entry-shaped reader for a NAMESPACE-array field (`[{ binding }]`: kv_namespaces, d1_databases,
|
|
1534
|
-
* r2_buckets, hyperdrive, services, vectorize, …). A PRESENT value that is not an array THROWS
|
|
1535
|
-
* rather than being re-read as a key-map (which could under-collect and hide a real collision);
|
|
1536
|
-
* every member is strictly validated for a non-empty string `.binding`.
|
|
1537
|
-
*/
|
|
1538
1324
|
function namespaceArrayBindingEntries(field, value) {
|
|
1539
1325
|
if (value === void 0) return [];
|
|
1540
|
-
if (!Array.isArray(value)) throw
|
|
1326
|
+
if (!Array.isArray(value)) throw bindingSetError(`"${field}" must be an array of binding entries`, "wrong-shaped field");
|
|
1541
1327
|
return strictBindingEntries(value, "binding", field);
|
|
1542
1328
|
}
|
|
1543
1329
|
/**
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1546
|
-
*
|
|
1547
|
-
* Identity is the `.name` ONLY. Verified against wrangler 4.131's bundle +
|
|
1548
|
-
* `config-schema.json`: NEITHER `send_email` NOR `ratelimits` has a `.binding` property in
|
|
1549
|
-
* the schema, and on UPLOAD wrangler keys them by `.name`. An optional `.binding` that happens
|
|
1550
|
-
* to sit on such an entry is NOT a binding identity wrangler recognizes, so unioning it would
|
|
1551
|
-
* invent a PHANTOM collision (e.g. `send_email:[{name:"EMAIL_A",binding:"QUEUE_JOBS"}]` would
|
|
1552
|
-
* falsely block a legitimate `QUEUE_JOBS` queue producer).
|
|
1330
|
+
* `send_email` and `ratelimits` are keyed by `.name` only. A `.binding` on such an entry is
|
|
1331
|
+
* not an identity Wrangler uses, so reading it would invent a collision.
|
|
1553
1332
|
*/
|
|
1554
1333
|
function nameKeyedBindingEntries(field, value) {
|
|
1555
1334
|
if (value === void 0) return [];
|
|
1556
|
-
if (!Array.isArray(value)) throw
|
|
1335
|
+
if (!Array.isArray(value)) throw bindingSetError(`"${field}" must be an array of binding entries`, "wrong-shaped field");
|
|
1557
1336
|
return strictBindingEntries(value, "name", field);
|
|
1558
1337
|
}
|
|
1559
|
-
/**
|
|
1560
|
-
* Entry-shaped reader for a binding-LIST field (`{ bindings: [{ name }] }`: durable_objects /
|
|
1561
|
-
* logfwdr / unsafe): the entry of each member is the member itself, keyed on `.name`. A wrong
|
|
1562
|
-
* outer shape, or a missing `bindings` when required (durable_objects / logfwdr per schema),
|
|
1563
|
-
* THROWS; a `bindings`-less `unsafe` (optional) contributes nothing.
|
|
1564
|
-
*/
|
|
1565
1338
|
function bindingListEntries(field, value, bindingsRequired) {
|
|
1566
1339
|
if (value === void 0) return [];
|
|
1567
|
-
if (!isRecord(value)) throw
|
|
1340
|
+
if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object with a "bindings" array`, "wrong-shaped field");
|
|
1568
1341
|
if (value.bindings === void 0) {
|
|
1569
|
-
if (bindingsRequired) throw
|
|
1342
|
+
if (bindingsRequired) throw bindingSetError(`"${field}" requires a "bindings" array`, "wrong-shaped field");
|
|
1570
1343
|
return [];
|
|
1571
1344
|
}
|
|
1572
|
-
if (!Array.isArray(value.bindings)) throw
|
|
1345
|
+
if (!Array.isArray(value.bindings)) throw bindingSetError(`"${field}.bindings" must be an array`, "wrong-shaped field");
|
|
1573
1346
|
return strictBindingEntries(value.bindings, "name", `${field}.bindings`);
|
|
1574
1347
|
}
|
|
1575
|
-
/**
|
|
1576
|
-
* Entry-shaped reader for a SINGLETON field (`{ binding }`: ai / browser / images / stream /
|
|
1577
|
-
* media / websearch / version_metadata / assets): the entry is the singleton value itself. A
|
|
1578
|
-
* PRESENT non-object THROWS; a present-but-malformed `binding` THROWS; a required-but-absent
|
|
1579
|
-
* `binding` THROWS (never a fall-through that would mis-collect the object's OTHER keys); a
|
|
1580
|
-
* binding-optional `assets` with no binding contributes nothing.
|
|
1581
|
-
*/
|
|
1582
1348
|
function singletonBindingEntry(field, value, bindingRequired) {
|
|
1583
1349
|
if (value === void 0) return [];
|
|
1584
|
-
if (!isRecord(value)) throw
|
|
1350
|
+
if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object with a "binding"`, "wrong-shaped field");
|
|
1585
1351
|
if (typeof value.binding === "string" && value.binding.length > 0) return [{
|
|
1586
1352
|
name: value.binding,
|
|
1587
1353
|
entry: value
|
|
1588
1354
|
}];
|
|
1589
|
-
if (value.binding !== void 0) throw
|
|
1590
|
-
if (bindingRequired) throw
|
|
1355
|
+
if (value.binding !== void 0) throw bindingSetError(`"${field}" has a malformed "binding" (expected a non-empty string)`, "dropped binding");
|
|
1356
|
+
if (bindingRequired) throw bindingSetError(`"${field}" requires a "binding" (a non-empty string)`, "dropped binding");
|
|
1591
1357
|
return [];
|
|
1592
1358
|
}
|
|
1593
|
-
/**
|
|
1594
|
-
* Read binding names from a KEY-MAP field (`vars`/`wasm_modules`/`text_blobs`/
|
|
1595
|
-
* `data_blobs`): the object's KEYS are the binding names. Reads ONLY the keys — never
|
|
1596
|
-
* the values — so a value that happens to look like a binding list (`{bindings:[…]}`)
|
|
1597
|
-
* or a singleton (`{binding:'x'}`) is NOT misread. A PRESENT value that is not a
|
|
1598
|
-
* plain object is the wrong outer shape and THROWS (fail closed). An explicitly
|
|
1599
|
-
* `undefined`-valued key is not a real binding and is skipped.
|
|
1600
|
-
*/
|
|
1359
|
+
/** The keys of a key-map field are its binding names; the values are never read. */
|
|
1601
1360
|
function keyMapBindingNames(field, value) {
|
|
1602
1361
|
if (value === void 0) return [];
|
|
1603
|
-
if (!isRecord(value)) throw
|
|
1362
|
+
if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object mapping names to values`, "wrong-shaped field");
|
|
1604
1363
|
return Object.keys(value).filter((key) => value[key] !== void 0);
|
|
1605
1364
|
}
|
|
1606
1365
|
/**
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1609
|
-
* member — never silently drops one. Dropping a malformed member could convert a mixed-validity
|
|
1610
|
-
* array (e.g. `[null, { binding: 'DB', id: '…' }]`) into an empty/partial binding set, so the
|
|
1611
|
-
* worker-wide uniqueness guard would MISS the existing `DB` and commit a conflicting binding.
|
|
1366
|
+
* Read `keyField` from every member, paired with the member. A malformed member throws:
|
|
1367
|
+
* dropping it could hide an existing binding from the uniqueness check.
|
|
1612
1368
|
*/
|
|
1613
1369
|
function strictBindingEntries(members, keyField, field) {
|
|
1614
1370
|
return members.map((member, index) => {
|
|
1615
|
-
if (!isRecord(member) || typeof member[keyField] !== "string" || member[keyField].length === 0) throw
|
|
1371
|
+
if (!isRecord(member) || typeof member[keyField] !== "string" || member[keyField].length === 0) throw bindingSetError(`"${field}" contains a malformed entry at index ${index} (missing a non-empty string "${keyField}")`, "dropped entry");
|
|
1616
1372
|
return {
|
|
1617
1373
|
name: member[keyField],
|
|
1618
1374
|
entry: member
|
|
1619
1375
|
};
|
|
1620
1376
|
});
|
|
1621
1377
|
}
|
|
1622
|
-
/**
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
*/
|
|
1378
|
+
/** A binding field that cannot be read completely; a missed name could hide a collision. */
|
|
1379
|
+
function bindingSetError(problem, hidden) {
|
|
1380
|
+
return /* @__PURE__ */ new Error(`deploy: cannot verify binding-name uniqueness — ${problem}. Refusing to proceed on a partially-readable binding set (a ${hidden} could hide a real collision). Fix the wrangler config and retry.`);
|
|
1381
|
+
}
|
|
1382
|
+
/** Wrangler's rule: the normalized pattern starts with `<dir>/`, unless the dir is ".". */
|
|
1628
1383
|
function migrationsPatternMatchesDir(pattern, dir) {
|
|
1629
1384
|
const normalizedDir = normalizeMigrationsPath(dir);
|
|
1630
1385
|
if (normalizedDir === ".") return true;
|
|
1631
1386
|
return normalizeMigrationsPath(pattern).startsWith(`${normalizedDir}/`);
|
|
1632
1387
|
}
|
|
1633
|
-
/**
|
|
1634
|
-
* Mirror wrangler's `normalizeRelativePath`: forward-slash, posix-normalize, then
|
|
1635
|
-
* drop a trailing slash. Keeps the migrations validity check byte-identical with
|
|
1636
|
-
* wrangler's own.
|
|
1637
|
-
*/
|
|
1388
|
+
/** Wrangler's `normalizeRelativePath`: forward slashes, normalized, no trailing slash. */
|
|
1638
1389
|
function normalizeMigrationsPath(p) {
|
|
1639
1390
|
const normalized = normalize(p.replace(/\\/g, "/"));
|
|
1640
1391
|
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
|
|
1641
1392
|
}
|
|
1642
|
-
/** Order-insensitive structural equality — avoids rewriting an entry that only
|
|
1643
|
-
* differs in key order (preserves the file's bytes/comments on that entry). */
|
|
1644
|
-
function jsonEqual(a, b) {
|
|
1645
|
-
return JSON.stringify(canonicalize(a)) === JSON.stringify(canonicalize(b));
|
|
1646
|
-
}
|
|
1647
|
-
function canonicalize(value) {
|
|
1648
|
-
if (Array.isArray(value)) return value.map(canonicalize);
|
|
1649
|
-
if (isRecord(value)) return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalize(value[key])]));
|
|
1650
|
-
return value;
|
|
1651
|
-
}
|
|
1652
1393
|
//#endregion
|
|
1653
1394
|
export { updateWranglerCustomDomain as A, readWranglerManagedQueueCleanupCandidates as C, syncWranglerBindings as D, resolveLiveBindingConfig as E, writeWranglerPublishedTrafficSnapshot as M, syncWranglerDurableObjects as O, readWranglerCustomDomains as S, readWranglerWebSocketTombstones as T, persistMaterializedWranglerConfig as _, LIVE_MIGRATION_TAG as a, readRootWranglerConfig as b, bindingEntriesForField as c, ensureWranglerCompatibilityDate as d, ensureWranglerNodejsAlsFlag as f, normalizeWranglerCompatibilityFlags as g, nextDurableObjectMigrationTag as h, LATEST_KNOWN_COMPAT_DATE as i, writeProvisionedWranglerConfig as j, syncWranglerWebSockets as k, bindingNamesForField as l, hasDurableObjectSqliteMigration as m, DEFAULT_LIVE_CLASS as n, acknowledgeWranglerManagedQueueRemovals as o, findBindingNameOwner as p, FRIENDLY_BINDING_NAMES as r, assertNoDuplicateMembers as s, DEFAULT_LIVE_BINDING as t, ensureWranglerCompat as u, readExistingLiveBindingConfig as v, readWranglerPublishedTrafficSnapshot as w, readWranglerCompat as x, readProvisionedBindingEntry as y };
|