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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as join, c as resolve$2, n as dirname, o as normalize, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
2
2
|
import { i as voidWarn, r as voidLog } from "./log-vqY3pqwI.mjs";
|
|
3
|
-
import { _ as persistMaterializedWranglerConfig, j as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, y as readProvisionedBindingEntry } from "./wrangler-
|
|
3
|
+
import { _ as persistMaterializedWranglerConfig, j as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, y as readProvisionedBindingEntry } from "./wrangler-C9XSzrju.mjs";
|
|
4
4
|
import { n as scanWranglerDotenvKeys } from "./dotenv-CNazY3-w.mjs";
|
|
5
|
-
import { l as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-
|
|
5
|
+
import { l as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-CZJ4viYl.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { closeSync, existsSync, fsyncSync, lstatSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, unlinkSync, writeSync } from "node:fs";
|
|
8
8
|
import { isRecord } from "@void/deploy-core";
|
|
@@ -102,9 +102,8 @@ const TRANSPORT_REDIRECT_ENV_VARS = [
|
|
|
102
102
|
"CLOUDFLARE_ENV"
|
|
103
103
|
];
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* dotenv, which wrangler reloads before writing.
|
|
105
|
+
* Session-output file variables. Provisioning keeps operation output off disk, so they are
|
|
106
|
+
* scrubbed from the child env and rejected in project dotenv. Secrets travel over stdin.
|
|
108
107
|
*/
|
|
109
108
|
const OUTPUT_FILE_ENV_VARS = ["WRANGLER_OUTPUT_FILE_PATH", "WRANGLER_OUTPUT_FILE_DIRECTORY"];
|
|
110
109
|
/**
|
|
@@ -140,7 +139,7 @@ function resolveComplianceRegion(env, configRegion) {
|
|
|
140
139
|
if (envRegion !== void 0 && configRegion !== void 0 && envRegion !== configRegion) throw new Error(`provision: the Cloudflare compliance region is set to conflicting values — the CLOUDFLARE_COMPLIANCE_REGION environment variable is ${JSON.stringify(envRegion)} but the wrangler config "compliance_region" is ${JSON.stringify(configRegion)}. wrangler refuses to run with a mismatched compliance region; reconcile them (remove one, or set them equal) and retry.`);
|
|
141
140
|
return envRegion ?? configRegion ?? "public";
|
|
142
141
|
}
|
|
143
|
-
/**
|
|
142
|
+
/** Project dotenv files the fence scans for `env`; provisioning selects no named env (`''`). */
|
|
144
143
|
function defaultWranglerEnvFiles(env) {
|
|
145
144
|
return [
|
|
146
145
|
".env",
|
|
@@ -151,8 +150,8 @@ function defaultWranglerEnvFiles(env) {
|
|
|
151
150
|
}
|
|
152
151
|
/**
|
|
153
152
|
* Fail when a project dotenv file sets a transport-redirect or session-output variable.
|
|
154
|
-
*
|
|
155
|
-
* away from the pinned base. Values exported in the shell are honored instead.
|
|
153
|
+
* Cloudflare tooling reads these files from the project, which would move its authenticated
|
|
154
|
+
* transport away from the pinned base. Values exported in the shell are honored instead.
|
|
156
155
|
*/
|
|
157
156
|
function assertNoTransportRedirectInProjectDotenv(root, platform = process.platform) {
|
|
158
157
|
const dotenvCaseInsensitive = platform === "win32";
|
|
@@ -169,9 +168,9 @@ function assertNoTransportRedirectInProjectDotenv(root, platform = process.platf
|
|
|
169
168
|
const lowerKeys = caseInsensitive ? new Set([...keys].map((key) => key.toLowerCase())) : void 0;
|
|
170
169
|
const declares = (name) => lowerKeys !== void 0 ? lowerKeys.has(name.toLowerCase()) : keys.has(name);
|
|
171
170
|
const offenders = TRANSPORT_REDIRECT_ENV_VARS.filter(declares);
|
|
172
|
-
if (offenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${offenders.join(", ")}, which
|
|
171
|
+
if (offenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${offenders.join(", ")}, which Cloudflare tooling reads from project files and would redirect its authenticated Cloudflare API transport (and credentials) to a different endpoint/account than this provision is pinned to (the Hyperdrive existence check would then run against a DIFFERENT endpoint, risking cross-environment writes or duplicate resources). Remove ${offenders.join(", ")} from "${file}" and, if you truly need a non-default endpoint, export it in your shell/CI environment instead — that pin IS honored for both the Cloudflare operations and the existence check.`);
|
|
173
172
|
const outputOffenders = OUTPUT_FILE_ENV_VARS.filter(declares);
|
|
174
|
-
if (outputOffenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${outputOffenders.join(", ")}
|
|
173
|
+
if (outputOffenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${outputOffenders.join(", ")}. Void does not allow Cloudflare session output files during provisioning. Remove ${outputOffenders.join(", ")} from "${file}".`);
|
|
175
174
|
}
|
|
176
175
|
}
|
|
177
176
|
/**
|
|
@@ -245,7 +244,7 @@ var WranglerQuarantineError = class extends Error {
|
|
|
245
244
|
pid;
|
|
246
245
|
constructor(pid, detail) {
|
|
247
246
|
const pidLabel = pid !== void 0 ? ` (pid ${pid})` : "";
|
|
248
|
-
super(`provision: the spawned
|
|
247
|
+
super(`provision: the spawned Cloudflare operation process could not be confirmed terminated${pidLabel} — ${detail}. It may still be running and creating resources, so the cross-process provision lock is intentionally RETAINED (not released) and its owner is recorded in a quarantine sidecar ("<Cloudflare config>.void-provision.lock.quarantine.json") that blocks concurrent provisions. Recovery: verify the process${pidLabel} is dead (e.g. \`kill -0 <pid>\`; terminate it if not) — the NEXT provision then confirms the recorded group is gone and clears the quarantine automatically. To clear it manually instead, remove the sidecar and the "<Cloudflare config>.void-provision.lock.lock" directory, then re-run.`);
|
|
249
248
|
this.name = "WranglerQuarantineError";
|
|
250
249
|
this.pid = pid;
|
|
251
250
|
}
|
|
@@ -253,7 +252,7 @@ var WranglerQuarantineError = class extends Error {
|
|
|
253
252
|
let activeProvisionSlot;
|
|
254
253
|
function acquireProcessProvisionSlot() {
|
|
255
254
|
if (activeProvisionSlot !== void 0) throw new Error("provision: a provision is already active in this process — run provisions sequentially. provisionCloudflareResources supports at most one concurrent provision per process; concurrent provisions across PROCESSES are serialized by the on-disk provision lock instead.");
|
|
256
|
-
if (retentionWatchdog !== void 0) throw new Error(`provision: a previous provision in this process is still retaining its lock — an unconfirmed
|
|
255
|
+
if (retentionWatchdog !== void 0) throw new Error(`provision: a previous provision in this process is still retaining its lock — an unconfirmed Cloudflare operation process${retentionWatchdog.info.pid !== void 0 ? ` (pid ${retentionWatchdog.info.pid})` : ""} could not be quarantined durably yet. No new provision may start until that retention resolves (the child is confirmed dead, or the quarantine metadata persists durably).`);
|
|
257
256
|
const token = Symbol("void-provision-slot");
|
|
258
257
|
activeProvisionSlot = token;
|
|
259
258
|
return () => {
|
|
@@ -307,7 +306,7 @@ function deregisterRunner(registrant) {
|
|
|
307
306
|
function coordinatorHandleSignal(signal) {
|
|
308
307
|
if (activeTeardown !== void 0) return;
|
|
309
308
|
if (retentionWatchdog !== void 0 && activeRegistrations.size === 0) {
|
|
310
|
-
process.stderr.write(`provision: ignoring ${signal} — a provision lock is retained while an unconfirmed
|
|
309
|
+
process.stderr.write(`provision: ignoring ${signal} — a provision lock is retained while an unconfirmed Cloudflare operation process may live and its quarantine metadata is not yet durable. The process exits once the child is confirmed dead or the metadata persists.\n`);
|
|
311
310
|
return;
|
|
312
311
|
}
|
|
313
312
|
const teardown = {
|
|
@@ -350,14 +349,14 @@ function coordinatorTearDownRegistrant(teardown, registration) {
|
|
|
350
349
|
if (lockQuarantine !== void 0) try {
|
|
351
350
|
lockQuarantine({
|
|
352
351
|
pid: registrant.pid(),
|
|
353
|
-
reason: `the spawned
|
|
352
|
+
reason: `the spawned Cloudflare operation process could not be confirmed terminated after a forwarded ${teardown.signal} — ${detail}`
|
|
354
353
|
});
|
|
355
354
|
} catch (failure) {
|
|
356
355
|
teardown.persistFailed = true;
|
|
357
356
|
process.stderr.write(`provision: ${failure.message}\n`);
|
|
358
357
|
}
|
|
359
358
|
const pid = registrant.pid();
|
|
360
|
-
process.stderr.write(`provision: warning — the
|
|
359
|
+
process.stderr.write(`provision: warning — the Cloudflare operation process group${typeof pid === "number" ? ` (pid ${pid})` : ""} could not be confirmed terminated after ${teardown.signal} (${detail}). It may still be running; the provision lock is retained (quarantined) — verify the process is dead before re-running provision.\n`);
|
|
361
360
|
registrant.quarantine(detail);
|
|
362
361
|
complete();
|
|
363
362
|
};
|
|
@@ -381,7 +380,7 @@ function finishCoordinatorTeardown(teardown) {
|
|
|
381
380
|
if (teardown.persistFailed || retentionWatchdog !== void 0) {
|
|
382
381
|
activeTeardown = void 0;
|
|
383
382
|
installCoordinatorListeners();
|
|
384
|
-
process.stderr.write(`provision: NOT re-raising ${teardown.signal} — a provision lock's quarantine metadata could not be persisted, so the lock is intentionally still held by this process to keep it from being stolen while the unconfirmed
|
|
383
|
+
process.stderr.write(`provision: NOT re-raising ${teardown.signal} — a provision lock's quarantine metadata could not be persisted, so the lock is intentionally still held by this process to keep it from being stolen while the unconfirmed Cloudflare operation process may live.\n`);
|
|
385
384
|
return;
|
|
386
385
|
}
|
|
387
386
|
if (reRaisedOnce) return;
|
|
@@ -403,7 +402,7 @@ function retainQuarantinedLock(lock, info) {
|
|
|
403
402
|
}
|
|
404
403
|
function armRetentionWatchdog(lock, info) {
|
|
405
404
|
if (retentionWatchdog !== void 0) return;
|
|
406
|
-
process.stderr.write(`provision: warning — quarantine metadata for the unconfirmed
|
|
405
|
+
process.stderr.write(`provision: warning — quarantine metadata for the unconfirmed Cloudflare operation process${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} could not be persisted, so the provision lock "${lock.lockTargetPath}.lock" is RETAINED by this process, which stays alive until the child is confirmed dead or the metadata persists durably.\n`);
|
|
407
406
|
installCoordinatorListeners();
|
|
408
407
|
let attempt = 0;
|
|
409
408
|
const resolveWatchdog = () => {
|
|
@@ -456,12 +455,13 @@ function createDefaultRunWrangler(root, options) {
|
|
|
456
455
|
const teardownDeadlineMs = options?.signalTeardownDeadlineMs ?? confirmGraceMs + SIGNAL_TEARDOWN_DEADLINE_MARGIN_MS;
|
|
457
456
|
return (args, opts) => new Promise((resolvePromise, rejectPromise) => {
|
|
458
457
|
const parallelWorkerUpload = options?.parallelWorkerUpload === true && args.type === "versions.upload";
|
|
458
|
+
const interactive = (args.type === "versions.upload" || args.type === "worker.deploy") && args.interactive === true;
|
|
459
459
|
if (activeTeardown !== void 0) {
|
|
460
|
-
rejectPromise(/* @__PURE__ */ new Error(`provision: refusing to spawn
|
|
460
|
+
rejectPromise(/* @__PURE__ */ new Error(`provision: refusing to spawn a Cloudflare operation process — a fatal ${activeTeardown.signal} is being handled and this process is terminating; no new Cloudflare operation may start.`));
|
|
461
461
|
return;
|
|
462
462
|
}
|
|
463
463
|
if (!canRegisterRunner(parallelWorkerUpload)) {
|
|
464
|
-
rejectPromise(/* @__PURE__ */ new Error("provision: refusing to spawn
|
|
464
|
+
rejectPromise(/* @__PURE__ */ new Error("provision: refusing to spawn a Cloudflare operation process — another one is already active in this process (only two immutable Worker uploads may overlap; all other Cloudflare commands and provisions remain sequential)."));
|
|
465
465
|
return;
|
|
466
466
|
}
|
|
467
467
|
const child = spawn(command, [...prefix, ...encodeCloudflareOperation(args)], {
|
|
@@ -475,7 +475,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
475
475
|
}),
|
|
476
476
|
...opts.suppressLogs ? { WRANGLER_WRITE_LOGS: "false" } : {}
|
|
477
477
|
},
|
|
478
|
-
stdio: [
|
|
478
|
+
stdio: interactive ? "inherit" : [
|
|
479
479
|
opts.input === void 0 ? "ignore" : "pipe",
|
|
480
480
|
"pipe",
|
|
481
481
|
"pipe"
|
|
@@ -548,7 +548,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
548
548
|
};
|
|
549
549
|
const timeoutStderr = (extra) => [
|
|
550
550
|
stderr,
|
|
551
|
-
`provision:
|
|
551
|
+
`provision: the Cloudflare operation process exceeded the ${timeoutMs}ms command timeout`,
|
|
552
552
|
extra
|
|
553
553
|
].filter(Boolean).join("\n");
|
|
554
554
|
const deregisterSelf = () => deregisterRunner(registrant);
|
|
@@ -557,7 +557,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
557
557
|
settled = true;
|
|
558
558
|
clearTimeout(commandTimer);
|
|
559
559
|
deregisterSelf();
|
|
560
|
-
resolvePromise(decodeCloudflareOperationResult(result));
|
|
560
|
+
resolvePromise(interactive ? result : decodeCloudflareOperationResult(result));
|
|
561
561
|
};
|
|
562
562
|
const quarantine = (detail) => {
|
|
563
563
|
if (settled) return;
|
|
@@ -652,7 +652,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
652
652
|
if (outcome === "gone") groupGone = true;
|
|
653
653
|
confirmThenSettle(() => normalizeRunWranglerResult({
|
|
654
654
|
stdout,
|
|
655
|
-
stderr: [stderr, `provision: the spawned
|
|
655
|
+
stderr: [stderr, `provision: the spawned Cloudflare operation process emitted an error after spawn: ${error.message}`].filter(Boolean).join("\n"),
|
|
656
656
|
status: null,
|
|
657
657
|
signal: "SIGKILL"
|
|
658
658
|
}), `a post-spawn child error (${error.message}; the group was SIGKILLed)`);
|
|
@@ -697,8 +697,8 @@ function createDefaultRunWrangler(root, options) {
|
|
|
697
697
|
function normalizeRunWranglerResult(result) {
|
|
698
698
|
const stdout = result.stdout ?? "";
|
|
699
699
|
const notes = [];
|
|
700
|
-
if (result.signal != null) notes.push(`provision:
|
|
701
|
-
if (result.error != null) notes.push(`provision:
|
|
700
|
+
if (result.signal != null) notes.push(`provision: the Cloudflare operation process was terminated by signal ${result.signal}`);
|
|
701
|
+
if (result.error != null) notes.push(`provision: the Cloudflare operation process could not be spawned: ${result.error.message}`);
|
|
702
702
|
const status = typeof result.status !== "number" || result.signal != null || result.error != null ? typeof result.status === "number" && result.status !== 0 ? result.status : 1 : result.status;
|
|
703
703
|
const baseStderr = result.stderr ?? "";
|
|
704
704
|
return {
|
|
@@ -903,7 +903,7 @@ function assertQuarantineClearedOrClear(lockTarget, onBeforeClear) {
|
|
|
903
903
|
}
|
|
904
904
|
if (!confirmedDead) {
|
|
905
905
|
const who = pid !== void 0 || pgid !== void 0 ? `process group ${String(pgid ?? pid)}` : "an unrecorded process";
|
|
906
|
-
throw new Error(`provision: refusing to provision — a previous provision QUARANTINED this config's lock because a spawned
|
|
906
|
+
throw new Error(`provision: refusing to provision — a previous provision QUARANTINED this config's lock because a spawned Cloudflare operation process could not be confirmed terminated (${who}${quarantinedAt ? `, quarantined at ${quarantinedAt}` : ""}${reason ? `; reason: ${reason}` : ""}). It may still be creating resources. Verify the process is dead (e.g. \`kill -0 ${String(pid ?? "<pid>")}\`; terminate it if not) and re-run — the quarantine then clears automatically. If you are CERTAIN the recorded process is unrelated (pid reuse) or gone, remove "${sidecarPath}" and the "${lockTarget}.lock" directory manually, then retry.`);
|
|
907
907
|
}
|
|
908
908
|
const inspectedGeneration = typeof recorded?.generation === "string" ? recorded.generation : void 0;
|
|
909
909
|
onBeforeClear?.();
|
|
@@ -1090,7 +1090,7 @@ async function acquireProvisionLock(configPath, lockOptions) {
|
|
|
1090
1090
|
try {
|
|
1091
1091
|
writeQuarantineSidecar(quarantineSidecarPath(lockTarget), info, lockOptions?.dirDurability);
|
|
1092
1092
|
} catch (error) {
|
|
1093
|
-
throw new Error(`provision: could not persist quarantine metadata to "${quarantineSidecarPath(lockTarget)}" (${error.message}). The cross-process provision lock "${lockTarget}.lock" is intentionally STILL HELD by this process (tracked, heartbeat running) so it cannot go stale and be stolen while the unconfirmed
|
|
1093
|
+
throw new Error(`provision: could not persist quarantine metadata to "${quarantineSidecarPath(lockTarget)}" (${error.message}). The cross-process provision lock "${lockTarget}.lock" is intentionally STILL HELD by this process (tracked, heartbeat running) so it cannot go stale and be stolen while the unconfirmed Cloudflare operation process${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} may still be running. Manual recovery: verify the process is dead${info.pid !== void 0 ? ` (e.g. \`kill -0 ${info.pid}\`)` : ""} and terminate it if not; the lock is freed when this process exits — remove the "${lockTarget}.lock" directory if it persists, then re-run.`);
|
|
1094
1094
|
}
|
|
1095
1095
|
releasePromise = Promise.resolve();
|
|
1096
1096
|
const locks = loadProperLockfileInternals()?.getLocks?.();
|
|
@@ -1125,7 +1125,7 @@ function readRootConfig(configPath) {
|
|
|
1125
1125
|
}
|
|
1126
1126
|
/** Throw unless a discovery call exited cleanly, so a failed list never means "absent". */
|
|
1127
1127
|
function assertDiscoverySucceeded(result, label) {
|
|
1128
|
-
if (!isCleanSuccess(result)) throw new Error(`provision:
|
|
1128
|
+
if (!isCleanSuccess(result)) throw new Error(`provision: ${label} failed (exit ${String(result.status)}): ${result.stderr || result.stdout || "no output"}. Cannot verify existing resources; refusing to create a possible duplicate.`);
|
|
1129
1129
|
}
|
|
1130
1130
|
/**
|
|
1131
1131
|
* Reject the whole list if any member lacks a non-empty name or a valid id. A malformed member
|
|
@@ -1134,12 +1134,12 @@ function assertDiscoverySucceeded(result, label) {
|
|
|
1134
1134
|
function validateResourceList(list, spec) {
|
|
1135
1135
|
const validated = [];
|
|
1136
1136
|
for (const member of list) {
|
|
1137
|
-
if (!isRecord(member)) throw new Error(`provision:
|
|
1137
|
+
if (!isRecord(member)) throw new Error(`provision: ${spec.command} returned a malformed ${spec.resource} entry (not an object). Cannot verify existing resources; refusing to create a possible duplicate.`);
|
|
1138
1138
|
const rawName = member[spec.nameField];
|
|
1139
1139
|
const nameValid = typeof rawName === "string" && rawName.length > 0;
|
|
1140
1140
|
const idValid = spec.hasValidId(member);
|
|
1141
|
-
if (nameValid && !idValid) throw new Error(`provision:
|
|
1142
|
-
if (!nameValid) throw new Error(`provision:
|
|
1141
|
+
if (nameValid && !idValid) throw new Error(`provision: ${spec.command} returned a ${spec.resource} ${spec.nameLabel} ${JSON.stringify(rawName)} with no valid id (${spec.idRule}). Cannot verify existing resources; refusing to create a possible duplicate.`);
|
|
1142
|
+
if (!nameValid) throw new Error(`provision: ${spec.command} returned a malformed ${spec.resource} entry with no valid ${spec.nameField}. Cannot verify existing resources; refusing to create a possible duplicate.`);
|
|
1143
1143
|
validated.push(member);
|
|
1144
1144
|
}
|
|
1145
1145
|
return validated;
|
|
@@ -1200,13 +1200,13 @@ function assertD1MigrationsDirApplied(result, binding, configPath) {
|
|
|
1200
1200
|
}
|
|
1201
1201
|
/**
|
|
1202
1202
|
* After a create reports success, re-read the config and require a real id, plus the exact
|
|
1203
|
-
* name where the name is the identity. A
|
|
1203
|
+
* name where the name is the identity. A success status alone is not trusted.
|
|
1204
1204
|
*/
|
|
1205
1205
|
function assertCreateWroteRealId(configPath, spec, binding, name) {
|
|
1206
1206
|
const entry = readBindingEntry(configPath, spec.field, binding);
|
|
1207
1207
|
const idOk = !!entry && spec.idValidator(entry[spec.idField]);
|
|
1208
1208
|
const nameOk = spec.nameField === void 0 || !!entry && entry[spec.nameField] === name;
|
|
1209
|
-
if (!idOk || !nameOk) throw new Error(`provision:
|
|
1209
|
+
if (!idOk || !nameOk) throw new Error(`provision: ${spec.command} ${name} reported success but "${configPath}" does not hold the expected ${spec.resource} for binding ${JSON.stringify(binding)} afterward (need a real ${spec.idField}${spec.nameField ? ` and ${spec.nameField} === ${JSON.stringify(name)}` : ""}). The create may have been interrupted or written a different resource. Refusing to record a wrong/unprovisioned resource; inspect the account/config and retry.`);
|
|
1210
1210
|
}
|
|
1211
1211
|
/** True when `value` contains an ASCII control character (0x00–0x1F or 0x7F). */
|
|
1212
1212
|
function hasControlChar(value) {
|
|
@@ -1216,9 +1216,9 @@ function hasControlChar(value) {
|
|
|
1216
1216
|
}
|
|
1217
1217
|
return false;
|
|
1218
1218
|
}
|
|
1219
|
-
/** The universal option-injection guard for ANY
|
|
1219
|
+
/** The universal option-injection guard for ANY Cloudflare operation ARGV positional. */
|
|
1220
1220
|
function assertNoOptionInjection(kind, name) {
|
|
1221
|
-
if (typeof name !== "string" || name.length === 0 || name.startsWith("-") || hasControlChar(name)) throw new Error(`provision: refusing to pass an unsafe ${kind} name ${JSON.stringify(name)} to
|
|
1221
|
+
if (typeof name !== "string" || name.length === 0 || name.startsWith("-") || hasControlChar(name)) throw new Error(`provision: refusing to pass an unsafe ${kind} name ${JSON.stringify(name)} to a Cloudflare operation. A name may not be empty, begin with "-" (it would be parsed as a CLI flag), or contain control characters. Rename the resource and retry.`);
|
|
1222
1222
|
}
|
|
1223
1223
|
/** Per-resource Cloudflare naming grammar. KV titles may contain spaces and mixed case. */
|
|
1224
1224
|
const RESOURCE_NAME_GRAMMARS = {
|
|
@@ -1252,7 +1252,7 @@ const RESOURCE_NAME_GRAMMARS = {
|
|
|
1252
1252
|
function assertValidResourceName(kind, name) {
|
|
1253
1253
|
assertNoOptionInjection(RESOURCE_NAME_GRAMMARS[kind].label, name);
|
|
1254
1254
|
const grammar = RESOURCE_NAME_GRAMMARS[kind];
|
|
1255
|
-
if (!grammar.re.test(name)) throw new Error(`provision: refusing to pass an invalid ${grammar.label} name ${JSON.stringify(name)} to
|
|
1255
|
+
if (!grammar.re.test(name)) throw new Error(`provision: refusing to pass an invalid ${grammar.label} name ${JSON.stringify(name)} to a Cloudflare operation. A ${grammar.label} name must ${grammar.rule}. Rename the resource and retry.`);
|
|
1256
1256
|
}
|
|
1257
1257
|
/** Redactor that replaces the exact connection string and masks any URL userinfo password. */
|
|
1258
1258
|
function createSecretRedactor(connectionString) {
|
|
@@ -1306,7 +1306,7 @@ async function provisionWithProcessSlot(root, rootWranglerPath, desired, opts) {
|
|
|
1306
1306
|
reason: typeof bodyError.message === "string" ? bodyError.message : String(bodyError)
|
|
1307
1307
|
});
|
|
1308
1308
|
} catch (quarantineError) {
|
|
1309
|
-
throw new AggregateError([bodyError, quarantineError], `provision failed with an unconfirmed
|
|
1309
|
+
throw new AggregateError([bodyError, quarantineError], `provision failed with an unconfirmed Cloudflare operation process AND its quarantine metadata could not be persisted — the cross-process provision lock is intentionally still held by this process (not released, not stealable) while the child may live. Primary error: ${bodyError instanceof Error ? bodyError.message : String(bodyError)}; quarantine error: ${quarantineError instanceof Error ? quarantineError.message : String(quarantineError)}.`, { cause: bodyError });
|
|
1310
1310
|
}
|
|
1311
1311
|
throw bodyError;
|
|
1312
1312
|
}
|
|
@@ -1359,19 +1359,19 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1359
1359
|
type: "d1.list",
|
|
1360
1360
|
configPath
|
|
1361
1361
|
}, {});
|
|
1362
|
-
assertDiscoverySucceeded(listResult, "
|
|
1362
|
+
assertDiscoverySucceeded(listResult, "Cloudflare d1 list");
|
|
1363
1363
|
const rawList = listResult.data;
|
|
1364
|
-
if (!Array.isArray(rawList)) throw new Error(`provision:
|
|
1364
|
+
if (!Array.isArray(rawList)) throw new Error(`provision: Cloudflare d1 list did not return a JSON array; cannot verify whether D1 database ${JSON.stringify(name)} exists. Refusing to create a possible duplicate.`);
|
|
1365
1365
|
const claimants = validateResourceList(rawList, {
|
|
1366
1366
|
resource: "D1 database",
|
|
1367
|
-
command: "
|
|
1367
|
+
command: "Cloudflare d1 list",
|
|
1368
1368
|
hasValidId: (member) => reconcileD1IdAliases(member).kind === "id",
|
|
1369
1369
|
idRule: "its uuid/database_id aliases must be present, well-formed D1 UUIDs agreeing on one id",
|
|
1370
1370
|
nameField: "name",
|
|
1371
1371
|
nameLabel: "named"
|
|
1372
1372
|
}).map((db) => normalizeD1(db, name)).filter((m) => m.kind !== "other");
|
|
1373
|
-
if (claimants.length > 1) throw new Error(`provision:
|
|
1374
|
-
if (claimants.length === 1 && claimants[0].kind === "claimed-but-invalid") throw new Error(`provision:
|
|
1373
|
+
if (claimants.length > 1) throw new Error(`provision: Cloudflare d1 list returned ${claimants.length} D1 databases named ${JSON.stringify(name)}. D1 database names are account-unique, so this is ambiguous; cannot pick one to adopt and refusing to create a possible duplicate. Inspect the account and retry.`);
|
|
1374
|
+
if (claimants.length === 1 && claimants[0].kind === "claimed-but-invalid") throw new Error(`provision: Cloudflare d1 list returned a D1 database named ${JSON.stringify(name)} with an ambiguous or empty id (conflicting/blank uuid/database_id, or conflicting name aliases). Cannot adopt it, and refusing to create a possible duplicate; inspect the account and retry.`);
|
|
1375
1375
|
const existing = claimants.length === 1 && claimants[0].kind === "match" ? claimants[0] : void 0;
|
|
1376
1376
|
if (existing) {
|
|
1377
1377
|
log.info(`adopted existing D1 database ${name} (${existing.id})`);
|
|
@@ -1407,7 +1407,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1407
1407
|
idValidator: isRealD1Id,
|
|
1408
1408
|
nameField: "database_name",
|
|
1409
1409
|
resource: "D1 database",
|
|
1410
|
-
command: "
|
|
1410
|
+
command: "Cloudflare d1 create"
|
|
1411
1411
|
}, binding, name);
|
|
1412
1412
|
persistCreatedConfig();
|
|
1413
1413
|
assertD1MigrationsDirApplied(write({ d1MigrationsDir: {
|
|
@@ -1426,9 +1426,9 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1426
1426
|
name,
|
|
1427
1427
|
configPath
|
|
1428
1428
|
}, {});
|
|
1429
|
-
assertDiscoverySucceeded(infoResult, `
|
|
1429
|
+
assertDiscoverySucceeded(infoResult, `Cloudflare d1 info ${name}`);
|
|
1430
1430
|
const info = normalizeD1(isRecord(infoResult.data) ? infoResult.data : void 0, name);
|
|
1431
|
-
if (info.kind !== "match") throw new Error(`provision:
|
|
1431
|
+
if (info.kind !== "match") throw new Error(`provision: Cloudflare d1 create ${name} reported the database already exists, but Cloudflare d1 info ${name} did not return a database with a matching name and an unambiguous id. Refusing to adopt an unverified database.`);
|
|
1432
1432
|
log.info(`adopted existing D1 database ${name} (${info.id})`);
|
|
1433
1433
|
assertD1MigrationsDirApplied(write({
|
|
1434
1434
|
d1: {
|
|
@@ -1448,7 +1448,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1448
1448
|
action: "adopted",
|
|
1449
1449
|
id: info.id
|
|
1450
1450
|
});
|
|
1451
|
-
} else throw new Error(`provision:
|
|
1451
|
+
} else throw new Error(`provision: Cloudflare d1 create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1452
1452
|
}
|
|
1453
1453
|
}
|
|
1454
1454
|
const databaseId = readBindingEntry(configPath, "d1_databases", binding)?.database_id;
|
|
@@ -1491,12 +1491,12 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
|
|
|
1491
1491
|
type: "kv.namespace.list",
|
|
1492
1492
|
configPath
|
|
1493
1493
|
}, {});
|
|
1494
|
-
assertDiscoverySucceeded(listResult, "
|
|
1494
|
+
assertDiscoverySucceeded(listResult, "Cloudflare kv namespace list");
|
|
1495
1495
|
const rawList = listResult.data;
|
|
1496
|
-
if (!Array.isArray(rawList)) throw new Error(`provision:
|
|
1496
|
+
if (!Array.isArray(rawList)) throw new Error(`provision: Cloudflare kv namespace list did not return a JSON array; cannot verify whether KV namespace ${JSON.stringify(title)} exists. Refusing to create a possible duplicate.`);
|
|
1497
1497
|
const matches = validateResourceList(rawList, {
|
|
1498
1498
|
resource: "KV namespace",
|
|
1499
|
-
command: "
|
|
1499
|
+
command: "Cloudflare kv namespace list",
|
|
1500
1500
|
hasValidId: (member) => isRealKvId(member.id),
|
|
1501
1501
|
idRule: "its id is missing or not a well-formed 32-hex namespace id",
|
|
1502
1502
|
nameField: "title",
|
|
@@ -1524,13 +1524,13 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
|
|
|
1524
1524
|
binding,
|
|
1525
1525
|
configPath
|
|
1526
1526
|
});
|
|
1527
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1527
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare kv namespace create ${title} failed: ${created.stderr || created.stdout}`);
|
|
1528
1528
|
assertCreateWroteRealId(configPath, {
|
|
1529
1529
|
field: "kv_namespaces",
|
|
1530
1530
|
idField: "id",
|
|
1531
1531
|
idValidator: isRealKvId,
|
|
1532
1532
|
resource: "KV namespace",
|
|
1533
|
-
command: "
|
|
1533
|
+
command: "Cloudflare kv namespace create"
|
|
1534
1534
|
}, binding, title);
|
|
1535
1535
|
persistCreatedConfig();
|
|
1536
1536
|
resources.push({
|
|
@@ -1563,7 +1563,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1563
1563
|
}, {});
|
|
1564
1564
|
if (isCleanSuccess(info)) {
|
|
1565
1565
|
const payload = info.data;
|
|
1566
|
-
if (!isRecord(payload) || payload.name !== bucketName) throw new Error(`provision:
|
|
1566
|
+
if (!isRecord(payload) || payload.name !== bucketName) throw new Error(`provision: Cloudflare r2 bucket info ${bucketName} exited 0 but did not identify the requested bucket (expected name ${JSON.stringify(bucketName)}). Refusing to adopt an unverified bucket. Output: ${info.stdout || info.stderr}`);
|
|
1567
1567
|
log.info(`adopted existing R2 bucket ${bucketName}`);
|
|
1568
1568
|
write({ r2: {
|
|
1569
1569
|
binding,
|
|
@@ -1582,14 +1582,14 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1582
1582
|
binding,
|
|
1583
1583
|
configPath
|
|
1584
1584
|
});
|
|
1585
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1585
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare r2 bucket create ${bucketName} failed: ${created.stderr || created.stdout}`);
|
|
1586
1586
|
assertCreateWroteRealId(configPath, {
|
|
1587
1587
|
field: "r2_buckets",
|
|
1588
1588
|
idField: "bucket_name",
|
|
1589
1589
|
idValidator: isValidR2BucketNameFormat,
|
|
1590
1590
|
nameField: "bucket_name",
|
|
1591
1591
|
resource: "R2 bucket",
|
|
1592
|
-
command: "
|
|
1592
|
+
command: "Cloudflare r2 bucket create"
|
|
1593
1593
|
}, binding, bucketName);
|
|
1594
1594
|
if (bucketName === R2_BUCKET_NAME_PLACEHOLDER) {
|
|
1595
1595
|
const verify = await runWrangler({
|
|
@@ -1597,7 +1597,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1597
1597
|
name: bucketName,
|
|
1598
1598
|
configPath
|
|
1599
1599
|
}, {});
|
|
1600
|
-
if (!isCleanSuccess(verify) || !isRecord(verify.data) || verify.data.name !== bucketName) throw new Error(`provision:
|
|
1600
|
+
if (!isCleanSuccess(verify) || !isRecord(verify.data) || verify.data.name !== bucketName) throw new Error(`provision: Cloudflare r2 bucket create ${bucketName} reported success but a follow-up Cloudflare r2 bucket info ${bucketName} did not confirm the bucket exists. The create may have been interrupted, and the config entry is indistinguishable from the local-dev placeholder for this name. Refusing to record an unprovisioned bucket; inspect the account and retry.`);
|
|
1601
1601
|
}
|
|
1602
1602
|
persistCreatedConfig();
|
|
1603
1603
|
resources.push({
|
|
@@ -1606,7 +1606,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1606
1606
|
name: bucketName,
|
|
1607
1607
|
action: "created"
|
|
1608
1608
|
});
|
|
1609
|
-
} else throw new Error(`provision:
|
|
1609
|
+
} else throw new Error(`provision: Cloudflare r2 bucket info ${bucketName} failed: ${info.stderr || info.stdout}. Cannot determine whether the bucket exists; refusing to create a possible duplicate.`);
|
|
1610
1610
|
}
|
|
1611
1611
|
}
|
|
1612
1612
|
}
|
|
@@ -1663,7 +1663,7 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
|
|
|
1663
1663
|
action: "skipped",
|
|
1664
1664
|
reason
|
|
1665
1665
|
});
|
|
1666
|
-
} else if (existenceUnknown) throw new Error(`provision:
|
|
1666
|
+
} else if (existenceUnknown) throw new Error(`provision: could not check whether Hyperdrive config ${JSON.stringify(name)} already exists (see the warning above). A create would duplicate a config with the same name, so Void did not create it. Check that CLOUDFLARE_API_TOKEN can read Hyperdrive configs, then retry.`);
|
|
1667
1667
|
else {
|
|
1668
1668
|
const created = await runWrangler({
|
|
1669
1669
|
type: "hyperdrive.create",
|
|
@@ -1671,13 +1671,13 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
|
|
|
1671
1671
|
binding,
|
|
1672
1672
|
configPath
|
|
1673
1673
|
}, { input: connectionString });
|
|
1674
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1674
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare hyperdrive create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1675
1675
|
assertCreateWroteRealId(configPath, {
|
|
1676
1676
|
field: "hyperdrive",
|
|
1677
1677
|
idField: "id",
|
|
1678
1678
|
idValidator: isRealHyperdriveId,
|
|
1679
1679
|
resource: "Hyperdrive config",
|
|
1680
|
-
command: "
|
|
1680
|
+
command: "Cloudflare hyperdrive create"
|
|
1681
1681
|
}, binding, name);
|
|
1682
1682
|
persistCreatedConfig();
|
|
1683
1683
|
resources.push({
|
|
@@ -1705,18 +1705,18 @@ async function reconcileQueues(desired, configPath, runWrangler, resources) {
|
|
|
1705
1705
|
});
|
|
1706
1706
|
continue;
|
|
1707
1707
|
}
|
|
1708
|
-
if (!isConfirmedAbsent(info, "queue")) throw new Error(`provision:
|
|
1708
|
+
if (!isConfirmedAbsent(info, "queue")) throw new Error(`provision: Cloudflare queues info ${name} failed or did not confirm the queue exists: ${info.stderr || info.stdout || "no output"}`);
|
|
1709
1709
|
const created = await runWrangler({
|
|
1710
1710
|
type: "queues.create",
|
|
1711
1711
|
name,
|
|
1712
1712
|
configPath
|
|
1713
1713
|
});
|
|
1714
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1714
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare queues create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1715
1715
|
if (!queueInfoConfirmsExists(await runWrangler({
|
|
1716
1716
|
type: "queues.info",
|
|
1717
1717
|
name,
|
|
1718
1718
|
configPath
|
|
1719
|
-
}), name)) throw new Error(`provision:
|
|
1719
|
+
}), name)) throw new Error(`provision: Cloudflare queues create ${name} reported success but Cloudflare queues info ${name} did not confirm the queue exists afterward. The create may have been interrupted. Refusing to record an unprovisioned queue; inspect the account and retry.`);
|
|
1720
1720
|
resources.push({
|
|
1721
1721
|
kind: "queue",
|
|
1722
1722
|
name,
|
|
@@ -1750,14 +1750,14 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
|
|
|
1750
1750
|
const write = (patch) => writeProvisionedWranglerConfig(root, patch, { configPath });
|
|
1751
1751
|
const persistCreatedConfig = () => persistMaterializedWranglerConfig(configPath);
|
|
1752
1752
|
const hasRemoteWork = !!desired.d1 || desired.kvNamespaces.length > 0 || !!desired.r2 || !!desired.hyperdrive || desired.queues.length > 0;
|
|
1753
|
-
if (hasRemoteWork && !effectiveAccountId) throw new Error("provision: no Cloudflare account is resolvable
|
|
1753
|
+
if (hasRemoteWork && !effectiveAccountId) throw new Error("provision: no Cloudflare account is resolvable. Set `cloudflare.account_id` in void.config.ts or export CLOUDFLARE_ACCOUNT_ID, then rerun `void deploy`. Void does not provision resources without a pinned account.");
|
|
1754
1754
|
if (hasRemoteWork) assertNoTransportRedirectInProjectDotenv(root);
|
|
1755
1755
|
if (desired.hyperdrive && !opts?.listHyperdriveConfigs) {
|
|
1756
1756
|
const { binding, name, connectionString } = desired.hyperdrive;
|
|
1757
1757
|
const entry = readBindingEntry(configPath, "hyperdrive", binding);
|
|
1758
1758
|
if (!(entry !== void 0 && isRealHyperdriveId(entry.id)) && !resolveHyperdriveApiToken(opts?.apiToken)) {
|
|
1759
|
-
if (connectionString) throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)}
|
|
1760
|
-
throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)}
|
|
1759
|
+
if (connectionString) throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} has no ID yet. Before Void creates one, it checks for an existing config with the Cloudflare API. That check needs an API token; a browser login cannot call it. Without the check, a create could duplicate an existing config with the same name, so nothing was provisioned. Either (a) export CLOUDFLARE_API_TOKEN with Hyperdrive edit permission and rerun, or (b) create the Hyperdrive config in the Cloudflare dashboard and add its ID to the ${JSON.stringify(binding)} entry in \`cloudflare.hyperdrive\` in void.config.ts. Deploying an already-provisioned Hyperdrive needs no token.`);
|
|
1760
|
+
throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} has no ID yet, and there is no DATABASE_URL to create it from. Nothing was provisioned. Either (a) export DATABASE_URL with your PostgreSQL connection string and rerun (Void reads it from the shell — a value in .env/.env.local is NOT used here, so it never ships as a plaintext worker var), or (b) create the Hyperdrive config in the Cloudflare dashboard and add its ID to the ${JSON.stringify(binding)} entry in \`cloudflare.hyperdrive\` in void.config.ts. Deploying an already-provisioned Hyperdrive needs neither DATABASE_URL nor an API token.`);
|
|
1761
1761
|
}
|
|
1762
1762
|
}
|
|
1763
1763
|
let accountIdWritten = false;
|
|
@@ -1794,4 +1794,4 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
|
|
|
1794
1794
|
};
|
|
1795
1795
|
}
|
|
1796
1796
|
//#endregion
|
|
1797
|
-
export {
|
|
1797
|
+
export { provisionEnv as _, checkCloudflareProvisionDrift as a, enableD1ReadReplicationViaApi as c, isQueueConfirmedAbsent as d, isRealD1Id as f, provisionCloudflareResources as g, normalizeRunWranglerResult as h, assertValidResourceName as i, isAlreadyGoneKillError as l, isRealKvId as m, acquireProvisionLock as n, createDefaultRunWrangler as o, isRealHyperdriveId as p, assertNoTransportRedirectInProjectDotenv as r, deleteEnvVarCaseAware as s, WranglerQuarantineError as t, isQuarantineError as u, resolvePinnedApiBaseUrl as v, resolveProperLockfileKey as y };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/runtime/remote/r2-conditions.ts
|
|
2
|
+
/** URI-encoded JSON object metadata that the binding handler sends with a streamed `/r2/get` body. */
|
|
3
|
+
const R2_OBJECT_HEADER = "x-void-r2-object";
|
|
4
|
+
const HTTP_METADATA_FIELDS = /* @__PURE__ */ new Set([
|
|
5
|
+
"contentType",
|
|
6
|
+
"contentLanguage",
|
|
7
|
+
"contentDisposition",
|
|
8
|
+
"contentEncoding",
|
|
9
|
+
"cacheControl"
|
|
10
|
+
]);
|
|
11
|
+
function serializeR2Conditional(value) {
|
|
12
|
+
if (value instanceof Headers) return Array.from(value.entries());
|
|
13
|
+
return {
|
|
14
|
+
...value,
|
|
15
|
+
uploadedBefore: value.uploadedBefore?.toISOString(),
|
|
16
|
+
uploadedAfter: value.uploadedAfter?.toISOString()
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function serializeR2HttpMetadata(value) {
|
|
20
|
+
if (value instanceof Headers) return Array.from(value.entries());
|
|
21
|
+
return {
|
|
22
|
+
...value,
|
|
23
|
+
cacheExpiry: value.cacheExpiry?.toISOString()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function parseHeaderEntries(value, message) {
|
|
27
|
+
if (!value.every((pair) => Array.isArray(pair) && pair.length === 2 && pair.every((item) => typeof item === "string"))) throw new Error(message);
|
|
28
|
+
return new Headers(value);
|
|
29
|
+
}
|
|
30
|
+
function parseR2Conditional(value) {
|
|
31
|
+
if (Array.isArray(value)) return parseHeaderEntries(value, "Invalid R2 conditional headers");
|
|
32
|
+
if (!value || typeof value !== "object") throw new Error("Invalid R2 conditional options");
|
|
33
|
+
const result = {};
|
|
34
|
+
for (const [key, entry] of Object.entries(value)) if (key === "etagMatches" || key === "etagDoesNotMatch") {
|
|
35
|
+
if (typeof entry !== "string") throw new Error(`Invalid R2 condition: ${key}`);
|
|
36
|
+
result[key] = entry;
|
|
37
|
+
} else if (key === "uploadedBefore" || key === "uploadedAfter") {
|
|
38
|
+
if (typeof entry !== "string" || !Number.isFinite(Date.parse(entry))) throw new Error(`Invalid R2 condition: ${key}`);
|
|
39
|
+
result[key] = new Date(entry);
|
|
40
|
+
} else if (key === "secondsGranularity") {
|
|
41
|
+
if (typeof entry !== "boolean") throw new Error(`Invalid R2 condition: ${key}`);
|
|
42
|
+
result[key] = entry;
|
|
43
|
+
} else throw new Error(`Unsupported R2 condition: ${key}`);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
/** Like native R2, unknown metadata fields are ignored. */
|
|
47
|
+
function parseR2HttpMetadata(value) {
|
|
48
|
+
if (Array.isArray(value)) return parseHeaderEntries(value, "Invalid R2 HTTP metadata headers");
|
|
49
|
+
if (!value || typeof value !== "object") throw new Error("Invalid R2 HTTP metadata");
|
|
50
|
+
const result = {};
|
|
51
|
+
for (const [key, entry] of Object.entries(value)) if (key === "cacheExpiry") {
|
|
52
|
+
if (typeof entry !== "string" || !Number.isFinite(Date.parse(entry))) throw new Error(`Invalid R2 HTTP metadata: ${key}`);
|
|
53
|
+
result[key] = new Date(entry);
|
|
54
|
+
} else if (HTTP_METADATA_FIELDS.has(key)) {
|
|
55
|
+
if (typeof entry !== "string") throw new Error(`Invalid R2 HTTP metadata: ${key}`);
|
|
56
|
+
result[key] = entry;
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { serializeR2HttpMetadata as a, serializeR2Conditional as i, parseR2Conditional as n, parseR2HttpMetadata as r, R2_OBJECT_HEADER as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
3
|
import { H as outro, L as log } from "./dist-BVdsO7Py.mjs";
|
|
4
|
-
import { f as import_picocolors, i as dim } from "./output-
|
|
5
|
-
import { r as PlatformClient } from "./client-
|
|
4
|
+
import { f as import_picocolors, i as dim } from "./output-CKguMgr7.mjs";
|
|
5
|
+
import { r as PlatformClient } from "./client-BdzxubTS.mjs";
|
|
6
6
|
//#region src/cli/requests.ts
|
|
7
7
|
async function runRequestsCommand(root, range, status) {
|
|
8
8
|
console.log();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
3
|
import { A as confirm, H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./dist-BVdsO7Py.mjs";
|
|
4
|
-
import { c as formatRelativeTime, i as dim, m as printSuccess, o as formatCount, r as createSpinner } from "./output-
|
|
5
|
-
import { r as PlatformClient } from "./client-
|
|
4
|
+
import { c as formatRelativeTime, i as dim, m as printSuccess, o as formatCount, r as createSpinner } from "./output-CKguMgr7.mjs";
|
|
5
|
+
import { r as PlatformClient } from "./client-BdzxubTS.mjs";
|
|
6
6
|
//#region src/cli/rollback.ts
|
|
7
|
-
async function runRollbackCommand(root, deployId) {
|
|
7
|
+
async function runRollbackCommand(root, deployId, explicitPlatform) {
|
|
8
8
|
console.log();
|
|
9
9
|
const platform = readDeploymentPlatform(root);
|
|
10
|
-
if (platform === "cloudflare") return runCloudflareRollback(root, deployId);
|
|
10
|
+
if (explicitPlatform === "cloudflare" || platform === "cloudflare") return runCloudflareRollback(root, deployId, platform !== "cloudflare");
|
|
11
11
|
if (platform === "none") throw new Error("rollback: Deployment is disabled. Run `void init` to choose a platform.");
|
|
12
12
|
const token = getToken(root);
|
|
13
13
|
if (!token) {
|
|
@@ -73,8 +73,8 @@ async function runRollbackCommand(root, deployId) {
|
|
|
73
73
|
process.exit(1);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
async function runCloudflareRollback(root, deployId) {
|
|
77
|
-
const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-
|
|
76
|
+
async function runCloudflareRollback(root, deployId, restorePlatformFlag) {
|
|
77
|
+
const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BFLCpUCV.mjs");
|
|
78
78
|
const context = resolveCloudflareOperationContext(root);
|
|
79
79
|
const status = await readCloudflareWorkerStatus(context);
|
|
80
80
|
const deployedVersionIds = new Set(status.deployedVersionIds);
|
|
@@ -116,7 +116,7 @@ async function runCloudflareRollback(root, deployId) {
|
|
|
116
116
|
await confirmRollbackOrExit();
|
|
117
117
|
} else {
|
|
118
118
|
const targetSet = new Set(target.metadata.migrations);
|
|
119
|
-
await confirmUnrevertedMigrations(current.metadata.migrations.filter((migration) => !targetSet.has(migration)), "version");
|
|
119
|
+
await confirmUnrevertedMigrations(current.metadata.migrations.filter((migration) => !targetSet.has(migration)), "version", restorePlatformFlag);
|
|
120
120
|
}
|
|
121
121
|
const spinner = createSpinner();
|
|
122
122
|
spinner.start("Rolling back...");
|
|
@@ -139,11 +139,12 @@ async function confirmRollbackOrExit() {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
/** List migrations the rollback will not revert and ask before continuing. */
|
|
142
|
-
async function confirmUnrevertedMigrations(migrationDiff, noun) {
|
|
142
|
+
async function confirmUnrevertedMigrations(migrationDiff, noun, restorePlatformFlag = false) {
|
|
143
143
|
if (migrationDiff.length === 0) return;
|
|
144
144
|
log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this ${noun}:`);
|
|
145
145
|
for (const migration of migrationDiff) log.message(` ${dim("•")} ${migration}`);
|
|
146
146
|
log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
|
|
147
|
+
if (noun === "version") log.message(dim(`For D1, \`void db restore${restorePlatformFlag ? " --platform cloudflare" : ""} --bookmark <bookmark>\` undoes them with the restore point deploy printed before migrating. Restore points expire after 7 days on Workers Free and 30 days on Paid; undo older migrations with a new migration.`));
|
|
147
148
|
await confirmRollbackOrExit();
|
|
148
149
|
}
|
|
149
150
|
//#endregion
|