void 0.21.2 → 0.21.4
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-D8OC-U7y.mjs → account-cmd-DGt9cpRe.mjs} +4 -4
- package/dist/{agents-gni4eqBu.mjs → agents-B_pX_HmQ.mjs} +1 -1
- package/dist/ast-CPGPjb0V.mjs +18 -0
- package/dist/{auth-CAw7zHqj.mjs → auth-CZuiVsFh.mjs} +1 -1
- package/dist/{auth-B9_D6ygs.mjs → auth-DLNN0D3Z.mjs} +4 -4
- package/dist/{auth-link-BYFeMJAp.mjs → auth-link-Cl9vOuf7.mjs} +4 -4
- package/dist/{auth-router-OHZNmrb_.mjs → auth-router-D4ZcMUSf.mjs} +6 -6
- package/dist/{better-auth-shared-BoVwA5Vm.d.mts → better-auth-shared-BVkjZ3vM.d.mts} +1 -0
- package/dist/{better-auth-shared-syGYYmnY.mjs → better-auth-shared-rsBGBvWJ.mjs} +3 -6
- package/dist/{build-cmd-Bft7EY51.mjs → build-cmd-Dpt0jd-x.mjs} +4 -4
- package/dist/{cache-CKV1Gz2w.mjs → cache-7_UeZdTk.mjs} +4 -4
- package/dist/{cancel-deploy-BAKmkX4f.mjs → cancel-deploy-D23R1RXT.mjs} +3 -3
- package/dist/{cf-access-rAZxzMkL.mjs → cf-access-P0iZnu0q.mjs} +1 -1
- package/dist/{cf-build-output-CTdlo6Rt.mjs → cf-build-output-CGT03qCD.mjs} +2 -2
- package/dist/cli/cf-compat.mjs +2 -2
- package/dist/cli/cli.mjs +47 -43
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-4cDVv7BO.mjs +2 -0
- package/dist/{client-PdAJ-F0t.mjs → client-QTl6ko_D.mjs} +28 -5
- package/dist/{cloudflare-auth-BCmTc1X_.mjs → cloudflare-auth-B9jPCkV2.mjs} +1 -1
- package/dist/{cloudflare-cmd-D6PrKn7o.mjs → cloudflare-cmd-BjNxR1XF.mjs} +3 -3
- package/dist/{cloudflare-connect-DloREDlc.mjs → cloudflare-connect-CCUozPOe.mjs} +3 -3
- package/dist/{cloudflare-operations-BHNJVDbN.mjs → cloudflare-operations-BipGMJ5O.mjs} +1 -1
- package/dist/{cloudflare-operations-CPEdHYhM.mjs → cloudflare-operations-sMZXpk_S.mjs} +4 -4
- package/dist/collect-DLyFDiKW.mjs +2 -0
- package/dist/{collect-DXHNWHcT.mjs → collect-DiTn9yr6.mjs} +1 -1
- package/dist/config-0acf1oys.mjs +2 -0
- package/dist/{config-DywxBLQC.d.mts → config-CF69HgXc.d.mts} +7 -0
- package/dist/{config-Dxr6cTXn.mjs → config-CafTW6Cz.mjs} +12 -1
- package/dist/{config-BSe70f4T.mjs → config-D8MOgiQV.mjs} +3 -3
- package/dist/config-DPByhVck.mjs +32 -0
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config--T87TD8T.mjs → config-s7Xj7tPb.mjs} +1 -1
- package/dist/{config-write-y3CBI_ux.mjs → config-write-BSduPMY8.mjs} +3 -3
- package/dist/{connect-DLx1pRYk.mjs → connect-4Ph5Y0QE.mjs} +7 -7
- package/dist/{create-project-JV9-6ICF.mjs → create-project-BniEV0OW.mjs} +1 -1
- package/dist/{create-project-BZBl_gQ0.mjs → create-project-DBfFSZKY.mjs} +4 -4
- package/dist/{db-B98_UV4H.mjs → db-CTXIWD42.mjs} +123 -55
- package/dist/{delete-BEEyqlwd.mjs → delete-D6dZ9B6B.mjs} +4 -4
- package/dist/deploy-BVwow28d.mjs +2 -0
- package/dist/{deploy-Bsymb0_c.mjs → deploy-F1exK5F4.mjs} +567 -263
- package/dist/discover-AMCBXivQ.mjs +2 -0
- package/dist/{discover-C4O6YxVS.mjs → discover-BcPPiF1o.mjs} +2 -2
- package/dist/{dist-4WkAWhWx.mjs → dist-BVqXeR_h.mjs} +9 -1
- package/dist/dist-_UUlL6bg.mjs +2 -0
- package/dist/{domain-Av2AkLQP.mjs → domain-Dmhvb2oU.mjs} +4 -4
- package/dist/{email-C5kaZXzJ.mjs → email--tEtMoj_.mjs} +1 -1
- package/dist/{email-CUqa6TtH.mjs → email-BxHabktK.mjs} +9 -9
- package/dist/{entry-DdRFGK0y.mjs → entry-CF5wvH4w.mjs} +4 -21
- package/dist/{env-D4RIGEzz.mjs → env-Csi-tMbT.mjs} +7 -7
- package/dist/{env-Yz4HcvHs.mjs → env-D5liuQYR.mjs} +5 -2
- package/dist/{env-DX_v-Q-v.mjs → env-_v349JBd.mjs} +1 -1
- package/dist/{env-types-CWDtqHgw.mjs → env-types-C2_bIk_b.mjs} +2 -2
- package/dist/{env-validation-BsFEXps5.mjs → env-validation-BB4GkLxn.mjs} +4 -4
- package/dist/{env-validation-DIDGM7h4.mjs → env-validation-BXge7uyK.mjs} +1 -1
- package/dist/{gen-pg-Ojg8Y.mjs → gen-Dz3X1Qab.mjs} +8 -8
- package/dist/gen-Vnv2f65C.mjs +2 -0
- package/dist/{generate-C0VY6RVf.mjs → generate-GDbL7sUr.mjs} +2 -2
- package/dist/{github-cmd-BEK4VprE.mjs → github-cmd-BED3_9JD.mjs} +4 -4
- package/dist/{headers-B_HBMgi0.mjs → headers-BOg_velo.mjs} +2 -2
- package/dist/{help-iQOt7WHk.mjs → help-DC7gdz7L.mjs} +7 -3
- package/dist/help-DQMfeKMz.mjs +2 -0
- package/dist/index.mjs +132 -158
- package/dist/{init-D5niUPAz.mjs → init-CRGDXzVC.mjs} +105 -289
- package/dist/{link-3lGrfXzd.mjs → link-CsHOinF7.mjs} +5 -5
- package/dist/{list-CVjGr_C6.mjs → list-CDb-4bZ1.mjs} +5 -5
- package/dist/{local-d1-DzykTWY8.mjs → local-d1-CC8sKFGu.mjs} +3 -3
- package/dist/{login-BgQJzxAl.mjs → login-BQyISZuW.mjs} +3 -3
- package/dist/login-r2gL8l7B.mjs +2 -0
- package/dist/{logs-DbzD-QDf.mjs → logs-BdfiOezj.mjs} +4 -4
- package/dist/{migrate-BV8qHiCb.mjs → migrate-B8KuoYsO.mjs} +69 -44
- package/dist/migrate-TsHGBnDA.mjs +2 -0
- package/dist/{node-Cupyf7-s.mjs → node-BM43oz4G.mjs} +5 -5
- package/dist/{operator-auth-BkVgJqv-.mjs → operator-auth-8KnOVXVd.mjs} +2 -2
- package/dist/{operator-client-A0iex2yi.mjs → operator-client-DUwumHpQ.mjs} +2 -2
- package/dist/{operator-cmd-CR6Lxzt0.mjs → operator-cmd-Co-PeaeD.mjs} +6 -6
- package/dist/{package-json-iCbMg5XF.mjs → package-json-DXfiT1jV.mjs} +1 -1
- package/dist/pages/index.d.mts +1 -1
- package/dist/pages/index.mjs +11 -6
- package/dist/pages/islands-plugin.d.mts +271 -1
- package/dist/pages/islands-plugin.mjs +95 -18
- package/dist/parse-filename-DioPHiR9.mjs +77 -0
- package/dist/{platform-auth-config-De7BqRJm.mjs → platform-auth-config-TSw8edHw.mjs} +5 -5
- package/dist/{platform-auth-protection-Dcat-6zu.mjs → platform-auth-protection-Ba1XqGhn.mjs} +6 -6
- package/dist/{platform-auth-recovery-C9gsM640.mjs → platform-auth-recovery-BkT3EsF2.mjs} +5 -5
- package/dist/{platform-cmd-Cl9Uhzru.mjs → platform-cmd-C8OqhqPt.mjs} +1 -1
- package/dist/{platform-cmd-CudokNIg.mjs → platform-cmd-CRSKfu8k.mjs} +5 -5
- package/dist/{platform-domain-Ckpd2kXw.mjs → platform-domain-j9YCXRm6.mjs} +3 -3
- package/dist/{platform-lifecycle-DVzM2T4j.mjs → platform-lifecycle-78H0XQUA.mjs} +277 -229
- package/dist/{platform-lifecycle-DlpiGcjr.mjs → platform-lifecycle-DDc9zCeJ.mjs} +1 -1
- package/dist/{platform-management-ibuS1as0.mjs → platform-management-6w8-DUjC.mjs} +2 -2
- package/dist/{platform-management-44Bxd3YC.mjs → platform-management-DzKNsMlt.mjs} +1 -1
- package/dist/{platform-recovery-D_KmvdSk.mjs → platform-recovery-Do8VOyDE.mjs} +3 -3
- package/dist/{platform-registry-BJbgZLS1.mjs → platform-registry-QBa4DK32.mjs} +1 -1
- package/dist/{plugin-inference-DsvtJLll.mjs → plugin-inference-BMfKRSqE.mjs} +188 -85
- package/dist/prepare-BZXkjdNe.mjs +2 -0
- package/dist/{prepare-pcWcxSCh.mjs → prepare-C3kt3Rst.mjs} +11 -11
- package/dist/{prepare-_T-Haxrr.mjs → prepare-DyZ-Yok5.mjs} +1 -1
- package/dist/{prerender-render-Cf_WDE9W.mjs → prerender-render-D9qbLs2f.mjs} +1 -1
- package/dist/prerender-render.mjs +1 -1
- package/dist/{preset-Dowh9tTt.mjs → preset-UHj9ARyP.mjs} +4 -4
- package/dist/{project-BEBFDFLz.mjs → project-BuUwfj6f.mjs} +1 -1
- package/dist/{project-CWNIPoXc.mjs → project-C0Fqu05O.mjs} +2 -2
- package/dist/{project-cmd-BuF9doku.mjs → project-cmd-B44I8J_W.mjs} +15 -15
- package/dist/{project-paths-CKQ-Q5JS.mjs → project-paths-GgcMozYz.mjs} +1 -1
- package/dist/{project-team-B1Tia8vd.mjs → project-team-BkbYIsXN.mjs} +4 -4
- package/dist/{project-token-Bwxjf4y6.mjs → project-token-C8xEEQnB.mjs} +4 -4
- package/dist/{project-tsconfig-CwfqUnVp.mjs → project-tsconfig-B8GeM0RM.mjs} +2 -2
- package/dist/{provision-Cck2m3jJ.mjs → provision-BhreDAOS.mjs} +141 -78
- package/dist/provision-DNtrtaVD.mjs +3 -0
- package/dist/{requests-CphRF98D.mjs → requests-DFyhBMaf.mjs} +3 -3
- package/dist/{resolve-project-Xvis70DG.mjs → resolve-project-BG5ORGID.mjs} +1 -1
- package/dist/resolve-project-DtbidV4y.mjs +2 -0
- package/dist/{rollback-BYHJV2yD.mjs → rollback-DHHxXZiS.mjs} +4 -4
- package/dist/{route-types-Id82-veQ.mjs → route-types-Clm4WD0B.mjs} +39 -16
- package/dist/{runner-CQs_cDSG.mjs → runner-B8wXwWlo.mjs} +1 -1
- package/dist/{runner-mysql-1o47achK.mjs → runner-mysql-CEG5JozK.mjs} +1 -1
- package/dist/{runner-mysql-BhwMk2Bm.mjs → runner-mysql-DmWchSWJ.mjs} +1 -1
- package/dist/{runner-BGVsGgkb.mjs → runner-p-dMs2UN.mjs} +3 -3
- package/dist/{runner-pg-D7z01mQS.mjs → runner-pg-Bh4AgZdj.mjs} +1 -1
- package/dist/{runner-pg-CJ_JeGF6.mjs → runner-pg-D4OPlil-.mjs} +1 -1
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +2 -2
- package/dist/runtime/db.mjs +8 -5
- package/dist/runtime/durable.mjs +1 -1
- package/dist/runtime/email/testing.mjs +1 -1
- package/dist/runtime/env-public.mjs +1 -1
- package/dist/runtime/env.d.mts +1 -1
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/kv.mjs +1 -1
- package/dist/runtime/live-server.mjs +38 -23
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/sandbox.mjs +1 -1
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/ws-server.d.mts +1 -1
- package/dist/runtime/ws-server.mjs +1 -1
- package/dist/{scan-DJbooZm2.mjs → scan-4tfN-PSn.mjs} +113 -99
- package/dist/{scan-DdDvRCU1.mjs → scan-ClYmX3sa.mjs} +35 -137
- package/dist/{secret-Rt9c4Ttw.mjs → secret-DN9sSNiV.mjs} +6 -6
- package/dist/{skills-B-690E7h.mjs → skills-O6FUaizK.mjs} +2 -2
- package/dist/sveltekit.mjs +1 -1
- package/dist/{validate-qNhV00PD.mjs → validate-CIUwFpjB.mjs} +2 -2
- package/dist/validate-EKmJWxmy.mjs +2 -0
- package/dist/{wrangler-D01qs6VB.mjs → wrangler-BymcxrRa.mjs} +3 -3
- package/dist/{yarn-pnp-CVEc3gE7.mjs → yarn-pnp-BV4AzNul.mjs} +1 -1
- package/package.json +7 -7
- package/schema.json +18 -0
- package/skills/void/docs/guide/app-types.md +1 -1
- package/skills/void/docs/guide/auth.md +2 -2
- package/skills/void/docs/guide/database/d1.md +6 -0
- package/skills/void/docs/guide/durable-state.md +1 -1
- package/skills/void/docs/guide/edge/rewrites.md +2 -3
- package/skills/void/docs/guide/env-migration.md +1 -1
- package/skills/void/docs/guide/pages-routing/markdown.md +1 -1
- package/skills/void/docs/guide/platform/development/local.md +1 -1
- package/skills/void/docs/guide/platform/installation/prerequisites.md +2 -2
- package/skills/void/docs/guide/platform/installation/setup.md +1 -1
- package/skills/void/docs/guide/server-routing.md +2 -3
- package/skills/void/docs/guide/ssr.md +4 -10
- package/skills/void/docs/guide/websockets.md +1 -1
- package/skills/void/docs/integrations/cloudflare.md +3 -0
- package/skills/void/docs/reference/api.md +1 -1
- package/skills/void/docs/reference/cli.md +10 -3
- package/skills/void/docs/reference/config.md +11 -0
- package/skills/void/docs/reference/resource-inference.md +1 -1
- package/dist/client-DAAivdid.mjs +0 -2
- package/dist/collect-DAUItMDS.mjs +0 -2
- package/dist/config-DDIFxQYx.mjs +0 -2
- package/dist/config-uP7ZDtVZ.mjs +0 -21
- package/dist/deploy-CsjbRNyv.mjs +0 -2
- package/dist/discover-BBzDZe_o.mjs +0 -2
- package/dist/dist-D7-nEOXi.mjs +0 -2
- package/dist/gen-B87rlalt.mjs +0 -2
- package/dist/help-r_vrpH_d.mjs +0 -2
- package/dist/login-Bz0zEPoy.mjs +0 -2
- package/dist/migrate-BXY3B3m7.mjs +0 -2
- package/dist/prepare-D4CkM3_v.mjs +0 -2
- package/dist/provision-CNgEBkVA.mjs +0 -3
- package/dist/resolve-project-BTotl8Nn.mjs +0 -2
- package/dist/validate-DqJ33oHj.mjs +0 -2
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { n as __toESM } from "./rolldown-runtime-DXIUcv95.mjs";
|
|
2
|
-
import { a as join } from "./dist-
|
|
2
|
+
import { a as join } from "./dist-BVqXeR_h.mjs";
|
|
3
3
|
import { c as import_picocolors$1, d as require_picocolors, i as createSpinner, n as cliCommandName, r as cliTitle } from "./output-CCH48AMM.mjs";
|
|
4
4
|
import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
|
|
5
|
-
import { d as openBrowser } from "./auth-
|
|
6
|
-
import { a as listInstallationManifests, d as readInstallationRecoverySecrets, f as readPendingInstallationSecrets, g as savePlatformConnection, h as resolveInstallationManifest, i as latestPlatformWorkerCutoverGeneration, l as platformWorkerSecretUpdateIntentState, n as assertPlatformInstallationSlugAvailable, s as normalizePlatformApiUrl, t as acquirePlatformLifecycleLock, u as promoteInstallationSecrets, v as writeInstallationManifest, y as writePendingInstallationSecrets } from "./platform-registry-
|
|
7
|
-
import { n as ensurePlatformAccessToken } from "./cf-access-
|
|
5
|
+
import { d as openBrowser } from "./auth-DLNN0D3Z.mjs";
|
|
6
|
+
import { a as listInstallationManifests, d as readInstallationRecoverySecrets, f as readPendingInstallationSecrets, g as savePlatformConnection, h as resolveInstallationManifest, i as latestPlatformWorkerCutoverGeneration, l as platformWorkerSecretUpdateIntentState, n as assertPlatformInstallationSlugAvailable, s as normalizePlatformApiUrl, t as acquirePlatformLifecycleLock, u as promoteInstallationSecrets, v as writeInstallationManifest, y as writePendingInstallationSecrets } from "./platform-registry-QBa4DK32.mjs";
|
|
7
|
+
import { n as ensurePlatformAccessToken } from "./cf-access-P0iZnu0q.mjs";
|
|
8
8
|
import { B as text$1, E as confirm, F as password, G as settings, I as select, K as u$1, M as multiselect, N as note, O as intro, P as outro, R as symbol, U as CANCEL_SYMBOL, W as isCancel, g as S_PASSWORD_MASK, i as S_BAR_END, j as log, r as S_BAR } from "./dist-Dn6nn2IU.mjs";
|
|
9
|
-
import { o as resolveWranglerArgv } from "./preset-
|
|
10
|
-
import { c as runCloudflareAuthCommand, n as announceCloudflareLogin } from "./cloudflare-auth-
|
|
11
|
-
import {
|
|
9
|
+
import { o as resolveWranglerArgv } from "./preset-UHj9ARyP.mjs";
|
|
10
|
+
import { c as runCloudflareAuthCommand, n as announceCloudflareLogin } from "./cloudflare-auth-B9jPCkV2.mjs";
|
|
11
|
+
import { _ as resolvePinnedApiBaseUrl, o as createDefaultRunWrangler } from "./provision-BhreDAOS.mjs";
|
|
12
12
|
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
@@ -1499,7 +1499,7 @@ async function verifyInstalledPlatformAccessProtection(input) {
|
|
|
1499
1499
|
}
|
|
1500
1500
|
const existingWorkers = input.plan.actions.filter((action) => action.kind === "worker" && action.action === "update").map((action) => action.name);
|
|
1501
1501
|
if (existingWorkers.length) {
|
|
1502
|
-
const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-
|
|
1502
|
+
const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-Ba1XqGhn.mjs");
|
|
1503
1503
|
await verifyProtectionWorkerOrigins({
|
|
1504
1504
|
request: input.client.request.bind(input.client),
|
|
1505
1505
|
listWorkerDomains: input.client.listWorkerDomains.bind(input.client),
|
|
@@ -1570,8 +1570,8 @@ function verifyExternalPlatformHyperdrive(input) {
|
|
|
1570
1570
|
const { config, expected } = input;
|
|
1571
1571
|
const database = platformDatabaseNameFromOwnerUrl(input.databaseUrl);
|
|
1572
1572
|
const hash = hyperdriveOriginConfigHash(config.origin);
|
|
1573
|
-
if (config.id !== expected.id || config.name !== expected.name || config.origin.host !== expected.host.toLowerCase() || config.origin.user !== expected.user || config.origin.database !== database || input.recordedHash && input.recordedHash !== hash) throw new Error("platform: The
|
|
1574
|
-
if (config.cachingDisabled !== true) throw new Error("platform: Disable SQL result caching on the
|
|
1573
|
+
if (config.id !== expected.id || config.name !== expected.name || config.origin.host !== expected.host.toLowerCase() || config.origin.user !== expected.user || config.origin.database !== database || input.recordedHash && input.recordedHash !== hash) throw new Error("platform: The externally managed Hyperdrive does not match the expected database origin.");
|
|
1574
|
+
if (config.cachingDisabled !== true) throw new Error("platform: Disable SQL result caching on the externally managed Hyperdrive before installing.");
|
|
1575
1575
|
return hash;
|
|
1576
1576
|
}
|
|
1577
1577
|
/** Authentication requires fresh reads; mutate only the installation-owned configuration. */
|
|
@@ -1782,16 +1782,18 @@ async function createPlatformInstallPlan(client, input, existing, options) {
|
|
|
1782
1782
|
const recordedHyperdrive = existing?.resources.find((resource) => resource.key === "hyperdrive");
|
|
1783
1783
|
const externalHyperdriveId = input.externalHyperdrive?.id || (recordedHyperdrive?.ownership === "adopted" ? recordedHyperdrive.id : "");
|
|
1784
1784
|
if (externalHyperdriveId) {
|
|
1785
|
-
if (recordedHyperdrive && (recordedHyperdrive.ownership !== "adopted" || recordedHyperdrive.id !== externalHyperdriveId)) throw new Error("platform: The
|
|
1785
|
+
if (recordedHyperdrive && (recordedHyperdrive.ownership !== "adopted" || recordedHyperdrive.id !== externalHyperdriveId)) throw new Error("platform: The externally managed Hyperdrive differs from this installation.");
|
|
1786
1786
|
const remote = hyperdrives.find((resource) => resource.id === externalHyperdriveId);
|
|
1787
|
-
|
|
1787
|
+
const selectedName = input.externalHyperdrive?.name;
|
|
1788
|
+
const recordedName = recordedHyperdrive?.name;
|
|
1789
|
+
if (!remote || selectedName && remote.name !== selectedName || recordedName && remote.name !== recordedName) throw new Error(`platform: Externally managed Hyperdrive ${JSON.stringify(externalHyperdriveId)} must exist with its selected name.`);
|
|
1788
1790
|
actions.push({
|
|
1789
1791
|
action: recordedHyperdrive ? "reuse" : "adopt",
|
|
1790
1792
|
id: remote.id,
|
|
1791
1793
|
key: "hyperdrive",
|
|
1792
1794
|
kind: "hyperdrive",
|
|
1793
1795
|
name: remote.name,
|
|
1794
|
-
reason: recordedHyperdrive ? "Reuse the recorded
|
|
1796
|
+
reason: recordedHyperdrive ? "Reuse the recorded externally managed Hyperdrive." : "Use the externally managed Hyperdrive without taking ownership."
|
|
1795
1797
|
});
|
|
1796
1798
|
} else addNamedPlan(actions, existing, "hyperdrive", "hyperdrive", names.hyperdrive, hyperdrives.filter((resource) => resource.name === names.hyperdrive), "reuse", options, remoteOwnership);
|
|
1797
1799
|
for (const [key, name] of [
|
|
@@ -2427,6 +2429,204 @@ function parseWorkerSecretUpdateIntent(value) {
|
|
|
2427
2429
|
function sanitizeWorkerSecretUpdates(updates) {
|
|
2428
2430
|
return Object.fromEntries(Object.entries(updates ?? {}).filter(([name, value]) => PLATFORM_WORKER_SECRET_UPDATE_NAMES.includes(name) && typeof value === "string" && value !== ""));
|
|
2429
2431
|
}
|
|
2432
|
+
async function reconcilePlatformInstallationResources(manifest, plan, secrets, zoneId, externalHyperdriveOriginHash, dependencies, now, writeRemoteInstallationCheckpoint, onManifestChange) {
|
|
2433
|
+
for (const action of plan.actions.filter((entry) => entry.key !== "routing-kv" && entry.kind !== "zone" && entry.kind !== "worker")) {
|
|
2434
|
+
const retainedManifest = retainReplacedInstallationResource(manifest, action, now());
|
|
2435
|
+
if (retainedManifest !== manifest) {
|
|
2436
|
+
manifest = retainedManifest;
|
|
2437
|
+
onManifestChange(manifest);
|
|
2438
|
+
writeInstallationManifest(manifest);
|
|
2439
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2440
|
+
}
|
|
2441
|
+
if (action.action === "adopt") {
|
|
2442
|
+
if (!action.id) throw new Error(`platform: Adopted ${action.kind} ${action.name} has no id.`);
|
|
2443
|
+
manifest = recordAdoptionIntent(manifest, action, action.id, now());
|
|
2444
|
+
onManifestChange(manifest);
|
|
2445
|
+
writeInstallationManifest(manifest);
|
|
2446
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2447
|
+
manifest = recordResource(manifest, action, action.id, "adopted", now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : void 0);
|
|
2448
|
+
onManifestChange(manifest);
|
|
2449
|
+
writeInstallationManifest(manifest);
|
|
2450
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2451
|
+
continue;
|
|
2452
|
+
}
|
|
2453
|
+
if (action.action === "reuse") {
|
|
2454
|
+
if (action.id && (action.kind === "hyperdrive" || !manifest.resources.some((resource) => resource.key === action.key))) {
|
|
2455
|
+
manifest = recordResource(manifest, action, action.id, void 0, now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : void 0);
|
|
2456
|
+
onManifestChange(manifest);
|
|
2457
|
+
writeInstallationManifest(manifest);
|
|
2458
|
+
await writeR2OwnershipMarkerIfNeeded(dependencies.client, plan, manifest, action);
|
|
2459
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2460
|
+
}
|
|
2461
|
+
continue;
|
|
2462
|
+
}
|
|
2463
|
+
manifest = recordProvisionIntent(manifest, action, now());
|
|
2464
|
+
onManifestChange(manifest);
|
|
2465
|
+
writeInstallationManifest(manifest);
|
|
2466
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2467
|
+
const resource = await createResource(dependencies.client, plan, action, secrets.databaseUrl, zoneId);
|
|
2468
|
+
manifest = recordResource(manifest, action, resource.id, "created", now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : resource.fingerprint);
|
|
2469
|
+
onManifestChange(manifest);
|
|
2470
|
+
writeInstallationManifest(manifest);
|
|
2471
|
+
await writeR2OwnershipMarkerIfNeeded(dependencies.client, plan, manifest, action);
|
|
2472
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2473
|
+
}
|
|
2474
|
+
return manifest;
|
|
2475
|
+
}
|
|
2476
|
+
async function preparePlatformDatabaseSchema(manifest, runtime, runtimeDirectory, sourcePlatformVersion, hadPriorWorkers, plan, secrets, dependencies, releaseDatabaseLock, now, writeRemoteInstallationCheckpoint, onManifestChange) {
|
|
2477
|
+
dependencies.onProgress?.("Checking the platform database schema");
|
|
2478
|
+
const rollbackDatabase = dependencies.databaseRollbackSource;
|
|
2479
|
+
const migrationStep = `database-schema:${runtime.database.schemaDigest}`;
|
|
2480
|
+
if (rollbackDatabase) {
|
|
2481
|
+
const verifyDatabase = releaseDatabaseLock.verifyDatabase;
|
|
2482
|
+
if (!verifyDatabase) throw new Error("platform: The PostgreSQL lifecycle lock cannot verify the forward-only rollback schema.");
|
|
2483
|
+
await verifyDatabase(rollbackDatabase.directory, rollbackDatabase.manifest.database);
|
|
2484
|
+
manifest = {
|
|
2485
|
+
...manifest,
|
|
2486
|
+
databaseSchemaDigest: rollbackDatabase.manifest.database.schemaDigest,
|
|
2487
|
+
updatedAt: now()
|
|
2488
|
+
};
|
|
2489
|
+
onManifestChange(manifest);
|
|
2490
|
+
writeInstallationManifest(manifest);
|
|
2491
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2492
|
+
} else if (!manifest.steps.some((step) => step.key === migrationStep)) {
|
|
2493
|
+
dependencies.onProgress?.("Applying platform database migrations");
|
|
2494
|
+
const legacyMigrationStep = `database-migrations:${runtime.database.journalSha256}`;
|
|
2495
|
+
if (dependencies.migrateDatabase) {
|
|
2496
|
+
if (!manifest.steps.some((step) => step.key === legacyMigrationStep)) await dependencies.migrateDatabase(secrets.databaseUrl, join(runtimeDirectory, "drizzle"));
|
|
2497
|
+
} else {
|
|
2498
|
+
const prepareDatabase = dependencies.prepareDatabase ?? releaseDatabaseLock.prepareDatabase;
|
|
2499
|
+
if (!prepareDatabase) throw new Error("platform: The PostgreSQL lifecycle lock cannot verify or migrate this database.");
|
|
2500
|
+
await prepareDatabase(runtimeDirectory, runtime.database, sourcePlatformVersion, hadPriorWorkers);
|
|
2501
|
+
}
|
|
2502
|
+
manifest = recordInstallationStep(manifest, {
|
|
2503
|
+
completedAt: now(),
|
|
2504
|
+
key: migrationStep,
|
|
2505
|
+
resultHash: runtime.database.schemaDigest
|
|
2506
|
+
}, now());
|
|
2507
|
+
manifest = {
|
|
2508
|
+
...manifest,
|
|
2509
|
+
databaseSchemaDigest: runtime.database.schemaDigest,
|
|
2510
|
+
updatedAt: now()
|
|
2511
|
+
};
|
|
2512
|
+
onManifestChange(manifest);
|
|
2513
|
+
writeInstallationManifest(manifest);
|
|
2514
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2515
|
+
} else if (releaseDatabaseLock.verifyDatabase) {
|
|
2516
|
+
await releaseDatabaseLock.verifyDatabase(runtimeDirectory, runtime.database);
|
|
2517
|
+
if (manifest.databaseSchemaDigest !== runtime.database.schemaDigest) {
|
|
2518
|
+
manifest = {
|
|
2519
|
+
...manifest,
|
|
2520
|
+
databaseSchemaDigest: runtime.database.schemaDigest,
|
|
2521
|
+
updatedAt: now()
|
|
2522
|
+
};
|
|
2523
|
+
onManifestChange(manifest);
|
|
2524
|
+
writeInstallationManifest(manifest);
|
|
2525
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
return manifest;
|
|
2529
|
+
}
|
|
2530
|
+
async function recoverInterruptedPlatformWorkerCutover(manifest, interruptedCutover, workerActions, configs, previousConfigs, plan, dependencies, ids, zoneId, previousPublicEndpoints, hasEmailGatewayArtifact, runPinnedPlatformWrangler, now, writeRemoteInstallationCheckpoint, onManifestChange) {
|
|
2531
|
+
if (interruptedCutover) {
|
|
2532
|
+
for (const key of [...interruptedCutover.staged.keys()].reverse()) {
|
|
2533
|
+
const snapshot = interruptedCutover.staged.get(key);
|
|
2534
|
+
const preservedRoutes = dependencies.recoverWorkerCutover ? [] : await inventoryUnmanagedPlatformWorkerTraffic(dependencies.client, plan, snapshot.workerName);
|
|
2535
|
+
const recoveryConfig = mergePlatformWorkerTrafficConfig({
|
|
2536
|
+
...configs[key],
|
|
2537
|
+
name: snapshot.workerName
|
|
2538
|
+
}, preservedRoutes);
|
|
2539
|
+
const previousRecoveryConfig = mergePlatformWorkerTrafficConfig({
|
|
2540
|
+
...previousConfigs[key],
|
|
2541
|
+
name: snapshot.workerName
|
|
2542
|
+
}, preservedRoutes);
|
|
2543
|
+
if (dependencies.recoverWorkerCutover) await dependencies.recoverWorkerCutover({
|
|
2544
|
+
key,
|
|
2545
|
+
preserveCustomDomains: interruptedCutover.unsafeTraffic.has(key),
|
|
2546
|
+
previousVersionId: snapshot.previousVersionId,
|
|
2547
|
+
stagedVersionId: snapshot.stagedVersionId,
|
|
2548
|
+
workerName: snapshot.workerName
|
|
2549
|
+
});
|
|
2550
|
+
else {
|
|
2551
|
+
const recoveryTraffic = isolatePlatformWorkerCustomDomains(recoveryConfig);
|
|
2552
|
+
const previousRecoveryTraffic = isolatePlatformWorkerCustomDomains(previousRecoveryConfig);
|
|
2553
|
+
await rollbackPlatformWorker({
|
|
2554
|
+
accountId: plan.account.id,
|
|
2555
|
+
activatedDeploymentId: null,
|
|
2556
|
+
activatedVersionId: snapshot.stagedVersionId,
|
|
2557
|
+
config: recoveryConfig,
|
|
2558
|
+
nextTriggers: readTriggerConfigFromObject(recoveryTraffic.wranglerConfig),
|
|
2559
|
+
previousConfig: previousRecoveryConfig,
|
|
2560
|
+
previousCustomDomains: previousRecoveryTraffic.customDomains,
|
|
2561
|
+
previousDeployment: null,
|
|
2562
|
+
previousTriggers: mergePreservedTriggerRoutes(withoutPlatformCustomDomainTriggers(snapshot.previousTriggers), preservedRoutes),
|
|
2563
|
+
previousVersionId: snapshot.previousVersionId,
|
|
2564
|
+
preserveCustomDomains: interruptedCutover.unsafeTraffic.has(key),
|
|
2565
|
+
inspectNewWorker: () => inspectNewPlatformWorker(dependencies.client, plan.account.id, manifest, key === "emailGateway" ? "email-gateway-worker" : `${key}-worker`, snapshot.workerName),
|
|
2566
|
+
removeCustomDomains: async () => {
|
|
2567
|
+
if (!dependencies.client.removeRoutes) throw new Error("platform: Cloudflare route removal is unavailable.");
|
|
2568
|
+
await dependencies.client.removeRoutes(plan.account.id, zoneId, trackedPlatformWorkerTraffic(manifest, /* @__PURE__ */ new Set([snapshot.workerName])));
|
|
2569
|
+
},
|
|
2570
|
+
publishCustomDomains: (workerName, origins) => publishPlatformWorkerCustomDomains(dependencies.client, plan.account.id, workerName, origins),
|
|
2571
|
+
retainNewWorker: async () => {
|
|
2572
|
+
await dependencies.client.putKvValue(plan.account.id, requireId(ids, "routing-kv"), PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
|
|
2573
|
+
},
|
|
2574
|
+
runner: runPinnedPlatformWrangler,
|
|
2575
|
+
workerExisted: snapshot.previousVersionId !== null,
|
|
2576
|
+
workerName: snapshot.workerName
|
|
2577
|
+
});
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
manifest = recordWorkerCutoverResolution(manifest, interruptedCutover.generation, "restored", now());
|
|
2581
|
+
manifest = recordWorkerTrafficState(manifest, interruptedCutover.generation, previousPublicEndpoints && interruptedCutover.unsafeTraffic.size === 0, now());
|
|
2582
|
+
let retainedNewWorker = false;
|
|
2583
|
+
for (const [, snapshot] of interruptedCutover.staged) {
|
|
2584
|
+
if (snapshot.previousVersionId !== null) continue;
|
|
2585
|
+
retainedNewWorker = true;
|
|
2586
|
+
}
|
|
2587
|
+
onManifestChange(manifest);
|
|
2588
|
+
writeInstallationManifest(manifest);
|
|
2589
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2590
|
+
if (retainedNewWorker) {
|
|
2591
|
+
if (!dependencies.replanWorkers) throw new Error("platform: Recovering retained Workers requires a fresh Cloudflare installation plan.");
|
|
2592
|
+
workerActions = validateReplannedWorkerActions(plan, manifest, await dependencies.replanWorkers(manifest)).filter((action) => hasEmailGatewayArtifact || action.key !== "email-gateway-worker");
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
return {
|
|
2596
|
+
manifest,
|
|
2597
|
+
workerActions
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
async function recoverFailedPlatformInstallation(error, manifest, plan, dependencies, workerTrafficGuarded, workerDeploymentCommitted, workerRollbacks, authenticationEnforcementActive, authenticationProtocolTransition, workerCutoverGeneration, previousPublicEndpoints, now, writeRemoteInstallationCheckpoint) {
|
|
2601
|
+
let failure = error;
|
|
2602
|
+
const currentWorkerRecoveryIncomplete = error instanceof PlatformWorkerRecoveryIncompleteError;
|
|
2603
|
+
if (workerTrafficGuarded) try {
|
|
2604
|
+
await dependencies.client.putKvValue(plan.account.id, requireId(Object.fromEntries(manifest.resources.map((resource) => [resource.key, resource.id])), "routing-kv"), PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
|
|
2605
|
+
} catch (guardError) {
|
|
2606
|
+
failure = new Error(`platform: ${errorMessage(error)} The installation also failed to retain its routing safety gate: ${errorMessage(guardError)}`, { cause: error });
|
|
2607
|
+
}
|
|
2608
|
+
if (!workerDeploymentCommitted && workerRollbacks.length > 0 && !(authenticationEnforcementActive && authenticationProtocolTransition)) {
|
|
2609
|
+
const rollbackFailures = [];
|
|
2610
|
+
for (const rollback of workerRollbacks.reverse()) try {
|
|
2611
|
+
await rollback();
|
|
2612
|
+
} catch (rollbackError) {
|
|
2613
|
+
rollbackFailures.push(errorMessage(rollbackError));
|
|
2614
|
+
}
|
|
2615
|
+
workerRollbacks = [];
|
|
2616
|
+
if (rollbackFailures.length > 0 || currentWorkerRecoveryIncomplete) failure = new Error(rollbackFailures.length > 0 ? `platform: ${errorMessage(error)} Automatic Worker rollback was incomplete: ${rollbackFailures.join("; ")} Inspect the installation before retrying.` : `platform: ${errorMessage(error)} The current Worker rollback was incomplete. The cutover remains unresolved and will be recovered on retry.`, { cause: error });
|
|
2617
|
+
else if (workerCutoverGeneration > 0) {
|
|
2618
|
+
manifest = recordWorkerCutoverResolution(manifest, workerCutoverGeneration, "restored", now());
|
|
2619
|
+
manifest = recordWorkerTrafficState(manifest, workerCutoverGeneration, previousPublicEndpoints, now());
|
|
2620
|
+
writeInstallationManifest(manifest);
|
|
2621
|
+
}
|
|
2622
|
+
} else if (authenticationEnforcementActive && authenticationProtocolTransition) workerRollbacks = [];
|
|
2623
|
+
if (manifest.status !== "failed" && manifest.status !== "uninstalled") try {
|
|
2624
|
+
manifest = transitionInstallation(manifest, "failed", now());
|
|
2625
|
+
writeInstallationManifest(manifest);
|
|
2626
|
+
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2627
|
+
} catch {}
|
|
2628
|
+
return failure;
|
|
2629
|
+
}
|
|
2430
2630
|
async function installPlatform(plan, secrets, existing, dependencies) {
|
|
2431
2631
|
if (plan.actions.some((action) => action.action === "inspect")) throw new Error("platform: AI Gateway access must be verified before provisioning. Provide AI Gateway: Edit on the runtime token, then retry.");
|
|
2432
2632
|
const now = dependencies.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
@@ -2457,8 +2657,8 @@ async function installPlatform(plan, secrets, existing, dependencies) {
|
|
|
2457
2657
|
const recordedHyperdrive = existing?.resources.find((resource) => resource.key === "hyperdrive");
|
|
2458
2658
|
let externalHyperdriveOriginHash;
|
|
2459
2659
|
if (hyperdriveAction && (hyperdriveAction.action === "adopt" || recordedHyperdrive?.ownership === "adopted")) {
|
|
2460
|
-
if (!hyperdriveAction.id) throw new Error("platform: The
|
|
2461
|
-
if (!plan.externalHyperdrive && !recordedHyperdrive) throw new Error("platform: The
|
|
2660
|
+
if (!hyperdriveAction.id) throw new Error("platform: The externally managed Hyperdrive has no ID.");
|
|
2661
|
+
if (!plan.externalHyperdrive && !recordedHyperdrive) throw new Error("platform: The externally managed Hyperdrive origin must be specified.");
|
|
2462
2662
|
const live = await dependencies.client.getHyperdriveConfig(plan.account.id, hyperdriveAction.id);
|
|
2463
2663
|
externalHyperdriveOriginHash = verifyExternalPlatformHyperdrive({
|
|
2464
2664
|
config: live,
|
|
@@ -2747,93 +2947,16 @@ async function installPlatform(plan, secrets, existing, dependencies) {
|
|
|
2747
2947
|
}
|
|
2748
2948
|
}
|
|
2749
2949
|
const zoneId = zone?.id ?? "";
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
manifest = retainedManifest;
|
|
2754
|
-
writeInstallationManifest(manifest);
|
|
2755
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2756
|
-
}
|
|
2757
|
-
if (action.action === "adopt") {
|
|
2758
|
-
if (!action.id) throw new Error(`platform: Adopted ${action.kind} ${action.name} has no id.`);
|
|
2759
|
-
manifest = recordAdoptionIntent(manifest, action, action.id, now());
|
|
2760
|
-
writeInstallationManifest(manifest);
|
|
2761
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2762
|
-
manifest = recordResource(manifest, action, action.id, "adopted", now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : void 0);
|
|
2763
|
-
writeInstallationManifest(manifest);
|
|
2764
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2765
|
-
continue;
|
|
2766
|
-
}
|
|
2767
|
-
if (action.action === "reuse") {
|
|
2768
|
-
if (action.id && (action.kind === "hyperdrive" || !manifest.resources.some((resource) => resource.key === action.key))) {
|
|
2769
|
-
manifest = recordResource(manifest, action, action.id, void 0, now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : void 0);
|
|
2770
|
-
writeInstallationManifest(manifest);
|
|
2771
|
-
await writeR2OwnershipMarkerIfNeeded(dependencies.client, plan, manifest, action);
|
|
2772
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2773
|
-
}
|
|
2774
|
-
continue;
|
|
2775
|
-
}
|
|
2776
|
-
manifest = recordProvisionIntent(manifest, action, now());
|
|
2777
|
-
writeInstallationManifest(manifest);
|
|
2778
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2779
|
-
const resource = await createResource(dependencies.client, plan, action, secrets.databaseUrl, zoneId);
|
|
2780
|
-
manifest = recordResource(manifest, action, resource.id, "created", now(), secrets.databaseUrl, action.kind === "hyperdrive" ? externalHyperdriveOriginHash : resource.fingerprint);
|
|
2781
|
-
writeInstallationManifest(manifest);
|
|
2782
|
-
await writeR2OwnershipMarkerIfNeeded(dependencies.client, plan, manifest, action);
|
|
2783
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2784
|
-
}
|
|
2950
|
+
manifest = await reconcilePlatformInstallationResources(manifest, plan, secrets, zoneId, externalHyperdriveOriginHash, dependencies, now, writeRemoteInstallationCheckpoint, (next) => {
|
|
2951
|
+
manifest = next;
|
|
2952
|
+
});
|
|
2785
2953
|
dependencies.onProgress?.("Verifying uncached authentication database reads");
|
|
2786
2954
|
const authenticationDatabase = manifest.resources.find((resource) => resource.key === "hyperdrive");
|
|
2787
2955
|
if (!authenticationDatabase) throw new Error("platform: The authentication database resource is missing.");
|
|
2788
2956
|
await verifyPlatformAuthenticationDatabase(dependencies.client, plan.account.id, authenticationDatabase, secrets.databaseUrl);
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
if (rollbackDatabase) {
|
|
2793
|
-
const verifyDatabase = releaseDatabaseLock.verifyDatabase;
|
|
2794
|
-
if (!verifyDatabase) throw new Error("platform: The PostgreSQL lifecycle lock cannot verify the forward-only rollback schema.");
|
|
2795
|
-
await verifyDatabase(rollbackDatabase.directory, rollbackDatabase.manifest.database);
|
|
2796
|
-
manifest = {
|
|
2797
|
-
...manifest,
|
|
2798
|
-
databaseSchemaDigest: rollbackDatabase.manifest.database.schemaDigest,
|
|
2799
|
-
updatedAt: now()
|
|
2800
|
-
};
|
|
2801
|
-
writeInstallationManifest(manifest);
|
|
2802
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2803
|
-
} else if (!manifest.steps.some((step) => step.key === migrationStep)) {
|
|
2804
|
-
dependencies.onProgress?.("Applying platform database migrations");
|
|
2805
|
-
const legacyMigrationStep = `database-migrations:${runtime.database.journalSha256}`;
|
|
2806
|
-
if (dependencies.migrateDatabase) {
|
|
2807
|
-
if (!manifest.steps.some((step) => step.key === legacyMigrationStep)) await dependencies.migrateDatabase(secrets.databaseUrl, join(runtimeDirectory, "drizzle"));
|
|
2808
|
-
} else {
|
|
2809
|
-
const prepareDatabase = dependencies.prepareDatabase ?? releaseDatabaseLock.prepareDatabase;
|
|
2810
|
-
if (!prepareDatabase) throw new Error("platform: The PostgreSQL lifecycle lock cannot verify or migrate this database.");
|
|
2811
|
-
await prepareDatabase(runtimeDirectory, runtime.database, sourcePlatformVersion, hadPriorWorkers);
|
|
2812
|
-
}
|
|
2813
|
-
manifest = recordInstallationStep(manifest, {
|
|
2814
|
-
completedAt: now(),
|
|
2815
|
-
key: migrationStep,
|
|
2816
|
-
resultHash: runtime.database.schemaDigest
|
|
2817
|
-
}, now());
|
|
2818
|
-
manifest = {
|
|
2819
|
-
...manifest,
|
|
2820
|
-
databaseSchemaDigest: runtime.database.schemaDigest,
|
|
2821
|
-
updatedAt: now()
|
|
2822
|
-
};
|
|
2823
|
-
writeInstallationManifest(manifest);
|
|
2824
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2825
|
-
} else if (releaseDatabaseLock.verifyDatabase) {
|
|
2826
|
-
await releaseDatabaseLock.verifyDatabase(runtimeDirectory, runtime.database);
|
|
2827
|
-
if (manifest.databaseSchemaDigest !== runtime.database.schemaDigest) {
|
|
2828
|
-
manifest = {
|
|
2829
|
-
...manifest,
|
|
2830
|
-
databaseSchemaDigest: runtime.database.schemaDigest,
|
|
2831
|
-
updatedAt: now()
|
|
2832
|
-
};
|
|
2833
|
-
writeInstallationManifest(manifest);
|
|
2834
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2835
|
-
}
|
|
2836
|
-
}
|
|
2957
|
+
manifest = await preparePlatformDatabaseSchema(manifest, runtime, runtimeDirectory, sourcePlatformVersion, hadPriorWorkers, plan, secrets, dependencies, releaseDatabaseLock, now, writeRemoteInstallationCheckpoint, (next) => {
|
|
2958
|
+
manifest = next;
|
|
2959
|
+
});
|
|
2837
2960
|
dependencies.onProgress?.("Checking platform safety");
|
|
2838
2961
|
const targetSandboxDrainProtocol = runtime.safetyProtocols?.sandboxDrain ?? 0;
|
|
2839
2962
|
const prepareSandboxDrain = dependencies.prepareSandboxDrain ?? releaseDatabaseLock.prepareSandboxDrain;
|
|
@@ -2937,69 +3060,9 @@ async function installPlatform(plan, secrets, existing, dependencies) {
|
|
|
2937
3060
|
});
|
|
2938
3061
|
const managedRoutes = platformManagedWorkerTraffic(plan.deployment).routes;
|
|
2939
3062
|
let workerActions = plan.actions.filter((action) => action.kind === "worker" && (hasEmailGatewayArtifact || action.key !== "email-gateway-worker"));
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
const preservedRoutes = dependencies.recoverWorkerCutover ? [] : await inventoryUnmanagedPlatformWorkerTraffic(dependencies.client, plan, snapshot.workerName);
|
|
2944
|
-
const recoveryConfig = mergePlatformWorkerTrafficConfig({
|
|
2945
|
-
...configs[key],
|
|
2946
|
-
name: snapshot.workerName
|
|
2947
|
-
}, preservedRoutes);
|
|
2948
|
-
const previousRecoveryConfig = mergePlatformWorkerTrafficConfig({
|
|
2949
|
-
...previousConfigs[key],
|
|
2950
|
-
name: snapshot.workerName
|
|
2951
|
-
}, preservedRoutes);
|
|
2952
|
-
if (dependencies.recoverWorkerCutover) await dependencies.recoverWorkerCutover({
|
|
2953
|
-
key,
|
|
2954
|
-
preserveCustomDomains: interruptedCutover.unsafeTraffic.has(key),
|
|
2955
|
-
previousVersionId: snapshot.previousVersionId,
|
|
2956
|
-
stagedVersionId: snapshot.stagedVersionId,
|
|
2957
|
-
workerName: snapshot.workerName
|
|
2958
|
-
});
|
|
2959
|
-
else {
|
|
2960
|
-
const recoveryTraffic = isolatePlatformWorkerCustomDomains(recoveryConfig);
|
|
2961
|
-
const previousRecoveryTraffic = isolatePlatformWorkerCustomDomains(previousRecoveryConfig);
|
|
2962
|
-
await rollbackPlatformWorker({
|
|
2963
|
-
accountId: plan.account.id,
|
|
2964
|
-
activatedDeploymentId: null,
|
|
2965
|
-
activatedVersionId: snapshot.stagedVersionId,
|
|
2966
|
-
config: recoveryConfig,
|
|
2967
|
-
nextTriggers: readTriggerConfigFromObject(recoveryTraffic.wranglerConfig),
|
|
2968
|
-
previousConfig: previousRecoveryConfig,
|
|
2969
|
-
previousCustomDomains: previousRecoveryTraffic.customDomains,
|
|
2970
|
-
previousDeployment: null,
|
|
2971
|
-
previousTriggers: mergePreservedTriggerRoutes(withoutPlatformCustomDomainTriggers(snapshot.previousTriggers), preservedRoutes),
|
|
2972
|
-
previousVersionId: snapshot.previousVersionId,
|
|
2973
|
-
preserveCustomDomains: interruptedCutover.unsafeTraffic.has(key),
|
|
2974
|
-
inspectNewWorker: () => inspectNewPlatformWorker(dependencies.client, plan.account.id, manifest, key === "emailGateway" ? "email-gateway-worker" : `${key}-worker`, snapshot.workerName),
|
|
2975
|
-
removeCustomDomains: async () => {
|
|
2976
|
-
if (!dependencies.client.removeRoutes) throw new Error("platform: Cloudflare route removal is unavailable.");
|
|
2977
|
-
await dependencies.client.removeRoutes(plan.account.id, zoneId, trackedPlatformWorkerTraffic(manifest, /* @__PURE__ */ new Set([snapshot.workerName])));
|
|
2978
|
-
},
|
|
2979
|
-
publishCustomDomains: (workerName, origins) => publishPlatformWorkerCustomDomains(dependencies.client, plan.account.id, workerName, origins),
|
|
2980
|
-
retainNewWorker: async () => {
|
|
2981
|
-
await dependencies.client.putKvValue(plan.account.id, requireId(ids, "routing-kv"), PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
|
|
2982
|
-
},
|
|
2983
|
-
runner: runPinnedPlatformWrangler,
|
|
2984
|
-
workerExisted: snapshot.previousVersionId !== null,
|
|
2985
|
-
workerName: snapshot.workerName
|
|
2986
|
-
});
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
manifest = recordWorkerCutoverResolution(manifest, interruptedCutover.generation, "restored", now());
|
|
2990
|
-
manifest = recordWorkerTrafficState(manifest, interruptedCutover.generation, previousPublicEndpoints && interruptedCutover.unsafeTraffic.size === 0, now());
|
|
2991
|
-
let retainedNewWorker = false;
|
|
2992
|
-
for (const [, snapshot] of interruptedCutover.staged) {
|
|
2993
|
-
if (snapshot.previousVersionId !== null) continue;
|
|
2994
|
-
retainedNewWorker = true;
|
|
2995
|
-
}
|
|
2996
|
-
writeInstallationManifest(manifest);
|
|
2997
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
2998
|
-
if (retainedNewWorker) {
|
|
2999
|
-
if (!dependencies.replanWorkers) throw new Error("platform: Recovering retained Workers requires a fresh Cloudflare installation plan.");
|
|
3000
|
-
workerActions = validateReplannedWorkerActions(plan, manifest, await dependencies.replanWorkers(manifest)).filter((action) => hasEmailGatewayArtifact || action.key !== "email-gateway-worker");
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3063
|
+
({manifest, workerActions} = await recoverInterruptedPlatformWorkerCutover(manifest, interruptedCutover, workerActions, configs, previousConfigs, plan, dependencies, ids, zoneId, previousPublicEndpoints, hasEmailGatewayArtifact, runPinnedPlatformWrangler, now, writeRemoteInstallationCheckpoint, (next) => {
|
|
3064
|
+
manifest = next;
|
|
3065
|
+
}));
|
|
3003
3066
|
workerCutoverGeneration = nextWorkerCutoverGeneration(manifest);
|
|
3004
3067
|
if (workerSecretUpdateIntent) {
|
|
3005
3068
|
manifest = recordWorkerSecretUpdateState(manifest, workerCutoverGeneration, "pending", workerSecretUpdateIntent.id, now());
|
|
@@ -3310,34 +3373,7 @@ async function installPlatform(plan, secrets, existing, dependencies) {
|
|
|
3310
3373
|
zoneNameServers: zone?.nameServers ?? []
|
|
3311
3374
|
};
|
|
3312
3375
|
} catch (error) {
|
|
3313
|
-
|
|
3314
|
-
const currentWorkerRecoveryIncomplete = error instanceof PlatformWorkerRecoveryIncompleteError;
|
|
3315
|
-
if (workerTrafficGuarded) try {
|
|
3316
|
-
await dependencies.client.putKvValue(plan.account.id, requireId(Object.fromEntries(manifest.resources.map((resource) => [resource.key, resource.id])), "routing-kv"), PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
|
|
3317
|
-
} catch (guardError) {
|
|
3318
|
-
failure = new Error(`platform: ${errorMessage(error)} The installation also failed to retain its routing safety gate: ${errorMessage(guardError)}`, { cause: error });
|
|
3319
|
-
}
|
|
3320
|
-
if (!workerDeploymentCommitted && workerRollbacks.length > 0 && !(authenticationEnforcementActive && authenticationProtocolTransition)) {
|
|
3321
|
-
const rollbackFailures = [];
|
|
3322
|
-
for (const rollback of workerRollbacks.reverse()) try {
|
|
3323
|
-
await rollback();
|
|
3324
|
-
} catch (rollbackError) {
|
|
3325
|
-
rollbackFailures.push(errorMessage(rollbackError));
|
|
3326
|
-
}
|
|
3327
|
-
workerRollbacks = [];
|
|
3328
|
-
if (rollbackFailures.length > 0 || currentWorkerRecoveryIncomplete) failure = new Error(rollbackFailures.length > 0 ? `platform: ${errorMessage(error)} Automatic Worker rollback was incomplete: ${rollbackFailures.join("; ")} Inspect the installation before retrying.` : `platform: ${errorMessage(error)} The current Worker rollback was incomplete. The cutover remains unresolved and will be recovered on retry.`, { cause: error });
|
|
3329
|
-
else if (workerCutoverGeneration > 0) {
|
|
3330
|
-
manifest = recordWorkerCutoverResolution(manifest, workerCutoverGeneration, "restored", now());
|
|
3331
|
-
manifest = recordWorkerTrafficState(manifest, workerCutoverGeneration, previousPublicEndpoints, now());
|
|
3332
|
-
writeInstallationManifest(manifest);
|
|
3333
|
-
}
|
|
3334
|
-
} else if (authenticationEnforcementActive && authenticationProtocolTransition) workerRollbacks = [];
|
|
3335
|
-
if (manifest.status !== "failed" && manifest.status !== "uninstalled") try {
|
|
3336
|
-
manifest = transitionInstallation(manifest, "failed", now());
|
|
3337
|
-
writeInstallationManifest(manifest);
|
|
3338
|
-
await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
|
|
3339
|
-
} catch {}
|
|
3340
|
-
throw failure;
|
|
3376
|
+
throw await recoverFailedPlatformInstallation(error, manifest, plan, dependencies, workerTrafficGuarded, workerDeploymentCommitted, workerRollbacks, authenticationEnforcementActive, authenticationProtocolTransition, workerCutoverGeneration, previousPublicEndpoints, now, writeRemoteInstallationCheckpoint);
|
|
3341
3377
|
} finally {
|
|
3342
3378
|
await releaseDatabaseLock();
|
|
3343
3379
|
}
|
|
@@ -5532,14 +5568,14 @@ function resolvePlatformInstallDatabaseUrl(checkpoint, manifest = null) {
|
|
|
5532
5568
|
}
|
|
5533
5569
|
async function runPlatformLifecycleCommand(args) {
|
|
5534
5570
|
if (args.subcommand === "domain") {
|
|
5535
|
-
const { runPlatformDomainCommand } = await import("./platform-domain-
|
|
5571
|
+
const { runPlatformDomainCommand } = await import("./platform-domain-j9YCXRm6.mjs");
|
|
5536
5572
|
await runPlatformDomainCommand(args);
|
|
5537
5573
|
return;
|
|
5538
5574
|
}
|
|
5539
5575
|
if (args.subcommand === "discover") {
|
|
5540
5576
|
const client = new PlatformCloudflareClient((await resolvePlatformCloudflareCredential()).token);
|
|
5541
5577
|
const accountId = await selectAccount(await readAccounts(client), args.account);
|
|
5542
|
-
const { recoverPlatformInstallations } = await import("./platform-recovery-
|
|
5578
|
+
const { recoverPlatformInstallations } = await import("./platform-recovery-Do8VOyDE.mjs");
|
|
5543
5579
|
const recovered = await recoverPlatformInstallations(client, accountId, void 0, args.selector);
|
|
5544
5580
|
if (recovered.length === 0) {
|
|
5545
5581
|
log.info(`No recoverable Void platform installations were found in ${accountId}.`);
|
|
@@ -5549,7 +5585,7 @@ async function runPlatformLifecycleCommand(args) {
|
|
|
5549
5585
|
return;
|
|
5550
5586
|
}
|
|
5551
5587
|
if (args.subcommand !== "install") {
|
|
5552
|
-
const { runInstalledPlatformCommand } = await import("./platform-management-
|
|
5588
|
+
const { runInstalledPlatformCommand } = await import("./platform-management-DzKNsMlt.mjs");
|
|
5553
5589
|
await runInstalledPlatformCommand(args);
|
|
5554
5590
|
return;
|
|
5555
5591
|
}
|
|
@@ -5709,48 +5745,60 @@ async function runPlatformLifecycleCommand(args) {
|
|
|
5709
5745
|
user: externalHyperdriveUser
|
|
5710
5746
|
} : void 0;
|
|
5711
5747
|
if (!externalHyperdrive && process.stdin.isTTY && (!existing || isPlatformSetupDraft(existing)) && !existing?.resources.some((resource) => resource.key === "hyperdrive")) {
|
|
5712
|
-
const
|
|
5713
|
-
const
|
|
5714
|
-
|
|
5715
|
-
const
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
const choice = await select({
|
|
5720
|
-
message: "How should Void set up Hyperdrive?",
|
|
5721
|
-
options: [{
|
|
5748
|
+
const suggestedName = existing?.deployment.resources.hyperdrive ?? createPlatformResourceNames(installationSlug).hyperdrive;
|
|
5749
|
+
const configurations = await client.listHyperdriveConfigs(accountId);
|
|
5750
|
+
const suggestedNameAvailable = !configurations.some((resource) => resource.name === suggestedName);
|
|
5751
|
+
const choice = await select({
|
|
5752
|
+
message: "How should Void set up Hyperdrive?",
|
|
5753
|
+
options: [
|
|
5754
|
+
...configurations.length > 0 ? [{
|
|
5722
5755
|
value: "existing",
|
|
5723
|
-
label:
|
|
5724
|
-
},
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5756
|
+
label: "Use an existing Hyperdrive"
|
|
5757
|
+
}] : [],
|
|
5758
|
+
...suggestedNameAvailable ? [{
|
|
5759
|
+
value: "create",
|
|
5760
|
+
label: "Let Void create Hyperdrive",
|
|
5761
|
+
hint: "recommended"
|
|
5762
|
+
}] : [],
|
|
5763
|
+
{
|
|
5764
|
+
value: "setup",
|
|
5765
|
+
label: "Set up a separately managed Hyperdrive"
|
|
5766
|
+
}
|
|
5767
|
+
]
|
|
5768
|
+
});
|
|
5769
|
+
if (isCancel(choice)) throw new Error("platform: Cancelled.");
|
|
5770
|
+
if (choice === "setup") {
|
|
5771
|
+
note(`Create a Hyperdrive in account ${accountId} with any unused name${suggestedNameAvailable ? ` (for example ${suggestedName})` : ""}. Point it at the same dedicated PostgreSQL database you will give Void, use a runtime database user, and disable SQL result caching. If your organization manages Hyperdrive, ask its administrator to create it. Then rerun this command and select it from the list.\nSetup: https://developers.cloudflare.com/hyperdrive/get-started/`, "Set up Hyperdrive first");
|
|
5772
|
+
outro("No Cloudflare or local installation state was changed.");
|
|
5773
|
+
return;
|
|
5774
|
+
}
|
|
5775
|
+
if (choice === "existing") {
|
|
5776
|
+
const selectedId = await select({
|
|
5777
|
+
message: "Which Hyperdrive should Void use?",
|
|
5778
|
+
options: [...configurations].sort((a, b) => Number(b.name === suggestedName) - Number(a.name === suggestedName) || a.name.localeCompare(b.name) || a.id.localeCompare(b.id)).map((resource) => ({
|
|
5779
|
+
value: resource.id,
|
|
5780
|
+
label: resource.name,
|
|
5781
|
+
hint: resource.name === suggestedName ? `suggested · ${resource.id}` : resource.id
|
|
5782
|
+
}))
|
|
5728
5783
|
});
|
|
5729
|
-
if (isCancel(
|
|
5730
|
-
|
|
5784
|
+
if (isCancel(selectedId)) throw new Error("platform: Cancelled.");
|
|
5785
|
+
const selected = configurations.find((resource) => resource.id === selectedId);
|
|
5786
|
+
if (!selected) throw new Error("platform: The selected Hyperdrive is no longer available.");
|
|
5787
|
+
const live = await client.getHyperdriveConfig(accountId, selected.id);
|
|
5788
|
+
if (live.id !== selected.id || live.name !== selected.name || !live.origin.user) throw new Error(`platform: Could not verify the database user for existing Hyperdrive ${selected.name}.`);
|
|
5789
|
+
note(`Database: ${live.origin.database}\nHost: ${live.origin.host}\nPort: ${live.origin.port}\nUser: ${live.origin.user}\nSQL result caching: ${live.cachingDisabled ? "disabled" : "enabled"}`, `Existing Hyperdrive ${live.name}`);
|
|
5790
|
+
if (!live.cachingDisabled) throw new Error(`platform: Disable SQL result caching on existing Hyperdrive ${live.name} before installing.`);
|
|
5791
|
+
const confirmed = await confirm({
|
|
5792
|
+
message: `Use ${live.name} for this platform?`,
|
|
5793
|
+
initialValue: true
|
|
5794
|
+
});
|
|
5795
|
+
if (isCancel(confirmed) || !confirmed) throw new Error("platform: Cancelled.");
|
|
5731
5796
|
externalHyperdrive = {
|
|
5732
5797
|
id: live.id,
|
|
5798
|
+
name: live.name,
|
|
5733
5799
|
host: live.origin.host,
|
|
5734
5800
|
user: live.origin.user
|
|
5735
5801
|
};
|
|
5736
|
-
} else {
|
|
5737
|
-
const choice = await select({
|
|
5738
|
-
message: "How should Void set up Hyperdrive?",
|
|
5739
|
-
options: [{
|
|
5740
|
-
value: "create",
|
|
5741
|
-
label: "Let Void create Hyperdrive",
|
|
5742
|
-
hint: "recommended"
|
|
5743
|
-
}, {
|
|
5744
|
-
value: "existing",
|
|
5745
|
-
label: "Use a separately managed Hyperdrive"
|
|
5746
|
-
}]
|
|
5747
|
-
});
|
|
5748
|
-
if (isCancel(choice)) throw new Error("platform: Cancelled.");
|
|
5749
|
-
if (choice === "existing") {
|
|
5750
|
-
note(`Create a Hyperdrive in account ${accountId} named ${expectedName}. Point it at the same dedicated PostgreSQL database you will give Void, use a runtime database user, and disable SQL result caching. If your organization manages Hyperdrive, ask its administrator to create it. Then rerun this command.\nSetup: https://developers.cloudflare.com/hyperdrive/get-started/`, "Set up Hyperdrive first");
|
|
5751
|
-
outro("No Cloudflare or local installation state was changed.");
|
|
5752
|
-
return;
|
|
5753
|
-
}
|
|
5754
5802
|
}
|
|
5755
5803
|
}
|
|
5756
5804
|
let authoritativeProvisionIntents = false;
|
|
@@ -5761,7 +5809,7 @@ async function runPlatformLifecycleCommand(args) {
|
|
|
5761
5809
|
progress?.stop("Read the saved installation.");
|
|
5762
5810
|
progress = void 0;
|
|
5763
5811
|
if (authoritative) {
|
|
5764
|
-
const { selectAuthoritativePlatformManifest } = await import("./platform-management-
|
|
5812
|
+
const { selectAuthoritativePlatformManifest } = await import("./platform-management-DzKNsMlt.mjs");
|
|
5765
5813
|
const selected = selectAuthoritativePlatformManifest(existing, authoritative);
|
|
5766
5814
|
authoritativeProvisionIntents = true;
|
|
5767
5815
|
if (!args.plan && JSON.stringify(selected) !== JSON.stringify(existing)) writeInstallationManifest(selected);
|
|
@@ -5990,7 +6038,7 @@ async function runPlatformLifecycleCommand(args) {
|
|
|
5990
6038
|
})).actions.filter((action) => action.kind === "worker"),
|
|
5991
6039
|
revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action),
|
|
5992
6040
|
verifyExistingOwnership: async (manifest, databaseCheckpointExists) => {
|
|
5993
|
-
const { verifyPlatformInstallationOwnership } = await import("./platform-management-
|
|
6041
|
+
const { verifyPlatformInstallationOwnership } = await import("./platform-management-DzKNsMlt.mjs");
|
|
5994
6042
|
const retainedReplacementKeys = new Set(plan.actions.filter((action) => {
|
|
5995
6043
|
const previous = manifest.resources.find((resource) => resource.key === action.key);
|
|
5996
6044
|
return action.action === "create" && previous && previous.name !== action.name;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-
|
|
1
|
+
import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-78H0XQUA.mjs";
|
|
2
2
|
export { runPlatformLifecycleCommand };
|