void 1.2.1 → 1.3.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 (166) hide show
  1. package/dist/{account-cmd-CdUll_35.mjs → account-cmd-B4i71m7k.mjs} +3 -3
  2. package/dist/{application-analysis-fEqoSeMp.mjs → application-analysis-DYdVoMAY.mjs} +8 -6
  3. package/dist/{application-routing-DAhNP4u3.mjs → application-routing-C8EqRDfv.mjs} +3 -1
  4. package/dist/{auth-link-C87vGXM-.mjs → auth-link-BKwHPbdv.mjs} +3 -3
  5. package/dist/{auth-router-6I81r-ix.mjs → auth-router-DqLx8E0F.mjs} +2 -2
  6. package/dist/{better-auth-shared-D-6z0q0f.mjs → better-auth-shared-7FM3Uk2N.mjs} +48 -2
  7. package/dist/{build-cmd-ex1g-j_e.mjs → build-cmd-Dy4psnt1.mjs} +1 -1
  8. package/dist/{cache-oHzrnY3z.mjs → cache-DV37S6dl.mjs} +1 -1
  9. package/dist/{cancel-deploy-viAMD0Q_.mjs → cancel-deploy-DMPyu1Vt.mjs} +1 -1
  10. package/dist/{cf-build-output-BhVxldCw.mjs → cf-build-output-Bapzc_8Z.mjs} +102 -1
  11. package/dist/cf-build-output-DlBkWdNU.mjs +1 -0
  12. package/dist/cli/cli.mjs +41 -32
  13. package/dist/cli/cloudflare-operation-process.mjs +27 -6
  14. package/dist/cli/env-schema-probe.mjs +2 -2
  15. package/dist/{client-BEkdj1kx.mjs → client-BEMtySaV.mjs} +8 -1
  16. package/dist/client-DyxPQnF_.mjs +1 -0
  17. package/dist/{cloudflare-cmd-DMzCv12s.mjs → cloudflare-cmd-BaqIigwI.mjs} +1 -1
  18. package/dist/{cloudflare-connect-CCRTVg-I.mjs → cloudflare-connect-pNLQmr_e.mjs} +1 -1
  19. package/dist/{cloudflare-operations-DsSaw2BT.mjs → cloudflare-operations-PCM4wucv.mjs} +1 -1
  20. package/dist/{cloudflare-operations-Dh9dEHJj.mjs → cloudflare-operations-vP3b5CQf.mjs} +3 -3
  21. package/dist/config-BTu1o3Dc.mjs +49 -0
  22. package/dist/{config-DQfHOKh9.d.mts → config-Du88-7Y8.d.mts} +2 -1
  23. package/dist/config-entry.d.mts +1 -1
  24. package/dist/{connect-k7R2rPVA.mjs → connect-DwVsBvVh.mjs} +4 -4
  25. package/dist/{create-project-DTuy-l0z.mjs → create-project-CgrnvzyA.mjs} +1 -1
  26. package/dist/{create-project-DV71ol5d.mjs → create-project-CjzbBlTv.mjs} +1 -1
  27. package/dist/{db-DVOkLH5X.mjs → db-rvo64snS.mjs} +13 -13
  28. package/dist/{delete-BbP5eopu.mjs → delete-DWX6dP4M.mjs} +1 -1
  29. package/dist/deploy-CtHE2A3R.mjs +2 -0
  30. package/dist/{deploy-7H32EnUs.mjs → deploy-hRPvw8ci.mjs} +229 -69
  31. package/dist/{deploy-managed-static-DlvcvnQT.mjs → deploy-managed-static-CDYA2p3L.mjs} +30 -14
  32. package/dist/{deploy-transport-BzGEj0Ge.mjs → deploy-transport-JCxw7QDi.mjs} +3 -3
  33. package/dist/deploy.mjs +4 -3
  34. package/dist/{dispatch-DoUnxTNo.mjs → dispatch-OVLeWW8K.mjs} +71 -2
  35. package/dist/{domain-CA2wBgra.mjs → domain-CH5iBD9Y.mjs} +2 -2
  36. package/dist/{email-DXpCc77w.mjs → email-CbTO1l78.mjs} +58 -9
  37. package/dist/{email-cloudflare-D03g2TkS.mjs → email-cloudflare-B8-pq_-W.mjs} +106 -5
  38. package/dist/{env-DgOQ9_8S.mjs → env-BBdw236G.mjs} +3 -3
  39. package/dist/{env-BJjULvL0.mjs → env-BaMz0j7H.mjs} +6 -1
  40. package/dist/{env-validation-BmsdCZEk.mjs → env-validation-BfBVvBNe.mjs} +1 -1
  41. package/dist/{env-validation-Dwq3PJzK.mjs → env-validation-XcukUlFM.mjs} +1 -1
  42. package/dist/{gen-BfmcIi2g.mjs → gen-CCx3t2Ju.mjs} +1 -1
  43. package/dist/gen-TgXy93Rr.mjs +1 -0
  44. package/dist/{github-cmd-CY9LUqLh.mjs → github-cmd-BzkRLkbg.mjs} +1 -1
  45. package/dist/{handler-BbkSPzGF.d.mts → handler-CQv5YDS0.d.mts} +1 -1
  46. package/dist/{help-CxSlPpzJ.mjs → help-CKbrhZha.mjs} +16 -1
  47. package/dist/help-qOZr3wng.mjs +1 -0
  48. package/dist/index.d.mts +2 -4
  49. package/dist/index.mjs +317 -122
  50. package/dist/{info-7VDlhtyy.mjs → info-oBm8yK8J.mjs} +2 -2
  51. package/dist/{init-DxYyOs4-.mjs → init-CBp_uMve.mjs} +217 -197
  52. package/dist/{link-Ddmod1dZ.mjs → link-Dt_QXmM4.mjs} +2 -2
  53. package/dist/{list-MogaugiO.mjs → list-DF6asTdt.mjs} +2 -2
  54. package/dist/{live-Bt8Y_0bg.d.mts → live-CXJ9yC98.d.mts} +1 -1
  55. package/dist/{local-d1-BHBnKWRb.mjs → local-d1-CUhH3qtj.mjs} +1 -1
  56. package/dist/{login-Cttnagmm.mjs → login-BjSyhXlT.mjs} +2 -2
  57. package/dist/login-Cdo8Aco1.mjs +1 -0
  58. package/dist/{logs-CAszUWZI.mjs → logs-DmvBl6xA.mjs} +2 -2
  59. package/dist/{migrate-DyT2jJ8y.mjs → migrate-BXRHpYwR.mjs} +1 -1
  60. package/dist/migrate-COPncCGx.mjs +1 -0
  61. package/dist/nitro.mjs +2 -2
  62. package/dist/{node-WB7c2N4L.mjs → node-DtD7ZiPf.mjs} +4 -4
  63. package/dist/{operator-args-UnE8Y2eK.mjs → operator-args-BsJIYXaT.mjs} +8 -1
  64. package/dist/operator-cmd-DDiX7Y3f.mjs +1 -0
  65. package/dist/{operator-cmd-skshjMGl.mjs → operator-cmd-DjZKGGgN.mjs} +4 -3
  66. package/dist/pages/client.d.mts +17 -4
  67. package/dist/pages/client.mjs +161 -29
  68. package/dist/pages/index.d.mts +18 -2
  69. package/dist/pages/index.mjs +2 -52
  70. package/dist/pages/islands-plugin.d.mts +1 -1
  71. package/dist/pages/islands-plugin.mjs +9 -3
  72. package/dist/pages/protocol.d.mts +2 -2
  73. package/dist/platform-args-BC8_hsDj.mjs +1 -0
  74. package/dist/{platform-args-DVbVClZl.mjs → platform-args-BMD2gjc_.mjs} +1 -1
  75. package/dist/{platform-auth-config-C-pm5Qzx.mjs → platform-auth-config-BgnuMbml.mjs} +3 -3
  76. package/dist/{platform-auth-protection-SHhvim1L.mjs → platform-auth-protection-NjRejttU.mjs} +2 -2
  77. package/dist/{platform-auth-recovery-DXVWs-wA.mjs → platform-auth-recovery-Ug12d9W5.mjs} +2 -2
  78. package/dist/{platform-cmd-PiNRkopU.mjs → platform-cmd-BYKLMPCn.mjs} +1 -1
  79. package/dist/{platform-cmd-D5I1beUX.mjs → platform-cmd-HByuZAO7.mjs} +4 -4
  80. package/dist/{platform-domain-jpmBfZeb.mjs → platform-domain-DLSQ8GF8.mjs} +2 -2
  81. package/dist/{platform-lifecycle-DyKmuNY6.mjs → platform-lifecycle-3dwFJmnq.mjs} +102 -40
  82. package/dist/{platform-lifecycle-DH3Yr1qQ.mjs → platform-lifecycle-BRqcxerG.mjs} +1 -1
  83. package/dist/{platform-management-7m-PLaPJ.mjs → platform-management-ZK6XcbCo.mjs} +1 -1
  84. package/dist/{platform-management--vDwSn35.mjs → platform-management-ZZ6bQM5j.mjs} +1 -1
  85. package/dist/{platform-recovery-BiNpZZab.mjs → platform-recovery-8vNE5dNN.mjs} +2 -2
  86. package/dist/{plugin-inference-DUjCd55H.mjs → plugin-inference-CeiB6BG5.mjs} +53 -18
  87. package/dist/{prepare-BcAE5Sdj.mjs → prepare-5BR7Splm.mjs} +1 -1
  88. package/dist/prepare-B3VrSF1Z.mjs +1 -0
  89. package/dist/{prepare-DA-17DhO.mjs → prepare-Dseww74N.mjs} +4 -4
  90. package/dist/{prerender-render-Cijv7UFo.mjs → prerender-render-CaShbHJ3.mjs} +13 -1
  91. package/dist/prerender-render.d.mts +1 -0
  92. package/dist/prerender-render.mjs +1 -1
  93. package/dist/{project-cmd-DA4K5faU.mjs → project-cmd-CjLNNxwe.mjs} +15 -15
  94. package/dist/{project-team-CQBNveX3.mjs → project-team-DE5drjcl.mjs} +1 -1
  95. package/dist/{project-token-CCalFyQf.mjs → project-token-XEYEXfiJ.mjs} +1 -1
  96. package/dist/{project-zero-trust-DPnkiEuT.mjs → project-zero-trust-6VPU8zmV.mjs} +1 -1
  97. package/dist/{protocol-BBDpJz3G.d.mts → protocol-BekmFxCI.d.mts} +2 -2
  98. package/dist/{provision-DtROpNNI.mjs → provision-B7UFrBH7.mjs} +1 -1
  99. package/dist/{provision-BFLCrnUp.mjs → provision-Chq0NRAV.mjs} +1 -1
  100. package/dist/{requests-BpH0kImL.mjs → requests-CG-Pj8ze.mjs} +1 -1
  101. package/dist/{rollback-CXS1tAa-.mjs → rollback-CIrm2txZ.mjs} +2 -2
  102. package/dist/{route-types-BZi26DVS.mjs → route-types--PAOzHlH.mjs} +49 -28
  103. package/dist/routes-stub.d.mts +22 -13
  104. package/dist/runtime/better-auth-mysql.mjs +1 -1
  105. package/dist/runtime/better-auth-pg.mjs +1 -1
  106. package/dist/runtime/better-auth.mjs +1 -1
  107. package/dist/runtime/handler.d.mts +1 -1
  108. package/dist/runtime/live-client.d.mts +1 -1
  109. package/dist/runtime/live.d.mts +1 -1
  110. package/dist/runtime/log.mjs +19 -1
  111. package/dist/runtime/routing.d.mts +2 -2
  112. package/dist/runtime/routing.mjs +4 -3
  113. package/dist/runtime/validator.d.mts +1 -1
  114. package/dist/runtime/ws-server.d.mts +1 -1
  115. package/dist/runtime/ws.d.mts +1 -1
  116. package/dist/{scan-8IzYXiU_.mjs → scan-N9WzdcAl.mjs} +302 -23
  117. package/dist/{secret-BbXHfLAt.mjs → secret-BL6g7mF5.mjs} +3 -3
  118. package/dist/static-asset-marker-Btf-6oCD.mjs +32 -0
  119. package/dist/{types-7AIz0OZu.d.mts → types-w72dljaA.d.mts} +6 -1
  120. package/dist/{version-metadata-tS39iW09.mjs → version-metadata-DmaZNTYW.mjs} +1 -1
  121. package/dist/worker-conditions-AWFRcFxR.mjs +11 -0
  122. package/dist/{wrangler-F96NnLyb.mjs → wrangler-CDiEBCdS.mjs} +2 -1
  123. package/dist/wrangler-DOPr4jyI.mjs +1 -0
  124. package/dist/{wrapper-D3sZyh2C.mjs → wrapper-CEiDeCqD.mjs} +6 -10
  125. package/dist/{ws-BH-im_tX.d.mts → ws-D1zWiB_P.d.mts} +1 -1
  126. package/docs/guide/auth.md +3 -1
  127. package/docs/guide/edge/static-assets.md +10 -0
  128. package/docs/guide/email/domains.md +1 -1
  129. package/docs/guide/email/receiving.md +2 -0
  130. package/docs/guide/email/sending.md +1 -1
  131. package/docs/guide/pages-routing/actions-and-forms.md +19 -13
  132. package/docs/guide/pages-routing/markdown.md +2 -0
  133. package/docs/guide/pages-routing/overview.md +33 -2
  134. package/docs/guide/platform/administration/email.md +18 -0
  135. package/docs/guide/platform/installation/prerequisites.md +9 -4
  136. package/docs/guide/platform/installation/uninstall.md +2 -0
  137. package/docs/guide/queues.md +13 -1
  138. package/docs/guide/server-routing.md +38 -2
  139. package/docs/guide/type-safety.md +7 -7
  140. package/docs/guide/websockets.md +4 -2
  141. package/docs/reference/api/pages.md +4 -4
  142. package/docs/reference/cli/email.md +13 -0
  143. package/docs/reference/cli/platform-email.md +2 -2
  144. package/docs/reference/cli.md +1 -0
  145. package/docs/reference/structure.md +3 -1
  146. package/package.json +8 -7
  147. package/templates/assets/icons.svg +49 -0
  148. package/templates/assets/react.svg +1 -0
  149. package/templates/assets/solid.svg +1 -0
  150. package/templates/assets/stack.svg +35 -0
  151. package/templates/assets/svelte.svg +1 -0
  152. package/templates/assets/void.svg +5 -0
  153. package/templates/assets/vue.svg +1 -0
  154. package/dist/cf-build-output-BJHuSsVN.mjs +0 -1
  155. package/dist/client-BiRDZTSd.mjs +0 -1
  156. package/dist/config-CyUJzi3q.mjs +0 -32
  157. package/dist/deploy-CE0Ev0Ob.mjs +0 -2
  158. package/dist/gen-NrOlWZaG.mjs +0 -1
  159. package/dist/help-BeAFFE5C.mjs +0 -1
  160. package/dist/login-DgDwlKc_.mjs +0 -1
  161. package/dist/migrate-n49ZeS1X.mjs +0 -1
  162. package/dist/operator-cmd-d2MvJOrl.mjs +0 -1
  163. package/dist/parse-filename-DioPHiR9.mjs +0 -77
  164. package/dist/platform-args-kQrgxScY.mjs +0 -1
  165. package/dist/prepare-C4I0f--h.mjs +0 -1
  166. package/dist/wrangler-BLb3_luP.mjs +0 -1
@@ -5,6 +5,7 @@ import { i as voidWarn } from "./log-BMwmN5Ae.mjs";
5
5
  import { n as ensureProjectTsconfig } from "./project-tsconfig-Itv1f4WC.mjs";
6
6
  import { n as generateDbDts, t as DRIZZLE_OPERATORS } from "./db-types-NGxPwnlt.mjs";
7
7
  import { t as discoverSchema } from "./discover-LaV0tbIu.mjs";
8
+ import { n as CLOUDFLARE_QUEUE_NAMES_BUILD_ENV } from "./env-BaMz0j7H.mjs";
8
9
  import { createRequire } from "node:module";
9
10
  import { existsSync, readFileSync, readdirSync } from "node:fs";
10
11
  import { fileURLToPath } from "node:url";
@@ -403,14 +404,82 @@ function resolvePackageEntry(name, file) {
403
404
  }
404
405
  }
405
406
  //#endregion
407
+ //#region src/queues/cloudflare-names.ts
408
+ /** `workerPrefix` is the Worker name in resource-name form (lowercase, `_` as `-`). */
409
+ function scopedCloudflareQueueName(workerPrefix, queueName) {
410
+ return `${workerPrefix}-${queueName}`;
411
+ }
412
+ const consumedBy = (state, workerName) => state?.consumers.includes(workerName) ?? false;
413
+ /**
414
+ * Pick the Cloudflare name for one queue: its scoped name, or its plain name
415
+ * when this Worker already consumes that queue. `plain` may be `undefined`
416
+ * when it was not looked up, which is only needed when the Worker does not
417
+ * already consume the scoped queue.
418
+ */
419
+ function chooseCloudflareQueueName(input) {
420
+ if (!consumedBy(input.scoped, input.workerName) && consumedBy(input.plain ?? null, input.workerName)) return {
421
+ name: input.queueName,
422
+ kept: true
423
+ };
424
+ return {
425
+ name: input.scopedName,
426
+ kept: false
427
+ };
428
+ }
429
+ /** Consumers of a queue other than this Worker. A queue has one consumer. */
430
+ function otherQueueConsumers(state, workerName) {
431
+ return state?.consumers.filter((consumer) => consumer !== workerName) ?? [];
432
+ }
433
+ /**
434
+ * The names `void deploy` chose, read inside its Vite build. Returns undefined
435
+ * outside that build, where queues keep their plain names.
436
+ */
437
+ function readDeployBuildQueueNames() {
438
+ if (process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] !== "1") return;
439
+ const raw = process.env[CLOUDFLARE_QUEUE_NAMES_BUILD_ENV];
440
+ if (raw === void 0) return;
441
+ let parsed;
442
+ try {
443
+ parsed = JSON.parse(raw);
444
+ } catch {
445
+ parsed = void 0;
446
+ }
447
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || Object.values(parsed).some((name) => typeof name !== "string" || name === "")) throw new Error(`queue: ${CLOUDFLARE_QUEUE_NAMES_BUILD_ENV} is not a valid queue name map.`);
448
+ return parsed;
449
+ }
450
+ /** The Cloudflare name of a queue: the deploy's choice, or its plain name. */
451
+ function cloudflareQueueName(queueName, names) {
452
+ return names && Object.hasOwn(names, queueName) ? names[queueName] : queueName;
453
+ }
454
+ //#endregion
406
455
  //#region src/queues/dispatch.ts
407
456
  /**
408
457
  * Emit the queue-name resolver used by generated native workers and framework
409
458
  * wrappers. Hosted relays send the exact logical name. Native Queue events may
410
459
  * expose a project-prefixed physical name, so fallback matching selects the
411
460
  * unique longest known `-name` suffix. Unknown or ambiguous inputs fail closed.
461
+ *
462
+ * `cloudflareNames` (aligned with `queueNames`) comes from
463
+ * `void deploy --platform cloudflare`, which knows each queue's exact name.
464
+ * Its events then match exactly: a suffix could pick the wrong queue, as
465
+ * `app-jobs` would for queues `jobs` and `app-jobs` in Worker `app`. Logical
466
+ * names still match, for the trigger endpoint.
412
467
  */
413
- function generateQueueResolverSource(queueNames) {
468
+ function generateQueueResolverSource(queueNames, cloudflareNames) {
469
+ if (cloudflareNames) {
470
+ const indexByName = {};
471
+ cloudflareNames.forEach((name, index) => {
472
+ indexByName[name] = index;
473
+ });
474
+ queueNames.forEach((name, index) => {
475
+ if (!Object.hasOwn(indexByName, name)) indexByName[name] = index;
476
+ });
477
+ return `const __queueIndexByName = ${JSON.stringify(indexByName)};
478
+ function __resolveQueueIndex(queueName) {
479
+ if (typeof queueName !== "string" || !Object.hasOwn(__queueIndexByName, queueName)) return -1;
480
+ return __queueIndexByName[queueName];
481
+ }`;
482
+ }
414
483
  return `const __queueNames = ${JSON.stringify(queueNames)};
415
484
  function __resolveQueueIndex(queueName) {
416
485
  if (typeof queueName !== "string") return -1;
@@ -432,4 +501,4 @@ function __resolveQueueIndex(queueName) {
432
501
  }`;
433
502
  }
434
503
  //#endregion
435
- export { drizzlePlugin as n, voidDbBundlerPlugin as r, generateQueueResolverSource as t };
504
+ export { readDeployBuildQueueNames as a, voidDbBundlerPlugin as c, otherQueueConsumers as i, chooseCloudflareQueueName as n, scopedCloudflareQueueName as o, cloudflareQueueName as r, drizzlePlugin as s, generateQueueResolverSource as t };
@@ -1,7 +1,7 @@
1
1
  import { n as readDeploymentPlatform } from "./project-rqDnVsJN.mjs";
2
2
  import { c as getToken } from "./auth-B6iOCjKI.mjs";
3
3
  import { L as log } from "./dist-Cor9XGoz.mjs";
4
- import { r as PlatformClient } from "./client-BEkdj1kx.mjs";
4
+ import { r as PlatformClient } from "./client-BEMtySaV.mjs";
5
5
  import { f as import_picocolors, m as printSuccess, p as note } from "./output-BpgYODYx.mjs";
6
6
  import { i as resolveCommandProjectId } from "./resolve-project-Xoi6eTWY.mjs";
7
7
  //#region src/cli/domain.ts
@@ -25,7 +25,7 @@ async function runDomainCommand(root, args) {
25
25
  }
26
26
  async function runCloudflareDomainCommand(root, args) {
27
27
  if (args.projectSlug) throw new Error("domain: --project selects a Void platform project and is not used for direct Cloudflare apps.");
28
- const { changeCloudflareDomain, listCloudflareDomains } = await import("./cloudflare-operations-DsSaw2BT.mjs");
28
+ const { changeCloudflareDomain, listCloudflareDomains } = await import("./cloudflare-operations-PCM4wucv.mjs");
29
29
  if (args.subcommand === "add") {
30
30
  const result = await changeCloudflareDomain(root, args.hostname, "add");
31
31
  note("Cloudflare Custom Domains manages the DNS record and TLS certificate in the zone on your account.", "Cloudflare Domain");
@@ -2,15 +2,15 @@ import { a as join } from "./dist-ipQi0Q8y.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-DGu_QZ_Q.mjs";
3
3
  import { p as readConfig } from "./config-DHgSEWT7.mjs";
4
4
  import { i as scanEmailHandlersSync } from "./email-B9ayYQEG.mjs";
5
- import { M as writeProvisionedWranglerConfig } from "./wrangler-F96NnLyb.mjs";
5
+ import { M as writeProvisionedWranglerConfig } from "./wrangler-CDiEBCdS.mjs";
6
6
  import { c as getToken, u as openBrowser } from "./auth-B6iOCjKI.mjs";
7
- import { a as emailConfigInputs, c as renderAddressMap, i as createNodeEmailDns, l as renderEmailChecklist, o as preflightEmail, r as applyEmailSetup, s as probeMx } from "./email-cloudflare-D03g2TkS.mjs";
7
+ import { a as emailConfigInputs, c as renderAddressMap, i as createNodeEmailDns, l as renderEmailChecklist, o as preflightEmail, r as applyEmailSetup, s as probeMx } from "./email-cloudflare-B8-pq_-W.mjs";
8
8
  import { A as confirm, L as log, U as password, tt as isCancel } from "./dist-Cor9XGoz.mjs";
9
- import { n as PlatformApiError, r as PlatformClient } from "./client-BEkdj1kx.mjs";
9
+ import { n as PlatformApiError, r as PlatformClient } from "./client-BEMtySaV.mjs";
10
10
  import { f as import_picocolors, l as formatUrl, m as printSuccess, p as note, r as createSpinner } from "./output-BpgYODYx.mjs";
11
11
  import { i as resolveCommandProjectId } from "./resolve-project-Xoi6eTWY.mjs";
12
- import { o as resolveDeployTransport } from "./deploy-transport-BzGEj0Ge.mjs";
13
- import { a as discoverRootWranglerConfig, c as runWranglerAuthToken, l as deriveWorkerName, o as createDeployWranglerRunner, s as isWranglerNonInteractiveOrCI } from "./deploy-7H32EnUs.mjs";
12
+ import { o as resolveDeployTransport } from "./deploy-transport-JCxw7QDi.mjs";
13
+ import { a as discoverRootWranglerConfig, c as runWranglerAuthToken, l as deriveWorkerName, o as createDeployWranglerRunner, s as isWranglerNonInteractiveOrCI } from "./deploy-hRPvw8ci.mjs";
14
14
  import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
15
15
  import { tmpdir } from "node:os";
16
16
  import { execSync } from "node:child_process";
@@ -20,7 +20,7 @@ import { setTimeout as setTimeout$1 } from "node:timers/promises";
20
20
  async function runEmailCommand(root, args) {
21
21
  if (args.platform === "cloudflare") return runEmailCloudflareCommand(root, args);
22
22
  if (args.subcommand === "setup") {
23
- log.error("email: `void email setup` sets email up on your OWN Cloudflare account — run it with `--platform cloudflare`. The Void platform needs no setup: deploy, and `void email usage` shows your address.");
23
+ log.error("email: `void email setup` sets email up on your OWN Cloudflare account — run it with `--platform cloudflare`. The Void platform needs no setup: deploy, and `void email alias` shows your address.");
24
24
  process.exit(1);
25
25
  }
26
26
  if (args.subcommand === "status") {
@@ -40,6 +40,7 @@ async function runEmailCommand(root, args) {
40
40
  case "destinations": return emailDestinations(client, projectId);
41
41
  case "allow": return emailAllow(client, projectId, args.address);
42
42
  case "disallow": return emailDisallow(client, projectId, args.address);
43
+ case "alias": return emailAlias(client, projectId, args.address, { yes: args.yes === true });
43
44
  case "domain": return runEmailDomainCommand(client, projectId, args);
44
45
  }
45
46
  }
@@ -54,6 +55,54 @@ async function emailUsage(client, projectId) {
54
55
  ];
55
56
  note(lines.join("\n"), "Email Usage");
56
57
  }
58
+ async function emailAlias(client, projectId, name, opts = { yes: false }) {
59
+ if (!name) {
60
+ const settings = await client.getEmailSettings(projectId);
61
+ const shared = settings.sharedInbound;
62
+ const domain = settings.sharedDomain ?? (shared ? shared.recipient.slice(shared.recipient.lastIndexOf("@") + 1) : null);
63
+ const name = settings.emailAlias ?? settings.domains.projectSlug;
64
+ if (!domain || !name) {
65
+ log.info("This platform has no shared mail domain.");
66
+ return;
67
+ }
68
+ const address = `${name}@${domain}`;
69
+ const lines = [`Address: ${address}`, `Inbound: ${inboundLine(shared, address)}`];
70
+ if (settings.emailAlias && settings.domains.projectSlug) lines.push(`Also: ${settings.domains.projectSlug}@${domain} (the project slug)`);
71
+ note(lines.join("\n"), "Shared mail address");
72
+ if (!settings.emailAlias) log.info("Run `void email alias <name>` to give this address a shorter, permanent name.");
73
+ return;
74
+ }
75
+ if (!opts.yes) {
76
+ if (!(opts.isInteractive ?? (process.stdin.isTTY && process.stdout.isTTY))) {
77
+ log.error("email: the alias is permanent. Pass --yes to set it without a prompt.");
78
+ process.exit(1);
79
+ }
80
+ const ok = await confirm({
81
+ message: `Set the permanent email alias "${name}"? It cannot be changed or removed later; the slug address keeps working.`,
82
+ initialValue: false
83
+ });
84
+ if (isCancel(ok) || !ok) {
85
+ log.info("Cancelled. No alias was set.");
86
+ return;
87
+ }
88
+ }
89
+ const result = await client.setEmailAlias(projectId, name);
90
+ printSuccess(`Email alias set: ${result.address}`);
91
+ const status = result.sharedInbound?.status;
92
+ if (status && status !== "ready") {
93
+ const other = result.sharedInbound.recipient === result.address ? "" : ` at ${result.sharedInbound.recipient}`;
94
+ log.info(`Inbound mail${other} is ${status}${result.sharedInbound?.reason ? `: ${result.sharedInbound.reason}` : ""}. It starts working once the project has an email handler deployed and routing is ready; check with \`void email alias\`.`);
95
+ }
96
+ }
97
+ /**
98
+ * The inbound status covers every name of the project, so name the address
99
+ * it belongs to when that is not the one shown (the slug row can be the one
100
+ * not ready yet).
101
+ */
102
+ function inboundLine(shared, address) {
103
+ if (!shared) return "not set up on this platform";
104
+ return shared.recipient === address ? shared.status : `${shared.status} (${shared.recipient})`;
105
+ }
57
106
  async function emailDestinations(client, projectId) {
58
107
  const rows = await client.listEmailDestinations(projectId);
59
108
  if (rows.length === 0) {
@@ -301,10 +350,10 @@ async function emailDomainAdd(client, projectId, rawDomain, deps = {}) {
301
350
  const domain = normalizeEmailDomainInput(rawDomain);
302
351
  if (!isValidEmailDomainInput(domain)) return fail(`email: invalid domain '${rawDomain}'.`);
303
352
  const dns = deps.dns ?? await createNodeEmailDns();
304
- const checkApexMx = async () => {
353
+ const checkApexMx = async (adminProject) => {
305
354
  const mx = await probeMx(dns, domain);
306
355
  if (mx.state === "unknown") log.info(`MX could not read ${domain}'s MX from here — the platform decides over public DNS.`);
307
- else if (mx.state === "foreign") fail(`email: ${domain} already receives mail from another provider. Platform custom inbound email requires an unused Cloudflare zone apex; choose another apex or use the platform shared mail address.`);
356
+ else if (mx.state === "foreign") fail(`email: ${domain} already receives mail from another provider. Platform custom inbound email requires an unused Cloudflare zone apex; choose another apex or use the platform shared mail address.${adminProject ? ` To only send from ${domain}, ask your administrator to run \`void platform email domain-add ${domain} --project ${adminProject} --outbound-only\`.` : ""}`);
308
357
  else log.info(`MX using the requested apex ${domain}`);
309
358
  };
310
359
  let renewal = false;
@@ -312,8 +361,8 @@ async function emailDomainAdd(client, projectId, rawDomain, deps = {}) {
312
361
  if (settings.domains.management === "admin") {
313
362
  renewal = (await client.listEmailDomains(projectId)).some((row) => row.domain === domain && row.managed_by !== "admin");
314
363
  if (!renewal) {
315
- await checkApexMx();
316
364
  const project = settings.domains.projectSlug ?? projectId;
365
+ await checkApexMx(project);
317
366
  log.info([
318
367
  "Email domains on this platform are managed by its administrator.",
319
368
  "Ask them to run:",
@@ -5,13 +5,13 @@ import { p as readConfig } from "./config-DHgSEWT7.mjs";
5
5
  import { i as voidWarn, r as voidLog } from "./log-BMwmN5Ae.mjs";
6
6
  import { i as collectFiles } from "./isr-config-fZaJJ8t7.mjs";
7
7
  import { i as readProjectIdField } from "./project-rqDnVsJN.mjs";
8
- import { p as findBindingNameOwner, u as ensureWranglerCompat } from "./wrangler-F96NnLyb.mjs";
8
+ import { p as findBindingNameOwner, u as ensureWranglerCompat } from "./wrangler-CDiEBCdS.mjs";
9
9
  import { n as scopedAccessCredentials } from "./cf-access-BM9G0lhO.mjs";
10
10
  import { n as ensurePlatformProxyAccess } from "./cf-access-CWP4avfP.mjs";
11
11
  import { a as getApiUrl, c as getToken, o as getProxyUrl } from "./auth-B6iOCjKI.mjs";
12
- import { l as stripInternalEnvKeys } from "./env-BJjULvL0.mjs";
13
- import { n as readPrerenderPathsResponse, r as renderPrerenderPaths, t as outputFileForPath } from "./prerender-render-Cijv7UFo.mjs";
14
- import { a as buildEnv } from "./version-metadata-tS39iW09.mjs";
12
+ import { u as stripInternalEnvKeys } from "./env-BaMz0j7H.mjs";
13
+ import { i as renderPrerenderPaths, n as outputFileForPath, r as readPrerenderPathsResponse } from "./prerender-render-CaShbHJ3.mjs";
14
+ import { a as buildEnv } from "./version-metadata-DmaZNTYW.mjs";
15
15
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
16
16
  import { isRecord } from "@void/deploy-core";
17
17
  import { execFile } from "node:child_process";
@@ -286,6 +286,107 @@ async function prerenderPagesNode(options) {
286
286
  return result;
287
287
  }
288
288
  //#endregion
289
+ //#region src/asset-worker-bypass.ts
290
+ /**
291
+ * Build-time decision for letting Cloudflare serve fingerprinted build files
292
+ * without starting the Worker. Native Cloudflare builds of apps with no global
293
+ * middleware and no edge rules gain nothing from running the Worker for those
294
+ * files: the Worker would only copy the asset response. Skipping it makes
295
+ * those requests free static requests and keeps auth and its session read off
296
+ * them. Each file gets its own negative `run_worker_first` rule, because a
297
+ * request matching a negative rule never reaches the Worker, even when the
298
+ * file is missing. Misses and other paths in the folder keep the Worker's
299
+ * not-found, SPA and page handling.
300
+ *
301
+ * The asset layer does not know which files are fingerprinted, so a generated
302
+ * `_headers` file gives every bypassed chunk the immutable policy the Worker
303
+ * would have set.
304
+ */
305
+ const GENERATED_ASSET_HEADERS_MARKER = "# Generated by Void: immutable caching for fingerprinted build files. Do not edit.";
306
+ /** Cloudflare accepts at most 100 `run_worker_first` rules, `/**` included. */
307
+ const MAX_BYPASS_FILES = 99;
308
+ /** Cloudflare limits each `run_worker_first` rule to 100 characters. */
309
+ const MAX_RUN_WORKER_FIRST_RULE_LENGTH = 100;
310
+ const INTERNAL_PATTERNS = ["/__void/*"];
311
+ const AUTH_PATTERNS = ["/api/auth/*"];
312
+ /** Trim surrounding slashes; null when nothing is left. */
313
+ function normalizeAssetsDir(dir) {
314
+ let start = 0;
315
+ let end = dir.length;
316
+ while (start < end && dir[start] === "/") start++;
317
+ while (end > start && dir[end - 1] === "/") end--;
318
+ const trimmed = dir.slice(start, end);
319
+ return trimmed === "" || trimmed === "." ? null : trimmed;
320
+ }
321
+ /**
322
+ * Whether a route pattern can match a path below `/<dir>/`. Parameters,
323
+ * wildcards and patterns with more segments than the directory count as a
324
+ * match, so the answer errs towards keeping the Worker in front.
325
+ */
326
+ function patternCanReachUnder(pattern, dir) {
327
+ const patternSegments = (pattern.startsWith("/") ? pattern.slice(1) : pattern).split("/");
328
+ const dirSegments = (dir.startsWith("/") ? dir.slice(1) : dir).split("/");
329
+ for (let i = 0; i < dirSegments.length; i++) {
330
+ const segment = patternSegments[i];
331
+ if (segment === void 0) return false;
332
+ if (segment.includes("*") || segment.includes("{")) return true;
333
+ if (segment.startsWith(":")) continue;
334
+ if (segment.toLowerCase() !== dirSegments[i].toLowerCase()) return false;
335
+ }
336
+ return patternSegments.length > dirSegments.length;
337
+ }
338
+ /**
339
+ * Characters that are plain text in both a `_headers` path and a
340
+ * `run_worker_first` rule. `*`, `:` and `!` have meaning there, and anything
341
+ * that needs URL encoding would not match the request path as written.
342
+ */
343
+ function isPlainPath(path) {
344
+ for (const char of path) if (!(char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char >= "0" && char <= "9" || char === "-" || char === "_" || char === "." || char === "~" || char === "/")) return false;
345
+ return path.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
346
+ }
347
+ /**
348
+ * Whether `run_worker_first` is the rule an earlier bypass wrote. A watch
349
+ * rebuild of only the client still finds it, because the Worker build that
350
+ * would write `['/**']` again did not run.
351
+ */
352
+ function isAssetBypassRule(runWorkerFirst, assetsDir) {
353
+ const dir = normalizeAssetsDir(assetsDir);
354
+ return dir !== null && Array.isArray(runWorkerFirst) && runWorkerFirst.length > 1 && runWorkerFirst[0] === "/**" && runWorkerFirst.slice(1).every((rule) => typeof rule === "string" && rule.startsWith("!/" + dir + "/"));
355
+ }
356
+ /** The bypass this build can use, or null when any rule keeps the Worker in front. */
357
+ function resolveAssetWorkerBypass(facts) {
358
+ const { runWorkerFirst } = facts;
359
+ if (!(Array.isArray(runWorkerFirst) && runWorkerFirst.length === 1 && runWorkerFirst[0] === "/**" || isAssetBypassRule(runWorkerFirst, facts.assetsDir)) || facts.notFoundHandling !== "none" || facts.base !== "/" || facts.hasMiddleware || facts.headerRuleCount > 0 || facts.redirectRuleCount > 0 || facts.fallbackRuleCount > 0 || facts.publicEdgeFiles) return null;
360
+ const assetsDir = normalizeAssetsDir(facts.assetsDir);
361
+ if (!assetsDir || !isPlainPath(assetsDir)) return null;
362
+ if ([
363
+ ...facts.patterns,
364
+ ...INTERNAL_PATTERNS,
365
+ ...facts.authEnabled ? AUTH_PATTERNS : []
366
+ ].some((pattern) => patternCanReachUnder(pattern, assetsDir))) return null;
367
+ const prefix = assetsDir + "/";
368
+ const files = [...new Set(facts.immutableFiles)].filter((file) => file.startsWith(prefix)).sort();
369
+ const rules = files.map((file) => "!/" + file);
370
+ if (files.length === 0 || files.length > MAX_BYPASS_FILES || files.some((file) => !isPlainPath(file)) || rules.some((rule) => rule.length > MAX_RUN_WORKER_FIRST_RULE_LENGTH)) return null;
371
+ return {
372
+ runWorkerFirst: ["/**", ...rules],
373
+ headers: renderGeneratedAssetHeaders(files)
374
+ };
375
+ }
376
+ /** One immutable rule per file after the marker line. */
377
+ function renderGeneratedAssetHeaders(files) {
378
+ const lines = [GENERATED_ASSET_HEADERS_MARKER];
379
+ for (const file of files) lines.push("/" + file, " Cache-Control: public, max-age=31536000, immutable");
380
+ return lines.join("\n") + "\n";
381
+ }
382
+ /** Whether a `_headers` file is the one Void generated. */
383
+ function isGeneratedAssetHeaders(text) {
384
+ const newline = text.indexOf("\n");
385
+ let firstLine = newline === -1 ? text : text.slice(0, newline);
386
+ if (firstLine.endsWith("\r")) firstLine = firstLine.slice(0, -1);
387
+ return firstLine === GENERATED_ASSET_HEADERS_MARKER;
388
+ }
389
+ //#endregion
289
390
  //#region src/cli/email-cloudflare.ts
290
391
  /** The `send_email` binding name Void provisions and the runtime reads. */
291
392
  const SEND_EMAIL_BINDING = "SEND_EMAIL";
@@ -1090,4 +1191,4 @@ async function createNodeEmailDns() {
1090
1191
  };
1091
1192
  }
1092
1193
  //#endregion
1093
- export { emailConfigInputs as a, renderAddressMap as c, collectPrerenderPathsNode as d, prerenderPages as f, createNodeEmailDns as i, renderEmailChecklist as l, SEND_EMAIL_BINDING as n, preflightEmail as o, prerenderPagesNode as p, applyEmailSetup as r, probeMx as s, EMAIL_FROM_VAR as t, collectPrerenderPaths as u };
1194
+ export { emailConfigInputs as a, renderAddressMap as c, isGeneratedAssetHeaders as d, resolveAssetWorkerBypass as f, prerenderPagesNode as g, prerenderPages as h, createNodeEmailDns as i, renderEmailChecklist as l, collectPrerenderPathsNode as m, SEND_EMAIL_BINDING as n, preflightEmail as o, collectPrerenderPaths as p, applyEmailSetup as r, probeMx as s, EMAIL_FROM_VAR as t, isAssetBypassRule as u };
@@ -3,9 +3,9 @@ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-r
3
3
  import { c as getToken } from "./auth-B6iOCjKI.mjs";
4
4
  import { r as generateEnvTypes, t as findEnvFile } from "./env-types-BicfKBhV.mjs";
5
5
  import { H as outro, L as log } from "./dist-Cor9XGoz.mjs";
6
- import { r as PlatformClient } from "./client-BEkdj1kx.mjs";
6
+ import { r as PlatformClient } from "./client-BEMtySaV.mjs";
7
7
  import { m as printSuccess, p as note } from "./output-BpgYODYx.mjs";
8
- import { d as formatEnvReport, g as validateProdEnv, u as fetchRemoteSecretNames } from "./env-validation-Dwq3PJzK.mjs";
8
+ import { d as formatEnvReport, g as validateProdEnv, u as fetchRemoteSecretNames } from "./env-validation-XcukUlFM.mjs";
9
9
  import { mkdirSync, writeFileSync } from "node:fs";
10
10
  //#region src/cli/env.ts
11
11
  async function runEnvCommand(root, args) {
@@ -25,7 +25,7 @@ async function runCheck(root, useRemoteSecrets) {
25
25
  const platform = readDeploymentPlatform(root);
26
26
  if (platform === "none") throw new Error("env: Deployment is disabled. Run `void init` to choose a platform.");
27
27
  if (platform === "cloudflare") {
28
- const { listCloudflareSecrets, resolveCloudflareOperationContext } = await import("./cloudflare-operations-DsSaw2BT.mjs");
28
+ const { listCloudflareSecrets, resolveCloudflareOperationContext } = await import("./cloudflare-operations-PCM4wucv.mjs");
29
29
  remoteSecrets = await listCloudflareSecrets(resolveCloudflareOperationContext(root));
30
30
  } else {
31
31
  const token = getToken(root);
@@ -23,6 +23,11 @@ function loadLocalEnv(root, options = {}) {
23
23
  */
24
24
  const CLOUDFLARE_DEPLOY_BUILD_ENV = "VOID_CLOUDFLARE_DEPLOY_BUILD";
25
25
  /**
26
+ * JSON map from each `queues/` name to the Cloudflare queue name that
27
+ * `void deploy --platform cloudflare` chose. Set only for its Vite build.
28
+ */
29
+ const CLOUDFLARE_QUEUE_NAMES_BUILD_ENV = "VOID_CLOUDFLARE_QUEUE_NAMES";
30
+ /**
26
31
  * Find legacy Vite dotenv variants. Void intentionally supports only `.env`;
27
32
  * production configuration is project-scoped remote state instead of a file.
28
33
  */
@@ -112,4 +117,4 @@ function stripInternalEnvKeys(input) {
112
117
  };
113
118
  }
114
119
  //#endregion
115
- export { isClientEnvKey as a, resolveRemoteMode as c, findReservedEnvKeys as i, stripInternalEnvKeys as l, LOCAL_ENV_FILE as n, loadLocalEnv as o, findLegacyEnvFiles as r, reservedEnvKeysMessage as s, CLOUDFLARE_DEPLOY_BUILD_ENV as t };
120
+ export { findReservedEnvKeys as a, reservedEnvKeysMessage as c, findLegacyEnvFiles as i, resolveRemoteMode as l, CLOUDFLARE_QUEUE_NAMES_BUILD_ENV as n, isClientEnvKey as o, LOCAL_ENV_FILE as r, loadLocalEnv as s, CLOUDFLARE_DEPLOY_BUILD_ENV as t, stripInternalEnvKeys as u };
@@ -1 +1 @@
1
- export { r as SelfHostSchemaError, a as computeInvalidEmittedKeys, c as deriveSelfHostSchemaFacts, p as readEmittedWorkerVars } from "./env-validation-Dwq3PJzK.mjs";
1
+ export { r as SelfHostSchemaError, a as computeInvalidEmittedKeys, c as deriveSelfHostSchemaFacts, p as readEmittedWorkerVars } from "./env-validation-XcukUlFM.mjs";
@@ -2,7 +2,7 @@ import { a as join, c as resolve, n as dirname } from "./dist-ipQi0Q8y.mjs";
2
2
  import { i as voidWarn } from "./log-BMwmN5Ae.mjs";
3
3
  import { n as readGeneratedWranglerConfigFile } from "./generated-wrangler-config-DeWj5F9Y.mjs";
4
4
  import { n as scanWranglerDotenvKeys } from "./dotenv-CNazY3-w.mjs";
5
- import { a as isClientEnvKey, i as findReservedEnvKeys, n as LOCAL_ENV_FILE, o as loadLocalEnv, r as findLegacyEnvFiles, s as reservedEnvKeysMessage } from "./env-BJjULvL0.mjs";
5
+ import { a as findReservedEnvKeys, c as reservedEnvKeysMessage, i as findLegacyEnvFiles, o as isClientEnvKey, r as LOCAL_ENV_FILE, s as loadLocalEnv } from "./env-BaMz0j7H.mjs";
6
6
  import { t as findEnvFile } from "./env-types-BicfKBhV.mjs";
7
7
  import { t as loadUserEnvFile } from "./load-user-env-DD5qveNU.mjs";
8
8
  import { l as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-8jEYIeim.mjs";
@@ -329,7 +329,7 @@ async function runModel(root, name, columns) {
329
329
  const existing = readFileSync(barrelPath, "utf-8");
330
330
  if (!existing.includes(exportLine)) writeFileSync(barrelPath, existing.trimEnd() + "\n" + exportLine + "\n");
331
331
  } else writeFileSync(barrelPath, exportLine + "\n");
332
- const { prepareProject } = await import("./prepare-C4I0f--h.mjs");
332
+ const { prepareProject } = await import("./prepare-B3VrSF1Z.mjs");
333
333
  await prepareProject(root);
334
334
  log.step(`Created ${relative(root, modelPath)}`);
335
335
  log.step(`Updated ${relative(root, barrelPath)}`);
@@ -0,0 +1 @@
1
+ export { r as runGenCommand } from "./gen-CCx3t2Ju.mjs";
@@ -1,7 +1,7 @@
1
1
  import { r as readProjectConfig } from "./project-rqDnVsJN.mjs";
2
2
  import { c as getToken, n as createCodeChallenge, r as createCodeVerifier, t as awaitBrowserCallback, u as openBrowser } from "./auth-B6iOCjKI.mjs";
3
3
  import { A as confirm, K as select, L as log, O as cancel, X as text, tt as isCancel } from "./dist-Cor9XGoz.mjs";
4
- import { c as platformErrorMessage, n as PlatformApiError, r as PlatformClient, s as parsePlatformErrorBody } from "./client-BEkdj1kx.mjs";
4
+ import { c as platformErrorMessage, n as PlatformApiError, r as PlatformClient, s as parsePlatformErrorBody } from "./client-BEMtySaV.mjs";
5
5
  import { f as import_picocolors, l as formatUrl, m as printSuccess } from "./output-BpgYODYx.mjs";
6
6
  import { a as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-Xoi6eTWY.mjs";
7
7
  import { t as collectGitDeployMetadata } from "./git-metadata-D-gurjzG.mjs";
@@ -2,7 +2,7 @@ import { l as VoidPlatformSandbox } from "./sandbox-q3waMc2T.mjs";
2
2
  import { t as StandardSchemaV1 } from "./standard-schema-Fo_vCAZh.mjs";
3
3
  import { n as HeadDescriptor } from "./head-C8K_iGe6.mjs";
4
4
  import { r as AuthUser, t as AuthSession } from "./auth-DkcFflXV.mjs";
5
- import { t as DevCssAsset } from "./types-7AIz0OZu.mjs";
5
+ import { t as DevCssAsset } from "./types-w72dljaA.mjs";
6
6
  import { Context, Env, ExecutionContext as ExecutionContext$1, MiddlewareHandler } from "hono";
7
7
  import { RewriteDestination } from "void/routes";
8
8
  //#region src/runtime/routing-assets.d.ts
@@ -1,7 +1,7 @@
1
1
  import { H as outro } from "./dist-Cor9XGoz.mjs";
2
2
  import { n as getOwnVersion } from "./agents-CuNtT0D_.mjs";
3
3
  import { d as helpLine, f as import_picocolors, g as sectionTitle, l as formatUrl, p as note, t as categoryTitle } from "./output-BpgYODYx.mjs";
4
- import { n as operatorGroups, t as operatorCommands } from "./operator-args-UnE8Y2eK.mjs";
4
+ import { n as operatorGroups, t as operatorCommands } from "./operator-args-BsJIYXaT.mjs";
5
5
  //#region src/cli/ascii.ts
6
6
  const asciiArts = [
7
7
  `
@@ -1110,6 +1110,10 @@ const HELP_TREE = {
1110
1110
  command: "disallow <address>",
1111
1111
  description: "Remove a recipient from the allowlist"
1112
1112
  },
1113
+ {
1114
+ command: "alias [name]",
1115
+ description: "Show the shared mail address, or set a shorter permanent name for it"
1116
+ },
1113
1117
  {
1114
1118
  command: "domain <add|status|list|sync|rotate-secret|remove>",
1115
1119
  description: "Send and receive at your own domain on a Cloudflare zone"
@@ -1139,6 +1143,17 @@ const HELP_TREE = {
1139
1143
  destinations: withProjectOption("List verified recipient addresses.", "void email destinations [options]"),
1140
1144
  allow: withProjectOption("Add a recipient and trigger a Cloudflare verification email.", "void email allow <address> [options]"),
1141
1145
  disallow: withProjectOption("Remove a recipient from the verified allowlist.", "void email disallow <address> [options]"),
1146
+ alias: {
1147
+ summary: "Show the project address on the shared mail domain, or give it a shorter name. The alias is permanent; the slug address keeps working.",
1148
+ usage: ["void email alias [options]", "void email alias <name> [options]"],
1149
+ options: [{
1150
+ command: "--project <name>",
1151
+ description: "Project name override"
1152
+ }, {
1153
+ command: "--yes",
1154
+ description: "Set the alias without asking (it cannot be changed)"
1155
+ }]
1156
+ },
1142
1157
  domain: {
1143
1158
  summary: "Send and receive at your own domain on a Cloudflare zone.",
1144
1159
  usage: ["void email domain <verb> [<domain>] [options]"],
@@ -0,0 +1 @@
1
+ export { r as printHelpPage } from "./help-CKbrhZha.mjs";
package/dist/index.d.mts CHANGED
@@ -1,12 +1,10 @@
1
1
  import { n as HeadDescriptor } from "./head-C8K_iGe6.mjs";
2
2
  import { r as AuthUser } from "./auth-DkcFflXV.mjs";
3
- import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, x as DeferredState, y as defineScheduled } from "./handler-BbkSPzGF.mjs";
3
+ import { s as RouteEnvironment } from "./types-w72dljaA.mjs";
4
+ import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, x as DeferredState, y as defineScheduled } from "./handler-CQv5YDS0.mjs";
4
5
  import { t as QueueMap } from "./queues-BWKt1Xo4.mjs";
5
6
  import { PluginConfig } from "@cloudflare/vite-plugin";
6
7
  import { Plugin } from "vite";
7
- //#region src/router/parse-filename.d.ts
8
- type RouteEnvironment = "dev" | "prod";
9
- //#endregion
10
8
  //#region src/plugin-binding-utils.d.ts
11
9
  /**
12
10
  * Decide whether to inject the `void dev` email-inbox loopback var.