void 0.20.0 → 0.20.2

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 (93) hide show
  1. package/README.md +5 -1
  2. package/dist/{auth-W9WII-mN.mjs → auth-DPl6kck4.mjs} +46 -26
  3. package/dist/{auth-cmd-CYVhSNFy.mjs → auth-cmd-gniL2fNt.mjs} +5 -4
  4. package/dist/auth-link-NZdjCmSc.mjs +28 -0
  5. package/dist/{build-cmd-CkVD1uOh.mjs → build-cmd-sI18tX_O.mjs} +3 -3
  6. package/dist/{cache-QcUfR-ff.mjs → cache-IHn5MwBC.mjs} +3 -3
  7. package/dist/{cancel-deploy-DsvWKFTe.mjs → cancel-deploy-C5qTOdLi.mjs} +3 -3
  8. package/dist/cf-access-DRsQRe6k.mjs +75 -0
  9. package/dist/cli/cli.mjs +364 -1883
  10. package/dist/cli/env-schema-probe.mjs +11 -2
  11. package/dist/{client-CyCHWSO_.mjs → client-dHfSJvAN.mjs} +336 -58
  12. package/dist/{cloudflare-auth-DRkGe7-s.mjs → cloudflare-auth-6M5llVPC.mjs} +53 -6
  13. package/dist/{cloudflare-cmd-D3ME2GAe.mjs → cloudflare-cmd-4RPGN3KB.mjs} +2 -2
  14. package/dist/{cloudflare-connect-BivMefMA.mjs → cloudflare-connect-t1UU5svD.mjs} +2 -2
  15. package/dist/{cloudflare-operations-CPTpRW6d.mjs → cloudflare-operations-BzWnlC1_.mjs} +1 -1
  16. package/dist/{config-BQFq7QvD.mjs → config-uNGuFsI2.mjs} +1 -1
  17. package/dist/{connect-D9Yr-T5f.mjs → connect-Bfk31O_8.mjs} +6 -6
  18. package/dist/{create-project-DMV-csEm.mjs → create-project-Bk9Z0-Jg.mjs} +6 -5
  19. package/dist/{db-BxoUWL0F.mjs → db-BkRoptAt.mjs} +75 -48
  20. package/dist/{delete-iJOqxBz1.mjs → delete-DouASY9P.mjs} +3 -3
  21. package/dist/{deploy-CcDoeBIf.mjs → deploy-DTaWUS1S.mjs} +137 -128
  22. package/dist/{dev-inbox-DkgRWLkW.mjs → dev-inbox-P0u4tM8Y.mjs} +1 -1
  23. package/dist/{domain-gu_iaHmn.mjs → domain-1RhhOVrC.mjs} +4 -4
  24. package/dist/email-C-lGh51B.mjs +795 -0
  25. package/dist/{env-D4Emu-M_.mjs → env-DBKmK4vc.mjs} +1 -0
  26. package/dist/{env-DmU2To0C.mjs → env-DJHsPE7Z.mjs} +5 -5
  27. package/dist/{env-validation-ENpMy6Ez.mjs → env-validation-CF6KvTRf.mjs} +3 -1
  28. package/dist/{gen-BKw6qHIg.mjs → gen-B_wPnVTK.mjs} +3 -3
  29. package/dist/generate-RTK8_kK1.mjs +47 -0
  30. package/dist/{github-cmd-DJS5Ab-H.mjs → github-cmd-PW7ZnWTp.mjs} +3 -3
  31. package/dist/{headers-D8QfRX9Y.mjs → headers-BAHwgHdW.mjs} +1 -1
  32. package/dist/help-CwOX-zmI.mjs +2216 -0
  33. package/dist/{inbound-BJ70in1n.d.mts → inbound-CH5Mksyy.d.mts} +37 -42
  34. package/dist/{inbound-CNKxb3FY.mjs → inbound-aVHEUhKo.mjs} +143 -101
  35. package/dist/index.mjs +69 -30
  36. package/dist/{init-Dx5cgKqK.mjs → init-BWZ7q5Z4.mjs} +11 -11
  37. package/dist/{link-D_rm5sRH.mjs → link-Rmvu2Wl_.mjs} +4 -4
  38. package/dist/{list-M8XShti7.mjs → list-DEE2S6mY.mjs} +4 -4
  39. package/dist/{local-d1-BE8KBbMy.mjs → local-d1-D2I6Ox5F.mjs} +1 -1
  40. package/dist/{login-C8-UuLnp.mjs → login-Uvferzmm.mjs} +28 -10
  41. package/dist/{logs-DwFU7dMW.mjs → logs-27FenuiC.mjs} +4 -4
  42. package/dist/{mime-BJD7d_qL.mjs → mime-D5Nmdzf7.mjs} +23 -9
  43. package/dist/{node-BkaXcpAc.mjs → node-Ez5KW5rn.mjs} +3 -3
  44. package/dist/operator-auth-B3e08unv.mjs +52 -0
  45. package/dist/operator-client-LUZnlnYk.mjs +82 -0
  46. package/dist/{operator-cmd-DYWRbWUA.mjs → operator-cmd-CjOTmAYE.mjs} +35 -55
  47. package/dist/{output-tFQLLj26.mjs → output-B0cfNSx5.mjs} +316 -2
  48. package/dist/pages/index.mjs +2 -2
  49. package/dist/platform-auth-config-DrbQXXiW.mjs +368 -0
  50. package/dist/platform-auth-protection-Bhtvp0B_.mjs +219 -0
  51. package/dist/platform-auth-recovery-CeOKGVeJ.mjs +310 -0
  52. package/dist/{platform-cmd-BEOVv1PN.mjs → platform-cmd-BFhieCdV.mjs} +16 -6
  53. package/dist/{platform-domain-BszUfiS8.mjs → platform-domain-C74PULqV.mjs} +4 -4
  54. package/dist/{platform-lifecycle-CjSr6xf0.mjs → platform-lifecycle-BwAIgz-t.mjs} +1667 -191
  55. package/dist/{platform-management-W30iCaTL.mjs → platform-management-COogu_Se.mjs} +33 -7
  56. package/dist/{platform-recovery-pHHv4ZSg.mjs → platform-recovery-ewqLefp1.mjs} +6 -5
  57. package/dist/{prepare-CBetXvsN.mjs → prepare-CtDJjoOj.mjs} +2 -2
  58. package/dist/{prepare-BfJvFUtJ.mjs → prepare-blNRQvQl.mjs} +2 -2
  59. package/dist/prerender-render.d.mts +11 -0
  60. package/dist/prerender-render.mjs +111 -0
  61. package/dist/{project-cmd-DCpk1cDt.mjs → project-cmd-DmZK9Hxf.mjs} +32 -14
  62. package/dist/project-team-D8jOJMUJ.mjs +130 -0
  63. package/dist/project-token-DA34bf-C.mjs +75 -0
  64. package/dist/{provision-Blnstcm2.mjs → provision-CSJOjjQk.mjs} +2 -0
  65. package/dist/{requests-Dn8Vheh1.mjs → requests-CUExwGQQ.mjs} +3 -3
  66. package/dist/{rollback-CtlPXEBi.mjs → rollback-CDNGU1gr.mjs} +4 -4
  67. package/dist/{runner-mysql-CgRFl3s6.mjs → runner-mysql-7BPUNGmL.mjs} +1 -1
  68. package/dist/{runner-pg-DCkWPsWS.mjs → runner-pg-BkEza-dX.mjs} +1 -1
  69. package/dist/runtime/ai.mjs +3 -2
  70. package/dist/runtime/email/testing.d.mts +1 -1
  71. package/dist/runtime/email/testing.mjs +3 -3
  72. package/dist/runtime/email-protocol.d.mts +15 -0
  73. package/dist/runtime/email-protocol.mjs +70 -0
  74. package/dist/runtime/email.d.mts +2 -2
  75. package/dist/runtime/email.mjs +189 -96
  76. package/dist/runtime/remote/index.mjs +5 -3
  77. package/dist/{secret-BqTxGqki.mjs → secret-Bzzi2e9E.mjs} +5 -5
  78. package/dist/{skills-Q46GZMO-.mjs → skills-C0RvGjeE.mjs} +1 -1
  79. package/dist/sqlite-validation-BzKMWnO4.mjs +25 -0
  80. package/dist/{subcommand-prompt-WfySCQ7S.mjs → subcommand-prompt-Bmyn5Rlc.mjs} +1 -1
  81. package/dist/{validate-Bihr8WBi.mjs → validate-tBBN_dXH.mjs} +1 -0
  82. package/package.json +12 -7
  83. package/skills/void/SKILL.md +35 -4
  84. package/skills/void/docs/guide/deployment.md +2 -0
  85. package/skills/void/docs/guide/email.md +121 -98
  86. package/skills/void/docs/guide/platform-administration.md +214 -2
  87. package/skills/void/docs/guide/platform-development.md +93 -2
  88. package/skills/void/docs/guide/project-collaboration.md +94 -0
  89. package/skills/void/docs/guide/self-hosted-platform.md +184 -30
  90. package/skills/void/docs/reference/cli.md +294 -15
  91. package/dist/cf-access-AJ1ehiFR.mjs +0 -42
  92. package/dist/cf-access-DsSsZUPr.mjs +0 -67
  93. package/dist/email-r6DHJyAB.mjs +0 -262
@@ -0,0 +1,82 @@
1
+ import { B as ensureCloudflaredToken, X as normalizePlatformApiUrl } from "./output-B0cfNSx5.mjs";
2
+ import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
3
+ const OPERATOR_MAX_TIMEOUT_MS = 36e5;
4
+ var OperatorClientError = class extends Error {
5
+ code;
6
+ status;
7
+ details;
8
+ constructor(message, code = "operator_error", status, details) {
9
+ super(message);
10
+ this.code = code;
11
+ this.status = status;
12
+ this.details = details;
13
+ this.name = "OperatorClientError";
14
+ }
15
+ toJSON() {
16
+ return {
17
+ error: this.code,
18
+ message: this.message,
19
+ ...this.status === void 0 ? {} : { status: this.status },
20
+ ...this.details === void 0 ? {} : { details: this.details }
21
+ };
22
+ }
23
+ };
24
+ var OperatorClient = class {
25
+ token;
26
+ fetcher;
27
+ origin;
28
+ constructor(origin, token, fetcher = fetch) {
29
+ this.token = token;
30
+ this.fetcher = fetcher;
31
+ this.origin = normalizePlatformApiUrl(origin);
32
+ }
33
+ async request(path, options = {}) {
34
+ if (!path.startsWith("/") || path.startsWith("//") || path.includes("?") || path.includes("#")) throw new OperatorClientError("Invalid operator API path.");
35
+ const timeoutMs = options.timeoutMs ?? (options.method === "POST" ? 3e5 : 3e4);
36
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1e3 || timeoutMs > 36e5) throw new OperatorClientError(`Operator request timeout must be an integer from 1 to ${OPERATOR_MAX_TIMEOUT_MS / 1e3} seconds.`, "invalid_timeout");
37
+ const url = new URL(`${this.origin}/operator/v1${path}`);
38
+ ensureCloudflaredToken(this.origin);
39
+ for (const [name, value] of Object.entries(options.query ?? {})) url.searchParams.set(name, value);
40
+ const timeoutController = new AbortController();
41
+ const timer = setTimeout(() => timeoutController.abort(), timeoutMs);
42
+ timer.unref();
43
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutController.signal]) : timeoutController.signal;
44
+ try {
45
+ let response;
46
+ try {
47
+ response = await this.fetcher(url, {
48
+ method: options.method ?? "GET",
49
+ headers: {
50
+ ...cfAccessHeaders(process.env, this.origin),
51
+ Authorization: `Bearer ${this.token}`,
52
+ Accept: "application/json",
53
+ ...options.body ? { "Content-Type": "application/json" } : {}
54
+ },
55
+ ...options.body ? { body: JSON.stringify(options.body) } : {},
56
+ redirect: "manual",
57
+ signal
58
+ });
59
+ } catch (error) {
60
+ if (options.signal?.aborted) throw error;
61
+ if (timeoutController.signal.aborted) throw new OperatorClientError(`Operator request exceeded the ${timeoutMs / 1e3}-second timeout. ${options.method === "POST" ? "Its outcome may be unknown; inspect platform state before retrying." : "Check connectivity and try again."}`, "request_timeout");
62
+ throw new OperatorClientError(`Operator request to ${this.origin} failed. ${options.method === "POST" ? "Its outcome may be unknown; inspect platform state before retrying." : "Check connectivity and try again."}`, "connection_failed");
63
+ }
64
+ if (response.status >= 300 && response.status < 400) throw new OperatorClientError("The operator API redirected the request. Credentials were not forwarded; use the exact platform API origin.", "redirect_rejected", response.status);
65
+ let data;
66
+ try {
67
+ data = await response.json();
68
+ } catch {
69
+ throw new OperatorClientError(`Operator API returned invalid JSON (HTTP ${response.status}).${options.method === "POST" ? " Inspect platform state before retrying." : ""}`, "invalid_response", response.status);
70
+ }
71
+ if (!data || typeof data !== "object" || Array.isArray(data)) throw new OperatorClientError("Operator API returned an invalid response object.", "invalid_response", response.status);
72
+ const result = data;
73
+ if (!response.ok) throw new OperatorClientError(typeof result.message === "string" ? result.message : `Operator request failed (HTTP ${response.status}).`, typeof result.error === "string" ? result.error : "request_failed", response.status, result.details);
74
+ if (result.partial === true || result.ok === false) throw new OperatorClientError("The operation did not fully complete. Inspect the partial result before retrying.", "partial_failure", response.status, result);
75
+ return result;
76
+ } finally {
77
+ clearTimeout(timer);
78
+ }
79
+ }
80
+ };
81
+ //#endregion
82
+ export { OperatorClient as n, OperatorClientError as r, OPERATOR_MAX_TIMEOUT_MS as t };
@@ -1,57 +1,8 @@
1
- import { G as normalizePlatformApiUrl, K as platformCredentialAccount, V as getActivePlatformConnection, W as listPlatformConnections, at as readKeyringPassword, it as deleteKeyringPassword, ot as writeKeyringPassword } from "./output-tFQLLj26.mjs";
2
- import { n as OperatorClient, r as OperatorClientError } from "./cli/cli.mjs";
1
+ import { n as OperatorClient, r as OperatorClientError } from "./operator-client-LUZnlnYk.mjs";
2
+ import { a as resolveOperatorOrigin, i as removeOperatorToken, n as readOperatorApiTokenStdin, o as saveOperatorToken, r as readOperatorToken, t as exchangeOperatorSession } from "./operator-auth-B3e08unv.mjs";
3
3
  import { createHash } from "node:crypto";
4
4
  import { createInterface } from "node:readline/promises";
5
5
  import { setTimeout } from "node:timers/promises";
6
- /** Operator authority never comes from repository-controlled metadata. */
7
- function resolveOperatorOrigin(connection = "") {
8
- if (connection) {
9
- let normalized = null;
10
- try {
11
- normalized = normalizePlatformApiUrl(connection);
12
- } catch {}
13
- const matches = listPlatformConnections().filter((entry) => entry.id === connection || entry.installationId === connection || entry.apiUrl === normalized);
14
- if (matches.length !== 1) throw new OperatorClientError("Select a registered platform connection ID or URL. Run `void connect <url> --no-login` to register it first.", "invalid_connection");
15
- return matches[0].apiUrl;
16
- }
17
- if (process.env.VOID_API_URL) return normalizePlatformApiUrl(process.env.VOID_API_URL);
18
- if (process.env.VOID_OPERATOR_TOKEN) throw new OperatorClientError("VOID_OPERATOR_TOKEN requires an explicit --connection or VOID_API_URL to select its recipient.", "explicit_origin_required");
19
- const active = getActivePlatformConnection();
20
- if (!active) throw new OperatorClientError("No default platform connection. Run `void connect <url>` or specify --connection.", "connection_required");
21
- return active.apiUrl;
22
- }
23
- function readOperatorToken(origin) {
24
- const token = process.env.VOID_OPERATOR_TOKEN || readKeyringPassword("dev.void.cli.operator", platformCredentialAccount(origin));
25
- if (!token) throw new OperatorClientError("No operator session. Run `void platform auth login` or set VOID_OPERATOR_TOKEN with an explicit origin.", "authentication_required");
26
- return token;
27
- }
28
- function saveOperatorToken(origin, token) {
29
- if (!writeKeyringPassword("dev.void.cli.operator", platformCredentialAccount(origin), token)) throw new OperatorClientError("The system keychain is unavailable. Use `void platform auth token --token-stdin` with a full API session to obtain a token for VOID_OPERATOR_TOKEN; plaintext credential storage is disabled.", "keychain_unavailable");
30
- }
31
- function removeOperatorToken(origin) {
32
- const account = platformCredentialAccount(origin);
33
- if (readKeyringPassword("dev.void.cli.operator", account) && !deleteKeyringPassword("dev.void.cli.operator", account)) throw new OperatorClientError("The operator session was revoked, but its local keychain entry could not be removed.", "keychain_unavailable");
34
- }
35
- async function readOperatorApiTokenStdin() {
36
- if (process.stdin.isTTY) throw new OperatorClientError("--token-stdin requires an API session token piped on standard input.", "invalid_token_input");
37
- let input = "";
38
- for await (const chunk of process.stdin) {
39
- input += String(chunk);
40
- if (input.length > 32768) throw new OperatorClientError("API session token input is too large.", "invalid_token_input");
41
- }
42
- const token = input.trim();
43
- if (!token || token.length > 32768 || /\s/.test(token)) throw new OperatorClientError("Standard input must contain one API session token.", "invalid_token_input");
44
- return token;
45
- }
46
- async function exchangeOperatorSession(origin, apiToken) {
47
- const session = await new OperatorClient(origin, apiToken).request("/session", {
48
- method: "POST",
49
- body: {}
50
- });
51
- if (typeof session.token !== "string" || !session.token || session.apiVersion !== 1 || typeof session.expiresAt !== "string") throw new OperatorClientError("Operator API returned an invalid session.", "invalid_response");
52
- return session;
53
- }
54
- //#endregion
55
6
  //#region src/cli/operator-cmd.ts
56
7
  const MAX_RUNTIME_FOLLOW_ROWS = 1e4;
57
8
  function printable(value) {
@@ -137,6 +88,20 @@ function outputLogs(result, json) {
137
88
  if (result.nextCursor) console.log(`Next cursor: ${printable(result.nextCursor)}`);
138
89
  } else output(result, false);
139
90
  }
91
+ function operationRecoveryFence(value) {
92
+ const target = value && typeof value === "object" && !Array.isArray(value) ? value : null;
93
+ if (!target || typeof target.stepId !== "string" || typeof target.attempt !== "number" || !Number.isSafeInteger(target.attempt) || typeof target.requestDigest !== "string" || typeof target.resourceIdentity !== "string" || typeof target.connectionId !== "string" || typeof target.desiredGeneration !== "number" || !Number.isSafeInteger(target.desiredGeneration) || target.routeId !== null && typeof target.routeId !== "string" || target.routeDesiredGeneration !== null && (typeof target.routeDesiredGeneration !== "number" || !Number.isSafeInteger(target.routeDesiredGeneration))) throw new OperatorClientError("The server did not return a valid email operation recovery fence. No change was requested.", "invalid_preview");
94
+ return {
95
+ stepId: target.stepId,
96
+ attempt: target.attempt,
97
+ requestDigest: target.requestDigest,
98
+ resourceIdentity: target.resourceIdentity,
99
+ connectionId: target.connectionId,
100
+ desiredGeneration: target.desiredGeneration,
101
+ routeId: target.routeId,
102
+ routeDesiredGeneration: target.routeDesiredGeneration
103
+ };
104
+ }
140
105
  function runtimeLogFingerprint(row) {
141
106
  const ingestedAt = row && typeof row === "object" && !Array.isArray(row) ? row.ingestedAt : void 0;
142
107
  if (!row || typeof row !== "object" || Array.isArray(row) || typeof ingestedAt !== "number" || !Number.isSafeInteger(ingestedAt)) throw new OperatorClientError("Runtime log response has an invalid ingestion cursor.", "invalid_response");
@@ -171,7 +136,13 @@ async function confirmOperatorMutation(origin, preview, args) {
171
136
  async function runAuth(origin, args) {
172
137
  if (args.action === "login" || args.action === "token" && args.tokenStdin) {
173
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");
174
- const session = await exchangeOperatorSession(origin, args.tokenStdin ? await readOperatorApiTokenStdin() : await import("./auth-W9WII-mN.mjs").then((n) => n.t).then(({ runPlatformLogin }) => runPlatformLogin(origin, args.provider, (url) => process.stderr.write(`Sign in at ${url}\n`))));
139
+ const apiToken = args.tokenStdin ? await readOperatorApiTokenStdin() : await (async () => {
140
+ const { discoverPlatform } = await import("./platform-cmd-BFhieCdV.mjs");
141
+ const { selectPlatformLoginMethod } = await import("./login-Uvferzmm.mjs").then((n) => n.t);
142
+ const { runPlatformLogin } = await import("./auth-DPl6kck4.mjs").then((n) => n.t);
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
+ })();
145
+ const session = await exchangeOperatorSession(origin, apiToken);
175
146
  const { token, ...identity } = session;
176
147
  if (args.action === "token") {
177
148
  if (args.json) output({
@@ -308,7 +279,7 @@ async function followOperatorLogs(client, args, signal, pollIntervalMs = 2e3) {
308
279
  }
309
280
  async function runOperatorCommand(args) {
310
281
  if (!args.action) {
311
- const { printHelpPage } = await import("./cli/cli.mjs").then((n) => n.t);
282
+ const { printHelpPage } = await import("./help-CwOX-zmI.mjs").then((n) => n.n);
312
283
  printHelpPage(["platform", args.group]);
313
284
  return;
314
285
  }
@@ -317,6 +288,13 @@ async function runOperatorCommand(args) {
317
288
  const client = new OperatorClient(origin, readOperatorToken(origin));
318
289
  if (args.method === "POST") {
319
290
  if (!args.plan && !args.yes && (!process.stdin.isTTY || !process.stderr.isTTY)) throw new OperatorClientError("Mutations in non-interactive mode require --yes or --plan.", "confirmation_required");
291
+ if (args.tokenStdin && args.group === "email" && (args.action === "domain-add" || args.action === "domain-remove")) args = {
292
+ ...args,
293
+ body: {
294
+ ...args.body,
295
+ apiToken: await readOperatorApiTokenStdin()
296
+ }
297
+ };
320
298
  const preview = await client.request(args.path, {
321
299
  method: "POST",
322
300
  body: {
@@ -326,10 +304,12 @@ async function runOperatorCommand(args) {
326
304
  timeoutMs: args.timeoutMs
327
305
  });
328
306
  if (preview.dryRun !== true || typeof preview.action !== "string" || !Object.hasOwn(preview, "target")) throw new OperatorClientError("The server did not return a valid mutation preview. No change was requested.", "invalid_preview");
307
+ const recoveryFence = args.group === "email" && args.action === "operation-resolve" ? operationRecoveryFence(preview.target) : {};
329
308
  if (!await confirmOperatorMutation(origin, preview, args)) return;
330
309
  const body = {
331
310
  ...args.body,
332
- ...args.group === "worker" && args.action === "rollback-all" ? { versions: preview.versions } : {}
311
+ ...args.group === "worker" && args.action === "rollback-all" ? { versions: preview.versions } : {},
312
+ ...recoveryFence
333
313
  };
334
314
  output(await client.request(args.path, {
335
315
  method: "POST",
@@ -339,7 +319,7 @@ async function runOperatorCommand(args) {
339
319
  } else if (args.follow) await followOperatorLogs(client, args);
340
320
  else {
341
321
  const result = await client.request(args.path, { query: args.query });
342
- if (args.action === "logs") outputLogs(result, args.json);
322
+ if (args.action === "logs" && args.group !== "email") outputLogs(result, args.json);
343
323
  else output(result, args.json);
344
324
  if (result.allOk === false) process.exitCode = 1;
345
325
  }
@@ -1,9 +1,11 @@
1
1
  import { n as __exportAll, r as __toESM, t as __commonJSMin } from "./rolldown-runtime-rQ84J-ij.mjs";
2
2
  import { l as resolve, o as join } from "./dist-BrsS7cai.mjs";
3
+ import { n as isVoidAccessGatedUrl, t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
3
4
  import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
4
5
  import { fileURLToPath } from "node:url";
5
6
  import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
6
7
  import { homedir, hostname } from "node:os";
8
+ import { spawnSync } from "node:child_process";
7
9
  import { Entry } from "@napi-rs/keyring";
8
10
  import { parsePlatformInstallationManifest } from "@void/platform";
9
11
  import { styleText } from "node:util";
@@ -505,6 +507,183 @@ function removePlatformConnectionForInstallation(installationId, directory = pla
505
507
  });
506
508
  }
507
509
  //#endregion
510
+ //#region src/cli/cf-access.ts
511
+ const ACCESS_KEYRING_SERVICE = "dev.void.cli.access";
512
+ const keyringTokens = /* @__PURE__ */ new Map();
513
+ function usableToken(token) {
514
+ try {
515
+ const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
516
+ return typeof payload.exp === "number" && payload.exp > Date.now() / 1e3 + 60;
517
+ } catch {
518
+ return false;
519
+ }
520
+ }
521
+ function rememberOriginToken(origin, token) {
522
+ let entries = {};
523
+ if (process.env.VOID_ACCESS_CREDENTIALS) {
524
+ const parsed = JSON.parse(process.env.VOID_ACCESS_CREDENTIALS);
525
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("platform: VOID_ACCESS_CREDENTIALS must contain an origin-keyed JSON object.");
526
+ entries = parsed;
527
+ }
528
+ process.env.VOID_ACCESS_CREDENTIALS = JSON.stringify({
529
+ ...entries,
530
+ [origin]: { CF_ACCESS_TOKEN: token }
531
+ });
532
+ }
533
+ function forgetOriginToken(origin) {
534
+ if (!process.env.VOID_ACCESS_CREDENTIALS) return;
535
+ const parsed = JSON.parse(process.env.VOID_ACCESS_CREDENTIALS);
536
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("platform: VOID_ACCESS_CREDENTIALS must contain an origin-keyed JSON object.");
537
+ const entries = { ...parsed };
538
+ delete entries[origin];
539
+ process.env.VOID_ACCESS_CREDENTIALS = JSON.stringify(entries);
540
+ }
541
+ function isCloudflareAccessChallenge(response) {
542
+ const location = response.headers.get("Location");
543
+ if (!location || response.status < 300 || response.status >= 400) return false;
544
+ try {
545
+ const target = new URL(location);
546
+ return target.protocol === "https:" && !target.username && !target.password && /^[a-z0-9-]+\.cloudflareaccess\.com$/.test(target.hostname) && target.pathname.startsWith("/cdn-cgi/access/login");
547
+ } catch {
548
+ return false;
549
+ }
550
+ }
551
+ /** Called for a selected origin, never for a redirect destination. */
552
+ function ensurePlatformAccessToken(apiUrl, challenged = false, required = false, rejectedToken) {
553
+ const origin = normalizePlatformApiUrl(apiUrl);
554
+ if (!origin.startsWith("https://")) return;
555
+ const headers = cfAccessHeaders(process.env, origin);
556
+ if (headers["CF-Access-Client-Id"]) return;
557
+ if (!challenged && headers["cf-access-token"] && usableToken(headers["cf-access-token"])) return;
558
+ const account = platformCredentialAccount(origin);
559
+ if (!keyringTokens.has(origin)) {
560
+ if (keyringTokens.size >= 64) keyringTokens.delete(keyringTokens.keys().next().value);
561
+ keyringTokens.set(origin, readKeyringPassword(ACCESS_KEYRING_SERVICE, account));
562
+ }
563
+ const stored = keyringTokens.get(origin);
564
+ if (!challenged && stored && usableToken(stored)) {
565
+ rememberOriginToken(origin, stored);
566
+ return;
567
+ }
568
+ if (!challenged && !required && !stored && !headers["cf-access-token"]) return;
569
+ const rejectedTokens = new Set([
570
+ headers["cf-access-token"],
571
+ stored,
572
+ rejectedToken
573
+ ].filter((token) => typeof token === "string" && token.length > 0));
574
+ if (challenged && rejectedTokens.size > 0) {
575
+ forgetOriginToken(origin);
576
+ keyringTokens.set(origin, null);
577
+ if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error(`platform: Cloudflare Access rejected the cached credential for ${origin}. Re-run this command in an interactive terminal to renew it.`);
578
+ console.error(`Renew Cloudflare Access authentication for ${origin}.`);
579
+ runCloudflared([
580
+ "access",
581
+ "login",
582
+ origin
583
+ ], {
584
+ inherit: true,
585
+ timeoutMs: 12e4
586
+ });
587
+ }
588
+ let token = runCloudflared([
589
+ "access",
590
+ "token",
591
+ `-app=${origin}`
592
+ ]);
593
+ if (token && rejectedTokens.has(token)) token = null;
594
+ if ((!token || !usableToken(token)) && process.stdin.isTTY && process.stdout.isTTY) {
595
+ console.error(`Authenticate to Cloudflare Access for ${origin}.`);
596
+ runCloudflared([
597
+ "access",
598
+ "login",
599
+ origin
600
+ ], {
601
+ inherit: true,
602
+ timeoutMs: 12e4
603
+ });
604
+ token = runCloudflared([
605
+ "access",
606
+ "token",
607
+ `-app=${origin}`
608
+ ]);
609
+ }
610
+ if (!token || !usableToken(token)) throw new Error("platform: Cloudflare Access authentication is required. Install cloudflared and sign in interactively, or set VOID_ACCESS_ORIGIN with scoped CF_ACCESS_CLIENT_ID/CF_ACCESS_CLIENT_SECRET credentials for CI.");
611
+ rememberOriginToken(origin, token);
612
+ keyringTokens.set(origin, token);
613
+ writeKeyringPassword(ACCESS_KEYRING_SERVICE, account, token);
614
+ }
615
+ const probedHosts = /* @__PURE__ */ new Set();
616
+ /**
617
+ * If the CLI is about to talk to a Cloudflare-Access-gated staging host,
618
+ * probe the locally-installed `cloudflared` binary for a cached user JWT
619
+ * and export it as `CF_ACCESS_TOKEN`. On interactive shells with no cached
620
+ * token, open a browser login flow to populate the cache, then re-read it.
621
+ *
622
+ * Cached per-host so that an early non-gated call (e.g. prod) does not
623
+ * permanently disable the probe for a later gated call (e.g. staging) in
624
+ * the same process. Noop when:
625
+ * - a service-token pair is already set (CI path)
626
+ * - `CF_ACCESS_TOKEN` is already set (manual override or prior probe)
627
+ * - the target host is not gated
628
+ * - `cloudflared` is not installed
629
+ */
630
+ function ensureCloudflaredToken(apiUrl) {
631
+ if (!isVoidAccessGatedUrl(apiUrl) || process.env.VOID_ACCESS_ORIGIN || process.env.VOID_ACCESS_CREDENTIALS) {
632
+ ensurePlatformAccessToken(apiUrl);
633
+ return;
634
+ }
635
+ if (process.env.CF_ACCESS_CLIENT_ID && process.env.CF_ACCESS_CLIENT_SECRET) return;
636
+ if (process.env.CF_ACCESS_TOKEN) return;
637
+ if (!isVoidAccessGatedUrl(apiUrl)) return;
638
+ const host = new URL(apiUrl).hostname;
639
+ if (probedHosts.has(host)) return;
640
+ probedHosts.add(host);
641
+ let token = runCloudflared([
642
+ "access",
643
+ "token",
644
+ `-app=${apiUrl}`
645
+ ]);
646
+ if (!token && process.stdin.isTTY && process.stdout.isTTY) {
647
+ runCloudflared([
648
+ "access",
649
+ "login",
650
+ apiUrl
651
+ ], {
652
+ inherit: true,
653
+ timeoutMs: 12e4
654
+ });
655
+ token = runCloudflared([
656
+ "access",
657
+ "token",
658
+ `-app=${apiUrl}`
659
+ ]);
660
+ }
661
+ if (token) process.env.CF_ACCESS_TOKEN = token;
662
+ }
663
+ function runCloudflared(args, opts) {
664
+ try {
665
+ const result = spawnSync("cloudflared", args, {
666
+ encoding: "utf-8",
667
+ stdio: opts?.inherit ? "inherit" : [
668
+ "ignore",
669
+ "pipe",
670
+ "pipe"
671
+ ],
672
+ timeout: opts?.timeoutMs ?? 5e3
673
+ });
674
+ if (result.error || result.status !== 0) return null;
675
+ const out = (result.stdout ?? "").trim();
676
+ return out.length > 0 ? out : null;
677
+ } catch {
678
+ return null;
679
+ }
680
+ }
681
+ /** A protected API and proxy have separate audiences and separately scoped credentials. */
682
+ function ensurePlatformProxyAccess(apiUrl, proxyUrl) {
683
+ ensurePlatformAccessToken(apiUrl);
684
+ ensurePlatformAccessToken(proxyUrl, false, Object.keys(cfAccessHeaders(process.env, apiUrl)).length > 0);
685
+ }
686
+ //#endregion
508
687
  //#region ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
509
688
  const getCodePointsLength = (() => {
510
689
  const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
@@ -1175,6 +1354,50 @@ var r = class extends y {
1175
1354
  });
1176
1355
  }
1177
1356
  };
1357
+ var a = class extends y {
1358
+ options;
1359
+ cursor = 0;
1360
+ get _value() {
1361
+ return this.options[this.cursor]?.value;
1362
+ }
1363
+ get _enabledOptions() {
1364
+ return this.options.filter((e) => e.disabled !== true);
1365
+ }
1366
+ toggleAll() {
1367
+ const e = this._enabledOptions, i = this.value !== void 0 && this.value.length === e.length;
1368
+ this.value = i ? [] : e.map((t) => t.value);
1369
+ }
1370
+ toggleInvert() {
1371
+ const e = this.value;
1372
+ if (!e) return;
1373
+ const i = this._enabledOptions.filter((t) => !e.includes(t.value));
1374
+ this.value = i.map((t) => t.value);
1375
+ }
1376
+ toggleValue() {
1377
+ this.value === void 0 && (this.value = []);
1378
+ const e = this.value.includes(this._value);
1379
+ this.value = e ? this.value.filter((i) => i !== this._value) : [...this.value, this._value];
1380
+ }
1381
+ constructor(e) {
1382
+ super(e, false), this.options = e.options, this.value = [...e.initialValues ?? []];
1383
+ const i = Math.max(this.options.findIndex(({ value: t }) => t === e.cursorAt), 0);
1384
+ this.cursor = this.options[i]?.disabled ? findCursor(i, 1, this.options) : i, this.on("key", (t, l) => {
1385
+ l.name === "a" && this.toggleAll(), l.name === "i" && this.toggleInvert();
1386
+ }), this.on("cursor", (t) => {
1387
+ switch (t) {
1388
+ case "left":
1389
+ case "up":
1390
+ this.cursor = findCursor(this.cursor, -1, this.options);
1391
+ break;
1392
+ case "down":
1393
+ case "right":
1394
+ this.cursor = findCursor(this.cursor, 1, this.options);
1395
+ break;
1396
+ case "space": this.toggleValue();
1397
+ }
1398
+ });
1399
+ }
1400
+ };
1178
1401
  let u$1 = class u extends y {
1179
1402
  _mask = "•";
1180
1403
  get cursor() {
@@ -1252,6 +1475,7 @@ var n = class extends y {
1252
1475
  //#endregion
1253
1476
  //#region ../../node_modules/.pnpm/@clack+prompts@1.8.0/node_modules/@clack/prompts/dist/index.mjs
1254
1477
  var dist_exports = /* @__PURE__ */ __exportAll({
1478
+ MULTISELECT_INSTRUCTIONS: () => MULTISELECT_INSTRUCTIONS,
1255
1479
  SELECT_INSTRUCTIONS: () => SELECT_INSTRUCTIONS,
1256
1480
  S_BAR: () => S_BAR,
1257
1481
  S_BAR_END: () => S_BAR_END,
@@ -1259,6 +1483,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1259
1483
  S_BAR_START: () => S_BAR_START,
1260
1484
  S_CHECKBOX_ACTIVE: () => S_CHECKBOX_ACTIVE,
1261
1485
  S_CHECKBOX_INACTIVE: () => S_CHECKBOX_INACTIVE,
1486
+ S_CHECKBOX_SELECTED: () => S_CHECKBOX_SELECTED,
1262
1487
  S_CONNECT_LEFT: () => S_CONNECT_LEFT,
1263
1488
  S_CORNER_BOTTOM_LEFT: () => S_CORNER_BOTTOM_LEFT,
1264
1489
  S_CORNER_BOTTOM_RIGHT: () => S_CORNER_BOTTOM_RIGHT,
@@ -1282,6 +1507,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
1282
1507
  isCancel: () => isCancel,
1283
1508
  limitOptions: () => limitOptions,
1284
1509
  log: () => log,
1510
+ multiselect: () => multiselect,
1285
1511
  note: () => note,
1286
1512
  outro: () => outro,
1287
1513
  password: () => password,
@@ -1310,6 +1536,7 @@ const S_BAR_END = unicodeOr("└", "—");
1310
1536
  const S_RADIO_ACTIVE = unicodeOr("●", ">");
1311
1537
  const S_RADIO_INACTIVE = unicodeOr("○", " ");
1312
1538
  const S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
1539
+ const S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
1313
1540
  const S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
1314
1541
  const S_PASSWORD_MASK = unicodeOr("▪", "•");
1315
1542
  const S_BAR_H = unicodeOr("─", "-");
@@ -1417,7 +1644,94 @@ ${g}
1417
1644
  }
1418
1645
  }).prompt();
1419
1646
  };
1420
- `${styleText("dim", "↑/↓")}`, `${styleText("dim", "Space:")}`, `${styleText("dim", "Enter:")}`;
1647
+ const MULTISELECT_INSTRUCTIONS = [
1648
+ `${styleText("dim", "↑/↓")} to navigate`,
1649
+ `${styleText("dim", "Space:")} select`,
1650
+ `${styleText("dim", "Enter:")} confirm`
1651
+ ];
1652
+ const m = (i, u) => i.split(`
1653
+ `).map((d) => u(d)).join(`
1654
+ `);
1655
+ const multiselect = (i) => {
1656
+ const u = (t, a) => {
1657
+ const r = t.label ?? String(t.value);
1658
+ return a === "disabled" ? `${styleText("gray", S_CHECKBOX_INACTIVE)} ${m(r, (o) => styleText(["strikethrough", "gray"], o))}${t.hint ? ` ${styleText("dim", `(${t.hint ?? "disabled"})`)}` : ""}` : a === "active" ? `${styleText("cyan", S_CHECKBOX_ACTIVE)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${m(r, (o) => styleText("dim", o))}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "cancelled" ? `${m(r, (o) => styleText(["strikethrough", "dim"], o))}` : a === "active-selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "submitted" ? `${m(r, (o) => styleText("dim", o))}` : `${styleText("dim", S_CHECKBOX_INACTIVE)} ${m(r, (o) => styleText("dim", o))}`;
1659
+ }, d = i.required ?? true, v = i.showInstructions ?? true;
1660
+ return new a({
1661
+ options: i.options,
1662
+ signal: i.signal,
1663
+ input: i.input,
1664
+ output: i.output,
1665
+ initialValues: i.initialValues,
1666
+ required: d,
1667
+ cursorAt: i.cursorAt,
1668
+ validate(t) {
1669
+ if (d && (t === void 0 || t.length === 0)) return `Please select at least one option.
1670
+ ${styleText("reset", styleText("dim", `Press ${styleText([
1671
+ "gray",
1672
+ "bgWhite",
1673
+ "inverse"
1674
+ ], " space ")} to select, ${styleText("gray", styleText("bgWhite", styleText("inverse", " enter ")))} to submit`))}`;
1675
+ },
1676
+ render() {
1677
+ const t = i.withGuide ?? settings.withGuide, a = wrapTextWithPrefix(i.output, i.message, t ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r = `${t ? `${styleText("gray", S_BAR)}
1678
+ ` : ""}${a}
1679
+ `, o = this.value ?? [], p = (n, l) => {
1680
+ if (n.disabled) return u(n, "disabled");
1681
+ const s = o.includes(n.value);
1682
+ return l && s ? u(n, "active-selected") : s ? u(n, "selected") : u(n, l ? "active" : "inactive");
1683
+ };
1684
+ switch (this.state) {
1685
+ case "submit": {
1686
+ const n = this.options.filter(({ value: s }) => o.includes(s)).map((s) => u(s, "submitted")).join(styleText("dim", ", ")) || styleText("dim", "none");
1687
+ return `${r}${wrapTextWithPrefix(i.output, n, t ? `${styleText("gray", S_BAR)} ` : "")}`;
1688
+ }
1689
+ case "cancel": {
1690
+ const n = this.options.filter(({ value: s }) => o.includes(s)).map((s) => u(s, "cancelled")).join(styleText("dim", ", "));
1691
+ if (n.trim() === "") return `${r}${styleText("gray", S_BAR)}`;
1692
+ return `${r}${wrapTextWithPrefix(i.output, n, t ? `${styleText("gray", S_BAR)} ` : "")}${t ? `
1693
+ ${styleText("gray", S_BAR)}` : ""}`;
1694
+ }
1695
+ case "error": {
1696
+ const n = t ? `${styleText("yellow", S_BAR)} ` : "", l = this.error.split(`
1697
+ `).map(($, C) => C === 0 ? `${t ? `${styleText("yellow", S_BAR_END)} ` : ""}${styleText("yellow", $)}` : ` ${$}`).join(`
1698
+ `), s = r.split(`
1699
+ `).length, h = l.split(`
1700
+ `).length + 1;
1701
+ return `${r}${n}${limitOptions({
1702
+ output: i.output,
1703
+ options: this.options,
1704
+ cursor: this.cursor,
1705
+ maxItems: i.maxItems,
1706
+ columnPadding: n.length,
1707
+ rowPadding: s + h,
1708
+ style: p
1709
+ }).join(`
1710
+ ${n}`)}
1711
+ ${l}
1712
+ `;
1713
+ }
1714
+ default: {
1715
+ const n = t ? `${styleText("cyan", S_BAR)} ` : "", l = r.split(`
1716
+ `).length, s = v ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t) : t ? [styleText("cyan", S_BAR_END)] : [], h = s.join(`
1717
+ `), $ = s.length + 1;
1718
+ return `${r}${n}${limitOptions({
1719
+ output: i.output,
1720
+ options: this.options,
1721
+ cursor: this.cursor,
1722
+ maxItems: i.maxItems,
1723
+ columnPadding: n.length,
1724
+ rowPadding: l + $,
1725
+ style: p
1726
+ }).join(`
1727
+ ${n}`)}
1728
+ ${h}
1729
+ `;
1730
+ }
1731
+ }
1732
+ }
1733
+ }).prompt();
1734
+ };
1421
1735
  const log = {
1422
1736
  message: (s = [], { symbol: e = styleText("gray", S_BAR), secondarySymbol: r = styleText("gray", S_BAR), output: m = process.stdout, spacing: l = 1, withGuide: c } = {}) => {
1423
1737
  const t = [], o = c ?? settings.withGuide, f = o ? r : "", O = o ? `${e} ` : "", u = o ? `${r} ` : "";
@@ -1916,4 +2230,4 @@ function ensureUtc(s) {
1916
2230
  return s + "Z";
1917
2231
  }
1918
2232
  //#endregion
1919
- export { resolveInstallationManifest as $, password as A, assertPlatformInstallationSlugAvailable as B, cancel as C, log as D, intro as E, isCancel as F, normalizePlatformApiUrl as G, latestPlatformWorkerCutoverGeneration as H, settings as I, promoteInstallationSecrets as J, platformCredentialAccount as K, u$1 as L, symbol as M, text as N, note as O, CANCEL_SYMBOL as P, removePlatformConnectionForInstallation as Q, wrapAnsi as R, S_STEP_SUBMIT as S, dist_exports as T, listInstallationManifests as U, getActivePlatformConnection as V, listPlatformConnections as W, readPendingInstallationSecrets as X, readInstallationRecoverySecrets as Y, removeInstallationRecoverySecrets as Z, S_CHECKBOX_INACTIVE as _, dim as a, readKeyringPassword as at, S_RADIO_INACTIVE as b, import_picocolors as c, formatCloudflareUserMessage as d, savePlatformConnection as et, detectAgents as f, S_CHECKBOX_ACTIVE as g, S_BAR_END as h, createSpinner as i, deleteKeyringPassword as it, select as j, outro as k, sectionTitle as l, S_BAR as m, cliCommandName as n, writeInstallationManifest as nt, ensureUtc as o, writeKeyringPassword as ot, getPackageDir as p, platformWorkerSecretUpdateIntentState as q, cliTitle as r, writePendingInstallationSecrets as rt, helpLine as s, require_picocolors as st, categoryTitle as t, selectPlatformConnection as tt, tablePrefix as u, S_PASSWORD_MASK as v, confirm as w, S_STEP_ACTIVE as x, S_RADIO_ACTIVE as y, acquirePlatformLifecycleLock as z };
2233
+ export { promoteInstallationSecrets as $, outro as A, ensureCloudflaredToken as B, cancel as C, log as D, intro as E, CANCEL_SYMBOL as F, assertPlatformInstallationSlugAvailable as G, ensurePlatformProxyAccess as H, isCancel as I, listInstallationManifests as J, getActivePlatformConnection as K, settings as L, select as M, symbol as N, multiselect as O, text as P, platformWorkerSecretUpdateIntentState as Q, u$1 as R, S_STEP_SUBMIT as S, dist_exports as T, isCloudflareAccessChallenge as U, ensurePlatformAccessToken as V, acquirePlatformLifecycleLock as W, normalizePlatformApiUrl as X, listPlatformConnections as Y, platformCredentialAccount as Z, S_CHECKBOX_INACTIVE as _, dim as a, savePlatformConnection as at, S_RADIO_INACTIVE as b, import_picocolors as c, writePendingInstallationSecrets as ct, formatCloudflareUserMessage as d, writeKeyringPassword as dt, readInstallationRecoverySecrets as et, detectAgents as f, require_picocolors as ft, S_CHECKBOX_ACTIVE as g, S_BAR_END as h, createSpinner as i, resolveInstallationManifest as it, password as j, note as k, sectionTitle as l, deleteKeyringPassword as lt, S_BAR as m, cliCommandName as n, removeInstallationRecoverySecrets as nt, ensureUtc as o, selectPlatformConnection as ot, getPackageDir as p, latestPlatformWorkerCutoverGeneration as q, cliTitle as r, removePlatformConnectionForInstallation as rt, helpLine as s, writeInstallationManifest as st, categoryTitle as t, readPendingInstallationSecrets as tt, tablePrefix as u, readKeyringPassword as ut, S_PASSWORD_MASK as v, confirm as w, S_STEP_ACTIVE as x, S_RADIO_ACTIVE as y, wrapAnsi as z };
@@ -1,7 +1,7 @@
1
1
  import { o as join } from "../dist-BrsS7cai.mjs";
2
2
  import { r as resolvePagesDir } from "../project-paths-SK8nMHPp.mjs";
3
- import { f as readConfig } from "../config-BQFq7QvD.mjs";
4
- import { i as parseRedirectsFile } from "../headers-D8QfRX9Y.mjs";
3
+ import { f as readConfig } from "../config-uNGuFsI2.mjs";
4
+ import { i as parseRedirectsFile } from "../headers-BAHwgHdW.mjs";
5
5
  import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, r as resolveLayoutChain, t as scanPages } from "../scan-CpK-57ug.mjs";
6
6
  import { renderBodyAttrs, renderHeadToString, renderHtmlAttrs, resolveHead } from "./head.mjs";
7
7
  import { serializePageData } from "./serialize.mjs";