void 1.1.0 → 1.1.11
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-R35a4Oa8.mjs} +3 -3
- 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-VHmiKZmP.mjs} +3 -3
- package/dist/{auth-migrations-Cgs0k6lS.mjs → auth-migrations-BO27GDNr.mjs} +38 -2
- package/dist/{auth-router-CIxiMG7i.mjs → auth-router-O_Wrs5kg.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-CMZiMn46.mjs} +1 -1
- package/dist/{cache-Ctzfig-W.mjs → cache-TZ5Ab3d7.mjs} +1 -1
- package/dist/{cancel-deploy-CD9o-SsC.mjs → cancel-deploy-DXoR6oC3.mjs} +1 -1
- package/dist/cli/cli.mjs +69 -50
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-DrdeJgHR.mjs +1 -0
- package/dist/{client-DM9Kcf4e.mjs → client-GuSO3v_x.mjs} +1 -1
- package/dist/{cloudflare-auth-CqFBDo52.mjs → cloudflare-auth-DSvBc1Gu.mjs} +1 -1
- package/dist/{cloudflare-cmd-BIAF_BIY.mjs → cloudflare-cmd-ZSErUl6Y.mjs} +3 -3
- 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-Cm8lVx7W.mjs} +1 -1
- package/dist/{cloudflare-operations-B42EZeJy.mjs → cloudflare-operations-DH3GedbV.mjs} +6 -6
- 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-yQuLbuiJ.mjs} +4 -4
- package/dist/{create-project-B-ewF_Af.mjs → create-project-CGOo_OL_.mjs} +1 -1
- package/dist/{create-project-yInGo72M.mjs → create-project-DEEWJX_M.mjs} +1 -1
- package/dist/database-provider.d.mts +6 -0
- package/dist/{db-7I_gfdVq.mjs → db-COI-yTJE.mjs} +255 -110
- package/dist/{db-types-Bb4WBWIs.mjs → db-types-NGxPwnlt.mjs} +1 -1
- package/dist/{delete-Cy-M1u-r.mjs → delete-PgN6L_9N.mjs} +1 -1
- package/dist/deploy-CxNgEYr4.mjs +2 -0
- package/dist/{deploy-BYYlnsiy.mjs → deploy-DsW-PrRQ.mjs} +38 -36
- package/dist/{deploy-managed-static-Ca4TFdmx.mjs → deploy-managed-static-Dqz06S2u.mjs} +20 -20
- package/dist/{deploy-transport-DWlWBe6M.mjs → deploy-transport-nY3vLXPL.mjs} +2 -2
- package/dist/deploy.mjs +5 -5
- 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-DKlNI0SR.mjs} +2 -2
- package/dist/{drizzle-CF84FOVM.mjs → drizzle-BQfyvQKX.mjs} +13 -2
- package/dist/{email-DzyNVuoU.mjs → email-C0s3OvJk.mjs} +10 -11
- 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-BX2JFsgF.mjs} +4 -4
- 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-DHLOuPyk.d.mts} +2 -2
- package/dist/{fetch-stream-obvZ7fvO.d.mts → fetch-stream-CNxOrBdP.d.mts} +1 -1
- package/dist/{gen-CufHEf42.mjs → gen-Bj6ZkOcI.mjs} +25 -19
- package/dist/gen-DsCukhuw.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-DQDryS-5.mjs} +1 -1
- package/dist/{headers-Di1FsD3e.mjs → headers-Bi4bOAwp.mjs} +1 -1
- package/dist/{help-BT2hovNI.mjs → help-D49SL_lN.mjs} +16 -12
- package/dist/help-DOFygYi4.mjs +1 -0
- package/dist/{inbound-brj2-TM5.d.mts → inbound-Da7XsjH3.d.mts} +6 -12
- package/dist/index.mjs +103 -57
- package/dist/{info-l249eUdH.mjs → info-Bxunp14X.mjs} +4 -4
- package/dist/{init-D0A6M64Q.mjs → init-DyTEY04s.mjs} +50 -27
- package/dist/{link-WMoJFf4i.mjs → link-CgOVn9EC.mjs} +2 -2
- package/dist/{list-CQ2EQEHL.mjs → list-CUfD9RSb.mjs} +2 -2
- package/dist/{local-d1-BxvQYEFi.mjs → local-d1-CpaPbd_L.mjs} +5 -5
- package/dist/{login-C2T1oVG-.mjs → login-BJvGW5Eu.mjs} +2 -2
- package/dist/login-alAlxw4S.mjs +1 -0
- package/dist/{logs-DnC1d7xB.mjs → logs-DeizBI4j.mjs} +2 -2
- package/dist/{migrate-BDIprOYd.mjs → migrate-8rk56vV8.mjs} +4 -4
- package/dist/migrate-D2odrAmh.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-DHieWtFp.mjs → operator-cmd-CA5QQyvE.mjs} +3 -3
- package/dist/operator-cmd-D7toMPJ9.mjs +1 -0
- package/dist/pages/client.d.mts +1 -1
- package/dist/pages/index.d.mts +1 -1
- package/dist/pages/index.mjs +4 -4
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +1 -1
- package/dist/pages/protocol.d.mts +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-CZaY812e.mjs} +3 -3
- package/dist/{platform-auth-protection-BXwZiJSF.mjs → platform-auth-protection-U9HCqoXv.mjs} +2 -2
- package/dist/{platform-auth-recovery-CXjfqyOv.mjs → platform-auth-recovery-B0BV2hfV.mjs} +2 -2
- package/dist/{platform-cmd-DaAOiWTl.mjs → platform-cmd-CXrjk4fb.mjs} +4 -4
- package/dist/{platform-cmd-PT4YwMLM.mjs → platform-cmd-D9lwFpcl.mjs} +1 -1
- package/dist/{platform-domain-CxpvUeo0.mjs → platform-domain-CXyq-68_.mjs} +2 -2
- package/dist/{platform-lifecycle-DBiS0cJd.mjs → platform-lifecycle-D0TdyXbN.mjs} +20 -11
- package/dist/{platform-lifecycle-u9pMOvxC.mjs → platform-lifecycle-Dz2cJsLX.mjs} +1 -1
- package/dist/{platform-management-DvBS83rC.mjs → platform-management-BvgbusqL.mjs} +1 -1
- package/dist/{platform-management-DhEFdQAf.mjs → platform-management-CnXhgxTM.mjs} +1 -3
- package/dist/{platform-recovery-BUGOB4RC.mjs → platform-recovery-CH_fThW6.mjs} +2 -2
- package/dist/{plugin-inference-DsARdQKE.mjs → plugin-inference-Bekzjuqw.mjs} +2 -2
- package/dist/{prepare-PQCgsny0.mjs → prepare-2XD6kh77.mjs} +1 -1
- package/dist/{prepare-DEB5SeVJ.mjs → prepare-DepAGBcV.mjs} +9 -9
- package/dist/prepare-EVEbQ9n2.mjs +1 -0
- package/dist/{project-cmd-DVatD8Ev.mjs → project-cmd-CpLYflCH.mjs} +16 -16
- package/dist/{project-paths-DMvEeSau.mjs → project-paths-DGu_QZ_Q.mjs} +1 -1
- package/dist/{project-team-DJrWEAG1.mjs → project-team-CTSY7W7Q.mjs} +1 -1
- package/dist/{project-token-CBgLBuL6.mjs → project-token-Cybtlfbl.mjs} +1 -1
- package/dist/{project-tsconfig-bveqhlYA.mjs → project-tsconfig-Itv1f4WC.mjs} +1 -1
- package/dist/{project-zero-trust-92gLtZ25.mjs → project-zero-trust-DKOtqyvu.mjs} +1 -1
- package/dist/{protocol-4H7V_3Os.d.mts → protocol-B8sI8dRD.d.mts} +1 -1
- package/dist/{providers-BXuhmuub.mjs → providers-BUHwJlmM.mjs} +10 -1
- package/dist/{provision-BnSSkiED.mjs → provision-BuifYvLc.mjs} +63 -64
- package/dist/provision-UcYjpTRh.mjs +1 -0
- package/dist/r2-conditions-B8xUgJRc.mjs +61 -0
- package/dist/{requests-7W1Pygt2.mjs → requests-Ryiazz9i.mjs} +1 -1
- package/dist/{rollback-BcASVnwP.mjs → rollback-Or0EV3rP.mjs} +2 -2
- 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-solid.d.mts +2 -2
- package/dist/runtime/client-svelte.d.mts +2 -2
- package/dist/runtime/client-vue.d.mts +2 -2
- package/dist/runtime/client.d.mts +2 -2
- 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-stream.d.mts +2 -2
- package/dist/runtime/fetch.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/sse-client.d.mts +4 -0
- 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-CClHaFxm.mjs} +3 -3
- 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-BOigE1xJ.mjs} +4 -4
- package/dist/{ws-aKVYB-fA.d.mts → ws-CsBNxv86.d.mts} +5 -0
- 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/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 +1 -1
- package/docs/guide/pages-routing/islands.md +2 -2
- package/docs/guide/platform/administration/connected-apps.md +18 -2
- package/docs/guide/remote-dev.md +2 -0
- package/docs/guide/websockets.md +2 -2
- package/docs/index.md +78 -22
- package/docs/reference/api/pages.md +7 -5
- package/docs/reference/api.md +2 -0
- package/docs/reference/cli/database.md +7 -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 +2 -2
- package/docs/reference/cli/project.md +4 -2
- package/docs/reference/cli.md +1 -1
- package/docs/reference/config.md +11 -1
- package/package.json +7 -7
- 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/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/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 = () => {
|
|
@@ -457,11 +456,11 @@ function createDefaultRunWrangler(root, options) {
|
|
|
457
456
|
return (args, opts) => new Promise((resolvePromise, rejectPromise) => {
|
|
458
457
|
const parallelWorkerUpload = options?.parallelWorkerUpload === true && args.type === "versions.upload";
|
|
459
458
|
if (activeTeardown !== void 0) {
|
|
460
|
-
rejectPromise(/* @__PURE__ */ new Error(`provision: refusing to spawn
|
|
459
|
+
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
460
|
return;
|
|
462
461
|
}
|
|
463
462
|
if (!canRegisterRunner(parallelWorkerUpload)) {
|
|
464
|
-
rejectPromise(/* @__PURE__ */ new Error("provision: refusing to spawn
|
|
463
|
+
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
464
|
return;
|
|
466
465
|
}
|
|
467
466
|
const child = spawn(command, [...prefix, ...encodeCloudflareOperation(args)], {
|
|
@@ -548,7 +547,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
548
547
|
};
|
|
549
548
|
const timeoutStderr = (extra) => [
|
|
550
549
|
stderr,
|
|
551
|
-
`provision:
|
|
550
|
+
`provision: the Cloudflare operation process exceeded the ${timeoutMs}ms command timeout`,
|
|
552
551
|
extra
|
|
553
552
|
].filter(Boolean).join("\n");
|
|
554
553
|
const deregisterSelf = () => deregisterRunner(registrant);
|
|
@@ -652,7 +651,7 @@ function createDefaultRunWrangler(root, options) {
|
|
|
652
651
|
if (outcome === "gone") groupGone = true;
|
|
653
652
|
confirmThenSettle(() => normalizeRunWranglerResult({
|
|
654
653
|
stdout,
|
|
655
|
-
stderr: [stderr, `provision: the spawned
|
|
654
|
+
stderr: [stderr, `provision: the spawned Cloudflare operation process emitted an error after spawn: ${error.message}`].filter(Boolean).join("\n"),
|
|
656
655
|
status: null,
|
|
657
656
|
signal: "SIGKILL"
|
|
658
657
|
}), `a post-spawn child error (${error.message}; the group was SIGKILLed)`);
|
|
@@ -697,8 +696,8 @@ function createDefaultRunWrangler(root, options) {
|
|
|
697
696
|
function normalizeRunWranglerResult(result) {
|
|
698
697
|
const stdout = result.stdout ?? "";
|
|
699
698
|
const notes = [];
|
|
700
|
-
if (result.signal != null) notes.push(`provision:
|
|
701
|
-
if (result.error != null) notes.push(`provision:
|
|
699
|
+
if (result.signal != null) notes.push(`provision: the Cloudflare operation process was terminated by signal ${result.signal}`);
|
|
700
|
+
if (result.error != null) notes.push(`provision: the Cloudflare operation process could not be spawned: ${result.error.message}`);
|
|
702
701
|
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
702
|
const baseStderr = result.stderr ?? "";
|
|
704
703
|
return {
|
|
@@ -903,7 +902,7 @@ function assertQuarantineClearedOrClear(lockTarget, onBeforeClear) {
|
|
|
903
902
|
}
|
|
904
903
|
if (!confirmedDead) {
|
|
905
904
|
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
|
|
905
|
+
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
906
|
}
|
|
908
907
|
const inspectedGeneration = typeof recorded?.generation === "string" ? recorded.generation : void 0;
|
|
909
908
|
onBeforeClear?.();
|
|
@@ -1090,7 +1089,7 @@ async function acquireProvisionLock(configPath, lockOptions) {
|
|
|
1090
1089
|
try {
|
|
1091
1090
|
writeQuarantineSidecar(quarantineSidecarPath(lockTarget), info, lockOptions?.dirDurability);
|
|
1092
1091
|
} 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
|
|
1092
|
+
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
1093
|
}
|
|
1095
1094
|
releasePromise = Promise.resolve();
|
|
1096
1095
|
const locks = loadProperLockfileInternals()?.getLocks?.();
|
|
@@ -1125,7 +1124,7 @@ function readRootConfig(configPath) {
|
|
|
1125
1124
|
}
|
|
1126
1125
|
/** Throw unless a discovery call exited cleanly, so a failed list never means "absent". */
|
|
1127
1126
|
function assertDiscoverySucceeded(result, label) {
|
|
1128
|
-
if (!isCleanSuccess(result)) throw new Error(`provision:
|
|
1127
|
+
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
1128
|
}
|
|
1130
1129
|
/**
|
|
1131
1130
|
* Reject the whole list if any member lacks a non-empty name or a valid id. A malformed member
|
|
@@ -1134,12 +1133,12 @@ function assertDiscoverySucceeded(result, label) {
|
|
|
1134
1133
|
function validateResourceList(list, spec) {
|
|
1135
1134
|
const validated = [];
|
|
1136
1135
|
for (const member of list) {
|
|
1137
|
-
if (!isRecord(member)) throw new Error(`provision:
|
|
1136
|
+
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
1137
|
const rawName = member[spec.nameField];
|
|
1139
1138
|
const nameValid = typeof rawName === "string" && rawName.length > 0;
|
|
1140
1139
|
const idValid = spec.hasValidId(member);
|
|
1141
|
-
if (nameValid && !idValid) throw new Error(`provision:
|
|
1142
|
-
if (!nameValid) throw new Error(`provision:
|
|
1140
|
+
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.`);
|
|
1141
|
+
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
1142
|
validated.push(member);
|
|
1144
1143
|
}
|
|
1145
1144
|
return validated;
|
|
@@ -1200,13 +1199,13 @@ function assertD1MigrationsDirApplied(result, binding, configPath) {
|
|
|
1200
1199
|
}
|
|
1201
1200
|
/**
|
|
1202
1201
|
* 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
|
|
1202
|
+
* name where the name is the identity. A success status alone is not trusted.
|
|
1204
1203
|
*/
|
|
1205
1204
|
function assertCreateWroteRealId(configPath, spec, binding, name) {
|
|
1206
1205
|
const entry = readBindingEntry(configPath, spec.field, binding);
|
|
1207
1206
|
const idOk = !!entry && spec.idValidator(entry[spec.idField]);
|
|
1208
1207
|
const nameOk = spec.nameField === void 0 || !!entry && entry[spec.nameField] === name;
|
|
1209
|
-
if (!idOk || !nameOk) throw new Error(`provision:
|
|
1208
|
+
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
1209
|
}
|
|
1211
1210
|
/** True when `value` contains an ASCII control character (0x00–0x1F or 0x7F). */
|
|
1212
1211
|
function hasControlChar(value) {
|
|
@@ -1216,9 +1215,9 @@ function hasControlChar(value) {
|
|
|
1216
1215
|
}
|
|
1217
1216
|
return false;
|
|
1218
1217
|
}
|
|
1219
|
-
/** The universal option-injection guard for ANY
|
|
1218
|
+
/** The universal option-injection guard for ANY Cloudflare operation ARGV positional. */
|
|
1220
1219
|
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
|
|
1220
|
+
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
1221
|
}
|
|
1223
1222
|
/** Per-resource Cloudflare naming grammar. KV titles may contain spaces and mixed case. */
|
|
1224
1223
|
const RESOURCE_NAME_GRAMMARS = {
|
|
@@ -1252,7 +1251,7 @@ const RESOURCE_NAME_GRAMMARS = {
|
|
|
1252
1251
|
function assertValidResourceName(kind, name) {
|
|
1253
1252
|
assertNoOptionInjection(RESOURCE_NAME_GRAMMARS[kind].label, name);
|
|
1254
1253
|
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
|
|
1254
|
+
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
1255
|
}
|
|
1257
1256
|
/** Redactor that replaces the exact connection string and masks any URL userinfo password. */
|
|
1258
1257
|
function createSecretRedactor(connectionString) {
|
|
@@ -1306,7 +1305,7 @@ async function provisionWithProcessSlot(root, rootWranglerPath, desired, opts) {
|
|
|
1306
1305
|
reason: typeof bodyError.message === "string" ? bodyError.message : String(bodyError)
|
|
1307
1306
|
});
|
|
1308
1307
|
} catch (quarantineError) {
|
|
1309
|
-
throw new AggregateError([bodyError, quarantineError], `provision failed with an unconfirmed
|
|
1308
|
+
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
1309
|
}
|
|
1311
1310
|
throw bodyError;
|
|
1312
1311
|
}
|
|
@@ -1359,19 +1358,19 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1359
1358
|
type: "d1.list",
|
|
1360
1359
|
configPath
|
|
1361
1360
|
}, {});
|
|
1362
|
-
assertDiscoverySucceeded(listResult, "
|
|
1361
|
+
assertDiscoverySucceeded(listResult, "Cloudflare d1 list");
|
|
1363
1362
|
const rawList = listResult.data;
|
|
1364
|
-
if (!Array.isArray(rawList)) throw new Error(`provision:
|
|
1363
|
+
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
1364
|
const claimants = validateResourceList(rawList, {
|
|
1366
1365
|
resource: "D1 database",
|
|
1367
|
-
command: "
|
|
1366
|
+
command: "Cloudflare d1 list",
|
|
1368
1367
|
hasValidId: (member) => reconcileD1IdAliases(member).kind === "id",
|
|
1369
1368
|
idRule: "its uuid/database_id aliases must be present, well-formed D1 UUIDs agreeing on one id",
|
|
1370
1369
|
nameField: "name",
|
|
1371
1370
|
nameLabel: "named"
|
|
1372
1371
|
}).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:
|
|
1372
|
+
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.`);
|
|
1373
|
+
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
1374
|
const existing = claimants.length === 1 && claimants[0].kind === "match" ? claimants[0] : void 0;
|
|
1376
1375
|
if (existing) {
|
|
1377
1376
|
log.info(`adopted existing D1 database ${name} (${existing.id})`);
|
|
@@ -1407,7 +1406,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1407
1406
|
idValidator: isRealD1Id,
|
|
1408
1407
|
nameField: "database_name",
|
|
1409
1408
|
resource: "D1 database",
|
|
1410
|
-
command: "
|
|
1409
|
+
command: "Cloudflare d1 create"
|
|
1411
1410
|
}, binding, name);
|
|
1412
1411
|
persistCreatedConfig();
|
|
1413
1412
|
assertD1MigrationsDirApplied(write({ d1MigrationsDir: {
|
|
@@ -1426,9 +1425,9 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1426
1425
|
name,
|
|
1427
1426
|
configPath
|
|
1428
1427
|
}, {});
|
|
1429
|
-
assertDiscoverySucceeded(infoResult, `
|
|
1428
|
+
assertDiscoverySucceeded(infoResult, `Cloudflare d1 info ${name}`);
|
|
1430
1429
|
const info = normalizeD1(isRecord(infoResult.data) ? infoResult.data : void 0, name);
|
|
1431
|
-
if (info.kind !== "match") throw new Error(`provision:
|
|
1430
|
+
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
1431
|
log.info(`adopted existing D1 database ${name} (${info.id})`);
|
|
1433
1432
|
assertD1MigrationsDirApplied(write({
|
|
1434
1433
|
d1: {
|
|
@@ -1448,7 +1447,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
|
|
|
1448
1447
|
action: "adopted",
|
|
1449
1448
|
id: info.id
|
|
1450
1449
|
});
|
|
1451
|
-
} else throw new Error(`provision:
|
|
1450
|
+
} else throw new Error(`provision: Cloudflare d1 create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1452
1451
|
}
|
|
1453
1452
|
}
|
|
1454
1453
|
const databaseId = readBindingEntry(configPath, "d1_databases", binding)?.database_id;
|
|
@@ -1491,12 +1490,12 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
|
|
|
1491
1490
|
type: "kv.namespace.list",
|
|
1492
1491
|
configPath
|
|
1493
1492
|
}, {});
|
|
1494
|
-
assertDiscoverySucceeded(listResult, "
|
|
1493
|
+
assertDiscoverySucceeded(listResult, "Cloudflare kv namespace list");
|
|
1495
1494
|
const rawList = listResult.data;
|
|
1496
|
-
if (!Array.isArray(rawList)) throw new Error(`provision:
|
|
1495
|
+
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
1496
|
const matches = validateResourceList(rawList, {
|
|
1498
1497
|
resource: "KV namespace",
|
|
1499
|
-
command: "
|
|
1498
|
+
command: "Cloudflare kv namespace list",
|
|
1500
1499
|
hasValidId: (member) => isRealKvId(member.id),
|
|
1501
1500
|
idRule: "its id is missing or not a well-formed 32-hex namespace id",
|
|
1502
1501
|
nameField: "title",
|
|
@@ -1524,13 +1523,13 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
|
|
|
1524
1523
|
binding,
|
|
1525
1524
|
configPath
|
|
1526
1525
|
});
|
|
1527
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1526
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare kv namespace create ${title} failed: ${created.stderr || created.stdout}`);
|
|
1528
1527
|
assertCreateWroteRealId(configPath, {
|
|
1529
1528
|
field: "kv_namespaces",
|
|
1530
1529
|
idField: "id",
|
|
1531
1530
|
idValidator: isRealKvId,
|
|
1532
1531
|
resource: "KV namespace",
|
|
1533
|
-
command: "
|
|
1532
|
+
command: "Cloudflare kv namespace create"
|
|
1534
1533
|
}, binding, title);
|
|
1535
1534
|
persistCreatedConfig();
|
|
1536
1535
|
resources.push({
|
|
@@ -1563,7 +1562,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1563
1562
|
}, {});
|
|
1564
1563
|
if (isCleanSuccess(info)) {
|
|
1565
1564
|
const payload = info.data;
|
|
1566
|
-
if (!isRecord(payload) || payload.name !== bucketName) throw new Error(`provision:
|
|
1565
|
+
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
1566
|
log.info(`adopted existing R2 bucket ${bucketName}`);
|
|
1568
1567
|
write({ r2: {
|
|
1569
1568
|
binding,
|
|
@@ -1582,14 +1581,14 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1582
1581
|
binding,
|
|
1583
1582
|
configPath
|
|
1584
1583
|
});
|
|
1585
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1584
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare r2 bucket create ${bucketName} failed: ${created.stderr || created.stdout}`);
|
|
1586
1585
|
assertCreateWroteRealId(configPath, {
|
|
1587
1586
|
field: "r2_buckets",
|
|
1588
1587
|
idField: "bucket_name",
|
|
1589
1588
|
idValidator: isValidR2BucketNameFormat,
|
|
1590
1589
|
nameField: "bucket_name",
|
|
1591
1590
|
resource: "R2 bucket",
|
|
1592
|
-
command: "
|
|
1591
|
+
command: "Cloudflare r2 bucket create"
|
|
1593
1592
|
}, binding, bucketName);
|
|
1594
1593
|
if (bucketName === R2_BUCKET_NAME_PLACEHOLDER) {
|
|
1595
1594
|
const verify = await runWrangler({
|
|
@@ -1597,7 +1596,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1597
1596
|
name: bucketName,
|
|
1598
1597
|
configPath
|
|
1599
1598
|
}, {});
|
|
1600
|
-
if (!isCleanSuccess(verify) || !isRecord(verify.data) || verify.data.name !== bucketName) throw new Error(`provision:
|
|
1599
|
+
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
1600
|
}
|
|
1602
1601
|
persistCreatedConfig();
|
|
1603
1602
|
resources.push({
|
|
@@ -1606,7 +1605,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
|
|
|
1606
1605
|
name: bucketName,
|
|
1607
1606
|
action: "created"
|
|
1608
1607
|
});
|
|
1609
|
-
} else throw new Error(`provision:
|
|
1608
|
+
} 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
1609
|
}
|
|
1611
1610
|
}
|
|
1612
1611
|
}
|
|
@@ -1663,7 +1662,7 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
|
|
|
1663
1662
|
action: "skipped",
|
|
1664
1663
|
reason
|
|
1665
1664
|
});
|
|
1666
|
-
} else if (existenceUnknown) throw new Error(`provision:
|
|
1665
|
+
} 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
1666
|
else {
|
|
1668
1667
|
const created = await runWrangler({
|
|
1669
1668
|
type: "hyperdrive.create",
|
|
@@ -1671,13 +1670,13 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
|
|
|
1671
1670
|
binding,
|
|
1672
1671
|
configPath
|
|
1673
1672
|
}, { input: connectionString });
|
|
1674
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1673
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare hyperdrive create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1675
1674
|
assertCreateWroteRealId(configPath, {
|
|
1676
1675
|
field: "hyperdrive",
|
|
1677
1676
|
idField: "id",
|
|
1678
1677
|
idValidator: isRealHyperdriveId,
|
|
1679
1678
|
resource: "Hyperdrive config",
|
|
1680
|
-
command: "
|
|
1679
|
+
command: "Cloudflare hyperdrive create"
|
|
1681
1680
|
}, binding, name);
|
|
1682
1681
|
persistCreatedConfig();
|
|
1683
1682
|
resources.push({
|
|
@@ -1705,18 +1704,18 @@ async function reconcileQueues(desired, configPath, runWrangler, resources) {
|
|
|
1705
1704
|
});
|
|
1706
1705
|
continue;
|
|
1707
1706
|
}
|
|
1708
|
-
if (!isConfirmedAbsent(info, "queue")) throw new Error(`provision:
|
|
1707
|
+
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
1708
|
const created = await runWrangler({
|
|
1710
1709
|
type: "queues.create",
|
|
1711
1710
|
name,
|
|
1712
1711
|
configPath
|
|
1713
1712
|
});
|
|
1714
|
-
if (!isCleanSuccess(created)) throw new Error(`provision:
|
|
1713
|
+
if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare queues create ${name} failed: ${created.stderr || created.stdout}`);
|
|
1715
1714
|
if (!queueInfoConfirmsExists(await runWrangler({
|
|
1716
1715
|
type: "queues.info",
|
|
1717
1716
|
name,
|
|
1718
1717
|
configPath
|
|
1719
|
-
}), name)) throw new Error(`provision:
|
|
1718
|
+
}), 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
1719
|
resources.push({
|
|
1721
1720
|
kind: "queue",
|
|
1722
1721
|
name,
|
|
@@ -1750,14 +1749,14 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
|
|
|
1750
1749
|
const write = (patch) => writeProvisionedWranglerConfig(root, patch, { configPath });
|
|
1751
1750
|
const persistCreatedConfig = () => persistMaterializedWranglerConfig(configPath);
|
|
1752
1751
|
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
|
|
1752
|
+
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
1753
|
if (hasRemoteWork) assertNoTransportRedirectInProjectDotenv(root);
|
|
1755
1754
|
if (desired.hyperdrive && !opts?.listHyperdriveConfigs) {
|
|
1756
1755
|
const { binding, name, connectionString } = desired.hyperdrive;
|
|
1757
1756
|
const entry = readBindingEntry(configPath, "hyperdrive", binding);
|
|
1758
1757
|
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)}
|
|
1758
|
+
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.`);
|
|
1759
|
+
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
1760
|
}
|
|
1762
1761
|
}
|
|
1763
1762
|
let accountIdWritten = false;
|
|
@@ -1794,4 +1793,4 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
|
|
|
1794
1793
|
};
|
|
1795
1794
|
}
|
|
1796
1795
|
//#endregion
|
|
1797
|
-
export {
|
|
1796
|
+
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 @@
|
|
|
1
|
+
export { f as isRealD1Id, p as isRealHyperdriveId } from "./provision-BuifYvLc.mjs";
|
|
@@ -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 };
|
|
@@ -2,7 +2,7 @@ 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
4
|
import { f as import_picocolors, i as dim } from "./output-Ba6ZbrzY.mjs";
|
|
5
|
-
import { r as PlatformClient } from "./client-
|
|
5
|
+
import { r as PlatformClient } from "./client-GuSO3v_x.mjs";
|
|
6
6
|
//#region src/cli/requests.ts
|
|
7
7
|
async function runRequestsCommand(root, range, status) {
|
|
8
8
|
console.log();
|
|
@@ -2,7 +2,7 @@ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-r
|
|
|
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
4
|
import { c as formatRelativeTime, i as dim, m as printSuccess, o as formatCount, r as createSpinner } from "./output-Ba6ZbrzY.mjs";
|
|
5
|
-
import { r as PlatformClient } from "./client-
|
|
5
|
+
import { r as PlatformClient } from "./client-GuSO3v_x.mjs";
|
|
6
6
|
//#region src/cli/rollback.ts
|
|
7
7
|
async function runRollbackCommand(root, deployId) {
|
|
8
8
|
console.log();
|
|
@@ -74,7 +74,7 @@ async function runRollbackCommand(root, deployId) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
async function runCloudflareRollback(root, deployId) {
|
|
77
|
-
const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-
|
|
77
|
+
const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-Cm8lVx7W.mjs");
|
|
78
78
|
const context = resolveCloudflareOperationContext(root);
|
|
79
79
|
const status = await readCloudflareWorkerStatus(context);
|
|
80
80
|
const deployedVersionIds = new Set(status.deployedVersionIds);
|