@reckona/mreact-router 0.0.160 → 0.0.162

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 (183) hide show
  1. package/dist/actions.d.ts +6 -0
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js.map +1 -1
  4. package/dist/adapters/aws-lambda.d.ts +29 -0
  5. package/dist/adapters/aws-lambda.d.ts.map +1 -1
  6. package/dist/adapters/aws-lambda.js.map +1 -1
  7. package/dist/adapters/cloudflare.d.ts +78 -0
  8. package/dist/adapters/cloudflare.d.ts.map +1 -1
  9. package/dist/adapters/cloudflare.js.map +1 -1
  10. package/dist/adapters/edge.d.ts +6 -0
  11. package/dist/adapters/edge.d.ts.map +1 -1
  12. package/dist/adapters/edge.js.map +1 -1
  13. package/dist/adapters/node.d.ts +7 -0
  14. package/dist/adapters/node.d.ts.map +1 -1
  15. package/dist/adapters/node.js.map +1 -1
  16. package/dist/adapters/static.d.ts +6 -0
  17. package/dist/adapters/static.d.ts.map +1 -1
  18. package/dist/adapters/static.js.map +1 -1
  19. package/dist/app-router-globals.d.ts +6 -0
  20. package/dist/app-router-globals.d.ts.map +1 -1
  21. package/dist/app-router-globals.js.map +1 -1
  22. package/dist/assets.d.ts +18 -0
  23. package/dist/assets.d.ts.map +1 -1
  24. package/dist/assets.js +6 -0
  25. package/dist/assets.js.map +1 -1
  26. package/dist/build.d.ts +30 -0
  27. package/dist/build.d.ts.map +1 -1
  28. package/dist/build.js +4 -0
  29. package/dist/build.js.map +1 -1
  30. package/dist/cache-stats.d.ts +3 -0
  31. package/dist/cache-stats.d.ts.map +1 -1
  32. package/dist/cache-stats.js.map +1 -1
  33. package/dist/cache.d.ts +15 -0
  34. package/dist/cache.d.ts.map +1 -1
  35. package/dist/cache.js.map +1 -1
  36. package/dist/cli-options.d.ts.map +1 -1
  37. package/dist/cli-options.js +2 -0
  38. package/dist/cli-options.js.map +1 -1
  39. package/dist/cli.js +1 -0
  40. package/dist/cli.js.map +1 -1
  41. package/dist/config.d.ts +15 -0
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js.map +1 -1
  44. package/dist/cookies.d.ts +3 -0
  45. package/dist/cookies.d.ts.map +1 -1
  46. package/dist/cookies.js.map +1 -1
  47. package/dist/csrf.d.ts +12 -0
  48. package/dist/csrf.d.ts.map +1 -1
  49. package/dist/csrf.js +12 -0
  50. package/dist/csrf.js.map +1 -1
  51. package/dist/deferred.d.ts +9 -0
  52. package/dist/deferred.d.ts.map +1 -1
  53. package/dist/deferred.js +6 -0
  54. package/dist/deferred.js.map +1 -1
  55. package/dist/dev-server.d.ts +3 -0
  56. package/dist/dev-server.d.ts.map +1 -1
  57. package/dist/dev-server.js.map +1 -1
  58. package/dist/file-conventions.d.ts +3 -0
  59. package/dist/file-conventions.d.ts.map +1 -1
  60. package/dist/file-conventions.js.map +1 -1
  61. package/dist/i18n.d.ts +15 -0
  62. package/dist/i18n.d.ts.map +1 -1
  63. package/dist/i18n.js +6 -0
  64. package/dist/i18n.js.map +1 -1
  65. package/dist/import-policy.d.ts +3 -0
  66. package/dist/import-policy.d.ts.map +1 -1
  67. package/dist/import-policy.js.map +1 -1
  68. package/dist/index.d.ts +19 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +10 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/link.d.ts +34 -0
  73. package/dist/link.d.ts.map +1 -1
  74. package/dist/link.js.map +1 -1
  75. package/dist/logger.d.ts +33 -0
  76. package/dist/logger.d.ts.map +1 -1
  77. package/dist/logger.js.map +1 -1
  78. package/dist/multipart.d.ts +15 -0
  79. package/dist/multipart.d.ts.map +1 -1
  80. package/dist/multipart.js +3 -0
  81. package/dist/multipart.js.map +1 -1
  82. package/dist/native-escape.d.ts +3 -0
  83. package/dist/native-escape.d.ts.map +1 -1
  84. package/dist/native-escape.js +3 -0
  85. package/dist/native-escape.js.map +1 -1
  86. package/dist/navigation-state.d.ts +15 -0
  87. package/dist/navigation-state.d.ts.map +1 -1
  88. package/dist/navigation-state.js +6 -0
  89. package/dist/navigation-state.js.map +1 -1
  90. package/dist/navigation.d.ts +9 -0
  91. package/dist/navigation.d.ts.map +1 -1
  92. package/dist/navigation.js +6 -0
  93. package/dist/navigation.js.map +1 -1
  94. package/dist/prerender-store.d.ts +21 -0
  95. package/dist/prerender-store.d.ts.map +1 -1
  96. package/dist/prerender-store.js +9 -0
  97. package/dist/prerender-store.js.map +1 -1
  98. package/dist/render.d.ts +12 -0
  99. package/dist/render.d.ts.map +1 -1
  100. package/dist/render.js +3 -0
  101. package/dist/render.js.map +1 -1
  102. package/dist/routes.d.ts +30 -0
  103. package/dist/routes.d.ts.map +1 -1
  104. package/dist/routes.js +6 -0
  105. package/dist/routes.js.map +1 -1
  106. package/dist/runtime-cache.d.ts +4 -0
  107. package/dist/runtime-cache.d.ts.map +1 -1
  108. package/dist/runtime-cache.js +3 -0
  109. package/dist/runtime-cache.js.map +1 -1
  110. package/dist/runtime-state.d.ts +3 -0
  111. package/dist/runtime-state.d.ts.map +1 -1
  112. package/dist/runtime-state.js +3 -0
  113. package/dist/runtime-state.js.map +1 -1
  114. package/dist/serve.d.ts +24 -0
  115. package/dist/serve.d.ts.map +1 -1
  116. package/dist/serve.js +6 -0
  117. package/dist/serve.js.map +1 -1
  118. package/dist/session.d.ts +12 -0
  119. package/dist/session.d.ts.map +1 -1
  120. package/dist/session.js.map +1 -1
  121. package/dist/stream-list.d.ts +12 -0
  122. package/dist/stream-list.d.ts.map +1 -1
  123. package/dist/stream-list.js +3 -0
  124. package/dist/stream-list.js.map +1 -1
  125. package/dist/trace.d.ts +30 -0
  126. package/dist/trace.d.ts.map +1 -1
  127. package/dist/trace.js +6 -0
  128. package/dist/trace.js.map +1 -1
  129. package/dist/typed-routes.d.ts +33 -0
  130. package/dist/typed-routes.d.ts.map +1 -1
  131. package/dist/typed-routes.js.map +1 -1
  132. package/dist/types.d.ts +72 -0
  133. package/dist/types.d.ts.map +1 -1
  134. package/dist/types.js.map +1 -1
  135. package/dist/upgrade.d.ts +3 -0
  136. package/dist/upgrade.d.ts.map +1 -1
  137. package/dist/upgrade.js.map +1 -1
  138. package/dist/vite.d.ts +21 -0
  139. package/dist/vite.d.ts.map +1 -1
  140. package/dist/vite.js +15 -0
  141. package/dist/vite.js.map +1 -1
  142. package/package.json +11 -11
  143. package/src/actions.ts +6 -0
  144. package/src/adapters/aws-lambda.ts +29 -0
  145. package/src/adapters/cloudflare.ts +78 -0
  146. package/src/adapters/edge.ts +6 -0
  147. package/src/adapters/node.ts +7 -0
  148. package/src/adapters/static.ts +6 -0
  149. package/src/app-router-globals.ts +6 -0
  150. package/src/assets.ts +18 -0
  151. package/src/build.ts +38 -0
  152. package/src/cache-stats.ts +3 -0
  153. package/src/cache.ts +15 -0
  154. package/src/cli-options.ts +2 -0
  155. package/src/cli.ts +1 -0
  156. package/src/config.ts +15 -0
  157. package/src/cookies.ts +3 -0
  158. package/src/csrf.ts +12 -0
  159. package/src/deferred.ts +9 -0
  160. package/src/dev-server.ts +3 -0
  161. package/src/file-conventions.ts +3 -0
  162. package/src/i18n.ts +15 -0
  163. package/src/import-policy.ts +3 -0
  164. package/src/index.ts +19 -0
  165. package/src/link.ts +34 -0
  166. package/src/logger.ts +33 -0
  167. package/src/multipart.ts +15 -0
  168. package/src/native-escape.ts +3 -0
  169. package/src/navigation-state.ts +15 -0
  170. package/src/navigation.ts +9 -0
  171. package/src/prerender-store.ts +21 -0
  172. package/src/render.ts +12 -0
  173. package/src/routes.ts +30 -0
  174. package/src/runtime-cache.ts +5 -0
  175. package/src/runtime-state.ts +3 -0
  176. package/src/serve.ts +24 -0
  177. package/src/session.ts +12 -0
  178. package/src/stream-list.ts +12 -0
  179. package/src/trace.ts +30 -0
  180. package/src/typed-routes.ts +33 -0
  181. package/src/types.ts +72 -0
  182. package/src/upgrade.ts +3 -0
  183. package/src/vite.ts +21 -0
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../src/cookies.ts"],"names":[],"mappings":"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","sourcesContent":["export interface CookieOptions {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n secure?: boolean;\n}\n\nconst COOKIE_NAME = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n\nfunction assertCookieName(name: string): void {\n if (!COOKIE_NAME.test(name)) {\n throw new TypeError(`invalid cookie name: ${JSON.stringify(name)}`);\n }\n}\n\nfunction assertAttributeValue(value: string): void {\n if (/[\\r\\n;]/.test(value)) {\n throw new TypeError(`invalid cookie attribute value: ${JSON.stringify(value)}`);\n }\n}\n\n/**\n * Parses a raw `Cookie` header into decoded name/value pairs.\n *\n * Malformed percent-encoded values are skipped so one bad cookie does not abort request handling.\n */\nexport function parseCookieHeader(\n cookieHeader: string | null | undefined,\n): Map<string, string> {\n const values = new Map<string, string>();\n\n for (const part of (cookieHeader ?? \"\").split(\";\")) {\n const [rawName, ...rawValue] = part.trim().split(\"=\");\n\n if (rawName === undefined || rawName === \"\") {\n continue;\n }\n\n const raw = rawValue.join(\"=\");\n if (raw.indexOf(\"%\") === -1) {\n values.set(rawName, raw);\n continue;\n }\n\n try {\n values.set(rawName, decodeURIComponent(raw));\n } catch {\n // Treat malformed cookie values as absent for this request.\n }\n }\n\n return values;\n}\n\n/**\n * Serializes a cookie name, value, and attributes for a `Set-Cookie` header.\n *\n * Cookie names and attribute values are validated, and `SameSite=None` requires `Secure`.\n */\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n assertCookieName(name);\n\n if (options.sameSite === \"None\" && options.secure !== true) {\n throw new TypeError(\"SameSite=None requires Secure\");\n }\n\n const parts = [`${name}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) {\n if (!Number.isSafeInteger(options.maxAge)) {\n throw new TypeError(\"invalid cookie Max-Age\");\n }\n parts.push(`Max-Age=${options.maxAge}`);\n }\n\n if (options.domain !== undefined) {\n assertAttributeValue(options.domain);\n parts.push(`Domain=${options.domain}`);\n }\n\n if (options.path !== undefined) {\n assertAttributeValue(options.path);\n parts.push(`Path=${options.path}`);\n }\n\n if (options.expires !== undefined) {\n parts.push(`Expires=${options.expires.toUTCString()}`);\n }\n\n if (options.httpOnly === true) parts.push(\"HttpOnly\");\n if (options.secure === true) parts.push(\"Secure\");\n if (options.sameSite !== undefined) parts.push(`SameSite=${options.sameSite}`);\n\n return parts.join(\"; \");\n}\n\n/**\n * Appends a serialized cookie to a response's `Set-Cookie` headers and returns the same response.\n */\nexport function setCookie(\n response: Response,\n name: string,\n value: string,\n options: CookieOptions = {},\n): Response {\n response.headers.append(\"set-cookie\", serializeCookie(name, value, options));\n return response;\n}\n\n/**\n * Appends an expiring `Set-Cookie` header that removes a cookie in the browser.\n */\nexport function deleteCookie(\n response: Response,\n name: string,\n options: Pick<CookieOptions, \"domain\" | \"path\" | \"sameSite\" | \"secure\"> = {},\n): Response {\n return setCookie(response, name, \"\", {\n ...options,\n maxAge: 0,\n });\n}\n"]}
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../src/cookies.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Configures attributes used when serializing a Set-Cookie header.\n */\nexport interface CookieOptions {\n domain?: string;\n expires?: Date;\n httpOnly?: boolean;\n maxAge?: number;\n path?: string;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n secure?: boolean;\n}\n\nconst COOKIE_NAME = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n\nfunction assertCookieName(name: string): void {\n if (!COOKIE_NAME.test(name)) {\n throw new TypeError(`invalid cookie name: ${JSON.stringify(name)}`);\n }\n}\n\nfunction assertAttributeValue(value: string): void {\n if (/[\\r\\n;]/.test(value)) {\n throw new TypeError(`invalid cookie attribute value: ${JSON.stringify(value)}`);\n }\n}\n\n/**\n * Parses a raw `Cookie` header into decoded name/value pairs.\n *\n * Malformed percent-encoded values are skipped so one bad cookie does not abort request handling.\n */\nexport function parseCookieHeader(\n cookieHeader: string | null | undefined,\n): Map<string, string> {\n const values = new Map<string, string>();\n\n for (const part of (cookieHeader ?? \"\").split(\";\")) {\n const [rawName, ...rawValue] = part.trim().split(\"=\");\n\n if (rawName === undefined || rawName === \"\") {\n continue;\n }\n\n const raw = rawValue.join(\"=\");\n if (raw.indexOf(\"%\") === -1) {\n values.set(rawName, raw);\n continue;\n }\n\n try {\n values.set(rawName, decodeURIComponent(raw));\n } catch {\n // Treat malformed cookie values as absent for this request.\n }\n }\n\n return values;\n}\n\n/**\n * Serializes a cookie name, value, and attributes for a `Set-Cookie` header.\n *\n * Cookie names and attribute values are validated, and `SameSite=None` requires `Secure`.\n */\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n assertCookieName(name);\n\n if (options.sameSite === \"None\" && options.secure !== true) {\n throw new TypeError(\"SameSite=None requires Secure\");\n }\n\n const parts = [`${name}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) {\n if (!Number.isSafeInteger(options.maxAge)) {\n throw new TypeError(\"invalid cookie Max-Age\");\n }\n parts.push(`Max-Age=${options.maxAge}`);\n }\n\n if (options.domain !== undefined) {\n assertAttributeValue(options.domain);\n parts.push(`Domain=${options.domain}`);\n }\n\n if (options.path !== undefined) {\n assertAttributeValue(options.path);\n parts.push(`Path=${options.path}`);\n }\n\n if (options.expires !== undefined) {\n parts.push(`Expires=${options.expires.toUTCString()}`);\n }\n\n if (options.httpOnly === true) parts.push(\"HttpOnly\");\n if (options.secure === true) parts.push(\"Secure\");\n if (options.sameSite !== undefined) parts.push(`SameSite=${options.sameSite}`);\n\n return parts.join(\"; \");\n}\n\n/**\n * Appends a serialized cookie to a response's `Set-Cookie` headers and returns the same response.\n */\nexport function setCookie(\n response: Response,\n name: string,\n value: string,\n options: CookieOptions = {},\n): Response {\n response.headers.append(\"set-cookie\", serializeCookie(name, value, options));\n return response;\n}\n\n/**\n * Appends an expiring `Set-Cookie` header that removes a cookie in the browser.\n */\nexport function deleteCookie(\n response: Response,\n name: string,\n options: Pick<CookieOptions, \"domain\" | \"path\" | \"sameSite\" | \"secure\"> = {},\n): Response {\n return setCookie(response, name, \"\", {\n ...options,\n maxAge: 0,\n });\n}\n"]}
package/dist/csrf.d.ts CHANGED
@@ -1,7 +1,19 @@
1
+ /**
2
+ * Names the hidden form field used for app-router CSRF validation.
3
+ */
1
4
  export declare const formCsrfFieldName = "__mreact_csrf";
2
5
  export declare function serverActionCookie(csrfToken: string): string;
6
+ /**
7
+ * Creates or reuses the CSRF token embedded into server-rendered forms.
8
+ */
3
9
  export declare function createFormCsrfToken(request?: Request | undefined): string;
10
+ /**
11
+ * Serializes the CSRF cookie used to validate app-router form submissions.
12
+ */
4
13
  export declare function formCsrfCookie(csrfToken: string): string;
14
+ /**
15
+ * Validates the CSRF cookie and hidden form field for a form submission.
16
+ */
5
17
  export declare function validateFormCsrf(request: Request, formData: FormData): Response | undefined;
6
18
  export declare function readExistingFormCsrfToken(request: Request | undefined): string | undefined;
7
19
  //# sourceMappingURL=csrf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../src/csrf.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,kBAAgB,CAAC;AAE/C,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAEzE;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAc3F;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAY1F"}
1
+ {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../src/csrf.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,iBAAiB,kBAAgB,CAAC;AAE/C,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAEzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAc3F;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAY1F"}
package/dist/csrf.js CHANGED
@@ -1,6 +1,9 @@
1
1
  const csrfCookieNameProduction = "__Host-mreact.csrf";
2
2
  const csrfCookieNameDevelopment = "mreact.csrf";
3
3
  const formFieldCsrf = "__mreact_csrf";
4
+ /**
5
+ * Names the hidden form field used for app-router CSRF validation.
6
+ */
4
7
  export const formCsrfFieldName = formFieldCsrf;
5
8
  export function serverActionCookie(csrfToken) {
6
9
  const production = isProductionEnvironment();
@@ -15,12 +18,21 @@ export function serverActionCookie(csrfToken) {
15
18
  }
16
19
  return parts.join("; ");
17
20
  }
21
+ /**
22
+ * Creates or reuses the CSRF token embedded into server-rendered forms.
23
+ */
18
24
  export function createFormCsrfToken(request) {
19
25
  return readExistingFormCsrfToken(request) ?? randomToken();
20
26
  }
27
+ /**
28
+ * Serializes the CSRF cookie used to validate app-router form submissions.
29
+ */
21
30
  export function formCsrfCookie(csrfToken) {
22
31
  return serverActionCookie(csrfToken);
23
32
  }
33
+ /**
34
+ * Validates the CSRF cookie and hidden form field for a form submission.
35
+ */
24
36
  export function validateFormCsrf(request, formData) {
25
37
  const formToken = stringFormValue(formData.get(formFieldCsrf));
26
38
  const cookieHeader = request.headers.get("cookie");
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\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 createFormCsrfToken(request?: Request | undefined): string {\n return readExistingFormCsrfToken(request) ?? randomToken();\n}\n\nexport function formCsrfCookie(csrfToken: string): string {\n return serverActionCookie(csrfToken);\n}\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 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\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,8 +1,17 @@
1
1
  declare const deferredLoaderDataSymbol: unique symbol;
2
+ /**
3
+ * Marks loader data that contains streamed deferred values.
4
+ */
2
5
  export type DeferredLoaderData<TData extends Record<string, unknown>> = TData & {
3
6
  readonly [deferredLoaderDataSymbol]: true;
4
7
  };
8
+ /**
9
+ * Marks loader data for deferred streaming without changing its data shape.
10
+ */
5
11
  export declare function defer<TData extends Record<string, unknown>>(data: TData): DeferredLoaderData<TData>;
12
+ /**
13
+ * Checks whether loader data was marked with `defer()`.
14
+ */
6
15
  export declare function isDeferredLoaderData(value: unknown): value is DeferredLoaderData<Record<string, unknown>>;
7
16
  export declare function unwrapDeferredLoaderData<TData extends Record<string, unknown>>(data: DeferredLoaderData<TData>): TData;
8
17
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"deferred.d.ts","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,wBAAwB,eAAmD,CAAC;AAElF,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,GAAG;IAC9E,QAAQ,CAAC,CAAC,wBAAwB,CAAC,EAAE,IAAI,CAAC;CAC3C,CAAC;AAEF,wBAAgB,KAAK,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,IAAI,EAAE,KAAK,GACV,kBAAkB,CAAC,KAAK,CAAC,CAO3B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMtD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAC9B,KAAK,CAEP"}
1
+ {"version":3,"file":"deferred.d.ts","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,wBAAwB,eAAmD,CAAC;AAElF;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,GAAG;IAC9E,QAAQ,CAAC,CAAC,wBAAwB,CAAC,EAAE,IAAI,CAAC;CAC3C,CAAC;AAEF;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,IAAI,EAAE,KAAK,GACV,kBAAkB,CAAC,KAAK,CAAC,CAO3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMtD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAC9B,KAAK,CAEP"}
package/dist/deferred.js CHANGED
@@ -1,4 +1,7 @@
1
1
  const deferredLoaderDataSymbol = Symbol.for("mreact.router.deferred-loader-data");
2
+ /**
3
+ * Marks loader data for deferred streaming without changing its data shape.
4
+ */
2
5
  export function defer(data) {
3
6
  markTopLevelPromisesHandled(data);
4
7
  return Object.defineProperty(data, deferredLoaderDataSymbol, {
@@ -6,6 +9,9 @@ export function defer(data) {
6
9
  value: true,
7
10
  });
8
11
  }
12
+ /**
13
+ * Checks whether loader data was marked with `defer()`.
14
+ */
9
15
  export function isDeferredLoaderData(value) {
10
16
  return (typeof value === "object" &&
11
17
  value !== null &&
@@ -1 +1 @@
1
- {"version":3,"file":"deferred.js","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AAMlF,MAAM,UAAU,KAAK,CACnB,IAAW;IAEX,2BAA2B,CAAC,IAAI,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,wBAAwB,EAAE;QAC3D,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,IAAI;KACZ,CAA8B,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAkD,CAAC,wBAAwB,CAAC,KAAK,IAAI,CACvF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAA+B;IAE/B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,2BAA2B,CAAC,IAA6B;IAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,wEAAwE;YACxE,oEAAoE;YACpE,yEAAyE;YACzE,2BAA2B;YAC3B,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC;QAC1D,KAAK,KAAK,IAAI;QACd,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU,CACzD,CAAC;AACJ,CAAC","sourcesContent":["const deferredLoaderDataSymbol = Symbol.for(\"mreact.router.deferred-loader-data\");\n\nexport type DeferredLoaderData<TData extends Record<string, unknown>> = TData & {\n readonly [deferredLoaderDataSymbol]: true;\n};\n\nexport function defer<TData extends Record<string, unknown>>(\n data: TData,\n): DeferredLoaderData<TData> {\n markTopLevelPromisesHandled(data);\n\n return Object.defineProperty(data, deferredLoaderDataSymbol, {\n enumerable: false,\n value: true,\n }) as DeferredLoaderData<TData>;\n}\n\nexport function isDeferredLoaderData(\n value: unknown,\n): value is DeferredLoaderData<Record<string, unknown>> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { [deferredLoaderDataSymbol]?: unknown })[deferredLoaderDataSymbol] === true\n );\n}\n\nexport function unwrapDeferredLoaderData<TData extends Record<string, unknown>>(\n data: DeferredLoaderData<TData>,\n): TData {\n return data;\n}\n\nfunction markTopLevelPromisesHandled(data: Record<string, unknown>): void {\n for (const value of Object.values(data)) {\n if (isPromiseLike(value)) {\n // Avoid process-level unhandled rejection noise before <Await> attaches\n // its boundary handlers. Callers should still render every deferred\n // promise through <Await catch>; unused rejected fields will not surface\n // as unhandled rejections.\n void Promise.resolve(value).catch(() => {});\n }\n }\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n"]}
1
+ {"version":3,"file":"deferred.js","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AASlF;;GAEG;AACH,MAAM,UAAU,KAAK,CACnB,IAAW;IAEX,2BAA2B,CAAC,IAAI,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,wBAAwB,EAAE;QAC3D,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,IAAI;KACZ,CAA8B,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAkD,CAAC,wBAAwB,CAAC,KAAK,IAAI,CACvF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAA+B;IAE/B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,2BAA2B,CAAC,IAA6B;IAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,wEAAwE;YACxE,oEAAoE;YACpE,yEAAyE;YACzE,2BAA2B;YAC3B,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC;QAC1D,KAAK,KAAK,IAAI;QACd,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU,CACzD,CAAC;AACJ,CAAC","sourcesContent":["const deferredLoaderDataSymbol = Symbol.for(\"mreact.router.deferred-loader-data\");\n\n/**\n * Marks loader data that contains streamed deferred values.\n */\nexport type DeferredLoaderData<TData extends Record<string, unknown>> = TData & {\n readonly [deferredLoaderDataSymbol]: true;\n};\n\n/**\n * Marks loader data for deferred streaming without changing its data shape.\n */\nexport function defer<TData extends Record<string, unknown>>(\n data: TData,\n): DeferredLoaderData<TData> {\n markTopLevelPromisesHandled(data);\n\n return Object.defineProperty(data, deferredLoaderDataSymbol, {\n enumerable: false,\n value: true,\n }) as DeferredLoaderData<TData>;\n}\n\n/**\n * Checks whether loader data was marked with `defer()`.\n */\nexport function isDeferredLoaderData(\n value: unknown,\n): value is DeferredLoaderData<Record<string, unknown>> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { [deferredLoaderDataSymbol]?: unknown })[deferredLoaderDataSymbol] === true\n );\n}\n\nexport function unwrapDeferredLoaderData<TData extends Record<string, unknown>>(\n data: DeferredLoaderData<TData>,\n): TData {\n return data;\n}\n\nfunction markTopLevelPromisesHandled(data: Record<string, unknown>): void {\n for (const value of Object.values(data)) {\n if (isPromiseLike(value)) {\n // Avoid process-level unhandled rejection noise before <Await> attaches\n // its boundary handlers. Callers should still render every deferred\n // promise through <Await catch>; unused rejected fields will not surface\n // as unhandled rejections.\n void Promise.resolve(value).catch(() => {});\n }\n }\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n"]}
@@ -6,6 +6,9 @@ import { type AppRouterProjectOptions } from "./config.js";
6
6
  import type { AppRouterImportPolicy } from "./import-policy.js";
7
7
  import { type AppRouterLogger } from "./logger.js";
8
8
  import type { HttpUpgradeHandler } from "./upgrade.js";
9
+ /**
10
+ * Configures the Vite-powered app-router development server.
11
+ */
9
12
  export interface StartDevServerOptions extends AppRouterProjectOptions {
10
13
  port?: number | undefined;
11
14
  hostname?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAItD,OAAO,EAAoC,KAAK,UAAU,EAAsB,MAAM,MAAM,CAAC;AAC7F,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAkC,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAMhE,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACrC,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACzD,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAuHlE"}
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAItD,OAAO,EAAoC,KAAK,UAAU,EAAsB,MAAM,MAAM,CAAC;AAC7F,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAkC,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAMhE,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACrC,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACzD,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAuHlE"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server } from \"node:http\";\nimport type { ServerResponse } from \"node:http\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { createServer as createViteServer, type UserConfig, type ViteDevServer } from \"vite\";\nimport type { AppRouterServerActionOptions } from \"./actions.js\";\nimport { createMemoryRouteCache, type AppRouterCache } from \"./cache.js\";\nimport { resolveAppRouterProjectOptions, type AppRouterProjectOptions } from \"./config.js\";\nimport type { AppRouterImportPolicy } from \"./import-policy.js\";\nimport { createAppRouterVitePlugin } from \"./vite.js\";\nimport {\n loadMreactRouterViteConfigDetails,\n type LoadedMreactRouterViteConfig,\n} from \"./vite-config.js\";\nimport {\n emitRouterLog,\n logDurationMs,\n logNow,\n nodeRequestPath,\n type AppRouterLogger,\n} from \"./logger.js\";\nimport type { HttpUpgradeHandler } from \"./upgrade.js\";\n\nexport interface StartDevServerOptions extends AppRouterProjectOptions {\n port?: number | undefined;\n hostname?: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n logger?: AppRouterLogger | undefined;\n routeCache?: AppRouterCache | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n verboseErrors?: boolean | undefined;\n viteConfig?: UserConfig | undefined;\n onUpgrade?: HttpUpgradeHandler | undefined;\n}\n\n/**\n * Starts the local app-router development server with Vite middleware and route compilation.\n *\n * The server trusts only the configured host settings, merges declared application packages into the development import policy, and returns a `close()` method that should be awaited by tests and scripts.\n */\nexport async function startDevServer(\n options: StartDevServerOptions,\n): Promise<{ close(): Promise<void>; server: Server; url: string }> {\n const hostname = options.hostname ?? \"127.0.0.1\";\n const resolved = await resolveStartDevServerProject(options);\n const project = resolved.project;\n const userViteConfig = options.viteConfig ?? resolved.viteConfig ?? {};\n const userViteServerConfig =\n typeof userViteConfig.server === \"object\" ? userViteConfig.server : {};\n const userHmrConfig =\n typeof userViteServerConfig.hmr === \"object\" ? userViteServerConfig.hmr : {};\n const port = options.port ?? resolved.serverPort ?? 3001;\n const routeCache = options.routeCache ?? createMemoryRouteCache();\n const declaredPackages = await readDeclaredProjectPackages(project.projectRoot);\n const configImportPolicy = resolved.importPolicy;\n const importPolicy: AppRouterImportPolicy = {\n ...configImportPolicy,\n ...options.importPolicy,\n allowedPackages: [\n ...new Set([\n ...declaredPackages,\n ...(configImportPolicy?.allowedPackages ?? []),\n ...(options.importPolicy?.allowedPackages ?? []),\n ]),\n ],\n };\n let vite: ViteDevServer | undefined;\n const server = createServer((incoming, outgoing) => {\n const logger = options.logger;\n const startedAt = logger === undefined ? undefined : logNow();\n const logFields =\n logger === undefined\n ? undefined\n : {\n method: incoming.method ?? \"GET\",\n path: nodeRequestPath(incoming.url),\n runtime: \"node\" as const,\n };\n\n if (logger !== undefined && logFields !== undefined && startedAt !== undefined) {\n emitRouterLog(logger, \"info\", {\n ...logFields,\n type: \"router:request:start\",\n });\n outgoing.once(\"finish\", () => {\n emitRouterLog(logger, \"info\", {\n ...logFields,\n durationMs: logDurationMs(startedAt),\n status: outgoing.statusCode,\n type: \"router:request:end\",\n });\n });\n }\n\n if (vite === undefined) {\n sendDevServerError(outgoing, new Error(\"Vite dev server is not initialized.\"), options);\n return;\n }\n\n vite.middlewares(incoming, outgoing, (error?: unknown) => {\n if (error !== undefined) {\n if (error instanceof Error) {\n vite?.ssrFixStacktrace(error);\n }\n sendDevServerError(outgoing, error, options);\n return;\n }\n\n outgoing.statusCode = 404;\n outgoing.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n outgoing.end(\"Not Found\");\n });\n });\n\n if (options.onUpgrade !== undefined) {\n server.on(\"upgrade\", options.onUpgrade);\n }\n\n vite = await createViteServer({\n ...userViteConfig,\n appType: \"custom\",\n configFile: false,\n root: project.projectRoot,\n server: {\n ...userViteServerConfig,\n hmr: { ...userHmrConfig, server },\n middlewareMode: true,\n },\n plugins: [\n ...(userViteConfig.plugins ?? []),\n createAppRouterVitePlugin({\n allowedSourceDirs: project.allowedSourceDirs,\n projectRoot: project.projectRoot,\n publicDir: project.publicDir,\n routesDir: project.routesDir,\n importPolicy,\n routeCache,\n serverActions: options.serverActions,\n }),\n ],\n });\n\n try {\n await listenDevHttpServer(server, port, hostname);\n } catch (error) {\n await vite.close();\n throw error;\n }\n const address = server.address();\n const actualPort = typeof address === \"object\" && address !== null ? address.port : port;\n\n return {\n server,\n url: `http://${hostname}:${actualPort}`,\n close: async () => {\n await vite?.close();\n await new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n },\n };\n}\n\nfunction listenDevHttpServer(server: Server, port: number, hostname: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const onError = (error: Error) => {\n server.off(\"listening\", onListening);\n reject(formatDevListenError(error, hostname, port));\n };\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(port, hostname);\n });\n}\n\nfunction formatDevListenError(error: Error, hostname: string, port: number): Error {\n if (isNodeErrorCode(error, \"EADDRINUSE\")) {\n return new Error(\n `mreact dev server could not start because ${hostname}:${port} is already in use. Stop the process using that port or run with PORT=<free-port>.`,\n );\n }\n\n return error;\n}\n\nfunction isNodeErrorCode(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\nasync function resolveStartDevServerProject(options: StartDevServerOptions): Promise<{\n project: ReturnType<typeof resolveAppRouterProjectOptions>;\n serverPort?: number | undefined;\n importPolicy?: LoadedMreactRouterViteConfig[\"importPolicy\"];\n viteConfig?: LoadedMreactRouterViteConfig[\"viteConfig\"];\n}> {\n if (options.appDir !== undefined || options.routesDir !== undefined) {\n return { project: resolveAppRouterProjectOptions(options) };\n }\n\n const config = await loadOptionalMreactRouterViteConfig(\n resolve(options.projectRoot ?? process.cwd()),\n );\n\n return {\n ...(config?.importPolicy === undefined ? {} : { importPolicy: config.importPolicy }),\n project: resolveAppRouterProjectOptions({\n ...config?.project,\n ...definedProjectOptions(options),\n }),\n serverPort: config?.serverPort,\n viteConfig: config?.viteConfig,\n };\n}\n\nasync function loadOptionalMreactRouterViteConfig(cwd: string) {\n try {\n return await loadMreactRouterViteConfigDetails({\n command: \"serve\",\n cwd,\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"vite.config.ts is required\")) {\n return undefined;\n }\n\n throw error;\n }\n}\n\nasync function readDeclaredProjectPackages(projectRoot: string): Promise<string[]> {\n try {\n const json = JSON.parse(await readFile(resolve(projectRoot, \"package.json\"), \"utf8\")) as {\n dependencies?: Record<string, unknown> | undefined;\n devDependencies?: Record<string, unknown> | undefined;\n optionalDependencies?: Record<string, unknown> | undefined;\n peerDependencies?: Record<string, unknown> | undefined;\n };\n\n return [\n ...Object.keys(json.dependencies ?? {}),\n ...Object.keys(json.devDependencies ?? {}),\n ...Object.keys(json.optionalDependencies ?? {}),\n ...Object.keys(json.peerDependencies ?? {}),\n ];\n } catch {\n return [];\n }\n}\n\nfunction definedProjectOptions(options: StartDevServerOptions): AppRouterProjectOptions {\n return {\n ...(options.allowedSourceDirs === undefined\n ? {}\n : { allowedSourceDirs: options.allowedSourceDirs }),\n ...(options.appDir === undefined ? {} : { appDir: options.appDir }),\n ...(options.projectRoot === undefined ? {} : { projectRoot: options.projectRoot }),\n ...(options.publicDir === undefined ? {} : { publicDir: options.publicDir }),\n ...(options.routesDir === undefined ? {} : { routesDir: options.routesDir }),\n };\n}\n\nfunction sendDevServerError(\n outgoing: ServerResponse,\n error: unknown,\n options: Pick<StartDevServerOptions, \"verboseErrors\">,\n): void {\n outgoing.statusCode = 500;\n outgoing.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n outgoing.end(options.verboseErrors === true\n ? error instanceof Error ? error.stack : String(error)\n : \"Internal Server Error\");\n}\n"]}
1
+ {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server } from \"node:http\";\nimport type { ServerResponse } from \"node:http\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { createServer as createViteServer, type UserConfig, type ViteDevServer } from \"vite\";\nimport type { AppRouterServerActionOptions } from \"./actions.js\";\nimport { createMemoryRouteCache, type AppRouterCache } from \"./cache.js\";\nimport { resolveAppRouterProjectOptions, type AppRouterProjectOptions } from \"./config.js\";\nimport type { AppRouterImportPolicy } from \"./import-policy.js\";\nimport { createAppRouterVitePlugin } from \"./vite.js\";\nimport {\n loadMreactRouterViteConfigDetails,\n type LoadedMreactRouterViteConfig,\n} from \"./vite-config.js\";\nimport {\n emitRouterLog,\n logDurationMs,\n logNow,\n nodeRequestPath,\n type AppRouterLogger,\n} from \"./logger.js\";\nimport type { HttpUpgradeHandler } from \"./upgrade.js\";\n\n/**\n * Configures the Vite-powered app-router development server.\n */\nexport interface StartDevServerOptions extends AppRouterProjectOptions {\n port?: number | undefined;\n hostname?: string;\n importPolicy?: AppRouterImportPolicy | undefined;\n logger?: AppRouterLogger | undefined;\n routeCache?: AppRouterCache | undefined;\n serverActions?: AppRouterServerActionOptions | undefined;\n verboseErrors?: boolean | undefined;\n viteConfig?: UserConfig | undefined;\n onUpgrade?: HttpUpgradeHandler | undefined;\n}\n\n/**\n * Starts the local app-router development server with Vite middleware and route compilation.\n *\n * The server trusts only the configured host settings, merges declared application packages into the development import policy, and returns a `close()` method that should be awaited by tests and scripts.\n */\nexport async function startDevServer(\n options: StartDevServerOptions,\n): Promise<{ close(): Promise<void>; server: Server; url: string }> {\n const hostname = options.hostname ?? \"127.0.0.1\";\n const resolved = await resolveStartDevServerProject(options);\n const project = resolved.project;\n const userViteConfig = options.viteConfig ?? resolved.viteConfig ?? {};\n const userViteServerConfig =\n typeof userViteConfig.server === \"object\" ? userViteConfig.server : {};\n const userHmrConfig =\n typeof userViteServerConfig.hmr === \"object\" ? userViteServerConfig.hmr : {};\n const port = options.port ?? resolved.serverPort ?? 3001;\n const routeCache = options.routeCache ?? createMemoryRouteCache();\n const declaredPackages = await readDeclaredProjectPackages(project.projectRoot);\n const configImportPolicy = resolved.importPolicy;\n const importPolicy: AppRouterImportPolicy = {\n ...configImportPolicy,\n ...options.importPolicy,\n allowedPackages: [\n ...new Set([\n ...declaredPackages,\n ...(configImportPolicy?.allowedPackages ?? []),\n ...(options.importPolicy?.allowedPackages ?? []),\n ]),\n ],\n };\n let vite: ViteDevServer | undefined;\n const server = createServer((incoming, outgoing) => {\n const logger = options.logger;\n const startedAt = logger === undefined ? undefined : logNow();\n const logFields =\n logger === undefined\n ? undefined\n : {\n method: incoming.method ?? \"GET\",\n path: nodeRequestPath(incoming.url),\n runtime: \"node\" as const,\n };\n\n if (logger !== undefined && logFields !== undefined && startedAt !== undefined) {\n emitRouterLog(logger, \"info\", {\n ...logFields,\n type: \"router:request:start\",\n });\n outgoing.once(\"finish\", () => {\n emitRouterLog(logger, \"info\", {\n ...logFields,\n durationMs: logDurationMs(startedAt),\n status: outgoing.statusCode,\n type: \"router:request:end\",\n });\n });\n }\n\n if (vite === undefined) {\n sendDevServerError(outgoing, new Error(\"Vite dev server is not initialized.\"), options);\n return;\n }\n\n vite.middlewares(incoming, outgoing, (error?: unknown) => {\n if (error !== undefined) {\n if (error instanceof Error) {\n vite?.ssrFixStacktrace(error);\n }\n sendDevServerError(outgoing, error, options);\n return;\n }\n\n outgoing.statusCode = 404;\n outgoing.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n outgoing.end(\"Not Found\");\n });\n });\n\n if (options.onUpgrade !== undefined) {\n server.on(\"upgrade\", options.onUpgrade);\n }\n\n vite = await createViteServer({\n ...userViteConfig,\n appType: \"custom\",\n configFile: false,\n root: project.projectRoot,\n server: {\n ...userViteServerConfig,\n hmr: { ...userHmrConfig, server },\n middlewareMode: true,\n },\n plugins: [\n ...(userViteConfig.plugins ?? []),\n createAppRouterVitePlugin({\n allowedSourceDirs: project.allowedSourceDirs,\n projectRoot: project.projectRoot,\n publicDir: project.publicDir,\n routesDir: project.routesDir,\n importPolicy,\n routeCache,\n serverActions: options.serverActions,\n }),\n ],\n });\n\n try {\n await listenDevHttpServer(server, port, hostname);\n } catch (error) {\n await vite.close();\n throw error;\n }\n const address = server.address();\n const actualPort = typeof address === \"object\" && address !== null ? address.port : port;\n\n return {\n server,\n url: `http://${hostname}:${actualPort}`,\n close: async () => {\n await vite?.close();\n await new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n },\n };\n}\n\nfunction listenDevHttpServer(server: Server, port: number, hostname: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const onError = (error: Error) => {\n server.off(\"listening\", onListening);\n reject(formatDevListenError(error, hostname, port));\n };\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(port, hostname);\n });\n}\n\nfunction formatDevListenError(error: Error, hostname: string, port: number): Error {\n if (isNodeErrorCode(error, \"EADDRINUSE\")) {\n return new Error(\n `mreact dev server could not start because ${hostname}:${port} is already in use. Stop the process using that port or run with PORT=<free-port>.`,\n );\n }\n\n return error;\n}\n\nfunction isNodeErrorCode(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\nasync function resolveStartDevServerProject(options: StartDevServerOptions): Promise<{\n project: ReturnType<typeof resolveAppRouterProjectOptions>;\n serverPort?: number | undefined;\n importPolicy?: LoadedMreactRouterViteConfig[\"importPolicy\"];\n viteConfig?: LoadedMreactRouterViteConfig[\"viteConfig\"];\n}> {\n if (options.appDir !== undefined || options.routesDir !== undefined) {\n return { project: resolveAppRouterProjectOptions(options) };\n }\n\n const config = await loadOptionalMreactRouterViteConfig(\n resolve(options.projectRoot ?? process.cwd()),\n );\n\n return {\n ...(config?.importPolicy === undefined ? {} : { importPolicy: config.importPolicy }),\n project: resolveAppRouterProjectOptions({\n ...config?.project,\n ...definedProjectOptions(options),\n }),\n serverPort: config?.serverPort,\n viteConfig: config?.viteConfig,\n };\n}\n\nasync function loadOptionalMreactRouterViteConfig(cwd: string) {\n try {\n return await loadMreactRouterViteConfigDetails({\n command: \"serve\",\n cwd,\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"vite.config.ts is required\")) {\n return undefined;\n }\n\n throw error;\n }\n}\n\nasync function readDeclaredProjectPackages(projectRoot: string): Promise<string[]> {\n try {\n const json = JSON.parse(await readFile(resolve(projectRoot, \"package.json\"), \"utf8\")) as {\n dependencies?: Record<string, unknown> | undefined;\n devDependencies?: Record<string, unknown> | undefined;\n optionalDependencies?: Record<string, unknown> | undefined;\n peerDependencies?: Record<string, unknown> | undefined;\n };\n\n return [\n ...Object.keys(json.dependencies ?? {}),\n ...Object.keys(json.devDependencies ?? {}),\n ...Object.keys(json.optionalDependencies ?? {}),\n ...Object.keys(json.peerDependencies ?? {}),\n ];\n } catch {\n return [];\n }\n}\n\nfunction definedProjectOptions(options: StartDevServerOptions): AppRouterProjectOptions {\n return {\n ...(options.allowedSourceDirs === undefined\n ? {}\n : { allowedSourceDirs: options.allowedSourceDirs }),\n ...(options.appDir === undefined ? {} : { appDir: options.appDir }),\n ...(options.projectRoot === undefined ? {} : { projectRoot: options.projectRoot }),\n ...(options.publicDir === undefined ? {} : { publicDir: options.publicDir }),\n ...(options.routesDir === undefined ? {} : { routesDir: options.routesDir }),\n };\n}\n\nfunction sendDevServerError(\n outgoing: ServerResponse,\n error: unknown,\n options: Pick<StartDevServerOptions, \"verboseErrors\">,\n): void {\n outgoing.statusCode = 500;\n outgoing.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n outgoing.end(options.verboseErrors === true\n ? error instanceof Error ? error.stack : String(error)\n : \"Internal Server Error\");\n}\n"]}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Names file conventions that app-router treats as metadata or static asset routes.
3
+ */
1
4
  export type AppFileConvention = "apple-icon" | "icon" | "manifest" | "opengraph-image" | "robots" | "sitemap";
2
5
  export type AppFileConventionRouteKind = "asset" | "metadata";
3
6
  export interface AppFileConventionRouteInfo {
@@ -1 +1 @@
1
- {"version":3,"file":"file-conventions.d.ts","sourceRoot":"","sources":["../src/file-conventions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,MAAM,GACN,UAAU,GACV,iBAAiB,GACjB,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,UAAU,CAAC;AAE9D,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,IAAI,EAAE,0BAA0B,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAwDD,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,GACf,0BAA0B,GAAG,SAAS,CAExC;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWrE"}
1
+ {"version":3,"file":"file-conventions.d.ts","sourceRoot":"","sources":["../src/file-conventions.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,MAAM,GACN,UAAU,GACV,iBAAiB,GACjB,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,UAAU,CAAC;AAE9D,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,IAAI,EAAE,0BAA0B,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAwDD,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,GACf,0BAA0B,GAAG,SAAS,CAExC;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-conventions.js","sourceRoot":"","sources":["../src/file-conventions.ts"],"names":[],"mappings":"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","sourcesContent":["export type AppFileConvention =\n | \"apple-icon\"\n | \"icon\"\n | \"manifest\"\n | \"opengraph-image\"\n | \"robots\"\n | \"sitemap\";\n\nexport type AppFileConventionRouteKind = \"asset\" | \"metadata\";\n\nexport interface AppFileConventionRouteInfo {\n convention: AppFileConvention;\n kind: AppFileConventionRouteKind;\n path: string;\n}\n\nconst conventionByFilename = new Map<string, AppFileConventionRouteInfo>([\n [\"robots.ts\", { convention: \"robots\", kind: \"metadata\", path: \"/robots.txt\" }],\n [\"robots.txt\", { convention: \"robots\", kind: \"asset\", path: \"/robots.txt\" }],\n [\"sitemap.ts\", { convention: \"sitemap\", kind: \"metadata\", path: \"/sitemap.xml\" }],\n [\"sitemap.xml\", { convention: \"sitemap\", kind: \"asset\", path: \"/sitemap.xml\" }],\n [\"manifest.ts\", { convention: \"manifest\", kind: \"metadata\", path: \"/manifest.webmanifest\" }],\n [\n \"manifest.webmanifest\",\n { convention: \"manifest\", kind: \"asset\", path: \"/manifest.webmanifest\" },\n ],\n [\"favicon.ico\", { convention: \"icon\", kind: \"asset\", path: \"/favicon.ico\" }],\n [\"icon.ico\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.png\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.jpg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.jpeg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.svg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"apple-icon.png\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.jpg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.jpeg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.svg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\n \"opengraph-image.png\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jpg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jpeg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.svg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.ts\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.tsx\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.js\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jsx\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n]);\n\nexport function appFileConventionForRootFilename(\n filename: string,\n): AppFileConventionRouteInfo | undefined {\n return conventionByFilename.get(filename);\n}\n\nexport function appFileConventionContentType(filename: string): string {\n if (filename.endsWith(\".txt\")) return \"text/plain; charset=utf-8\";\n if (filename.endsWith(\".xml\")) return \"application/xml; charset=utf-8\";\n if (filename.endsWith(\".webmanifest\")) return \"application/manifest+json; charset=utf-8\";\n if (filename.endsWith(\".json\")) return \"application/json; charset=utf-8\";\n if (filename.endsWith(\".svg\")) return \"image/svg+xml\";\n if (filename.endsWith(\".png\")) return \"image/png\";\n if (filename.endsWith(\".jpg\") || filename.endsWith(\".jpeg\")) return \"image/jpeg\";\n if (filename.endsWith(\".ico\")) return \"image/x-icon\";\n\n return \"application/octet-stream\";\n}\n"]}
1
+ {"version":3,"file":"file-conventions.js","sourceRoot":"","sources":["../src/file-conventions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Names file conventions that app-router treats as metadata or static asset routes.\n */\nexport type AppFileConvention =\n | \"apple-icon\"\n | \"icon\"\n | \"manifest\"\n | \"opengraph-image\"\n | \"robots\"\n | \"sitemap\";\n\nexport type AppFileConventionRouteKind = \"asset\" | \"metadata\";\n\nexport interface AppFileConventionRouteInfo {\n convention: AppFileConvention;\n kind: AppFileConventionRouteKind;\n path: string;\n}\n\nconst conventionByFilename = new Map<string, AppFileConventionRouteInfo>([\n [\"robots.ts\", { convention: \"robots\", kind: \"metadata\", path: \"/robots.txt\" }],\n [\"robots.txt\", { convention: \"robots\", kind: \"asset\", path: \"/robots.txt\" }],\n [\"sitemap.ts\", { convention: \"sitemap\", kind: \"metadata\", path: \"/sitemap.xml\" }],\n [\"sitemap.xml\", { convention: \"sitemap\", kind: \"asset\", path: \"/sitemap.xml\" }],\n [\"manifest.ts\", { convention: \"manifest\", kind: \"metadata\", path: \"/manifest.webmanifest\" }],\n [\n \"manifest.webmanifest\",\n { convention: \"manifest\", kind: \"asset\", path: \"/manifest.webmanifest\" },\n ],\n [\"favicon.ico\", { convention: \"icon\", kind: \"asset\", path: \"/favicon.ico\" }],\n [\"icon.ico\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.png\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.jpg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.jpeg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"icon.svg\", { convention: \"icon\", kind: \"asset\", path: \"/icon\" }],\n [\"apple-icon.png\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.jpg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.jpeg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\"apple-icon.svg\", { convention: \"apple-icon\", kind: \"asset\", path: \"/apple-icon\" }],\n [\n \"opengraph-image.png\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jpg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jpeg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.svg\",\n { convention: \"opengraph-image\", kind: \"asset\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.ts\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.tsx\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.js\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n [\n \"opengraph-image.jsx\",\n { convention: \"opengraph-image\", kind: \"metadata\", path: \"/opengraph-image\" },\n ],\n]);\n\nexport function appFileConventionForRootFilename(\n filename: string,\n): AppFileConventionRouteInfo | undefined {\n return conventionByFilename.get(filename);\n}\n\nexport function appFileConventionContentType(filename: string): string {\n if (filename.endsWith(\".txt\")) return \"text/plain; charset=utf-8\";\n if (filename.endsWith(\".xml\")) return \"application/xml; charset=utf-8\";\n if (filename.endsWith(\".webmanifest\")) return \"application/manifest+json; charset=utf-8\";\n if (filename.endsWith(\".json\")) return \"application/json; charset=utf-8\";\n if (filename.endsWith(\".svg\")) return \"image/svg+xml\";\n if (filename.endsWith(\".png\")) return \"image/png\";\n if (filename.endsWith(\".jpg\") || filename.endsWith(\".jpeg\")) return \"image/jpeg\";\n if (filename.endsWith(\".ico\")) return \"image/x-icon\";\n\n return \"application/octet-stream\";\n}\n"]}
package/dist/i18n.d.ts CHANGED
@@ -1,15 +1,30 @@
1
+ /**
2
+ * Configures locale detection for app-router requests.
3
+ */
1
4
  export interface LocaleRoutingOptions<Locale extends string = string> {
2
5
  defaultLocale: Locale;
3
6
  locales: readonly Locale[];
4
7
  }
8
+ /**
9
+ * Reports the locale selected for an incoming request.
10
+ */
5
11
  export interface DetectedLocale<Locale extends string = string> {
6
12
  locale: Locale;
7
13
  pathname: string;
8
14
  source: "accept-language" | "default" | "path";
9
15
  }
16
+ /**
17
+ * Describes a nested tree of localized message strings.
18
+ */
10
19
  export type MessageTree = {
11
20
  readonly [key: string]: MessageTree | string;
12
21
  };
22
+ /**
23
+ * Detects the request locale from the URL path or Accept-Language header.
24
+ */
13
25
  export declare function detectLocale<Locale extends string>(request: Request, options: LocaleRoutingOptions<Locale>): DetectedLocale<Locale>;
26
+ /**
27
+ * Preserves literal types for a localized message tree.
28
+ */
14
29
  export declare function defineMessages<const Messages extends MessageTree>(messages: Messages): Messages;
15
30
  //# sourceMappingURL=i18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;CAC9C,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,SAAS,MAAM,EAChD,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACpC,cAAc,CAAC,MAAM,CAAC,CA8BxB;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,QAAQ,SAAS,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAE/F"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;CAC9C,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,SAAS,MAAM,EAChD,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACpC,cAAc,CAAC,MAAM,CAAC,CA8BxB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,QAAQ,SAAS,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAE/F"}
package/dist/i18n.js CHANGED
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Detects the request locale from the URL path or Accept-Language header.
3
+ */
1
4
  export function detectLocale(request, options) {
2
5
  const url = new URL(request.url);
3
6
  const pathMatch = localeFromPath(url.pathname, options.locales);
@@ -22,6 +25,9 @@ export function detectLocale(request, options) {
22
25
  source: "default",
23
26
  };
24
27
  }
28
+ /**
29
+ * Preserves literal types for a localized message tree.
30
+ */
25
31
  export function defineMessages(messages) {
26
32
  return messages;
27
33
  }
package/dist/i18n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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","sourcesContent":["export interface LocaleRoutingOptions<Locale extends string = string> {\n defaultLocale: Locale;\n locales: readonly Locale[];\n}\n\nexport interface DetectedLocale<Locale extends string = string> {\n locale: Locale;\n pathname: string;\n source: \"accept-language\" | \"default\" | \"path\";\n}\n\nexport type MessageTree = {\n readonly [key: string]: MessageTree | string;\n};\n\nexport function detectLocale<Locale extends string>(\n request: Request,\n options: LocaleRoutingOptions<Locale>,\n): DetectedLocale<Locale> {\n const url = new URL(request.url);\n const pathMatch = localeFromPath(url.pathname, options.locales);\n\n if (pathMatch !== undefined) {\n return {\n locale: pathMatch.locale,\n pathname: pathMatch.pathname,\n source: \"path\",\n };\n }\n\n const accepted = localeFromAcceptLanguage(\n request.headers.get(\"accept-language\"),\n options.locales,\n );\n\n if (accepted !== undefined) {\n return {\n locale: accepted,\n pathname: url.pathname,\n source: \"accept-language\",\n };\n }\n\n return {\n locale: options.defaultLocale,\n pathname: url.pathname,\n source: \"default\",\n };\n}\n\nexport function defineMessages<const Messages extends MessageTree>(messages: Messages): Messages {\n return messages;\n}\n\nfunction localeFromPath<Locale extends string>(\n pathname: string,\n locales: readonly Locale[],\n): { locale: Locale; pathname: string } | undefined {\n const [, firstSegment = \"\", ...rest] = pathname.split(\"/\");\n const locale = locales.find((candidate) => candidate === firstSegment);\n\n if (locale === undefined) {\n return undefined;\n }\n\n return {\n locale,\n pathname: rest.length === 0 ? \"/\" : `/${rest.join(\"/\")}`,\n };\n}\n\nfunction localeFromAcceptLanguage<Locale extends string>(\n header: string | null,\n locales: readonly Locale[],\n): Locale | undefined {\n if (header === null) {\n return undefined;\n }\n\n return header\n .split(\",\")\n .map((part) => {\n const [tag = \"\", ...params] = part.trim().split(\";\");\n const q = params\n .map((param) => /^q=(?<value>\\d(?:\\.\\d+)?)$/.exec(param.trim())?.groups?.value)\n .find((value): value is string => value !== undefined);\n\n return {\n q: q === undefined ? 1 : Number(q),\n tag: tag.toLowerCase(),\n };\n })\n .filter((entry) => entry.tag !== \"\" && Number.isFinite(entry.q) && entry.q > 0)\n .sort((left, right) => right.q - left.q)\n .flatMap((entry) => [entry.tag, entry.tag.split(\"-\")[0] ?? \"\"])\n .map((tag) => locales.find((locale) => locale.toLowerCase() === tag))\n .find((locale): locale is Locale => locale !== undefined);\n}\n"]}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAgB,EAChB,OAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO;YACL,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,MAAM,EAAE,MAAM;SACf,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,wBAAwB,CACvC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EACtC,OAAO,CAAC,OAAO,CAChB,CAAC;IAEF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,MAAM,EAAE,iBAAiB;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,aAAa;QAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,MAAM,EAAE,SAAS;KAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAqC,QAAkB;IACnF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CACrB,QAAgB,EAChB,OAA0B;IAE1B,MAAM,CAAC,EAAE,YAAY,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;IAEvE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;KACzD,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAC/B,MAAqB,EACrB,OAA0B;IAE1B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,MAAM;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM;aACb,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC;aAC9E,IAAI,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QAEzD,OAAO;YACL,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAClC,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;SACvB,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;SAC9E,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;SACvC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;SACpE,IAAI,CAAC,CAAC,MAAM,EAAoB,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["/**\n * Configures locale detection for app-router requests.\n */\nexport interface LocaleRoutingOptions<Locale extends string = string> {\n defaultLocale: Locale;\n locales: readonly Locale[];\n}\n\n/**\n * Reports the locale selected for an incoming request.\n */\nexport interface DetectedLocale<Locale extends string = string> {\n locale: Locale;\n pathname: string;\n source: \"accept-language\" | \"default\" | \"path\";\n}\n\n/**\n * Describes a nested tree of localized message strings.\n */\nexport type MessageTree = {\n readonly [key: string]: MessageTree | string;\n};\n\n/**\n * Detects the request locale from the URL path or Accept-Language header.\n */\nexport function detectLocale<Locale extends string>(\n request: Request,\n options: LocaleRoutingOptions<Locale>,\n): DetectedLocale<Locale> {\n const url = new URL(request.url);\n const pathMatch = localeFromPath(url.pathname, options.locales);\n\n if (pathMatch !== undefined) {\n return {\n locale: pathMatch.locale,\n pathname: pathMatch.pathname,\n source: \"path\",\n };\n }\n\n const accepted = localeFromAcceptLanguage(\n request.headers.get(\"accept-language\"),\n options.locales,\n );\n\n if (accepted !== undefined) {\n return {\n locale: accepted,\n pathname: url.pathname,\n source: \"accept-language\",\n };\n }\n\n return {\n locale: options.defaultLocale,\n pathname: url.pathname,\n source: \"default\",\n };\n}\n\n/**\n * Preserves literal types for a localized message tree.\n */\nexport function defineMessages<const Messages extends MessageTree>(messages: Messages): Messages {\n return messages;\n}\n\nfunction localeFromPath<Locale extends string>(\n pathname: string,\n locales: readonly Locale[],\n): { locale: Locale; pathname: string } | undefined {\n const [, firstSegment = \"\", ...rest] = pathname.split(\"/\");\n const locale = locales.find((candidate) => candidate === firstSegment);\n\n if (locale === undefined) {\n return undefined;\n }\n\n return {\n locale,\n pathname: rest.length === 0 ? \"/\" : `/${rest.join(\"/\")}`,\n };\n}\n\nfunction localeFromAcceptLanguage<Locale extends string>(\n header: string | null,\n locales: readonly Locale[],\n): Locale | undefined {\n if (header === null) {\n return undefined;\n }\n\n return header\n .split(\",\")\n .map((part) => {\n const [tag = \"\", ...params] = part.trim().split(\";\");\n const q = params\n .map((param) => /^q=(?<value>\\d(?:\\.\\d+)?)$/.exec(param.trim())?.groups?.value)\n .find((value): value is string => value !== undefined);\n\n return {\n q: q === undefined ? 1 : Number(q),\n tag: tag.toLowerCase(),\n };\n })\n .filter((entry) => entry.tag !== \"\" && Number.isFinite(entry.q) && entry.q > 0)\n .sort((left, right) => right.q - left.q)\n .flatMap((entry) => [entry.tag, entry.tag.split(\"-\")[0] ?? \"\"])\n .map((tag) => locales.find((locale) => locale.toLowerCase() === tag))\n .find((locale): locale is Locale => locale !== undefined);\n}\n"]}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Controls which source roots and runtime packages built app-router handlers may import.
3
+ */
1
4
  export interface AppRouterImportPolicy {
2
5
  allowedPackages?: readonly string[] | undefined;
3
6
  allowedSourceDirs?: readonly string[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"import-policy.d.ts","sourceRoot":"","sources":["../src/import-policy.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,kCAAkC;IACjD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,kCAAkC;;oBAiBzE;QACd,SAAS,CACP,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;SACpB,KAAK;YAAE,MAAM,CAAC,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,GACxF,IAAI,CAAC;KACT;EAoEJ"}
1
+ {"version":3,"file":"import-policy.d.ts","sourceRoot":"","sources":["../src/import-policy.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,kCAAkC;IACjD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,kCAAkC;;oBAiBzE;QACd,SAAS,CACP,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;SACpB,KAAK;YAAE,MAAM,CAAC,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,GACxF,IAAI,CAAC;KACT;EAoEJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"import-policy.js","sourceRoot":"","sources":["../src/import-policy.ts"],"names":[],"mappings":"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","sourcesContent":["import { builtinModules, createRequire } from \"node:module\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { resolveWorkspacePackageFile } from \"./workspace-packages.js\";\n\nconst builtinModuleNames = new Set(builtinModules.flatMap((name) => [name, `node:${name}`]));\nconst alwaysAllowedPackages = new Set([\n \"@reckona/mreact\",\n \"@reckona/mreact-auth\",\n \"@reckona/mreact-query\",\n \"@reckona/mreact-reactive-core\",\n \"@reckona/mreact-router\",\n]);\n\nexport interface AppRouterImportPolicy {\n allowedPackages?: readonly string[] | undefined;\n allowedSourceDirs?: readonly string[] | undefined;\n projectRoot?: string | undefined;\n}\n\nexport interface AppRouterImportPolicyPluginOptions {\n allowedSourceDirs?: readonly string[] | undefined;\n appDir: string;\n externalizeAllowedPackages?: boolean | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n label: string;\n projectRoot?: string | undefined;\n}\n\nexport function createAppRouterImportPolicyPlugin(options: AppRouterImportPolicyPluginOptions) {\n const projectRoot = resolve(\n options.importPolicy?.projectRoot ?? options.projectRoot ?? options.appDir,\n );\n const configuredAllowedSourceDirs =\n options.importPolicy?.allowedSourceDirs ?? options.allowedSourceDirs;\n const allowedSourceDirs = (configuredAllowedSourceDirs ?? [options.appDir]).map((directory) =>\n resolve(projectRoot, directory),\n );\n const allowedPackages = new Set([\n ...alwaysAllowedPackages,\n ...(options.importPolicy?.allowedPackages ?? []),\n ]);\n const customAllowedSourceDirs = configuredAllowedSourceDirs !== undefined;\n\n return {\n name: `mreact-router-${options.label}-import-policy`,\n setup(buildApi: {\n onResolve(\n options: { filter: RegExp },\n callback: (args: {\n path: string;\n resolveDir: string;\n }) => { errors?: Array<{ text: string }>; external?: boolean; path?: string } | undefined,\n ): void;\n }) {\n buildApi.onResolve({ filter: /.*/ }, (args) => {\n if (isRelativeImport(args.path)) {\n const baseDir = args.resolveDir === \"\" ? options.appDir : args.resolveDir;\n if (!isInsideAnyDirectory(allowedSourceDirs, baseDir)) {\n return undefined;\n }\n\n const resolvedPath = resolve(baseDir, args.path);\n\n return !isInsideDirectory(projectRoot, resolvedPath) ||\n !isInsideAnyDirectory(allowedSourceDirs, resolvedPath)\n ? {\n errors: [\n {\n text: customAllowedSourceDirs\n ? `${options.label} imports must stay inside allowed source directories: ${args.path}`\n : `${options.label} imports must stay inside the app directory: ${args.path}`,\n },\n ],\n }\n : undefined;\n }\n\n if (isAbsoluteOrProtocolImport(args.path)) {\n return undefined;\n }\n\n if (builtinModuleNames.has(args.path)) {\n return { external: true, path: args.path };\n }\n\n const workspacePath = workspacePackagePath(args.path, args.resolveDir);\n if (workspacePath !== undefined) {\n return { path: workspacePath };\n }\n\n if (args.resolveDir !== \"\" && !isInsideAnyDirectory(allowedSourceDirs, args.resolveDir)) {\n return undefined;\n }\n\n const packageName = packageNameForSpecifier(args.path);\n\n if (!allowedPackages.has(packageName)) {\n return {\n errors: [\n {\n text: importPolicyPackageError(options.label, packageName),\n },\n ],\n };\n }\n\n const resolvedPackage = resolvePackageSpecifier(args.path, args.resolveDir, options.appDir);\n\n if (resolvedPackage === undefined) {\n return undefined;\n }\n\n return options.externalizeAllowedPackages === false\n ? undefined\n : {\n external: true,\n path: pathToFileURL(resolvedPackage).href,\n };\n });\n },\n };\n}\n\nfunction resolvePackageSpecifier(\n specifier: string,\n resolveDir: string,\n appDir: string,\n): string | undefined {\n const baseDir = resolveDir === \"\" ? appDir : resolveDir;\n\n try {\n return createRequire(join(baseDir, \"__mreact_resolve__.cjs\")).resolve(specifier);\n } catch {\n return undefined;\n }\n}\n\nfunction importPolicyPackageError(label: string, packageName: string): string {\n const normalizedLabel = label.toLowerCase();\n const moduleKind =\n normalizedLabel.includes(\"loader\") ||\n normalizedLabel.includes(\"middleware\") ||\n normalizedLabel.includes(\"route\") ||\n normalizedLabel.includes(\"metadata\") ||\n normalizedLabel.includes(\"action\")\n ? normalizedLabel\n : `${normalizedLabel} module`;\n const aliasHint =\n packageName === \"~\" || packageName === \"@\"\n ? [\n \"\",\n 'This looks like an app-local alias import. Use a relative import such as \"./\" or \"../\" in server-side route code, or move the import behind a supported client boundary.',\n ]\n : [];\n\n return [\n `\"${packageName}\" is imported by a ${moduleKind} but is not allowed by the app-router import policy.`,\n \"\",\n \"The policy blocks server-side static imports from loader, middleware, route handler, metadata, and server action modules unless the package is explicitly allowed.\",\n ...aliasHint,\n \"\",\n \"Allow it in the Vite plugin config:\",\n \" mreactRouter({\",\n ` importPolicy: { allowedPackages: [${JSON.stringify(packageName)}] },`,\n \" })\",\n \"\",\n \"For production builds, also declare the package in package.json dependencies so mreact-router build can derive the generated policy and the package is installed in the runtime artifact.\",\n ].join(\"\\n\");\n}\n\nfunction workspacePackagePath(specifier: string, resolveDir: string): string | undefined {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const packageRoot = dirname(currentDir);\n const entries = new Map<\n string,\n string | { entry: string; monorepoDir: string; packageName: string }\n >([\n [\n \"@reckona/mreact-auth\",\n { entry: \"index\", monorepoDir: \"auth\", packageName: \"@reckona/mreact-auth\" },\n ],\n [\n \"@reckona/mreact-compiler\",\n { entry: \"index\", monorepoDir: \"compiler\", packageName: \"@reckona/mreact-compiler\" },\n ],\n [\n \"@reckona/mreact-query\",\n { entry: \"index\", monorepoDir: \"query\", packageName: \"@reckona/mreact-query\" },\n ],\n [\n \"@reckona/mreact-reactive-core\",\n {\n entry: \"index\",\n monorepoDir: \"reactive-core\",\n packageName: \"@reckona/mreact-reactive-core\",\n },\n ],\n [\n \"@reckona/mreact-router\",\n join(packageRoot, currentDir.endsWith(`${sep}dist`) ? \"dist/index.js\" : \"src/index.ts\"),\n ],\n [\n \"@reckona/mreact-router/app-router-globals\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`)\n ? \"dist/app-router-globals.js\"\n : \"src/app-router-globals.ts\",\n ),\n ],\n [\n \"@reckona/mreact-router/link\",\n join(packageRoot, currentDir.endsWith(`${sep}dist`) ? \"dist/link.js\" : \"src/link.ts\"),\n ],\n [\n \"@reckona/mreact-router/navigation-state\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`) ? \"dist/navigation-state.js\" : \"src/navigation-state.ts\",\n ),\n ],\n [\n \"@reckona/mreact-router/stream-list\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`) ? \"dist/stream-list.js\" : \"src/stream-list.ts\",\n ),\n ],\n [\n \"@reckona/mreact-server\",\n { entry: \"index\", monorepoDir: \"server\", packageName: \"@reckona/mreact-server\" },\n ],\n ]);\n const entry = entries.get(specifier);\n\n if (entry === undefined || typeof entry === \"string\") {\n return entry;\n }\n\n return resolveWorkspacePackageFile({\n currentFileUrl: import.meta.url,\n entry: entry.entry,\n monorepoDir: entry.monorepoDir,\n packageName: entry.packageName,\n resolveDir,\n specifier,\n });\n}\n\nfunction isRelativeImport(path: string): boolean {\n return path === \".\" || path === \"..\" || path.startsWith(\"./\") || path.startsWith(\"../\");\n}\n\nfunction isAbsoluteOrProtocolImport(path: string): boolean {\n return path.startsWith(\"/\") || /^[A-Za-z][A-Za-z0-9+.-]*:/.test(path);\n}\n\nfunction packageNameForSpecifier(specifier: string): string {\n if (!specifier.startsWith(\"@\")) {\n return specifier.split(\"/\")[0] ?? specifier;\n }\n\n const [scope, name] = specifier.split(\"/\");\n\n return scope !== undefined && name !== undefined ? `${scope}/${name}` : specifier;\n}\n\nfunction isInsideDirectory(directory: string, candidate: string): boolean {\n const relativePath = relative(directory, candidate);\n\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !relativePath.startsWith(sep));\n}\n\nfunction isInsideAnyDirectory(directories: readonly string[], candidate: string): boolean {\n return directories.some((directory) => isInsideDirectory(directory, candidate));\n}\n"]}
1
+ {"version":3,"file":"import-policy.js","sourceRoot":"","sources":["../src/import-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7F,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,iBAAiB;IACjB,sBAAsB;IACtB,uBAAuB;IACvB,+BAA+B;IAC/B,wBAAwB;CACzB,CAAC,CAAC;AAoBH,MAAM,UAAU,iCAAiC,CAAC,OAA2C;IAC3F,MAAM,WAAW,GAAG,OAAO,CACzB,OAAO,CAAC,YAAY,EAAE,WAAW,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,MAAM,CAC3E,CAAC;IACF,MAAM,2BAA2B,GAC/B,OAAO,CAAC,YAAY,EAAE,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IACvE,MAAM,iBAAiB,GAAG,CAAC,2BAA2B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAC5F,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAChC,CAAC;IACF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;QAC9B,GAAG,qBAAqB;QACxB,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,eAAe,IAAI,EAAE,CAAC;KACjD,CAAC,CAAC;IACH,MAAM,uBAAuB,GAAG,2BAA2B,KAAK,SAAS,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,iBAAiB,OAAO,CAAC,KAAK,gBAAgB;QACpD,KAAK,CAAC,QAQL;YACC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5C,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAChC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;oBAC1E,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE,CAAC;wBACtD,OAAO,SAAS,CAAC;oBACnB,CAAC;oBAED,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAEjD,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC;wBAClD,CAAC,oBAAoB,CAAC,iBAAiB,EAAE,YAAY,CAAC;wBACtD,CAAC,CAAC;4BACE,MAAM,EAAE;gCACN;oCACE,IAAI,EAAE,uBAAuB;wCAC3B,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,yDAAyD,IAAI,CAAC,IAAI,EAAE;wCACtF,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,gDAAgD,IAAI,CAAC,IAAI,EAAE;iCAChF;6BACF;yBACF;wBACH,CAAC,CAAC,SAAS,CAAC;gBAChB,CAAC;gBAED,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1C,OAAO,SAAS,CAAC;gBACnB,CAAC;gBAED,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7C,CAAC;gBAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvE,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;oBAChC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;gBACjC,CAAC;gBAED,IAAI,IAAI,CAAC,UAAU,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxF,OAAO,SAAS,CAAC;gBACnB,CAAC;gBAED,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEvD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtC,OAAO;wBACL,MAAM,EAAE;4BACN;gCACE,IAAI,EAAE,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC;6BAC3D;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,MAAM,eAAe,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAE5F,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;oBAClC,OAAO,SAAS,CAAC;gBACnB,CAAC;gBAED,OAAO,OAAO,CAAC,0BAA0B,KAAK,KAAK;oBACjD,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC;wBACE,QAAQ,EAAE,IAAI;wBACd,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,IAAI;qBAC1C,CAAC;YACR,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,SAAiB,EACjB,UAAkB,EAClB,MAAc;IAEd,MAAM,OAAO,GAAG,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;IAExD,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAa,EAAE,WAAmB;IAClE,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,UAAU,GACd,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAClC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC;QACtC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;QACjC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC;QACpC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAChC,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,GAAG,eAAe,SAAS,CAAC;IAClC,MAAM,SAAS,GACb,WAAW,KAAK,GAAG,IAAI,WAAW,KAAK,GAAG;QACxC,CAAC,CAAC;YACE,EAAE;YACF,0KAA0K;SAC3K;QACH,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,IAAI,WAAW,sBAAsB,UAAU,sDAAsD;QACrG,EAAE;QACF,oKAAoK;QACpK,GAAG,SAAS;QACZ,EAAE;QACF,qCAAqC;QACrC,kBAAkB;QAClB,yCAAyC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM;QAC1E,MAAM;QACN,EAAE;QACF,2LAA2L;KAC5L,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAiB,EAAE,UAAkB;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,GAAG,CAGrB;QACA;YACE,sBAAsB;YACtB,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,sBAAsB,EAAE;SAC7E;QACD;YACE,0BAA0B;YAC1B,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,0BAA0B,EAAE;SACrF;QACD;YACE,uBAAuB;YACvB,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE;SAC/E;QACD;YACE,+BAA+B;YAC/B;gBACE,KAAK,EAAE,OAAO;gBACd,WAAW,EAAE,eAAe;gBAC5B,WAAW,EAAE,+BAA+B;aAC7C;SACF;QACD;YACE,wBAAwB;YACxB,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC;SACxF;QACD;YACE,2CAA2C;YAC3C,IAAI,CACF,WAAW,EACX,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC;gBAC/B,CAAC,CAAC,4BAA4B;gBAC9B,CAAC,CAAC,2BAA2B,CAChC;SACF;QACD;YACE,6BAA6B;YAC7B,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC;SACtF;QACD;YACE,yCAAyC;YACzC,IAAI,CACF,WAAW,EACX,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,yBAAyB,CAC3F;SACF;QACD;YACE,oCAAoC;YACpC,IAAI,CACF,WAAW,EACX,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CACjF;SACF;QACD;YACE,wBAAwB;YACxB,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;SACjF;KACF,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAErC,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,2BAA2B,CAAC;QACjC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;QAC/B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,UAAU;QACV,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,uBAAuB,CAAC,SAAiB;IAChD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAC9C,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE3C,OAAO,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACpF,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB,EAAE,SAAiB;IAC7D,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEpD,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,oBAAoB,CAAC,WAA8B,EAAE,SAAiB;IAC7E,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAClF,CAAC","sourcesContent":["import { builtinModules, createRequire } from \"node:module\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { resolveWorkspacePackageFile } from \"./workspace-packages.js\";\n\nconst builtinModuleNames = new Set(builtinModules.flatMap((name) => [name, `node:${name}`]));\nconst alwaysAllowedPackages = new Set([\n \"@reckona/mreact\",\n \"@reckona/mreact-auth\",\n \"@reckona/mreact-query\",\n \"@reckona/mreact-reactive-core\",\n \"@reckona/mreact-router\",\n]);\n\n/**\n * Controls which source roots and runtime packages built app-router handlers may import.\n */\nexport interface AppRouterImportPolicy {\n allowedPackages?: readonly string[] | undefined;\n allowedSourceDirs?: readonly string[] | undefined;\n projectRoot?: string | undefined;\n}\n\nexport interface AppRouterImportPolicyPluginOptions {\n allowedSourceDirs?: readonly string[] | undefined;\n appDir: string;\n externalizeAllowedPackages?: boolean | undefined;\n importPolicy?: AppRouterImportPolicy | undefined;\n label: string;\n projectRoot?: string | undefined;\n}\n\nexport function createAppRouterImportPolicyPlugin(options: AppRouterImportPolicyPluginOptions) {\n const projectRoot = resolve(\n options.importPolicy?.projectRoot ?? options.projectRoot ?? options.appDir,\n );\n const configuredAllowedSourceDirs =\n options.importPolicy?.allowedSourceDirs ?? options.allowedSourceDirs;\n const allowedSourceDirs = (configuredAllowedSourceDirs ?? [options.appDir]).map((directory) =>\n resolve(projectRoot, directory),\n );\n const allowedPackages = new Set([\n ...alwaysAllowedPackages,\n ...(options.importPolicy?.allowedPackages ?? []),\n ]);\n const customAllowedSourceDirs = configuredAllowedSourceDirs !== undefined;\n\n return {\n name: `mreact-router-${options.label}-import-policy`,\n setup(buildApi: {\n onResolve(\n options: { filter: RegExp },\n callback: (args: {\n path: string;\n resolveDir: string;\n }) => { errors?: Array<{ text: string }>; external?: boolean; path?: string } | undefined,\n ): void;\n }) {\n buildApi.onResolve({ filter: /.*/ }, (args) => {\n if (isRelativeImport(args.path)) {\n const baseDir = args.resolveDir === \"\" ? options.appDir : args.resolveDir;\n if (!isInsideAnyDirectory(allowedSourceDirs, baseDir)) {\n return undefined;\n }\n\n const resolvedPath = resolve(baseDir, args.path);\n\n return !isInsideDirectory(projectRoot, resolvedPath) ||\n !isInsideAnyDirectory(allowedSourceDirs, resolvedPath)\n ? {\n errors: [\n {\n text: customAllowedSourceDirs\n ? `${options.label} imports must stay inside allowed source directories: ${args.path}`\n : `${options.label} imports must stay inside the app directory: ${args.path}`,\n },\n ],\n }\n : undefined;\n }\n\n if (isAbsoluteOrProtocolImport(args.path)) {\n return undefined;\n }\n\n if (builtinModuleNames.has(args.path)) {\n return { external: true, path: args.path };\n }\n\n const workspacePath = workspacePackagePath(args.path, args.resolveDir);\n if (workspacePath !== undefined) {\n return { path: workspacePath };\n }\n\n if (args.resolveDir !== \"\" && !isInsideAnyDirectory(allowedSourceDirs, args.resolveDir)) {\n return undefined;\n }\n\n const packageName = packageNameForSpecifier(args.path);\n\n if (!allowedPackages.has(packageName)) {\n return {\n errors: [\n {\n text: importPolicyPackageError(options.label, packageName),\n },\n ],\n };\n }\n\n const resolvedPackage = resolvePackageSpecifier(args.path, args.resolveDir, options.appDir);\n\n if (resolvedPackage === undefined) {\n return undefined;\n }\n\n return options.externalizeAllowedPackages === false\n ? undefined\n : {\n external: true,\n path: pathToFileURL(resolvedPackage).href,\n };\n });\n },\n };\n}\n\nfunction resolvePackageSpecifier(\n specifier: string,\n resolveDir: string,\n appDir: string,\n): string | undefined {\n const baseDir = resolveDir === \"\" ? appDir : resolveDir;\n\n try {\n return createRequire(join(baseDir, \"__mreact_resolve__.cjs\")).resolve(specifier);\n } catch {\n return undefined;\n }\n}\n\nfunction importPolicyPackageError(label: string, packageName: string): string {\n const normalizedLabel = label.toLowerCase();\n const moduleKind =\n normalizedLabel.includes(\"loader\") ||\n normalizedLabel.includes(\"middleware\") ||\n normalizedLabel.includes(\"route\") ||\n normalizedLabel.includes(\"metadata\") ||\n normalizedLabel.includes(\"action\")\n ? normalizedLabel\n : `${normalizedLabel} module`;\n const aliasHint =\n packageName === \"~\" || packageName === \"@\"\n ? [\n \"\",\n 'This looks like an app-local alias import. Use a relative import such as \"./\" or \"../\" in server-side route code, or move the import behind a supported client boundary.',\n ]\n : [];\n\n return [\n `\"${packageName}\" is imported by a ${moduleKind} but is not allowed by the app-router import policy.`,\n \"\",\n \"The policy blocks server-side static imports from loader, middleware, route handler, metadata, and server action modules unless the package is explicitly allowed.\",\n ...aliasHint,\n \"\",\n \"Allow it in the Vite plugin config:\",\n \" mreactRouter({\",\n ` importPolicy: { allowedPackages: [${JSON.stringify(packageName)}] },`,\n \" })\",\n \"\",\n \"For production builds, also declare the package in package.json dependencies so mreact-router build can derive the generated policy and the package is installed in the runtime artifact.\",\n ].join(\"\\n\");\n}\n\nfunction workspacePackagePath(specifier: string, resolveDir: string): string | undefined {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const packageRoot = dirname(currentDir);\n const entries = new Map<\n string,\n string | { entry: string; monorepoDir: string; packageName: string }\n >([\n [\n \"@reckona/mreact-auth\",\n { entry: \"index\", monorepoDir: \"auth\", packageName: \"@reckona/mreact-auth\" },\n ],\n [\n \"@reckona/mreact-compiler\",\n { entry: \"index\", monorepoDir: \"compiler\", packageName: \"@reckona/mreact-compiler\" },\n ],\n [\n \"@reckona/mreact-query\",\n { entry: \"index\", monorepoDir: \"query\", packageName: \"@reckona/mreact-query\" },\n ],\n [\n \"@reckona/mreact-reactive-core\",\n {\n entry: \"index\",\n monorepoDir: \"reactive-core\",\n packageName: \"@reckona/mreact-reactive-core\",\n },\n ],\n [\n \"@reckona/mreact-router\",\n join(packageRoot, currentDir.endsWith(`${sep}dist`) ? \"dist/index.js\" : \"src/index.ts\"),\n ],\n [\n \"@reckona/mreact-router/app-router-globals\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`)\n ? \"dist/app-router-globals.js\"\n : \"src/app-router-globals.ts\",\n ),\n ],\n [\n \"@reckona/mreact-router/link\",\n join(packageRoot, currentDir.endsWith(`${sep}dist`) ? \"dist/link.js\" : \"src/link.ts\"),\n ],\n [\n \"@reckona/mreact-router/navigation-state\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`) ? \"dist/navigation-state.js\" : \"src/navigation-state.ts\",\n ),\n ],\n [\n \"@reckona/mreact-router/stream-list\",\n join(\n packageRoot,\n currentDir.endsWith(`${sep}dist`) ? \"dist/stream-list.js\" : \"src/stream-list.ts\",\n ),\n ],\n [\n \"@reckona/mreact-server\",\n { entry: \"index\", monorepoDir: \"server\", packageName: \"@reckona/mreact-server\" },\n ],\n ]);\n const entry = entries.get(specifier);\n\n if (entry === undefined || typeof entry === \"string\") {\n return entry;\n }\n\n return resolveWorkspacePackageFile({\n currentFileUrl: import.meta.url,\n entry: entry.entry,\n monorepoDir: entry.monorepoDir,\n packageName: entry.packageName,\n resolveDir,\n specifier,\n });\n}\n\nfunction isRelativeImport(path: string): boolean {\n return path === \".\" || path === \"..\" || path.startsWith(\"./\") || path.startsWith(\"../\");\n}\n\nfunction isAbsoluteOrProtocolImport(path: string): boolean {\n return path.startsWith(\"/\") || /^[A-Za-z][A-Za-z0-9+.-]*:/.test(path);\n}\n\nfunction packageNameForSpecifier(specifier: string): string {\n if (!specifier.startsWith(\"@\")) {\n return specifier.split(\"/\")[0] ?? specifier;\n }\n\n const [scope, name] = specifier.split(\"/\");\n\n return scope !== undefined && name !== undefined ? `${scope}/${name}` : specifier;\n}\n\nfunction isInsideDirectory(directory: string, candidate: string): boolean {\n const relativePath = relative(directory, candidate);\n\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !relativePath.startsWith(sep));\n}\n\nfunction isInsideAnyDirectory(directories: readonly string[], candidate: string): boolean {\n return directories.some((directory) => isInsideDirectory(directory, candidate));\n}\n"]}