@reckona/mreact-router 0.0.180 → 0.0.182

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 (45) hide show
  1. package/dist/actions.d.ts.map +1 -1
  2. package/dist/actions.js +20 -8
  3. package/dist/actions.js.map +1 -1
  4. package/dist/adapters/cloudflare.d.ts.map +1 -1
  5. package/dist/adapters/cloudflare.js +53 -18
  6. package/dist/adapters/cloudflare.js.map +1 -1
  7. package/dist/build.d.ts.map +1 -1
  8. package/dist/build.js +65 -12
  9. package/dist/build.js.map +1 -1
  10. package/dist/built-assets.d.ts.map +1 -1
  11. package/dist/built-assets.js +2 -2
  12. package/dist/built-assets.js.map +1 -1
  13. package/dist/cache-config.d.ts +1 -1
  14. package/dist/cache-config.d.ts.map +1 -1
  15. package/dist/cache-config.js.map +1 -1
  16. package/dist/cache.d.ts.map +1 -1
  17. package/dist/cache.js +18 -1
  18. package/dist/cache.js.map +1 -1
  19. package/dist/client.d.ts.map +1 -1
  20. package/dist/client.js +16 -6
  21. package/dist/client.js.map +1 -1
  22. package/dist/csrf.js +10 -6
  23. package/dist/csrf.js.map +1 -1
  24. package/dist/navigation.d.ts.map +1 -1
  25. package/dist/navigation.js +14 -1
  26. package/dist/navigation.js.map +1 -1
  27. package/dist/render.d.ts +2 -0
  28. package/dist/render.d.ts.map +1 -1
  29. package/dist/render.js +81 -38
  30. package/dist/render.js.map +1 -1
  31. package/dist/vite.d.ts.map +1 -1
  32. package/dist/vite.js +5 -3
  33. package/dist/vite.js.map +1 -1
  34. package/package.json +11 -11
  35. package/src/actions.ts +26 -9
  36. package/src/adapters/cloudflare.ts +98 -41
  37. package/src/build.ts +93 -30
  38. package/src/built-assets.ts +2 -3
  39. package/src/cache-config.ts +1 -0
  40. package/src/cache.ts +20 -1
  41. package/src/client.ts +16 -6
  42. package/src/csrf.ts +13 -6
  43. package/src/navigation.ts +16 -1
  44. package/src/render.ts +168 -70
  45. package/src/vite.ts +6 -3
package/dist/csrf.js CHANGED
@@ -6,14 +6,14 @@ const formFieldCsrf = "__mreact_csrf";
6
6
  */
7
7
  export const formCsrfFieldName = formFieldCsrf;
8
8
  export function serverActionCookie(csrfToken) {
9
- const production = isProductionEnvironment();
9
+ const secure = shouldUseSecureCsrfCookie();
10
10
  const parts = [
11
11
  `${currentCsrfCookieName()}=${encodeURIComponent(csrfToken)}`,
12
12
  "Path=/",
13
13
  "SameSite=Lax",
14
14
  "HttpOnly",
15
15
  ];
16
- if (production) {
16
+ if (secure) {
17
17
  parts.push("Secure");
18
18
  }
19
19
  return parts.join("; ");
@@ -77,14 +77,18 @@ function randomToken() {
77
77
  const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
78
78
  return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
79
79
  }
80
- function isProductionEnvironment() {
81
- return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
80
+ function isLocalCsrfEnvironment() {
81
+ return (typeof process !== "undefined" &&
82
+ (process.env?.NODE_ENV === "development" || process.env?.NODE_ENV === "test"));
83
+ }
84
+ function shouldUseSecureCsrfCookie() {
85
+ return !isLocalCsrfEnvironment();
82
86
  }
83
87
  function currentCsrfCookieName() {
84
- return isProductionEnvironment() ? csrfCookieNameProduction : csrfCookieNameDevelopment;
88
+ return shouldUseSecureCsrfCookie() ? csrfCookieNameProduction : csrfCookieNameDevelopment;
85
89
  }
86
90
  function csrfCookieNamesRead() {
87
- return isProductionEnvironment()
91
+ return shouldUseSecureCsrfCookie()
88
92
  ? [csrfCookieNameProduction]
89
93
  : [csrfCookieNameProduction, csrfCookieNameDevelopment];
90
94
  }
package/dist/csrf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../src/csrf.ts"],"names":[],"mappings":"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","sourcesContent":["const csrfCookieNameProduction = \"__Host-mreact.csrf\";\nconst csrfCookieNameDevelopment = \"mreact.csrf\";\nconst formFieldCsrf = \"__mreact_csrf\";\n\n/**\n * Names the hidden form field used for app-router CSRF validation.\n */\nexport const formCsrfFieldName = formFieldCsrf;\n\nexport function serverActionCookie(csrfToken: string): string {\n const production = isProductionEnvironment();\n const parts = [\n `${currentCsrfCookieName()}=${encodeURIComponent(csrfToken)}`,\n \"Path=/\",\n \"SameSite=Lax\",\n \"HttpOnly\",\n ];\n\n if (production) {\n parts.push(\"Secure\");\n }\n\n return parts.join(\"; \");\n}\n\nexport function serverActionCookieName(): string {\n return currentCsrfCookieName();\n}\n\n/**\n * Creates or reuses the CSRF token embedded into server-rendered forms.\n */\nexport function createFormCsrfToken(request?: Request | undefined): string {\n return readExistingFormCsrfToken(request) ?? randomToken();\n}\n\n/**\n * Serializes the CSRF cookie used to validate app-router form submissions.\n */\nexport function formCsrfCookie(csrfToken: string): string {\n return serverActionCookie(csrfToken);\n}\n\n/**\n * Validates the CSRF cookie and hidden form field for a form submission.\n */\nexport function validateFormCsrf(request: Request, formData: FormData): Response | undefined {\n const formToken = stringFormValue(formData.get(formFieldCsrf));\n const cookieHeader = request.headers.get(\"cookie\");\n const cookieToken = csrfCookieNamesRead()\n .map((name) => readCookie(cookieHeader, name))\n .find((token) => token !== undefined);\n\n if (formToken === undefined || cookieToken === undefined) {\n return jsonResponse({ ok: false, error: \"Invalid CSRF token.\" }, 403);\n }\n\n return timingSafeStringEqual(formToken, cookieToken)\n ? undefined\n : jsonResponse({ ok: false, error: \"Invalid CSRF token.\" }, 403);\n}\n\nexport function readExistingFormCsrfToken(request: Request | undefined): string | undefined {\n const cookieHeader = request?.headers.get(\"cookie\") ?? null;\n\n for (const name of csrfCookieNamesRead()) {\n const token = readCookie(cookieHeader, name);\n\n if (token !== undefined && isCsrfTokenShape(token)) {\n return token;\n }\n }\n\n return undefined;\n}\n\nfunction isCsrfTokenShape(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction randomToken(): string {\n const cryptoApi = globalThis.crypto;\n\n if (typeof cryptoApi?.randomUUID === \"function\") {\n return cryptoApi.randomUUID();\n }\n\n if (typeof cryptoApi?.getRandomValues !== \"function\") {\n throw new Error(\"Web Crypto is required to create a CSRF token.\");\n }\n\n const bytes = new Uint8Array(16);\n cryptoApi.getRandomValues(bytes);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\"));\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10).join(\"\")}`;\n}\n\nfunction isProductionEnvironment(): boolean {\n return typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\";\n}\n\nfunction currentCsrfCookieName(): string {\n return isProductionEnvironment() ? csrfCookieNameProduction : csrfCookieNameDevelopment;\n}\n\nfunction csrfCookieNamesRead(): readonly string[] {\n return isProductionEnvironment()\n ? [csrfCookieNameProduction]\n : [csrfCookieNameProduction, csrfCookieNameDevelopment];\n}\n\nfunction timingSafeStringEqual(left: string, right: string): boolean {\n let diff = left.length ^ right.length;\n const length = Math.max(left.length, right.length);\n\n for (let index = 0; index < length; index += 1) {\n diff |= (left.charCodeAt(index) || 0) ^ (right.charCodeAt(index) || 0);\n }\n\n return diff === 0;\n}\n\nfunction stringFormValue(value: FormDataEntryValue | null): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readCookie(cookieHeader: string | null, name: string): string | undefined {\n if (cookieHeader === null || cookieHeader.trim() === \"\") {\n return undefined;\n }\n\n for (const part of cookieHeader.split(\";\")) {\n const [rawName, ...rawValue] = part.trim().split(\"=\");\n\n if (rawName !== name) {\n continue;\n }\n\n try {\n return decodeURIComponent(rawValue.join(\"=\"));\n } catch {\n return rawValue.join(\"=\");\n }\n }\n\n return undefined;\n}\n\nfunction jsonResponse(payload: unknown, status: number): Response {\n return Response.json(payload, { status });\n}\n"]}
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../src/csrf.ts"],"names":[],"mappings":"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","sourcesContent":["const csrfCookieNameProduction = \"__Host-mreact.csrf\";\nconst csrfCookieNameDevelopment = \"mreact.csrf\";\nconst formFieldCsrf = \"__mreact_csrf\";\n\n/**\n * Names the hidden form field used for app-router CSRF validation.\n */\nexport const formCsrfFieldName = formFieldCsrf;\n\nexport function serverActionCookie(csrfToken: string): string {\n const secure = shouldUseSecureCsrfCookie();\n const parts = [\n `${currentCsrfCookieName()}=${encodeURIComponent(csrfToken)}`,\n \"Path=/\",\n \"SameSite=Lax\",\n \"HttpOnly\",\n ];\n\n if (secure) {\n parts.push(\"Secure\");\n }\n\n return parts.join(\"; \");\n}\n\nexport function serverActionCookieName(): string {\n return currentCsrfCookieName();\n}\n\n/**\n * Creates or reuses the CSRF token embedded into server-rendered forms.\n */\nexport function createFormCsrfToken(request?: Request | undefined): string {\n return readExistingFormCsrfToken(request) ?? randomToken();\n}\n\n/**\n * Serializes the CSRF cookie used to validate app-router form submissions.\n */\nexport function formCsrfCookie(csrfToken: string): string {\n return serverActionCookie(csrfToken);\n}\n\n/**\n * Validates the CSRF cookie and hidden form field for a form submission.\n */\nexport function validateFormCsrf(request: Request, formData: FormData): Response | undefined {\n const formToken = stringFormValue(formData.get(formFieldCsrf));\n const cookieHeader = request.headers.get(\"cookie\");\n const cookieToken = csrfCookieNamesRead()\n .map((name) => readCookie(cookieHeader, name))\n .find((token) => token !== undefined);\n\n if (formToken === undefined || cookieToken === undefined) {\n return jsonResponse({ ok: false, error: \"Invalid CSRF token.\" }, 403);\n }\n\n return timingSafeStringEqual(formToken, cookieToken)\n ? undefined\n : jsonResponse({ ok: false, error: \"Invalid CSRF token.\" }, 403);\n}\n\nexport function readExistingFormCsrfToken(request: Request | undefined): string | undefined {\n const cookieHeader = request?.headers.get(\"cookie\") ?? null;\n\n for (const name of csrfCookieNamesRead()) {\n const token = readCookie(cookieHeader, name);\n\n if (token !== undefined && isCsrfTokenShape(token)) {\n return token;\n }\n }\n\n return undefined;\n}\n\nfunction isCsrfTokenShape(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction randomToken(): string {\n const cryptoApi = globalThis.crypto;\n\n if (typeof cryptoApi?.randomUUID === \"function\") {\n return cryptoApi.randomUUID();\n }\n\n if (typeof cryptoApi?.getRandomValues !== \"function\") {\n throw new Error(\"Web Crypto is required to create a CSRF token.\");\n }\n\n const bytes = new Uint8Array(16);\n cryptoApi.getRandomValues(bytes);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\"));\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10).join(\"\")}`;\n}\n\nfunction isLocalCsrfEnvironment(): boolean {\n return (\n typeof process !== \"undefined\" &&\n (process.env?.NODE_ENV === \"development\" || process.env?.NODE_ENV === \"test\")\n );\n}\n\nfunction shouldUseSecureCsrfCookie(): boolean {\n return !isLocalCsrfEnvironment();\n}\n\nfunction currentCsrfCookieName(): string {\n return shouldUseSecureCsrfCookie() ? csrfCookieNameProduction : csrfCookieNameDevelopment;\n}\n\nfunction csrfCookieNamesRead(): readonly string[] {\n return shouldUseSecureCsrfCookie()\n ? [csrfCookieNameProduction]\n : [csrfCookieNameProduction, csrfCookieNameDevelopment];\n}\n\nfunction timingSafeStringEqual(left: string, right: string): boolean {\n let diff = left.length ^ right.length;\n const length = Math.max(left.length, right.length);\n\n for (let index = 0; index < length; index += 1) {\n diff |= (left.charCodeAt(index) || 0) ^ (right.charCodeAt(index) || 0);\n }\n\n return diff === 0;\n}\n\nfunction stringFormValue(value: FormDataEntryValue | null): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readCookie(cookieHeader: string | null, name: string): string | undefined {\n if (cookieHeader === null || cookieHeader.trim() === \"\") {\n return undefined;\n }\n\n for (const part of cookieHeader.split(\";\")) {\n const [rawName, ...rawValue] = part.trim().split(\"=\");\n\n if (rawName !== name) {\n continue;\n }\n\n try {\n return decodeURIComponent(rawValue.join(\"=\"));\n } catch {\n return rawValue.join(\"=\");\n }\n }\n\n return undefined;\n}\n\nfunction jsonResponse(payload: unknown, status: number): Response {\n return Response.json(payload, { status });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC;CAC3B;AAgDD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,KAAK,CAS/E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,KAAK,CASP;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAa/E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAY1F;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrE,wBAAsB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAUzF;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,KAAK,CAKhC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,KAAK,CAErC;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,cAAc,CAErC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAiB3E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAElE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAkBrE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAYxD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAOtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAIrG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvD"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC;CAC3B;AA+DD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,KAAK,CAS/E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,KAAK,CASP;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAa/E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAY1F;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrE,wBAAsB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAUzF;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,KAAK,CAKhC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,KAAK,CAErC;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,cAAc,CAErC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAiB3E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAElE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAkBrE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAYxD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAOtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAIrG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvD"}
@@ -13,11 +13,22 @@ function stripLeadingControlOrWhitespace(value) {
13
13
  }
14
14
  return value.slice(start);
15
15
  }
16
+ function containsControlCharacter(value) {
17
+ for (let index = 0; index < value.length; index += 1) {
18
+ const code = value.charCodeAt(index);
19
+ if (code <= 0x1f || code === 0x7f) {
20
+ return true;
21
+ }
22
+ }
23
+ return false;
24
+ }
16
25
  // Returns true if `location` is safe to use as a same-origin Location header.
17
26
  // Allowed: path-absolute (`/foo`), query-only (`?x=1`), hash-only (`#x`),
18
27
  // relative (`foo`). Rejected: protocol-relative (`//evil`), backslash variants
19
28
  // (`/\evil`, `\\evil`), and anything with a scheme like `javascript:`.
20
29
  function isSafeInternalRedirect(location) {
30
+ if (containsControlCharacter(location))
31
+ return false;
21
32
  const trimmed = stripLeadingControlOrWhitespace(location);
22
33
  if (trimmed === "")
23
34
  return false;
@@ -33,6 +44,8 @@ function isSafeInternalRedirect(location) {
33
44
  return true;
34
45
  }
35
46
  function isSafeExternalRedirect(location) {
47
+ if (containsControlCharacter(location))
48
+ return false;
36
49
  const trimmed = stripLeadingControlOrWhitespace(location);
37
50
  const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(trimmed);
38
51
  if (match === null || match[1] === undefined)
@@ -44,7 +57,7 @@ function throwUnsafeRedirect(location) {
44
57
  throw new TypeError(`unsafe redirect target: ${JSON.stringify(location)} - use redirectExternal() for off-site destinations and ensure the URL is http(s)`);
45
58
  }
46
59
  function throwUnsafeRewrite(location) {
47
- throw new TypeError(`unsafe rewrite target: ${JSON.stringify(location)}`);
60
+ throw new TypeError(`unsafe rewrite target: ${JSON.stringify(location)} - rewrite() only accepts same-origin paths, query strings, or hashes; external, protocol-relative, backslash, and control-character targets are rejected`);
48
61
  }
49
62
  /**
50
63
  * Throws an internal redirect for loaders, middleware, route handlers, or server actions.
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseCookieHeader } from \"./cookies.js\";\n\nconst redirectErrorName = \"MReactRedirect\";\nconst notFoundErrorName = \"MReactNotFound\";\nconst rewriteHeaderName = \"x-mreact-rewrite\";\nconst rewriteLocationSymbol = Symbol.for(\"mreact.router.rewriteLocation\");\n\nexport interface RedirectOptions {\n status?: 301 | 302 | 303 | 307 | 308;\n}\n\nexport type MiddlewareNext = undefined;\n\n/**\n * Describes a parser used by `parseForm()` to validate submitted form data.\n */\nexport interface ParseSchema<T> {\n parse(value: FormData): T;\n}\n\n// Strip leading C0 controls + ASCII whitespace per WHATWG URL parsing.\n// Browsers ignore these characters when resolving the Location header,\n// so attacker payloads must be rejected after the same normalization.\nfunction stripLeadingControlOrWhitespace(value: string): string {\n let start = 0;\n\n while (start < value.length && value.charCodeAt(start) <= 0x20) {\n start += 1;\n }\n\n return value.slice(start);\n}\n\n// Returns true if `location` is safe to use as a same-origin Location header.\n// Allowed: path-absolute (`/foo`), query-only (`?x=1`), hash-only (`#x`),\n// relative (`foo`). Rejected: protocol-relative (`//evil`), backslash variants\n// (`/\\evil`, `\\\\evil`), and anything with a scheme like `javascript:`.\nfunction isSafeInternalRedirect(location: string): boolean {\n const trimmed = stripLeadingControlOrWhitespace(location);\n if (trimmed === \"\") return false;\n if (trimmed.startsWith(\"//\")) return false;\n if (trimmed.startsWith(\"/\\\\\")) return false;\n if (trimmed.startsWith(\"\\\\\")) return false;\n // Reject anything that parses as a URL with a scheme.\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) return false;\n return true;\n}\n\nfunction isSafeExternalRedirect(location: string): boolean {\n const trimmed = stripLeadingControlOrWhitespace(location);\n const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(trimmed);\n if (match === null || match[1] === undefined) return false;\n const scheme = match[1].toLowerCase();\n return scheme === \"http\" || scheme === \"https\";\n}\n\nfunction throwUnsafeRedirect(location: string): never {\n throw new TypeError(\n `unsafe redirect target: ${JSON.stringify(location)} - use redirectExternal() for off-site destinations and ensure the URL is http(s)`,\n );\n}\n\nfunction throwUnsafeRewrite(location: string): never {\n throw new TypeError(`unsafe rewrite target: ${JSON.stringify(location)}`);\n}\n\n/**\n * Throws an internal redirect for loaders, middleware, route handlers, or server actions.\n *\n * The target must be same-origin or relative; use `redirectExternal()` for trusted `http` or `https` destinations. The default status is `303`.\n */\nexport function redirect(location: string, options: RedirectOptions = {}): never {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n throw Object.assign(new Error(`Redirect to ${location}`), {\n location,\n name: redirectErrorName,\n status: options.status ?? 303,\n });\n}\n\n/**\n * Throws an external redirect for trusted `http` or `https` destinations.\n *\n * This helper is intentionally separate from `redirect()` so off-site navigation is explicit. The default status is `307`.\n */\nexport function redirectExternal(\n location: string,\n options: RedirectOptions = {},\n): never {\n if (!isSafeExternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n throw Object.assign(new Error(`Redirect to ${location}`), {\n location,\n name: redirectErrorName,\n status: options.status ?? 307,\n });\n}\n\n/**\n * Creates a same-origin `303 See Other` redirect response.\n *\n * Use this from route handlers when returning a `Response` is more convenient than throwing through the app-router control flow.\n */\nexport function redirect303(location: string, init: ResponseInit = {}): Response {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n\n const headers = new Headers(init.headers);\n headers.set(\"location\", location);\n\n return new Response(null, {\n ...init,\n headers,\n status: 303,\n });\n}\n\n/**\n * Creates a plain-text error response with a default `text/plain` content type.\n */\nexport function textError(message: string, status = 400, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/plain; charset=utf-8\");\n }\n\n return new Response(message, {\n ...init,\n headers,\n status,\n });\n}\n\n/**\n * Reads `request.formData()` and optionally validates it with a schema-like parser.\n *\n * Pass a schema object with `parse(FormData)` when a route handler or server action should receive typed form data.\n */\nexport async function parseForm(request: Request): Promise<FormData>;\nexport async function parseForm<T>(request: Request, schema: ParseSchema<T>): Promise<T>;\nexport async function parseForm<T>(\n request: Request,\n schema?: ParseSchema<T>,\n): Promise<FormData | T> {\n const form = await request.formData();\n\n return schema === undefined ? form : schema.parse(form);\n}\n\n/**\n * Throws a route-level 404 control error.\n *\n * Use this from loaders, metadata, middleware, or route handlers when the matched route is valid but the requested resource is absent.\n */\nexport function notFound(): never {\n throw Object.assign(new Error(\"Not Found\"), {\n name: notFoundErrorName,\n status: 404,\n });\n}\n\n/**\n * Alias for `notFound()` for codebases that prefer an explicit throwing helper name.\n */\nexport function throwNotFound(): never {\n return notFound();\n}\n\n/**\n * Continues middleware processing without changing the request.\n */\nexport function next(): MiddlewareNext {\n return undefined;\n}\n\n/**\n * Creates an internal rewrite response consumed by app-router middleware.\n *\n * The target must be a same-origin route path, query, hash, or relative URL; protocol-relative, external, and control-character targets are rejected.\n */\nexport function rewrite(location: string, init: ResponseInit = {}): Response {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRewrite(location);\n }\n\n const response = new Response(null, {\n ...init,\n status: init.status ?? 200,\n });\n\n Object.defineProperty(response, rewriteLocationSymbol, {\n configurable: false,\n enumerable: false,\n value: location,\n });\n\n return response;\n}\n\n/**\n * Creates a JSON response using the platform `Response.json()` implementation.\n */\nexport function json(value: unknown, init?: ResponseInit): Response {\n return Response.json(value, init);\n}\n\n/**\n * Creates an HTML response and defaults the content type to `text/html; charset=utf-8`.\n */\nexport function html(value: string, init: ResponseInit = {}): Response {\n if (init.headers === undefined) {\n return new Response(value, {\n ...init,\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n });\n }\n\n const headers = new Headers(init.headers);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/html; charset=utf-8\");\n }\n\n return new Response(value, {\n ...init,\n headers,\n });\n}\n\n/**\n * Returns the request headers object for route code that follows app-router helper naming.\n */\nexport function headers(request: Request): Headers {\n return request.headers;\n}\n\nexport interface RequestCookies {\n entries(): IterableIterator<[string, string]>;\n get(name: string): string | undefined;\n has(name: string): boolean;\n}\n\n/**\n * Parses request cookies into a small read-only helper.\n *\n * Values are decoded with `decodeURIComponent`; malformed encoded values are ignored rather than throwing during request handling.\n */\nexport function cookies(request: Request): RequestCookies {\n let values: ReadonlyMap<string, string> | undefined;\n const cookieValues = () => {\n values ??= parseCookieHeader(request.headers.get(\"cookie\"));\n return values;\n };\n\n return {\n entries: () => cookieValues().entries(),\n get: (name) => cookieValues().get(name),\n has: (name) => cookieValues().has(name),\n };\n}\n\nexport function rewriteLocation(response: Response): string | undefined {\n const marked = (response as { [rewriteLocationSymbol]?: unknown })[rewriteLocationSymbol];\n const candidate = typeof marked === \"string\"\n ? marked\n : response.headers.get(rewriteHeaderName) ?? undefined;\n\n return candidate !== undefined && isSafeInternalRedirect(candidate) ? candidate : undefined;\n}\n\n/**\n * Checks whether an unknown error is an app-router redirect signal.\n */\nexport function isRedirectError(error: unknown): error is Error & { location: string; status: number } {\n return error instanceof Error &&\n error.name === redirectErrorName &&\n typeof (error as { location?: unknown }).location === \"string\";\n}\n\n/**\n * Checks whether an unknown error is an app-router not-found signal.\n */\nexport function isNotFoundError(error: unknown): boolean {\n return error instanceof Error && error.name === notFoundErrorName;\n}\n"]}
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseCookieHeader } from \"./cookies.js\";\n\nconst redirectErrorName = \"MReactRedirect\";\nconst notFoundErrorName = \"MReactNotFound\";\nconst rewriteHeaderName = \"x-mreact-rewrite\";\nconst rewriteLocationSymbol = Symbol.for(\"mreact.router.rewriteLocation\");\n\nexport interface RedirectOptions {\n status?: 301 | 302 | 303 | 307 | 308;\n}\n\nexport type MiddlewareNext = undefined;\n\n/**\n * Describes a parser used by `parseForm()` to validate submitted form data.\n */\nexport interface ParseSchema<T> {\n parse(value: FormData): T;\n}\n\n// Strip leading C0 controls + ASCII whitespace per WHATWG URL parsing.\n// Browsers ignore these characters when resolving the Location header,\n// so attacker payloads must be rejected after the same normalization.\nfunction stripLeadingControlOrWhitespace(value: string): string {\n let start = 0;\n\n while (start < value.length && value.charCodeAt(start) <= 0x20) {\n start += 1;\n }\n\n return value.slice(start);\n}\n\nfunction containsControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code <= 0x1f || code === 0x7f) {\n return true;\n }\n }\n\n return false;\n}\n\n// Returns true if `location` is safe to use as a same-origin Location header.\n// Allowed: path-absolute (`/foo`), query-only (`?x=1`), hash-only (`#x`),\n// relative (`foo`). Rejected: protocol-relative (`//evil`), backslash variants\n// (`/\\evil`, `\\\\evil`), and anything with a scheme like `javascript:`.\nfunction isSafeInternalRedirect(location: string): boolean {\n if (containsControlCharacter(location)) return false;\n const trimmed = stripLeadingControlOrWhitespace(location);\n if (trimmed === \"\") return false;\n if (trimmed.startsWith(\"//\")) return false;\n if (trimmed.startsWith(\"/\\\\\")) return false;\n if (trimmed.startsWith(\"\\\\\")) return false;\n // Reject anything that parses as a URL with a scheme.\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) return false;\n return true;\n}\n\nfunction isSafeExternalRedirect(location: string): boolean {\n if (containsControlCharacter(location)) return false;\n const trimmed = stripLeadingControlOrWhitespace(location);\n const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(trimmed);\n if (match === null || match[1] === undefined) return false;\n const scheme = match[1].toLowerCase();\n return scheme === \"http\" || scheme === \"https\";\n}\n\nfunction throwUnsafeRedirect(location: string): never {\n throw new TypeError(\n `unsafe redirect target: ${JSON.stringify(location)} - use redirectExternal() for off-site destinations and ensure the URL is http(s)`,\n );\n}\n\nfunction throwUnsafeRewrite(location: string): never {\n throw new TypeError(\n `unsafe rewrite target: ${JSON.stringify(location)} - rewrite() only accepts same-origin paths, query strings, or hashes; external, protocol-relative, backslash, and control-character targets are rejected`,\n );\n}\n\n/**\n * Throws an internal redirect for loaders, middleware, route handlers, or server actions.\n *\n * The target must be same-origin or relative; use `redirectExternal()` for trusted `http` or `https` destinations. The default status is `303`.\n */\nexport function redirect(location: string, options: RedirectOptions = {}): never {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n throw Object.assign(new Error(`Redirect to ${location}`), {\n location,\n name: redirectErrorName,\n status: options.status ?? 303,\n });\n}\n\n/**\n * Throws an external redirect for trusted `http` or `https` destinations.\n *\n * This helper is intentionally separate from `redirect()` so off-site navigation is explicit. The default status is `307`.\n */\nexport function redirectExternal(\n location: string,\n options: RedirectOptions = {},\n): never {\n if (!isSafeExternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n throw Object.assign(new Error(`Redirect to ${location}`), {\n location,\n name: redirectErrorName,\n status: options.status ?? 307,\n });\n}\n\n/**\n * Creates a same-origin `303 See Other` redirect response.\n *\n * Use this from route handlers when returning a `Response` is more convenient than throwing through the app-router control flow.\n */\nexport function redirect303(location: string, init: ResponseInit = {}): Response {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRedirect(location);\n }\n\n const headers = new Headers(init.headers);\n headers.set(\"location\", location);\n\n return new Response(null, {\n ...init,\n headers,\n status: 303,\n });\n}\n\n/**\n * Creates a plain-text error response with a default `text/plain` content type.\n */\nexport function textError(message: string, status = 400, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/plain; charset=utf-8\");\n }\n\n return new Response(message, {\n ...init,\n headers,\n status,\n });\n}\n\n/**\n * Reads `request.formData()` and optionally validates it with a schema-like parser.\n *\n * Pass a schema object with `parse(FormData)` when a route handler or server action should receive typed form data.\n */\nexport async function parseForm(request: Request): Promise<FormData>;\nexport async function parseForm<T>(request: Request, schema: ParseSchema<T>): Promise<T>;\nexport async function parseForm<T>(\n request: Request,\n schema?: ParseSchema<T>,\n): Promise<FormData | T> {\n const form = await request.formData();\n\n return schema === undefined ? form : schema.parse(form);\n}\n\n/**\n * Throws a route-level 404 control error.\n *\n * Use this from loaders, metadata, middleware, or route handlers when the matched route is valid but the requested resource is absent.\n */\nexport function notFound(): never {\n throw Object.assign(new Error(\"Not Found\"), {\n name: notFoundErrorName,\n status: 404,\n });\n}\n\n/**\n * Alias for `notFound()` for codebases that prefer an explicit throwing helper name.\n */\nexport function throwNotFound(): never {\n return notFound();\n}\n\n/**\n * Continues middleware processing without changing the request.\n */\nexport function next(): MiddlewareNext {\n return undefined;\n}\n\n/**\n * Creates an internal rewrite response consumed by app-router middleware.\n *\n * The target must be a same-origin route path, query, hash, or relative URL; protocol-relative, external, and control-character targets are rejected.\n */\nexport function rewrite(location: string, init: ResponseInit = {}): Response {\n if (!isSafeInternalRedirect(location)) {\n throwUnsafeRewrite(location);\n }\n\n const response = new Response(null, {\n ...init,\n status: init.status ?? 200,\n });\n\n Object.defineProperty(response, rewriteLocationSymbol, {\n configurable: false,\n enumerable: false,\n value: location,\n });\n\n return response;\n}\n\n/**\n * Creates a JSON response using the platform `Response.json()` implementation.\n */\nexport function json(value: unknown, init?: ResponseInit): Response {\n return Response.json(value, init);\n}\n\n/**\n * Creates an HTML response and defaults the content type to `text/html; charset=utf-8`.\n */\nexport function html(value: string, init: ResponseInit = {}): Response {\n if (init.headers === undefined) {\n return new Response(value, {\n ...init,\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n });\n }\n\n const headers = new Headers(init.headers);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/html; charset=utf-8\");\n }\n\n return new Response(value, {\n ...init,\n headers,\n });\n}\n\n/**\n * Returns the request headers object for route code that follows app-router helper naming.\n */\nexport function headers(request: Request): Headers {\n return request.headers;\n}\n\nexport interface RequestCookies {\n entries(): IterableIterator<[string, string]>;\n get(name: string): string | undefined;\n has(name: string): boolean;\n}\n\n/**\n * Parses request cookies into a small read-only helper.\n *\n * Values are decoded with `decodeURIComponent`; malformed encoded values are ignored rather than throwing during request handling.\n */\nexport function cookies(request: Request): RequestCookies {\n let values: ReadonlyMap<string, string> | undefined;\n const cookieValues = () => {\n values ??= parseCookieHeader(request.headers.get(\"cookie\"));\n return values;\n };\n\n return {\n entries: () => cookieValues().entries(),\n get: (name) => cookieValues().get(name),\n has: (name) => cookieValues().has(name),\n };\n}\n\nexport function rewriteLocation(response: Response): string | undefined {\n const marked = (response as { [rewriteLocationSymbol]?: unknown })[rewriteLocationSymbol];\n const candidate = typeof marked === \"string\"\n ? marked\n : response.headers.get(rewriteHeaderName) ?? undefined;\n\n return candidate !== undefined && isSafeInternalRedirect(candidate) ? candidate : undefined;\n}\n\n/**\n * Checks whether an unknown error is an app-router redirect signal.\n */\nexport function isRedirectError(error: unknown): error is Error & { location: string; status: number } {\n return error instanceof Error &&\n error.name === redirectErrorName &&\n typeof (error as { location?: unknown }).location === \"string\";\n}\n\n/**\n * Checks whether an unknown error is an app-router not-found signal.\n */\nexport function isNotFoundError(error: unknown): boolean {\n return error instanceof Error && error.name === notFoundErrorName;\n}\n"]}
package/dist/render.d.ts CHANGED
@@ -46,6 +46,7 @@ export interface RenderAppRequestOptions {
46
46
  routes?: readonly AppRoute[] | undefined;
47
47
  serverModules?: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined;
48
48
  serverModuleCacheVersion?: string | undefined;
49
+ devServerModuleCacheVersion?: string | undefined;
49
50
  dev?: boolean | undefined;
50
51
  serverSourceFiles?: ReadonlyMap<string, string> | undefined;
51
52
  serverActions?: AppRouterServerActionOptions | undefined;
@@ -145,6 +146,7 @@ declare function composedRouteMetadataCacheKey(options: {
145
146
  appDir: string;
146
147
  code: string;
147
148
  define?: UserConfig["define"] | undefined;
149
+ devServerModuleCacheVersion?: string | undefined;
148
150
  filename: string;
149
151
  importPolicy?: AppRouterImportPolicy | undefined;
150
152
  serverModuleCacheVersion?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
package/dist/render.js CHANGED
@@ -212,6 +212,8 @@ const routeOutOfOrderBoundaryAnalysisCache = new Map();
212
212
  const routeOutOfOrderBoundaryAnalysisCacheCounters = createRouterRuntimeCacheCounters();
213
213
  const routeLoaderModuleCache = new Map();
214
214
  const routeLoaderModuleCacheCounters = createRouterRuntimeCacheCounters();
215
+ const routeMetadataModuleCache = new Map();
216
+ const routeMetadataModuleCacheCounters = createRouterRuntimeCacheCounters();
215
217
  const middlewareModuleCache = new Map();
216
218
  const middlewareModuleCacheCounters = createRouterRuntimeCacheCounters();
217
219
  const serverRouteModuleCache = new Map();
@@ -223,6 +225,7 @@ const maxServerSourceFileCacheEntries = resolveRouterCacheLimit("SERVER_SOURCE_F
223
225
  const maxRouteSourceAnalysisCacheEntries = resolveRouterCacheLimit("ROUTE_SOURCE_ANALYSIS", 512);
224
226
  const maxRouteOutOfOrderBoundaryAnalysisCacheEntries = resolveRouterCacheLimit("ROUTE_OUT_OF_ORDER_BOUNDARY_ANALYSIS", 512);
225
227
  const maxRouteLoaderModuleCacheEntries = resolveRouterCacheLimit("ROUTE_LOADER_MODULE", 512);
228
+ const maxRouteMetadataModuleCacheEntries = resolveRouterCacheLimit("ROUTE_METADATA_MODULE", 512);
226
229
  const maxMiddlewareModuleCacheEntries = resolveRouterCacheLimit("MIDDLEWARE_MODULE", 64);
227
230
  const maxServerRouteModuleCacheEntries = resolveRouterCacheLimit("SERVER_ROUTE_MODULE", 512);
228
231
  const maxComposedRouteMetadataCacheEntries = resolveRouterCacheLimit("COMPOSED_ROUTE_METADATA", 512);
@@ -233,6 +236,7 @@ export function routerRenderRuntimeCacheStats() {
233
236
  routerRuntimeCacheStat("route-source-analysis", routeSourceAnalysisCache, maxRouteSourceAnalysisCacheEntries, routeSourceAnalysisCacheCounters),
234
237
  routerRuntimeCacheStat("route-out-of-order-boundary-analysis", routeOutOfOrderBoundaryAnalysisCache, maxRouteOutOfOrderBoundaryAnalysisCacheEntries, routeOutOfOrderBoundaryAnalysisCacheCounters),
235
238
  routerRuntimeCacheStat("route-loader-module", routeLoaderModuleCache, maxRouteLoaderModuleCacheEntries, routeLoaderModuleCacheCounters),
239
+ routerRuntimeCacheStat("route-metadata-module", routeMetadataModuleCache, maxRouteMetadataModuleCacheEntries, routeMetadataModuleCacheCounters),
236
240
  routerRuntimeCacheStat("middleware-module", middlewareModuleCache, maxMiddlewareModuleCacheEntries, middlewareModuleCacheCounters),
237
241
  routerRuntimeCacheStat("server-route-module", serverRouteModuleCache, maxServerRouteModuleCacheEntries, serverRouteModuleCacheCounters),
238
242
  routerRuntimeCacheStat("composed-route-metadata", composedRouteMetadataCache, maxComposedRouteMetadataCacheEntries, composedRouteMetadataCacheCounters),
@@ -304,9 +308,9 @@ function addRenderTimingPhaseDuration(timing, startedAt, phaseName) {
304
308
  timing.phases[phaseName] = (timing.phases[phaseName] ?? 0) + logDurationMs(startedAt);
305
309
  }
306
310
  function routeLoaderMayReturnControlResponse(code) {
307
- return /\b(?:redirect|redirectExternal|rewrite|notFound|throwNotFound)\s*\(/.test(code) ||
311
+ return (/\b(?:redirect|redirectExternal|rewrite|notFound|throwNotFound)\s*\(/.test(code) ||
308
312
  /\bnew\s+Response\s*\(/.test(code) ||
309
- /\bResponse\.(?:redirect|json)\s*\(/.test(code);
313
+ /\bResponse\.(?:redirect|json)\s*\(/.test(code));
310
314
  }
311
315
  async function waitForRenderPreload(options, timing) {
312
316
  if (options.preload?.wait !== "before-render") {
@@ -368,7 +372,9 @@ async function renderAppRequestInternal(options) {
368
372
  finishRenderTimingPhase(timing, phaseStartedAt, "routeScanMs");
369
373
  const url = options.requestUrl ?? new URL(options.request.url);
370
374
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
371
- const matched = options.matchedRoute ?? options.routeMatcher?.match(url.pathname) ?? matchRoute(routes, url.pathname);
375
+ const matched = options.matchedRoute ??
376
+ options.routeMatcher?.match(url.pathname) ??
377
+ matchRoute(routes, url.pathname);
372
378
  finishRenderTimingPhase(timing, phaseStartedAt, "routeMatchMs");
373
379
  const hasMiddleware = options.skipMiddleware === true
374
380
  ? false
@@ -675,7 +681,7 @@ async function renderAppRequestInternal(options) {
675
681
  params: matched.params,
676
682
  queryClient,
677
683
  request: options.request,
678
- }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, undefined, options.importPolicy));
684
+ }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, undefined, options.importPolicy, options.devServerModuleCacheVersion));
679
685
  const pageHtml = renderedPage.html;
680
686
  const pageHtmlForLayout = clientRoute
681
687
  ? withHydrationMarkers({
@@ -728,6 +734,7 @@ async function renderAppRequestInternal(options) {
728
734
  routes,
729
735
  serverModules: options.serverModules,
730
736
  serverModuleCacheVersion: options.serverModuleCacheVersion,
737
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
731
738
  serverSourceFiles: options.serverSourceFiles,
732
739
  define: options.define,
733
740
  vitePlugins: options.vitePlugins,
@@ -908,7 +915,7 @@ async function renderAppRequestInternal(options) {
908
915
  params: matched.params,
909
916
  queryClient,
910
917
  request: options.request,
911
- }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, timing, options.importPolicy));
918
+ }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, timing, options.importPolicy, options.devServerModuleCacheVersion));
912
919
  finishRenderTimingPhase(timing, phaseStartedAt, "pageRenderMs");
913
920
  const pageHtml = renderedPage.html;
914
921
  // Wrap the page (not the full document) with the hydration marker so
@@ -969,6 +976,7 @@ async function renderAppRequestInternal(options) {
969
976
  routes,
970
977
  serverModules: options.serverModules,
971
978
  serverModuleCacheVersion: options.serverModuleCacheVersion,
979
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
972
980
  serverSourceFiles: options.serverSourceFiles,
973
981
  define: options.define,
974
982
  vitePlugins: options.vitePlugins,
@@ -1897,9 +1905,9 @@ async function runServerModule(code, props, sourcefile, serverModules, serverMod
1897
1905
  async function renderServerComponentResult(value) {
1898
1906
  return typeof value === "string" ? value : renderReactNodeToString(value);
1899
1907
  }
1900
- async function runServerModuleWithSlots(code, props, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, timing, importPolicy) {
1908
+ async function runServerModuleWithSlots(code, props, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, timing, importPolicy, devServerModuleCacheVersion) {
1901
1909
  const moduleLoadStartedAt = renderTimingPhaseStartedAt(timing);
1902
- const module = await loadServerModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy);
1910
+ const module = await loadServerModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy, devServerModuleCacheVersion);
1903
1911
  finishRenderTimingPhase(timing, moduleLoadStartedAt, "pageModuleLoadMs");
1904
1912
  const component = selectServerComponent(module);
1905
1913
  const componentStartedAt = renderTimingPhaseStartedAt(timing);
@@ -1913,7 +1921,7 @@ async function runServerModuleWithSlots(code, props, sourcefile, serverModules,
1913
1921
  slots,
1914
1922
  };
1915
1923
  }
1916
- async function loadServerModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy) {
1924
+ async function loadServerModule(code, sourcefile, serverModules, serverModuleCacheVersion, define, vitePlugins, importPolicy, devServerModuleCacheVersion) {
1917
1925
  const artifact = serverModules?.get(sourcefile)?.string;
1918
1926
  const codeHash = memoizedHashText(code);
1919
1927
  const prebuiltCode = prebuiltServerComponentModuleCode(artifact, code, codeHash);
@@ -1927,10 +1935,13 @@ async function loadServerModule(code, sourcefile, serverModules, serverModuleCac
1927
1935
  serverModuleCacheVersion,
1928
1936
  });
1929
1937
  }
1930
- const moduleCode = prebuiltCode === undefined ? code : rewriteCompatVendorPlaceholderImportsForRunner(prebuiltCode);
1931
- const cacheKey = serverModuleCacheVersion === undefined
1938
+ const moduleCode = prebuiltCode === undefined
1939
+ ? code
1940
+ : rewriteCompatVendorPlaceholderImportsForRunner(prebuiltCode);
1941
+ const sourceModuleCacheVersion = serverModuleCacheVersion ?? devServerModuleCacheVersion;
1942
+ const cacheKey = sourceModuleCacheVersion === undefined
1932
1943
  ? undefined
1933
- : `server-component:${serverModuleCacheVersion}:${sourcefile}:${moduleCode === code ? codeHash : memoizedHashText(moduleCode)}:${importPolicyCacheKey(importPolicy)}:${viteDefineCacheKey(define)}:${vitePluginsCacheKey(vitePlugins)}`;
1944
+ : `server-component:${serverModuleCacheVersion === undefined ? "dev" : "build"}:${sourceModuleCacheVersion}:${sourcefile}:${moduleCode === code ? codeHash : memoizedHashText(moduleCode)}:${importPolicyCacheKey(importPolicy)}:${viteDefineCacheKey(define)}:${vitePluginsCacheKey(vitePlugins)}`;
1934
1945
  return await importAppRouterSourceModule({
1935
1946
  cacheKey,
1936
1947
  code: moduleCode,
@@ -2258,7 +2269,9 @@ async function loadServerStreamModule(code, sourcefile, serverModules, serverMod
2258
2269
  serverModuleCacheVersion,
2259
2270
  });
2260
2271
  }
2261
- const moduleCode = prebuiltCode === undefined ? code : rewriteCompatVendorPlaceholderImportsForRunner(prebuiltCode);
2272
+ const moduleCode = prebuiltCode === undefined
2273
+ ? code
2274
+ : rewriteCompatVendorPlaceholderImportsForRunner(prebuiltCode);
2262
2275
  const cacheKey = serverModuleCacheVersion === undefined
2263
2276
  ? undefined
2264
2277
  : `server-stream-component:${serverModuleCacheVersion}:${sourcefile}:${moduleCode === code ? codeHash : memoizedHashText(moduleCode)}:${importPolicyCacheKey(importPolicy)}:${viteDefineCacheKey(define)}:${vitePluginsCacheKey(vitePlugins)}`;
@@ -2524,8 +2537,7 @@ async function shellFilesForPage(appDir, pageFile, serverModuleCacheVersion) {
2524
2537
  if (devCacheKey !== undefined) {
2525
2538
  const directoryStats = await routeShellDirectoryStats(appDir, pageFile);
2526
2539
  const cached = devShellFilesCache.get(devCacheKey);
2527
- if (cached !== undefined &&
2528
- sameFileStats(cached.directoryStats, directoryStats)) {
2540
+ if (cached !== undefined && sameFileStats(cached.directoryStats, directoryStats)) {
2529
2541
  return cached.files;
2530
2542
  }
2531
2543
  const files = await shellFilesForPageUncached(appDir, pageFile);
@@ -2587,8 +2599,7 @@ async function hasAppMiddleware(options) {
2587
2599
  if (cacheKey === undefined) {
2588
2600
  const directoryStat = await fileStat(options.appDir);
2589
2601
  const cached = devAppMiddlewareFileCache.get(options.appDir);
2590
- if (cached !== undefined &&
2591
- sameFileStat(cached.directoryStat, directoryStat)) {
2602
+ if (cached !== undefined && sameFileStat(cached.directoryStat, directoryStat)) {
2592
2603
  return cached.hasMiddleware;
2593
2604
  }
2594
2605
  const hasMiddleware = await hasAppMiddlewareUncached(middlewareFiles);
@@ -2855,19 +2866,54 @@ async function loadRouteMetadata(options) {
2855
2866
  });
2856
2867
  return await resolveRouteMetadataModule(module, options.context);
2857
2868
  }
2858
- const code = prebuiltArtifact?.code ?? (await bundleRouteMetadataModuleCode(options));
2859
- const module = await importAppRouterSourceModule({
2860
- ...(options.serverModuleCacheVersion === undefined
2861
- ? {}
2862
- : {
2863
- cacheKey: `metadata:${options.filename}:${options.serverModuleCacheVersion}:${memoizedHashText(code)}:${viteDefineCacheKey(options.define)}`,
2864
- }),
2865
- code,
2866
- define: options.define,
2867
- label: `metadata:${options.filename}`,
2868
- });
2869
+ const module = await loadRouteMetadataModule(options, prebuiltArtifact);
2869
2870
  return await resolveRouteMetadataModule(module, options.context);
2870
2871
  }
2872
+ async function loadRouteMetadataModule(options, prebuiltArtifact) {
2873
+ if (prebuiltArtifact?.moduleFile !== undefined) {
2874
+ return await importBuiltServerModuleFile({
2875
+ file: prebuiltArtifact.moduleFile,
2876
+ label: `metadata:${options.filename}`,
2877
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
2878
+ });
2879
+ }
2880
+ const sourceHash = memoizedHashText(options.code);
2881
+ const moduleCacheVersion = options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion;
2882
+ const moduleCacheKey = moduleCacheVersion === undefined
2883
+ ? undefined
2884
+ : `metadata-module:${options.serverModuleCacheVersion === undefined ? "dev" : "build"}:${options.filename}:${moduleCacheVersion}:${sourceHash}:${viteDefineCacheKey(options.define)}:${vitePluginsCacheKey(options.vitePlugins)}`;
2885
+ if (moduleCacheKey !== undefined) {
2886
+ const cached = readRouterRuntimeCacheEntry(routeMetadataModuleCache, moduleCacheKey, routeMetadataModuleCacheCounters);
2887
+ if (cached !== undefined) {
2888
+ return await cached;
2889
+ }
2890
+ }
2891
+ const loaded = (async () => {
2892
+ const code = prebuiltArtifact?.code ?? (await bundleRouteMetadataModuleCode(options));
2893
+ return await importAppRouterSourceModule({
2894
+ ...(moduleCacheVersion === undefined
2895
+ ? {}
2896
+ : {
2897
+ cacheKey: `metadata:${options.serverModuleCacheVersion === undefined ? "dev" : "build"}:${options.filename}:${moduleCacheVersion}:${memoizedHashText(code)}:${viteDefineCacheKey(options.define)}`,
2898
+ }),
2899
+ code,
2900
+ define: options.define,
2901
+ label: `metadata:${options.filename}`,
2902
+ });
2903
+ })();
2904
+ if (moduleCacheKey !== undefined) {
2905
+ setBoundedCacheEntry(routeMetadataModuleCache, moduleCacheKey, loaded, maxRouteMetadataModuleCacheEntries, routeMetadataModuleCacheCounters);
2906
+ }
2907
+ try {
2908
+ return await loaded;
2909
+ }
2910
+ catch (error) {
2911
+ if (moduleCacheKey !== undefined) {
2912
+ routeMetadataModuleCache.delete(moduleCacheKey);
2913
+ }
2914
+ throw error;
2915
+ }
2916
+ }
2871
2917
  async function resolveRouteMetadataModule(module, context) {
2872
2918
  const staticMetadata = validateRouteMetadata(module.metadata);
2873
2919
  if (module.generateMetadata === undefined) {
@@ -2937,9 +2983,10 @@ async function loadComposedRouteMetadata(options) {
2937
2983
  }
2938
2984
  }
2939
2985
  function composedRouteMetadataCacheKey(options) {
2940
- return options.serverModuleCacheVersion === undefined
2986
+ const moduleCacheVersion = options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion;
2987
+ return moduleCacheVersion === undefined
2941
2988
  ? undefined
2942
- : `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
2989
+ : `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion === undefined ? "dev" : "build"}\0${moduleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
2943
2990
  }
2944
2991
  export const __composedRouteMetadataCacheKeyForTesting = composedRouteMetadataCacheKey;
2945
2992
  async function loadComposedRouteMetadataUncached(options) {
@@ -2959,6 +3006,7 @@ async function loadComposedRouteMetadataUncached(options) {
2959
3006
  importPolicy: options.importPolicy,
2960
3007
  serverModules: options.serverModules,
2961
3008
  serverModuleCacheVersion: options.serverModuleCacheVersion,
3009
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
2962
3010
  define: options.define,
2963
3011
  vitePlugins: options.vitePlugins,
2964
3012
  });
@@ -2972,6 +3020,7 @@ async function loadComposedRouteMetadataUncached(options) {
2972
3020
  importPolicy: options.importPolicy,
2973
3021
  serverModules: options.serverModules,
2974
3022
  serverModuleCacheVersion: options.serverModuleCacheVersion,
3023
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
2975
3024
  define: options.define,
2976
3025
  vitePlugins: options.vitePlugins,
2977
3026
  });
@@ -3134,18 +3183,14 @@ function injectQueryState(html, state) {
3134
3183
  return html;
3135
3184
  }
3136
3185
  const script = `<script type="application/json" id="${__MREACT_QUERY_STATE_SCRIPT_ID}">${escapeJsonForHtml(JSON.stringify(state))}</script>`;
3137
- return /<\/body>/i.test(html)
3138
- ? replaceFinalBodyCloseTag(html, script)
3139
- : `${html}${script}`;
3186
+ return /<\/body>/i.test(html) ? replaceFinalBodyCloseTag(html, script) : `${html}${script}`;
3140
3187
  }
3141
3188
  function injectAuthSessionClaims(html, claims) {
3142
3189
  if (claims === undefined) {
3143
3190
  return html;
3144
3191
  }
3145
3192
  const script = `<script type="application/json" id="${authSessionScriptId}">${escapeJsonForHtml(JSON.stringify(claims))}</script>`;
3146
- return /<\/body>/i.test(html)
3147
- ? replaceFinalBodyCloseTag(html, script)
3148
- : `${html}${script}`;
3193
+ return /<\/body>/i.test(html) ? replaceFinalBodyCloseTag(html, script) : `${html}${script}`;
3149
3194
  }
3150
3195
  function replaceFinalBodyCloseTag(html, insertion) {
3151
3196
  const matches = [...html.matchAll(/<\/body>/gi)];
@@ -3198,9 +3243,7 @@ function readServerSourceFile(file, serverModuleCacheVersion, serverSourceFiles)
3198
3243
  async function readDevServerSourceFile(file) {
3199
3244
  const stats = await fileStat(file);
3200
3245
  const cached = devServerSourceFileCache.get(file);
3201
- if (cached !== undefined &&
3202
- cached.mtimeMs === stats.mtimeMs &&
3203
- cached.size === stats.size) {
3246
+ if (cached !== undefined && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) {
3204
3247
  return cached.source;
3205
3248
  }
3206
3249
  const source = await readFile(file, "utf8");