void 0.21.8 → 0.21.9

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.
Files changed (28) hide show
  1. package/dist/{account-cmd-CQ2wi4Th.mjs → account-cmd-DZZGK80W.mjs} +2 -2
  2. package/dist/{auth-link-B_lceSHK.mjs → auth-link-B_CeugBw.mjs} +2 -2
  3. package/dist/{auth-router-cZq0HuWe.mjs → auth-router-BgEFRuvZ.mjs} +3 -3
  4. package/dist/cli/cf-compat.mjs +19 -11
  5. package/dist/cli/cli.mjs +16 -16
  6. package/dist/{connect-BY38i-9E.mjs → connect-BsUSRzln.mjs} +2 -2
  7. package/dist/{db-BIo37Y7H.mjs → db-hRrvZaq_.mjs} +1 -1
  8. package/dist/{deploy-BM_LoBXC.mjs → deploy-DDz7c8LK.mjs} +1 -1
  9. package/dist/{deploy-C0JaQSWS.mjs → deploy-WaAQez1O.mjs} +1 -1
  10. package/dist/{email-dMnE_Lat.mjs → email-DFi-s2t4.mjs} +1 -1
  11. package/dist/index.mjs +1 -1
  12. package/dist/{init-CJSnEcuj.mjs → init-WO0JlPx8.mjs} +2 -2
  13. package/dist/login-DFQk7rbW.mjs +2 -0
  14. package/dist/{login-DZldyb8c.mjs → login-DvqXsfGs.mjs} +1 -1
  15. package/dist/{operator-cmd-B9dbG3Od.mjs → operator-cmd-03819ATr.mjs} +2 -2
  16. package/dist/{platform-auth-config-Bex45lQt.mjs → platform-auth-config-z92h63q5.mjs} +2 -2
  17. package/dist/{platform-auth-protection-Dma02l6-.mjs → platform-auth-protection-DeE3yr2R.mjs} +2 -2
  18. package/dist/{platform-auth-recovery-COOhMCvx.mjs → platform-auth-recovery-o_340Ixx.mjs} +2 -2
  19. package/dist/{platform-cmd-CjNB09OF.mjs → platform-cmd-C4ZV3Vpy.mjs} +1 -1
  20. package/dist/{platform-cmd-BtxZrT6w.mjs → platform-cmd-DNl8WosH.mjs} +3 -3
  21. package/dist/{platform-domain-DppaTARe.mjs → platform-domain-CU1JtJkW.mjs} +2 -2
  22. package/dist/{platform-lifecycle-BpDlxT3t.mjs → platform-lifecycle-Bc047IeT.mjs} +271 -23
  23. package/dist/{platform-lifecycle-CYll-oKE.mjs → platform-lifecycle-Bs2qx1E3.mjs} +1 -1
  24. package/dist/{platform-management-BS5r6Ao8.mjs → platform-management-C8tt6D8h.mjs} +1 -1
  25. package/dist/{platform-management-BKYenDlE.mjs → platform-management-CVpGI9Y5.mjs} +19 -2
  26. package/dist/{platform-recovery-dJ5Me-I0.mjs → platform-recovery-dvUaptLr.mjs} +2 -2
  27. package/package.json +7 -7
  28. package/dist/login-t6rndSRW.mjs +0 -2
@@ -1,13 +1,13 @@
1
1
  import { c as getToken, p as removeToken } from "./auth-DLNN0D3Z.mjs";
2
2
  import { j as log } from "./dist-Dn6nn2IU.mjs";
3
3
  import { n as PlatformClient } from "./client-QTl6ko_D.mjs";
4
- import { n as runLoginCommand } from "./login-DZldyb8c.mjs";
4
+ import { n as runLoginCommand } from "./login-DvqXsfGs.mjs";
5
5
  import { execSync } from "node:child_process";
6
6
  //#region src/cli/account-cmd.ts
7
7
  async function runAccountCommand(root, args) {
8
8
  switch (args.subcommand) {
9
9
  case "login": return runLoginCommand(root);
10
- case "link": return import("./auth-link-B_lceSHK.mjs").then(({ runAuthLink }) => runAuthLink(root, args.connectionId));
10
+ case "link": return import("./auth-link-B_CeugBw.mjs").then(({ runAuthLink }) => runAuthLink(root, args.connectionId));
11
11
  case "logout":
12
12
  if (removeToken(root)) log.success("Logged out.");
13
13
  else log.info("Not logged in.");
@@ -1,8 +1,8 @@
1
1
  import { a as getApiUrl, c as getToken, d as openBrowser, g as savePlatformToken, h as runPlatformLogin } from "./auth-DLNN0D3Z.mjs";
2
2
  import { j as log } from "./dist-Dn6nn2IU.mjs";
3
3
  import { n as PlatformClient } from "./client-QTl6ko_D.mjs";
4
- import { r as selectPlatformLoginMethod } from "./login-DZldyb8c.mjs";
5
- import { t as discoverPlatform } from "./platform-cmd-BtxZrT6w.mjs";
4
+ import { r as selectPlatformLoginMethod } from "./login-DvqXsfGs.mjs";
5
+ import { t as discoverPlatform } from "./platform-cmd-DNl8WosH.mjs";
6
6
  import { execFile } from "node:child_process";
7
7
  //#region src/cli/auth-link.ts
8
8
  async function runAuthLink(root, connectionId) {
@@ -37,7 +37,7 @@ async function chooseDestination(root, args, interactive) {
37
37
  }
38
38
  async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isTTY)) {
39
39
  if (args.subcommand === "link") {
40
- const { runAccountCommand } = await import("./account-cmd-CQ2wi4Th.mjs");
40
+ const { runAccountCommand } = await import("./account-cmd-DZZGK80W.mjs");
41
41
  await runAccountCommand(root, {
42
42
  subcommand: "link",
43
43
  ...args.connectionId ? { connectionId: args.connectionId } : {}
@@ -45,7 +45,7 @@ async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isT
45
45
  return;
46
46
  }
47
47
  if (args.subcommand === "token") {
48
- const { runAccountCommand } = await import("./account-cmd-CQ2wi4Th.mjs");
48
+ const { runAccountCommand } = await import("./account-cmd-DZZGK80W.mjs");
49
49
  await runAccountCommand(root, { subcommand: "token" });
50
50
  return;
51
51
  }
@@ -55,7 +55,7 @@ async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isT
55
55
  await runCloudflareCommand(root, { subcommand: args.subcommand === "whoami" || args.subcommand === "status" ? "status" : args.subcommand });
56
56
  return;
57
57
  }
58
- const { runAccountCommand } = await import("./account-cmd-CQ2wi4Th.mjs");
58
+ const { runAccountCommand } = await import("./account-cmd-DZZGK80W.mjs");
59
59
  const subcommand = args.subcommand === "status" ? "whoami" : args.subcommand;
60
60
  if (!destination.apiUrl) {
61
61
  await runAccountCommand(root, { subcommand });
@@ -22,7 +22,7 @@ function cfEnvironment() {
22
22
  CF_DELEGATION: "1",
23
23
  CF_SEND_TELEMETRY: "false",
24
24
  CF_NO_OSC_PROGRESS: "1",
25
- CLOUDFLARE_AUTH_USE_KEYRING: "true"
25
+ CLOUDFLARE_AUTH_USE_KEYRING: process.env.CLOUDFLARE_AUTH_USE_KEYRING ?? "true"
26
26
  };
27
27
  if (env.HTTP_PROXY || env.HTTPS_PROXY || env.http_proxy || env.https_proxy) env.NODE_USE_ENV_PROXY = "1";
28
28
  for (const [canonical, alias] of [
@@ -287,16 +287,24 @@ async function sessionCredential() {
287
287
  const dist = join(dirname(fileURLToPath(import.meta.resolve("cf/package.json"))), "dist");
288
288
  const entry = readdirSync(dist).find((name) => /^cf-[^/]+\.mjs$/.test(name));
289
289
  if (!entry) throw new Error("The bundled Cloudflare credential reader is unavailable.");
290
- const module = await import(pathToFileURL(join(dist, entry)).href);
291
- if (typeof module.t !== "function") throw new Error("The bundled Cloudflare credential reader is unavailable.");
292
- const noop = () => {};
293
- const stored = module.t({ logger: {
294
- debug: noop,
295
- info: noop,
296
- log: noop,
297
- warn: noop,
298
- error: noop
299
- } }).readAuthCredentials();
290
+ const previousKeyringSetting = process.env.CLOUDFLARE_AUTH_USE_KEYRING;
291
+ process.env.CLOUDFLARE_AUTH_USE_KEYRING = previousKeyringSetting ?? "true";
292
+ let stored;
293
+ try {
294
+ const module = await import(pathToFileURL(join(dist, entry)).href);
295
+ if (typeof module.t !== "function") throw new Error("The bundled Cloudflare credential reader is unavailable.");
296
+ const noop = () => {};
297
+ stored = module.t({ logger: {
298
+ debug: noop,
299
+ info: noop,
300
+ log: noop,
301
+ warn: noop,
302
+ error: noop
303
+ } }).readAuthCredentials();
304
+ } finally {
305
+ if (previousKeyringSetting === void 0) delete process.env.CLOUDFLARE_AUTH_USE_KEYRING;
306
+ else process.env.CLOUDFLARE_AUTH_USE_KEYRING = previousKeyringSetting;
307
+ }
300
308
  const credential = stored && typeof stored === "object" ? stored : null;
301
309
  return credential && typeof credential.oauth_token === "string" && credential.oauth_token ? {
302
310
  type: "oauth",
package/dist/cli/cli.mjs CHANGED
@@ -2020,7 +2020,7 @@ if (helpPath) {
2020
2020
  log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2021
2021
  process.exit(1);
2022
2022
  }
2023
- import("../deploy-BM_LoBXC.mjs").then(({ runDeploy }) => {
2023
+ import("../deploy-DDz7c8LK.mjs").then(({ runDeploy }) => {
2024
2024
  runDeploy(root, {
2025
2025
  projectSlug: deployArgs.projectSlug,
2026
2026
  dir: deployArgs.dir,
@@ -2039,21 +2039,21 @@ if (helpPath) {
2039
2039
  });
2040
2040
  } else if (command === "connect") (async () => {
2041
2041
  const parsed = parseConnectArgs(args.slice(1));
2042
- const { runConnectCommand } = await import("../connect-BY38i-9E.mjs");
2042
+ const { runConnectCommand } = await import("../connect-BsUSRzln.mjs");
2043
2043
  await runConnectCommand(process.cwd(), parsed);
2044
2044
  })().catch((err) => {
2045
2045
  log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2046
2046
  process.exit(1);
2047
2047
  });
2048
- else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-router-cZq0HuWe.mjs").then(({ runAuthRouter }) => runAuthRouter(root, parsed)));
2049
- else if (command === "account") runSubcommandGroup("account", accountSubcommands, parseAccountArgs, (root, parsed) => import("../account-cmd-CQ2wi4Th.mjs").then(({ runAccountCommand }) => runAccountCommand(root, parsed)));
2050
- else if (command === "platform") runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (root, parsed) => import("../platform-cmd-CjNB09OF.mjs").then(({ runPlatformCommand }) => runPlatformCommand(root, parsed)));
2048
+ else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-router-BgEFRuvZ.mjs").then(({ runAuthRouter }) => runAuthRouter(root, parsed)));
2049
+ else if (command === "account") runSubcommandGroup("account", accountSubcommands, parseAccountArgs, (root, parsed) => import("../account-cmd-DZZGK80W.mjs").then(({ runAccountCommand }) => runAccountCommand(root, parsed)));
2050
+ else if (command === "platform") runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (root, parsed) => import("../platform-cmd-C4ZV3Vpy.mjs").then(({ runPlatformCommand }) => runPlatformCommand(root, parsed)));
2051
2051
  else if (command === "cloudflare") runSubcommandGroup("cloudflare", cloudflareSubcommands, parseCloudflareArgs, (root, parsed) => import("../cloudflare-cmd-bSmZ1d5L.mjs").then(({ runCloudflareCommand }) => runCloudflareCommand(root, parsed)));
2052
2052
  else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-B44I8J_W.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
2053
2053
  else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-DN9sSNiV.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
2054
2054
  else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-Dmhvb2oU.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
2055
- else if (command === "email") runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (root, parsed) => import("../email-dMnE_Lat.mjs").then(({ runEmailCommand }) => runEmailCommand(root, parsed)));
2056
- else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-BIo37Y7H.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
2055
+ else if (command === "email") runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (root, parsed) => import("../email-DFi-s2t4.mjs").then(({ runEmailCommand }) => runEmailCommand(root, parsed)));
2056
+ else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-hRrvZaq_.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
2057
2057
  else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-Csi-tMbT.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
2058
2058
  else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-Vnv2f65C.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
2059
2059
  else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-BED3_9JD.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
@@ -2075,7 +2075,7 @@ else if (command === "prepare") {
2075
2075
  });
2076
2076
  } else if (command === "init") {
2077
2077
  const root = process.cwd();
2078
- import("../init-CJSnEcuj.mjs").then(({ runInitCommand, parseInitArgs }) => {
2078
+ import("../init-WO0JlPx8.mjs").then(({ runInitCommand, parseInitArgs }) => {
2079
2079
  let initArgs;
2080
2080
  try {
2081
2081
  initArgs = parseInitArgs(args.slice(1));
@@ -2207,12 +2207,12 @@ else if (command === "prepare") {
2207
2207
  const root = process.cwd();
2208
2208
  switch (cmd) {
2209
2209
  case "connect": {
2210
- const { runConnectCommand } = await import("../connect-BY38i-9E.mjs");
2210
+ const { runConnectCommand } = await import("../connect-BsUSRzln.mjs");
2211
2211
  await runConnectCommand(root, parseConnectArgs([]));
2212
2212
  return;
2213
2213
  }
2214
2214
  case "init": {
2215
- const { runInitCommand, parseInitArgs } = await import("../init-CJSnEcuj.mjs");
2215
+ const { runInitCommand, parseInitArgs } = await import("../init-WO0JlPx8.mjs");
2216
2216
  await runInitCommand(root, parseInitArgs([]));
2217
2217
  return;
2218
2218
  }
@@ -2222,21 +2222,21 @@ else if (command === "prepare") {
2222
2222
  return;
2223
2223
  }
2224
2224
  case "deploy": {
2225
- const { runDeploy } = await import("../deploy-BM_LoBXC.mjs");
2225
+ const { runDeploy } = await import("../deploy-DDz7c8LK.mjs");
2226
2226
  await runDeploy(root);
2227
2227
  return;
2228
2228
  }
2229
- case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-router-cZq0HuWe.mjs").then(({ runAuthRouter }) => runAuthRouter(r, p)));
2230
- case "account": return runSubcommandGroup("account", accountSubcommands, parseAccountArgs, (r, p) => import("../account-cmd-CQ2wi4Th.mjs").then(({ runAccountCommand }) => runAccountCommand(r, p)));
2231
- case "platform": return runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (r, p) => import("../platform-cmd-CjNB09OF.mjs").then(({ runPlatformCommand }) => runPlatformCommand(r, p)));
2229
+ case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-router-BgEFRuvZ.mjs").then(({ runAuthRouter }) => runAuthRouter(r, p)));
2230
+ case "account": return runSubcommandGroup("account", accountSubcommands, parseAccountArgs, (r, p) => import("../account-cmd-DZZGK80W.mjs").then(({ runAccountCommand }) => runAccountCommand(r, p)));
2231
+ case "platform": return runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (r, p) => import("../platform-cmd-C4ZV3Vpy.mjs").then(({ runPlatformCommand }) => runPlatformCommand(r, p)));
2232
2232
  case "cloudflare": return runSubcommandGroup("cloudflare", cloudflareSubcommands, parseCloudflareArgs, (r, p) => import("../cloudflare-cmd-bSmZ1d5L.mjs").then(({ runCloudflareCommand }) => runCloudflareCommand(r, p)));
2233
2233
  case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-B44I8J_W.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
2234
2234
  case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-DN9sSNiV.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
2235
2235
  case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-Dmhvb2oU.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
2236
2236
  case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-BED3_9JD.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
2237
2237
  case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-Dpt0jd-x.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
2238
- case "email": return runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (r, p) => import("../email-dMnE_Lat.mjs").then(({ runEmailCommand }) => runEmailCommand(r, p)));
2239
- case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-BIo37Y7H.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2238
+ case "email": return runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (r, p) => import("../email-DFi-s2t4.mjs").then(({ runEmailCommand }) => runEmailCommand(r, p)));
2239
+ case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-hRrvZaq_.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2240
2240
  case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-Csi-tMbT.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
2241
2241
  case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-Vnv2f65C.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
2242
2242
  case "prepare": {
@@ -3,8 +3,8 @@ import { o as listPlatformConnections, s as normalizePlatformApiUrl } from "./pl
3
3
  import { i as readDeploymentPlatform, l as writeDeploymentPlatform, u as writePlatformSelection } from "./project-C0Fqu05O.mjs";
4
4
  import { I as select, W as isCancel, j as log } from "./dist-Dn6nn2IU.mjs";
5
5
  import { i as isExpiredTokenError, n as PlatformClient } from "./client-QTl6ko_D.mjs";
6
- import { t as promptForLoginToken } from "./login-DZldyb8c.mjs";
7
- import { i as saveDiscoveredPlatform, n as promptPlatformUrl, t as discoverPlatform } from "./platform-cmd-BtxZrT6w.mjs";
6
+ import { t as promptForLoginToken } from "./login-DvqXsfGs.mjs";
7
+ import { i as saveDiscoveredPlatform, n as promptPlatformUrl, t as discoverPlatform } from "./platform-cmd-DNl8WosH.mjs";
8
8
  import { t as connectCloudflare } from "./cloudflare-connect-jAwacxxP.mjs";
9
9
  //#region src/cli/connect.ts
10
10
  async function selectVoidPlatform(interactive) {
@@ -862,7 +862,7 @@ async function runMigrate(root, dialect, remote) {
862
862
  log.error(getErrorMessage(error));
863
863
  process.exit(1);
864
864
  }
865
- const { checkWranglerMigrationApplySet, parseRootWranglerConfig } = await import("./deploy-BM_LoBXC.mjs");
865
+ const { checkWranglerMigrationApplySet, parseRootWranglerConfig } = await import("./deploy-DDz7c8LK.mjs");
866
866
  const applySet = await checkWranglerMigrationApplySet(context.operation.configPath, parseRootWranglerConfig(context.operation.configPath), binding, context.migrationsDir, rawMigrations);
867
867
  if (!applySet.ok) {
868
868
  log.error(applySet.reason);
@@ -1,2 +1,2 @@
1
- import { A as parseRootWranglerConfig, J as runDeploy, f as checkWranglerMigrationApplySet } from "./deploy-C0JaQSWS.mjs";
1
+ import { A as parseRootWranglerConfig, J as runDeploy, f as checkWranglerMigrationApplySet } from "./deploy-WaAQez1O.mjs";
2
2
  export { checkWranglerMigrationApplySet, parseRootWranglerConfig, runDeploy };
@@ -44,7 +44,7 @@ import { t as formatCloudflareUserMessage } from "./cloudflare-user-output-Q-k0Q
44
44
  import { a as promptProjectSetupAction, i as promptProjectSelection, r as promptAndCreateProject } from "./create-project-DBfFSZKY.mjs";
45
45
  import { t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
46
46
  import { t as collectGitDeployMetadata } from "./git-metadata-D-gurjzG.mjs";
47
- import { t as promptForLoginToken } from "./login-DZldyb8c.mjs";
47
+ import { t as promptForLoginToken } from "./login-DvqXsfGs.mjs";
48
48
  import { createRequire } from "node:module";
49
49
  import { copyFileSync, cpSync, createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
50
50
  import { fileURLToPath } from "node:url";
@@ -1,6 +1,6 @@
1
1
  import { a as join } from "./dist-BVqXeR_h.mjs";
2
2
  import { c as import_picocolors, i as createSpinner } from "./output-CCH48AMM.mjs";
3
- import { L as resolveDeployTransport, O as isWranglerNonInteractiveOrCI, X as runWranglerAuthToken, _ as deriveWorkerName, _t as findEmailConfigConflicts, bt as renderEmailChecklist, gt as createNodeEmailDns, h as createDeployWranglerRunner, ht as applyEmailSetup, k as loadProvisionModule, v as discoverRootWranglerConfig, vt as preflightEmail, yt as renderAddressMap } from "./deploy-C0JaQSWS.mjs";
3
+ import { L as resolveDeployTransport, O as isWranglerNonInteractiveOrCI, X as runWranglerAuthToken, _ as deriveWorkerName, _t as findEmailConfigConflicts, bt as renderEmailChecklist, gt as createNodeEmailDns, h as createDeployWranglerRunner, ht as applyEmailSetup, k as loadProvisionModule, v as discoverRootWranglerConfig, vt as preflightEmail, yt as renderAddressMap } from "./deploy-WaAQez1O.mjs";
4
4
  import { n as readProjectPaths } from "./project-paths-GgcMozYz.mjs";
5
5
  import { c as getToken, d as openBrowser } from "./auth-DLNN0D3Z.mjs";
6
6
  import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as __toESM } from "./rolldown-runtime-DXIUcv95.mjs";
2
2
  import { a as join, l as relative, n as dirname, u as resolve } from "./dist-BVqXeR_h.mjs";
3
3
  import { d as require_picocolors } from "./output-CCH48AMM.mjs";
4
- import { G as resolveWorkerDirName, St as hasDocumentRoutes, V as resolveDistDir, ct as prerenderPagesNode, dt as collectRevalidate, ft as hasRevalidate, mt as SEND_EMAIL_BINDING, ot as generateQueueResolverSource, pt as scanDurableObjectModules, st as prerenderPages, ut as collectPages, wt as resolveAssetRoutingPolicy, xt as hasApiRoutes } from "./deploy-C0JaQSWS.mjs";
4
+ import { G as resolveWorkerDirName, St as hasDocumentRoutes, V as resolveDistDir, ct as prerenderPagesNode, dt as collectRevalidate, ft as hasRevalidate, mt as SEND_EMAIL_BINDING, ot as generateQueueResolverSource, pt as scanDurableObjectModules, st as prerenderPages, ut as collectPages, wt as resolveAssetRoutingPolicy, xt as hasApiRoutes } from "./deploy-WaAQez1O.mjs";
5
5
  import { i as resolveProjectPaths, n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-GgcMozYz.mjs";
6
6
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-DPByhVck.mjs";
7
7
  import { r as scopedAccessCredentials } from "./cf-access-DRsQRe6k.mjs";
@@ -17,8 +17,8 @@ import { r as formatProjectCommand } from "./preset-UHj9ARyP.mjs";
17
17
  import { n as writeVoidProjectConfig, t as canRewriteVoidProjectConfig } from "./config-write-BSduPMY8.mjs";
18
18
  import { i as migrateFrameworkAdapterPaths, t as migrateLegacyVoidConfig } from "./migrate-B8KuoYsO.mjs";
19
19
  import { i as promptProjectSelection, r as promptAndCreateProject } from "./create-project-DBfFSZKY.mjs";
20
- import { t as promptForLoginToken } from "./login-DZldyb8c.mjs";
21
- import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-BtxZrT6w.mjs";
20
+ import { t as promptForLoginToken } from "./login-DvqXsfGs.mjs";
21
+ import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-DNl8WosH.mjs";
22
22
  import { t as connectCloudflare } from "./cloudflare-connect-jAwacxxP.mjs";
23
23
  import { n as findInstalledYarnPnpRuntime, r as hasLocalLockfile, t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-BV4AzNul.mjs";
24
24
  import { createRequire } from "node:module";
@@ -0,0 +1,2 @@
1
+ import { r as selectPlatformLoginMethod } from "./login-DvqXsfGs.mjs";
2
+ export { selectPlatformLoginMethod };
@@ -29,7 +29,7 @@ async function selectPlatformLoginMethod(platform, requestedId) {
29
29
  return methods.find((method) => method.id === provider);
30
30
  }
31
31
  async function promptForLoginToken(root = process.cwd(), platform) {
32
- const { id: provider, label: providerName } = await selectPlatformLoginMethod(platform ?? await import("./platform-cmd-CjNB09OF.mjs").then(({ discoverPlatform }) => discoverPlatform(getApiUrl(root))));
32
+ const { id: provider, label: providerName } = await selectPlatformLoginMethod(platform ?? await import("./platform-cmd-C4ZV3Vpy.mjs").then(({ discoverPlatform }) => discoverPlatform(getApiUrl(root))));
33
33
  const s = createSpinner();
34
34
  s.start(`Opening browser for ${providerName} login...`);
35
35
  try {
@@ -137,8 +137,8 @@ async function runAuth(origin, args) {
137
137
  if (args.action === "login" || args.action === "token" && args.tokenStdin) {
138
138
  if (!args.tokenStdin && !process.stdin.isTTY) throw new OperatorClientError("Browser login requires an interactive terminal. Use --token-stdin to exchange an API session.", "interactive_login_required");
139
139
  const apiToken = args.tokenStdin ? await readOperatorApiTokenStdin() : await (async () => {
140
- const { discoverPlatform } = await import("./platform-cmd-CjNB09OF.mjs");
141
- const { selectPlatformLoginMethod } = await import("./login-t6rndSRW.mjs");
140
+ const { discoverPlatform } = await import("./platform-cmd-C4ZV3Vpy.mjs");
141
+ const { selectPlatformLoginMethod } = await import("./login-DFQk7rbW.mjs");
142
142
  const { runPlatformLogin } = await import("./auth-CZuiVsFh.mjs");
143
143
  return runPlatformLogin(origin, (await selectPlatformLoginMethod(await discoverPlatform(origin), args.providerExplicit ? args.provider : void 0)).id, (url) => process.stderr.write(`Sign in at ${url}\n`));
144
144
  })();
@@ -140,11 +140,11 @@ async function configurationInput(args, existing) {
140
140
  }
141
141
  async function runPlatformAuthConfig(args) {
142
142
  if (args.action === "recover") {
143
- const { runPlatformAuthRecovery } = await import("./platform-auth-recovery-COOhMCvx.mjs");
143
+ const { runPlatformAuthRecovery } = await import("./platform-auth-recovery-o_340Ixx.mjs");
144
144
  return runPlatformAuthRecovery(args);
145
145
  }
146
146
  if (args.action === "protection") {
147
- const { runPlatformProtectionConfig } = await import("./platform-auth-protection-Dma02l6-.mjs");
147
+ const { runPlatformProtectionConfig } = await import("./platform-auth-protection-DeE3yr2R.mjs");
148
148
  return runPlatformProtectionConfig(args);
149
149
  }
150
150
  const origin = resolveOperatorOrigin(args.connection);
@@ -4,8 +4,8 @@ import { n as ensurePlatformAccessToken } from "./cf-access-P0iZnu0q.mjs";
4
4
  import { E as confirm, W as isCancel } from "./dist-Dn6nn2IU.mjs";
5
5
  import { n as OperatorClient } from "./operator-client-DUwumHpQ.mjs";
6
6
  import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-8KnOVXVd.mjs";
7
- import { D as preparePlatformAccessSetup, E as parsePlatformAccessSetupSpec, O as PlatformCloudflareClient, T as checkpointPlatformAccessResources, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-BpDlxT3t.mjs";
8
- import { c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-BKYenDlE.mjs";
7
+ import { D as preparePlatformAccessSetup, E as parsePlatformAccessSetupSpec, O as PlatformCloudflareClient, T as checkpointPlatformAccessResources, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-Bc047IeT.mjs";
8
+ import { c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
9
9
  import { createHmac } from "node:crypto";
10
10
  import { parsePlatformAccessProtection, platformProtectionProofMessage } from "@void/platform";
11
11
  import { readFile } from "node:fs/promises";
@@ -2,8 +2,8 @@ import { d as openBrowser } from "./auth-DLNN0D3Z.mjs";
2
2
  import { d as readInstallationRecoverySecrets, h as resolveInstallationManifest, t as acquirePlatformLifecycleLock } from "./platform-registry-QBa4DK32.mjs";
3
3
  import { E as confirm, W as isCancel } from "./dist-Dn6nn2IU.mjs";
4
4
  import { a as resolveOperatorOrigin } from "./operator-auth-8KnOVXVd.mjs";
5
- import { O as PlatformCloudflareClient, f as platformDatabaseClientUrl, n as resolvePlatformInstallDatabaseUrl, s as acquirePlatformDatabaseLifecycleLockConnection, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-BpDlxT3t.mjs";
6
- import { c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-BKYenDlE.mjs";
5
+ import { O as PlatformCloudflareClient, f as platformDatabaseClientUrl, n as resolvePlatformInstallDatabaseUrl, s as acquirePlatformDatabaseLifecycleLockConnection, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-Bc047IeT.mjs";
6
+ import { c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
7
7
  import { createCipheriv, createDecipheriv, createHash, createHmac, hkdfSync, randomBytes, randomUUID } from "node:crypto";
8
8
  import { execFile } from "node:child_process";
9
9
  import { parsePlatformAccessProtection, parsePlatformAdmissionPolicy, parsePlatformLoginConfiguration, platformAuthenticationRecoveryMessage, validatePlatformAdmissionPolicy } from "@void/platform";
@@ -1,2 +1,2 @@
1
- import { r as runPlatformCommand, t as discoverPlatform } from "./platform-cmd-BtxZrT6w.mjs";
1
+ import { r as runPlatformCommand, t as discoverPlatform } from "./platform-cmd-DNl8WosH.mjs";
2
2
  export { discoverPlatform, runPlatformCommand };
@@ -92,12 +92,12 @@ function saveDiscoveredPlatform(discovery) {
92
92
  }
93
93
  async function runPlatformCommand(_root, args) {
94
94
  if (args.subcommand === "config") {
95
- const { runPlatformAuthConfig } = await import("./platform-auth-config-Bex45lQt.mjs");
95
+ const { runPlatformAuthConfig } = await import("./platform-auth-config-z92h63q5.mjs");
96
96
  await runPlatformAuthConfig(args);
97
97
  return;
98
98
  }
99
99
  if (args.subcommand === "operator") {
100
- const { runOperatorCommand } = await import("./operator-cmd-B9dbG3Od.mjs");
100
+ const { runOperatorCommand } = await import("./operator-cmd-03819ATr.mjs");
101
101
  await runOperatorCommand(args);
102
102
  return;
103
103
  }
@@ -129,7 +129,7 @@ async function runPlatformCommand(_root, args) {
129
129
  console.log(`Capabilities: ${Object.entries(discovery.capabilities).filter(([, enabled]) => enabled).map(([name]) => name).join(", ")}`);
130
130
  return;
131
131
  }
132
- const { runPlatformLifecycleCommand } = await import("./platform-lifecycle-CYll-oKE.mjs");
132
+ const { runPlatformLifecycleCommand } = await import("./platform-lifecycle-Bs2qx1E3.mjs");
133
133
  await runPlatformLifecycleCommand(args);
134
134
  }
135
135
  //#endregion
@@ -1,8 +1,8 @@
1
1
  import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
2
2
  import { d as readInstallationRecoverySecrets, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
3
  import { B as text, E as confirm, N as note, W as isCancel, j as log } from "./dist-Dn6nn2IU.mjs";
4
- import { C as assertPlatformOperatorCredentialCanApplyPlan, O as PlatformCloudflareClient, _ as createPlatformInstallPlan, c as createPlatformHealthProbeToken, h as recordPlatformWorkerTraffic, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, p as recordResource, t as assertNoninteractivePlatformMutationAcknowledged, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-BpDlxT3t.mjs";
5
- import { a as resolveInstalledPlatformManifest, c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-BKYenDlE.mjs";
4
+ import { C as assertPlatformOperatorCredentialCanApplyPlan, O as PlatformCloudflareClient, _ as createPlatformInstallPlan, c as createPlatformHealthProbeToken, h as recordPlatformWorkerTraffic, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, p as recordResource, t as assertNoninteractivePlatformMutationAcknowledged, w as resolvePlatformCloudflareCredential } from "./platform-lifecycle-Bc047IeT.mjs";
5
+ import { a as resolveInstalledPlatformManifest, c as selectAuthoritativePlatformManifest, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { PLATFORM_APPLICATION_KEY, PLATFORM_REMOTE_INSTALLATION_MANIFEST_KEY, createApplicationRoutes, createPlatformDeploymentManifest, normalizeApplicationDomain } from "@void/platform";
8
8
  //#region src/cli/platform-domain.ts
@@ -1,5 +1,5 @@
1
1
  import { n as __toESM } from "./rolldown-runtime-DXIUcv95.mjs";
2
- import { a as join } from "./dist-BVqXeR_h.mjs";
2
+ import { a as join, n as dirname, u as resolve } 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
5
  import { d as openBrowser } from "./auth-DLNN0D3Z.mjs";
@@ -9,7 +9,8 @@ import { B as text$1, E as confirm, F as password, G as settings, I as select, K
9
9
  import { o as resolveWranglerArgv } from "./preset-UHj9ARyP.mjs";
10
10
  import { c as runCloudflareAuthCommand, n as announceCloudflareLogin } from "./cloudflare-auth-C4_GPZr0.mjs";
11
11
  import { _ as resolvePinnedApiBaseUrl, o as createDefaultRunWrangler } from "./provision-BhreDAOS.mjs";
12
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
12
+ import { copyFileSync, cpSync, existsSync, lstatSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
13
+ import { fileURLToPath } from "node:url";
13
14
  import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
14
15
  import { tmpdir } from "node:os";
15
16
  import { execFile } from "node:child_process";
@@ -1499,7 +1500,7 @@ async function verifyInstalledPlatformAccessProtection(input) {
1499
1500
  }
1500
1501
  const existingWorkers = input.plan.actions.filter((action) => action.kind === "worker" && action.action === "update").map((action) => action.name);
1501
1502
  if (existingWorkers.length) {
1502
- const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-Dma02l6-.mjs");
1503
+ const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-DeE3yr2R.mjs");
1503
1504
  await verifyProtectionWorkerOrigins({
1504
1505
  request: input.client.request.bind(input.client),
1505
1506
  listWorkerDomains: input.client.listWorkerDomains.bind(input.client),
@@ -3076,17 +3077,28 @@ async function installPlatform(plan, secrets, existing, dependencies) {
3076
3077
  }
3077
3078
  for (const key of workerKeys) {
3078
3079
  dependencies.onProgress?.(`Deploying the ${key} service`);
3080
+ let workerStepStarted = performance.now();
3081
+ const markWorkerStep = (step) => {
3082
+ if (process.env.VOID_PLATFORM_TIMINGS === "1") process.stderr.write(`[platform timing] worker ${key} ${step} ${(performance.now() - workerStepStarted).toFixed(0)} ms\n`);
3083
+ workerStepStarted = performance.now();
3084
+ };
3079
3085
  const action = workerActions.find((entry) => entry.key === (key === "emailGateway" ? "email-gateway-worker" : `${key}-worker`));
3080
3086
  const workerSecrets = platformWorkerSecretPayload(key, workerDeploymentSecrets, plan.account.id, zoneId, action.action !== "create");
3081
- manifest = recordProvisionIntent(manifest, action, now());
3082
- writeInstallationManifest(manifest);
3083
- await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3087
+ const intended = recordProvisionIntent(manifest, action, now());
3088
+ if (intended !== manifest) {
3089
+ manifest = intended;
3090
+ writeInstallationManifest(manifest);
3091
+ await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3092
+ }
3084
3093
  await dependencies.revalidateBeforeWorkerDeploy(manifest, action);
3094
+ markWorkerStep("revalidate");
3085
3095
  const preservedRoutes = dependencies.deployWorker ? [] : action.action === "create" ? [] : await inventoryUnmanagedPlatformWorkerTraffic(dependencies.client, plan, action.name);
3096
+ markWorkerStep("traffic inventory");
3086
3097
  const workerConfig = mergePlatformWorkerTrafficConfig(configs[key], preservedRoutes);
3087
3098
  const previousWorkerConfig = mergePlatformWorkerTrafficConfig(previousConfigs[key], preservedRoutes);
3088
3099
  const rollback = dependencies.deployWorker ? await dependencies.deployWorker(workerConfig, workerSecrets, previousWorkerConfig) : await deployPlatformWorker(workerConfig, workerSecrets, {
3089
3100
  apiBaseUrl: cloudflareApiBaseUrl,
3101
+ ...dependencies.client.request ? { readCloudflare: (path) => dependencies.client.request(path) } : {},
3090
3102
  onStaged: async (previousVersionId, stagedVersionId, previousTriggers) => {
3091
3103
  manifest = recordWorkerCutoverStage(manifest, workerCutoverGeneration, key, previousVersionId, stagedVersionId, action.name, previousTriggers, now());
3092
3104
  writeInstallationManifest(manifest);
@@ -3095,12 +3107,15 @@ async function installPlatform(plan, secrets, existing, dependencies) {
3095
3107
  onTrafficPublished: async () => {
3096
3108
  if (!dependencies.client.listWorkerDomains || !dependencies.client.listWorkerRoutes) throw new Error("platform: Cloudflare traffic inventory is unavailable.");
3097
3109
  const [customDomains, routes] = await Promise.all([dependencies.client.listWorkerDomains(plan.account.id), zoneId ? dependencies.client.listWorkerRoutes(zoneId) : Promise.resolve([])]);
3098
- manifest = recordPlatformWorkerTraffic(manifest, action.name, {
3110
+ const next = recordPlatformWorkerTraffic(manifest, action.name, {
3099
3111
  customDomains,
3100
3112
  routes
3101
3113
  }, now());
3102
- writeInstallationManifest(manifest);
3103
- await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3114
+ if (JSON.stringify(next.resources) !== JSON.stringify(manifest.resources)) {
3115
+ manifest = next;
3116
+ writeInstallationManifest(manifest);
3117
+ await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3118
+ }
3104
3119
  },
3105
3120
  onUnsafeTraffic: async () => {
3106
3121
  manifest = recordWorkerUnsafeTraffic(manifest, workerCutoverGeneration, key, action.name, now());
@@ -3128,10 +3143,15 @@ async function installPlatform(plan, secrets, existing, dependencies) {
3128
3143
  runner: runPinnedPlatformWrangler,
3129
3144
  workerExisted: action.action !== "create"
3130
3145
  });
3146
+ markWorkerStep("deploy");
3131
3147
  if (rollback) workerRollbacks.push(rollback);
3132
- manifest = recordResource(manifest, action, action.name, "created", now());
3133
- writeInstallationManifest(manifest);
3134
- await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3148
+ const recorded = recordResource(manifest, action, action.name, "created", now());
3149
+ if (rollback || dependencies.deployWorker || JSON.stringify(recorded.resources) !== JSON.stringify(manifest.resources)) {
3150
+ manifest = recorded;
3151
+ writeInstallationManifest(manifest);
3152
+ await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3153
+ }
3154
+ markWorkerStep("record");
3135
3155
  }
3136
3156
  manifest = setInstallationEndpoints(manifest, {
3137
3157
  apiUrl: plan.apiUrl,
@@ -3276,6 +3296,7 @@ async function installPlatform(plan, secrets, existing, dependencies) {
3276
3296
  const previousWorkerConfig = mergePlatformWorkerTrafficConfig(configs[key], preservedRoutes);
3277
3297
  const rollback = dependencies.deployWorker ? await dependencies.deployWorker(workerConfig, workerSecrets, previousWorkerConfig) : await deployPlatformWorker(workerConfig, workerSecrets, {
3278
3298
  apiBaseUrl: cloudflareApiBaseUrl,
3299
+ ...dependencies.client.request ? { readCloudflare: (path) => dependencies.client.request(path) } : {},
3279
3300
  onStaged: async (previousVersionId, stagedVersionId, previousTriggers) => {
3280
3301
  manifest = recordWorkerCutoverStage(manifest, workerCutoverGeneration, key, previousVersionId, stagedVersionId, action.name, previousTriggers, now());
3281
3302
  writeInstallationManifest(manifest);
@@ -3284,12 +3305,15 @@ async function installPlatform(plan, secrets, existing, dependencies) {
3284
3305
  onTrafficPublished: async () => {
3285
3306
  if (!dependencies.client.listWorkerDomains || !dependencies.client.listWorkerRoutes) throw new Error("platform: Cloudflare traffic inventory is unavailable.");
3286
3307
  const [customDomains, routes] = await Promise.all([dependencies.client.listWorkerDomains(plan.account.id), zoneId ? dependencies.client.listWorkerRoutes(zoneId) : Promise.resolve([])]);
3287
- manifest = recordPlatformWorkerTraffic(manifest, action.name, {
3308
+ const next = recordPlatformWorkerTraffic(manifest, action.name, {
3288
3309
  customDomains,
3289
3310
  routes
3290
3311
  }, now());
3291
- writeInstallationManifest(manifest);
3292
- await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3312
+ if (JSON.stringify(next.resources) !== JSON.stringify(manifest.resources)) {
3313
+ manifest = next;
3314
+ writeInstallationManifest(manifest);
3315
+ await writeRemoteInstallationCheckpoint(dependencies.client, plan, manifest);
3316
+ }
3293
3317
  },
3294
3318
  onUnsafeTraffic: async () => {
3295
3319
  manifest = recordWorkerUnsafeTraffic(manifest, workerCutoverGeneration, key, action.name, now());
@@ -3407,10 +3431,14 @@ function saveInstalledPlatformConnection(plan, manifest) {
3407
3431
  });
3408
3432
  }
3409
3433
  async function writeRemoteInstallationCheckpointWithoutDatabase(client, plan, manifest, databaseLock) {
3434
+ const startedAt = performance.now();
3410
3435
  await databaseLock?.checkpoint?.(manifest);
3436
+ if (process.env.VOID_PLATFORM_TIMINGS === "1") process.stderr.write(`[platform timing] database checkpoint ${(performance.now() - startedAt).toFixed(0)} ms\n`);
3411
3437
  const routing = manifest.resources.find((resource) => resource.key === "routing-kv" && resource.kind === "kv-namespace" && resource.ownership === "created" && resource.state === "ready");
3412
3438
  if (!routing) return;
3439
+ const kvStartedAt = performance.now();
3413
3440
  await client.putKvValue(plan.account.id, routing.id, REMOTE_INSTALLATION_MANIFEST_KEY, JSON.stringify(manifest));
3441
+ if (process.env.VOID_PLATFORM_TIMINGS === "1") process.stderr.write(`[platform timing] remote checkpoint ${(performance.now() - kvStartedAt).toFixed(0)} ms\n`);
3414
3442
  }
3415
3443
  function recordProvisionIntent(manifest, action, now) {
3416
3444
  const previousResourceId = manifest.resources.find((resource) => resource.key === action.key)?.id ?? null;
@@ -4122,6 +4150,146 @@ async function claimPlatformDatabaseConnection(client, installationId, ownership
4122
4150
  throw error;
4123
4151
  }
4124
4152
  }
4153
+ let cachedPlatformUploaderHash;
4154
+ function platformWorkerUploaderHash() {
4155
+ if (cachedPlatformUploaderHash !== void 0) return cachedPlatformUploaderHash;
4156
+ try {
4157
+ const launcher = resolveWranglerArgv(process.cwd())[1];
4158
+ if (!launcher) return cachedPlatformUploaderHash = null;
4159
+ const digest = createHash("sha256");
4160
+ digest.update("platform-uploader:v1\0");
4161
+ digest.update(process.version);
4162
+ digest.update(readFileSync(resolve(dirname(launcher), "..", "..", "package.json")));
4163
+ const cfDirectory = dirname(fileURLToPath(import.meta.resolve("cf/package.json")));
4164
+ digest.update(readFileSync(join(cfDirectory, "package.json")));
4165
+ digest.update(readFileSync(join(cfDirectory, "bin", "cf")));
4166
+ const cfCodeHash = platformWorkerDirectoryHash(join(cfDirectory, "dist"));
4167
+ if (!cfCodeHash) throw new Error("Cloudflare CLI code is unavailable.");
4168
+ digest.update(cfCodeHash);
4169
+ let dependencyDirectory = dirname(fileURLToPath(import.meta.resolve("@cloudflare/build-output-utils")));
4170
+ while (!existsSync(join(dependencyDirectory, "package.json"))) {
4171
+ const parent = dirname(dependencyDirectory);
4172
+ if (parent === dependencyDirectory) throw new Error("Cloudflare build output package is unavailable.");
4173
+ dependencyDirectory = parent;
4174
+ }
4175
+ digest.update(readFileSync(join(dependencyDirectory, "package.json")));
4176
+ const buildOutputCodeHash = platformWorkerDirectoryHash(join(dependencyDirectory, "dist"));
4177
+ if (!buildOutputCodeHash) throw new Error("Cloudflare build output code is unavailable.");
4178
+ digest.update(buildOutputCodeHash);
4179
+ const visited = /* @__PURE__ */ new Set();
4180
+ const visit = (path, name) => {
4181
+ if (visited.has(path)) return;
4182
+ visited.add(path);
4183
+ const source = readFileSync(path);
4184
+ digest.update(`${name}\0`);
4185
+ digest.update(source);
4186
+ const imports = [...source.toString("utf8").matchAll(/\b(?:from|import)\s*(?:\(\s*)?['"](\.{1,2}\/[^'"]+)['"]/g)].map((match) => match[1]).sort();
4187
+ for (const specifier of imports) visit(resolve(dirname(path), specifier), specifier);
4188
+ };
4189
+ visit(launcher, "launcher");
4190
+ return cachedPlatformUploaderHash = digest.digest("hex");
4191
+ } catch {
4192
+ return cachedPlatformUploaderHash = null;
4193
+ }
4194
+ }
4195
+ function platformWorkerDirectoryHash(directory) {
4196
+ if (!lstatSync(directory).isDirectory()) return null;
4197
+ const digest = createHash("sha256");
4198
+ const visit = (path, prefix) => {
4199
+ for (const entry of readdirSync(path, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
4200
+ const relativePath = `${prefix}${entry.name}`;
4201
+ const absolutePath = join(path, entry.name);
4202
+ if (entry.isDirectory()) {
4203
+ digest.update(`directory:${relativePath}\0`);
4204
+ if (!visit(absolutePath, `${relativePath}/`)) return false;
4205
+ } else if (entry.isFile()) {
4206
+ digest.update(`file:${relativePath}\0`);
4207
+ digest.update(createHash("sha256").update(readFileSync(absolutePath)).digest("hex"));
4208
+ } else return false;
4209
+ }
4210
+ return true;
4211
+ };
4212
+ return visit(directory, "") ? digest.digest("hex") : null;
4213
+ }
4214
+ /** Hash every input that can change a version upload; missing or unusual files disable reuse. */
4215
+ function platformWorkerUploadFingerprint(config, managedRoutes = []) {
4216
+ const uploaderHash = platformWorkerUploaderHash();
4217
+ if (typeof config.main !== "string" || !uploaderHash) return null;
4218
+ try {
4219
+ if (!lstatSync(config.main).isFile()) return null;
4220
+ const mainSha256 = createHash("sha256").update(readFileSync(config.main)).digest("hex");
4221
+ const normalized = {
4222
+ ...config,
4223
+ main: { sha256: mainSha256 }
4224
+ };
4225
+ if (config.assets !== void 0) {
4226
+ const assets = config.assets;
4227
+ if (!assets || typeof assets !== "object" || Array.isArray(assets)) return null;
4228
+ const directory = assets.directory;
4229
+ if (typeof directory !== "string") return null;
4230
+ const assetsHash = platformWorkerDirectoryHash(directory);
4231
+ if (!assetsHash) return null;
4232
+ normalized.assets = {
4233
+ ...assets,
4234
+ directory: assetsHash
4235
+ };
4236
+ }
4237
+ return createHash("sha256").update(JSON.stringify({
4238
+ schema: 2,
4239
+ config: normalized,
4240
+ managedRoutes,
4241
+ uploaderHash
4242
+ })).digest("hex");
4243
+ } catch {
4244
+ return null;
4245
+ }
4246
+ }
4247
+ function snapshotPlatformWorkerUploadInputs(config, directory) {
4248
+ const main = config.main;
4249
+ if (typeof main !== "string") throw new Error("platform: Worker upload has no script artifact.");
4250
+ const snapshotMain = join(directory, "worker-upload.js");
4251
+ copyFileSync(main, snapshotMain);
4252
+ const snapshot = {
4253
+ ...config,
4254
+ main: snapshotMain
4255
+ };
4256
+ if (config.assets !== void 0) {
4257
+ const assets = config.assets;
4258
+ const sourceDirectory = assets.directory;
4259
+ if (typeof sourceDirectory !== "string") throw new Error("platform: Worker upload has no assets directory.");
4260
+ const snapshotDirectory = join(directory, "worker-assets");
4261
+ cpSync(sourceDirectory, snapshotDirectory, { recursive: true });
4262
+ snapshot.assets = {
4263
+ ...assets,
4264
+ directory: snapshotDirectory
4265
+ };
4266
+ }
4267
+ return snapshot;
4268
+ }
4269
+ function platformWorkerApiReadRunner(accountId, workerName, readCloudflare, fallback) {
4270
+ const base = `/accounts/${encodeURIComponent(accountId)}/workers/scripts/${encodeURIComponent(workerName)}`;
4271
+ return async (args, account, cwd, capture) => {
4272
+ if (args[0] === "deployments" && (args[1] === "status" || args[1] === "list")) {
4273
+ const response = await readCloudflare(`${base}/deployments`);
4274
+ const deployments = response && typeof response === "object" && !Array.isArray(response) ? response.deployments : null;
4275
+ if (!Array.isArray(deployments)) throw new Error(`platform: Cloudflare returned malformed deployment history for ${workerName}.`);
4276
+ return {
4277
+ status: args[1] === "status" && deployments.length === 0 ? 1 : 0,
4278
+ stderr: "",
4279
+ stdout: JSON.stringify(args[1] === "status" ? deployments[0] : deployments)
4280
+ };
4281
+ }
4282
+ if (args[0] === "versions" && args[1] === "view" && args[2]) {
4283
+ const version = await readCloudflare(`${base}/versions/${encodeURIComponent(args[2])}`);
4284
+ return {
4285
+ status: 0,
4286
+ stderr: "",
4287
+ stdout: JSON.stringify(version)
4288
+ };
4289
+ }
4290
+ return fallback(args, account, cwd, capture);
4291
+ };
4292
+ }
4125
4293
  async function deployPlatformWorker(config, secrets, options) {
4126
4294
  const directory = mkdtempSync(join(tmpdir(), "void-platform-deploy-"));
4127
4295
  const workerName = String(config.name);
@@ -4136,10 +4304,67 @@ async function deployPlatformWorker(config, secrets, options) {
4136
4304
  const previousTraffic = isolatePlatformWorkerCustomDomains(options.previousConfig);
4137
4305
  let uploadConfig = withoutPlatformWorkerTrafficAttachments(nextTraffic.wranglerConfig);
4138
4306
  const nextTriggers = readTriggerConfigFromObject(nextTraffic.wranglerConfig);
4307
+ const contentHash = secrets === null ? platformWorkerUploadFingerprint(config, options.managedRoutes) : null;
4139
4308
  let previousTriggers = readTriggerConfigFromObject(previousTraffic.wranglerConfig);
4140
4309
  try {
4141
4310
  const configPath = join(directory, "wrangler.json");
4142
4311
  writeFileSync(configPath, `${JSON.stringify(uploadConfig, null, 2)}\n`, { mode: 384 });
4312
+ const reconcileExistingVersion = async (versionId, triggerConfig, runner, deploymentId) => {
4313
+ try {
4314
+ assertPlatformTriggerStabilization(await stabilizeCloudflareVersionTriggers({
4315
+ configPath,
4316
+ knownTriggerConfigs: { [versionId]: nextTriggers },
4317
+ manageRoutes: false,
4318
+ previousTriggerConfig: triggerConfig,
4319
+ publishEmptyCustomDomains: async () => {
4320
+ await options.removeCustomDomains();
4321
+ return cleanPlatformCommandResult();
4322
+ },
4323
+ runWrangler: platformWorkerCommandRunner(accountId, directory, runner),
4324
+ targetTriggerConfig: nextTriggers,
4325
+ targetVersionId: versionId,
4326
+ workerName
4327
+ }), workerName, versionId, "publish");
4328
+ if (nextTraffic.customDomains.length > 0) await options.publishCustomDomains(workerName, nextTraffic.customDomains);
4329
+ if (options.managedRoutes.length > 0) await options.publishRoutes(workerName, options.managedRoutes);
4330
+ await options.onTrafficPublished();
4331
+ if (!deploymentId && await readActivePlatformWorkerVersion(configPath, accountId, workerName, runner) !== versionId) throw new Error(`platform: Worker ${workerName} changed during traffic reconciliation.`);
4332
+ if (deploymentId) {
4333
+ const after = await readPlatformWorkerDeployments(configPath, accountId, workerName, runner);
4334
+ if (after[0]?.id !== deploymentId || !deploymentRunsOnlyVersion(after[0], versionId)) throw new Error(`platform: Worker ${workerName} changed deployment lineage during reconciliation.`);
4335
+ }
4336
+ return null;
4337
+ } catch (error) {
4338
+ const failures = await recoverFailedPlatformWorkerDeployment({
4339
+ checkpointUnsafeTraffic: options.onUnsafeTraffic,
4340
+ closeRoutingGate: options.retainNewWorker,
4341
+ rollback: null,
4342
+ unsafeTraffic: true
4343
+ });
4344
+ throw new PlatformWorkerRecoveryIncompleteError(`platform: Worker ${workerName} traffic reconciliation failed: ${errorMessage(error)}${failures.length > 0 ? ` Safety recovery also failed: ${failures.join("; ")}` : ""}`, { cause: error });
4345
+ }
4346
+ };
4347
+ if (options.workerExisted && contentHash && options.readCloudflare) {
4348
+ const directRunner = platformWorkerApiReadRunner(accountId, workerName, options.readCloudflare, options.runner);
4349
+ let candidate;
4350
+ let changedDuringRead = false;
4351
+ try {
4352
+ const before = await readPlatformWorkerDeployments(configPath, accountId, workerName, directRunner);
4353
+ const activeVersion = before[0]?.versions.length === 1 && before[0].versions[0]?.percentage === 100 ? before[0].versions[0].versionId : null;
4354
+ if (!activeVersion) throw new Error(`platform: Existing Worker ${workerName} has no single active production version.`);
4355
+ const snapshot = await readPlatformWorkerVersionSnapshot(configPath, accountId, workerName, readPlatformWorkerOwnershipMarker(config), activeVersion, directRunner);
4356
+ const after = await readPlatformWorkerDeployments(configPath, accountId, workerName, directRunner);
4357
+ changedDuringRead = before[0]?.id !== after[0]?.id || !deploymentRunsOnlyVersion(after[0], snapshot.versionId);
4358
+ if (!changedDuringRead && snapshot.contentHash === contentHash) candidate = {
4359
+ deploymentId: after[0].id,
4360
+ snapshot
4361
+ };
4362
+ } catch (error) {
4363
+ if (error instanceof Error && (error.message.includes("changed concurrently") || error.message.includes("does not belong to this installation"))) throw error;
4364
+ }
4365
+ if (changedDuringRead) throw new Error(`platform: Worker ${workerName} changed concurrently while its deployment lineage was inspected.`);
4366
+ if (candidate && platformWorkerUploadFingerprint(config, options.managedRoutes) === contentHash) return await reconcileExistingVersion(candidate.snapshot.versionId, candidate.snapshot.triggerConfig, directRunner, candidate.deploymentId);
4367
+ }
4143
4368
  if (options.workerExisted) {
4144
4369
  const previous = await readActivePlatformWorkerSnapshot(configPath, accountId, workerName, readPlatformWorkerOwnershipMarker(config), options.runner);
4145
4370
  previousVersionId = previous.versionId;
@@ -4147,11 +4372,22 @@ async function deployPlatformWorker(config, secrets, options) {
4147
4372
  if (!deploymentRunsOnlyVersion(deployments[0], previousVersionId)) throw new Error(`platform: Worker ${workerName} changed concurrently while its deployment lineage was inspected.`);
4148
4373
  previousDeployment = deployments[0];
4149
4374
  previousDeploymentId = previousDeployment.id;
4375
+ if (contentHash && previous.contentHash === contentHash && platformWorkerUploadFingerprint(config, options.managedRoutes) === contentHash) return await reconcileExistingVersion(previousVersionId, previous.triggerConfig, options.runner);
4150
4376
  uploadConfig = withoutCompletedPlatformWorkerMigrations(uploadConfig, previous.migrationTag);
4151
4377
  writeFileSync(configPath, `${JSON.stringify(uploadConfig, null, 2)}\n`, { mode: 384 });
4152
4378
  previousTriggers = resolvePlatformPreviousTriggerConfig(withoutPlatformCustomDomainTriggers(previous.triggerConfig), previousTriggers, options.previousPublicEndpoints);
4153
4379
  previousTriggers = withoutPlatformCustomDomainTriggers(mergePreservedTriggerRoutes(previousTriggers, options.preservedRoutes));
4154
4380
  }
4381
+ const immutableConfig = contentHash ? snapshotPlatformWorkerUploadInputs(config, directory) : null;
4382
+ const uploadedContentHash = immutableConfig ? platformWorkerUploadFingerprint(immutableConfig, options.managedRoutes) : null;
4383
+ if (immutableConfig) {
4384
+ uploadConfig = {
4385
+ ...uploadConfig,
4386
+ main: immutableConfig.main,
4387
+ ...immutableConfig.assets === void 0 ? {} : { assets: immutableConfig.assets }
4388
+ };
4389
+ writeFileSync(configPath, `${JSON.stringify(uploadConfig, null, 2)}\n`, { mode: 384 });
4390
+ }
4155
4391
  const argv = [
4156
4392
  ...options.workerExisted ? ["versions", "upload"] : ["deploy"],
4157
4393
  "--config",
@@ -4161,7 +4397,7 @@ async function deployPlatformWorker(config, secrets, options) {
4161
4397
  "--experimental-auto-create=false",
4162
4398
  ...!options.workerExisted ? ["--autoconfig=false"] : [],
4163
4399
  "--message",
4164
- encodeCloudflareVersionMessage([], nextTriggers)
4400
+ encodeCloudflareVersionMessage([], nextTriggers, uploadedContentHash ?? void 0)
4165
4401
  ];
4166
4402
  if (secrets) {
4167
4403
  const secretsPath = join(directory, "secrets.json");
@@ -4388,6 +4624,7 @@ async function runPlatformWrangler(args, accountId, cwd, capture) {
4388
4624
  }
4389
4625
  const PLATFORM_WRANGLER_TIMEOUT_MS = 6e5;
4390
4626
  async function runPlatformWranglerAtApiBase(args, accountId, cwd, capture, apiBaseUrl = resolvePinnedApiBaseUrl()) {
4627
+ const startedAt = performance.now();
4391
4628
  const result = await createDefaultRunWrangler(process.cwd(), {
4392
4629
  launcher: resolveWranglerArgv(process.cwd()),
4393
4630
  timeoutMs: PLATFORM_WRANGLER_TIMEOUT_MS
@@ -4397,6 +4634,10 @@ async function runPlatformWranglerAtApiBase(args, accountId, cwd, capture, apiBa
4397
4634
  captureJson: capture,
4398
4635
  cwd
4399
4636
  });
4637
+ if (process.env.VOID_PLATFORM_TIMINGS === "1") {
4638
+ const operation = args[0] === "versions" || args[0] === "deployments" ? `${args[0]} ${args[1] ?? ""}` : args[0] ?? "unknown";
4639
+ process.stderr.write(`[platform timing] wrangler ${operation} ${(performance.now() - startedAt).toFixed(0)} ms\n`);
4640
+ }
4400
4641
  const stdout = result.stdout || "";
4401
4642
  const stderr = result.stderr || "";
4402
4643
  if (!capture && result.status !== 0) {
@@ -4655,6 +4896,11 @@ async function readActivePlatformWorkerSnapshot(configPath, accountId, workerNam
4655
4896
  const readActiveVersion = () => readActivePlatformWorkerVersion(configPath, accountId, workerName, runner);
4656
4897
  const versionId = await readActiveVersion();
4657
4898
  if (!versionId) throw new Error(`platform: Existing Worker ${workerName} has no single active production version.`);
4899
+ return await readPlatformWorkerVersionSnapshot(configPath, accountId, workerName, expectedOwnershipMarker, versionId, runner, async () => {
4900
+ if (await readActiveVersion() !== versionId) throw new Error(`platform: Worker ${workerName} changed concurrently while its active version was inspected.`);
4901
+ });
4902
+ }
4903
+ async function readPlatformWorkerVersionSnapshot(configPath, accountId, workerName, expectedOwnershipMarker, versionId, runner, validateCurrentVersion) {
4658
4904
  const result = await runner([
4659
4905
  "versions",
4660
4906
  "view",
@@ -4677,13 +4923,15 @@ async function readActivePlatformWorkerSnapshot(configPath, accountId, workerNam
4677
4923
  const bindings = resources && typeof resources === "object" && !Array.isArray(resources) ? resources.bindings : null;
4678
4924
  const ownershipBindings = Array.isArray(bindings) ? bindings.filter((binding) => binding && typeof binding === "object" && binding.name === "PLATFORM_OWNERSHIP_MARKER" && binding.type === "plain_text" && typeof binding.text === "string") : [];
4679
4925
  if (ownershipBindings.length !== 1 || ownershipBindings[0].text !== expectedOwnershipMarker) throw new Error(`platform: Active Worker version ${versionId} for ${workerName} does not belong to this installation.`);
4680
- if (await readActiveVersion() !== versionId) throw new Error(`platform: Worker ${workerName} changed concurrently while its active version was inspected.`);
4926
+ await validateCurrentVersion?.();
4681
4927
  const annotations = value.annotations;
4682
4928
  const message = annotations && typeof annotations === "object" && typeof annotations["workers/message"] === "string" ? annotations["workers/message"] ?? null : null;
4683
4929
  const metadata = parseCloudflareVersionMessage(message);
4684
4930
  if (metadata?.schema !== 2) throw new Error(`platform: Active Worker ${workerName} predates safe trigger snapshots. Refusing to upgrade because its routes, cron, and queue consumers could not be restored after a failed cutover.`);
4931
+ const migrationTag = readCloudflareVersionMigrationTag(value);
4685
4932
  return {
4686
- migrationTag: readCloudflareVersionMigrationTag(value),
4933
+ ...metadata.contentHash ? { contentHash: metadata.contentHash } : {},
4934
+ migrationTag,
4687
4935
  triggerConfig: metadata.triggerConfig,
4688
4936
  versionId
4689
4937
  };
@@ -5568,14 +5816,14 @@ function resolvePlatformInstallDatabaseUrl(checkpoint, manifest = null) {
5568
5816
  }
5569
5817
  async function runPlatformLifecycleCommand(args) {
5570
5818
  if (args.subcommand === "domain") {
5571
- const { runPlatformDomainCommand } = await import("./platform-domain-DppaTARe.mjs");
5819
+ const { runPlatformDomainCommand } = await import("./platform-domain-CU1JtJkW.mjs");
5572
5820
  await runPlatformDomainCommand(args);
5573
5821
  return;
5574
5822
  }
5575
5823
  if (args.subcommand === "discover") {
5576
5824
  const client = new PlatformCloudflareClient((await resolvePlatformCloudflareCredential()).token);
5577
5825
  const accountId = await selectAccount(await readAccounts(client), args.account);
5578
- const { recoverPlatformInstallations } = await import("./platform-recovery-dJ5Me-I0.mjs");
5826
+ const { recoverPlatformInstallations } = await import("./platform-recovery-dvUaptLr.mjs");
5579
5827
  const recovered = await recoverPlatformInstallations(client, accountId, void 0, args.selector);
5580
5828
  if (recovered.length === 0) {
5581
5829
  log.info(`No recoverable Void platform installations were found in ${accountId}.`);
@@ -5585,7 +5833,7 @@ async function runPlatformLifecycleCommand(args) {
5585
5833
  return;
5586
5834
  }
5587
5835
  if (args.subcommand !== "install") {
5588
- const { runInstalledPlatformCommand } = await import("./platform-management-BS5r6Ao8.mjs");
5836
+ const { runInstalledPlatformCommand } = await import("./platform-management-C8tt6D8h.mjs");
5589
5837
  await runInstalledPlatformCommand(args);
5590
5838
  return;
5591
5839
  }
@@ -5809,7 +6057,7 @@ async function runPlatformLifecycleCommand(args) {
5809
6057
  progress?.stop("Read the saved installation.");
5810
6058
  progress = void 0;
5811
6059
  if (authoritative) {
5812
- const { selectAuthoritativePlatformManifest } = await import("./platform-management-BS5r6Ao8.mjs");
6060
+ const { selectAuthoritativePlatformManifest } = await import("./platform-management-C8tt6D8h.mjs");
5813
6061
  const selected = selectAuthoritativePlatformManifest(existing, authoritative);
5814
6062
  authoritativeProvisionIntents = true;
5815
6063
  if (!args.plan && JSON.stringify(selected) !== JSON.stringify(existing)) writeInstallationManifest(selected);
@@ -6038,7 +6286,7 @@ async function runPlatformLifecycleCommand(args) {
6038
6286
  })).actions.filter((action) => action.kind === "worker"),
6039
6287
  revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action),
6040
6288
  verifyExistingOwnership: async (manifest, databaseCheckpointExists) => {
6041
- const { verifyPlatformInstallationOwnership } = await import("./platform-management-BS5r6Ao8.mjs");
6289
+ const { verifyPlatformInstallationOwnership } = await import("./platform-management-C8tt6D8h.mjs");
6042
6290
  const retainedReplacementKeys = new Set(plan.actions.filter((action) => {
6043
6291
  const previous = manifest.resources.find((resource) => resource.key === action.key);
6044
6292
  return action.action === "create" && previous && previous.name !== action.name;
@@ -1,2 +1,2 @@
1
- import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-BpDlxT3t.mjs";
1
+ import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-Bc047IeT.mjs";
2
2
  export { runPlatformLifecycleCommand };
@@ -1,2 +1,2 @@
1
- import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-BKYenDlE.mjs";
1
+ import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
2
2
  export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
@@ -1,7 +1,7 @@
1
1
  import { i as createSpinner } from "./output-CCH48AMM.mjs";
2
2
  import { a as listInstallationManifests, d as readInstallationRecoverySecrets, h as resolveInstallationManifest, m as removePlatformConnectionForInstallation, p as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
3
  import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-Dn6nn2IU.mjs";
4
- import { A as hyperdriveOriginFromConnectionString, C as assertPlatformOperatorCredentialCanApplyPlan, M as verifyPlatformRuntimeTokenPermissions, O as PlatformCloudflareClient, S as platformDatabaseNameFromOwnerUrl, _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as platformProvisionIntentHash, d as loadPlatformRuntime, g as trackedPlatformWorkerTraffic, j as hyperdriveOriginMatches, k as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, m as resolveBootstrapGitHubId, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as formatPlatformInstallPlan, w as resolvePlatformCloudflareCredential, x as revalidatePlatformInstallAction, y as platformAdoptionIntentHash } from "./platform-lifecycle-BpDlxT3t.mjs";
4
+ import { A as hyperdriveOriginFromConnectionString, C as assertPlatformOperatorCredentialCanApplyPlan, M as verifyPlatformRuntimeTokenPermissions, O as PlatformCloudflareClient, S as platformDatabaseNameFromOwnerUrl, _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as platformProvisionIntentHash, d as loadPlatformRuntime, g as trackedPlatformWorkerTraffic, j as hyperdriveOriginMatches, k as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, m as resolveBootstrapGitHubId, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as formatPlatformInstallPlan, w as resolvePlatformCloudflareCredential, x as revalidatePlatformInstallAction, y as platformAdoptionIntentHash } from "./platform-lifecycle-Bc047IeT.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
7
7
  //#region src/cli/platform-management.ts
@@ -26,6 +26,14 @@ function selectAuthoritativePlatformManifest(local, authoritative) {
26
26
  async function runInstalledPlatformCommand(args) {
27
27
  if (args.subcommand !== "upgrade" && args.subcommand !== "rollback" && args.subcommand !== "repair" && args.subcommand !== "disable" && args.subcommand !== "enable" && args.subcommand !== "uninstall") throw new Error(`platform: Unsupported lifecycle command ${args.subcommand}.`);
28
28
  assertNoninteractivePlatformMutationAcknowledged(args, process.stdin.isTTY === true);
29
+ const timingStart = performance.now();
30
+ let timingPrevious = timingStart;
31
+ const markPhase = (phase) => {
32
+ if (process.env.VOID_PLATFORM_TIMINGS !== "1") return;
33
+ const current = performance.now();
34
+ process.stderr.write(`[platform timing] phase ${phase} ${(current - timingPrevious).toFixed(0)} ms, total ${(current - timingStart).toFixed(0)} ms\n`);
35
+ timingPrevious = current;
36
+ };
29
37
  const manifest = await resolveInstalledPlatformManifest(args.selector);
30
38
  const operatorCredential = await resolvePlatformCloudflareCredential();
31
39
  const operatorClient = new PlatformCloudflareClient(operatorCredential.token);
@@ -77,6 +85,7 @@ async function runInstalledPlatformCommand(args) {
77
85
  includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
78
86
  enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
79
87
  });
88
+ markPhase("plan");
80
89
  note(formatPlatformInstallPlan(plan), args.subcommand === "upgrade" ? "Upgrade plan" : args.subcommand === "rollback" ? "Rollback plan" : args.subcommand === "enable" ? "Enable plan" : "Repair plan");
81
90
  note([
82
91
  `Version: ${runtime.manifest.platformVersion}`,
@@ -99,6 +108,7 @@ async function runInstalledPlatformCommand(args) {
99
108
  allowUninitializedRoutingCheckpoint: args.subcommand === "repair" && databaseCheckpointExists,
100
109
  databaseUrl
101
110
  });
111
+ markPhase("ownership");
102
112
  const installation = args.subcommand === "enable" ? setInstallationDesiredState(manifest, "enabled", (/* @__PURE__ */ new Date()).toISOString()) : manifest;
103
113
  if (installation !== manifest) writeInstallationManifest(installation);
104
114
  const bootstrapGitHubLogin = process.env.VOID_PLATFORM_ADMIN_GITHUB_LOGIN || recovery?.bootstrapGitHubLogin || "";
@@ -130,6 +140,7 @@ async function runInstalledPlatformCommand(args) {
130
140
  customDomains: plan.deployment.capabilities.customDomains,
131
141
  zoneId: plan.zone?.id ?? null
132
142
  });
143
+ markPhase("runtime token");
133
144
  if (!databaseLock?.readAuthenticationState) throw new Error("platform: The database lifecycle lock cannot read authoritative authentication settings.");
134
145
  const result = await installPlatform(plan, secrets, installation, {
135
146
  acquireDatabaseLifecycleLock: async () => Object.assign(async () => {}, {
@@ -142,7 +153,10 @@ async function runInstalledPlatformCommand(args) {
142
153
  }),
143
154
  client,
144
155
  databaseRollbackSource: rollbackSourceRuntime ?? void 0,
145
- onProgress: (message) => progress?.message(message),
156
+ onProgress: (message) => {
157
+ markPhase(message);
158
+ progress?.message(message);
159
+ },
146
160
  runtime,
147
161
  replanWorkers: async (recoveryManifest) => (await createPlatformInstallPlan(client, planInput, recoveryManifest, {
148
162
  authoritativeProvisionIntents: true,
@@ -153,6 +167,7 @@ async function runInstalledPlatformCommand(args) {
153
167
  revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, { repairMissing: args.subcommand === "repair" })
154
168
  });
155
169
  progress.message("Finalizing platform changes");
170
+ markPhase("installer complete");
156
171
  reportResult = () => {
157
172
  progress?.stop(result.waitingForDns || result.waitingForSandboxDrain ? "Platform operation paused; progress is saved." : `Platform ${args.subcommand} complete.`);
158
173
  progress = void 0;
@@ -186,6 +201,7 @@ async function runInstalledPlatformCommand(args) {
186
201
  const databaseUrl = resolvePlatformInstallDatabaseUrl(recovery, current);
187
202
  if (!databaseUrl) throw new Error("platform: DATABASE_URL is required to safely serialize lifecycle changes across hosts.");
188
203
  const releaseDatabase = await acquirePlatformDatabaseLifecycleLock(databaseUrl, current.id, current.ownershipNonce);
204
+ markPhase("database lock");
189
205
  try {
190
206
  const authoritative = releaseDatabase.authoritativeManifest;
191
207
  const databaseCheckpointExists = authoritative !== null && authoritative !== void 0;
@@ -197,6 +213,7 @@ async function runInstalledPlatformCommand(args) {
197
213
  await releaseDatabase();
198
214
  }
199
215
  reportResult?.();
216
+ markPhase("complete");
200
217
  } catch (error) {
201
218
  progress?.error(`Platform ${args.subcommand} failed.`);
202
219
  progress = void 0;
@@ -1,7 +1,7 @@
1
1
  import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
2
2
  import { a as listInstallationManifests, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
- import { _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-BpDlxT3t.mjs";
4
- import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-BKYenDlE.mjs";
3
+ import { _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-Bc047IeT.mjs";
4
+ import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
5
5
  import { parsePlatformInstallationManifest, setInstallationEndpoints } from "@void/platform";
6
6
  //#region src/cli/platform-recovery.ts
7
7
  async function recoverPlatformInstallations(client, accountId, verifyEndpoint = verifyInstallationEndpoint, selector = "") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.21.8",
3
+ "version": "0.21.9",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -325,11 +325,11 @@
325
325
  "@cloudflare/vite-plugin": "1.54.7",
326
326
  "@cloudflare/workers-types": "^4.20260702.1",
327
327
  "@napi-rs/keyring": "2.0.0",
328
- "@void/deploy-cloudflare": "0.21.8",
329
- "@void/deploy-core": "0.21.8",
330
- "@void/edge": "0.21.8",
331
- "@void/isr": "0.21.8",
332
- "@void/platform": "0.21.8",
328
+ "@void/deploy-cloudflare": "0.21.9",
329
+ "@void/deploy-core": "0.21.9",
330
+ "@void/edge": "0.21.9",
331
+ "@void/isr": "0.21.9",
332
+ "@void/platform": "0.21.9",
333
333
  "acorn": "^8.15.0",
334
334
  "better-auth": "^1.7.3",
335
335
  "better-sqlite3": "^13.0.3",
@@ -379,7 +379,7 @@
379
379
  "zod": "^4.6.1"
380
380
  },
381
381
  "peerDependencies": {
382
- "@void/md": "0.21.8",
382
+ "@void/md": "0.21.9",
383
383
  "arktype": ">=2.0.0",
384
384
  "valibot": ">=1.0.0-beta.7",
385
385
  "vite": "^8.0.0",
@@ -1,2 +0,0 @@
1
- import { r as selectPlatformLoginMethod } from "./login-DZldyb8c.mjs";
2
- export { selectPlatformLoginMethod };