void 0.24.0 → 0.25.0

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 (137) hide show
  1. package/README.md +19 -106
  2. package/dist/{account-cmd-vJhh5lrb.mjs → account-cmd-DcR1ywt8.mjs} +5 -5
  3. package/dist/{auth-CQkSDS50.mjs → auth-7wuZ5ob8.mjs} +3 -3
  4. package/dist/{auth-DX3JURcX.mjs → auth-CdgZ9uag.mjs} +1 -1
  5. package/dist/{auth-link-D75t9wO2.mjs → auth-link-Z6E5DYvM.mjs} +5 -6
  6. package/dist/{auth-router-ClfhL1J7.mjs → auth-router-BdM4avI8.mjs} +7 -7
  7. package/dist/{build-cmd-zMi1iFnS.mjs → build-cmd-CEE7D-hM.mjs} +6 -7
  8. package/dist/{cache-ZtQmyxVV.mjs → cache-TcZnBLtH.mjs} +6 -7
  9. package/dist/{cancel-deploy-Box0kkEV.mjs → cancel-deploy-CYoZmcmR.mjs} +4 -6
  10. package/dist/{cf-access-BGe5sWXF.mjs → cf-access-AHKBzmuu.mjs} +1 -1
  11. package/dist/cf-build-output-ChY6-XWP.mjs +2 -0
  12. package/dist/cli/cli.mjs +45 -45
  13. package/dist/cli/cloudflare-operation-process.mjs +2 -2
  14. package/dist/cli/env-schema-probe.mjs +2 -2
  15. package/dist/client-B4Me-9HE.mjs +2 -0
  16. package/dist/{client-DKAsFA4X.mjs → client-RsPo8wsP.mjs} +103 -25
  17. package/dist/{cloudflare-cmd-CmY8dGkd.mjs → cloudflare-cmd-bhwCxAN6.mjs} +2 -2
  18. package/dist/{cloudflare-connect-IiR3ZieC.mjs → cloudflare-connect-CuhRgk3k.mjs} +2 -2
  19. package/dist/{cloudflare-operations-BCdXSsmo.mjs → cloudflare-operations-BhbK6yTq.mjs} +1 -1
  20. package/dist/{cloudflare-operations-DzH-A966.mjs → cloudflare-operations-CjaV4lZi.mjs} +2 -2
  21. package/dist/{connect-B-usTnlF.mjs → connect-DCvUmPXY.mjs} +12 -9
  22. package/dist/{create-project-FWbf5Olo.mjs → create-project-C734I-Mu.mjs} +1 -1
  23. package/dist/{create-project-CYOOAYcn.mjs → create-project-eAPgYq35.mjs} +6 -6
  24. package/dist/{db-Ck2eZ2iB.mjs → db-C07GEdKF.mjs} +25 -28
  25. package/dist/{delete-sK56qtzZ.mjs → delete-pKMVsrpJ.mjs} +5 -6
  26. package/dist/deploy-BDu1vhSH.mjs +2 -0
  27. package/dist/{deploy-gCVaiJbS.mjs → deploy-DfsAe-T0.mjs} +9212 -8902
  28. package/dist/{dev-inbox-P0u4tM8Y.mjs → dev-inbox-D64ZKUod.mjs} +5 -6
  29. package/dist/{domain-DFfQE8jg.mjs → domain-D3uA9ize.mjs} +8 -8
  30. package/dist/{email-CdnhUHvJ.mjs → email-z3o2cwjH.mjs} +7 -7
  31. package/dist/{env-DmGdHi5i.mjs → env-3Q8-_2IH.mjs} +6 -8
  32. package/dist/{env-validation-zZOCcQVZ.mjs → env-validation-cZBvGWaP.mjs} +1 -1
  33. package/dist/gen-ById9r2j.mjs +2 -0
  34. package/dist/{gen-CshAkukR.mjs → gen-NjwoG9FK.mjs} +2 -4
  35. package/dist/{github-cmd-DftuEvIt.mjs → github-cmd-DquUq-b1.mjs} +7 -16
  36. package/dist/help-DPGBwomV.mjs +2 -0
  37. package/dist/{help-Dotbf6iz.mjs → help-DRZXC4fj.mjs} +3 -3
  38. package/dist/index.d.mts +18 -14
  39. package/dist/index.mjs +2166 -2096
  40. package/dist/{info-B97bTX9N.mjs → info-BmA3_IFZ.mjs} +1 -3
  41. package/dist/{init-BTQEZZGJ.mjs → init-DT7yuuyl.mjs} +16 -18
  42. package/dist/{link-B46sYH0K.mjs → link-CXOlqh2F.mjs} +6 -7
  43. package/dist/{list-BnPrIsU_.mjs → list-eEWVJEPn.mjs} +8 -9
  44. package/dist/{local-d1-2CMnpuW_.mjs → local-d1-Df4XpwhW.mjs} +1 -1
  45. package/dist/login-C98-sw79.mjs +2 -0
  46. package/dist/{login-BuiMyUrx.mjs → login-pWQHYVu2.mjs} +9 -7
  47. package/dist/{logs-CZG9d-ic.mjs → logs-DnxVX7TR.mjs} +7 -8
  48. package/dist/migrate-CEu2X5DB.mjs +2 -0
  49. package/dist/{migrate-q4_njtaW.mjs → migrate-CV1on-yJ.mjs} +2 -4
  50. package/dist/{operator-args-B3BTmSoi.mjs → operator-args-CAVcmwUt.mjs} +1 -1
  51. package/dist/{operator-auth-7erYc6Lt.mjs → operator-auth-CkmTE3rt.mjs} +2 -2
  52. package/dist/{operator-client-CpHjTd0t.mjs → operator-client-LmwjxT6q.mjs} +2 -2
  53. package/dist/{operator-cmd-DGqPJUD3.mjs → operator-cmd-d-IEKgNk.mjs} +6 -6
  54. package/dist/{output-CbM85T4k.mjs → output-BBsUwdyT.mjs} +5 -5
  55. package/dist/pages/client.d.mts +3 -0
  56. package/dist/pages/client.mjs +120 -29
  57. package/dist/{platform-args-3k8X9-H_.mjs → platform-args-Bzf8JPc2.mjs} +1 -1
  58. package/dist/platform-args-Cq6EjQro.mjs +2 -0
  59. package/dist/{platform-auth-config-DDrxUy4m.mjs → platform-auth-config-0V0lA3pF.mjs} +7 -7
  60. package/dist/{platform-auth-protection-BLadnnct.mjs → platform-auth-protection-DFeJ-JkK.mjs} +8 -8
  61. package/dist/{platform-auth-recovery-CmCzX2Fl.mjs → platform-auth-recovery-ICy4muq6.mjs} +7 -7
  62. package/dist/{platform-cmd-pMTRhvYs.mjs → platform-cmd-BPySFOew.mjs} +1 -1
  63. package/dist/{platform-cmd-DMDEc9uS.mjs → platform-cmd-D7vSWMvV.mjs} +37 -27
  64. package/dist/platform-discovery-DDDUvnqp.mjs +27 -0
  65. package/dist/{platform-domain-Di6EYrQl.mjs → platform-domain-CUdY064e.mjs} +4 -4
  66. package/dist/{platform-lifecycle-BFdSi9Qt.mjs → platform-lifecycle-BaUdTRPU.mjs} +1 -1
  67. package/dist/{platform-lifecycle-BBoNzojY.mjs → platform-lifecycle-Dm09JNkn.mjs} +3901 -3651
  68. package/dist/{platform-management-CWOQOWXm.mjs → platform-management-BSEc_ZeG.mjs} +47 -10
  69. package/dist/platform-management-Bp6aoH2C.mjs +2 -0
  70. package/dist/{platform-plans-config-Vl9BP3H4.mjs → platform-plans-config-B0pOVQyW.mjs} +3 -3
  71. package/dist/{platform-recovery-BJnQJEtQ.mjs → platform-recovery-WOZ95Uze.mjs} +3 -3
  72. package/dist/{prepare-CBLT3CHH.mjs → prepare-39EvOhI6.mjs} +1 -3
  73. package/dist/{project-DKG5Ra8p.mjs → project-BkbfDs0V.mjs} +1 -1
  74. package/dist/{project-DsblYifa.mjs → project-IOjBU8R6.mjs} +1 -1
  75. package/dist/{project-cmd-DxnXstAq.mjs → project-cmd-Bs5A392E.mjs} +21 -22
  76. package/dist/{project-team-BmHcaALJ.mjs → project-team-ohAWWaew.mjs} +8 -9
  77. package/dist/{project-token-GionZlBI.mjs → project-token-CP01Jna6.mjs} +6 -9
  78. package/dist/{project-zero-trust-JLCjVQA7.mjs → project-zero-trust-BzkVgx35.mjs} +5 -6
  79. package/dist/{prompts-BNUoTiaf.mjs → prompts-6OSVA7DJ.mjs} +58 -15
  80. package/dist/{prompts-2TGE6oXx.mjs → prompts-ZAuJlyCj.mjs} +1 -1
  81. package/dist/{provision-CVku1JFU.mjs → provision-BEv0k-qz.mjs} +1 -1
  82. package/dist/{provision-CaoxO_U7.mjs → provision-Btj1jppf.mjs} +5 -7
  83. package/dist/{requests-BOjIVAeF.mjs → requests-B3PBuGlX.mjs} +5 -6
  84. package/dist/{rollback-CwR3pLj3.mjs → rollback-DDub9GsO.mjs} +9 -10
  85. package/dist/runtime/email/testing.mjs +1 -1
  86. package/dist/runtime/email.mjs +35 -17
  87. package/dist/runtime/routing.mjs +1 -1
  88. package/dist/{secret-ByWJWBUG.mjs → secret-3c72lY1U.mjs} +15 -16
  89. package/dist/{skills-C1PlclPt.mjs → skills-BPQUGClu.mjs} +1 -1
  90. package/dist/{subcommand-prompt-klFCfcor.mjs → subcommand-prompt-Dhom39bd.mjs} +2 -2
  91. package/dist/sveltekit.d.mts +1 -1
  92. package/dist/sveltekit.mjs +4 -9
  93. package/dist/{wrangler-7K-bW_DL.mjs → wrangler-DhUerFkW.mjs} +10 -15
  94. package/package.json +21 -21
  95. package/sandbox.Dockerfile +1 -1
  96. package/skills/void/docs/guide/ai.md +24 -86
  97. package/skills/void/docs/guide/auth.md +0 -2
  98. package/skills/void/docs/guide/database/d1.md +7 -7
  99. package/skills/void/docs/guide/deployment.md +58 -124
  100. package/skills/void/docs/guide/env-vars.md +1 -5
  101. package/skills/void/docs/guide/index.md +19 -18
  102. package/skills/void/docs/guide/kv.md +0 -2
  103. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +49 -47
  104. package/skills/void/docs/guide/pages-routing/overview.md +2 -2
  105. package/skills/void/docs/guide/platform/administration/email.md +0 -2
  106. package/skills/void/docs/guide/platform/administration/operations.md +11 -22
  107. package/skills/void/docs/guide/platform/administration/plans.md +1 -5
  108. package/skills/void/docs/guide/platform/administration/zero-trust.md +1 -4
  109. package/skills/void/docs/guide/platform/development/schema-ci.md +7 -1
  110. package/skills/void/docs/guide/platform/installation/maintenance.md +30 -10
  111. package/skills/void/docs/guide/platform/installation/prerequisites.md +79 -7
  112. package/skills/void/docs/guide/quickstart.md +37 -80
  113. package/skills/void/docs/guide/sandboxes.md +36 -46
  114. package/skills/void/docs/guide/self-hosted-platform.md +20 -0
  115. package/skills/void/docs/guide/websockets.md +0 -2
  116. package/skills/void/docs/integrations/frameworks/overview.md +2 -2
  117. package/skills/void/docs/integrations/frameworks/sveltekit.md +40 -25
  118. package/skills/void/docs/integrations/nodejs-bun-deno.md +7 -2
  119. package/skills/void/docs/reference/api/resources.md +27 -0
  120. package/skills/void/docs/reference/api.md +1 -1
  121. package/skills/void/docs/reference/cli/deploy.md +1 -1
  122. package/skills/void/docs/reference/cli/platform-operations.md +4 -8
  123. package/skills/void/docs/reference/cli/platform.md +5 -0
  124. package/skills/void/docs/reference/resource-inference.md +11 -8
  125. package/dist/cf-build-output-_0HNWysu.mjs +0 -2
  126. package/dist/client-B9UBI03V.mjs +0 -2
  127. package/dist/deploy-irP5q0-x.mjs +0 -2
  128. package/dist/gen-DvQTWzDU.mjs +0 -2
  129. package/dist/help-mabuIV98.mjs +0 -2
  130. package/dist/login-DIy9Sb-U.mjs +0 -2
  131. package/dist/migrate-BCiJ8w0f.mjs +0 -2
  132. package/dist/platform-args-DdnM6WIf.mjs +0 -2
  133. package/dist/platform-management-DG47jys8.mjs +0 -2
  134. package/skills/void/docs/guide/env-migration.md +0 -109
  135. package/dist/{cf-build-output-BPqOT964.mjs → cf-build-output-U8o1Gl6X.mjs} +1 -1
  136. package/dist/{env-validation-C_8tPdhs.mjs → env-validation-vBSQ8gw5.mjs} +1 -1
  137. package/dist/{platform-registry-DkPPXfp_.mjs → platform-registry-KfNEF84O.mjs} +1 -1
@@ -1,12 +1,11 @@
1
- import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-DKG5Ra8p.mjs";
2
- import { c as getToken } from "./auth-CQkSDS50.mjs";
3
- import { A as confirm, H as outro, K as select, L as log, N as intro, O as cancel, tt as isCancel } from "./prompts-BNUoTiaf.mjs";
4
- import { n as PlatformClient } from "./client-DKAsFA4X.mjs";
5
- import { a as dim, c as import_picocolors, i as createSpinner, o as ensureUtc, r as cliTitle } from "./output-CbM85T4k.mjs";
1
+ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { A as confirm, H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { a as ensureUtc, c as import_picocolors, i as dim, o as formatCount, r as createSpinner } from "./output-BBsUwdyT.mjs";
6
6
  //#region src/cli/rollback.ts
7
7
  async function runRollbackCommand(root, deployId) {
8
8
  console.log();
9
- intro(cliTitle("project rollback"));
10
9
  const platform = readDeploymentPlatform(root);
11
10
  if (platform === "cloudflare") return runCloudflareRollback(root, deployId);
12
11
  if (platform === "none") throw new Error("rollback: Deployment is disabled. Run `void init` to choose a platform.");
@@ -56,7 +55,7 @@ async function runRollbackCommand(root, deployId) {
56
55
  const targetMigrations = target.applied_migrations ? JSON.parse(target.applied_migrations) : [];
57
56
  const migrationDiff = currentMigrations.filter((m) => !targetMigrations.includes(m));
58
57
  if (migrationDiff.length > 0) {
59
- log.warn(`The current database has ${migrationDiff.length} migration(s) applied after this deployment:`);
58
+ log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this deployment:`);
60
59
  for (const m of migrationDiff) log.message(` ${dim("•")} ${m}`);
61
60
  log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
62
61
  const proceed = await confirm({ message: "Proceed with rollback?" });
@@ -83,7 +82,7 @@ async function runRollbackCommand(root, deployId) {
83
82
  outro(dim("Traffic is now serving the rolled-back deployment."));
84
83
  }
85
84
  async function runCloudflareRollback(root, deployId) {
86
- const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BCdXSsmo.mjs");
85
+ const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BhbK6yTq.mjs");
87
86
  const context = resolveCloudflareOperationContext(root);
88
87
  const status = await readCloudflareWorkerStatus(context);
89
88
  const deployedVersionIds = new Set(status.deployedVersionIds);
@@ -109,7 +108,7 @@ async function runCloudflareRollback(root, deployId) {
109
108
  options: candidates.map((version) => ({
110
109
  value: version.id,
111
110
  label: `${version.id} ${dim(formatAge(version.createdAt))}`,
112
- hint: version.metadata ? `${version.metadata.migrations.length} migration(s)` : "migration state unknown"
111
+ hint: version.metadata ? formatCount(version.metadata.migrations.length, "migration") : "migration state unknown"
113
112
  }))
114
113
  });
115
114
  if (isCancel(result)) {
@@ -131,7 +130,7 @@ async function runCloudflareRollback(root, deployId) {
131
130
  const targetSet = new Set(target.metadata.migrations);
132
131
  const migrationDiff = current.metadata.migrations.filter((migration) => !targetSet.has(migration));
133
132
  if (migrationDiff.length > 0) {
134
- log.warn(`The current database has ${migrationDiff.length} migration(s) applied after this version:`);
133
+ log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this version:`);
135
134
  for (const migration of migrationDiff) log.message(` ${dim("•")} ${migration}`);
136
135
  log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
137
136
  const proceed = await confirm({ message: "Proceed with rollback?" });
@@ -1,6 +1,6 @@
1
1
  import { i as normalizeEmail, r as buildMime } from "../../mime-D5Nmdzf7.mjs";
2
2
  import { n as compileEmailPattern, t as compareEmailRoutes } from "../../email--tEtMoj_.mjs";
3
- import { y as registerEmailSink } from "../../dev-inbox-P0u4tM8Y.mjs";
3
+ import { y as registerEmailSink } from "../../dev-inbox-D64ZKUod.mjs";
4
4
  import { i as createMessageProxy, n as MAX_INBOUND_HEADERS, t as MAX_INBOUND_BYTES } from "../../inbound-fRkqcXaC.mjs";
5
5
  //#region src/runtime/email/testing.ts
6
6
  /**
@@ -1,7 +1,8 @@
1
1
  import { i as normalizeEmail, n as MimeError, r as buildMime } from "../mime-D5Nmdzf7.mjs";
2
- import { a as DEV_INBOX_ENV_VAR, b as serializeCapturedMessage, c as DEV_INBOX_TOKEN_ENV_VAR, d as captureMessage, h as hasActiveSink, i as DEV_INBOX_CAPTURE_URL, p as dispatchToSinks } from "../dev-inbox-P0u4tM8Y.mjs";
2
+ import { a as DEV_INBOX_ENV_VAR, b as serializeCapturedMessage, c as DEV_INBOX_TOKEN_ENV_VAR, d as captureMessage, h as hasActiveSink, i as DEV_INBOX_CAPTURE_URL, p as dispatchToSinks } from "../dev-inbox-D64ZKUod.mjs";
3
3
  import { a as getRawRuntimeEnv } from "../env-raw-Cx8ElDdj.mjs";
4
4
  import { a as defineEmail, c as parseEmail, i as createMessageProxy, l as replyEmail, o as enactEmailActions, r as ParseEmailError, s as isForwardableEmailMessage } from "../inbound-fRkqcXaC.mjs";
5
+ import { isRecord } from "@void/deploy-core";
5
6
  //#region src/runtime/email.ts
6
7
  const VALID_SLUG = /^[a-z0-9](?:[a-z0-9-]{0,54}[a-z0-9])?$/;
7
8
  function makeError(code, message, cause) {
@@ -232,7 +233,7 @@ function coerceErrorCode(code) {
232
233
  "IDEMPOTENCY_CONFLICT",
233
234
  "OUTCOME_UNKNOWN",
234
235
  "UPSTREAM_ERROR"
235
- ].includes(code) ? code : "UPSTREAM_ERROR";
236
+ ].find((knownCode) => knownCode === code) ?? "UPSTREAM_ERROR";
236
237
  }
237
238
  /**
238
239
  * The text of a refusal the proxy's middleware sent instead of a send
@@ -247,13 +248,30 @@ function readProxyRefusal(body) {
247
248
  if (typeof error !== "string" || error === "") return null;
248
249
  return typeof message === "string" && message !== "" ? message : error;
249
250
  }
250
- function isValidProxyResponse(b) {
251
- if (typeof b !== "object" || b === null) return false;
252
- const r = b;
253
- if (r.ok === true && Array.isArray(r.ids)) return true;
254
- if (r.ok === false && typeof r.error === "object" && r.error !== null) return true;
255
- if (r.ok === false && Array.isArray(r.deliveries)) return true;
256
- return false;
251
+ function readProxyResponse(value) {
252
+ if (!isRecord(value)) return null;
253
+ const operationId = value.operationId;
254
+ if (value.ok === true && Array.isArray(value.ids)) return {
255
+ ok: true,
256
+ ids: value.ids,
257
+ operationId
258
+ };
259
+ if (value.ok !== false) return null;
260
+ if (Array.isArray(value.deliveries)) return {
261
+ ok: false,
262
+ deliveries: value.deliveries,
263
+ operationId
264
+ };
265
+ const error = value.error;
266
+ if (typeof error === "object" && error !== null) return {
267
+ ok: false,
268
+ error: {
269
+ code: "code" in error ? error.code : void 0,
270
+ message: "message" in error ? error.message : void 0
271
+ },
272
+ operationId
273
+ };
274
+ return null;
257
275
  }
258
276
  /**
259
277
  * Require exactly one valid outcome per requested recipient in either list
@@ -410,31 +428,31 @@ async function readResponseAsResult(res, recipients, fallbackId, beforeDeadline)
410
428
  } catch {
411
429
  return err("OUTCOME_UNKNOWN", `email: could not establish the send outcome (status ${res.status}); check email logs or repeat the same idempotency key`);
412
430
  }
413
- if (!isValidProxyResponse(body)) {
431
+ const response = readProxyResponse(body);
432
+ if (response === null) {
414
433
  const refusal = readProxyRefusal(body);
415
434
  if (!res.ok && refusal !== null) return err("UPSTREAM_ERROR", `email: proxy returned ${res.status}: ${refusal}`, body);
416
435
  return err("OUTCOME_UNKNOWN", `email: proxy returned malformed response (status ${res.status})`, body);
417
436
  }
418
437
  const malformedList = (reason) => err("OUTCOME_UNKNOWN", `email: proxy returned a malformed delivery list (${reason}); do not retry with a new idempotency key`, body);
419
- const operation = typeof body.operationId === "string" && body.operationId.length <= 128 ? { operationId: body.operationId } : {};
420
- if (body.ok === true) {
421
- const list = readDeliveryList(body.ids, recipients, fallbackId);
438
+ const operation = typeof response.operationId === "string" && response.operationId.length <= 128 ? { operationId: response.operationId } : {};
439
+ if (response.ok === true) {
440
+ const list = readDeliveryList(response.ids, recipients, fallbackId);
422
441
  return list.ok ? {
423
442
  ok: true,
424
443
  ids: list.entries,
425
444
  ...operation
426
445
  } : malformedList(list.reason);
427
446
  }
428
- const failure = body;
429
- if (Array.isArray(failure.deliveries)) {
430
- const list = readFailureDeliveries(failure.deliveries, recipients, fallbackId);
447
+ if ("deliveries" in response) {
448
+ const list = readFailureDeliveries(response.deliveries, recipients, fallbackId);
431
449
  return list.ok ? {
432
450
  ok: false,
433
451
  deliveries: list.entries,
434
452
  ...operation
435
453
  } : malformedList(list.reason);
436
454
  }
437
- const e = failure.error;
455
+ const e = response.error;
438
456
  return {
439
457
  ...err(coerceErrorCode(e.code), typeof e.message === "string" ? e.message : "email: upstream send failed"),
440
458
  ...operation
@@ -1,8 +1,8 @@
1
1
  import { t as convertReturnValue } from "../response-Tn7rU0MV.mjs";
2
2
  import { t as VoidAssetRewriteError } from "../handler-DghKr6dU.mjs";
3
3
  import { n as handlePageGet, r as handlePageMutation } from "../protocol-U7bfjHmA.mjs";
4
- import { compilePattern, mergeQueryIntoLocation, substituteParams } from "@void/edge";
5
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
+ import { compilePattern, mergeQueryIntoLocation, substituteParams } from "@void/edge";
6
6
  //#region src/runtime/routing-errors.ts
7
7
  const __VOID_ERROR_PAGE_FONT_STACK = "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif";
8
8
  const errorStack = Error;
@@ -1,15 +1,14 @@
1
- import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-DKG5Ra8p.mjs";
2
- import { c as getToken } from "./auth-CQkSDS50.mjs";
3
- import { _ as validateSecretValues } from "./env-validation-C_8tPdhs.mjs";
4
- import { A as confirm, B as note, H as outro, L as log, N as intro, O as cancel, U as password, tt as isCancel } from "./prompts-BNUoTiaf.mjs";
5
- import { n as PlatformClient } from "./client-DKAsFA4X.mjs";
6
- import { r as cliTitle } from "./output-CbM85T4k.mjs";
1
+ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { _ as validateSecretValues } from "./env-validation-vBSQ8gw5.mjs";
4
+ import { A as confirm, B as note, H as outro, L as log, O as cancel, U as password, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
5
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
6
+ import { o as formatCount } from "./output-BBsUwdyT.mjs";
7
7
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
8
8
  import { readFileSync } from "node:fs";
9
9
  //#region src/cli/secret.ts
10
10
  async function runSecretCommand(root, args) {
11
11
  console.log();
12
- intro(cliTitle("secret"));
13
12
  const platform = readDeploymentPlatform(root);
14
13
  if (platform === "cloudflare") return runCloudflareSecretCommand(root, args);
15
14
  if (platform === "none") throw new Error("secret: Deployment is disabled. Run `void init` to choose a platform.");
@@ -38,7 +37,7 @@ async function runSecretCommand(root, args) {
38
37
  return;
39
38
  }
40
39
  note(secrets.map((s) => ` ${s.name}`).join("\n"), "Secrets");
41
- outro(`${secrets.length} secret(s)`);
40
+ outro(formatCount(secrets.length, "secret"));
42
41
  return;
43
42
  }
44
43
  if (args.action === "put") {
@@ -59,9 +58,9 @@ async function runSecretCommand(root, args) {
59
58
  return;
60
59
  }
61
60
  await validateSecretValues(root, secrets);
62
- log.info(`Found ${secrets.length} secret(s):`);
61
+ log.info(`Found ${formatCount(secrets.length, "secret")}:`);
63
62
  for (const s of secrets) log.message(` ${s.name}`);
64
- const proceed = await confirm({ message: `This will overwrite ${secrets.length} secret(s) in the remote environment. Continue?` });
63
+ const proceed = await confirm({ message: `This will overwrite ${formatCount(secrets.length, "secret")} in the remote environment. Continue?` });
65
64
  if (isCancel(proceed) || !proceed) {
66
65
  cancel("Secret sync cancelled.");
67
66
  process.exit(0);
@@ -70,7 +69,7 @@ async function runSecretCommand(root, args) {
70
69
  await client.setSecret(projectId, s.name, s.value);
71
70
  log.success(`Set ${s.name}`);
72
71
  }
73
- outro(`Synced ${secrets.length} secret(s).`);
72
+ outro(`Synced ${formatCount(secrets.length, "secret")}.`);
74
73
  return;
75
74
  }
76
75
  await client.deleteSecret(projectId, args.name);
@@ -78,7 +77,7 @@ async function runSecretCommand(root, args) {
78
77
  }
79
78
  async function runCloudflareSecretCommand(root, args) {
80
79
  if (args.projectName) throw new Error("secret: --project selects a Void platform project and is not used for direct Cloudflare apps.");
81
- const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-BCdXSsmo.mjs");
80
+ const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-BhbK6yTq.mjs");
82
81
  const context = resolveCloudflareOperationContext(root);
83
82
  if (args.action === "list") {
84
83
  const secrets = await listCloudflareSecrets(context);
@@ -87,7 +86,7 @@ async function runCloudflareSecretCommand(root, args) {
87
86
  return;
88
87
  }
89
88
  note(secrets.map((name) => ` ${name}`).join("\n"), "Secrets");
90
- outro(`${secrets.length} secret(s)`);
89
+ outro(formatCount(secrets.length, "secret"));
91
90
  return;
92
91
  }
93
92
  if (args.action === "put") {
@@ -108,15 +107,15 @@ async function runCloudflareSecretCommand(root, args) {
108
107
  return;
109
108
  }
110
109
  await validateSecretValues(root, secrets);
111
- log.info(`Found ${secrets.length} secret(s):`);
110
+ log.info(`Found ${formatCount(secrets.length, "secret")}:`);
112
111
  for (const secret of secrets) log.message(` ${secret.name}`);
113
- const proceed = await confirm({ message: `This will overwrite ${secrets.length} secret(s) in the Cloudflare Worker. Continue?` });
112
+ const proceed = await confirm({ message: `This will overwrite ${formatCount(secrets.length, "secret")} in the Cloudflare Worker. Continue?` });
114
113
  if (isCancel(proceed) || !proceed) {
115
114
  cancel("Secret sync cancelled.");
116
115
  process.exit(0);
117
116
  }
118
117
  await syncCloudflareSecrets(context, secrets);
119
- outro(`Synced ${secrets.length} secret(s).`);
118
+ outro(`Synced ${formatCount(secrets.length, "secret")}.`);
120
119
  return;
121
120
  }
122
121
  await deleteCloudflareSecret(context, args.name);
@@ -1,5 +1,5 @@
1
1
  import { a as join, l as relative } from "./dist-BVqXeR_h.mjs";
2
- import { L as log } from "./prompts-BNUoTiaf.mjs";
2
+ import { L as log } from "./prompts-6OSVA7DJ.mjs";
3
3
  import { n as getPackageDir } from "./agents-B_pX_HmQ.mjs";
4
4
  import { existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, symlinkSync } from "node:fs";
5
5
  //#region src/cli/skills.ts
@@ -1,5 +1,5 @@
1
- import { $ as wrapTextWithPrefix, G as promptTitle, M as getGuide, V as optionText, b as S_RADIO_ACTIVE, d as S_CHECKBOX_SELECTED, i as S_BAR_END, it as wrapAnsi, j as formatInstructionFooter, n as SELECT_INSTRUCTIONS, r as S_BAR, t as MULTISELECT_INSTRUCTIONS, u as S_CHECKBOX_INACTIVE, w as S_STEP_SUBMIT } from "./prompts-BNUoTiaf.mjs";
2
- import { c as import_picocolors } from "./output-CbM85T4k.mjs";
1
+ import { $ as wrapTextWithPrefix, G as promptTitle, M as getGuide, V as optionText, b as S_RADIO_ACTIVE, d as S_CHECKBOX_SELECTED, i as S_BAR_END, it as wrapAnsi, j as formatInstructionFooter, n as SELECT_INSTRUCTIONS, r as S_BAR, t as MULTISELECT_INSTRUCTIONS, u as S_CHECKBOX_INACTIVE, w as S_STEP_SUBMIT } from "./prompts-6OSVA7DJ.mjs";
2
+ import { c as import_picocolors } from "./output-BBsUwdyT.mjs";
3
3
  //#region src/cli/subcommand-prompt.ts
4
4
  function promptSubcommand(command, subcommands) {
5
5
  return new Promise((resolve) => {
@@ -4,7 +4,7 @@ type TsconfigHook = (config: Tsconfig) => Tsconfig | void;
4
4
  export type VoidSvelteKitTsconfigOptions = {
5
5
  /** Project root. Defaults to process.cwd(). */
6
6
  root?: string;
7
- /** SvelteKit output directory. Defaults to ".svelte-kit". */
7
+ /** @deprecated Generated paths no longer depend on SvelteKit's output directory. */
8
8
  outDir?: string;
9
9
  };
10
10
  /**
@@ -1,4 +1,4 @@
1
- import { a as join, i as isAbsolute, l as relative, u as resolve } from "./dist-BVqXeR_h.mjs";
1
+ import { a as join, i as isAbsolute, u as resolve } from "./dist-BVqXeR_h.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  //#region src/sveltekit.ts
4
4
  /**
@@ -7,18 +7,17 @@ import { existsSync, readFileSync } from "node:fs";
7
7
  * `kit.typescript.config` in `svelte.config.js`.
8
8
  */
9
9
  function mergeVoidSvelteKitTsconfig(config, options = {}) {
10
- const root = options.root ?? process.cwd();
10
+ const root = resolve(options.root ?? process.cwd());
11
11
  const voidDir = join(root, ".void");
12
12
  const voidTsconfigPath = join(voidDir, "tsconfig.json");
13
13
  if (!existsSync(voidTsconfigPath)) return config;
14
14
  const voidConfig = JSON.parse(readFileSync(voidTsconfigPath, "utf-8"));
15
- const outputDir = resolve(root, options.outDir ?? ".svelte-kit");
16
15
  const voidFiles = Array.isArray(voidConfig.files) ? voidConfig.files.filter((entry) => typeof entry === "string") : [];
17
- if (voidFiles.length > 0) config.files = uniqueStrings([...Array.isArray(config.files) ? config.files.filter((entry) => typeof entry === "string") : [], ...voidFiles.map((entry) => relativeFrom(outputDir, resolveTsconfigEntry(voidDir, entry)))]);
16
+ if (voidFiles.length > 0) config.files = uniqueStrings([...Array.isArray(config.files) ? config.files.filter((entry) => typeof entry === "string") : [], ...voidFiles.map((entry) => resolveTsconfigEntry(voidDir, entry))]);
18
17
  const voidPaths = readPathMap(readObject(readObject(voidConfig.compilerOptions)?.paths));
19
18
  if (Object.keys(voidPaths).length > 0) {
20
19
  const paths = ensureObject(ensureObject(config, "compilerOptions"), "paths");
21
- for (const [key, values] of Object.entries(voidPaths)) paths[key] = values.map((entry) => relativeFrom(outputDir, resolveTsconfigEntry(voidDir, entry)));
20
+ for (const [key, values] of Object.entries(voidPaths)) paths[key] = values.map((entry) => resolveTsconfigEntry(voidDir, entry));
22
21
  }
23
22
  return config;
24
23
  }
@@ -51,10 +50,6 @@ function readPathMap(value) {
51
50
  function resolveTsconfigEntry(baseDir, entry) {
52
51
  return isAbsolute(entry) ? entry : resolve(baseDir, entry);
53
52
  }
54
- function relativeFrom(fromDir, target) {
55
- const value = relative(fromDir, target);
56
- return value.startsWith(".") ? value : `./${value}`;
57
- }
58
53
  function uniqueStrings(values) {
59
54
  return Array.from(new Set(values));
60
55
  }
@@ -4,7 +4,7 @@ import { m as readConfig } from "./config-Br_JZD6u.mjs";
4
4
  import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, r as SANDBOX_MIGRATION_TAG } from "./config-C_XRIPx2.mjs";
5
5
  import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-Bktvwtpf.mjs";
6
6
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
7
- import { appendSqliteClassMigration } from "@void/deploy-core";
7
+ import { appendSqliteClassMigration, isRecord } from "@void/deploy-core";
8
8
  import { createHash } from "node:crypto";
9
9
  import { SyntaxKind, applyEdits, createScanner, findNodeAtLocation, modify, parse, parseTree } from "jsonc-parser";
10
10
  //#region src/cli/wrangler.ts
@@ -686,7 +686,10 @@ function writeProvisionedWranglerConfig(root, patch, options) {
686
686
  const matches = [];
687
687
  for (let i = 0; i < currentList.length; i++) {
688
688
  const entry = currentList[i];
689
- if (isRecord(entry) && entry[identityKey] === binding) matches.push(i);
689
+ if (isRecord(entry) && entry[identityKey] === binding) matches.push({
690
+ index: i,
691
+ entry
692
+ });
690
693
  }
691
694
  if (matches.length > 1) throw new Error(`deploy: cannot update "${configPath}" — binding ${JSON.stringify(binding)} is declared ${matches.length} times in "${field}". Void cannot choose which entry to update, and wrangler rejects duplicate binding names. Remove the duplicate and retry.`);
692
695
  const owners = collectWorkerBindingNames(configWithoutField(currentConfig, field));
@@ -694,8 +697,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
694
697
  const owner = owners.get(binding);
695
698
  if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — cannot adopt ${JSON.stringify(binding)} into "${field}" because that binding name is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this would make the config undeployable. Rename the conflicting binding and retry.`);
696
699
  if (matches.length === 1) {
697
- const index = matches[0];
698
- const existing = isRecord(currentList[index]) ? currentList[index] : {};
700
+ const { index, entry: existing } = matches[0];
699
701
  for (const [key, value] of Object.entries(properties)) if (!jsonEqual(existing[key], value)) set([
700
702
  field,
701
703
  index,
@@ -752,20 +754,16 @@ function writeProvisionedWranglerConfig(root, patch, options) {
752
754
  const upsertQueueEntries = (section, entries) => {
753
755
  if (!entries || entries.length === 0) return;
754
756
  const currentQueues = assertObjectContainer(parseJsonc(text).queues, "queues");
755
- if (section === "producers") assertValidQueueProducers(currentQueues?.producers);
756
- const currentList = Array.isArray(currentQueues?.[section]) ? [...currentQueues[section]] : [];
757
+ const currentList = section === "producers" ? assertValidQueueProducers(currentQueues?.producers) : Array.isArray(currentQueues?.consumers) ? [...currentQueues.consumers] : [];
757
758
  for (const entry of entries) {
758
759
  let index;
759
760
  if (section === "producers") {
760
761
  const matches = [];
761
- for (let i = 0; i < currentList.length; i++) {
762
- const existing = currentList[i];
763
- if (isRecord(existing) && existing.binding === entry.binding) matches.push(i);
764
- }
762
+ for (let i = 0; i < currentList.length; i++) if (currentList[i].binding === entry.binding) matches.push(i);
765
763
  if (matches.length > 1) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is declared ${matches.length} times across producers. A producer binding must map to exactly one queue, so wrangler rejects this config. Remove the duplicate producers and retry.`);
766
764
  if (matches.length === 1) {
767
765
  const existing = currentList[matches[0]];
768
- if (isRecord(existing) && existing.queue !== entry.queue) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is already bound to queue ${JSON.stringify(existing.queue)}, but queue ${JSON.stringify(entry.queue)} also requests it. A producer binding must map to exactly one queue. Rename or remove the conflicting producer and retry.`);
766
+ if (existing.queue !== entry.queue) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is already bound to queue ${JSON.stringify(existing.queue)}, but queue ${JSON.stringify(entry.queue)} also requests it. A producer binding must map to exactly one queue. Rename or remove the conflicting producer and retry.`);
769
767
  }
770
768
  index = matches.length === 1 ? matches[0] : -1;
771
769
  workerBindingOwners ??= collectWorkerBindingNames(parseJsonc(text));
@@ -774,7 +772,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
774
772
  if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(bindingName)} is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this producer would make the config undeployable. Rename the conflicting binding (or the queue) and retry.`);
775
773
  } else index = currentList.findIndex((existing) => isRecord(existing) && existing.queue === entry.queue);
776
774
  if (index >= 0) {
777
- const existing = isRecord(currentList[index]) ? currentList[index] : {};
775
+ const existing = currentList[index];
778
776
  for (const [key, value] of Object.entries(entry)) {
779
777
  if (value === void 0) continue;
780
778
  if (!jsonEqual(existing[key], value)) set([
@@ -1243,9 +1241,6 @@ function offsetToLineColumn(text, offset) {
1243
1241
  column
1244
1242
  };
1245
1243
  }
1246
- function isRecord(value) {
1247
- return typeof value === "object" && value !== null && !Array.isArray(value);
1248
- }
1249
1244
  function validateDurableObjectMigrations(value, configPath) {
1250
1245
  if (value === void 0) return [];
1251
1246
  if (!Array.isArray(value)) throw new Error(`deploy: cannot update "${configPath}" — "migrations" must be an array of Durable Object migration steps.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -331,24 +331,24 @@
331
331
  }
332
332
  },
333
333
  "dependencies": {
334
- "@cloudflare/build-output-utils": "0.8.4",
335
- "@cloudflare/codemods": "0.3.0",
336
- "@cloudflare/config": "0.22.0",
334
+ "@cloudflare/build-output-utils": "0.8.5",
335
+ "@cloudflare/codemods": "0.4.0",
336
+ "@cloudflare/config": "0.23.0",
337
337
  "@cloudflare/sandbox": "1.0.0",
338
- "@cloudflare/vite-plugin": "1.62.2",
339
- "@cloudflare/workers-auth": "0.9.5",
338
+ "@cloudflare/vite-plugin": "1.62.5",
339
+ "@cloudflare/workers-auth": "0.12.0",
340
340
  "@cloudflare/workers-types": "^4.20260702.1",
341
341
  "@napi-rs/keyring": "2.1.0",
342
- "@void/deploy-cloudflare": "0.24.0",
343
- "@void/deploy-core": "0.24.0",
344
- "@void/edge": "0.24.0",
345
- "@void/isr": "0.24.0",
346
- "@void/platform": "0.24.0",
342
+ "@void/deploy-cloudflare": "0.25.0",
343
+ "@void/deploy-core": "0.25.0",
344
+ "@void/edge": "0.25.0",
345
+ "@void/isr": "0.25.0",
346
+ "@void/platform": "0.25.0",
347
347
  "acorn": "^8.18.0",
348
- "better-auth": "^1.7.6",
348
+ "better-auth": "^1.7.7",
349
349
  "better-sqlite3": "^13.0.3",
350
350
  "blake3-jit": "^1.1.0",
351
- "cf": "1.0.0-beta.9",
351
+ "cf": "1.0.0-beta.12",
352
352
  "drizzle-arktype": "^0.1.3",
353
353
  "drizzle-kit": "^0.31.11",
354
354
  "drizzle-orm": "^0.45.3",
@@ -356,27 +356,27 @@
356
356
  "drizzle-zod": "^0.8.3",
357
357
  "email-validator": "^2.0.4",
358
358
  "es-module-lexer": "^3.0.2",
359
- "hono": "^4.13.11",
360
- "ignore": "^7.0.10",
359
+ "hono": "^4.13.13",
360
+ "ignore": "^7.0.12",
361
361
  "jiti": "^2.7.0",
362
362
  "jsonc-parser": "3.3.1",
363
363
  "mime": "4.1.0",
364
- "miniflare": "5.20260926.1-alpha",
364
+ "miniflare": "5.20261001.0-alpha",
365
365
  "minimatch": "^10.2.6",
366
366
  "mysql2": "3.24.5",
367
- "pg": "8.23.0",
368
- "postal-mime": "^4.0.0",
367
+ "pg": "8.23.1",
368
+ "postal-mime": "^4.0.4",
369
369
  "proper-lockfile": "^4.1.2",
370
370
  "undici": "8.11.2"
371
371
  },
372
372
  "devDependencies": {
373
373
  "@electric-sql/pglite": "0.5.8",
374
374
  "@types/better-sqlite3": "^9.6.0",
375
- "@types/node": "^26.6.3",
375
+ "@types/node": "^26.6.4",
376
376
  "@types/pg": "^8.23.1",
377
377
  "@types/proper-lockfile": "^4.1.4",
378
378
  "@voidzero-dev/vite-plus-prompts": "0.0.0",
379
- "arktype": "^2.2.5",
379
+ "arktype": "^2.2.7",
380
380
  "ci-info": "^4.4.0",
381
381
  "estree-walker": "^3.0.3",
382
382
  "fast-wrap-ansi": "^0.2.2",
@@ -393,7 +393,7 @@
393
393
  "zod": "^4.6.5"
394
394
  },
395
395
  "peerDependencies": {
396
- "@void/md": "0.24.0",
396
+ "@void/md": "0.25.0",
397
397
  "arktype": ">=2.0.0",
398
398
  "valibot": ">=1.0.0-beta.7",
399
399
  "vite": "^8.0.0",
@@ -1,4 +1,4 @@
1
- FROM node:24.21.0-trixie-slim
1
+ FROM node:26.10.0-trixie-slim
2
2
  COPY --from=docker.io/cloudflare/sandbox:1.0.0 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
3
3
  WORKDIR /workspace
4
4
  CMD ["sleep", "infinity"]