void 1.2.0 → 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 (169) 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 +21 -4
  67. package/dist/pages/client.mjs +174 -35
  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 +34 -3
  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/quickstart.md +26 -1
  139. package/docs/guide/sandboxes.md +2 -2
  140. package/docs/guide/server-routing.md +38 -2
  141. package/docs/guide/type-safety.md +7 -7
  142. package/docs/guide/websockets.md +4 -2
  143. package/docs/reference/api/pages.md +4 -4
  144. package/docs/reference/cli/email.md +13 -0
  145. package/docs/reference/cli/platform-email.md +2 -2
  146. package/docs/reference/cli.md +2 -1
  147. package/docs/reference/structure.md +3 -1
  148. package/package.json +8 -7
  149. package/sandbox.Dockerfile +1 -1
  150. package/templates/assets/icons.svg +49 -0
  151. package/templates/assets/react.svg +1 -0
  152. package/templates/assets/solid.svg +1 -0
  153. package/templates/assets/stack.svg +35 -0
  154. package/templates/assets/svelte.svg +1 -0
  155. package/templates/assets/void.svg +5 -0
  156. package/templates/assets/vue.svg +1 -0
  157. package/dist/cf-build-output-BJHuSsVN.mjs +0 -1
  158. package/dist/client-BiRDZTSd.mjs +0 -1
  159. package/dist/config-CyUJzi3q.mjs +0 -32
  160. package/dist/deploy-CE0Ev0Ob.mjs +0 -2
  161. package/dist/gen-NrOlWZaG.mjs +0 -1
  162. package/dist/help-BeAFFE5C.mjs +0 -1
  163. package/dist/login-DgDwlKc_.mjs +0 -1
  164. package/dist/migrate-n49ZeS1X.mjs +0 -1
  165. package/dist/operator-cmd-d2MvJOrl.mjs +0 -1
  166. package/dist/parse-filename-DioPHiR9.mjs +0 -77
  167. package/dist/platform-args-kQrgxScY.mjs +0 -1
  168. package/dist/prepare-C4I0f--h.mjs +0 -1
  169. package/dist/wrangler-BLb3_luP.mjs +0 -1
@@ -1,14 +1,14 @@
1
1
  import { n as dirname } from "./dist-ipQi0Q8y.mjs";
2
- import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-CyUJzi3q.mjs";
2
+ import { i as loadVoidAuthConfig, r as findVoidAuthConfig } from "./config-BTu1o3Dc.mjs";
3
3
  import { p as readConfig } from "./config-DHgSEWT7.mjs";
4
4
  import { r as getMiniflareDatabasePath } from "./runner-3uGC-oLF.mjs";
5
- import { o as loadLocalEnv } from "./env-BJjULvL0.mjs";
5
+ import { s as loadLocalEnv } from "./env-BaMz0j7H.mjs";
6
6
  import { a as pgMigrationRunner, i as mysqlMigrationRunner, n as applyPgAuthMigrations, r as applySqliteAuthMigrations, t as applyMySqlAuthMigrations } from "./auth-migrations-BO27GDNr.mjs";
7
7
  import { r as resolveVoidAuthMigrationSchema } from "./drizzle-BQfyvQKX.mjs";
8
8
  import { mkdirSync } from "node:fs";
9
9
  //#region src/auth/node.ts
10
- async function runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, configPath = findVoidAuthConfig(root), databaseUrl) {
11
- const authConfig = await loadVoidAuthConfig(configPath);
10
+ async function runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, configPath = findVoidAuthConfig(root), databaseUrl, importModule) {
11
+ const authConfig = await loadVoidAuthConfig(configPath, importModule);
12
12
  const runtime = {
13
13
  dialect,
14
14
  providers: readConfig(root).auth?.providers ?? null,
@@ -488,7 +488,10 @@ const operatorCommands = [
488
488
  path: "/email/domains",
489
489
  positional: ["domain"],
490
490
  values: { project: "Project id or slug" },
491
- booleans: { "token-stdin": "Read a scoped Cloudflare API token from stdin" },
491
+ booleans: {
492
+ "token-stdin": "Read a scoped Cloudflare API token from stdin",
493
+ "outbound-only": "Send only; leave the MX records and inbound mail with the current provider"
494
+ },
492
495
  method: "POST"
493
496
  },
494
497
  {
@@ -701,6 +704,10 @@ function parseOperatorArgs(args) {
701
704
  if (flags.has("check")) parsed.query.check = "true";
702
705
  } else if (group === "zero-trust" && action === "project-protect") parsed.body.protected = true;
703
706
  else if (group === "zero-trust" && action === "project-public") parsed.body.protected = false;
707
+ else if (group === "email" && action === "domain-add" && flags.has("outbound-only")) {
708
+ delete parsed.body["outbound-only"];
709
+ parsed.body.outboundOnly = true;
710
+ }
704
711
  return parsed;
705
712
  }
706
713
  //#endregion
@@ -0,0 +1 @@
1
+ export { a as runOperatorCommand } from "./operator-cmd-DjZKGGgN.mjs";
@@ -163,8 +163,8 @@ async function runAuth(origin, args) {
163
163
  if (args.action === "login" || args.action === "token" && args.tokenStdin) {
164
164
  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");
165
165
  const apiToken = args.tokenStdin ? await readOperatorApiTokenStdin() : await (async () => {
166
- const { discoverPlatform } = await import("./platform-cmd-PiNRkopU.mjs");
167
- const { selectPlatformLoginMethod } = await import("./login-DgDwlKc_.mjs");
166
+ const { discoverPlatform } = await import("./platform-cmd-BYKLMPCn.mjs");
167
+ const { selectPlatformLoginMethod } = await import("./login-Cdo8Aco1.mjs");
168
168
  const { runPlatformLogin } = await import("./auth-Cbqi1iVX.mjs");
169
169
  return runPlatformLogin(origin, (await selectPlatformLoginMethod(await discoverPlatform(origin), args.provider)).id, (url) => process.stderr.write(`Sign in at ${url}\n`));
170
170
  })();
@@ -344,7 +344,7 @@ async function migrateDeploymentAssets(client, origin, args) {
344
344
  }
345
345
  async function runOperatorCommand(args) {
346
346
  if (!args.action) {
347
- const { printHelpPage } = await import("./help-BeAFFE5C.mjs");
347
+ const { printHelpPage } = await import("./help-qOZr3wng.mjs");
348
348
  printHelpPage(["platform", args.group]);
349
349
  return;
350
350
  }
@@ -376,6 +376,7 @@ async function runOperatorCommand(args) {
376
376
  if (!target || typeof target.recoveryFence !== "string" || !/^[a-f0-9]{64}$/.test(target.recoveryFence)) throw new OperatorClientError("The server did not return a valid shared recipient recovery fence. No change was requested.", "invalid_preview");
377
377
  recoveryFence = { recoveryFence: target.recoveryFence };
378
378
  }
379
+ if (args.group === "email" && args.action === "domain-add" && args.body.outboundOnly === true && preview.target?.inboundMode !== "none") throw new OperatorClientError("This platform does not support outbound-only email domains. Upgrade it first. No change was requested.", "unsupported");
379
380
  if (!await confirmOperatorMutation(origin, preview, args)) return;
380
381
  const body = {
381
382
  ...args.body,
@@ -1,5 +1,5 @@
1
1
  import { t as interpolateRouteParams } from "../route-url-BgPja1GS.mjs";
2
- import { t as PageObject } from "../protocol-BBDpJz3G.mjs";
2
+ import { t as PageObject } from "../protocol-BekmFxCI.mjs";
3
3
  import { n as CacheForInput, r as CacheForResult } from "../prefetch-Ce6la4EI.mjs";
4
4
  import { UsageLimitData } from "@void/edge";
5
5
  import { ActionUrl, ResolveActionBody, ResolveActionParams } from "void/routes";
@@ -50,6 +50,8 @@ type VisitOptions = {
50
50
  } | null;
51
51
  /** @internal Used by popstate handler to avoid writing history while traversing */
52
52
  _popstate?: boolean;
53
+ /** @internal Used by router.refresh() to refetch the current URL even when it has a hash */
54
+ _refresh?: boolean;
53
55
  };
54
56
  type PrefetchOptions = {
55
57
  method?: string;
@@ -69,7 +71,8 @@ type PageNavigationEngineConfig = {
69
71
  routeMeta: Record<string, {
70
72
  island?: boolean;
71
73
  }>;
72
- matchRoute(url: string): string | null;
74
+ /** Page id for a decoded pathname (see `decodePagePath`). */
75
+ matchRoute(path: string): string | null;
73
76
  staticPageData?: boolean;
74
77
  staticPageDataFastPath?: boolean;
75
78
  viewTransitions: boolean;
@@ -93,7 +96,8 @@ type PageNavigationResource = {
93
96
  immediate: boolean;
94
97
  shell: Promise<PageNavigationResult | undefined>;
95
98
  abort(): void;
96
- commit(): Promise<void>;
99
+ /** Resolves false when a newer visit has already set the URL, so nothing was committed. */
100
+ commit(): Promise<boolean>;
97
101
  dispose(): void;
98
102
  };
99
103
  type PageNavigationEngine = {
@@ -123,6 +127,17 @@ export declare function isModifiedEvent(e: Pick<MouseEvent, "currentTarget" | "c
123
127
  //#region src/pages/form-value-equality.d.ts
124
128
  export declare function isEqualFormValue(a: unknown, b: unknown): boolean;
125
129
  //#endregion
130
+ //#region src/pages/form-reset.d.ts
131
+ type FormResetOptions = {
132
+ initial?: boolean;
133
+ };
134
+ export declare function isFormResetOptions(value: unknown): value is FormResetOptions;
135
+ export declare function cloneFormValue<T>(value: T): T;
136
+ export declare function parseFormResetArgs(args: ReadonlyArray<string | FormResetOptions>): {
137
+ initial: boolean;
138
+ fields: ReadonlyArray<string>;
139
+ };
140
+ //#endregion
126
141
  //#region src/pages/form-presentation.d.ts
127
142
  type FormMethod = "post" | "put" | "patch" | "delete";
128
143
  type FormModel<Args extends Array<unknown> = []> = {
@@ -170,6 +185,8 @@ export declare function idleNavigationState(): NavigationState;
170
185
  export declare function createRouterFacade(router: VoidRouter, getCurrentUrl: () => string, getCurrentParams?: () => Record<string, string>): VoidRouter;
171
186
  export declare function createSsrRouter(url?: string, params?: Record<string, string>): VoidRouter;
172
187
  export declare const ssrProxy: VoidRouter;
188
+ /** Refetch the current page in place: same history entry, URL hash, state and scroll. */
189
+ export declare function refreshPage(router: Pick<VoidRouter, "visit">, options?: VisitOptions): Promise<unknown>;
173
190
  export declare function submitAction(router: VoidRouter, url: string, options: VisitOptions): Promise<ActionResult>;
174
191
  type ActionMethod = "POST" | "PUT" | "PATCH" | "DELETE";
175
192
  type HasParams<U extends string> = [ResolveActionParams<U>] extends [never] ? false : true;
@@ -198,4 +215,4 @@ export declare function createVoidRouter(config: VoidRouterConfig): Promise<{
198
215
  export declare function scheduleHydration(el: Element, loader: () => Promise<unknown>, props: Record<string, unknown>, strategy: string, hydrateFn: (el: Element, mod: unknown, props: Record<string, unknown>) => void | Promise<void>): void;
199
216
  export declare function initIslands(islands: Record<string, () => Promise<unknown>>, hydrateFn: (el: Element, mod: unknown, props: Record<string, unknown>, frontmatter: Record<string, unknown>) => void | Promise<void>): void;
200
217
  //#endregion
201
- export { type ActionErrorHandlingScope, type ActionResult, type FormMethod, type FormModel, type PageNavigationEngine, type PageNavigationResource, type PageNavigationResult, type PrefetchOptions, type VisitOptions, interpolateRouteParams };
218
+ export { type ActionErrorHandlingScope, type ActionResult, type FormMethod, type FormModel, type FormResetOptions, type PageNavigationEngine, type PageNavigationResource, type PageNavigationResult, type PrefetchOptions, type VisitOptions, interpolateRouteParams };
@@ -215,13 +215,14 @@ function createScrollRestoration() {
215
215
  },
216
216
  save,
217
217
  writeHistory(url, replace) {
218
- renderedKey = newKey();
218
+ const key = (replace ? readKey(history.state) : null) ?? newKey();
219
219
  const state = {
220
220
  ...replace ? history.state : {},
221
- __voidScrollKey: renderedKey
221
+ __voidScrollKey: key
222
222
  };
223
223
  if (replace) history.replaceState(state, "", url);
224
224
  else history.pushState(state, "", url);
225
+ renderedKey = key;
225
226
  },
226
227
  commit() {
227
228
  renderedKey = readKey(history.state) ?? renderedKey;
@@ -255,11 +256,46 @@ function isSameOrigin(url, origin) {
255
256
  }
256
257
  return url.origin === origin;
257
258
  }
259
+ function isHexDigit(char) {
260
+ return char !== void 0 && (char >= "0" && char <= "9" || char >= "a" && char <= "f" || char >= "A" && char <= "F");
261
+ }
262
+ function tryDecodeURI(text) {
263
+ try {
264
+ return decodeURI(text);
265
+ } catch {
266
+ return text;
267
+ }
268
+ }
269
+ /**
270
+ * The path a page is matched on, decoded the way the server (Hono's getPath)
271
+ * decodes it: `/caf%C3%A9` becomes `/café`, while `%25`, reserved escapes such
272
+ * as `%2F` and malformed escapes stay encoded.
273
+ */
274
+ function decodePagePath(path) {
275
+ if (!path.includes("%")) return path;
276
+ const escaped = path.split("%25").join("%2525");
277
+ try {
278
+ return decodeURI(escaped);
279
+ } catch {}
280
+ let decoded = "";
281
+ let index = 0;
282
+ while (index < escaped.length) {
283
+ let end = index;
284
+ while (escaped[end] === "%" && isHexDigit(escaped[end + 1]) && isHexDigit(escaped[end + 2])) end += 3;
285
+ if (end === index) decoded += escaped[index++];
286
+ else {
287
+ decoded += tryDecodeURI(escaped.slice(index, end));
288
+ index = end;
289
+ }
290
+ }
291
+ return decoded;
292
+ }
258
293
  //#endregion
259
294
  //#region src/pages/navigation-engine.ts
260
295
  /**
261
296
  * The server leaves a named action's key out of the page URL. When the page URL
262
297
  * shows that, drop the key from the URL written to history as well.
298
+ * Otherwise keep the requested URL: the page URL may reflect a server rewrite.
263
299
  */
264
300
  function withoutActionKey(fetchUrl, pageUrl) {
265
301
  const q = fetchUrl.indexOf("?");
@@ -330,9 +366,11 @@ async function fetchPageResponse(fetchUrl, init) {
330
366
  }
331
367
  }
332
368
  async function createPageNavigationEngine(config) {
333
- const { adapter, components, layoutTree, routeMeta, matchRoute, staticPageData: STATIC_PAGE_DATA_ENABLED = false, staticPageDataFastPath: STATIC_PAGE_DATA_FAST_PATH = STATIC_PAGE_DATA_ENABLED, prefetchHoverDelay: PREFETCH_HOVER_DELAY, prefetchDefaultCacheFor: PREFETCH_DEFAULT_CACHE_FOR, cacheVisitedPageData: CACHE_VISITED_PAGE_DATA = false } = config;
369
+ const { adapter, components, layoutTree, routeMeta, staticPageData: STATIC_PAGE_DATA_ENABLED = false, staticPageDataFastPath: STATIC_PAGE_DATA_FAST_PATH = STATIC_PAGE_DATA_ENABLED, prefetchHoverDelay: PREFETCH_HOVER_DELAY, prefetchDefaultCacheFor: PREFETCH_DEFAULT_CACHE_FOR, cacheVisitedPageData: CACHE_VISITED_PAGE_DATA = false } = config;
370
+ const matchRoute = (url) => config.matchRoute(decodePagePath(new URL(url, "http://x").pathname));
334
371
  const _prefetchCache = new PrefetchCache();
335
372
  let _nextNavigationId = 0;
373
+ let _urlNavigationId = 0;
336
374
  let _pendingResource = null;
337
375
  let _committedResource = null;
338
376
  let _committedDeferredRegistry = null;
@@ -551,8 +589,8 @@ async function createPageNavigationEngine(config) {
551
589
  deferredWindow.__resolveDeferred = (group, data) => _htmlDeferredRegistry?.resolve(group, data, void 0);
552
590
  deferredWindow.__rejectDeferred = (group, error) => _htmlDeferredRegistry?.resolve(group, void 0, error);
553
591
  function commitHashNavigation(effectiveFetchUrl, hash, options, writeHistory) {
554
- _currentFetchUrl = effectiveFetchUrl;
555
592
  if (writeHistory) scrollRestoration.writeHistory(effectiveFetchUrl + hash, !!options.replace);
593
+ _currentFetchUrl = effectiveFetchUrl;
556
594
  scrollRestoration.commit();
557
595
  restoreScroll(options._scrollPosition, hash);
558
596
  }
@@ -617,14 +655,11 @@ async function createPageNavigationEngine(config) {
617
655
  window.location.href = method === "GET" ? url : response.url;
618
656
  return;
619
657
  }
620
- commitTarget.fetchUrl = redirectUrl.pathname + redirectUrl.search;
658
+ method = "GET";
659
+ fetchUrl = redirectUrl.pathname + redirectUrl.search;
660
+ url = fetchUrl + redirectUrl.hash;
661
+ commitTarget.fetchUrl = fetchUrl;
621
662
  commitTarget.hash = redirectUrl.hash;
622
- return loadNavigationShell(id, redirectUrl.pathname + redirectUrl.search + redirectUrl.hash, redirectUrl.pathname + redirectUrl.search, "GET", {
623
- preserveScroll: options.preserveScroll,
624
- preserveState: options.preserveState,
625
- replace: options.replace,
626
- viewTransition: options.viewTransition
627
- }, signal, commitTarget, deferredRegistry);
628
663
  }
629
664
  if (response && method !== "GET" && !response.ok) throw await createActionErrorFromResponse(response, fetchUrl);
630
665
  if (response && !response.headers.get("X-VoidPages")) {
@@ -704,10 +739,25 @@ async function createPageNavigationEngine(config) {
704
739
  function makeCommit(commitTarget, options, shell, deferredRegistry, resourceId, getResource) {
705
740
  let committed = false;
706
741
  return async () => {
707
- if (committed) return;
742
+ if (committed) return false;
708
743
  committed = true;
709
744
  const result = await shell;
710
- if (!result) return;
745
+ if (!result) return false;
746
+ if (resourceId < _urlNavigationId) return false;
747
+ if (!options._popstate) {
748
+ const historyUrl = commitTarget.fetchUrl + commitTarget.hash;
749
+ const resource = getResource();
750
+ const currentDocumentUrl = window.location.pathname + window.location.search;
751
+ const replaceHistory = !!options.replace || resource.method !== "GET" && historyUrl === currentDocumentUrl + commitTarget.hash;
752
+ try {
753
+ scrollRestoration.writeHistory(historyUrl, replaceHistory);
754
+ } catch (error) {
755
+ if (_pendingResource?.id === resourceId) _pendingResource = null;
756
+ resource.dispose();
757
+ throw error;
758
+ }
759
+ }
760
+ _urlNavigationId = resourceId;
711
761
  if (_pendingResource?.id === resourceId) _pendingResource = null;
712
762
  const previousResource = _committedResource;
713
763
  const previousDeferredRegistry = _committedDeferredRegistry;
@@ -726,14 +776,11 @@ async function createPageNavigationEngine(config) {
726
776
  if (preservedDeferredRegistry && preservedDeferredRegistry !== deferredRegistry) deferredRegistry.dispose();
727
777
  applyClientHead(result.pageData.head);
728
778
  _currentFetchUrl = commitTarget.fetchUrl;
729
- if (!options.preserveState) {
730
- const historyUrl = commitTarget.fetchUrl + commitTarget.hash;
731
- scrollRestoration.writeHistory(historyUrl, !!options.replace);
732
- }
733
779
  scrollRestoration.commit();
734
780
  requestAnimationFrame(() => {
735
781
  if (!options.preserveScroll) restoreScroll(options._scrollPosition, commitTarget.hash);
736
782
  });
783
+ return true;
737
784
  };
738
785
  }
739
786
  const initialPageData = readInitialPageData();
@@ -760,8 +807,13 @@ async function createPageNavigationEngine(config) {
760
807
  const hashNavigationBaseUrl = options._popstate ? _currentFetchUrl : currentPath;
761
808
  _pendingResource?.abort();
762
809
  _pendingResource = null;
763
- if (effectiveFetchUrl === hashNavigationBaseUrl && method === "GET" && !options.data && Boolean(hash || options._popstate)) {
764
- commitHashNavigation(effectiveFetchUrl, hash, options, !options._popstate && !options.preserveState);
810
+ if (!options._refresh && effectiveFetchUrl === hashNavigationBaseUrl && method === "GET" && !options.data && Boolean(hash || options._popstate)) {
811
+ let shell = Promise.resolve(void 0);
812
+ try {
813
+ commitHashNavigation(effectiveFetchUrl, hash, options, !options._popstate);
814
+ } catch (error) {
815
+ shell = Promise.reject(error);
816
+ }
765
817
  return {
766
818
  id,
767
819
  url,
@@ -770,12 +822,15 @@ async function createPageNavigationEngine(config) {
770
822
  method,
771
823
  options,
772
824
  immediate: true,
773
- shell: Promise.resolve(void 0),
825
+ shell,
774
826
  abort() {},
775
- async commit() {},
827
+ async commit() {
828
+ return true;
829
+ },
776
830
  dispose() {}
777
831
  };
778
832
  }
833
+ if (options._popstate) _urlNavigationId = id;
779
834
  const controller = new AbortController();
780
835
  const deferredRegistry = new DeferredRegistry();
781
836
  const commitTarget = {
@@ -783,7 +838,7 @@ async function createPageNavigationEngine(config) {
783
838
  hash
784
839
  };
785
840
  const shell = loadNavigationShell(id, url, effectiveFetchUrl, method, options, controller.signal, commitTarget, deferredRegistry);
786
- let commitResource = async () => {};
841
+ let commitResource = async () => false;
787
842
  const stop = () => {
788
843
  controller.abort(abortError());
789
844
  deferredRegistry.dispose();
@@ -940,6 +995,39 @@ function isEqualFormValue(a, b) {
940
995
  return false;
941
996
  }
942
997
  //#endregion
998
+ //#region src/pages/form-reset.ts
999
+ function isFormResetOptions(value) {
1000
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1001
+ }
1002
+ function cloneFormValue(value) {
1003
+ return clone(value, /* @__PURE__ */ new WeakMap());
1004
+ }
1005
+ function clone(value, seen) {
1006
+ if (value === null || typeof value !== "object") return value;
1007
+ const prototype = Object.getPrototypeOf(value);
1008
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return value;
1009
+ if (seen.has(value)) return seen.get(value);
1010
+ const result = Array.isArray(value) ? new Array(value.length) : Object.create(prototype);
1011
+ seen.set(value, result);
1012
+ for (const key of Object.keys(value)) Object.defineProperty(result, key, {
1013
+ value: clone(value[key], seen),
1014
+ enumerable: true,
1015
+ configurable: true,
1016
+ writable: true
1017
+ });
1018
+ return result;
1019
+ }
1020
+ function parseFormResetArgs(args) {
1021
+ if (args.length > 0 && isFormResetOptions(args[0])) return {
1022
+ initial: args[0].initial === true,
1023
+ fields: args.slice(1)
1024
+ };
1025
+ return {
1026
+ initial: false,
1027
+ fields: args
1028
+ };
1029
+ }
1030
+ //#endregion
943
1031
  //#region src/pages/form-presentation.ts
944
1032
  function formErrorMessage(form) {
945
1033
  return form.error?.message ?? (Object.values(form.errors).filter(Boolean).join(". ") || null);
@@ -1069,6 +1157,17 @@ function createSsrRouter(url = "/", params = {}) {
1069
1157
  };
1070
1158
  }
1071
1159
  const ssrProxy = createSsrRouter();
1160
+ /** Refetch the current page in place: same history entry, URL hash, state and scroll. */
1161
+ function refreshPage(router, options = {}) {
1162
+ const { pathname, search, hash } = window.location;
1163
+ return router.visit(pathname + search + hash, {
1164
+ preserveState: true,
1165
+ preserveScroll: true,
1166
+ replace: true,
1167
+ ...options,
1168
+ _refresh: true
1169
+ });
1170
+ }
1072
1171
  async function submitAction(router, url, options) {
1073
1172
  try {
1074
1173
  const pageData = await router.visit(url, options);
@@ -1122,6 +1221,13 @@ async function createVoidRouter(config) {
1122
1221
  let routeUrl = currentUrl();
1123
1222
  let routeParams = engine.initialPageData.params ?? {};
1124
1223
  let activeNavigationId = null;
1224
+ let committedPage = {
1225
+ pageData: engine.initialPageData,
1226
+ component: engine.initialComponent,
1227
+ layouts: engine.initialLayouts
1228
+ };
1229
+ let renderedPage = committedPage;
1230
+ let failedRender = null;
1125
1231
  const setRouteState = (url, params = routeParams) => {
1126
1232
  routeUrl = url;
1127
1233
  routeParams = params;
@@ -1137,20 +1243,57 @@ async function createVoidRouter(config) {
1137
1243
  const result = await resource.shell;
1138
1244
  if (!result) return;
1139
1245
  setRouteState(result.pageData.url || resource.fetchUrl + resource.hash, result.pageData.params ?? {});
1140
- const applyUpdate = () => config.adapter.applyUpdate(result.pageData, result.component, result.layouts, { preserveState: resource.options.preserveState ?? resource.method !== "GET" });
1141
- if ((resource.options.viewTransition ?? config.viewTransitions) && document.startViewTransition) await document.startViewTransition(() => applyUpdate()).updateCallbackDone;
1246
+ const preserveState = resource.options.preserveState ?? resource.method !== "GET";
1247
+ const applyUpdate = () => {
1248
+ renderedPage = result;
1249
+ failedRender = null;
1250
+ return config.adapter.applyUpdate(result.pageData, result.component, result.layouts, { preserveState });
1251
+ };
1252
+ let applied = true;
1253
+ if ((resource.options.viewTransition ?? config.viewTransitions) && document.startViewTransition) await document.startViewTransition(() => {
1254
+ if (activeNavigationId !== resource.id) {
1255
+ applied = false;
1256
+ return;
1257
+ }
1258
+ return applyUpdate();
1259
+ }).updateCallbackDone;
1142
1260
  else await applyUpdate();
1143
- await resource.commit();
1261
+ let committed = false;
1262
+ if (applied) try {
1263
+ committed = await resource.commit();
1264
+ } catch (error) {
1265
+ if (renderedPage === result) failedRender = { preserveState };
1266
+ throw error;
1267
+ }
1268
+ if (!committed) throw new DOMException("Navigation aborted", "AbortError");
1269
+ committedPage = result;
1270
+ if (renderedPage === result) failedRender = null;
1144
1271
  if (activeNavigationId === resource.id) setRouteState(currentUrl(), result.pageData.params ?? {});
1145
1272
  return result.pageData;
1146
1273
  } catch (error) {
1147
1274
  if (resource.method.toUpperCase() === "GET" && !resource.options._resolveOnShell && isAbortError(error)) return;
1148
1275
  throw error;
1149
1276
  } finally {
1150
- if (activeNavigationId === resource.id) {
1151
- activeNavigationId = null;
1152
- setRouteState(currentUrl());
1153
- setNavigation(idleNavigationState());
1277
+ const ownsNavigation = activeNavigationId === resource.id;
1278
+ if (ownsNavigation || activeNavigationId === null) {
1279
+ let restored = false;
1280
+ if (failedRender && renderedPage !== committedPage) {
1281
+ const { preserveState } = failedRender;
1282
+ failedRender = null;
1283
+ renderedPage = committedPage;
1284
+ restored = true;
1285
+ const page = committedPage;
1286
+ try {
1287
+ await config.adapter.applyUpdate(page.pageData, page.component, page.layouts, { preserveState });
1288
+ } catch (error) {
1289
+ reportError(error);
1290
+ }
1291
+ }
1292
+ if (ownsNavigation && activeNavigationId === resource.id) {
1293
+ activeNavigationId = null;
1294
+ setRouteState(currentUrl(), restored ? committedPage.pageData.params ?? {} : void 0);
1295
+ setNavigation(idleNavigationState());
1296
+ } else if (restored && activeNavigationId === null) setRouteState(currentUrl(), committedPage.pageData.params ?? {});
1154
1297
  }
1155
1298
  }
1156
1299
  }
@@ -1172,11 +1315,7 @@ async function createVoidRouter(config) {
1172
1315
  return applyNavigationResource(engine.prepareVisit(normalizeUrl(url), options));
1173
1316
  },
1174
1317
  refresh(options = {}) {
1175
- return router.visit(window.location.pathname + window.location.search, {
1176
- preserveState: true,
1177
- preserveScroll: true,
1178
- ...options
1179
- });
1318
+ return refreshPage(router, options);
1180
1319
  },
1181
1320
  prefetch(url, options = {}) {
1182
1321
  return engine.prefetch(normalizeUrl(url), options);
@@ -1238,4 +1377,4 @@ function initIslands(islands, hydrateFn) {
1238
1377
  });
1239
1378
  }
1240
1379
  //#endregion
1241
- export { VoidActionError, categorizeActionError, createActionClient, createPageNavigationEngine, createRouterFacade, createSsrRouter, createVoidRouter, formErrorMessage, formRetryMessage, formSubmissionBlocked, getValidationErrors, hasFiles, idleNavigationState, initIslands, interpolateRouteParams, isAbortError, isCallSiteActionError, isEqualFormValue, isFile, isModifiedEvent, mergeDataIntoHref, objectToFormData, scheduleFormRetry, scheduleHydration, ssrProxy, submitAction };
1380
+ export { VoidActionError, categorizeActionError, cloneFormValue, createActionClient, createPageNavigationEngine, createRouterFacade, createSsrRouter, createVoidRouter, formErrorMessage, formRetryMessage, formSubmissionBlocked, getValidationErrors, hasFiles, idleNavigationState, initIslands, interpolateRouteParams, isAbortError, isCallSiteActionError, isEqualFormValue, isFile, isFormResetOptions, isModifiedEvent, mergeDataIntoHref, objectToFormData, parseFormResetArgs, refreshPage, scheduleFormRetry, scheduleHydration, ssrProxy, submitAction };
@@ -1,6 +1,6 @@
1
1
  import { a as renderHtmlAttrs, i as renderHeadToString, n as HeadDescriptor, o as resolveHead, r as renderBodyAttrs, t as HeadConfig } from "../head-C8K_iGe6.mjs";
2
- import "../config-DQfHOKh9.mjs";
3
- import { i as PageDefinition, n as LayoutDefinition, o as PageScanResult, r as NamedLayoutDefinition } from "../types-7AIz0OZu.mjs";
2
+ import "../config-Du88-7Y8.mjs";
3
+ import { i as PageDefinition, n as LayoutDefinition, o as PageScanResult, r as NamedLayoutDefinition, s as RouteEnvironment } from "../types-w72dljaA.mjs";
4
4
  import { r as serializePageData } from "../serialize-DtR8Vwa_.mjs";
5
5
  //#region src/project-paths.d.ts
6
6
  type ProjectPaths = {
@@ -41,13 +41,29 @@ type PageScanOptions = {
41
41
  output?: "server" | "static";
42
42
  paths?: ProjectPaths;
43
43
  pagesDir?: string;
44
+ /** Report pages that share a route. Off when another framework owns pages/ (Nuxt nests users.vue and users/index.vue). */
45
+ checkRoutes?: boolean;
46
+ /** Keep only pages for this environment (`.dev` / `.prod` suffix). Unset keeps every page. */
47
+ environment?: RouteEnvironment;
44
48
  };
49
+ /**
50
+ * The environment a file under pages/ is limited to, read from its name the way
51
+ * scanPages does: `home.dev.tsx`, `home.dev.island.vue` and `home.dev.server.ts`
52
+ * give 'dev'. Files the scanner skips (`_` segments, other extensions) give null.
53
+ */
54
+ export declare function pageFileEnvironment(relativePath: string): RouteEnvironment | null;
45
55
  export declare function scanPages(root: string, options?: PageScanOptions): Promise<PageScanResult>;
46
56
  //#endregion
47
57
  //#region src/pages/manifest.d.ts
48
58
  /**
49
59
  * Generates the component import map and layout tree as code strings.
50
60
  * Used by both SSR renderer and client entry virtual modules.
61
+ *
62
+ * Client entries load this eagerly, so it grows with every page. Each page id
63
+ * is written once, identical layout chains are shared, and static routes are
64
+ * matched by exact lookup instead of a RegExp per page. The emitted bindings
65
+ * (`components`, `layoutTree`, `routeMeta`, `matchRoute`) keep their shape;
66
+ * `matchRoute` takes a decoded pathname (see `decodePagePath`).
51
67
  */
52
68
  export declare function generateComponentManifest(scan: PageScanResult, pagesDir: string): string;
53
69
  //#endregion
@@ -1,60 +1,10 @@
1
1
  import { a as join } from "../dist-ipQi0Q8y.mjs";
2
2
  import { r as resolvePagesDir } from "../project-paths-DGu_QZ_Q.mjs";
3
3
  import { p as readConfig } from "../config-DHgSEWT7.mjs";
4
- import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, o as toLayoutId, r as resolveLayoutChain, t as scanPages } from "../scan-8IzYXiU_.mjs";
4
+ import { a as resolveLayoutChain, i as resolveEffectiveLayoutChain, n as scanPages, r as generateComponentManifest, s as resolveNamedLayout, t as pageFileEnvironment } from "../scan-N9WzdcAl.mjs";
5
5
  import { r as parseRedirectsFile } from "../headers-D522zd0A.mjs";
6
6
  import { i as resolveHead, n as renderHeadToString, r as renderHtmlAttrs, t as renderBodyAttrs } from "../head-D2VF4ApL.mjs";
7
7
  import { r as serializePageData } from "../serialize-YHvlcG3Q.mjs";
8
- //#region src/pages/manifest.ts
9
- /**
10
- * Generates the component import map and layout tree as code strings.
11
- * Used by both SSR renderer and client entry virtual modules.
12
- */
13
- function generateComponentManifest(scan, pagesDir) {
14
- const lines = [];
15
- lines.push("const components = {");
16
- for (const page of scan.pages) {
17
- const importPath = `${pagesDir}/${page.componentPath}`;
18
- lines.push(` ${JSON.stringify(page.componentId)}: () => import(${JSON.stringify(importPath)}),`);
19
- }
20
- for (const layout of [...scan.layouts, ...scan.namedLayouts]) {
21
- const importPath = `${pagesDir}/${layout.filePath}`;
22
- lines.push(` ${JSON.stringify(toLayoutId(layout))}: () => import(${JSON.stringify(importPath)}),`);
23
- }
24
- lines.push("};");
25
- lines.push("const layoutTree = {");
26
- for (const page of scan.pages) {
27
- const chain = resolveLayoutIds(page, scan.layouts, scan.namedLayouts);
28
- if (chain.length > 0) lines.push(` ${JSON.stringify(page.componentId)}: ${JSON.stringify(chain)},`);
29
- }
30
- lines.push("};");
31
- lines.push("const routeMeta = {");
32
- for (const page of scan.pages) if (page.island) lines.push(` ${JSON.stringify(page.componentId)}: { island: true },`);
33
- lines.push("};");
34
- lines.push("const routes = [");
35
- for (const page of scan.pages) {
36
- const regex = patternToRegex(page.pattern);
37
- lines.push(` { pattern: ${regex}, id: ${JSON.stringify(page.componentId)} },`);
38
- }
39
- lines.push("];");
40
- lines.push(`function matchRoute(url) {
41
- const path = new URL(url, "http://x").pathname;
42
- for (const r of routes) {
43
- if (r.pattern.test(path)) return r.id;
44
- }
45
- return null;
46
- }`);
47
- return lines.join("\n");
48
- }
49
- function patternToRegex(pattern) {
50
- return `/^${pattern.split("/").map((segment) => {
51
- if (segment === "*") return "(.*)";
52
- if (/^:[^/{}]+\{\.\+\}$/.test(segment)) return "(.+)";
53
- if (/^:[^/]+$/.test(segment)) return "([^/]+)";
54
- return segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
55
- }).join("/").replace(/\//g, "\\/")}$/`;
56
- }
57
- //#endregion
58
8
  //#region src/pages/static-data.ts
59
9
  function resolveStaticPageDataBuildOptions(root, options = {}) {
60
10
  const config = readConfig(root);
@@ -73,4 +23,4 @@ function resolveStaticPageDataBuildOptions(root, options = {}) {
73
23
  };
74
24
  }
75
25
  //#endregion
76
- export { generateComponentManifest, renderBodyAttrs, renderHeadToString, renderHtmlAttrs, resolveEffectiveLayoutChain, resolveHead, resolveLayoutChain, resolveNamedLayout, resolvePagesDir, resolveStaticPageDataBuildOptions, scanPages, serializePageData };
26
+ export { generateComponentManifest, pageFileEnvironment, renderBodyAttrs, renderHeadToString, renderHtmlAttrs, resolveEffectiveLayoutChain, resolveHead, resolveLayoutChain, resolveNamedLayout, resolvePagesDir, resolveStaticPageDataBuildOptions, scanPages, serializePageData };
@@ -1,4 +1,4 @@
1
- import { o as PageScanResult } from "../types-7AIz0OZu.mjs";
1
+ import { o as PageScanResult } from "../types-w72dljaA.mjs";
2
2
  import { Plugin, ResolvedConfig, ViteDevServer } from "vite";
3
3
  //#region ../../node_modules/.pnpm/magic-string@1.4.3/node_modules/magic-string/dist/index.d.mts
4
4
  //#region src/SourceMap.d.ts
@@ -1,5 +1,5 @@
1
1
  import { c as resolve, n as dirname } from "../dist-ipQi0Q8y.mjs";
2
- import { c as findIslandImports, l as findStaticCssImports, n as resolveEffectiveLayoutChain, s as editIslandSource, t as scanPages } from "../scan-8IzYXiU_.mjs";
2
+ import { c as editIslandSource, i as resolveEffectiveLayoutChain, l as findIslandImports, n as scanPages, u as findStaticCssImports } from "../scan-N9WzdcAl.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { isCSSRequest, normalizePath } from "vite";
5
5
  //#region src/pages/islands-plugin.ts
@@ -23,7 +23,10 @@ function resolveSpecifier(specifier, importerDir, extensions) {
23
23
  async function hasIslandPages(root, pagesDir) {
24
24
  if (!existsSync(pagesDir)) return false;
25
25
  try {
26
- return (await scanPages(root, { pagesDir })).pages.some((page) => page.island);
26
+ return (await scanPages(root, {
27
+ pagesDir,
28
+ environment: "prod"
29
+ })).pages.some((page) => page.island);
27
30
  } catch {
28
31
  return false;
29
32
  }
@@ -181,7 +184,10 @@ function watchPagesForRescan(server, pagesDir, root, onRescan) {
181
184
  if (debounceTimer) clearTimeout(debounceTimer);
182
185
  debounceTimer = setTimeout(() => {
183
186
  debounceTimer = null;
184
- pending = scanPages(root, { pagesDir }).then((pageScan) => {
187
+ pending = scanPages(root, {
188
+ pagesDir,
189
+ environment: "dev"
190
+ }).then((pageScan) => {
185
191
  onRescan(pageScan);
186
192
  for (const env of Object.values(server.environments)) {
187
193
  const mod = env.moduleGraph.getModuleById("\0virtual:void-islands-renderer");
@@ -1,3 +1,3 @@
1
- import { w as ValidationError } from "../handler-BbkSPzGF.mjs";
2
- import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-BBDpJz3G.mjs";
1
+ import { w as ValidationError } from "../handler-CQv5YDS0.mjs";
2
+ import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-BekmFxCI.mjs";
3
3
  export { PageObject, PageRenderResult, ValidationError, flattenValidationErrors, handlePageGet, handlePageMutation, safeJsonStringify };
@@ -0,0 +1 @@
1
+ export { t as parsePlatformArgs } from "./platform-args-BMD2gjc_.mjs";
@@ -1,4 +1,4 @@
1
- import { n as operatorGroups, r as parseOperatorArgs } from "./operator-args-UnE8Y2eK.mjs";
1
+ import { n as operatorGroups, r as parseOperatorArgs } from "./operator-args-BsJIYXaT.mjs";
2
2
  import { PLATFORM_LOGIN_KINDS, normalizePlatformDashboardUrl, parsePlatformLoginId } from "@void/platform";
3
3
  import { parsePlatformPlanId } from "@void/platform/plans";
4
4
  //#region src/cli/platform-config-args.ts