@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.4

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 (192) hide show
  1. package/dist/agent-runtime.d.mts +2 -1
  2. package/dist/agent-runtime.d.ts +2 -1
  3. package/dist/api/route-manager.cjs +313 -10
  4. package/dist/api/route-manager.cjs.map +1 -1
  5. package/dist/api/route-manager.d.mts +3 -2
  6. package/dist/api/route-manager.d.ts +3 -2
  7. package/dist/api/route-manager.mjs +6 -5
  8. package/dist/api/runtime.cjs +313 -10
  9. package/dist/api/runtime.cjs.map +1 -1
  10. package/dist/api/runtime.d.mts +2 -1
  11. package/dist/api/runtime.d.ts +2 -1
  12. package/dist/api/runtime.mjs +4 -3
  13. package/dist/api.cjs +642 -57
  14. package/dist/api.cjs.map +1 -1
  15. package/dist/api.d.mts +3 -2
  16. package/dist/api.d.ts +3 -2
  17. package/dist/api.mjs +29 -9
  18. package/dist/{app-DOKxo-LH.d.ts → app-BjN-da13.d.ts} +38 -3
  19. package/dist/{app-BB3Iu3xh.d.mts → app-CakAr8Be.d.mts} +38 -3
  20. package/dist/app-markdown.d.mts +2 -1
  21. package/dist/app-markdown.d.ts +2 -1
  22. package/dist/cache.cjs +395 -12
  23. package/dist/cache.cjs.map +1 -1
  24. package/dist/cache.d.mts +100 -6
  25. package/dist/cache.d.ts +100 -6
  26. package/dist/cache.mjs +8 -2
  27. package/dist/{chunk-XUBZ7JI4.mjs → chunk-2CUKEMVR.mjs} +187 -16
  28. package/dist/chunk-2CUKEMVR.mjs.map +1 -0
  29. package/dist/{chunk-5QH4IKY3.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
  30. package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
  31. package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  32. package/dist/{chunk-OHC6VCDI.mjs → chunk-AJWRO5WE.mjs} +521 -42
  33. package/dist/chunk-AJWRO5WE.mjs.map +1 -0
  34. package/dist/chunk-ALCLXXTY.mjs +187 -0
  35. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  36. package/dist/{chunk-XJSHJN4M.mjs → chunk-AOBXKNS5.mjs} +593 -49
  37. package/dist/chunk-AOBXKNS5.mjs.map +1 -0
  38. package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
  39. package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
  40. package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
  41. package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
  42. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  43. package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
  44. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  45. package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
  46. package/dist/chunk-QM746KUO.mjs.map +1 -0
  47. package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
  48. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  49. package/dist/{chunk-MH6FKW2I.mjs → chunk-SADGIRS2.mjs} +3 -3
  50. package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
  51. package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
  52. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  53. package/dist/chunk-V3XURYJO.mjs +756 -0
  54. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  55. package/dist/{chunk-5FW6PQ3J.mjs → chunk-VVKWFZAH.mjs} +41 -16
  56. package/dist/chunk-VVKWFZAH.mjs.map +1 -0
  57. package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
  58. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  59. package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
  60. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  61. package/dist/{chunk-JNYVN7YP.mjs → chunk-W4UIVMVI.mjs} +2 -2
  62. package/dist/{chunk-JNYVN7YP.mjs.map → chunk-W4UIVMVI.mjs.map} +1 -1
  63. package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
  64. package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
  65. package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
  66. package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
  67. package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
  68. package/dist/client-plugins.d.mts +2 -1
  69. package/dist/client-plugins.d.ts +2 -1
  70. package/dist/client.cjs +665 -82
  71. package/dist/client.cjs.map +1 -1
  72. package/dist/client.d.mts +70 -4
  73. package/dist/client.d.ts +70 -4
  74. package/dist/client.mjs +10 -7
  75. package/dist/config.d.mts +2 -1
  76. package/dist/config.d.ts +2 -1
  77. package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
  78. package/dist/docs.cjs +11 -1
  79. package/dist/docs.cjs.map +1 -1
  80. package/dist/docs.mjs +4 -4
  81. package/dist/index.cjs +2112 -197
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.mts +12 -11
  84. package/dist/index.d.ts +12 -11
  85. package/dist/index.mjs +49 -21
  86. package/dist/index.mjs.map +1 -1
  87. package/dist/integrations.d.mts +2 -1
  88. package/dist/integrations.d.ts +2 -1
  89. package/dist/internal/build-runtime.cjs +1455 -90
  90. package/dist/internal/build-runtime.cjs.map +1 -1
  91. package/dist/internal/build-runtime.d.mts +4 -3
  92. package/dist/internal/build-runtime.d.ts +4 -3
  93. package/dist/internal/build-runtime.mjs +15 -14
  94. package/dist/internal/config-runtime.cjs +12 -1
  95. package/dist/internal/config-runtime.cjs.map +1 -1
  96. package/dist/internal/config-runtime.d.mts +3 -2
  97. package/dist/internal/config-runtime.d.ts +3 -2
  98. package/dist/internal/config-runtime.mjs +3 -3
  99. package/dist/internal/production-runtime.cjs +282 -6
  100. package/dist/internal/production-runtime.cjs.map +1 -1
  101. package/dist/internal/production-runtime.d.mts +4 -4
  102. package/dist/internal/production-runtime.d.ts +4 -4
  103. package/dist/internal/production-runtime.mjs +4 -2
  104. package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  105. package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  106. package/dist/middleware.d.mts +4 -3
  107. package/dist/middleware.d.ts +4 -3
  108. package/dist/navigation.cjs +40 -15
  109. package/dist/navigation.cjs.map +1 -1
  110. package/dist/navigation.mjs +2 -2
  111. package/dist/plugin.cjs +913 -53
  112. package/dist/plugin.cjs.map +1 -1
  113. package/dist/plugin.d.mts +2 -1
  114. package/dist/plugin.d.ts +2 -1
  115. package/dist/plugin.mjs +11 -10
  116. package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  117. package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  118. package/dist/routes.cjs +276 -6
  119. package/dist/routes.cjs.map +1 -1
  120. package/dist/routes.d.mts +1 -1
  121. package/dist/routes.d.ts +1 -1
  122. package/dist/routes.mjs +3 -3
  123. package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
  124. package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
  125. package/dist/server-action-security.cjs +28 -10
  126. package/dist/server-action-security.cjs.map +1 -1
  127. package/dist/server-action-security.d.mts +2 -1
  128. package/dist/server-action-security.d.ts +2 -1
  129. package/dist/server-action-security.mjs +2 -2
  130. package/dist/server-fn-client.d.mts +1 -0
  131. package/dist/server-fn-client.d.ts +1 -0
  132. package/dist/server-fn.cjs +785 -3
  133. package/dist/server-fn.cjs.map +1 -1
  134. package/dist/server-fn.d.mts +10 -1
  135. package/dist/server-fn.d.ts +10 -1
  136. package/dist/server-fn.mjs +6 -3
  137. package/dist/server-plugins.d.mts +3 -2
  138. package/dist/server-plugins.d.ts +3 -2
  139. package/dist/server-query-client.cjs +278 -7
  140. package/dist/server-query-client.cjs.map +1 -1
  141. package/dist/server-query-client.mjs +4 -4
  142. package/dist/server-query.cjs +381 -10
  143. package/dist/server-query.cjs.map +1 -1
  144. package/dist/server-query.mjs +5 -5
  145. package/dist/server.cjs +1086 -76
  146. package/dist/server.cjs.map +1 -1
  147. package/dist/server.d.mts +8 -7
  148. package/dist/server.d.ts +8 -7
  149. package/dist/server.mjs +31 -16
  150. package/dist/server.mjs.map +1 -1
  151. package/dist/testing.cjs +341 -20
  152. package/dist/testing.cjs.map +1 -1
  153. package/dist/testing.d.mts +3 -2
  154. package/dist/testing.d.ts +3 -2
  155. package/dist/testing.mjs +7 -6
  156. package/dist/testing.mjs.map +1 -1
  157. package/dist/transport-BmbGTXA5.d.mts +49 -0
  158. package/dist/transport-BmbGTXA5.d.ts +49 -0
  159. package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  160. package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  161. package/dist/version.cjs +1 -1
  162. package/dist/version.cjs.map +1 -1
  163. package/dist/version.mjs +1 -1
  164. package/dist/vite.cjs +914 -54
  165. package/dist/vite.cjs.map +1 -1
  166. package/dist/vite.d.mts +2 -1
  167. package/dist/vite.d.ts +2 -1
  168. package/dist/vite.mjs +11 -10
  169. package/package.json +1 -1
  170. package/types/api.d.ts +44 -0
  171. package/types/client.d.ts +85 -4
  172. package/dist/chunk-45LKHSHJ.mjs.map +0 -1
  173. package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
  174. package/dist/chunk-6VS6CKAV.mjs.map +0 -1
  175. package/dist/chunk-C33RALN7.mjs.map +0 -1
  176. package/dist/chunk-GZWT6VI5.mjs +0 -382
  177. package/dist/chunk-GZWT6VI5.mjs.map +0 -1
  178. package/dist/chunk-HZYXGV4K.mjs.map +0 -1
  179. package/dist/chunk-LWMGIEJA.mjs.map +0 -1
  180. package/dist/chunk-OHC6VCDI.mjs.map +0 -1
  181. package/dist/chunk-SHRJG6OG.mjs.map +0 -1
  182. package/dist/chunk-T543TMFY.mjs.map +0 -1
  183. package/dist/chunk-XJSHJN4M.mjs.map +0 -1
  184. package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
  185. /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-3U3ZUQAQ.mjs.map} +0 -0
  186. /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  187. /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
  188. /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
  189. /package/dist/{chunk-MH6FKW2I.mjs.map → chunk-SADGIRS2.mjs.map} +0 -0
  190. /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  191. /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  192. /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/api/route-manager.ts","../../src/utils.ts","../../src/routes.ts","../../src/observability.ts","../../src/cache-invalidation.ts","../../src/i18n/bridge.ts","../../src/cache.ts","../../src/route-runtime.ts","../../src/routes.server.ts","../../src/i18n/server.ts","../../src/i18n/runtime.ts","../../src/i18n/catalog.ts","../../src/i18n/config.ts","../../src/server/request.ts","../../src/server/request-bridge.ts","../../src/api/endpoint.ts","../../src/api/runtime.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { ViteDevServer } from \"vite\";\nimport { logger } from \"../utils\";\nimport {\n createProgrammaticRouteModuleId,\n getProgrammaticRouteManifest,\n type ProgrammaticApiRoute,\n} from \"../routes\";\nimport { findProgrammaticRouteFilesInDir } from \"../routes.server\";\nimport {\n getFarmRouteRuntimeConfig,\n normalizeFarmRouteRuntimeConfig,\n type FarmRouteRuntimeConfig,\n} from \"../route-runtime\";\nimport { _runWithFarmI18nRequest, type FarmI18nRuntime } from \"../i18n/server\";\nimport { invokeAPIRouteEndpoint, matchAPIRoute, type APIRouteMatch } from \"./runtime\";\n\nexport interface APIRoute extends FarmRouteRuntimeConfig {\n path: string;\n filePath: string;\n methods: string[];\n endpoints: Record<string, any>;\n}\n\nexport interface APIRouteManagerOptions {\n throwOnLoadError?: boolean;\n i18n?: FarmI18nRuntime;\n}\n\nexport const API_ROUTE_METHODS = [\n \"GET\",\n \"HEAD\",\n \"POST\",\n \"PUT\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n] as const;\n\nexport class APIRouteManager {\n private routes: Map<string, APIRoute> = new Map();\n private viteServer?: ViteDevServer;\n private appDirs: string[];\n private throwOnLoadError: boolean;\n private i18n?: FarmI18nRuntime;\n\n constructor(\n appDir: string | readonly string[],\n viteServer?: ViteDevServer,\n options: APIRouteManagerOptions = {},\n ) {\n this.appDirs = Array.isArray(appDir) ? [...appDir] : [appDir as string];\n this.viteServer = viteServer;\n this.throwOnLoadError = options.throwOnLoadError === true;\n this.i18n = options.i18n;\n }\n\n /**\n * Discover route.ts files in /app/api and explicit endpoints in root routes.ts\n */\n async discoverRoutes(): Promise<void> {\n this.routes.clear();\n\n for (const appDir of this.appDirs) {\n const apiDir = path.join(appDir, \"api\");\n let routeFiles: string[] = [];\n\n if (fs.existsSync(apiDir)) {\n routeFiles = this.findRouteFiles(apiDir);\n }\n\n for (const filePath of routeFiles) {\n await this.loadRoute(filePath, appDir);\n }\n\n await this.loadRootRoutes(appDir);\n await this.loadProgrammaticApiRoutes(appDir);\n }\n\n if (process.env.FARM_VERBOSE) {\n logger.success(`Discovered ${this.routes.size} API routes`);\n for (const [routePath, route] of this.routes) {\n logger.info(` ${route.methods.join(\", \")} ${routePath}`);\n }\n }\n }\n\n /**\n * Recursively find all route.ts files\n */\n private findRouteFiles(dir: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...this.findRouteFiles(fullPath));\n } else if (\n entry.name === \"route.ts\" ||\n entry.name === \"route.tsx\" ||\n entry.name === \"route.js\"\n ) {\n files.push(fullPath);\n }\n }\n\n return files;\n }\n\n /**\n * Load a route.ts file and extract HTTP method exports\n */\n private async loadRoute(filePath: string, appDir: string): Promise<void> {\n try {\n // Convert file path to API route path\n // /app/api/auth/login/route.ts -> /api/auth/login\n const apiDir = path.join(appDir, \"api\");\n const relativePath = path.relative(apiDir, path.dirname(filePath));\n const routePath = \"/api/\" + (relativePath === \".\" ? \"\" : relativePath.replace(/\\\\/g, \"/\"));\n\n const routeModule = await this.loadModule(filePath);\n\n const endpoints: Record<string, any> = {};\n const availableMethods: string[] = [];\n\n for (const method of API_ROUTE_METHODS) {\n if (routeModule[method]) {\n endpoints[method] = routeModule[method];\n availableMethods.push(method);\n }\n }\n\n if (availableMethods.length > 0) {\n const runtimeConfig = normalizeFarmRouteRuntimeConfig(\n getFarmRouteRuntimeConfig(routeModule),\n `API route \"${routePath}\"`,\n );\n this.routes.set(routePath, {\n path: routePath,\n filePath,\n methods: availableMethods,\n endpoints,\n ...runtimeConfig,\n });\n }\n } catch (error) {\n this.handleLoadError(`Error loading route ${filePath}`, error);\n }\n }\n\n /**\n * Load explicit-path endpoints from src/routes.ts-style files.\n */\n private async loadRootRoutes(appDir: string): Promise<void> {\n const routesFile = this.findRootRoutesFile(appDir);\n if (!routesFile) {\n return;\n }\n\n try {\n const routesModule = await this.loadModule(routesFile);\n\n for (const exportValue of Object.values(routesModule)) {\n const endpoint = exportValue as any;\n if (!endpoint?.__path) {\n continue;\n }\n\n const method = String(endpoint.__method || \"GET\").toUpperCase();\n this.addEndpoint(endpoint.__path, routesFile, method, endpoint);\n }\n } catch (error) {\n this.handleLoadError(`Error loading root API routes ${routesFile}`, error);\n }\n }\n\n private async loadProgrammaticApiRoutes(appDir: string): Promise<void> {\n const candidateRoots = [path.dirname(appDir), appDir];\n const routeFiles = Array.from(\n new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot))),\n );\n\n for (const routeFile of routeFiles) {\n try {\n const routesModule = await this.loadModule(routeFile);\n const manifest = getProgrammaticRouteManifest(routesModule);\n if (!manifest) continue;\n\n for (const definition of manifest.routes) {\n if (definition.kind !== \"api\") continue;\n this.addProgrammaticApiRoute(routeFile, definition);\n }\n } catch (error) {\n this.handleLoadError(`Error loading programmatic API routes ${routeFile}`, error);\n }\n }\n }\n\n private handleLoadError(message: string, error: unknown): void {\n logger.error(`${message}: ${error}`);\n if (this.throwOnLoadError) {\n throw error;\n }\n }\n\n private findRootRoutesFile(appDir: string): string | null {\n const routeNames = [\"routes.ts\", \"routes.tsx\", \"routes.js\"];\n const candidateDirs = [path.dirname(appDir), appDir];\n const seen = new Set<string>();\n\n for (const dir of candidateDirs) {\n for (const routeName of routeNames) {\n const routesFile = path.join(dir, routeName);\n if (seen.has(routesFile)) {\n continue;\n }\n seen.add(routesFile);\n\n if (fs.existsSync(routesFile)) {\n return routesFile;\n }\n }\n }\n\n return null;\n }\n\n private async loadModule(filePath: string): Promise<Record<string, unknown>> {\n if (this.viteServer) {\n return await this.viteServer.ssrLoadModule(filePath);\n }\n\n const fileUrl = `file://${filePath}`;\n return await import(/* @vite-ignore */ fileUrl);\n }\n\n private addEndpoint(\n routePath: string,\n filePath: string,\n method: string,\n endpoint: any,\n runtimeConfig: FarmRouteRuntimeConfig = {},\n ): void {\n const normalizedMethod = method.toUpperCase();\n const existingRoute = this.routes.get(routePath);\n\n if (existingRoute) {\n if (!existingRoute.methods.includes(normalizedMethod)) {\n existingRoute.methods.push(normalizedMethod);\n }\n existingRoute.endpoints[normalizedMethod] = endpoint;\n Object.assign(existingRoute, runtimeConfig);\n return;\n }\n\n this.routes.set(routePath, {\n path: routePath,\n filePath,\n methods: [normalizedMethod],\n endpoints: { [normalizedMethod]: endpoint },\n ...runtimeConfig,\n });\n }\n\n private addProgrammaticApiRoute(filePath: string, route: ProgrammaticApiRoute): void {\n const modulePath = createProgrammaticRouteModuleId(filePath, \"api\", route.path);\n const runtimeConfig = normalizeFarmRouteRuntimeConfig(route, `API route \"${route.path}\"`);\n for (const [method, endpoint] of Object.entries(route.methods)) {\n if (endpoint) {\n this.addEndpoint(route.path, modulePath, method, endpoint, runtimeConfig);\n }\n }\n }\n\n /**\n * Get the handler that directly invokes endpoint handlers\n */\n getHandler(): ((req: Request) => Promise<Response>) | null {\n if (this.routes.size === 0) {\n return null;\n }\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n const pathname = url.pathname;\n const method = request.method.toUpperCase();\n\n // Find matching route\n const match = matchAPIRoute(this.routes, pathname);\n if (!match) {\n return new Response(JSON.stringify({ error: \"Not Found\" }), {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // Check if method is supported\n const { route, params } = match;\n const endpoint = route.endpoints[method];\n if (!endpoint) {\n return new Response(JSON.stringify({ error: \"Method Not Allowed\" }), {\n status: 405,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n const invoke = async () => {\n try {\n return await invokeAPIRouteEndpoint(endpoint, request, params);\n } catch (error: any) {\n console.error(`[API Error] ${pathname}:`, error);\n return new Response(JSON.stringify({ error: \"Internal Server Error\" }), {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n };\n\n return this.i18n?.config.enabled\n ? _runWithFarmI18nRequest(this.i18n, request, invoke, {\n redirect: false,\n })\n : invoke();\n };\n }\n\n /**\n * Check if a path is an API route\n */\n isAPIRoute(pathname: string): boolean {\n return Boolean(this.matchRoute(pathname));\n }\n\n matchRoute(pathname: string): APIRouteMatch<APIRoute> | null {\n return matchAPIRoute(this.routes, pathname);\n }\n\n /**\n * Get all routes for client type generation\n */\n getRoutes(): Map<string, APIRoute> {\n return this.routes;\n }\n}\n\nexport {\n invokeAPIRouteEndpoint,\n isWebResponse,\n matchAPIRoute,\n normalizeRouteResponse,\n} from \"./runtime\";\nexport type { APIRouteMatch, APIRouteParams, APIRouteParamValue } from \"./runtime\";\n","import type { RouteSegment, ParsedRoute } from \"./types\";\nimport path from \"path\";\n\nexport function parseRoutePath(filePath: string): ParsedRoute {\n const segments: RouteSegment[] = [];\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n const pathParts = normalizedPath.split(\"/\").filter(Boolean);\n\n const fileName = pathParts.pop() || \"\";\n const fileType = getRouteType(fileName);\n\n for (const part of pathParts) {\n if (part.startsWith(\"[\") && part.endsWith(\"]\")) {\n let segment = part.slice(1, -1);\n const isDynamic = true;\n let isOptional = false;\n let isCatchAll = false;\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n isOptional = true;\n segment = segment.slice(1, -1);\n if (segment.startsWith(\"...\")) {\n segment = segment.slice(3);\n isCatchAll = true;\n }\n } else if (segment.startsWith(\"...\")) {\n segment = segment.slice(3);\n isCatchAll = true;\n }\n\n segments.push({ segment, isDynamic, isOptional, isCatchAll });\n } else {\n segments.push({\n segment: part,\n isDynamic: false,\n isOptional: false,\n isCatchAll: false,\n });\n }\n }\n\n return {\n segments,\n filePath: normalizedPath,\n type: fileType,\n };\n}\n\nfunction getRouteType(fileName: string): ParsedRoute[\"type\"] {\n const baseName = fileName.replace(/\\.(tsx?|jsx?|mdx?|markdown)$/, \"\");\n\n switch (baseName) {\n case \"page\":\n return \"page\";\n case \"layout\":\n return \"layout\";\n case \"loading\":\n return \"loading\";\n case \"error\":\n return \"error\";\n case \"not-found\":\n return \"not-found\";\n default:\n return \"page\";\n }\n}\n\nexport function segmentsToPattern(segments: RouteSegment[]): string {\n if (segments.length === 0) return \"/\";\n\n return (\n \"/\" +\n segments\n .map((segment) => {\n if (!segment.isDynamic) return segment.segment;\n\n if (segment.isCatchAll) {\n return segment.isOptional ? `*${segment.segment}?` : `*${segment.segment}`;\n }\n\n return `:${segment.segment}`;\n })\n .join(\"/\")\n );\n}\n\nexport function matchRoute(\n url: string,\n segments: RouteSegment[],\n): { params: Record<string, string>; matches: boolean } {\n const urlParts = url.split(\"/\").filter(Boolean);\n const params: Record<string, string> = {};\n if (segments.length === 0) {\n return { params, matches: urlParts.length === 0 };\n }\n\n let urlIndex = 0;\n let segmentIndex = 0;\n\n while (segmentIndex < segments.length && urlIndex <= urlParts.length) {\n const segment = segments[segmentIndex];\n\n if (!segment.isDynamic) {\n if (urlParts[urlIndex] !== segment.segment) {\n return { params: {}, matches: false };\n }\n urlIndex++;\n segmentIndex++;\n } else if (segment.isCatchAll) {\n const remainingParts = urlParts.slice(urlIndex);\n\n if (remainingParts.length === 0 && !segment.isOptional) {\n return { params: {}, matches: false };\n }\n\n params[segment.segment] = remainingParts.join(\"/\");\n urlIndex = urlParts.length;\n segmentIndex++;\n } else {\n if (urlIndex >= urlParts.length) {\n return { params: {}, matches: false };\n }\n\n params[segment.segment] = urlParts[urlIndex];\n urlIndex++;\n segmentIndex++;\n }\n }\n\n const matches = segmentIndex === segments.length && urlIndex === urlParts.length;\n\n return { params, matches };\n}\n\nexport function resolveAppPath(root: string, ...paths: string[]): string {\n return path.resolve(root, ...paths);\n}\n\nexport function toViteModuleId(filePath: string, root: string): string {\n if (!path.isAbsolute(filePath)) return filePath;\n\n const relativePath = path.relative(root, filePath);\n if (relativePath && !relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath)) {\n return `/${relativePath.split(path.sep).join(\"/\")}`;\n }\n\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n return normalizedPath.startsWith(\"/\") ? `/@fs${normalizedPath}` : `/@fs/${normalizedPath}`;\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const fs = await import(\"fs/promises\");\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function globFiles(pattern: string, cwd: string): Promise<string[]> {\n const glob = await import(\"fast-glob\");\n return glob.default(pattern, { cwd, absolute: false });\n}\n\nexport function parseSearchParams(\n searchParams: URLSearchParams,\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n\n for (const [key, value] of searchParams.entries()) {\n if (key in result) {\n const existing = result[key];\n if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n result[key] = [existing, value];\n }\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport const logger = {\n info: (message: string) => console.log(`[info] ${message}`),\n success: (message: string) => console.log(`[success] ${message}`),\n warn: (message: string) => console.warn(`⚠️ ${message}`),\n error: (message: string) => console.error(`❌ ${message}`),\n ready: (message: string) => console.log(`${message}`),\n event: (message: string) => console.log(` ${message}`),\n};\n","import { Suspense, createElement, type ComponentType } from \"react\";\nimport {\n createFarmCacheKey,\n createRouteDataCacheTag,\n getFarmDataCache,\n type FarmCacheOptions,\n type RouteDataCacheKey,\n} from \"./cache\";\nimport { getFarmRouteContext } from \"./route-context\";\nimport { normalizeFarmRouteRuntimeConfig, type FarmRouteRuntimeConfig } from \"./route-runtime\";\nimport type {\n FarmAppContext,\n LayoutProps,\n Metadata,\n PageProps,\n ParsedRoute,\n PluginContextProps,\n RouteModule,\n} from \"./types\";\n\nexport type ProgrammaticRouteRenderMode = \"static\" | \"dynamic\";\nexport type ProgrammaticRouteMethod =\n | \"GET\"\n | \"HEAD\"\n | \"POST\"\n | \"PUT\"\n | \"DELETE\"\n | \"PATCH\"\n | \"OPTIONS\";\n\nexport type ProgrammaticRoutePrimitive = string | number | boolean;\nexport type ProgrammaticStaticPathParams = Record<\n string,\n ProgrammaticRoutePrimitive | readonly ProgrammaticRoutePrimitive[]\n>;\nexport type ProgrammaticStaticPath =\n | string\n | readonly ProgrammaticRoutePrimitive[]\n | ProgrammaticStaticPathParams;\nexport type ProgrammaticStaticPaths = () =>\n | readonly ProgrammaticStaticPath[]\n | Promise<readonly ProgrammaticStaticPath[]>;\n\nexport interface ProgrammaticRouteSchema<TOutput = unknown> {\n parse(value: unknown): TOutput;\n}\n\nexport interface ProgrammaticRouteSearchOptions<TOutput = ProgrammaticRouteSearchFallback> {\n schema?: ProgrammaticRouteSchema<TOutput>;\n stripDefaults?: boolean | readonly string[];\n preserve?: readonly string[];\n temporary?: readonly string[];\n}\n\nexport type ProgrammaticRouteSearchConfig<TOutput = ProgrammaticRouteSearchFallback> =\n | ProgrammaticRouteSchema<TOutput>\n | ProgrammaticRouteSearchOptions<TOutput>;\n\nexport type InferProgrammaticRouteSchema<TSchema, TFallback> =\n TSchema extends ProgrammaticRouteSchema<infer TOutput> ? TOutput : TFallback;\n\nexport type InferProgrammaticRouteSearch<TSearch, TFallback> =\n TSearch extends ProgrammaticRouteSearchOptions<infer TOutput>\n ? TOutput\n : TSearch extends ProgrammaticRouteSchema<infer TOutput>\n ? TOutput\n : TFallback;\n\nexport type ProgrammaticRouteParamsFallback = Record<string, string>;\nexport type ProgrammaticRouteSearchFallback = Record<string, string | string[] | undefined>;\nexport type ProgrammaticRouteMaybePromise<T> = T | Promise<T>;\nexport type ProgrammaticRouteDataStaleTime =\n | number\n | false\n | `${number}ms`\n | `${number}s`\n | `${number}m`\n | `${number}h`;\nexport type ProgrammaticRouteContext = keyof FarmAppContext extends never\n ? unknown\n : FarmAppContext;\n\nexport type ProgrammaticRouteComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TData = undefined,\n> = Omit<PageProps, \"params\" | \"searchParams\"> & {\n params: TParams;\n search: TSearch;\n searchParams: Promise<TSearch>;\n} & ([TData] extends [undefined] ? { data?: undefined } : { data: TData });\n\nexport type ProgrammaticRouteDataContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = Omit<ProgrammaticRouteComponentProps<TParams, TSearch>, \"context\" | \"data\"> & {\n context: TContext;\n pluginContext?: PluginContextProps;\n};\n\nexport type ProgrammaticRouteDataCacheContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TContext = ProgrammaticRouteContext,\n> = ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: TBefore;\n};\n\nexport type ProgrammaticRouteGuardContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = ProgrammaticRouteDataContext<TParams, TSearch, TContext>;\n\nexport type ProgrammaticRouteGuard<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = (\n context: ProgrammaticRouteGuardContext<TParams, TSearch, TContext>,\n) => ProgrammaticRouteMaybePromise<void>;\n\nexport type ProgrammaticRouteErrorComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n> = Partial<ProgrammaticRouteComponentProps<TParams, TSearch>> & {\n error: unknown;\n};\n\nexport type ProgrammaticRoutePendingComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n> = Partial<ProgrammaticRouteComponentProps<TParams, TSearch>>;\n\nexport type ProgrammaticRouteDataCacheKeys<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TContext = ProgrammaticRouteContext,\n> =\n | readonly string[]\n | ((\n context: ProgrammaticRouteDataCacheContext<TParams, TSearch, TBefore, TContext>,\n ) => ProgrammaticRouteMaybePromise<readonly string[]>);\n\nexport interface ProgrammaticRouteDataHooks<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TData = unknown,\n TContext = ProgrammaticRouteContext,\n> {\n key?: (\n context: ProgrammaticRouteDataCacheContext<TParams, TSearch, NoInfer<TBefore>, TContext>,\n ) => ProgrammaticRouteMaybePromise<RouteDataCacheKey | null | undefined>;\n staleTime?: ProgrammaticRouteDataStaleTime;\n tags?: ProgrammaticRouteDataCacheKeys<TParams, TSearch, NoInfer<TBefore>, TContext>;\n paths?: ProgrammaticRouteDataCacheKeys<TParams, TSearch, NoInfer<TBefore>, TContext>;\n before?: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext>,\n ) => ProgrammaticRouteMaybePromise<TBefore>;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<TBefore>;\n },\n ) => ProgrammaticRouteMaybePromise<TData>;\n after?: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<TBefore>;\n data: NoInfer<TData>;\n },\n ) => ProgrammaticRouteMaybePromise<void>;\n}\n\nexport type InferProgrammaticRouteData<TDataHooks> = TDataHooks extends {\n main: (...args: any[]) => infer TResult;\n}\n ? Awaited<TResult>\n : undefined;\n\nexport interface ProgrammaticPageRoute<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TDataHooks extends ProgrammaticRouteDataHooks<TParams, TSearch, any, any, any> | undefined =\n | ProgrammaticRouteDataHooks<TParams, TSearch, any, any, any>\n | undefined,\n TContext = ProgrammaticRouteContext,\n> extends FarmRouteRuntimeConfig {\n kind: \"page\";\n path: string;\n component: ComponentType<any>;\n params?: ProgrammaticRouteSchema<TParams>;\n search?: ProgrammaticRouteSearchConfig<TSearch>;\n guard?: ProgrammaticRouteGuard<TParams, TSearch, TContext>;\n data?: TDataHooks;\n pending?: ComponentType<ProgrammaticRoutePendingComponentProps<TParams, TSearch>>;\n error?: ComponentType<ProgrammaticRouteErrorComponentProps<TParams, TSearch>>;\n notFound?: ComponentType<ProgrammaticRouteErrorComponentProps<TParams, TSearch>>;\n render?: ProgrammaticRouteRenderMode;\n staticPaths?: ProgrammaticStaticPaths;\n revalidate?: number | false;\n ppr?: boolean;\n metadata?: Metadata & Record<string, any>;\n generateMetadata?: RouteModule[\"generateMetadata\"];\n}\n\nexport interface ProgrammaticLayoutRoute extends FarmRouteRuntimeConfig {\n kind: \"layout\";\n path: string;\n component: ComponentType<LayoutProps>;\n metadata?: Metadata & Record<string, any>;\n generateMetadata?: (props: { params: Record<string, string> }) => Promise<Metadata> | Metadata;\n}\n\nexport type ProgrammaticApiRouteOptions = Partial<Record<ProgrammaticRouteMethod, any>> & {\n render?: ProgrammaticRouteRenderMode;\n} & FarmRouteRuntimeConfig;\n\nexport interface ProgrammaticApiRoute extends FarmRouteRuntimeConfig {\n kind: \"api\";\n path: string;\n methods: Partial<Record<ProgrammaticRouteMethod, any>>;\n render?: ProgrammaticRouteRenderMode;\n}\n\nexport interface ProgrammaticRedirectRoute {\n kind: \"redirect\";\n source: string;\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n}\n\nexport type ProgrammaticRouteDefinition =\n | ProgrammaticPageRoute<any, any>\n | ProgrammaticLayoutRoute\n | ProgrammaticApiRoute\n | ProgrammaticRedirectRoute;\n\nexport interface ProgrammaticRouteManifest {\n readonly __farmRoutes: true;\n routes: ProgrammaticRouteDefinition[];\n}\n\nexport interface ProgrammaticRouteBuilder {\n page(\n path: string,\n options: Omit<ProgrammaticPageRoute<any, any>, \"kind\" | \"path\">,\n ): ProgrammaticPageRoute;\n layout(\n path: string,\n options: Omit<ProgrammaticLayoutRoute, \"kind\" | \"path\">,\n ): ProgrammaticLayoutRoute;\n api(path: string, options: ProgrammaticApiRouteOptions): ProgrammaticApiRoute;\n redirect(\n source: string,\n destination: string,\n options?: Omit<ProgrammaticRedirectRoute, \"kind\" | \"source\" | \"destination\">,\n ): ProgrammaticRedirectRoute;\n}\n\nexport type ProgrammaticRouteFactory = (\n builder: ProgrammaticRouteBuilder,\n) => readonly ProgrammaticRouteDefinition[];\n\ntype CreateRouteParams<TParamsSchema> = InferProgrammaticRouteSchema<\n TParamsSchema,\n ProgrammaticRouteParamsFallback\n>;\n\ntype CreateRouteSearch<TSearchConfig> = InferProgrammaticRouteSearch<\n TSearchConfig,\n ProgrammaticRouteSearchFallback\n>;\n\ntype CreateRouteSharedOptions<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n> = Omit<\n ProgrammaticPageRoute<CreateRouteParams<TParamsSchema>, CreateRouteSearch<TSearchConfig>>,\n \"kind\" | \"path\" | \"component\" | \"params\" | \"search\" | \"data\" | \"guard\"\n> & {\n params?: TParamsSchema;\n search?: TSearchConfig;\n guard?: ProgrammaticRouteGuard<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>\n >;\n};\n\ntype CreateRouteDataHooksWithBefore<\n TParams,\n TSearch,\n TBeforeResult,\n TMainResult,\n TContext = ProgrammaticRouteContext,\n> = Omit<\n ProgrammaticRouteDataHooks<\n TParams,\n TSearch,\n NoInfer<Awaited<TBeforeResult>>,\n NoInfer<Awaited<TMainResult>>,\n TContext\n >,\n \"before\" | \"main\"\n> & {\n before: (context: ProgrammaticRouteDataContext<TParams, TSearch, TContext>) => TBeforeResult;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<Awaited<TBeforeResult>>;\n },\n ) => TMainResult;\n};\n\ntype CreateRouteDataHooksWithoutBefore<\n TParams,\n TSearch,\n TMainResult,\n TContext = ProgrammaticRouteContext,\n> = Omit<\n ProgrammaticRouteDataHooks<TParams, TSearch, undefined, NoInfer<Awaited<TMainResult>>, TContext>,\n \"before\" | \"main\"\n> & {\n before?: undefined;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: undefined;\n },\n ) => TMainResult;\n};\n\ntype CreateRouteOptionsWithBefore<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n TBefore,\n TData,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data: CreateRouteDataHooksWithBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TBefore,\n TData\n >;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n NoInfer<Awaited<TData>>\n >\n >;\n};\n\ntype CreateRouteOptionsWithoutBefore<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n TData,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data: CreateRouteDataHooksWithoutBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TData\n >;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n NoInfer<Awaited<TData>>\n >\n >;\n};\n\ntype CreateRouteOptionsWithoutData<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data?: undefined;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n undefined\n >\n >;\n};\n\ntype CreateRouteComponentOption<TComponent extends ComponentType<any>, TProps> = {\n component: TComponent;\n} & (TComponent extends ComponentType<TProps> ? unknown : { component: ComponentType<TProps> });\n\nexport type CreateRouteOptions<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TBefore = unknown,\n TData = unknown,\n> =\n | CreateRouteOptionsWithBefore<TParamsSchema, TSearchConfig, TBefore, TData>\n | CreateRouteOptionsWithoutBefore<TParamsSchema, TSearchConfig, TData>\n | CreateRouteOptionsWithoutData<TParamsSchema, TSearchConfig>;\n\nconst FARM_ROUTES_BRAND = Symbol.for(\"farm.routes\");\nexport const PROGRAMMATIC_ROUTE_FILE_NAMES = [\n \"farm.route.ts\",\n \"farm.route.tsx\",\n \"farm.route.js\",\n \"farm.route.jsx\",\n \"farm.routes.ts\",\n \"farm.routes.tsx\",\n \"farm.routes.js\",\n \"farm.routes.jsx\",\n \"routes.ts\",\n \"routes.tsx\",\n \"routes.js\",\n \"routes.jsx\",\n];\n\nexport function defineRoutes(\n input: readonly ProgrammaticRouteDefinition[] | ProgrammaticRouteFactory,\n): ProgrammaticRouteManifest {\n const routes = typeof input === \"function\" ? input(routesBuilder) : input;\n const manifest = {\n __farmRoutes: true as const,\n routes: routes.map(normalizeProgrammaticRoute),\n };\n\n Object.defineProperty(manifest, FARM_ROUTES_BRAND, {\n value: true,\n enumerable: false,\n });\n\n return manifest;\n}\n\nexport const routesBuilder: ProgrammaticRouteBuilder = {\n page(path, options) {\n return normalizeProgrammaticRoute({\n kind: \"page\",\n path,\n ...options,\n }) as ProgrammaticPageRoute;\n },\n layout(path, options) {\n return normalizeProgrammaticRoute({\n kind: \"layout\",\n path,\n ...options,\n }) as ProgrammaticLayoutRoute;\n },\n api(path, options) {\n const { render, runtime, regions, maxDuration, ...methods } = options;\n return normalizeProgrammaticRoute({\n kind: \"api\",\n path,\n render,\n runtime,\n regions,\n maxDuration,\n methods: normalizeApiMethods(methods),\n }) as ProgrammaticApiRoute;\n },\n redirect(source, destination, options = {}) {\n return normalizeProgrammaticRoute({\n kind: \"redirect\",\n source,\n destination,\n ...options,\n }) as ProgrammaticRedirectRoute;\n },\n};\n\nexport const page = routesBuilder.page;\nexport const layout = routesBuilder.layout;\nexport const api = routesBuilder.api;\nexport const redirect = routesBuilder.redirect;\n\nexport interface ProgrammaticRouteSearchClientOptions {\n stripDefaults?: boolean | readonly string[];\n preserve?: readonly string[];\n temporary?: readonly string[];\n}\n\nexport interface ProgrammaticRouteSearchResolution<TSearch = unknown> {\n search: TSearch;\n canonicalPath?: string;\n}\n\nexport function getProgrammaticRouteSearchSchema<TSearch = unknown>(\n search: ProgrammaticRouteSearchConfig<TSearch> | undefined,\n): ProgrammaticRouteSchema<TSearch> | undefined {\n if (!search) return undefined;\n if (isProgrammaticRouteSchema(search)) return search;\n return search.schema;\n}\n\nexport function getProgrammaticRouteSearchClientOptions(\n search: ProgrammaticRouteSearchConfig<any> | undefined,\n): ProgrammaticRouteSearchClientOptions | undefined {\n if (!search || isProgrammaticRouteSchema(search)) return undefined;\n\n const options: ProgrammaticRouteSearchClientOptions = {};\n if (typeof search.stripDefaults !== \"undefined\") options.stripDefaults = search.stripDefaults;\n if (search.preserve?.length) options.preserve = [...search.preserve];\n if (search.temporary?.length) options.temporary = [...search.temporary];\n\n return Object.keys(options).length > 0 ? options : undefined;\n}\n\nfunction resolveProgrammaticRouteSearch<TSearch>(\n searchConfig: ProgrammaticRouteSearchConfig<TSearch> | undefined,\n rawSearch: ProgrammaticRouteSearchFallback,\n path: string,\n routePath: string,\n): ProgrammaticRouteSearchResolution<TSearch | ProgrammaticRouteSearchFallback> {\n const schema = getProgrammaticRouteSearchSchema(searchConfig);\n const search = parseProgrammaticSchema(schema, rawSearch, \"search\", routePath) as\n | TSearch\n | ProgrammaticRouteSearchFallback;\n const options = getProgrammaticRouteSearchOptions(searchConfig);\n const canonicalPath = resolveProgrammaticRouteCanonicalPath({\n options,\n schema,\n rawSearch,\n parsedSearch: search,\n path,\n });\n\n return { search, canonicalPath };\n}\n\nfunction getProgrammaticRouteSearchOptions(\n search: ProgrammaticRouteSearchConfig<any> | undefined,\n): ProgrammaticRouteSearchOptions<any> | undefined {\n if (!search || isProgrammaticRouteSchema(search)) return undefined;\n return search;\n}\n\nfunction isProgrammaticRouteSchema(value: unknown): value is ProgrammaticRouteSchema<any> {\n return !!value && typeof value === \"object\" && typeof (value as any).parse === \"function\";\n}\n\nfunction resolveProgrammaticRouteCanonicalPath(input: {\n options: ProgrammaticRouteSearchOptions<any> | undefined;\n schema: ProgrammaticRouteSchema<any> | undefined;\n rawSearch: ProgrammaticRouteSearchFallback;\n parsedSearch: unknown;\n path: string;\n}): string | undefined {\n const options = input.options;\n if (!options?.temporary?.length && !options?.stripDefaults) {\n return undefined;\n }\n\n const params = createSearchParams(input.rawSearch);\n const original = params.toString();\n\n for (const key of options.temporary || []) {\n params.delete(key);\n }\n\n if (options.stripDefaults) {\n const defaultSearch = parseDefaultSearch(input.schema);\n if (defaultSearch !== undefined) {\n const keys =\n options.stripDefaults === true\n ? Array.from(new Set(Array.from(params.keys())))\n : [...options.stripDefaults];\n\n for (const key of keys) {\n if (\n params.has(key) &&\n searchValuesEqual(\n readSearchValue(input.parsedSearch, key),\n readSearchValue(defaultSearch, key),\n )\n ) {\n params.delete(key);\n }\n }\n }\n }\n\n const next = params.toString();\n if (next === original) {\n return undefined;\n }\n\n return next ? `${input.path}?${next}` : input.path;\n}\n\nfunction createSearchParams(value: ProgrammaticRouteSearchFallback): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, item] of Object.entries(value)) {\n if (item == null) continue;\n const values = Array.isArray(item) ? item : [item];\n for (const entry of values) {\n if (entry != null) params.append(key, String(entry));\n }\n }\n\n return params;\n}\n\nfunction parseDefaultSearch(\n schema: ProgrammaticRouteSchema<any> | undefined,\n): Record<string, unknown> | undefined {\n if (!schema) return undefined;\n\n try {\n const value = schema.parse({});\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readSearchValue(value: unknown, key: string): unknown {\n return value && typeof value === \"object\" ? (value as Record<string, unknown>)[key] : undefined;\n}\n\nfunction searchValuesEqual(left: unknown, right: unknown): boolean {\n return (\n JSON.stringify(normalizeComparableValue(left)) ===\n JSON.stringify(normalizeComparableValue(right))\n );\n}\n\nfunction normalizeComparableValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(normalizeComparableValue);\n }\n if (value && typeof value === \"object\") {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((output, key) => {\n output[key] = normalizeComparableValue((value as Record<string, unknown>)[key]);\n return output;\n }, {});\n }\n return value;\n}\n\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TBeforeResult = unknown,\n TMainResult = unknown,\n TComponent extends ComponentType<any> = ComponentType<any>,\n>(\n path: string,\n options: Omit<\n CreateRouteOptionsWithBefore<TParamsSchema, TSearchConfig, TBeforeResult, TMainResult>,\n \"component\"\n > &\n CreateRouteComponentOption<\n TComponent,\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n Awaited<TMainResult>\n >\n >,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n CreateRouteDataHooksWithBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TBeforeResult,\n TMainResult\n >\n>;\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TMainResult = unknown,\n TComponent extends ComponentType<any> = ComponentType<any>,\n>(\n path: string,\n options: Omit<\n CreateRouteOptionsWithoutBefore<TParamsSchema, TSearchConfig, TMainResult>,\n \"component\"\n > &\n CreateRouteComponentOption<\n TComponent,\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n Awaited<TMainResult>\n >\n >,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n CreateRouteDataHooksWithoutBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TMainResult\n >\n>;\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n>(\n path: string,\n options: CreateRouteOptionsWithoutData<TParamsSchema, TSearchConfig>,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n undefined\n>;\nexport function createRoute(path: string, options: any): any {\n return routesBuilder.page(path, options);\n}\n\nexport function isProgrammaticRoutesFileName(fileName: string): boolean {\n const normalized = fileName.replace(/\\\\/g, \"/\");\n const baseName = normalized.split(\"/\").pop() || normalized;\n return PROGRAMMATIC_ROUTE_FILE_NAMES.includes(baseName);\n}\n\nexport function getProgrammaticRouteManifest(\n mod: Record<string, any> | null | undefined,\n): ProgrammaticRouteManifest | null {\n if (!mod) return null;\n\n const candidates = [mod.default, mod.routes, mod.Route];\n for (const candidate of candidates) {\n if (isProgrammaticRouteManifest(candidate)) {\n return candidate;\n }\n if (isProgrammaticRouteDefinition(candidate)) {\n return defineRoutes([candidate]);\n }\n if (Array.isArray(candidate)) {\n return defineRoutes(candidate as ProgrammaticRouteDefinition[]);\n }\n }\n\n const routeDefinitions = Object.values(mod).filter(isProgrammaticRouteDefinition);\n if (routeDefinitions.length > 0) {\n return defineRoutes(routeDefinitions);\n }\n\n return null;\n}\n\nexport function isProgrammaticRouteManifest(value: unknown): value is ProgrammaticRouteManifest {\n return (\n !!value &&\n typeof value === \"object\" &&\n (value as ProgrammaticRouteManifest).__farmRoutes === true &&\n Array.isArray((value as ProgrammaticRouteManifest).routes)\n );\n}\n\nexport function isProgrammaticRouteDefinition(\n value: unknown,\n): value is ProgrammaticRouteDefinition {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const kind = (value as { kind?: unknown }).kind;\n return kind === \"page\" || kind === \"layout\" || kind === \"api\" || kind === \"redirect\";\n}\n\nexport function createProgrammaticRouteModuleId(\n filePath: string,\n kind: \"page\" | \"layout\" | \"api\",\n routePath: string,\n): string {\n return `${filePath}?farm-route=${kind}:${encodeURIComponent(normalizeRoutePath(routePath))}`;\n}\n\nexport function parseProgrammaticRouteModuleId(moduleId: string): {\n filePath: string;\n kind: \"page\" | \"layout\" | \"api\";\n routePath: string;\n} | null {\n const queryIndex = moduleId.indexOf(\"?\");\n if (queryIndex === -1) {\n return null;\n }\n\n const filePath = moduleId.slice(0, queryIndex);\n const params = new URLSearchParams(moduleId.slice(queryIndex + 1));\n const value = params.get(\"farm-route\");\n if (!value) {\n return null;\n }\n\n const separator = value.indexOf(\":\");\n if (separator === -1) {\n return null;\n }\n\n const kind = value.slice(0, separator);\n if (kind !== \"page\" && kind !== \"layout\" && kind !== \"api\") {\n return null;\n }\n\n return {\n filePath,\n kind,\n routePath: normalizeRoutePath(value.slice(separator + 1)),\n };\n}\n\nexport function parseProgrammaticRoutePath(\n routePath: string,\n type: ParsedRoute[\"type\"] = \"page\",\n): ParsedRoute {\n const fileName = type === \"layout\" ? \"layout.tsx\" : \"page.tsx\";\n const normalized = normalizeRoutePath(routePath);\n const filePath =\n normalized === \"/\" ? fileName : `${normalized.slice(1).replace(/\\/+$/, \"\")}/${fileName}`;\n\n return {\n filePath,\n type,\n segments: normalized === \"/\" ? [] : normalized.slice(1).split(\"/\").map(parseRouteSegment),\n };\n}\n\nexport function createRouteModuleFromProgrammaticPage(route: ProgrammaticPageRoute): RouteModule {\n const mod: RouteModule = {\n default: createProgrammaticPageComponent(route),\n ...normalizeFarmRouteRuntimeConfig(route, `Route \"${route.path}\"`),\n };\n\n if (route.params || route.search || route.guard || route.data) {\n (mod as any).__farmRouteSchemas = {\n params: route.params,\n search: getProgrammaticRouteSearchSchema(route.search),\n };\n (mod as any).__farmRouteSearch = getProgrammaticRouteSearchClientOptions(route.search);\n (mod as any).__farmRouteGuard = route.guard;\n (mod as any).__farmRouteData = route.data;\n (mod as any).__farmRouteParsesProps = true;\n (mod as any).__farmResolveRouteProps = (props: PageProps) =>\n resolveProgrammaticRouteProps(route, props);\n (mod as any).__farmResolveRouteCanonicalPath = (\n rawSearch: ProgrammaticRouteSearchFallback,\n path: string,\n ) => resolveProgrammaticRouteSearch(route.search, rawSearch, path, route.path).canonicalPath;\n }\n\n if (route.pending || route.error || route.notFound) {\n (mod as any).__farmRouteComponents = {\n pending: route.pending,\n error: route.error,\n notFound: route.notFound,\n };\n }\n\n if (route.render === \"static\" || route.staticPaths) {\n mod.ssg = true;\n mod.dynamic = \"force-static\";\n } else if (route.render === \"dynamic\") {\n mod.ssg = false;\n mod.dynamic = \"force-dynamic\";\n }\n\n if (typeof route.revalidate !== \"undefined\") {\n mod.revalidate = route.revalidate;\n }\n\n if (route.ppr) {\n mod.ppr = true;\n }\n\n if (route.metadata) {\n mod.metadata = route.metadata;\n }\n\n if (route.generateMetadata) {\n mod.generateMetadata = route.generateMetadata;\n }\n\n if (route.staticPaths) {\n mod.getStaticPaths = async () => normalizeStaticPaths(route.path, await route.staticPaths!());\n }\n\n return mod;\n}\n\nexport function createLayoutModuleFromProgrammaticLayout(route: ProgrammaticLayoutRoute) {\n return {\n default: route.component,\n ...normalizeFarmRouteRuntimeConfig(route, `Layout \"${route.path}\"`),\n metadata: route.metadata,\n generateMetadata: route.generateMetadata,\n };\n}\n\nexport function scanProgrammaticPagePaths(source: string): string[] {\n const paths = new Set<string>();\n const callRe = /\\b(?:page|createRoute)\\s*\\(\\s*([\"'`])([^\"'`]+)\\1/g;\n\n for (const match of source.matchAll(callRe)) {\n if (match[2]) {\n paths.add(normalizeRoutePath(match[2]));\n }\n }\n\n return Array.from(paths);\n}\n\nfunction createProgrammaticPageComponent(route: ProgrammaticPageRoute): ComponentType<PageProps> {\n if (\n !route.params &&\n !route.search &&\n !route.guard &&\n !route.data &&\n !route.pending &&\n !route.error &&\n !route.notFound\n ) {\n return route.component as ComponentType<PageProps>;\n }\n\n const Component = route.component;\n\n if (route.pending) {\n const PendingComponent = route.pending;\n const routePropsResources = new WeakMap<object, ProgrammaticRoutePropsResource>();\n const FarmProgrammaticPageContent = function FarmProgrammaticPageContent(props: PageProps) {\n try {\n const resolvedProps = readProgrammaticRouteProps(route, props, routePropsResources);\n return createElement(Component, stripProgrammaticRoutePropsMarker(resolvedProps));\n } catch (error) {\n if (isPromiseLike(error) || isProgrammaticRedirectSignal(error)) {\n throw error;\n }\n\n if (isProgrammaticNotFoundSignal(error) && route.notFound) {\n return createElement(route.notFound, createProgrammaticRouteErrorProps(error, props));\n }\n\n if (route.error) {\n return createElement(route.error, createProgrammaticRouteErrorProps(error, props));\n }\n\n throw error;\n }\n };\n const PageContent = FarmProgrammaticPageContent as unknown as ComponentType<PageProps>;\n const FarmProgrammaticPage = function FarmProgrammaticPage(props: PageProps) {\n return createElement(\n Suspense,\n {\n fallback: createElement(PendingComponent, createProgrammaticRoutePendingProps(props)),\n },\n createElement(PageContent, props),\n );\n };\n\n return FarmProgrammaticPage as unknown as ComponentType<PageProps>;\n }\n\n const FarmProgrammaticPageContent = async function FarmProgrammaticPageContent(props: PageProps) {\n try {\n const resolvedProps = isProgrammaticRoutePropsResolved(props)\n ? props\n : await resolveProgrammaticRouteProps(route, props);\n\n return createElement(Component, stripProgrammaticRoutePropsMarker(resolvedProps));\n } catch (error) {\n if (isProgrammaticRedirectSignal(error)) {\n throw error;\n }\n\n if (isProgrammaticNotFoundSignal(error) && route.notFound) {\n return createElement(route.notFound, createProgrammaticRouteErrorProps(error, props));\n }\n\n if (route.error) {\n return createElement(route.error, createProgrammaticRouteErrorProps(error, props));\n }\n\n throw error;\n }\n };\n\n return FarmProgrammaticPageContent as unknown as ComponentType<PageProps>;\n}\n\ntype ProgrammaticRoutePropsResource =\n | { status: \"pending\"; promise: Promise<Record<string, any>> }\n | { status: \"resolved\"; value: Record<string, any> }\n | { status: \"rejected\"; error: unknown };\n\nfunction readProgrammaticRouteProps(\n route: ProgrammaticPageRoute,\n props: PageProps,\n resources: WeakMap<object, ProgrammaticRoutePropsResource>,\n): Record<string, any> {\n if (isProgrammaticRoutePropsResolved(props)) {\n return props;\n }\n\n let resource = resources.get(props as object);\n if (!resource) {\n const deferredRouteProps = (props as any).__farmRoutePropsPromise;\n const promise = Promise.resolve<Record<string, any>>(\n isPromiseLike(deferredRouteProps)\n ? (deferredRouteProps as PromiseLike<Record<string, any>>)\n : resolveProgrammaticRouteProps(route, props),\n );\n resource = { status: \"pending\", promise };\n resources.set(props as object, resource);\n promise.then(\n (value) => resources.set(props as object, { status: \"resolved\", value }),\n (error) => resources.set(props as object, { status: \"rejected\", error }),\n );\n }\n\n if (resource.status === \"pending\") throw resource.promise;\n if (resource.status === \"rejected\") throw resource.error;\n return resource.value;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as PromiseLike<unknown>).then === \"function\",\n );\n}\n\nfunction createProgrammaticRoutePendingProps(\n props: PageProps,\n): ProgrammaticRoutePendingComponentProps {\n return {\n params: props.params,\n searchParams: props.searchParams,\n path: props.path,\n };\n}\n\nfunction createProgrammaticRouteErrorProps(\n error: unknown,\n props: PageProps,\n): ProgrammaticRouteErrorComponentProps {\n return {\n error,\n params: props.params,\n searchParams: props.searchParams,\n path: props.path,\n };\n}\n\nfunction isProgrammaticRedirectSignal(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const digest = (error as { digest?: unknown }).digest;\n return typeof digest === \"string\" && digest.startsWith(\"FARM_REDIRECT;\");\n}\n\nfunction isProgrammaticNotFoundSignal(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const digest = (error as { digest?: unknown }).digest;\n return digest === \"FARM_NOT_FOUND\";\n}\n\nasync function resolveProgrammaticRouteProps(\n route: ProgrammaticPageRoute,\n props: PageProps,\n): Promise<Record<string, any> & { __farmRoutePropsResolved: true }> {\n const rawSearch = await props.searchParams;\n const params = parseProgrammaticSchema(route.params, props.params, \"params\", route.path);\n const { search, canonicalPath } = resolveProgrammaticRouteSearch(\n route.search,\n rawSearch,\n props.path,\n route.path,\n );\n const routeContextValue = getFarmRouteContext(props);\n const pluginContext = props.context;\n const baseProps = {\n ...props,\n params,\n search,\n searchParams: Promise.resolve(search),\n };\n const routeContextProps = {\n ...baseProps,\n context: routeContextValue,\n pluginContext,\n };\n\n if (route.guard) {\n await route.guard(routeContextProps as any);\n }\n\n if (!route.data) {\n return markProgrammaticRoutePropsResolved(addCanonicalPath(baseProps, canonicalPath));\n }\n\n const before = route.data.before ? await route.data.before(routeContextProps as any) : undefined;\n const dataContext = {\n ...(routeContextProps as any),\n before,\n };\n const data = await resolveProgrammaticRouteData(route, route.data, dataContext);\n\n if (route.data.after) {\n await route.data.after({\n ...(routeContextProps as any),\n before,\n data,\n });\n }\n\n return markProgrammaticRoutePropsResolved({\n ...baseProps,\n data,\n ...(canonicalPath ? { __farmCanonicalPath: canonicalPath } : {}),\n });\n}\n\nasync function resolveProgrammaticRouteData(\n route: ProgrammaticPageRoute,\n dataHooks: ProgrammaticRouteDataHooks<any, any, any, any>,\n context: ProgrammaticRouteDataCacheContext<any, any, any>,\n): Promise<unknown> {\n if (!dataHooks?.key) {\n return dataHooks.main(context);\n }\n\n const routeDataKey = await dataHooks.key(context);\n if (routeDataKey == null) {\n return dataHooks.main(context);\n }\n\n const cacheKey = createFarmCacheKey([\"route-data\", routeDataKey]);\n const cacheOptions: FarmCacheOptions = {\n tags: [\n createRouteDataCacheTag(routeDataKey),\n ...(await resolveProgrammaticRouteDataKeys(dataHooks.tags, context)),\n ],\n paths: [\n ...(typeof context.path === \"string\" ? [context.path] : []),\n ...(await resolveProgrammaticRouteDataKeys(dataHooks.paths, context)),\n ],\n revalidate: normalizeProgrammaticRouteStaleTime(dataHooks.staleTime),\n };\n\n return getFarmDataCache().getOrSet(cacheKey, () => dataHooks.main(context), cacheOptions);\n}\n\nasync function resolveProgrammaticRouteDataKeys(\n input: ProgrammaticRouteDataCacheKeys<any, any, any> | undefined,\n context: ProgrammaticRouteDataCacheContext<any, any, any>,\n): Promise<readonly string[]> {\n if (!input) return [];\n const value = typeof input === \"function\" ? await input(context) : input;\n return value.filter((item) => typeof item === \"string\" && item.trim().length > 0);\n}\n\nfunction normalizeProgrammaticRouteStaleTime(\n staleTime: ProgrammaticRouteDataStaleTime | undefined,\n): number | false | undefined {\n if (staleTime === undefined) return undefined;\n if (staleTime === false) return false;\n\n if (typeof staleTime === \"number\") {\n if (!Number.isFinite(staleTime) || staleTime <= 0) return undefined;\n return Math.max(1, Math.ceil(staleTime / 1000));\n }\n\n const match = staleTime.match(/^(\\d+(?:\\.\\d+)?)(ms|s|m|h)$/);\n if (!match) return undefined;\n\n const value = Number(match[1]);\n if (!Number.isFinite(value) || value <= 0) return undefined;\n\n const unit = match[2];\n const milliseconds =\n unit === \"ms\"\n ? value\n : unit === \"s\"\n ? value * 1000\n : unit === \"m\"\n ? value * 60000\n : value * 3600000;\n\n return Math.max(1, Math.ceil(milliseconds / 1000));\n}\n\nfunction isProgrammaticRoutePropsResolved(value: unknown): boolean {\n return !!value && typeof value === \"object\" && (value as any).__farmRoutePropsResolved === true;\n}\n\nfunction markProgrammaticRoutePropsResolved<T extends Record<string, any>>(\n props: T,\n): T & { __farmRoutePropsResolved: true } {\n return {\n ...props,\n __farmRoutePropsResolved: true,\n };\n}\n\nfunction addCanonicalPath<T extends Record<string, any>>(\n props: T,\n canonicalPath: string | undefined,\n): T {\n return canonicalPath ? ({ ...props, __farmCanonicalPath: canonicalPath } as T) : props;\n}\n\nfunction stripProgrammaticRoutePropsMarker<TProps>(props: TProps): TProps {\n if (!isProgrammaticRoutePropsResolved(props)) {\n return props;\n }\n\n const {\n __farmRoutePropsResolved,\n __farmCanonicalPath,\n __farmRoutePropsPromise,\n ...componentProps\n } = props as any;\n return componentProps;\n}\n\nfunction parseProgrammaticSchema<TFallback>(\n schema: ProgrammaticRouteSchema<any> | undefined,\n value: TFallback,\n label: string,\n routePath: string,\n): unknown {\n if (!schema) {\n return value;\n }\n\n try {\n return schema.parse(value);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid ${label} for route \"${routePath}\": ${message}`);\n }\n}\n\nfunction normalizeProgrammaticRoute(\n route: ProgrammaticRouteDefinition,\n): ProgrammaticRouteDefinition {\n if (route.kind === \"redirect\") {\n return {\n ...route,\n source: normalizeRoutePath(route.source),\n };\n }\n\n if (route.kind === \"api\") {\n return {\n ...route,\n ...normalizeFarmRouteRuntimeConfig(route, `API route \"${route.path}\"`),\n path: normalizeRoutePath(route.path),\n methods: normalizeApiMethods(route.methods),\n };\n }\n\n return {\n ...route,\n ...normalizeFarmRouteRuntimeConfig(\n route,\n `${route.kind === \"layout\" ? \"Layout\" : \"Route\"} \"${route.path}\"`,\n ),\n path: normalizeRoutePath(route.path),\n };\n}\n\nfunction normalizeRoutePath(routePath: string): string {\n const withSlash = routePath.startsWith(\"/\") ? routePath : `/${routePath}`;\n const withoutTrailing = withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n return withoutTrailing || \"/\";\n}\n\nfunction parseRouteSegment(segment: string): ParsedRoute[\"segments\"][number] {\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n let name = segment.slice(1, -1);\n let isOptional = false;\n let isCatchAll = false;\n\n if (name.startsWith(\"[\") && name.endsWith(\"]\")) {\n isOptional = true;\n name = name.slice(1, -1);\n }\n\n if (name.startsWith(\"...\")) {\n isCatchAll = true;\n name = name.slice(3);\n }\n\n return {\n segment: name,\n isDynamic: true,\n isOptional,\n isCatchAll,\n };\n }\n\n return {\n segment,\n isDynamic: false,\n isOptional: false,\n isCatchAll: false,\n };\n}\n\nfunction normalizeApiMethods(\n methods: Record<string, any>,\n): Partial<Record<ProgrammaticRouteMethod, any>> {\n const normalized: Partial<Record<ProgrammaticRouteMethod, any>> = {};\n\n for (const [method, handler] of Object.entries(methods)) {\n const normalizedMethod = method.toUpperCase() as ProgrammaticRouteMethod;\n if (handler && isProgrammaticRouteMethod(normalizedMethod)) {\n normalized[normalizedMethod] = handler;\n }\n }\n\n return normalized;\n}\n\nfunction isProgrammaticRouteMethod(method: string): method is ProgrammaticRouteMethod {\n return (\n method === \"GET\" ||\n method === \"HEAD\" ||\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"DELETE\" ||\n method === \"PATCH\" ||\n method === \"OPTIONS\"\n );\n}\n\nfunction normalizeStaticPaths(\n routePath: string,\n paths: readonly ProgrammaticStaticPath[],\n): Record<string, string>[] {\n const dynamicSegments = parseProgrammaticRoutePath(routePath).segments.filter(\n (segment) => segment.isDynamic,\n );\n\n return paths.map((entry) => {\n if (typeof entry === \"string\" || Array.isArray(entry)) {\n if (dynamicSegments.length !== 1) {\n throw new Error(\n `staticPaths for \"${routePath}\" must return objects when the route has ${dynamicSegments.length} dynamic params.`,\n );\n }\n\n const value = Array.isArray(entry) ? entry.join(\"/\") : entry;\n return { [dynamicSegments[0].segment]: String(value) };\n }\n\n return Object.fromEntries(\n Object.entries(entry).map(([key, value]) => [\n key,\n Array.isArray(value) ? value.map(String).join(\"/\") : String(value),\n ]),\n );\n });\n}\n","export type FarmEventLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface FarmEventBase {\n type: string;\n timestamp: number;\n level: FarmEventLevel;\n requestId?: string;\n route?: string;\n pathname?: string;\n}\n\nexport type FarmServerEvent =\n | (FarmEventBase & {\n type: \"server.start\";\n mode: \"dev\" | \"preview\" | \"production\";\n port?: number;\n })\n | (FarmEventBase & { type: \"server.ready\"; url?: string })\n | (FarmEventBase & { type: \"server.shutdown\"; reason?: string });\n\nexport type FarmRouteEvent =\n | (FarmEventBase & { type: \"route.discovered\"; route: string; filePath: string })\n | (FarmEventBase & {\n type: \"route.matched\";\n pathname: string;\n route: string;\n params?: Record<string, string>;\n })\n | (FarmEventBase & { type: \"route.notFound\"; pathname: string })\n | (FarmEventBase & { type: \"route.redirect\"; from: string; to: string; status?: number })\n | (FarmEventBase & { type: \"route.rewrite\"; from: string; to: string });\n\nexport type FarmRenderEvent =\n | (FarmEventBase & { type: \"render.start\"; route: string; pathname?: string })\n | (FarmEventBase & {\n type: \"render.complete\";\n route: string;\n durationMs: number;\n status?: number;\n })\n | (FarmEventBase & { type: \"render.error\"; route?: string; error: unknown })\n | (FarmEventBase & { type: \"render.stream.start\"; route: string })\n | (FarmEventBase & { type: \"render.stream.shellReady\"; route: string; durationMs: number })\n | (FarmEventBase & { type: \"render.stream.complete\"; route: string; durationMs: number });\n\nexport type FarmCacheEvent =\n | (FarmEventBase & {\n type: \"cache.hit\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n stale?: boolean;\n })\n | (FarmEventBase & { type: \"cache.miss\"; key: string; route?: string; reason?: string })\n | (FarmEventBase & {\n type: \"cache.set\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n })\n | (FarmEventBase & { type: \"cache.dedupe\"; key: string })\n | (FarmEventBase & { type: \"cache.bypass\"; key?: string; route?: string; reason: string })\n | (FarmEventBase & {\n type: \"cache.stale\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n })\n | (FarmEventBase & { type: \"cache.revalidatePath\"; path: string; count: number })\n | (FarmEventBase & {\n type: \"cache.revalidateTag\";\n tag: string;\n profile?: unknown;\n count: number;\n })\n | (FarmEventBase & { type: \"cache.updateTag\"; tag: string; count: number })\n | (FarmEventBase & {\n type: \"cache.invalidated\";\n key?: string;\n route?: string;\n tag?: string;\n reason?: string;\n count?: number;\n })\n | (FarmEventBase & { type: \"cache.delete\"; key: string; deleted: boolean })\n | (FarmEventBase & { type: \"cache.clear\"; count: number })\n | (FarmEventBase & {\n type: \"cache.error\";\n key?: string;\n operation: \"get\" | \"set\" | \"delete\" | \"revalidate\";\n error: unknown;\n });\n\nexport type FarmPPREvent =\n | (FarmEventBase & { type: \"ppr.shell.hit\"; route: string; key: string })\n | (FarmEventBase & { type: \"ppr.shell.miss\"; route: string; key: string })\n | (FarmEventBase & {\n type: \"ppr.shell.cached\";\n route: string;\n key: string;\n revalidate?: number;\n })\n | (FarmEventBase & { type: \"ppr.shell.bypass\"; route: string; reason: string })\n | (FarmEventBase & {\n type: \"ppr.shell.invalidated\";\n route: string;\n reason?: string;\n count?: number;\n })\n | (FarmEventBase & { type: \"ppr.suspense.holeDetected\"; route: string })\n | (FarmEventBase & { type: \"ppr.refresh.start\"; route: string })\n | (FarmEventBase & { type: \"ppr.refresh.complete\"; route: string; durationMs: number })\n | (FarmEventBase & { type: \"ppr.refresh.error\"; route: string; error: unknown });\n\nexport type FarmAPIEvent =\n | (FarmEventBase & { type: \"api.request.start\"; route: string; method: string })\n | (FarmEventBase & {\n type: \"api.request.complete\";\n route: string;\n method: string;\n status: number;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"api.validation.failed\";\n route: string;\n method: string;\n issues?: unknown;\n })\n | (FarmEventBase & { type: \"api.error\"; route: string; method: string; error: unknown });\n\nexport type FarmIntegrationEvent =\n | (FarmEventBase & { type: \"integration.registered\"; name: string })\n | (FarmEventBase & { type: \"integration.config.validated\"; name: string })\n | (FarmEventBase & { type: \"integration.ready\"; name: string })\n | (FarmEventBase & { type: \"integration.disposed\"; name: string })\n | (FarmEventBase & {\n type: \"integration.api.call.start\";\n integration: string;\n operation: string;\n })\n | (FarmEventBase & {\n type: \"integration.api.call.complete\";\n integration: string;\n operation: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"integration.api.call.error\";\n integration: string;\n operation: string;\n error: unknown;\n })\n | (FarmEventBase & { type: \"integration.webhook.received\"; integration: string; event?: string })\n | (FarmEventBase & { type: \"integration.webhook.verified\"; integration: string; event?: string })\n | (FarmEventBase & { type: \"integration.webhook.failed\"; integration: string; reason: string });\n\nexport type FarmMiddlewareEvent =\n | (FarmEventBase & { type: \"middleware.start\"; route?: string; name?: string })\n | (FarmEventBase & {\n type: \"middleware.complete\";\n route?: string;\n name?: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"middleware.shortCircuit\";\n route?: string;\n name?: string;\n status?: number;\n })\n | (FarmEventBase & { type: \"middleware.error\"; route?: string; name?: string; error: unknown });\n\nexport type FarmStorageEvent =\n | (FarmEventBase & { type: \"storage.query.start\"; integration?: string; operation: string })\n | (FarmEventBase & {\n type: \"storage.query.complete\";\n integration?: string;\n operation: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"storage.query.error\";\n integration?: string;\n operation: string;\n error: unknown;\n })\n | (FarmEventBase & { type: \"storage.schema.ready\"; integration?: string })\n | (FarmEventBase & { type: \"storage.schema.error\"; integration?: string; error: unknown });\n\nexport type FarmBuildEvent =\n | (FarmEventBase & { type: \"build.start\"; target?: string })\n | (FarmEventBase & { type: \"build.complete\"; target?: string; durationMs: number })\n | (FarmEventBase & { type: \"build.error\"; target?: string; error: unknown })\n | (FarmEventBase & { type: \"routes.generated\"; pageCount: number; apiCount?: number })\n | (FarmEventBase & { type: \"types.generated\"; filePath: string })\n | (FarmEventBase & { type: \"manifest.generated\"; routeCount: number });\n\nexport type FarmPluginEvent =\n | (FarmEventBase & { type: \"plugin.hook.start\"; plugin: string; hook: string })\n | (FarmEventBase & {\n type: \"plugin.hook.complete\";\n plugin: string;\n hook: string;\n durationMs: number;\n })\n | (FarmEventBase & { type: \"plugin.hook.error\"; plugin: string; hook: string; error: unknown });\n\nexport type FarmErrorEvent = FarmEventBase & {\n type: \"error\";\n source: string;\n error: unknown;\n route?: string;\n};\n\nexport type FarmEvent =\n | FarmServerEvent\n | FarmRouteEvent\n | FarmRenderEvent\n | FarmCacheEvent\n | FarmPPREvent\n | FarmAPIEvent\n | FarmIntegrationEvent\n | FarmMiddlewareEvent\n | FarmStorageEvent\n | FarmBuildEvent\n | FarmPluginEvent\n | FarmErrorEvent;\n\nexport type FarmEventType = FarmEvent[\"type\"];\nexport type FarmEventHandler = (event: FarmEvent) => void | Promise<void>;\n\nexport type FarmEventInput = FarmEvent extends infer T\n ? T extends FarmEvent\n ? Omit<T, \"timestamp\" | \"level\"> & Partial<Pick<T, \"timestamp\" | \"level\">>\n : never\n : never;\n\nexport type FarmObservabilityUserConfig =\n | boolean\n | {\n logs?: boolean;\n onEvent?: FarmEventHandler | readonly FarmEventHandler[];\n events?: readonly FarmEventType[];\n };\n\nexport interface FarmResolvedObservabilityConfig {\n logs: boolean;\n handlers: FarmEventHandler[];\n events?: Set<FarmEventType>;\n}\n\nconst runtimeHandlers = new Set<FarmEventHandler>();\nlet observabilityState: FarmResolvedObservabilityConfig = {\n logs: false,\n handlers: [],\n};\n\nexport function configureFarmObservability(config: FarmObservabilityUserConfig | undefined): void {\n observabilityState = normalizeFarmObservabilityConfig(config);\n}\n\nexport function normalizeFarmObservabilityConfig(\n config: FarmObservabilityUserConfig | undefined,\n): FarmResolvedObservabilityConfig {\n if (config === undefined || config === false) {\n return { logs: false, handlers: [] };\n }\n\n if (config === true) {\n return { logs: true, handlers: [] };\n }\n\n const handlers = config.onEvent\n ? Array.isArray(config.onEvent)\n ? [...config.onEvent]\n : [config.onEvent]\n : [];\n\n return {\n logs: config.logs ?? false,\n handlers,\n events: config.events ? new Set(config.events) : undefined,\n };\n}\n\nexport function onFarmEvent(handler: FarmEventHandler): () => void {\n runtimeHandlers.add(handler);\n return () => {\n runtimeHandlers.delete(handler);\n };\n}\n\nexport function resetFarmObservability(): void {\n runtimeHandlers.clear();\n observabilityState = {\n logs: false,\n handlers: [],\n };\n}\n\nexport function emitFarmEvent(input: FarmEventInput): FarmEvent {\n const event = {\n timestamp: Date.now(),\n level: inferFarmEventLevel(input.type),\n ...input,\n } as FarmEvent;\n\n if (!shouldEmitFarmEvent(event)) {\n return event;\n }\n\n if (observabilityState.logs) {\n logFarmEvent(event);\n }\n\n for (const handler of [...observabilityState.handlers, ...runtimeHandlers]) {\n try {\n Promise.resolve(handler(event)).catch((error) => {\n console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);\n });\n } catch (error) {\n console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);\n }\n }\n\n return event;\n}\n\nfunction shouldEmitFarmEvent(event: FarmEvent): boolean {\n if (\n !observabilityState.logs &&\n observabilityState.handlers.length === 0 &&\n runtimeHandlers.size === 0\n ) {\n return false;\n }\n\n if (observabilityState.events && !observabilityState.events.has(event.type)) {\n return false;\n }\n\n return true;\n}\n\nfunction inferFarmEventLevel(type: FarmEventType): FarmEventLevel {\n if (type === \"error\" || type.endsWith(\".error\") || type.endsWith(\".failed\")) {\n return \"error\";\n }\n if (\n type.endsWith(\".bypass\") ||\n type.endsWith(\".invalidated\") ||\n type.endsWith(\".stale\") ||\n type.endsWith(\".notFound\")\n ) {\n return \"warn\";\n }\n if (\n type.endsWith(\".hit\") ||\n type.endsWith(\".miss\") ||\n type.endsWith(\".start\") ||\n type.endsWith(\".shellReady\")\n ) {\n return \"debug\";\n }\n return \"info\";\n}\n\nfunction logFarmEvent(event: FarmEvent): void {\n const message = `[farm:${event.level}] ${event.type}${formatFarmEventDetails(event)}`;\n switch (event.level) {\n case \"error\":\n console.error(message);\n break;\n case \"warn\":\n console.warn(message);\n break;\n default:\n console.log(message);\n break;\n }\n}\n\nfunction formatFarmEventDetails(event: FarmEvent): string {\n const details: string[] = [];\n const record = event as unknown as Record<string, unknown>;\n\n for (const key of [\n \"route\",\n \"pathname\",\n \"method\",\n \"status\",\n \"key\",\n \"tag\",\n \"path\",\n \"reason\",\n \"durationMs\",\n \"integration\",\n \"operation\",\n \"plugin\",\n \"hook\",\n \"target\",\n \"count\",\n ]) {\n const value = record[key];\n if (value !== undefined) {\n details.push(`${key}=${formatDetailValue(value)}`);\n }\n }\n\n return details.length > 0 ? ` ${details.join(\" \")}` : \"\";\n}\n\nfunction formatDetailValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","export type FarmCacheInvalidationListener = (key: string) => void;\n\nexport const FARM_CACHE_INVALIDATION_HEADER = \"x-farm-cache-invalidations\";\n\ntype FarmCacheInvalidationState = {\n listeners: Set<FarmCacheInvalidationListener>;\n};\n\nconst FARM_CACHE_INVALIDATION_STATE = Symbol.for(\"farm.cacheInvalidationState\");\nconst globalState = globalThis as typeof globalThis & {\n [FARM_CACHE_INVALIDATION_STATE]?: FarmCacheInvalidationState;\n};\n\nfunction getFarmCacheInvalidationState(): FarmCacheInvalidationState {\n return (globalState[FARM_CACHE_INVALIDATION_STATE] ??= {\n listeners: new Set(),\n });\n}\n\nexport function notifyFarmCacheInvalidation(key: string): void {\n if (typeof key !== \"string\" || key.length === 0) return;\n\n for (const listener of getFarmCacheInvalidationState().listeners) {\n listener(key);\n }\n}\n\nexport function applyFarmCacheInvalidations(keys: unknown): void {\n if (!Array.isArray(keys)) return;\n\n for (const key of keys) {\n if (typeof key === \"string\") {\n notifyFarmCacheInvalidation(key);\n }\n }\n}\n\nexport function encodeFarmCacheInvalidations(keys: readonly string[]): string | null {\n const normalized = Array.from(\n new Set(keys.filter((key) => typeof key === \"string\" && key.length > 0)),\n );\n if (normalized.length === 0) return null;\n return encodeURIComponent(JSON.stringify(normalized));\n}\n\nexport function decodeFarmCacheInvalidations(value: string | null | undefined): readonly string[] {\n if (!value) return [];\n\n try {\n const parsed = JSON.parse(decodeURIComponent(value));\n return Array.isArray(parsed)\n ? Array.from(\n new Set(parsed.filter((key): key is string => typeof key === \"string\" && key.length > 0)),\n )\n : [];\n } catch {\n return [];\n }\n}\n\nexport function subscribeFarmCacheInvalidation(\n listener: FarmCacheInvalidationListener,\n): () => void {\n const state = getFarmCacheInvalidationState();\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n}\n","import type { FarmI18nClientSnapshot } from \"./types\";\n\ntype SnapshotResolver = () => FarmI18nClientSnapshot | undefined;\n\nconst FARM_I18N_SNAPSHOT_RESOLVER = Symbol.for(\"farm.i18n.snapshotResolver\");\ntype GlobalWithI18nResolver = typeof globalThis & {\n [FARM_I18N_SNAPSHOT_RESOLVER]?: SnapshotResolver;\n};\n\nexport function _setFarmI18nSnapshotResolver(resolver: SnapshotResolver | undefined): void {\n (globalThis as GlobalWithI18nResolver)[FARM_I18N_SNAPSHOT_RESOLVER] = resolver;\n}\n\nexport function getActiveFarmI18nSnapshot(): FarmI18nClientSnapshot | undefined {\n if (typeof window !== \"undefined\" && window.__FARM_I18N__) {\n return window.__FARM_I18N__;\n }\n return (globalThis as GlobalWithI18nResolver)[FARM_I18N_SNAPSHOT_RESOLVER]?.();\n}\n","import { emitFarmEvent } from \"./observability\";\nimport { notifyFarmCacheInvalidation } from \"./cache-invalidation\";\nimport { getActiveFarmI18nSnapshot } from \"./i18n/bridge\";\n\nexport { applyFarmCacheInvalidations } from \"./cache-invalidation\";\n\nexport type RevalidateTagProfile =\n | \"max\"\n | \"default\"\n | \"seconds\"\n | \"minutes\"\n | \"hours\"\n | \"days\"\n | \"weeks\"\n | \"months\"\n | { expire?: number };\n\nexport interface FarmCacheOptions {\n /**\n * Tag cached data so it can be invalidated with revalidateTag/updateTag.\n */\n tags?: readonly string[];\n /**\n * Path tags let revalidatePath invalidate data tied to a route.\n */\n paths?: readonly string[];\n /**\n * Time in seconds before the entry becomes stale. False means no TTL.\n */\n revalidate?: number | false;\n}\n\nexport interface FarmCacheSetOptions extends FarmCacheOptions {\n createdAt?: number;\n}\n\nexport type RouteDataCacheKey = string | readonly unknown[];\n\ndeclare const FARM_DEFINED_CACHE_KEY_DATA: unique symbol;\n\n/**\n * A regular Farm cache key carrying the data shape stored under that key.\n *\n * The brand exists only in TypeScript. At runtime the value remains the\n * original string or structured array, so all existing cache APIs continue to\n * accept untyped keys.\n */\nexport type DefinedCacheKey<TData, TKey extends RouteDataCacheKey = RouteDataCacheKey> = TKey & {\n readonly [FARM_DEFINED_CACHE_KEY_DATA]: TData;\n};\n\nexport type CacheKeyFactory<\n TData,\n TArguments extends readonly unknown[],\n TKey extends RouteDataCacheKey = RouteDataCacheKey,\n> = (...args: TArguments) => DefinedCacheKey<TData, TKey>;\n\nexport type InferCacheKeyData<TKey> =\n TKey extends DefinedCacheKey<infer TData, RouteDataCacheKey> ? TData : unknown;\n\n/**\n * Optionally add a data type to an existing string/array cache-key factory.\n *\n * This helper does not introduce a new runtime key representation. Calling the\n * returned factory produces the exact key returned by `factory`.\n */\nexport function defineCacheKey<TData>() {\n return <const TArguments extends readonly unknown[], const TKey extends RouteDataCacheKey>(\n factory: (...args: TArguments) => TKey,\n ): CacheKeyFactory<TData, TArguments, TKey> => {\n if (typeof factory !== \"function\") {\n throw new TypeError(\"defineCacheKey expects a key factory function.\");\n }\n\n return ((...args: TArguments) => {\n const key = factory(...args);\n if (typeof key !== \"string\" && !Array.isArray(key)) {\n throw new TypeError(\n \"A defined cache key factory must return a string or structured array.\",\n );\n }\n return key as DefinedCacheKey<TData, TKey>;\n }) as CacheKeyFactory<TData, TArguments, TKey>;\n };\n}\n\nexport interface FarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: readonly string[];\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\ninterface InternalFarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: Set<string>;\n createdAt: number;\n createdVersion: number;\n revalidate?: number | false;\n}\n\nexport interface GetFarmCacheEntryOptions {\n allowStale?: boolean;\n now?: number;\n}\n\ninterface FarmCacheStaleEntry {\n tags: Iterable<string>;\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\nexport class FarmDataCache {\n private entries = new Map<string, InternalFarmCacheEntry>();\n private inflight = new Map<string, Promise<unknown>>();\n private invalidatedTagVersions = new Map<string, number>();\n private version = 0;\n\n get size(): number {\n return this.entries.size;\n }\n\n get<T>(key: string, options: GetFarmCacheEntryOptions = {}): T | undefined {\n return this.getEntry<T>(key, options)?.value;\n }\n\n getEntry<T = unknown>(\n key: string,\n options: GetFarmCacheEntryOptions = {},\n ): FarmCacheEntry<T> | undefined {\n const entry = this.entries.get(key) as InternalFarmCacheEntry<T> | undefined;\n if (!entry) {\n emitFarmEvent({ type: \"cache.miss\", key });\n return undefined;\n }\n\n const stale = this.isStale(entry, options.now);\n if (stale) {\n emitFarmEvent({\n type: \"cache.stale\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n });\n }\n\n if (!options.allowStale && stale) {\n emitFarmEvent({ type: \"cache.miss\", key, reason: \"stale\" });\n return undefined;\n }\n\n emitFarmEvent({\n type: \"cache.hit\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n stale,\n });\n\n return this.toPublicEntry(entry);\n }\n\n set<T>(key: string, value: T, options: FarmCacheSetOptions = {}): FarmCacheEntry<T> {\n const tags = new Set<string>();\n for (const tag of options.tags ?? []) {\n tags.add(normalizeCacheTag(tag));\n }\n for (const routePath of options.paths ?? []) {\n tags.add(createPathCacheTag(routePath));\n }\n\n const entry: InternalFarmCacheEntry<T> = {\n key,\n value,\n tags,\n createdAt: options.createdAt ?? Date.now(),\n createdVersion: ++this.version,\n revalidate: normalizeRevalidate(options.revalidate),\n };\n\n this.entries.set(key, entry);\n emitFarmEvent({\n type: \"cache.set\",\n key,\n tags: Array.from(tags),\n revalidate: entry.revalidate,\n });\n return this.toPublicEntry(entry);\n }\n\n delete(key: string): boolean {\n const deleted = this.entries.delete(key);\n emitFarmEvent({ type: \"cache.delete\", key, deleted });\n return deleted;\n }\n\n clear(): void {\n const count = this.entries.size;\n this.entries.clear();\n this.inflight.clear();\n this.invalidatedTagVersions.clear();\n this.version = 0;\n emitFarmEvent({ type: \"cache.clear\", count });\n }\n\n isStale(entry: FarmCacheStaleEntry, now = Date.now()): boolean {\n if (\n typeof entry.revalidate === \"number\" &&\n entry.revalidate > 0 &&\n now - entry.createdAt >= entry.revalidate * 1000\n ) {\n return true;\n }\n\n for (const tag of entry.tags) {\n const invalidatedVersion = this.invalidatedTagVersions.get(normalizeCacheTag(tag));\n if (\n typeof invalidatedVersion === \"number\" &&\n typeof entry.createdVersion === \"number\" &&\n invalidatedVersion > entry.createdVersion\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n revalidateTag(\n tag: string,\n options: { source?: \"revalidateTag\" | \"updateTag\"; profile?: RevalidateTagProfile } = {},\n ): number {\n const normalized = normalizeCacheTag(tag);\n const count = this.invalidateTag(normalized);\n emitFarmEvent(\n options.source === \"updateTag\"\n ? { type: \"cache.updateTag\", tag: normalized, count }\n : { type: \"cache.revalidateTag\", tag: normalized, profile: options.profile, count },\n );\n return count;\n }\n\n revalidatePath(routePath: string): number {\n const normalizedPath = normalizeRevalidatePath(routePath);\n const pathTag = createPathCacheTag(normalizedPath);\n const pprCount = this.countEntriesForTags([pathTag, \"ppr\"]);\n const count = this.invalidateTag(pathTag);\n emitFarmEvent({ type: \"cache.revalidatePath\", path: normalizedPath, count });\n\n if (pprCount > 0) {\n emitFarmEvent({\n type: \"ppr.shell.invalidated\",\n route: normalizedPath,\n reason: \"revalidatePath\",\n count: pprCount,\n });\n }\n\n return count;\n }\n\n async getOrSet<T>(\n key: string,\n producer: () => Promise<T> | T,\n options: FarmCacheOptions = {},\n ): Promise<T> {\n const cached = this.getEntry<T>(key);\n if (cached) {\n return cached.value;\n }\n\n const inflight = this.inflight.get(key) as Promise<T> | undefined;\n if (inflight) {\n emitFarmEvent({ type: \"cache.dedupe\", key });\n return inflight;\n }\n\n const promise = Promise.resolve()\n .then(producer)\n .then((value) => {\n this.set(key, value, options);\n return value;\n })\n .catch((error) => {\n emitFarmEvent({ type: \"cache.error\", key, operation: \"set\", error });\n throw error;\n })\n .finally(() => {\n this.inflight.delete(key);\n });\n\n this.inflight.set(key, promise);\n return promise;\n }\n\n private countEntriesForTag(tag: string): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (entry.tags.has(tag)) {\n count++;\n }\n }\n return count;\n }\n\n private countEntriesForTags(tags: readonly string[]): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (tags.every((tag) => entry.tags.has(tag))) {\n count++;\n }\n }\n return count;\n }\n\n private invalidateTag(normalizedTag: string): number {\n this.invalidatedTagVersions.set(normalizedTag, ++this.version);\n return this.countEntriesForTag(normalizedTag);\n }\n\n private toPublicEntry<T>(entry: InternalFarmCacheEntry<T>): FarmCacheEntry<T> {\n return {\n key: entry.key,\n value: entry.value,\n tags: Array.from(entry.tags),\n createdAt: entry.createdAt,\n createdVersion: entry.createdVersion,\n revalidate: entry.revalidate,\n };\n }\n}\n\nconst FARM_DATA_CACHE_SYMBOL = Symbol.for(\"farm.dataCache\");\nconst farmDataCacheGlobal = globalThis as typeof globalThis & {\n [FARM_DATA_CACHE_SYMBOL]?: FarmDataCache;\n};\nconst sharedFarmDataCache = (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ??= new FarmDataCache());\nconst functionIds = new WeakMap<Function, number>();\nlet nextFunctionId = 0;\n\nexport function getFarmDataCache(): FarmDataCache {\n return sharedFarmDataCache;\n}\n\nexport function unstable_cache<Args extends unknown[], Result>(\n fn: (...args: Args) => Result | Promise<Result>,\n keyParts: readonly unknown[] = [],\n options: FarmCacheOptions = {},\n): (...args: Args) => Promise<Result> {\n return async (...args: Args): Promise<Result> => {\n const locale = getActiveFarmI18nSnapshot()?.locale;\n const key = createFarmCacheKey([\n \"unstable_cache\",\n getFunctionCacheIdentity(fn),\n locale ? [\"locale\", locale] : null,\n keyParts,\n args,\n ]);\n return getFarmDataCache().getOrSet<Result>(key, () => fn(...args), options);\n };\n}\n\nexport function revalidateTag(_tag: string, _profile?: RevalidateTagProfile): void {\n getFarmDataCache().revalidateTag(_tag, {\n source: \"revalidateTag\",\n profile: _profile,\n });\n}\n\nexport function updateTag(tag: string): void {\n getFarmDataCache().revalidateTag(tag, { source: \"updateTag\" });\n}\n\nexport function revalidatePath(routePath: string): void {\n getFarmDataCache().revalidatePath(routePath);\n}\n\nexport function invalidate(key: RouteDataCacheKey): void {\n const clientKey = createRouteDataCacheKey(key);\n getFarmDataCache().revalidateTag(createRouteDataCacheTag(key), { source: \"updateTag\" });\n notifyFarmCacheInvalidation(clientKey);\n}\n\nexport function invalidateRouteData(key: RouteDataCacheKey): void {\n invalidate(key);\n}\n\nexport function createPathCacheTag(routePath: string): string {\n return `path:${normalizeRevalidatePath(routePath)}`;\n}\n\nexport function createRouteDataCacheTag(key: RouteDataCacheKey): string {\n return `route-data:${createRouteDataCacheKey(key)}`;\n}\n\nexport function createRouteDataCacheKey(key: RouteDataCacheKey): string {\n return createFarmCacheKey(Array.isArray(key) ? key : [key]);\n}\n\nexport function normalizeRevalidatePath(routePath: string): string {\n if (typeof routePath !== \"string\") {\n throw new TypeError(\"revalidatePath expects a path string.\");\n }\n\n let normalized = routePath.trim();\n if (!normalized) {\n throw new Error(\"revalidatePath expects a non-empty path.\");\n }\n\n try {\n if (/^https?:\\/\\//.test(normalized)) {\n normalized = new URL(normalized).pathname;\n }\n } catch {\n // Keep the original path if URL parsing fails.\n }\n\n normalized = normalized.split(\"?\")[0] ?? normalized;\n normalized = normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n normalized = normalized.replace(/\\/{2,}/g, \"/\");\n if (normalized.length > 1) {\n normalized = normalized.replace(/\\/+$/, \"\");\n }\n return normalized || \"/\";\n}\n\nexport function createFarmCacheKey(parts: readonly unknown[]): string {\n return stableSerialize(parts);\n}\n\nfunction normalizeRevalidate(revalidate: number | false | undefined): number | false | undefined {\n if (revalidate === false || revalidate === undefined) {\n return revalidate;\n }\n if (!Number.isFinite(revalidate) || revalidate <= 0) {\n return undefined;\n }\n return revalidate;\n}\n\nfunction normalizeCacheTag(tag: string): string {\n if (typeof tag !== \"string\") {\n throw new TypeError(\"Cache tags must be strings.\");\n }\n const normalized = tag.trim();\n if (!normalized) {\n throw new Error(\"Cache tags cannot be empty.\");\n }\n return normalized;\n}\n\nfunction getFunctionCacheIdentity(fn: Function): string {\n if (fn.name) {\n return `name:${fn.name}`;\n }\n\n let id = functionIds.get(fn);\n if (!id) {\n id = ++nextFunctionId;\n functionIds.set(fn, id);\n }\n return `anonymous:${id}`;\n}\n\nfunction stableSerialize(value: unknown, seen = new WeakSet<object>()): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n\n const valueType = typeof value;\n if (valueType === \"string\") return JSON.stringify(value);\n if (valueType === \"number\" || valueType === \"boolean\" || valueType === \"bigint\") {\n return `${valueType}:${String(value)}`;\n }\n if (valueType === \"symbol\") {\n return `symbol:${String(value)}`;\n }\n if (valueType === \"function\") {\n return `function:${getFunctionCacheIdentity(value as Function)}`;\n }\n\n if (value instanceof Date) {\n return `date:${value.toISOString()}`;\n }\n if (value instanceof URL) {\n return `url:${value.toString()}`;\n }\n if (value instanceof RegExp) {\n return `regexp:${value.toString()}`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerialize(item, seen)).join(\",\")}]`;\n }\n\n if (value && typeof value === \"object\") {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n const serialized = entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`)\n .join(\",\");\n\n seen.delete(value);\n return `{${serialized}}`;\n }\n\n return String(value);\n}\n","export type FarmRouteRuntime = \"auto\" | \"node\" | \"edge\";\nexport type FarmRouteRegions = \"auto\" | readonly string[];\nexport type FarmRouteMaxDuration = \"auto\" | number;\n\n/** Portable execution controls shared by file, programmatic, and config routes. */\nexport interface FarmRouteRuntimeConfig {\n runtime?: FarmRouteRuntime;\n regions?: FarmRouteRegions;\n maxDuration?: FarmRouteMaxDuration;\n}\n\nexport interface ResolvedFarmRouteRuntimeConfig {\n runtime: FarmRouteRuntime;\n regions?: string[];\n maxDuration?: number;\n}\n\nexport type FarmRouteRuntimeEntryKind = \"page\" | \"api\" | \"rule\";\nexport type FarmRouteRenderingMode = \"static\" | \"dynamic\";\n\nexport interface FarmRouteRuntimeManifestEntry extends ResolvedFarmRouteRuntimeConfig {\n kind: FarmRouteRuntimeEntryKind;\n pattern: string;\n rendering: FarmRouteRenderingMode;\n source?: string;\n}\n\nexport interface FarmRouteRuntimeManifest {\n version: 1;\n routes: FarmRouteRuntimeManifestEntry[];\n}\n\nexport function normalizeFarmRouteRuntimeConfig(\n value: FarmRouteRuntimeConfig | null | undefined,\n source = \"Route configuration\",\n): FarmRouteRuntimeConfig {\n if (!value) return {};\n\n const normalized: FarmRouteRuntimeConfig = {};\n\n if (value.runtime !== undefined) {\n if (value.runtime !== \"auto\" && value.runtime !== \"node\" && value.runtime !== \"edge\") {\n throw new TypeError(`${source} runtime must be \"auto\", \"node\", or \"edge\"`);\n }\n normalized.runtime = value.runtime;\n }\n\n if (value.regions !== undefined) {\n if (value.regions === \"auto\") {\n normalized.regions = \"auto\";\n } else {\n if (!Array.isArray(value.regions) || value.regions.length === 0) {\n throw new TypeError(`${source} regions must be \"auto\" or a non-empty string array`);\n }\n\n const regions = Array.from(\n new Set(\n value.regions.map((region) => {\n if (\n typeof region !== \"string\" ||\n !region.trim() ||\n /[\\u0000-\\u001f\\u007f]/.test(region)\n ) {\n throw new TypeError(`${source} regions must contain non-empty region identifiers`);\n }\n return region.trim();\n }),\n ),\n );\n\n normalized.regions = regions;\n }\n }\n\n if (value.maxDuration !== undefined) {\n if (value.maxDuration === \"auto\") {\n normalized.maxDuration = \"auto\";\n } else if (\n typeof value.maxDuration !== \"number\" ||\n !Number.isInteger(value.maxDuration) ||\n value.maxDuration <= 0\n ) {\n throw new TypeError(`${source} maxDuration must be \"auto\" or a positive integer in seconds`);\n } else {\n normalized.maxDuration = value.maxDuration;\n }\n }\n\n return normalized;\n}\n\n/** Merge from lowest to highest precedence. Explicit \"auto\" values reset inherited hints. */\nexport function mergeFarmRouteRuntimeConfigs(\n ...configs: Array<FarmRouteRuntimeConfig | null | undefined>\n): FarmRouteRuntimeConfig {\n const merged: FarmRouteRuntimeConfig = {};\n\n for (const config of configs) {\n if (!config) continue;\n if (config.runtime !== undefined) merged.runtime = config.runtime;\n if (config.regions !== undefined) merged.regions = config.regions;\n if (config.maxDuration !== undefined) merged.maxDuration = config.maxDuration;\n }\n\n return merged;\n}\n\nexport function resolveFarmRouteRuntimeConfig(\n config: FarmRouteRuntimeConfig | null | undefined,\n source?: string,\n): ResolvedFarmRouteRuntimeConfig {\n const normalized = normalizeFarmRouteRuntimeConfig(config, source);\n\n return {\n runtime: normalized.runtime ?? \"auto\",\n ...(normalized.regions && normalized.regions !== \"auto\"\n ? { regions: [...normalized.regions] }\n : {}),\n ...(typeof normalized.maxDuration === \"number\" ? { maxDuration: normalized.maxDuration } : {}),\n };\n}\n\nexport function hasFarmRouteRuntimeControls(\n config: FarmRouteRuntimeConfig | null | undefined,\n): boolean {\n return Boolean(\n config &&\n (config.runtime !== undefined ||\n config.regions !== undefined ||\n config.maxDuration !== undefined),\n );\n}\n\nexport function getFarmRouteRuntimeConfig(value: unknown): FarmRouteRuntimeConfig {\n if (!value || typeof value !== \"object\") return {};\n const route = value as FarmRouteRuntimeConfig;\n return {\n ...(route.runtime !== undefined ? { runtime: route.runtime } : {}),\n ...(route.regions !== undefined ? { regions: route.regions } : {}),\n ...(route.maxDuration !== undefined ? { maxDuration: route.maxDuration } : {}),\n };\n}\n\nexport function createFarmRouteRuntimeKey(config: ResolvedFarmRouteRuntimeConfig): string {\n return JSON.stringify({\n runtime: config.runtime,\n regions: config.regions || null,\n maxDuration: config.maxDuration || null,\n });\n}\n\n/** Resolve matching route rules from broadest to most specific. */\nexport function resolveFarmRouteRuleRuntimeConfig(\n pathname: string,\n routeRules: Record<string, FarmRouteRuntimeConfig> | null | undefined,\n): FarmRouteRuntimeConfig {\n if (!routeRules) return {};\n\n const matches = Object.entries(routeRules)\n .filter(\n ([pattern, rule]) =>\n hasFarmRouteRuntimeControls(rule) && farmRouteRuleMatches(pattern, pathname),\n )\n .sort(([left], [right]) => compareFarmRouteRuleSpecificity(left, right));\n\n return mergeFarmRouteRuntimeConfigs(...matches.map(([, rule]) => rule));\n}\n\nexport function farmRouteRuleMatches(pattern: string, pathname: string): boolean {\n const normalizedPattern = normalizeRoutePattern(pattern);\n const normalizedPathname = normalizeRoutePattern(pathname);\n if (normalizedPattern === normalizedPathname) return true;\n\n const expression = normalizedPattern\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment === \"**\") return \".*\";\n if (segment === \"*\") return \"[^/]+\";\n if (/^\\[\\[\\.\\.\\..+\\]\\]$/.test(segment)) return \".*\";\n if (/^\\[\\.\\.\\..+\\]$/.test(segment)) return \".+\";\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return \"[^/]+\";\n return escapeRegExp(segment);\n })\n .join(\"/\");\n\n return new RegExp(`^/${expression}/?$`).test(normalizedPathname);\n}\n\nfunction compareFarmRouteRuleSpecificity(left: string, right: string): number {\n const leftScore = getFarmRouteRuleSpecificity(left);\n const rightScore = getFarmRouteRuleSpecificity(right);\n return leftScore - rightScore || left.localeCompare(right);\n}\n\nfunction getFarmRouteRuleSpecificity(pattern: string): number {\n return normalizeRoutePattern(pattern)\n .split(\"/\")\n .filter(Boolean)\n .reduce((score, segment) => {\n if (segment === \"**\" || segment.startsWith(\"[[...\")) return score + 1;\n if (segment === \"*\" || segment.startsWith(\"[...\")) return score + 10;\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return score + 50;\n return score + 100;\n }, 0);\n}\n\nfunction normalizeRoutePattern(value: string): string {\n const withSlash = value.trim().startsWith(\"/\") ? value.trim() : `/${value.trim()}`;\n return withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport {\n PROGRAMMATIC_ROUTE_FILE_NAMES,\n getProgrammaticRouteManifest,\n scanProgrammaticPagePaths,\n type ProgrammaticRouteManifest,\n} from \"./routes\";\n\nexport interface LoadedProgrammaticRouteManifest {\n filePath: string;\n manifest: ProgrammaticRouteManifest;\n}\n\nexport async function loadProgrammaticRouteManifests(options: {\n root: string;\n srcDir?: string;\n loadModule: (filePath: string) => Promise<Record<string, any>>;\n}): Promise<LoadedProgrammaticRouteManifest[]> {\n const manifests: LoadedProgrammaticRouteManifest[] = [];\n\n for (const filePath of findProgrammaticRouteFiles(options.root, options.srcDir)) {\n const mod = await options.loadModule(filePath);\n const manifest = getProgrammaticRouteManifest(mod);\n if (manifest) {\n manifests.push({ filePath, manifest });\n }\n }\n\n return manifests;\n}\n\nexport function findProgrammaticRouteFiles(root: string, srcDir = \"src\"): string[] {\n return findProgrammaticRouteFilesInDir(join(root, srcDir));\n}\n\nexport function findProgrammaticRouteFilesInDir(srcRoot: string): string[] {\n const files: string[] = [];\n\n for (const fileName of PROGRAMMATIC_ROUTE_FILE_NAMES) {\n const filePath = join(srcRoot, fileName);\n if (existsSync(filePath)) {\n files.push(filePath);\n }\n }\n\n return files;\n}\n\nexport async function discoverProgrammaticRoutePaths(\n root: string,\n srcDir = \"src\",\n): Promise<string[]> {\n const paths = new Set<string>();\n const files = new Set([\n ...findProgrammaticRouteFiles(root, srcDir),\n ...(await findProgrammaticRouteSourceFiles(join(root, srcDir))),\n ]);\n\n for (const filePath of files) {\n const source = readFileSync(filePath, \"utf8\");\n for (const routePath of scanProgrammaticPagePaths(source)) {\n paths.add(routePath);\n }\n }\n\n return Array.from(paths).sort();\n}\n\nasync function findProgrammaticRouteSourceFiles(srcRoot: string): Promise<string[]> {\n if (!existsSync(srcRoot)) {\n return [];\n }\n\n try {\n const glob = await import(\"fast-glob\");\n return await glob.default(\"**/*.{ts,tsx,js,jsx}\", {\n cwd: srcRoot,\n absolute: true,\n ignore: [\n \"**/*.d.ts\",\n \"**/node_modules/**\",\n \"**/.*/**\",\n \"farm-routes.d.ts\",\n \"farm-env.d.ts\",\n \"lib/api.generated.ts\",\n ],\n });\n } catch {\n return [];\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { FarmLocaleResolution } from \"./resolver\";\nimport { _setFarmI18nSnapshotResolver } from \"./bridge\";\nimport { FarmI18nRuntime, createFarmI18nRuntime } from \"./runtime\";\nimport type {\n FarmI18nClientSnapshot,\n FarmI18nLocale,\n FarmI18nLocaleSource,\n FarmI18nMessageArgs,\n FarmI18nMessageKey,\n FarmTranslator,\n} from \"./types\";\n\ninterface FarmI18nRequestState {\n runtime: FarmI18nRuntime;\n resolution: FarmLocaleResolution;\n snapshot: FarmI18nClientSnapshot;\n}\n\ninterface FarmListFormatOptions {\n localeMatcher?: \"lookup\" | \"best fit\";\n type?: \"conjunction\" | \"disjunction\" | \"unit\";\n style?: \"long\" | \"short\" | \"narrow\";\n}\n\nconst FARM_I18N_REQUEST_STORE = Symbol.for(\"farm.i18n.requestStore\");\nconst FARM_I18N_DEFAULT_RUNTIME = Symbol.for(\"farm.i18n.defaultRuntime\");\n\ntype GlobalFarmI18nState = typeof globalThis & {\n [FARM_I18N_REQUEST_STORE]?: AsyncLocalStorage<FarmI18nRequestState>;\n [FARM_I18N_DEFAULT_RUNTIME]?: FarmI18nRuntime;\n};\n\nfunction getRequestStore(): AsyncLocalStorage<FarmI18nRequestState> {\n const state = globalThis as GlobalFarmI18nState;\n return (state[FARM_I18N_REQUEST_STORE] ??= new AsyncLocalStorage<FarmI18nRequestState>());\n}\n\nfunction getState(): FarmI18nRequestState {\n const state = getRequestStore().getStore();\n if (!state) {\n throw new Error(\n \"No Farm i18n request context is active. Use this API while rendering, inside an API route, or use createTranslator(locale).\",\n );\n }\n return state;\n}\n\nexport function _setDefaultFarmI18nRuntime(runtime: FarmI18nRuntime | undefined): void {\n (globalThis as GlobalFarmI18nState)[FARM_I18N_DEFAULT_RUNTIME] = runtime;\n}\n\nexport async function _runWithFarmI18nRequest<T>(\n runtime: FarmI18nRuntime,\n request: Request,\n fn: (resolution: FarmLocaleResolution) => T | Promise<T>,\n options: { redirect?: boolean } = {},\n): Promise<T> {\n const resolution = runtime.resolveRequest(request, options);\n const state: FarmI18nRequestState = {\n runtime,\n resolution,\n snapshot: runtime.getClientSnapshot(resolution),\n };\n return getRequestStore().run(state, () => fn(resolution));\n}\n\nexport async function runWithLocale<T>(\n locale: FarmI18nLocale,\n fn: () => T | Promise<T>,\n): Promise<T> {\n const runtime = getDefaultRuntime();\n assertLocale(runtime, locale);\n const resolution: FarmLocaleResolution = {\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n };\n const state: FarmI18nRequestState = {\n runtime,\n resolution,\n snapshot: runtime.getClientSnapshot(resolution),\n };\n return getRequestStore().run(state, fn);\n}\n\nexport function getLocale(): FarmI18nLocale {\n return getState().resolution.locale as FarmI18nLocale;\n}\n\nexport function getLocaleSource(): FarmI18nLocaleSource {\n return getState().resolution.source;\n}\n\nexport const t = createTranslatorFromState(() => getState());\n\nexport function createTranslator(locale: FarmI18nLocale): FarmTranslator {\n const runtime = getDefaultRuntime();\n assertLocale(runtime, locale);\n return createTranslatorFromState(() => ({\n runtime,\n resolution: {\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n },\n snapshot: runtime.getClientSnapshot({\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n }),\n }));\n}\n\nexport function getFarmI18nClientSnapshot(): FarmI18nClientSnapshot | undefined {\n return getRequestStore().getStore()?.snapshot;\n}\n\nexport const format = {\n number(value: number, options?: Intl.NumberFormatOptions): string {\n return new Intl.NumberFormat(getLocale(), options).format(value);\n },\n currency(\n value: number,\n currency: string,\n options: Omit<Intl.NumberFormatOptions, \"style\" | \"currency\"> = {},\n ): string {\n return new Intl.NumberFormat(getLocale(), {\n ...options,\n style: \"currency\",\n currency,\n }).format(value);\n },\n date(value: Date | number, options?: Intl.DateTimeFormatOptions): string {\n return new Intl.DateTimeFormat(getLocale(), options).format(value);\n },\n relativeTime(\n value: number,\n unit: Intl.RelativeTimeFormatUnit,\n options?: Intl.RelativeTimeFormatOptions,\n ): string {\n return new Intl.RelativeTimeFormat(getLocale(), options).format(value, unit);\n },\n list(values: Iterable<string>, options?: FarmListFormatOptions): string {\n const ListFormat = (Intl as any).ListFormat;\n return new ListFormat(getLocale(), options).format(Array.from(values));\n },\n};\n\nfunction getDefaultRuntime(): FarmI18nRuntime {\n const runtime = (globalThis as GlobalFarmI18nState)[FARM_I18N_DEFAULT_RUNTIME];\n if (!runtime?.config.enabled) {\n throw new Error(\"Farm i18n is not configured for this application.\");\n }\n return runtime;\n}\n\nfunction assertLocale(runtime: FarmI18nRuntime, locale: string): void {\n if (!runtime.config.locales.includes(locale)) {\n throw new Error(`Unsupported Farm i18n locale \"${locale}\".`);\n }\n}\n\nfunction createTranslatorFromState(resolveState: () => FarmI18nRequestState): FarmTranslator {\n const translator = ((key: string, values?: Record<string, unknown>) => {\n const state = resolveState();\n return state.runtime.translate(state.resolution.locale, key, values);\n }) as FarmTranslator;\n translator.rich = (key: string, values?: Record<string, unknown>) => {\n const state = resolveState();\n return state.runtime.translateRich(state.resolution.locale, key, values);\n };\n translator.raw = (key: string) => {\n const state = resolveState();\n return state.runtime.getRawMessage(state.resolution.locale, key);\n };\n translator.has = (key: string) => {\n const state = resolveState();\n return state.runtime.hasMessage(state.resolution.locale, key);\n };\n return translator;\n}\n\n_setFarmI18nSnapshotResolver(() => getFarmI18nClientSnapshot());\n\nexport { FarmI18nRuntime, createFarmI18nRuntime };\nexport type { FarmI18nClientSnapshot, FarmI18nLocale, FarmI18nMessageArgs, FarmI18nMessageKey };\n","import IntlMessageFormat from \"intl-messageformat\";\nimport { readFarmI18nCatalogs } from \"./catalog\";\nimport { getFarmLocaleDirection } from \"./routing\";\nimport { resolveFarmLocaleRequest, type FarmLocaleResolution } from \"./resolver\";\nimport type { FarmI18nCatalogs, FarmI18nClientSnapshot, ResolvedFarmI18nConfig } from \"./types\";\n\nexport class FarmI18nRuntime {\n readonly config: ResolvedFarmI18nConfig;\n private catalogs: FarmI18nCatalogs;\n private compiled = new Map<string, IntlMessageFormat>();\n private warnedMissing = new Set<string>();\n\n constructor(config: ResolvedFarmI18nConfig, catalogs: FarmI18nCatalogs = {}) {\n this.config = config;\n this.catalogs = catalogs;\n }\n\n async initialize(): Promise<void> {\n if (!this.config.enabled) return;\n const bundle = await readFarmI18nCatalogs(this.config);\n this.replaceCatalogs(bundle.catalogs);\n }\n\n async reload(): Promise<void> {\n await this.initialize();\n }\n\n replaceCatalogs(catalogs: FarmI18nCatalogs): void {\n this.catalogs = catalogs;\n this.compiled.clear();\n this.warnedMissing.clear();\n }\n\n getCatalogs(): FarmI18nCatalogs {\n return Object.fromEntries(\n Object.entries(this.catalogs).map(([locale, catalog]) => [locale, { ...catalog }]),\n );\n }\n\n resolveRequest(request: Request, options: { redirect?: boolean } = {}): FarmLocaleResolution {\n return resolveFarmLocaleRequest(request, this.config, options);\n }\n\n translate(locale: string, key: string, values?: Record<string, unknown>): string {\n const result = this.formatMessage(locale, key, values);\n if (Array.isArray(result) && result.some((part) => typeof part !== \"string\")) {\n throw new Error(`Farm i18n message \"${key}\" contains rich content. Render it with t.rich().`);\n }\n return Array.isArray(result) ? result.join(\"\") : String(result);\n }\n\n translateRich(locale: string, key: string, values?: Record<string, unknown>): unknown {\n const result = this.formatMessage(locale, key, values);\n return Array.isArray(result) && result.length === 1 ? result[0] : result;\n }\n\n getRawMessage(locale: string, key: string): string {\n return this.resolveMessage(locale, key);\n }\n\n hasMessage(locale: string, key: string): boolean {\n return (\n (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !==\n undefined\n );\n }\n\n getClientSnapshot(resolution: FarmLocaleResolution): FarmI18nClientSnapshot {\n return {\n locale: resolution.locale,\n source: resolution.source,\n locales: this.config.locales,\n defaultLocale: this.config.defaultLocale,\n routing: this.config.routing,\n cookie: this.config.cookie,\n direction: getFarmLocaleDirection(resolution.locale, this.config.direction),\n messages: {\n ...this.catalogs[this.config.fallbackLocale],\n ...this.catalogs[resolution.locale],\n },\n };\n }\n\n private formatMessage(locale: string, key: string, values?: Record<string, unknown>): unknown {\n const message = this.resolveMessage(locale, key);\n const cacheKey = `${locale}\\u0000${key}\\u0000${message}`;\n let formatter = this.compiled.get(cacheKey);\n if (!formatter) {\n formatter = new IntlMessageFormat(message, locale);\n this.compiled.set(cacheKey, formatter);\n }\n return formatter.format(values as any);\n }\n\n private resolveMessage(locale: string, key: string): string {\n const message =\n this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];\n if (message !== undefined) return message;\n if (this.config.strict) {\n throw new Error(`Missing Farm i18n message \"${key}\" for locale \"${locale}\".`);\n }\n const warningKey = `${locale}:${key}`;\n if (!this.warnedMissing.has(warningKey)) {\n this.warnedMissing.add(warningKey);\n console.warn(`[Farm.js] Missing i18n message \"${key}\" for locale \"${locale}\".`);\n }\n return key;\n }\n}\n\nexport function createFarmI18nRuntime(\n config: ResolvedFarmI18nConfig,\n catalogs?: FarmI18nCatalogs,\n): FarmI18nRuntime {\n return new FarmI18nRuntime(config, catalogs);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { TYPE, parse, type MessageFormatElement } from \"@formatjs/icu-messageformat-parser\";\nimport { resolveFarmI18nMessagePath } from \"./config\";\nimport type { FarmI18nCatalog, FarmI18nCatalogs, ResolvedFarmI18nConfig } from \"./types\";\n\nexport type FarmI18nArgumentKind = \"string\" | \"number\" | \"date\" | \"select\" | \"rich\";\nexport type FarmI18nMessageSignature = Record<string, FarmI18nArgumentKind>;\n\nexport interface FarmI18nCatalogBundle {\n catalogs: FarmI18nCatalogs;\n signatures: Record<string, FarmI18nMessageSignature>;\n}\n\nexport async function readFarmI18nCatalogs(\n config: ResolvedFarmI18nConfig,\n): Promise<FarmI18nCatalogBundle> {\n if (!config.enabled) {\n return { catalogs: {}, signatures: {} };\n }\n\n const catalogs: FarmI18nCatalogs = {};\n for (const locale of config.locales) {\n const filePath = resolveFarmI18nMessagePath(config, locale);\n let source: string;\n try {\n source = await readFile(filePath, \"utf8\");\n } catch (error) {\n throw new Error(\n `Unable to read Farm i18n catalog for \"${locale}\" at ${filePath}: ${messageOf(error)}`,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (error) {\n throw new Error(`Invalid JSON in Farm i18n catalog ${filePath}: ${messageOf(error)}`);\n }\n catalogs[locale] = flattenFarmI18nCatalog(parsed, filePath);\n }\n\n const reference = catalogs[config.defaultLocale] || {};\n const signatures: Record<string, FarmI18nMessageSignature> = {};\n for (const [key, message] of Object.entries(reference)) {\n signatures[key] = analyzeFarmI18nMessage(message, `${config.defaultLocale}:${key}`);\n }\n\n validateFarmI18nCatalogs(config, catalogs, signatures);\n return { catalogs, signatures };\n}\n\nexport function flattenFarmI18nCatalog(input: unknown, source = \"i18n catalog\"): FarmI18nCatalog {\n if (!isPlainObject(input)) {\n throw new Error(`${source} must contain a JSON object at its root.`);\n }\n\n const output: FarmI18nCatalog = {};\n const visit = (value: unknown, segments: string[]) => {\n if (typeof value === \"string\") {\n const key = segments.join(\".\");\n if (!key) throw new Error(`${source} contains an empty message key.`);\n if (key in output) throw new Error(`${source} contains duplicate message key \"${key}\".`);\n output[key] = value;\n return;\n }\n\n if (!isPlainObject(value)) {\n const key = segments.join(\".\") || \"<root>\";\n throw new Error(`${source} message \"${key}\" must be a string or nested object.`);\n }\n\n for (const [key, nested] of Object.entries(value)) {\n if (!key.trim()) throw new Error(`${source} contains an empty message key.`);\n visit(nested, [...segments, key]);\n }\n };\n\n visit(input, []);\n return output;\n}\n\nexport function analyzeFarmI18nMessage(\n message: string,\n label = \"message\",\n): FarmI18nMessageSignature {\n let ast: MessageFormatElement[];\n try {\n ast = parse(message, { captureLocation: false });\n } catch (error) {\n throw new Error(`Invalid ICU syntax in ${label}: ${messageOf(error)}`);\n }\n\n const signature: FarmI18nMessageSignature = {};\n collectArguments(ast, signature, label);\n return signature;\n}\n\nfunction validateFarmI18nCatalogs(\n config: ResolvedFarmI18nConfig,\n catalogs: FarmI18nCatalogs,\n signatures: Record<string, FarmI18nMessageSignature>,\n): void {\n const referenceKeys = Object.keys(catalogs[config.defaultLocale] || {}).sort();\n\n for (const locale of config.locales) {\n const catalog = catalogs[locale] || {};\n const localeKeys = Object.keys(catalog).sort();\n const missing = referenceKeys.filter((key) => !(key in catalog));\n const extra = localeKeys.filter((key) => !(key in signatures));\n\n if (config.strict && (missing.length > 0 || extra.length > 0)) {\n const details = [\n missing.length ? `missing: ${missing.join(\", \")}` : \"\",\n extra.length ? `extra: ${extra.join(\", \")}` : \"\",\n ]\n .filter(Boolean)\n .join(\"; \");\n throw new Error(\n `Farm i18n catalog \"${locale}\" does not match the default catalog (${details}).`,\n );\n }\n\n for (const [key, message] of Object.entries(catalog)) {\n const actual = analyzeFarmI18nMessage(message, `${locale}:${key}`);\n const expected = signatures[key];\n if (!expected || sameSignature(expected, actual)) continue;\n throw new Error(\n `Farm i18n message \"${key}\" in \"${locale}\" uses different variables than \"${config.defaultLocale}\".`,\n );\n }\n }\n}\n\nfunction collectArguments(\n elements: MessageFormatElement[],\n signature: FarmI18nMessageSignature,\n label: string,\n): void {\n for (const element of elements) {\n switch (element.type) {\n case TYPE.argument:\n addArgument(signature, element.value, \"string\", label);\n break;\n case TYPE.number:\n case TYPE.plural:\n addArgument(signature, element.value, \"number\", label);\n break;\n case TYPE.date:\n case TYPE.time:\n addArgument(signature, element.value, \"date\", label);\n break;\n case TYPE.select:\n addArgument(signature, element.value, \"select\", label);\n break;\n case TYPE.tag:\n addArgument(signature, element.value, \"rich\", label);\n collectArguments(element.children, signature, label);\n break;\n }\n\n if (element.type === TYPE.plural || element.type === TYPE.select) {\n for (const option of Object.values(element.options)) {\n collectArguments(option.value, signature, label);\n }\n }\n }\n}\n\nfunction addArgument(\n signature: FarmI18nMessageSignature,\n name: string,\n kind: FarmI18nArgumentKind,\n label: string,\n): void {\n const existing = signature[name];\n if (existing && existing !== kind) {\n throw new Error(`Farm i18n ${label} uses variable \"${name}\" as both ${existing} and ${kind}.`);\n }\n signature[name] = kind;\n}\n\nfunction sameSignature(\n expected: FarmI18nMessageSignature,\n actual: FarmI18nMessageSignature,\n): boolean {\n const expectedEntries = Object.entries(expected).sort(([a], [b]) => a.localeCompare(b));\n const actualEntries = Object.entries(actual).sort(([a], [b]) => a.localeCompare(b));\n return JSON.stringify(expectedEntries) === JSON.stringify(actualEntries);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import path from \"node:path\";\nimport type {\n FarmI18nDetectionSignal,\n FarmI18nDirection,\n FarmI18nUserConfig,\n ResolvedFarmI18nConfig,\n} from \"./types\";\n\nexport const DEFAULT_FARM_I18N_COOKIE = \"farm_locale\";\nexport const DEFAULT_FARM_I18N_COOKIE_MAX_AGE = 60 * 60 * 24 * 365;\n\nconst DEFAULT_DETECTION: readonly FarmI18nDetectionSignal[] = [\"url\", \"cookie\", \"accept-language\"];\n\nexport function resolveFarmI18nConfig(\n input: FarmI18nUserConfig | false | undefined,\n options: { root?: string; mode?: \"development\" | \"production\" } = {},\n): ResolvedFarmI18nConfig {\n const root = options.root || process.cwd();\n const strictByDefault = options.mode === \"production\";\n\n if (!input) {\n return {\n enabled: false,\n locales: [\"en\"],\n defaultLocale: \"en\",\n messages: path.join(root, \"src/messages\"),\n routing: \"none\",\n detection: [],\n fallbackLocale: \"en\",\n strict: strictByDefault,\n cookie: {\n name: DEFAULT_FARM_I18N_COOKIE,\n maxAge: DEFAULT_FARM_I18N_COOKIE_MAX_AGE,\n path: \"/\",\n sameSite: \"lax\",\n secure: options.mode === \"production\",\n },\n direction: {},\n };\n }\n\n if (!Array.isArray(input.locales) || input.locales.length === 0) {\n throw new Error(\"i18n.locales must contain at least one locale.\");\n }\n\n const locales = input.locales.map(canonicalizeLocale);\n if (new Set(locales).size !== locales.length) {\n throw new Error(\"i18n.locales must not contain duplicate locales.\");\n }\n\n const defaultLocale = canonicalizeLocale(input.defaultLocale);\n if (!locales.includes(defaultLocale)) {\n throw new Error(`i18n.defaultLocale \"${defaultLocale}\" must be included in i18n.locales.`);\n }\n\n const fallbackLocale = canonicalizeLocale(input.fallbackLocale || defaultLocale);\n if (!locales.includes(fallbackLocale)) {\n throw new Error(`i18n.fallbackLocale \"${fallbackLocale}\" must be included in i18n.locales.`);\n }\n\n const detection = resolveDetection(input);\n const direction: Record<string, FarmI18nDirection> = {};\n for (const [rawLocale, value] of Object.entries(input.direction || {})) {\n const locale = canonicalizeLocale(rawLocale);\n if (!locales.includes(locale)) {\n throw new Error(`i18n.direction contains unknown locale \"${rawLocale}\".`);\n }\n if (value !== \"ltr\" && value !== \"rtl\") {\n throw new Error(`i18n.direction.${rawLocale} must be \"ltr\" or \"rtl\".`);\n }\n direction[locale] = value;\n }\n\n return {\n enabled: true,\n locales,\n defaultLocale,\n messages: path.resolve(root, input.messages || \"src/messages\"),\n routing: input.routing || \"prefix-except-default\",\n detection,\n fallbackLocale,\n strict: input.strict ?? strictByDefault,\n cookie: {\n name: input.cookie?.name?.trim() || DEFAULT_FARM_I18N_COOKIE,\n maxAge: normalizePositiveInteger(\n input.cookie?.maxAge,\n DEFAULT_FARM_I18N_COOKIE_MAX_AGE,\n \"i18n.cookie.maxAge\",\n ),\n path: input.cookie?.path || \"/\",\n sameSite: input.cookie?.sameSite || \"lax\",\n secure: input.cookie?.secure ?? options.mode === \"production\",\n },\n direction,\n };\n}\n\nexport function resolveFarmI18nMessagePath(\n config: Pick<ResolvedFarmI18nConfig, \"messages\">,\n locale: string,\n): string {\n return config.messages.includes(\"{locale}\")\n ? config.messages.split(\"{locale}\").join(locale)\n : path.join(config.messages, `${locale}.json`);\n}\n\nexport function canonicalizeLocale(locale: string): string {\n if (!locale || typeof locale !== \"string\") {\n throw new Error(\"Farm i18n locales must be non-empty strings.\");\n }\n\n try {\n return Intl.getCanonicalLocales(locale)[0]!;\n } catch {\n throw new Error(`Invalid i18n locale \"${locale}\".`);\n }\n}\n\nfunction resolveDetection(input: FarmI18nUserConfig): readonly FarmI18nDetectionSignal[] {\n if (input.detection === false || input.localeDetection === false) {\n return [\"url\"];\n }\n\n const detection = input.detection || DEFAULT_DETECTION;\n const allowed = new Set<FarmI18nDetectionSignal>([\"url\", \"cookie\", \"accept-language\"]);\n const unique: FarmI18nDetectionSignal[] = [];\n\n for (const signal of detection) {\n if (!allowed.has(signal)) {\n throw new Error(`Unsupported i18n detection signal \"${signal}\".`);\n }\n if (!unique.includes(signal)) unique.push(signal);\n }\n\n return unique;\n}\n\nfunction normalizePositiveInteger(\n value: number | undefined,\n fallback: number,\n name: string,\n): number {\n if (value === undefined) return fallback;\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} must be a positive integer.`);\n }\n return value;\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { FarmRequest } from \"../types\";\nimport { _setCurrentRequestResolver } from \"./request-bridge\";\n\nconst REQUEST_STORAGE_KEY = Symbol.for(\"@farm.js/core/request-storage\");\n\nfunction getRequestStore(): AsyncLocalStorage<Request> {\n const runtime = globalThis as typeof globalThis & Record<PropertyKey, unknown>;\n const existing = runtime[REQUEST_STORAGE_KEY];\n if (existing instanceof AsyncLocalStorage) {\n return existing as AsyncLocalStorage<Request>;\n }\n\n const storage = new AsyncLocalStorage<Request>();\n runtime[REQUEST_STORAGE_KEY] = storage;\n return storage;\n}\n\nconst requestStore = getRequestStore();\n\n_setCurrentRequestResolver(() => requestStore.getStore());\n\nexport function createWebRequestFromFarmRequest(req: FarmRequest): Request {\n const forwardedHost = req.headers[\"x-forwarded-host\"];\n const host = Array.isArray(forwardedHost)\n ? forwardedHost[0]\n : forwardedHost || req.headers.host || \"localhost\";\n const forwardedProto = req.headers[\"x-forwarded-proto\"];\n const proto = Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto || \"http\";\n const fullUrl = new URL(req.url || \"/\", `${proto}://${host}`).toString();\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value == null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(key, item);\n }\n continue;\n }\n\n headers.set(key, value);\n }\n\n return new Request(fullUrl, {\n method: req.method,\n headers,\n });\n}\n\nexport async function _runWithCurrentRequest<T>(\n request: Request,\n fn: () => Promise<T> | T,\n): Promise<T> {\n return requestStore.run(request, fn);\n}\n\nexport function getCurrentRequest(): Request {\n const request = requestStore.getStore();\n if (!request) {\n throw new Error(\n \"No current request is available. getCurrentRequest() can only be used during server rendering.\",\n );\n }\n\n return request;\n}\n","type CurrentRequestResolver = () => Request | undefined;\n\nconst CURRENT_REQUEST_RESOLVER_KEY = Symbol.for(\"farm.currentRequestResolver\");\n\ntype GlobalWithCurrentRequestResolver = typeof globalThis & {\n [CURRENT_REQUEST_RESOLVER_KEY]?: CurrentRequestResolver;\n};\n\nfunction getGlobalState(): GlobalWithCurrentRequestResolver {\n return globalThis as GlobalWithCurrentRequestResolver;\n}\n\nexport function _setCurrentRequestResolver(resolver: CurrentRequestResolver | undefined): void {\n getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY] = resolver;\n}\n\nexport function _resolveCurrentRequest(): Request | undefined {\n return getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY]?.();\n}\n","import { createEndpoint as betterCallEndpoint } from \"better-call\";\nimport {\n createRouteDataCacheKey,\n invalidate,\n revalidatePath,\n type RouteDataCacheKey,\n} from \"../cache\";\n\n// Generic schema type that works with both Zod v3 and v4\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySchema = { _output?: any; _input?: any; parse?: (data: unknown) => any };\n\ntype MaybePromise<T> = T | Promise<T>;\ntype Simplify<T> = { [TKey in keyof T]: T[TKey] } & {};\ntype UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (\n value: infer TIntersection,\n) => void\n ? TIntersection\n : never;\n\n// Infer output type from schema (works with Zod v3 and v4)\ntype InferOutput<T> = T extends { _output: infer O }\n ? O\n : T extends { parse: (data: unknown) => infer R }\n ? R\n : unknown;\n\ntype InferHeadersOutput<T> = [T] extends [never]\n ? Record<string, string>\n : T extends AnySchema\n ? InferOutput<T>\n : Record<string, string>;\n\nexport type EndpointErrorDefinition<\n TSchema extends AnySchema = AnySchema,\n TStatus extends number = number,\n> = {\n status: TStatus;\n schema: TSchema;\n /** Public message safe to expose to API callers. */\n message?: string;\n};\n\nexport type EndpointErrorDefinitions = Record<string, EndpointErrorDefinition<AnySchema, number>>;\n\nexport type EndpointErrorContracts<TErrors extends EndpointErrorDefinitions> = {\n [TCode in keyof TErrors]: {\n data: InferOutput<TErrors[TCode][\"schema\"]>;\n status: TErrors[TCode][\"status\"];\n };\n};\n\nexport type EndpointFail<TErrors extends EndpointErrorDefinitions> = <\n TCode extends keyof TErrors & string,\n>(\n code: TCode,\n data: InferOutput<TErrors[TCode][\"schema\"]>,\n) => never;\n\nexport class EndpointFailure<TCode extends string = string, TData = unknown> extends Error {\n readonly code: TCode;\n readonly data: TData;\n readonly status: number;\n\n constructor(\n code: TCode,\n data: TData,\n options: {\n status: number;\n message: string;\n },\n ) {\n super(options.message);\n this.name = \"EndpointFailure\";\n this.code = code;\n this.data = data;\n this.status = options.status;\n }\n}\n\nexport function isEndpointFailure(value: unknown): value is EndpointFailure<string, unknown> {\n return value instanceof EndpointFailure;\n}\n\nexport type EndpointParamValue = string | string[];\nexport type EndpointParams = Record<string, EndpointParamValue>;\n\nexport type EndpointMiddlewareContext<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = {\n body: TBody;\n query: TQuery;\n headers: THeaders;\n request: Request;\n /** Context accumulated from middleware that ran earlier in the chain. */\n context: Readonly<TContext>;\n params: EndpointParams;\n};\n\nexport type EndpointMiddlewareResult<TProvidedContext extends object = object> =\n | TProvidedContext\n | true\n | false\n | Response;\n\n/** A plain async function. No wrapper or `next()` callback is required. */\nexport type EndpointMiddleware<\n TProvidedContext extends object = object,\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = (\n ctx: EndpointMiddlewareContext<TContext, TBody, TQuery, THeaders>,\n) => MaybePromise<EndpointMiddlewareResult<TProvidedContext>>;\n\nexport type AnyEndpointMiddleware = (ctx: EndpointMiddlewareContext<any, any, any, any>) => unknown;\n\nexport type EndpointInvalidationTarget =\n | {\n key: RouteDataCacheKey;\n }\n | {\n path: string;\n };\n\nexport type EndpointInvalidationContext<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = EndpointMiddlewareContext<TContext, TBody, TQuery, THeaders> & {\n /** The raw value returned by the endpoint handler. */\n result: unknown;\n};\n\nexport type EndpointInvalidations<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> =\n | readonly EndpointInvalidationTarget[]\n | ((\n context: EndpointInvalidationContext<TContext, TBody, TQuery, THeaders>,\n ) => readonly EndpointInvalidationTarget[] | Promise<readonly EndpointInvalidationTarget[]>);\n\ntype ValidateEndpointMiddlewares<TMiddlewares extends readonly AnyEndpointMiddleware[]> = {\n readonly [TIndex in keyof TMiddlewares]: TMiddlewares[TIndex] extends AnyEndpointMiddleware\n ? [Awaited<ReturnType<TMiddlewares[TIndex]>>] extends [EndpointMiddlewareResult<object>]\n ? TMiddlewares[TIndex]\n : never\n : never;\n};\n\ntype ContextFromMiddlewareResult<TResult> =\n Exclude<TResult, Response | boolean> extends infer TContext\n ? [TContext] extends [never]\n ? {}\n : TContext extends object\n ? TContext\n : {}\n : {};\n\ntype ContextFromMiddleware<TMiddleware> = TMiddleware extends (...args: any[]) => infer TResult\n ? ContextFromMiddlewareResult<Awaited<TResult>>\n : {};\n\nexport type InferEndpointMiddlewareContext<\n TMiddlewares extends readonly ((...args: any[]) => any)[],\n TContext extends object = {},\n> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest]\n ? TMiddleware extends (...args: any[]) => any\n ? TRest extends readonly ((...args: any[]) => any)[]\n ? InferEndpointMiddlewareContext<\n TRest,\n Simplify<TContext & ContextFromMiddleware<TMiddleware>>\n >\n : Simplify<TContext>\n : Simplify<TContext>\n : number extends TMiddlewares[\"length\"]\n ? Simplify<TContext & UnionToIntersection<ContextFromMiddleware<TMiddlewares[number]>>>\n : Simplify<TContext>;\n\nexport type EndpointOptions<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TMiddlewares extends readonly AnyEndpointMiddleware[] = readonly [],\n TErrors extends EndpointErrorDefinitions = {},\n> = {\n method?: \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\";\n body?: TBody;\n query?: TQuery;\n headers?: THeaders;\n middleware?: TMiddlewares;\n /**\n * Cache keys and route paths made stale after a successful handler result.\n * The resolver receives validated input and middleware context.\n */\n invalidates?: EndpointInvalidations<\n InferEndpointMiddlewareContext<TMiddlewares>,\n InferOutput<TBody>,\n InferOutput<TQuery>,\n InferHeadersOutput<THeaders>\n >;\n errors?: TErrors;\n /** @deprecated Use plain functions in `middleware` for Farm endpoint middleware. */\n use?: any[];\n};\n\nexport type EndpointHandler<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n TContext extends object = {},\n TErrors extends EndpointErrorDefinitions = {},\n> = (ctx: {\n body: InferOutput<TBody>;\n query: InferOutput<TQuery>;\n headers: InferHeadersOutput<THeaders>;\n request: Request;\n context: Readonly<TContext>;\n params: EndpointParams;\n fail: EndpointFail<TErrors>;\n}) => Promise<TResponse> | TResponse;\n\n// Type to represent an endpoint with its input/output types\nexport type TypedEndpoint<\n TBody = never,\n TQuery = never,\n TResponse = any,\n THeaders = Record<string, string>,\n TErrors = never,\n> = {\n __types: {\n body: TBody;\n query: TQuery;\n headers: THeaders;\n response: TResponse;\n errors: TErrors;\n };\n __path?: string;\n __method?: string;\n} & ((options?: { body?: TBody; query?: TQuery }) => Promise<TResponse>);\n\ntype CreatedEndpoint<\n TBody extends AnySchema,\n TQuery extends AnySchema,\n THeaders extends AnySchema,\n TResponse,\n TErrors extends EndpointErrorDefinitions = {},\n> = TypedEndpoint<\n InferOutput<TBody>,\n InferOutput<TQuery>,\n Awaited<TResponse>,\n InferHeadersOutput<THeaders>,\n EndpointErrorContracts<TErrors>\n>;\n\ntype AnyEndpointOptions = EndpointOptions<\n AnySchema,\n AnySchema,\n AnySchema,\n readonly AnyEndpointMiddleware[],\n EndpointErrorDefinitions\n>;\ntype EndpointBodyFromOptions<TOptions> = TOptions extends {\n body: infer TBody extends AnySchema;\n}\n ? TBody\n : never;\ntype EndpointQueryFromOptions<TOptions> = TOptions extends {\n query: infer TQuery extends AnySchema;\n}\n ? TQuery\n : never;\ntype EndpointHeadersFromOptions<TOptions> = TOptions extends {\n headers: infer THeaders extends AnySchema;\n}\n ? THeaders\n : never;\ntype EndpointMiddlewaresFromOptions<TOptions> = TOptions extends {\n middleware: infer TMiddlewares extends readonly AnyEndpointMiddleware[];\n}\n ? TMiddlewares\n : readonly [];\ntype EndpointErrorsFromOptions<TOptions> = TOptions extends {\n errors: infer TErrors extends EndpointErrorDefinitions;\n}\n ? TErrors\n : {};\ntype MethodlessEndpointOptions = Omit<AnyEndpointOptions, \"method\">;\ntype EndpointHandlerFromOptions<TOptions, TResponse> = EndpointHandler<\n EndpointBodyFromOptions<TOptions>,\n EndpointQueryFromOptions<TOptions>,\n EndpointHeadersFromOptions<TOptions>,\n TResponse,\n InferEndpointMiddlewareContext<EndpointMiddlewaresFromOptions<TOptions>>,\n EndpointErrorsFromOptions<TOptions>\n>;\ntype ValidatedEndpointHandlerFromOptions<TOptions, TResponse> = EndpointHandlerFromOptions<\n TOptions,\n TResponse\n> &\n (EndpointMiddlewaresFromOptions<TOptions> extends ValidateEndpointMiddlewares<\n EndpointMiddlewaresFromOptions<TOptions>\n >\n ? unknown\n : never);\ntype CreatedEndpointFromOptions<TOptions, TResponse> = CreatedEndpoint<\n EndpointBodyFromOptions<TOptions>,\n EndpointQueryFromOptions<TOptions>,\n EndpointHeadersFromOptions<TOptions>,\n TResponse,\n EndpointErrorsFromOptions<TOptions>\n>;\n\n/**\n * Create a Farm.js API endpoint\n *\n * Supports two patterns:\n * 1. File-based routing (path auto-inferred from file location):\n * `export const POST = createEndpoint({ method: 'POST', body: schema }, handler)`\n * `createEndpoint({ method: 'GET', query: z.object({...}) }, handler)`\n *\n * 2. Explicit path (for routes.ts at project root):\n * `createEndpoint('/api/hello', { method: 'GET', query: z.object({...}) }, handler)`\n */\nexport function createEndpoint<const TOptions extends AnyEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function createEndpoint<const TOptions extends AnyEndpointOptions, TResponse = any>(\n path: string,\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function createEndpoint<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: EndpointOptions<TBody, TQuery, THeaders, readonly []>,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function createEndpoint<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n path: string,\n options: EndpointOptions<TBody, TQuery, THeaders, readonly []>,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function createEndpoint(\n pathOrOptions:\n | string\n | EndpointOptions<any, any, any, readonly AnyEndpointMiddleware[], EndpointErrorDefinitions>,\n optionsOrHandler:\n | EndpointOptions<any, any, any, readonly AnyEndpointMiddleware[], EndpointErrorDefinitions>\n | EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n maybeHandler?: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n): TypedEndpoint<any, any, any, any> {\n // Determine if first arg is path or options\n let path: string;\n let options: EndpointOptions<\n any,\n any,\n any,\n readonly AnyEndpointMiddleware[],\n EndpointErrorDefinitions\n >;\n let handler: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>;\n\n if (typeof pathOrOptions === \"string\") {\n // createEndpoint('/path', options, handler)\n path = pathOrOptions;\n options = optionsOrHandler as typeof options;\n handler = maybeHandler as typeof handler;\n } else {\n // createEndpoint(options, handler) - path will be set by API plugin from file location\n path = \"\";\n options = pathOrOptions;\n handler = optionsOrHandler as typeof handler;\n }\n\n if (typeof handler !== \"function\") {\n throw new TypeError(\"createEndpoint requires a handler function\");\n }\n\n const middleware = normalizeEndpointMiddleware(options.middleware);\n const errors = normalizeEndpointErrors(options.errors);\n const fail = createEndpointFail(errors);\n const wrappedHandler = (async (ctx: EndpointMiddlewareContext<any, any, any, any>) => {\n const execution = await runEndpointMiddleware(\n middleware,\n ctx,\n handler,\n fail,\n options.invalidates,\n );\n return execution.result;\n }) as typeof handler;\n const {\n middleware: _middleware,\n errors: _errors,\n invalidates: _invalidates,\n ...betterCallOptions\n } = options;\n\n // Create the endpoint - path will be set later by API plugin if not provided\n // We use a temporary path that will be replaced when the router is created\n const endpoint = betterCallEndpoint(\n path || \"/__farm_auto_path__\",\n betterCallOptions as any,\n wrappedHandler as any,\n ) as any;\n\n // Store the path and type information on the endpoint for later access\n // Empty/undefined path means it will be inferred from file location by the API plugin\n endpoint.__path = path || undefined;\n endpoint.__method = options.method || \"GET\";\n endpoint.__autoPath = !path; // Flag to indicate path should be auto-inferred\n endpoint.__handler = wrappedHandler; // Used by Farm's route runtime.\n endpoint.__farmInvoke = (ctx: EndpointMiddlewareContext<any, any, any, any>) =>\n runEndpointMiddleware(middleware, ctx, handler, fail, options.invalidates);\n endpoint.__middleware = middleware;\n endpoint.__sourceHandler = handler;\n endpoint.__invalidates = options.invalidates;\n endpoint.__errors = errors;\n\n // Store type information for inference\n endpoint.__types = {\n body: options.body,\n query: options.query,\n headers: options.headers,\n response: null as any,\n errors,\n };\n\n return endpoint as any;\n}\n\nconst EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]) as readonly AnyEndpointMiddleware[];\nconst EMPTY_ENDPOINT_CONTEXT = Object.freeze(Object.create(null)) as Readonly<\n Record<string | symbol, unknown>\n>;\nconst UNSAFE_ENDPOINT_CONTEXT_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nfunction normalizeEndpointErrors(\n definitions: EndpointErrorDefinitions | undefined,\n): Readonly<EndpointErrorDefinitions> {\n if (definitions === undefined) return Object.freeze({});\n if (!isPlainEndpointContext(definitions)) {\n throw new TypeError(\"createEndpoint errors must be an object\");\n }\n\n const normalized: EndpointErrorDefinitions = Object.create(null);\n for (const [code, definition] of Object.entries(definitions)) {\n if (!code.trim()) {\n throw new TypeError(\"Endpoint error codes cannot be empty\");\n }\n if (!definition || typeof definition !== \"object\") {\n throw new TypeError(`Endpoint error \"${code}\" must be an object`);\n }\n if (\n !Number.isInteger(definition.status) ||\n definition.status < 400 ||\n definition.status > 599\n ) {\n throw new TypeError(`Endpoint error \"${code}\" status must be an integer between 400 and 599`);\n }\n if (!definition.schema || typeof definition.schema.parse !== \"function\") {\n throw new TypeError(`Endpoint error \"${code}\" requires a schema with parse()`);\n }\n if (definition.message !== undefined && typeof definition.message !== \"string\") {\n throw new TypeError(`Endpoint error \"${code}\" message must be a string`);\n }\n\n normalized[code] = Object.freeze({ ...definition });\n }\n\n return Object.freeze(normalized);\n}\n\nfunction createEndpointFail(\n definitions: Readonly<EndpointErrorDefinitions>,\n): EndpointFail<EndpointErrorDefinitions> {\n return ((code: string, data: unknown): never => {\n const definition = definitions[code];\n if (!definition) {\n throw new TypeError(`Endpoint error \"${code}\" is not declared`);\n }\n\n const parsed = definition.schema.parse!(data);\n throw new EndpointFailure(code, parsed, {\n status: definition.status,\n message: definition.message ?? \"Request failed\",\n });\n }) as EndpointFail<EndpointErrorDefinitions>;\n}\n\nfunction normalizeEndpointMiddleware(\n middleware: readonly AnyEndpointMiddleware[] | undefined,\n): readonly AnyEndpointMiddleware[] {\n if (middleware === undefined) return EMPTY_ENDPOINT_MIDDLEWARE;\n if (!Array.isArray(middleware)) {\n throw new TypeError(\"createEndpoint middleware must be an array of functions\");\n }\n\n const normalized = [...middleware];\n for (const entry of normalized) {\n if (typeof entry !== \"function\") {\n throw new TypeError(\"createEndpoint middleware entries must be functions\");\n }\n }\n\n return Object.freeze(normalized);\n}\n\nasync function runEndpointMiddleware(\n middleware: readonly AnyEndpointMiddleware[],\n handlerContext: EndpointMiddlewareContext<any, any, any, any>,\n handler: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n fail: EndpointFail<EndpointErrorDefinitions>,\n invalidations: EndpointInvalidations<any, any, any, any> | undefined,\n): Promise<{\n result: unknown;\n context: Readonly<Record<string | symbol, unknown>>;\n handlerExecuted: boolean;\n invalidations: readonly string[];\n}> {\n let context = createInitialEndpointContext(handlerContext.context);\n\n for (let index = 0; index < middleware.length; index++) {\n const result = await middleware[index]({ ...handlerContext, context });\n\n if (isEndpointResponse(result)) {\n return {\n result,\n context,\n handlerExecuted: false,\n invalidations: [],\n };\n }\n if (result === false) {\n return {\n result: forbiddenEndpointResponse(),\n context,\n handlerExecuted: false,\n invalidations: [],\n };\n }\n if (result === true) continue;\n\n if (!isPlainEndpointContext(result)) {\n throw new TypeError(\n `Endpoint middleware ${index + 1} must return an object, true, false, or a Response`,\n );\n }\n\n context = mergeEndpointContext(context, result, index);\n }\n\n const result = await handler({ ...handlerContext, context, fail });\n return {\n result,\n context,\n handlerExecuted: true,\n invalidations: await applyEndpointInvalidations(\n invalidations,\n {\n ...handlerContext,\n context,\n result,\n },\n result,\n ),\n };\n}\n\nasync function applyEndpointInvalidations(\n declaration: EndpointInvalidations<any, any, any, any> | undefined,\n context: EndpointInvalidationContext<any, any, any, any>,\n result: unknown,\n): Promise<readonly string[]> {\n if (!declaration || (isEndpointResponse(result) && result.status >= 400)) {\n return [];\n }\n\n const targets = typeof declaration === \"function\" ? await declaration(context) : declaration;\n if (!Array.isArray(targets)) {\n throw new TypeError(\n \"Endpoint invalidates must resolve to an array of { key } or { path } targets\",\n );\n }\n\n const clientKeys: string[] = [];\n for (const target of targets) {\n assertEndpointInvalidationTarget(target);\n if (\"key\" in target) {\n invalidate(target.key);\n clientKeys.push(createRouteDataCacheKey(target.key));\n } else {\n revalidatePath(target.path);\n }\n }\n\n return Array.from(new Set(clientKeys));\n}\n\nfunction assertEndpointInvalidationTarget(\n target: unknown,\n): asserts target is EndpointInvalidationTarget {\n if (!target || typeof target !== \"object\") {\n throw new TypeError(\"Endpoint invalidation targets must be { key } or { path } objects\");\n }\n\n if (\"key\" in target) {\n const key = (target as { key?: unknown }).key;\n if (typeof key === \"string\" || Array.isArray(key)) return;\n } else if (\"path\" in target && typeof (target as { path?: unknown }).path === \"string\") {\n return;\n }\n\n throw new TypeError(\n \"Endpoint invalidation targets must contain a string/array key or a path string\",\n );\n}\n\nfunction createInitialEndpointContext(value: unknown) {\n if (value === undefined || value === null) return EMPTY_ENDPOINT_CONTEXT;\n if (!isPlainEndpointContext(value)) {\n throw new TypeError(\"Endpoint context must be a plain object\");\n }\n\n return mergeEndpointContext(EMPTY_ENDPOINT_CONTEXT, value);\n}\n\nfunction mergeEndpointContext(\n current: Readonly<Record<string | symbol, unknown>>,\n added: object,\n middlewareIndex?: number,\n) {\n const next = Object.assign(Object.create(null), current) as Record<string | symbol, unknown>;\n\n for (const key of Reflect.ownKeys(added)) {\n if (!Object.prototype.propertyIsEnumerable.call(added, key)) continue;\n if (typeof key === \"string\" && UNSAFE_ENDPOINT_CONTEXT_KEYS.has(key)) {\n throw new TypeError(`Endpoint middleware cannot provide the unsafe context key \"${key}\"`);\n }\n if (Object.prototype.hasOwnProperty.call(current, key)) {\n const source =\n middlewareIndex === undefined\n ? \"Endpoint context\"\n : `Endpoint middleware ${middlewareIndex + 1}`;\n throw new TypeError(`${source} cannot replace the existing context key \"${String(key)}\"`);\n }\n next[key] = (added as Record<string | symbol, unknown>)[key];\n }\n\n return Object.freeze(next);\n}\n\nfunction isPlainEndpointContext(value: unknown): value is object {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isEndpointResponse(value: unknown): value is Response {\n return (\n value instanceof Response ||\n (typeof value === \"object\" &&\n value !== null &&\n \"headers\" in value &&\n \"status\" in value &&\n typeof (value as Response).arrayBuffer === \"function\")\n );\n}\n\nfunction forbiddenEndpointResponse() {\n return new Response(JSON.stringify({ error: \"Forbidden\" }), {\n status: 403,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\n/**\n * Convenience method for GET requests\n */\nexport function GET<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function GET<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function GET<\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<never, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<never, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<never, TQuery, THeaders, TResponse>;\nexport function GET(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"GET\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"GET\" }, args[1]);\n}\n\n/**\n * Convenience method for HEAD requests\n */\nexport function HEAD<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function HEAD<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function HEAD<\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<never, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<never, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<never, TQuery, THeaders, TResponse>;\nexport function HEAD(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"HEAD\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"HEAD\" }, args[1]);\n}\n\n/**\n * Convenience method for POST requests\n */\nexport function POST<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function POST<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function POST<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function POST(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"POST\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"POST\" }, args[1]);\n}\n\n/**\n * Convenience method for PUT requests\n */\nexport function PUT<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function PUT<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function PUT<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function PUT(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"PUT\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"PUT\" }, args[1]);\n}\n\n/**\n * Convenience method for DELETE requests\n */\nexport function DELETE<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function DELETE<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function DELETE<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function DELETE(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"DELETE\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"DELETE\" }, args[1]);\n}\n\n/**\n * Convenience method for PATCH requests\n */\nexport function PATCH<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function PATCH<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function PATCH<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function PATCH(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"PATCH\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"PATCH\" }, args[1]);\n}\n\n/**\n * Convenience method for OPTIONS requests\n */\nexport function OPTIONS<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function OPTIONS<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function OPTIONS<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function OPTIONS(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"OPTIONS\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"OPTIONS\" }, args[1]);\n}\n","import { _runWithCurrentRequest } from \"../server/request\";\nimport {\n decodeFarmCacheInvalidations,\n encodeFarmCacheInvalidations,\n FARM_CACHE_INVALIDATION_HEADER,\n} from \"../cache-invalidation\";\nimport { isEndpointFailure, type EndpointFailure } from \"./endpoint\";\n\nexport type APIRouteParamValue = string | string[];\nexport type APIRouteParams = Record<string, APIRouteParamValue>;\n\nexport interface APIRouteMatch<T extends { path: string }> {\n route: T;\n params: APIRouteParams;\n}\n\nexport function matchAPIRoute<T extends { path: string }>(\n routes: Map<string, T>,\n pathname: string,\n): APIRouteMatch<T> | null {\n const exactRoute = routes.get(pathname);\n if (exactRoute) {\n return { route: exactRoute, params: {} };\n }\n\n const normalizedPathname = normalizePathname(pathname);\n if (normalizedPathname !== pathname) {\n const normalizedRoute = routes.get(normalizedPathname);\n if (normalizedRoute) {\n return { route: normalizedRoute, params: {} };\n }\n }\n\n for (const route of routes.values()) {\n const params = matchRoutePath(route.path, pathname);\n if (params) {\n return { route, params };\n }\n }\n\n return null;\n}\n\nexport async function invokeAPIRouteEndpoint(\n endpoint: any,\n request: Request,\n params: APIRouteParams = {},\n): Promise<Response> {\n return _runWithCurrentRequest(request, () =>\n invokeAPIRouteEndpointInContext(endpoint, request, params),\n );\n}\n\nasync function invokeAPIRouteEndpointInContext(\n endpoint: any,\n request: Request,\n params: APIRouteParams,\n): Promise<Response> {\n const farmHandler = endpoint.__handler || (isFarmContextHandler(endpoint) ? endpoint : null);\n\n if (!farmHandler) {\n const result = await endpoint(request, {\n params: Promise.resolve(params),\n });\n return normalizeRouteResponse(result);\n }\n\n const url = new URL(request.url);\n const query: Record<string, string> = {};\n url.searchParams.forEach((value, key) => {\n query[key] = value;\n });\n\n let body: any = undefined;\n if (request.method.toUpperCase() !== \"GET\" && request.method.toUpperCase() !== \"HEAD\") {\n body = await readJSONBody(request);\n }\n\n const headers = Object.fromEntries(request.headers.entries());\n const types = endpoint.__types || {};\n\n const queryValidation = validateInput(types.query, query, \"Invalid query parameters\");\n if (queryValidation instanceof Response) {\n return queryValidation;\n }\n\n const bodyValidation = validateInput(types.body, body, \"Invalid request body\");\n if (bodyValidation instanceof Response) {\n return bodyValidation;\n }\n\n const headersValidation = validateInput(types.headers, headers, \"Invalid request headers\");\n if (headersValidation instanceof Response) {\n return headersValidation;\n }\n\n const handlerContext = {\n query: queryValidation,\n body: bodyValidation,\n headers: headersValidation,\n request,\n context: {},\n params,\n };\n let execution: {\n result: unknown;\n context: unknown;\n handlerExecuted: boolean;\n invalidations: readonly string[];\n };\n try {\n execution =\n typeof endpoint.__farmInvoke === \"function\"\n ? await endpoint.__farmInvoke(handlerContext)\n : {\n result: await farmHandler(handlerContext),\n context: handlerContext.context,\n handlerExecuted: true,\n invalidations: [],\n };\n } catch (error) {\n if (isEndpointFailure(error)) {\n return createEndpointFailureResponse(error);\n }\n throw error;\n }\n\n const response = normalizeRouteResponse(execution.result);\n return attachEndpointInvalidations(response, execution.invalidations);\n}\n\nexport function normalizeRouteResponse(result: unknown): Response {\n if (isWebResponse(result)) {\n return result;\n }\n\n if (result === undefined) {\n return new Response(null, { status: 204 });\n }\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nexport function isWebResponse(value: unknown): value is Response {\n return (\n value instanceof Response ||\n (typeof value === \"object\" &&\n value !== null &&\n \"headers\" in value &&\n \"status\" in value &&\n typeof (value as Response).arrayBuffer === \"function\")\n );\n}\n\nfunction attachEndpointInvalidations(response: Response, keys: readonly string[]): Response {\n const existing = decodeFarmCacheInvalidations(\n response.headers.get(FARM_CACHE_INVALIDATION_HEADER),\n );\n const encoded = encodeFarmCacheInvalidations([...existing, ...keys]);\n if (!encoded) return response;\n\n const headers = new Headers(response.headers);\n headers.set(FARM_CACHE_INVALIDATION_HEADER, encoded);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nexport function createEndpointFailureResponse(failure: EndpointFailure<string, unknown>): Response {\n return new Response(\n JSON.stringify({\n error: {\n code: failure.code,\n message: failure.message,\n data: failure.data,\n },\n }),\n {\n status: failure.status,\n headers: {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json\",\n },\n },\n );\n}\n\nfunction isFarmContextHandler(endpoint: unknown): boolean {\n if (typeof endpoint !== \"function\") {\n return false;\n }\n\n const source = Function.prototype.toString.call(endpoint).trim();\n const arrowMatch = source.match(/^(?:async\\s*)?(?:\\(([^)]*)\\)|([A-Za-z_$][\\w$]*))\\s*=>/);\n const functionMatch = source.match(/^(?:async\\s*)?function[^(]*\\(([^)]*)\\)/);\n const firstParameter = (arrowMatch?.[1] || arrowMatch?.[2] || functionMatch?.[1] || \"\")\n .split(\",\")[0]\n .trim();\n\n return firstParameter === \"ctx\" || firstParameter === \"context\" || firstParameter.startsWith(\"{\");\n}\n\nasync function readJSONBody(request: Request): Promise<unknown> {\n try {\n const text = await request.clone().text();\n if (text) {\n return JSON.parse(text);\n }\n } catch {\n // Body might not be JSON.\n }\n\n return undefined;\n}\n\nfunction validateInput(schema: any, value: unknown, error: string): unknown | Response {\n if (!schema || typeof schema.parse !== \"function\") {\n return value;\n }\n\n try {\n return schema.parse(value);\n } catch (validationError: any) {\n return new Response(\n JSON.stringify({\n error,\n details: validationError.errors || validationError.issues || validationError.message,\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nfunction matchRoutePath(routePath: string, pathname: string): APIRouteParams | null {\n const routeSegments = getPathSegments(routePath);\n const pathnameSegments = getPathSegments(pathname);\n const params: APIRouteParams = {};\n let pathIndex = 0;\n\n for (const routeSegment of routeSegments) {\n const dynamicSegment = parseDynamicSegment(routeSegment);\n\n if (dynamicSegment?.catchAll) {\n const remainingSegments = pathnameSegments.slice(pathIndex).map(decodePathSegment);\n if (remainingSegments.length === 0 && !dynamicSegment.optional) {\n return null;\n }\n if (remainingSegments.length > 0) {\n params[dynamicSegment.name] = remainingSegments;\n }\n pathIndex = pathnameSegments.length;\n continue;\n }\n\n const pathnameSegment = pathnameSegments[pathIndex];\n if (pathnameSegment === undefined) {\n return null;\n }\n\n if (dynamicSegment) {\n params[dynamicSegment.name] = decodePathSegment(pathnameSegment);\n pathIndex++;\n continue;\n }\n\n if (routeSegment !== pathnameSegment) {\n return null;\n }\n\n pathIndex++;\n }\n\n return pathIndex === pathnameSegments.length ? params : null;\n}\n\nfunction getPathSegments(pathname: string): string[] {\n return normalizePathname(pathname)\n .split(\"/\")\n .filter((segment) => segment.length > 0);\n}\n\nfunction normalizePathname(pathname: string): string {\n if (pathname.length > 1 && pathname.endsWith(\"/\")) {\n return pathname.replace(/\\/+$/, \"\");\n }\n\n return pathname;\n}\n\nfunction parseDynamicSegment(\n segment: string,\n): { name: string; catchAll: boolean; optional: boolean } | null {\n const optionalCatchAll = segment.match(/^\\[\\[\\.\\.\\.(.+)\\]\\]$/);\n if (optionalCatchAll?.[1]) {\n return { name: optionalCatchAll[1], catchAll: true, optional: true };\n }\n\n const catchAll = segment.match(/^\\[\\.\\.\\.(.+)\\]$/);\n if (catchAll?.[1]) {\n return { name: catchAll[1], catchAll: true, optional: false };\n }\n\n const dynamic = segment.match(/^\\[(.+)\\]$/);\n if (dynamic?.[1]) {\n return { name: dynamic[1], catchAll: false, optional: false };\n }\n\n return null;\n}\n\nfunction decodePathSegment(segment: string): string {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,IAAAA,QAAsB;;;ACyLf,IAAM,SAAS;AAAA,EACpB,MAAM,wBAAC,YAAoB,QAAQ,IAAI,UAAU,OAAO,EAAE,GAApD;AAAA,EACN,SAAS,wBAAC,YAAoB,QAAQ,IAAI,aAAa,OAAO,EAAE,GAAvD;AAAA,EACT,MAAM,wBAAC,YAAoB,QAAQ,KAAK,iBAAO,OAAO,EAAE,GAAlD;AAAA,EACN,OAAO,wBAAC,YAAoB,QAAQ,MAAM,UAAK,OAAO,EAAE,GAAjD;AAAA,EACP,OAAO,wBAAC,YAAoB,QAAQ,IAAI,GAAG,OAAO,EAAE,GAA7C;AAAA,EACP,OAAO,wBAAC,YAAoB,QAAQ,IAAI,KAAK,OAAO,EAAE,GAA/C;AACT;;;ACjMA,mBAA4D;;;AC+P5D,IAAM,kBAAkB,oBAAI,IAAsB;AAClD,IAAI,qBAAsD;AAAA,EACxD,MAAM;AAAA,EACN,UAAU,CAAC;AACb;AA6CO,SAAS,cAAc,OAAkC;AAC9D,QAAM,QAAQ;AAAA,IACZ,WAAW,KAAK,IAAI;AAAA,IACpB,OAAO,oBAAoB,MAAM,IAAI;AAAA,IACrC,GAAG;AAAA,EACL;AAEA,MAAI,CAAC,oBAAoB,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,MAAM;AAC3B,iBAAa,KAAK;AAAA,EACpB;AAEA,aAAW,WAAW,CAAC,GAAG,mBAAmB,UAAU,GAAG,eAAe,GAAG;AAC1E,QAAI;AACF,cAAQ,QAAQ,QAAQ,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU;AAC/C,gBAAQ,KAAK,8CAA8C,YAAY,KAAK,CAAC,EAAE;AAAA,MACjF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,KAAK,8CAA8C,YAAY,KAAK,CAAC,EAAE;AAAA,IACjF;AAAA,EACF;AAEA,SAAO;AACT;AA1BgB;AA4BhB,SAAS,oBAAoB,OAA2B;AACtD,MACE,CAAC,mBAAmB,QACpB,mBAAmB,SAAS,WAAW,KACvC,gBAAgB,SAAS,GACzB;AACA,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,UAAU,CAAC,mBAAmB,OAAO,IAAI,MAAM,IAAI,GAAG;AAC3E,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAdS;AAgBT,SAAS,oBAAoB,MAAqC;AAChE,MAAI,SAAS,WAAW,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,SAAS,GAAG;AAC3E,WAAO;AAAA,EACT;AACA,MACE,KAAK,SAAS,SAAS,KACvB,KAAK,SAAS,cAAc,KAC5B,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,WAAW,GACzB;AACA,WAAO;AAAA,EACT;AACA,MACE,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,OAAO,KACrB,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,aAAa,GAC3B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AArBS;AAuBT,SAAS,aAAa,OAAwB;AAC5C,QAAM,UAAU,SAAS,MAAM,KAAK,KAAK,MAAM,IAAI,GAAG,uBAAuB,KAAK,CAAC;AACnF,UAAQ,MAAM,OAAO;AAAA,IACnB,KAAK;AACH,cAAQ,MAAM,OAAO;AACrB;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,OAAO;AACpB;AAAA,IACF;AACE,cAAQ,IAAI,OAAO;AACnB;AAAA,EACJ;AACF;AAbS;AAeT,SAAS,uBAAuB,OAA0B;AACxD,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAS;AAEf,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAG;AACD,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,UAAU,QAAW;AACvB,cAAQ,KAAK,GAAG,GAAG,IAAI,kBAAkB,KAAK,CAAC,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,SAAO,QAAQ,SAAS,IAAI,IAAI,QAAQ,KAAK,GAAG,CAAC,KAAK;AACxD;AA5BS;AA8BT,SAAS,kBAAkB,OAAwB;AACjD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAC3D,WAAO,OAAO,KAAK;AAAA,EACrB;AACA,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAZS;AAcT,SAAS,YAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAFS;;;AC5aF,IAAM,iCAAiC;AAmCvC,SAAS,6BAA6B,MAAwC;AACnF,QAAM,aAAa,MAAM;AAAA,IACvB,IAAI,IAAI,KAAK,OAAO,CAAC,QAAQ,OAAO,QAAQ,YAAY,IAAI,SAAS,CAAC,CAAC;AAAA,EACzE;AACA,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,SAAO,mBAAmB,KAAK,UAAU,UAAU,CAAC;AACtD;AANgB;AAQT,SAAS,6BAA6B,OAAqD;AAChG,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,mBAAmB,KAAK,CAAC;AACnD,WAAO,MAAM,QAAQ,MAAM,IACvB,MAAM;AAAA,MACJ,IAAI,IAAI,OAAO,OAAO,CAAC,QAAuB,OAAO,QAAQ,YAAY,IAAI,SAAS,CAAC,CAAC;AAAA,IAC1F,IACA,CAAC;AAAA,EACP,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAbgB;;;ACzChB,IAAM,8BAA8B,uBAAO,IAAI,4BAA4B;AAKpE,SAAS,6BAA6B,UAA8C;AACzF,EAAC,WAAsC,2BAA2B,IAAI;AACxE;AAFgB;;;AC2GT,IAAM,iBAAN,MAAM,eAAc;AAAA,EAApB;AACL,SAAQ,UAAU,oBAAI,IAAoC;AAC1D,SAAQ,WAAW,oBAAI,IAA8B;AACrD,SAAQ,yBAAyB,oBAAI,IAAoB;AACzD,SAAQ,UAAU;AAAA;AAAA,EAElB,IAAI,OAAe;AACjB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAO,KAAa,UAAoC,CAAC,GAAkB;AACzE,WAAO,KAAK,SAAY,KAAK,OAAO,GAAG;AAAA,EACzC;AAAA,EAEA,SACE,KACA,UAAoC,CAAC,GACN;AAC/B,UAAM,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAClC,QAAI,CAAC,OAAO;AACV,oBAAc,EAAE,MAAM,cAAc,IAAI,CAAC;AACzC,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,KAAK,QAAQ,OAAO,QAAQ,GAAG;AAC7C,QAAI,OAAO;AACT,oBAAc;AAAA,QACZ,MAAM;AAAA,QACN;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,IAAI;AAAA,QAC3B,YAAY,MAAM;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,QAAQ,cAAc,OAAO;AAChC,oBAAc,EAAE,MAAM,cAAc,KAAK,QAAQ,QAAQ,CAAC;AAC1D,aAAO;AAAA,IACT;AAEA,kBAAc;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,MAAM,MAAM,KAAK,MAAM,IAAI;AAAA,MAC3B,YAAY,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAED,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,IAAO,KAAa,OAAU,UAA+B,CAAC,GAAsB;AAClF,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,OAAO,QAAQ,QAAQ,CAAC,GAAG;AACpC,WAAK,IAAI,kBAAkB,GAAG,CAAC;AAAA,IACjC;AACA,eAAW,aAAa,QAAQ,SAAS,CAAC,GAAG;AAC3C,WAAK,IAAI,mBAAmB,SAAS,CAAC;AAAA,IACxC;AAEA,UAAM,QAAmC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,QAAQ,aAAa,KAAK,IAAI;AAAA,MACzC,gBAAgB,EAAE,KAAK;AAAA,MACvB,YAAY,oBAAoB,QAAQ,UAAU;AAAA,IACpD;AAEA,SAAK,QAAQ,IAAI,KAAK,KAAK;AAC3B,kBAAc;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,YAAY,MAAM;AAAA,IACpB,CAAC;AACD,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,OAAO,KAAsB;AAC3B,UAAM,UAAU,KAAK,QAAQ,OAAO,GAAG;AACvC,kBAAc,EAAE,MAAM,gBAAgB,KAAK,QAAQ,CAAC;AACpD,WAAO;AAAA,EACT;AAAA,EAEA,QAAc;AACZ,UAAM,QAAQ,KAAK,QAAQ;AAC3B,SAAK,QAAQ,MAAM;AACnB,SAAK,SAAS,MAAM;AACpB,SAAK,uBAAuB,MAAM;AAClC,SAAK,UAAU;AACf,kBAAc,EAAE,MAAM,eAAe,MAAM,CAAC;AAAA,EAC9C;AAAA,EAEA,QAAQ,OAA4B,MAAM,KAAK,IAAI,GAAY;AAC7D,QACE,OAAO,MAAM,eAAe,YAC5B,MAAM,aAAa,KACnB,MAAM,MAAM,aAAa,MAAM,aAAa,KAC5C;AACA,aAAO;AAAA,IACT;AAEA,eAAW,OAAO,MAAM,MAAM;AAC5B,YAAM,qBAAqB,KAAK,uBAAuB,IAAI,kBAAkB,GAAG,CAAC;AACjF,UACE,OAAO,uBAAuB,YAC9B,OAAO,MAAM,mBAAmB,YAChC,qBAAqB,MAAM,gBAC3B;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,cACE,KACA,UAAsF,CAAC,GAC/E;AACR,UAAM,aAAa,kBAAkB,GAAG;AACxC,UAAM,QAAQ,KAAK,cAAc,UAAU;AAC3C;AAAA,MACE,QAAQ,WAAW,cACf,EAAE,MAAM,mBAAmB,KAAK,YAAY,MAAM,IAClD,EAAE,MAAM,uBAAuB,KAAK,YAAY,SAAS,QAAQ,SAAS,MAAM;AAAA,IACtF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,WAA2B;AACxC,UAAM,iBAAiB,wBAAwB,SAAS;AACxD,UAAM,UAAU,mBAAmB,cAAc;AACjD,UAAM,WAAW,KAAK,oBAAoB,CAAC,SAAS,KAAK,CAAC;AAC1D,UAAM,QAAQ,KAAK,cAAc,OAAO;AACxC,kBAAc,EAAE,MAAM,wBAAwB,MAAM,gBAAgB,MAAM,CAAC;AAE3E,QAAI,WAAW,GAAG;AAChB,oBAAc;AAAA,QACZ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,KACA,UACA,UAA4B,CAAC,GACjB;AACZ,UAAM,SAAS,KAAK,SAAY,GAAG;AACnC,QAAI,QAAQ;AACV,aAAO,OAAO;AAAA,IAChB;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,GAAG;AACtC,QAAI,UAAU;AACZ,oBAAc,EAAE,MAAM,gBAAgB,IAAI,CAAC;AAC3C,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,QAAQ,QAAQ,EAC7B,KAAK,QAAQ,EACb,KAAK,CAAC,UAAU;AACf,WAAK,IAAI,KAAK,OAAO,OAAO;AAC5B,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,oBAAc,EAAE,MAAM,eAAe,KAAK,WAAW,OAAO,MAAM,CAAC;AACnE,YAAM;AAAA,IACR,CAAC,EACA,QAAQ,MAAM;AACb,WAAK,SAAS,OAAO,GAAG;AAAA,IAC1B,CAAC;AAEH,SAAK,SAAS,IAAI,KAAK,OAAO;AAC9B,WAAO;AAAA,EACT;AAAA,EAEQ,mBAAmB,KAAqB;AAC9C,QAAI,QAAQ;AACZ,eAAW,SAAS,KAAK,QAAQ,OAAO,GAAG;AACzC,UAAI,MAAM,KAAK,IAAI,GAAG,GAAG;AACvB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,MAAiC;AAC3D,QAAI,QAAQ;AACZ,eAAW,SAAS,KAAK,QAAQ,OAAO,GAAG;AACzC,UAAI,KAAK,MAAM,CAAC,QAAQ,MAAM,KAAK,IAAI,GAAG,CAAC,GAAG;AAC5C;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,eAA+B;AACnD,SAAK,uBAAuB,IAAI,eAAe,EAAE,KAAK,OAAO;AAC7D,WAAO,KAAK,mBAAmB,aAAa;AAAA,EAC9C;AAAA,EAEQ,cAAiB,OAAqD;AAC5E,WAAO;AAAA,MACL,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA,MACb,MAAM,MAAM,KAAK,MAAM,IAAI;AAAA,MAC3B,WAAW,MAAM;AAAA,MACjB,gBAAgB,MAAM;AAAA,MACtB,YAAY,MAAM;AAAA,IACpB;AAAA,EACF;AACF;AA1N2B;AAApB,IAAM,gBAAN;AA4NP,IAAM,yBAAyB,uBAAO,IAAI,gBAAgB;AAC1D,IAAM,sBAAsB;AAG5B,IAAM,sBAAuB,8FAAgD,IAAI,cAAc;AAmDxF,SAAS,mBAAmB,WAA2B;AAC5D,SAAO,QAAQ,wBAAwB,SAAS,CAAC;AACnD;AAFgB;AAYT,SAAS,wBAAwB,WAA2B;AACjE,MAAI,OAAO,cAAc,UAAU;AACjC,UAAM,IAAI,UAAU,uCAAuC;AAAA,EAC7D;AAEA,MAAI,aAAa,UAAU,KAAK;AAChC,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAEA,MAAI;AACF,QAAI,eAAe,KAAK,UAAU,GAAG;AACnC,mBAAa,IAAI,IAAI,UAAU,EAAE;AAAA,IACnC;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,eAAa,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK;AACzC,eAAa,WAAW,WAAW,GAAG,IAAI,aAAa,IAAI,UAAU;AACrE,eAAa,WAAW,QAAQ,WAAW,GAAG;AAC9C,MAAI,WAAW,SAAS,GAAG;AACzB,iBAAa,WAAW,QAAQ,QAAQ,EAAE;AAAA,EAC5C;AACA,SAAO,cAAc;AACvB;AAzBgB;AA+BhB,SAAS,oBAAoB,YAAoE;AAC/F,MAAI,eAAe,SAAS,eAAe,QAAW;AACpD,WAAO;AAAA,EACT;AACA,MAAI,CAAC,OAAO,SAAS,UAAU,KAAK,cAAc,GAAG;AACnD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AARS;AAUT,SAAS,kBAAkB,KAAqB;AAC9C,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,UAAU,6BAA6B;AAAA,EACnD;AACA,QAAM,aAAa,IAAI,KAAK;AAC5B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,SAAO;AACT;AATS;;;AC5ZF,SAAS,gCACd,OACA,SAAS,uBACe;AACxB,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,QAAM,aAAqC,CAAC;AAE5C,MAAI,MAAM,YAAY,QAAW;AAC/B,QAAI,MAAM,YAAY,UAAU,MAAM,YAAY,UAAU,MAAM,YAAY,QAAQ;AACpF,YAAM,IAAI,UAAU,GAAG,MAAM,4CAA4C;AAAA,IAC3E;AACA,eAAW,UAAU,MAAM;AAAA,EAC7B;AAEA,MAAI,MAAM,YAAY,QAAW;AAC/B,QAAI,MAAM,YAAY,QAAQ;AAC5B,iBAAW,UAAU;AAAA,IACvB,OAAO;AACL,UAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,WAAW,GAAG;AAC/D,cAAM,IAAI,UAAU,GAAG,MAAM,qDAAqD;AAAA,MACpF;AAEA,YAAM,UAAU,MAAM;AAAA,QACpB,IAAI;AAAA,UACF,MAAM,QAAQ,IAAI,CAAC,WAAW;AAC5B,gBACE,OAAO,WAAW,YAClB,CAAC,OAAO,KAAK,KACb,wBAAwB,KAAK,MAAM,GACnC;AACA,oBAAM,IAAI,UAAU,GAAG,MAAM,oDAAoD;AAAA,YACnF;AACA,mBAAO,OAAO,KAAK;AAAA,UACrB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAEA,MAAI,MAAM,gBAAgB,QAAW;AACnC,QAAI,MAAM,gBAAgB,QAAQ;AAChC,iBAAW,cAAc;AAAA,IAC3B,WACE,OAAO,MAAM,gBAAgB,YAC7B,CAAC,OAAO,UAAU,MAAM,WAAW,KACnC,MAAM,eAAe,GACrB;AACA,YAAM,IAAI,UAAU,GAAG,MAAM,8DAA8D;AAAA,IAC7F,OAAO;AACL,iBAAW,cAAc,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAzDgB;AAqGT,SAAS,0BAA0B,OAAwC;AAChF,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,CAAC;AACjD,QAAM,QAAQ;AACd,SAAO;AAAA,IACL,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IAChE,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IAChE,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,EAC9E;AACF;AARgB;;;AL4QhB,IAAM,oBAAoB,uBAAO,IAAI,aAAa;AAC3C,IAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,aACd,OAC2B;AAC3B,QAAM,SAAS,OAAO,UAAU,aAAa,MAAM,aAAa,IAAI;AACpE,QAAM,WAAW;AAAA,IACf,cAAc;AAAA,IACd,QAAQ,OAAO,IAAI,0BAA0B;AAAA,EAC/C;AAEA,SAAO,eAAe,UAAU,mBAAmB;AAAA,IACjD,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AACT;AAfgB;AAiBT,IAAM,gBAA0C;AAAA,EACrD,KAAKC,OAAM,SAAS;AAClB,WAAO,2BAA2B;AAAA,MAChC,MAAM;AAAA,MACN,MAAAA;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EACA,OAAOA,OAAM,SAAS;AACpB,WAAO,2BAA2B;AAAA,MAChC,MAAM;AAAA,MACN,MAAAA;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EACA,IAAIA,OAAM,SAAS;AACjB,UAAM,EAAE,QAAQ,SAAS,SAAS,aAAa,GAAG,QAAQ,IAAI;AAC9D,WAAO,2BAA2B;AAAA,MAChC,MAAM;AAAA,MACN,MAAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,oBAAoB,OAAO;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EACA,SAAS,QAAQ,aAAa,UAAU,CAAC,GAAG;AAC1C,WAAO,2BAA2B;AAAA,MAChC,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;AAEO,IAAM,OAAO,cAAc;AAC3B,IAAM,SAAS,cAAc;AAC7B,IAAM,MAAM,cAAc;AAC1B,IAAM,WAAW,cAAc;AAwP/B,SAAS,6BACd,KACkC;AAClC,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,aAAa,CAAC,IAAI,SAAS,IAAI,QAAQ,IAAI,KAAK;AACtD,aAAW,aAAa,YAAY;AAClC,QAAI,4BAA4B,SAAS,GAAG;AAC1C,aAAO;AAAA,IACT;AACA,QAAI,8BAA8B,SAAS,GAAG;AAC5C,aAAO,aAAa,CAAC,SAAS,CAAC;AAAA,IACjC;AACA,QAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,aAAO,aAAa,SAA0C;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,mBAAmB,OAAO,OAAO,GAAG,EAAE,OAAO,6BAA6B;AAChF,MAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAO,aAAa,gBAAgB;AAAA,EACtC;AAEA,SAAO;AACT;AAxBgB;AA0BT,SAAS,4BAA4B,OAAoD;AAC9F,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YAChB,MAAoC,iBAAiB,QACtD,MAAM,QAAS,MAAoC,MAAM;AAE7D;AAPgB;AAST,SAAS,8BACd,OACsC;AACtC,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,OAAQ,MAA6B;AAC3C,SAAO,SAAS,UAAU,SAAS,YAAY,SAAS,SAAS,SAAS;AAC5E;AATgB;AAWT,SAAS,gCACd,UACA,MACA,WACQ;AACR,SAAO,GAAG,QAAQ,eAAe,IAAI,IAAI,mBAAmB,mBAAmB,SAAS,CAAC,CAAC;AAC5F;AANgB;AA2dhB,SAAS,2BACP,OAC6B;AAC7B,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,mBAAmB,MAAM,MAAM;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,OAAO;AACxB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,gCAAgC,OAAO,cAAc,MAAM,IAAI,GAAG;AAAA,MACrE,MAAM,mBAAmB,MAAM,IAAI;AAAA,MACnC,SAAS,oBAAoB,MAAM,OAAO;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,MACD;AAAA,MACA,GAAG,MAAM,SAAS,WAAW,WAAW,OAAO,KAAK,MAAM,IAAI;AAAA,IAChE;AAAA,IACA,MAAM,mBAAmB,MAAM,IAAI;AAAA,EACrC;AACF;AA3BS;AA6BT,SAAS,mBAAmB,WAA2B;AACrD,QAAM,YAAY,UAAU,WAAW,GAAG,IAAI,YAAY,IAAI,SAAS;AACvE,QAAM,kBAAkB,UAAU,SAAS,IAAI,UAAU,QAAQ,QAAQ,EAAE,IAAI;AAC/E,SAAO,mBAAmB;AAC5B;AAJS;AAsCT,SAAS,oBACP,SAC+C;AAC/C,QAAM,aAA4D,CAAC;AAEnE,aAAW,CAAC,QAAQ,OAAO,KAAK,OAAO,QAAQ,OAAO,GAAG;AACvD,UAAM,mBAAmB,OAAO,YAAY;AAC5C,QAAI,WAAW,0BAA0B,gBAAgB,GAAG;AAC1D,iBAAW,gBAAgB,IAAI;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAbS;AAeT,SAAS,0BAA0B,QAAmD;AACpF,SACE,WAAW,SACX,WAAW,UACX,WAAW,UACX,WAAW,SACX,WAAW,YACX,WAAW,WACX,WAAW;AAEf;AAVS;;;AM7yCT,gBAAyC;AACzC,kBAAqB;AAmCd,SAAS,gCAAgC,SAA2B;AACzE,QAAM,QAAkB,CAAC;AAEzB,aAAW,YAAY,+BAA+B;AACpD,UAAM,eAAW,kBAAK,SAAS,QAAQ;AACvC,YAAI,sBAAW,QAAQ,GAAG;AACxB,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAXgB;;;ACpChB,8BAAkC;;;ACAlC,gCAA8B;;;ACA9B,sBAAyB;AACzB,sCAAuD;;;ACDvD,uBAAiB;AASV,IAAM,mCAAmC,KAAK,KAAK,KAAK;;;AHgB/D,IAAM,0BAA0B,uBAAO,IAAI,wBAAwB;AAQnE,SAAS,kBAA2D;AAClE,QAAM,QAAQ;AACd,SAAQ,oEAAmC,IAAI,0CAAwC;AACzF;AAHS;AAKT,SAAS,WAAiC;AACxC,QAAM,QAAQ,gBAAgB,EAAE,SAAS;AACzC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AARS;AAcT,eAAsB,wBACpB,SACA,SACA,IACA,UAAkC,CAAC,GACvB;AACZ,QAAM,aAAa,QAAQ,eAAe,SAAS,OAAO;AAC1D,QAAM,QAA8B;AAAA,IAClC;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,kBAAkB,UAAU;AAAA,EAChD;AACA,SAAO,gBAAgB,EAAE,IAAI,OAAO,MAAM,GAAG,UAAU,CAAC;AAC1D;AAbsB;AA2Cf,IAAM,IAAI,0BAA0B,MAAM,SAAS,CAAC;AAsBpD,SAAS,4BAAgE;AAC9E,SAAO,gBAAgB,EAAE,SAAS,GAAG;AACvC;AAFgB;AAiDhB,SAAS,0BAA0B,cAA0D;AAC3F,QAAM,aAAc,yBAAC,KAAa,WAAqC;AACrE,UAAM,QAAQ,aAAa;AAC3B,WAAO,MAAM,QAAQ,UAAU,MAAM,WAAW,QAAQ,KAAK,MAAM;AAAA,EACrE,IAHoB;AAIpB,aAAW,OAAO,CAAC,KAAa,WAAqC;AACnE,UAAM,QAAQ,aAAa;AAC3B,WAAO,MAAM,QAAQ,cAAc,MAAM,WAAW,QAAQ,KAAK,MAAM;AAAA,EACzE;AACA,aAAW,MAAM,CAAC,QAAgB;AAChC,UAAM,QAAQ,aAAa;AAC3B,WAAO,MAAM,QAAQ,cAAc,MAAM,WAAW,QAAQ,GAAG;AAAA,EACjE;AACA,aAAW,MAAM,CAAC,QAAgB;AAChC,UAAM,QAAQ,aAAa;AAC3B,WAAO,MAAM,QAAQ,WAAW,MAAM,WAAW,QAAQ,GAAG;AAAA,EAC9D;AACA,SAAO;AACT;AAlBS;AAoBT,6BAA6B,MAAM,0BAA0B,CAAC;;;AI1L9D,IAAAC,2BAAkC;;;ACElC,IAAM,+BAA+B,uBAAO,IAAI,6BAA6B;AAM7E,SAAS,iBAAmD;AAC1D,SAAO;AACT;AAFS;AAIF,SAAS,2BAA2B,UAAoD;AAC7F,iBAAe,EAAE,4BAA4B,IAAI;AACnD;AAFgB;;;ADRhB,IAAM,sBAAsB,uBAAO,IAAI,+BAA+B;AAEtE,SAASC,mBAA8C;AACrD,QAAM,UAAU;AAChB,QAAM,WAAW,QAAQ,mBAAmB;AAC5C,MAAI,oBAAoB,4CAAmB;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,2CAA2B;AAC/C,UAAQ,mBAAmB,IAAI;AAC/B,SAAO;AACT;AAVS,OAAAA,kBAAA;AAYT,IAAM,eAAeA,iBAAgB;AAErC,2BAA2B,MAAM,aAAa,SAAS,CAAC;AAiCxD,eAAsB,uBACpB,SACA,IACY;AACZ,SAAO,aAAa,IAAI,SAAS,EAAE;AACrC;AALsB;;;AErDtB,yBAAqD;AA2D9C,IAAM,mBAAN,MAAM,yBAAwE,MAAM;AAAA,EAKzF,YACE,MACA,MACA,SAIA;AACA,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS,QAAQ;AAAA,EACxB;AACF;AAnB2F;AAApF,IAAM,kBAAN;AAqBA,SAAS,kBAAkB,OAA2D;AAC3F,SAAO,iBAAiB;AAC1B;AAFgB;AAkXhB,IAAM,4BAA4B,OAAO,OAAO,CAAC,CAAC;AAClD,IAAM,yBAAyB,OAAO,OAAO,uBAAO,OAAO,IAAI,CAAC;;;ACnbzD,SAAS,cACd,QACA,UACyB;AACzB,QAAM,aAAa,OAAO,IAAI,QAAQ;AACtC,MAAI,YAAY;AACd,WAAO,EAAE,OAAO,YAAY,QAAQ,CAAC,EAAE;AAAA,EACzC;AAEA,QAAM,qBAAqB,kBAAkB,QAAQ;AACrD,MAAI,uBAAuB,UAAU;AACnC,UAAM,kBAAkB,OAAO,IAAI,kBAAkB;AACrD,QAAI,iBAAiB;AACnB,aAAO,EAAE,OAAO,iBAAiB,QAAQ,CAAC,EAAE;AAAA,IAC9C;AAAA,EACF;AAEA,aAAW,SAAS,OAAO,OAAO,GAAG;AACnC,UAAM,SAAS,eAAe,MAAM,MAAM,QAAQ;AAClD,QAAI,QAAQ;AACV,aAAO,EAAE,OAAO,OAAO;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AACT;AAzBgB;AA2BhB,eAAsB,uBACpB,UACA,SACA,SAAyB,CAAC,GACP;AACnB,SAAO;AAAA,IAAuB;AAAA,IAAS,MACrC,gCAAgC,UAAU,SAAS,MAAM;AAAA,EAC3D;AACF;AARsB;AAUtB,eAAe,gCACb,UACA,SACA,QACmB;AACnB,QAAM,cAAc,SAAS,cAAc,qBAAqB,QAAQ,IAAI,WAAW;AAEvF,MAAI,CAAC,aAAa;AAChB,UAAM,SAAS,MAAM,SAAS,SAAS;AAAA,MACrC,QAAQ,QAAQ,QAAQ,MAAM;AAAA,IAChC,CAAC;AACD,WAAO,uBAAuB,MAAM;AAAA,EACtC;AAEA,QAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAM,QAAgC,CAAC;AACvC,MAAI,aAAa,QAAQ,CAAC,OAAO,QAAQ;AACvC,UAAM,GAAG,IAAI;AAAA,EACf,CAAC;AAED,MAAI,OAAY;AAChB,MAAI,QAAQ,OAAO,YAAY,MAAM,SAAS,QAAQ,OAAO,YAAY,MAAM,QAAQ;AACrF,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC;AAEA,QAAM,UAAU,OAAO,YAAY,QAAQ,QAAQ,QAAQ,CAAC;AAC5D,QAAM,QAAQ,SAAS,WAAW,CAAC;AAEnC,QAAM,kBAAkB,cAAc,MAAM,OAAO,OAAO,0BAA0B;AACpF,MAAI,2BAA2B,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,cAAc,MAAM,MAAM,MAAM,sBAAsB;AAC7E,MAAI,0BAA0B,UAAU;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,cAAc,MAAM,SAAS,SAAS,yBAAyB;AACzF,MAAI,6BAA6B,UAAU;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB;AAAA,IACrB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT;AAAA,IACA,SAAS,CAAC;AAAA,IACV;AAAA,EACF;AACA,MAAI;AAMJ,MAAI;AACF,gBACE,OAAO,SAAS,iBAAiB,aAC7B,MAAM,SAAS,aAAa,cAAc,IAC1C;AAAA,MACE,QAAQ,MAAM,YAAY,cAAc;AAAA,MACxC,SAAS,eAAe;AAAA,MACxB,iBAAiB;AAAA,MACjB,eAAe,CAAC;AAAA,IAClB;AAAA,EACR,SAAS,OAAO;AACd,QAAI,kBAAkB,KAAK,GAAG;AAC5B,aAAO,8BAA8B,KAAK;AAAA,IAC5C;AACA,UAAM;AAAA,EACR;AAEA,QAAM,WAAW,uBAAuB,UAAU,MAAM;AACxD,SAAO,4BAA4B,UAAU,UAAU,aAAa;AACtE;AA5Ee;AA8ER,SAAS,uBAAuB,QAA2B;AAChE,MAAI,cAAc,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,QAAW;AACxB,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C;AAEA,SAAO,IAAI,SAAS,KAAK,UAAU,MAAM,GAAG;AAAA,IAC1C,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AACH;AAbgB;AAeT,SAAS,cAAc,OAAmC;AAC/D,SACE,iBAAiB,YAChB,OAAO,UAAU,YAChB,UAAU,QACV,aAAa,SACb,YAAY,SACZ,OAAQ,MAAmB,gBAAgB;AAEjD;AATgB;AAWhB,SAAS,4BAA4B,UAAoB,MAAmC;AAC1F,QAAM,WAAW;AAAA,IACf,SAAS,QAAQ,IAAI,8BAA8B;AAAA,EACrD;AACA,QAAM,UAAU,6BAA6B,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC;AACnE,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,UAAQ,IAAI,gCAAgC,OAAO;AACnD,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAdS;AAgBF,SAAS,8BAA8B,SAAqD;AACjG,SAAO,IAAI;AAAA,IACT,KAAK,UAAU;AAAA,MACb,OAAO;AAAA,QACL,MAAM,QAAQ;AAAA,QACd,SAAS,QAAQ;AAAA,QACjB,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,IACD;AAAA,MACE,QAAQ,QAAQ;AAAA,MAChB,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAjBgB;AAmBhB,SAAS,qBAAqB,UAA4B;AACxD,MAAI,OAAO,aAAa,YAAY;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,UAAU,SAAS,KAAK,QAAQ,EAAE,KAAK;AAC/D,QAAM,aAAa,OAAO,MAAM,uDAAuD;AACvF,QAAM,gBAAgB,OAAO,MAAM,wCAAwC;AAC3E,QAAM,kBAAkB,aAAa,CAAC,KAAK,aAAa,CAAC,KAAK,gBAAgB,CAAC,KAAK,IACjF,MAAM,GAAG,EAAE,CAAC,EACZ,KAAK;AAER,SAAO,mBAAmB,SAAS,mBAAmB,aAAa,eAAe,WAAW,GAAG;AAClG;AAbS;AAeT,eAAe,aAAa,SAAoC;AAC9D,MAAI;AACF,UAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,KAAK;AACxC,QAAI,MAAM;AACR,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAXe;AAaf,SAAS,cAAc,QAAa,OAAgB,OAAmC;AACrF,MAAI,CAAC,UAAU,OAAO,OAAO,UAAU,YAAY;AACjD,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,OAAO,MAAM,KAAK;AAAA,EAC3B,SAAS,iBAAsB;AAC7B,WAAO,IAAI;AAAA,MACT,KAAK,UAAU;AAAA,QACb;AAAA,QACA,SAAS,gBAAgB,UAAU,gBAAgB,UAAU,gBAAgB;AAAA,MAC/E,CAAC;AAAA,MACD;AAAA,QACE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAnBS;AAqBT,SAAS,eAAe,WAAmB,UAAyC;AAClF,QAAM,gBAAgB,gBAAgB,SAAS;AAC/C,QAAM,mBAAmB,gBAAgB,QAAQ;AACjD,QAAM,SAAyB,CAAC;AAChC,MAAI,YAAY;AAEhB,aAAW,gBAAgB,eAAe;AACxC,UAAM,iBAAiB,oBAAoB,YAAY;AAEvD,QAAI,gBAAgB,UAAU;AAC5B,YAAM,oBAAoB,iBAAiB,MAAM,SAAS,EAAE,IAAI,iBAAiB;AACjF,UAAI,kBAAkB,WAAW,KAAK,CAAC,eAAe,UAAU;AAC9D,eAAO;AAAA,MACT;AACA,UAAI,kBAAkB,SAAS,GAAG;AAChC,eAAO,eAAe,IAAI,IAAI;AAAA,MAChC;AACA,kBAAY,iBAAiB;AAC7B;AAAA,IACF;AAEA,UAAM,kBAAkB,iBAAiB,SAAS;AAClD,QAAI,oBAAoB,QAAW;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,gBAAgB;AAClB,aAAO,eAAe,IAAI,IAAI,kBAAkB,eAAe;AAC/D;AACA;AAAA,IACF;AAEA,QAAI,iBAAiB,iBAAiB;AACpC,aAAO;AAAA,IACT;AAEA;AAAA,EACF;AAEA,SAAO,cAAc,iBAAiB,SAAS,SAAS;AAC1D;AAxCS;AA0CT,SAAS,gBAAgB,UAA4B;AACnD,SAAO,kBAAkB,QAAQ,EAC9B,MAAM,GAAG,EACT,OAAO,CAAC,YAAY,QAAQ,SAAS,CAAC;AAC3C;AAJS;AAMT,SAAS,kBAAkB,UAA0B;AACnD,MAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAG,GAAG;AACjD,WAAO,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACpC;AAEA,SAAO;AACT;AANS;AAQT,SAAS,oBACP,SAC+D;AAC/D,QAAM,mBAAmB,QAAQ,MAAM,sBAAsB;AAC7D,MAAI,mBAAmB,CAAC,GAAG;AACzB,WAAO,EAAE,MAAM,iBAAiB,CAAC,GAAG,UAAU,MAAM,UAAU,KAAK;AAAA,EACrE;AAEA,QAAM,WAAW,QAAQ,MAAM,kBAAkB;AACjD,MAAI,WAAW,CAAC,GAAG;AACjB,WAAO,EAAE,MAAM,SAAS,CAAC,GAAG,UAAU,MAAM,UAAU,MAAM;AAAA,EAC9D;AAEA,QAAM,UAAU,QAAQ,MAAM,YAAY;AAC1C,MAAI,UAAU,CAAC,GAAG;AAChB,WAAO,EAAE,MAAM,QAAQ,CAAC,GAAG,UAAU,OAAO,UAAU,MAAM;AAAA,EAC9D;AAEA,SAAO;AACT;AAnBS;AAqBT,SAAS,kBAAkB,SAAyB;AAClD,MAAI;AACF,WAAO,mBAAmB,OAAO;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AANS;;;AhBhSF,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,mBAAN,MAAM,iBAAgB;AAAA,EAO3B,YACE,QACA,YACA,UAAkC,CAAC,GACnC;AAVF,SAAQ,SAAgC,oBAAI,IAAI;AAW9C,SAAK,UAAU,MAAM,QAAQ,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,MAAgB;AACtE,SAAK,aAAa;AAClB,SAAK,mBAAmB,QAAQ,qBAAqB;AACrD,SAAK,OAAO,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAgC;AACpC,SAAK,OAAO,MAAM;AAElB,eAAW,UAAU,KAAK,SAAS;AACjC,YAAM,SAAc,WAAK,QAAQ,KAAK;AACtC,UAAI,aAAuB,CAAC;AAE5B,UAAO,cAAW,MAAM,GAAG;AACzB,qBAAa,KAAK,eAAe,MAAM;AAAA,MACzC;AAEA,iBAAW,YAAY,YAAY;AACjC,cAAM,KAAK,UAAU,UAAU,MAAM;AAAA,MACvC;AAEA,YAAM,KAAK,eAAe,MAAM;AAChC,YAAM,KAAK,0BAA0B,MAAM;AAAA,IAC7C;AAEA,QAAI,QAAQ,IAAI,cAAc;AAC5B,aAAO,QAAQ,cAAc,KAAK,OAAO,IAAI,aAAa;AAC1D,iBAAW,CAAC,WAAW,KAAK,KAAK,KAAK,QAAQ;AAC5C,eAAO,KAAK,KAAK,MAAM,QAAQ,KAAK,IAAI,CAAC,IAAI,SAAS,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,KAAuB;AAC5C,UAAM,QAAkB,CAAC;AAEzB,QAAI,CAAI,cAAW,GAAG,GAAG;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,UAAa,eAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAE3D,eAAW,SAAS,SAAS;AAC3B,YAAM,WAAgB,WAAK,KAAK,MAAM,IAAI;AAE1C,UAAI,MAAM,YAAY,GAAG;AACvB,cAAM,KAAK,GAAG,KAAK,eAAe,QAAQ,CAAC;AAAA,MAC7C,WACE,MAAM,SAAS,cACf,MAAM,SAAS,eACf,MAAM,SAAS,YACf;AACA,cAAM,KAAK,QAAQ;AAAA,MACrB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAU,UAAkB,QAA+B;AACvE,QAAI;AAGF,YAAM,SAAc,WAAK,QAAQ,KAAK;AACtC,YAAM,eAAoB,eAAS,QAAa,cAAQ,QAAQ,CAAC;AACjE,YAAM,YAAY,WAAW,iBAAiB,MAAM,KAAK,aAAa,QAAQ,OAAO,GAAG;AAExF,YAAM,cAAc,MAAM,KAAK,WAAW,QAAQ;AAElD,YAAM,YAAiC,CAAC;AACxC,YAAM,mBAA6B,CAAC;AAEpC,iBAAW,UAAU,mBAAmB;AACtC,YAAI,YAAY,MAAM,GAAG;AACvB,oBAAU,MAAM,IAAI,YAAY,MAAM;AACtC,2BAAiB,KAAK,MAAM;AAAA,QAC9B;AAAA,MACF;AAEA,UAAI,iBAAiB,SAAS,GAAG;AAC/B,cAAM,gBAAgB;AAAA,UACpB,0BAA0B,WAAW;AAAA,UACrC,cAAc,SAAS;AAAA,QACzB;AACA,aAAK,OAAO,IAAI,WAAW;AAAA,UACzB,MAAM;AAAA,UACN;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,WAAK,gBAAgB,uBAAuB,QAAQ,IAAI,KAAK;AAAA,IAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,QAA+B;AAC1D,UAAM,aAAa,KAAK,mBAAmB,MAAM;AACjD,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,QAAI;AACF,YAAM,eAAe,MAAM,KAAK,WAAW,UAAU;AAErD,iBAAW,eAAe,OAAO,OAAO,YAAY,GAAG;AACrD,cAAM,WAAW;AACjB,YAAI,CAAC,UAAU,QAAQ;AACrB;AAAA,QACF;AAEA,cAAM,SAAS,OAAO,SAAS,YAAY,KAAK,EAAE,YAAY;AAC9D,aAAK,YAAY,SAAS,QAAQ,YAAY,QAAQ,QAAQ;AAAA,MAChE;AAAA,IACF,SAAS,OAAO;AACd,WAAK,gBAAgB,iCAAiC,UAAU,IAAI,KAAK;AAAA,IAC3E;AAAA,EACF;AAAA,EAEA,MAAc,0BAA0B,QAA+B;AACrE,UAAM,iBAAiB,CAAM,cAAQ,MAAM,GAAG,MAAM;AACpD,UAAM,aAAa,MAAM;AAAA,MACvB,IAAI,IAAI,eAAe,QAAQ,CAAC,YAAY,gCAAgC,OAAO,CAAC,CAAC;AAAA,IACvF;AAEA,eAAW,aAAa,YAAY;AAClC,UAAI;AACF,cAAM,eAAe,MAAM,KAAK,WAAW,SAAS;AACpD,cAAM,WAAW,6BAA6B,YAAY;AAC1D,YAAI,CAAC,SAAU;AAEf,mBAAW,cAAc,SAAS,QAAQ;AACxC,cAAI,WAAW,SAAS,MAAO;AAC/B,eAAK,wBAAwB,WAAW,UAAU;AAAA,QACpD;AAAA,MACF,SAAS,OAAO;AACd,aAAK,gBAAgB,yCAAyC,SAAS,IAAI,KAAK;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAiB,OAAsB;AAC7D,WAAO,MAAM,GAAG,OAAO,KAAK,KAAK,EAAE;AACnC,QAAI,KAAK,kBAAkB;AACzB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,mBAAmB,QAA+B;AACxD,UAAM,aAAa,CAAC,aAAa,cAAc,WAAW;AAC1D,UAAM,gBAAgB,CAAM,cAAQ,MAAM,GAAG,MAAM;AACnD,UAAM,OAAO,oBAAI,IAAY;AAE7B,eAAW,OAAO,eAAe;AAC/B,iBAAW,aAAa,YAAY;AAClC,cAAM,aAAkB,WAAK,KAAK,SAAS;AAC3C,YAAI,KAAK,IAAI,UAAU,GAAG;AACxB;AAAA,QACF;AACA,aAAK,IAAI,UAAU;AAEnB,YAAO,cAAW,UAAU,GAAG;AAC7B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,WAAW,UAAoD;AAC3E,QAAI,KAAK,YAAY;AACnB,aAAO,MAAM,KAAK,WAAW,cAAc,QAAQ;AAAA,IACrD;AAEA,UAAM,UAAU,UAAU,QAAQ;AAClC,WAAO,MAAM;AAAA;AAAA,MAA0B;AAAA;AAAA,EACzC;AAAA,EAEQ,YACN,WACA,UACA,QACA,UACA,gBAAwC,CAAC,GACnC;AACN,UAAM,mBAAmB,OAAO,YAAY;AAC5C,UAAM,gBAAgB,KAAK,OAAO,IAAI,SAAS;AAE/C,QAAI,eAAe;AACjB,UAAI,CAAC,cAAc,QAAQ,SAAS,gBAAgB,GAAG;AACrD,sBAAc,QAAQ,KAAK,gBAAgB;AAAA,MAC7C;AACA,oBAAc,UAAU,gBAAgB,IAAI;AAC5C,aAAO,OAAO,eAAe,aAAa;AAC1C;AAAA,IACF;AAEA,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,MAAM;AAAA,MACN;AAAA,MACA,SAAS,CAAC,gBAAgB;AAAA,MAC1B,WAAW,EAAE,CAAC,gBAAgB,GAAG,SAAS;AAAA,MAC1C,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEQ,wBAAwB,UAAkB,OAAmC;AACnF,UAAM,aAAa,gCAAgC,UAAU,OAAO,MAAM,IAAI;AAC9E,UAAM,gBAAgB,gCAAgC,OAAO,cAAc,MAAM,IAAI,GAAG;AACxF,eAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,MAAM,OAAO,GAAG;AAC9D,UAAI,UAAU;AACZ,aAAK,YAAY,MAAM,MAAM,YAAY,QAAQ,UAAU,aAAa;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAA2D;AACzD,QAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,YAAwC;AACpD,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,YAAM,WAAW,IAAI;AACrB,YAAM,SAAS,QAAQ,OAAO,YAAY;AAG1C,YAAM,QAAQ,cAAc,KAAK,QAAQ,QAAQ;AACjD,UAAI,CAAC,OAAO;AACV,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,YAAY,CAAC,GAAG;AAAA,UAC1D,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAGA,YAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,YAAM,WAAW,MAAM,UAAU,MAAM;AACvC,UAAI,CAAC,UAAU;AACb,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,qBAAqB,CAAC,GAAG;AAAA,UACnE,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAEA,YAAM,SAAS,mCAAY;AACzB,YAAI;AACF,iBAAO,MAAM,uBAAuB,UAAU,SAAS,MAAM;AAAA,QAC/D,SAAS,OAAY;AACnB,kBAAQ,MAAM,eAAe,QAAQ,KAAK,KAAK;AAC/C,iBAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC,GAAG;AAAA,YACtE,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAChD,CAAC;AAAA,QACH;AAAA,MACF,GAVe;AAYf,aAAO,KAAK,MAAM,OAAO,UACrB,wBAAwB,KAAK,MAAM,SAAS,QAAQ;AAAA,QAClD,UAAU;AAAA,MACZ,CAAC,IACD,OAAO;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,UAA2B;AACpC,WAAO,QAAQ,KAAK,WAAW,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,WAAW,UAAkD;AAC3D,WAAO,cAAc,KAAK,QAAQ,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,YAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AACF;AAvT6B;AAAtB,IAAM,kBAAN;","names":["path","path","import_node_async_hooks","getRequestStore"]}
1
+ {"version":3,"sources":["../../src/api/route-manager.ts","../../src/utils.ts","../../src/routes.ts","../../src/observability.ts","../../src/cache-invalidation.ts","../../src/i18n/bridge.ts","../../src/cache.ts","../../src/route-runtime.ts","../../src/routes.server.ts","../../src/i18n/server.ts","../../src/i18n/runtime.ts","../../src/i18n/catalog.ts","../../src/i18n/config.ts","../../src/server/request.ts","../../src/server/request-bridge.ts","../../src/api/endpoint.ts","../../src/api/runtime.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { ViteDevServer } from \"vite\";\nimport { logger } from \"../utils\";\nimport {\n createProgrammaticRouteModuleId,\n getProgrammaticRouteManifest,\n type ProgrammaticApiRoute,\n} from \"../routes\";\nimport { findProgrammaticRouteFilesInDir } from \"../routes.server\";\nimport {\n getFarmRouteRuntimeConfig,\n normalizeFarmRouteRuntimeConfig,\n type FarmRouteRuntimeConfig,\n} from \"../route-runtime\";\nimport { _runWithFarmI18nRequest, type FarmI18nRuntime } from \"../i18n/server\";\nimport { invokeAPIRouteEndpoint, matchAPIRoute, type APIRouteMatch } from \"./runtime\";\n\nexport interface APIRoute extends FarmRouteRuntimeConfig {\n path: string;\n filePath: string;\n methods: string[];\n endpoints: Record<string, any>;\n}\n\nexport interface APIRouteManagerOptions {\n throwOnLoadError?: boolean;\n i18n?: FarmI18nRuntime;\n}\n\nexport const API_ROUTE_METHODS = [\n \"GET\",\n \"HEAD\",\n \"POST\",\n \"PUT\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n] as const;\n\nexport class APIRouteManager {\n private routes: Map<string, APIRoute> = new Map();\n private viteServer?: ViteDevServer;\n private appDirs: string[];\n private throwOnLoadError: boolean;\n private i18n?: FarmI18nRuntime;\n\n constructor(\n appDir: string | readonly string[],\n viteServer?: ViteDevServer,\n options: APIRouteManagerOptions = {},\n ) {\n this.appDirs = Array.isArray(appDir) ? [...appDir] : [appDir as string];\n this.viteServer = viteServer;\n this.throwOnLoadError = options.throwOnLoadError === true;\n this.i18n = options.i18n;\n }\n\n /**\n * Discover route.ts files in /app/api and explicit endpoints in root routes.ts\n */\n async discoverRoutes(): Promise<void> {\n this.routes.clear();\n\n for (const appDir of this.appDirs) {\n const apiDir = path.join(appDir, \"api\");\n let routeFiles: string[] = [];\n\n if (fs.existsSync(apiDir)) {\n routeFiles = this.findRouteFiles(apiDir);\n }\n\n for (const filePath of routeFiles) {\n await this.loadRoute(filePath, appDir);\n }\n\n await this.loadRootRoutes(appDir);\n await this.loadProgrammaticApiRoutes(appDir);\n }\n\n if (process.env.FARM_VERBOSE) {\n logger.success(`Discovered ${this.routes.size} API routes`);\n for (const [routePath, route] of this.routes) {\n logger.info(` ${route.methods.join(\", \")} ${routePath}`);\n }\n }\n }\n\n /**\n * Recursively find all route.ts files\n */\n private findRouteFiles(dir: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...this.findRouteFiles(fullPath));\n } else if (\n entry.name === \"route.ts\" ||\n entry.name === \"route.tsx\" ||\n entry.name === \"route.js\"\n ) {\n files.push(fullPath);\n }\n }\n\n return files;\n }\n\n /**\n * Load a route.ts file and extract HTTP method exports\n */\n private async loadRoute(filePath: string, appDir: string): Promise<void> {\n try {\n // Convert file path to API route path\n // /app/api/auth/login/route.ts -> /api/auth/login\n const apiDir = path.join(appDir, \"api\");\n const relativePath = path.relative(apiDir, path.dirname(filePath));\n const routePath = \"/api/\" + (relativePath === \".\" ? \"\" : relativePath.replace(/\\\\/g, \"/\"));\n\n const routeModule = await this.loadModule(filePath);\n\n const endpoints: Record<string, any> = {};\n const availableMethods: string[] = [];\n\n for (const method of API_ROUTE_METHODS) {\n if (routeModule[method]) {\n endpoints[method] = routeModule[method];\n availableMethods.push(method);\n }\n }\n\n if (availableMethods.length > 0) {\n const runtimeConfig = normalizeFarmRouteRuntimeConfig(\n getFarmRouteRuntimeConfig(routeModule),\n `API route \"${routePath}\"`,\n );\n this.routes.set(routePath, {\n path: routePath,\n filePath,\n methods: availableMethods,\n endpoints,\n ...runtimeConfig,\n });\n }\n } catch (error) {\n this.handleLoadError(`Error loading route ${filePath}`, error);\n }\n }\n\n /**\n * Load explicit-path endpoints from src/routes.ts-style files.\n */\n private async loadRootRoutes(appDir: string): Promise<void> {\n const routesFile = this.findRootRoutesFile(appDir);\n if (!routesFile) {\n return;\n }\n\n try {\n const routesModule = await this.loadModule(routesFile);\n\n for (const exportValue of Object.values(routesModule)) {\n const endpoint = exportValue as any;\n if (!endpoint?.__path) {\n continue;\n }\n\n const method = String(endpoint.__method || \"GET\").toUpperCase();\n this.addEndpoint(endpoint.__path, routesFile, method, endpoint);\n }\n } catch (error) {\n this.handleLoadError(`Error loading root API routes ${routesFile}`, error);\n }\n }\n\n private async loadProgrammaticApiRoutes(appDir: string): Promise<void> {\n const candidateRoots = [path.dirname(appDir), appDir];\n const routeFiles = Array.from(\n new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot))),\n );\n\n for (const routeFile of routeFiles) {\n try {\n const routesModule = await this.loadModule(routeFile);\n const manifest = getProgrammaticRouteManifest(routesModule);\n if (!manifest) continue;\n\n for (const definition of manifest.routes) {\n if (definition.kind !== \"api\") continue;\n this.addProgrammaticApiRoute(routeFile, definition);\n }\n } catch (error) {\n this.handleLoadError(`Error loading programmatic API routes ${routeFile}`, error);\n }\n }\n }\n\n private handleLoadError(message: string, error: unknown): void {\n logger.error(`${message}: ${error}`);\n if (this.throwOnLoadError) {\n throw error;\n }\n }\n\n private findRootRoutesFile(appDir: string): string | null {\n const routeNames = [\"routes.ts\", \"routes.tsx\", \"routes.js\"];\n const candidateDirs = [path.dirname(appDir), appDir];\n const seen = new Set<string>();\n\n for (const dir of candidateDirs) {\n for (const routeName of routeNames) {\n const routesFile = path.join(dir, routeName);\n if (seen.has(routesFile)) {\n continue;\n }\n seen.add(routesFile);\n\n if (fs.existsSync(routesFile)) {\n return routesFile;\n }\n }\n }\n\n return null;\n }\n\n private async loadModule(filePath: string): Promise<Record<string, unknown>> {\n if (this.viteServer) {\n return await this.viteServer.ssrLoadModule(filePath);\n }\n\n const fileUrl = `file://${filePath}`;\n return await import(/* @vite-ignore */ fileUrl);\n }\n\n private addEndpoint(\n routePath: string,\n filePath: string,\n method: string,\n endpoint: any,\n runtimeConfig: FarmRouteRuntimeConfig = {},\n ): void {\n const normalizedMethod = method.toUpperCase();\n const existingRoute = this.routes.get(routePath);\n\n if (existingRoute) {\n if (!existingRoute.methods.includes(normalizedMethod)) {\n existingRoute.methods.push(normalizedMethod);\n }\n existingRoute.endpoints[normalizedMethod] = endpoint;\n Object.assign(existingRoute, runtimeConfig);\n return;\n }\n\n this.routes.set(routePath, {\n path: routePath,\n filePath,\n methods: [normalizedMethod],\n endpoints: { [normalizedMethod]: endpoint },\n ...runtimeConfig,\n });\n }\n\n private addProgrammaticApiRoute(filePath: string, route: ProgrammaticApiRoute): void {\n const modulePath = createProgrammaticRouteModuleId(filePath, \"api\", route.path);\n const runtimeConfig = normalizeFarmRouteRuntimeConfig(route, `API route \"${route.path}\"`);\n for (const [method, endpoint] of Object.entries(route.methods)) {\n if (endpoint) {\n this.addEndpoint(route.path, modulePath, method, endpoint, runtimeConfig);\n }\n }\n }\n\n /**\n * Get the handler that directly invokes endpoint handlers\n */\n getHandler(): ((req: Request) => Promise<Response>) | null {\n if (this.routes.size === 0) {\n return null;\n }\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n const pathname = url.pathname;\n const method = request.method.toUpperCase();\n\n // Find matching route\n const match = matchAPIRoute(this.routes, pathname);\n if (!match) {\n return new Response(JSON.stringify({ error: \"Not Found\" }), {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // Check if method is supported\n const { route, params } = match;\n const endpoint = route.endpoints[method];\n if (!endpoint) {\n return new Response(JSON.stringify({ error: \"Method Not Allowed\" }), {\n status: 405,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n const invoke = async () => {\n try {\n return await invokeAPIRouteEndpoint(endpoint, request, params);\n } catch (error: any) {\n console.error(`[API Error] ${pathname}:`, error);\n return new Response(JSON.stringify({ error: \"Internal Server Error\" }), {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n };\n\n return this.i18n?.config.enabled\n ? _runWithFarmI18nRequest(this.i18n, request, invoke, {\n redirect: false,\n })\n : invoke();\n };\n }\n\n /**\n * Check if a path is an API route\n */\n isAPIRoute(pathname: string): boolean {\n return Boolean(this.matchRoute(pathname));\n }\n\n matchRoute(pathname: string): APIRouteMatch<APIRoute> | null {\n return matchAPIRoute(this.routes, pathname);\n }\n\n /**\n * Get all routes for client type generation\n */\n getRoutes(): Map<string, APIRoute> {\n return this.routes;\n }\n}\n\nexport {\n invokeAPIRouteEndpoint,\n isWebResponse,\n matchAPIRoute,\n normalizeRouteResponse,\n} from \"./runtime\";\nexport type { APIRouteMatch, APIRouteParams, APIRouteParamValue } from \"./runtime\";\n","import type { RouteSegment, ParsedRoute } from \"./types\";\nimport path from \"path\";\n\nexport function parseRoutePath(filePath: string): ParsedRoute {\n const segments: RouteSegment[] = [];\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n const pathParts = normalizedPath.split(\"/\").filter(Boolean);\n\n const fileName = pathParts.pop() || \"\";\n const fileType = getRouteType(fileName);\n\n for (const part of pathParts) {\n if (part.startsWith(\"[\") && part.endsWith(\"]\")) {\n let segment = part.slice(1, -1);\n const isDynamic = true;\n let isOptional = false;\n let isCatchAll = false;\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n isOptional = true;\n segment = segment.slice(1, -1);\n if (segment.startsWith(\"...\")) {\n segment = segment.slice(3);\n isCatchAll = true;\n }\n } else if (segment.startsWith(\"...\")) {\n segment = segment.slice(3);\n isCatchAll = true;\n }\n\n segments.push({ segment, isDynamic, isOptional, isCatchAll });\n } else {\n segments.push({\n segment: part,\n isDynamic: false,\n isOptional: false,\n isCatchAll: false,\n });\n }\n }\n\n return {\n segments,\n filePath: normalizedPath,\n type: fileType,\n };\n}\n\nfunction getRouteType(fileName: string): ParsedRoute[\"type\"] {\n const baseName = fileName.replace(/\\.(tsx?|jsx?|mdx?|markdown)$/, \"\");\n\n switch (baseName) {\n case \"page\":\n return \"page\";\n case \"layout\":\n return \"layout\";\n case \"loading\":\n return \"loading\";\n case \"error\":\n return \"error\";\n case \"not-found\":\n return \"not-found\";\n default:\n return \"page\";\n }\n}\n\nexport function segmentsToPattern(segments: RouteSegment[]): string {\n if (segments.length === 0) return \"/\";\n\n return (\n \"/\" +\n segments\n .map((segment) => {\n if (!segment.isDynamic) return segment.segment;\n\n if (segment.isCatchAll) {\n return segment.isOptional ? `*${segment.segment}?` : `*${segment.segment}`;\n }\n\n return `:${segment.segment}`;\n })\n .join(\"/\")\n );\n}\n\nexport function matchRoute(\n url: string,\n segments: RouteSegment[],\n): { params: Record<string, string>; matches: boolean } {\n const urlParts = url.split(\"/\").filter(Boolean);\n const params: Record<string, string> = {};\n if (segments.length === 0) {\n return { params, matches: urlParts.length === 0 };\n }\n\n let urlIndex = 0;\n let segmentIndex = 0;\n\n while (segmentIndex < segments.length && urlIndex <= urlParts.length) {\n const segment = segments[segmentIndex];\n\n if (!segment.isDynamic) {\n if (urlParts[urlIndex] !== segment.segment) {\n return { params: {}, matches: false };\n }\n urlIndex++;\n segmentIndex++;\n } else if (segment.isCatchAll) {\n const remainingParts = urlParts.slice(urlIndex);\n\n if (remainingParts.length === 0 && !segment.isOptional) {\n return { params: {}, matches: false };\n }\n\n params[segment.segment] = remainingParts.join(\"/\");\n urlIndex = urlParts.length;\n segmentIndex++;\n } else {\n if (urlIndex >= urlParts.length) {\n return { params: {}, matches: false };\n }\n\n params[segment.segment] = urlParts[urlIndex];\n urlIndex++;\n segmentIndex++;\n }\n }\n\n const matches = segmentIndex === segments.length && urlIndex === urlParts.length;\n\n return { params, matches };\n}\n\nexport function resolveAppPath(root: string, ...paths: string[]): string {\n return path.resolve(root, ...paths);\n}\n\nexport function toViteModuleId(filePath: string, root: string): string {\n if (!path.isAbsolute(filePath)) return filePath;\n\n const relativePath = path.relative(root, filePath);\n if (relativePath && !relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath)) {\n return `/${relativePath.split(path.sep).join(\"/\")}`;\n }\n\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n return normalizedPath.startsWith(\"/\") ? `/@fs${normalizedPath}` : `/@fs/${normalizedPath}`;\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const fs = await import(\"fs/promises\");\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function globFiles(pattern: string, cwd: string): Promise<string[]> {\n const glob = await import(\"fast-glob\");\n return glob.default(pattern, { cwd, absolute: false });\n}\n\nexport function parseSearchParams(\n searchParams: URLSearchParams,\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n\n for (const [key, value] of searchParams.entries()) {\n if (key in result) {\n const existing = result[key];\n if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n result[key] = [existing, value];\n }\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport const logger = {\n info: (message: string) => console.log(`[info] ${message}`),\n success: (message: string) => console.log(`[success] ${message}`),\n warn: (message: string) => console.warn(`⚠️ ${message}`),\n error: (message: string) => console.error(`❌ ${message}`),\n ready: (message: string) => console.log(`${message}`),\n event: (message: string) => console.log(` ${message}`),\n};\n","import { Suspense, createElement, type ComponentType } from \"react\";\nimport {\n createFarmCacheKey,\n createRouteDataCacheTag,\n getFarmDataCache,\n type FarmCacheOptions,\n type RouteDataCacheKey,\n} from \"./cache\";\nimport { getFarmRouteContext } from \"./route-context\";\nimport { normalizeFarmRouteRuntimeConfig, type FarmRouteRuntimeConfig } from \"./route-runtime\";\nimport type {\n FarmAppContext,\n LayoutProps,\n Metadata,\n PageProps,\n ParsedRoute,\n PluginContextProps,\n RouteModule,\n} from \"./types\";\n\nexport type ProgrammaticRouteRenderMode = \"static\" | \"dynamic\";\nexport type ProgrammaticRouteMethod =\n | \"GET\"\n | \"HEAD\"\n | \"POST\"\n | \"PUT\"\n | \"DELETE\"\n | \"PATCH\"\n | \"OPTIONS\";\n\nexport type ProgrammaticRoutePrimitive = string | number | boolean;\nexport type ProgrammaticStaticPathParams = Record<\n string,\n ProgrammaticRoutePrimitive | readonly ProgrammaticRoutePrimitive[]\n>;\nexport type ProgrammaticStaticPath =\n | string\n | readonly ProgrammaticRoutePrimitive[]\n | ProgrammaticStaticPathParams;\nexport type ProgrammaticStaticPaths = () =>\n | readonly ProgrammaticStaticPath[]\n | Promise<readonly ProgrammaticStaticPath[]>;\n\nexport interface ProgrammaticRouteSchema<TOutput = unknown> {\n parse(value: unknown): TOutput;\n}\n\nexport interface ProgrammaticRouteSearchOptions<TOutput = ProgrammaticRouteSearchFallback> {\n schema?: ProgrammaticRouteSchema<TOutput>;\n stripDefaults?: boolean | readonly string[];\n preserve?: readonly string[];\n temporary?: readonly string[];\n}\n\nexport type ProgrammaticRouteSearchConfig<TOutput = ProgrammaticRouteSearchFallback> =\n | ProgrammaticRouteSchema<TOutput>\n | ProgrammaticRouteSearchOptions<TOutput>;\n\nexport type InferProgrammaticRouteSchema<TSchema, TFallback> =\n TSchema extends ProgrammaticRouteSchema<infer TOutput> ? TOutput : TFallback;\n\nexport type InferProgrammaticRouteSearch<TSearch, TFallback> =\n TSearch extends ProgrammaticRouteSearchOptions<infer TOutput>\n ? TOutput\n : TSearch extends ProgrammaticRouteSchema<infer TOutput>\n ? TOutput\n : TFallback;\n\nexport type ProgrammaticRouteParamsFallback = Record<string, string>;\nexport type ProgrammaticRouteSearchFallback = Record<string, string | string[] | undefined>;\nexport type ProgrammaticRouteMaybePromise<T> = T | Promise<T>;\nexport type ProgrammaticRouteDataStaleTime =\n | number\n | false\n | `${number}ms`\n | `${number}s`\n | `${number}m`\n | `${number}h`;\nexport type ProgrammaticRouteContext = keyof FarmAppContext extends never\n ? unknown\n : FarmAppContext;\n\nexport type ProgrammaticRouteComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TData = undefined,\n> = Omit<PageProps, \"params\" | \"searchParams\"> & {\n params: TParams;\n search: TSearch;\n searchParams: Promise<TSearch>;\n} & ([TData] extends [undefined] ? { data?: undefined } : { data: TData });\n\nexport type ProgrammaticRouteDataContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = Omit<ProgrammaticRouteComponentProps<TParams, TSearch>, \"context\" | \"data\"> & {\n context: TContext;\n pluginContext?: PluginContextProps;\n};\n\nexport type ProgrammaticRouteDataCacheContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TContext = ProgrammaticRouteContext,\n> = ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: TBefore;\n};\n\nexport type ProgrammaticRouteGuardContext<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = ProgrammaticRouteDataContext<TParams, TSearch, TContext>;\n\nexport type ProgrammaticRouteGuard<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TContext = ProgrammaticRouteContext,\n> = (\n context: ProgrammaticRouteGuardContext<TParams, TSearch, TContext>,\n) => ProgrammaticRouteMaybePromise<void>;\n\nexport type ProgrammaticRouteErrorComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n> = Partial<ProgrammaticRouteComponentProps<TParams, TSearch>> & {\n error: unknown;\n};\n\nexport type ProgrammaticRoutePendingComponentProps<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n> = Partial<ProgrammaticRouteComponentProps<TParams, TSearch>>;\n\nexport type ProgrammaticRouteDataCacheKeys<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TContext = ProgrammaticRouteContext,\n> =\n | readonly string[]\n | ((\n context: ProgrammaticRouteDataCacheContext<TParams, TSearch, TBefore, TContext>,\n ) => ProgrammaticRouteMaybePromise<readonly string[]>);\n\nexport interface ProgrammaticRouteDataHooks<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TBefore = unknown,\n TData = unknown,\n TContext = ProgrammaticRouteContext,\n> {\n key?: (\n context: ProgrammaticRouteDataCacheContext<TParams, TSearch, NoInfer<TBefore>, TContext>,\n ) => ProgrammaticRouteMaybePromise<RouteDataCacheKey | null | undefined>;\n staleTime?: ProgrammaticRouteDataStaleTime;\n tags?: ProgrammaticRouteDataCacheKeys<TParams, TSearch, NoInfer<TBefore>, TContext>;\n paths?: ProgrammaticRouteDataCacheKeys<TParams, TSearch, NoInfer<TBefore>, TContext>;\n before?: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext>,\n ) => ProgrammaticRouteMaybePromise<TBefore>;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<TBefore>;\n },\n ) => ProgrammaticRouteMaybePromise<TData>;\n after?: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<TBefore>;\n data: NoInfer<TData>;\n },\n ) => ProgrammaticRouteMaybePromise<void>;\n}\n\nexport type InferProgrammaticRouteData<TDataHooks> = TDataHooks extends {\n main: (...args: any[]) => infer TResult;\n}\n ? Awaited<TResult>\n : undefined;\n\nexport interface ProgrammaticPageRoute<\n TParams = ProgrammaticRouteParamsFallback,\n TSearch = ProgrammaticRouteSearchFallback,\n TDataHooks extends ProgrammaticRouteDataHooks<TParams, TSearch, any, any, any> | undefined =\n | ProgrammaticRouteDataHooks<TParams, TSearch, any, any, any>\n | undefined,\n TContext = ProgrammaticRouteContext,\n> extends FarmRouteRuntimeConfig {\n kind: \"page\";\n path: string;\n component: ComponentType<any>;\n params?: ProgrammaticRouteSchema<TParams>;\n search?: ProgrammaticRouteSearchConfig<TSearch>;\n guard?: ProgrammaticRouteGuard<TParams, TSearch, TContext>;\n data?: TDataHooks;\n pending?: ComponentType<ProgrammaticRoutePendingComponentProps<TParams, TSearch>>;\n error?: ComponentType<ProgrammaticRouteErrorComponentProps<TParams, TSearch>>;\n notFound?: ComponentType<ProgrammaticRouteErrorComponentProps<TParams, TSearch>>;\n render?: ProgrammaticRouteRenderMode;\n staticPaths?: ProgrammaticStaticPaths;\n revalidate?: number | false;\n ppr?: boolean;\n metadata?: Metadata & Record<string, any>;\n generateMetadata?: RouteModule[\"generateMetadata\"];\n}\n\nexport interface ProgrammaticLayoutRoute extends FarmRouteRuntimeConfig {\n kind: \"layout\";\n path: string;\n component: ComponentType<LayoutProps>;\n metadata?: Metadata & Record<string, any>;\n generateMetadata?: (props: { params: Record<string, string> }) => Promise<Metadata> | Metadata;\n}\n\nexport type ProgrammaticApiRouteOptions = Partial<Record<ProgrammaticRouteMethod, any>> & {\n render?: ProgrammaticRouteRenderMode;\n} & FarmRouteRuntimeConfig;\n\nexport interface ProgrammaticApiRoute extends FarmRouteRuntimeConfig {\n kind: \"api\";\n path: string;\n methods: Partial<Record<ProgrammaticRouteMethod, any>>;\n render?: ProgrammaticRouteRenderMode;\n}\n\nexport interface ProgrammaticRedirectRoute {\n kind: \"redirect\";\n source: string;\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n}\n\nexport type ProgrammaticRouteDefinition =\n | ProgrammaticPageRoute<any, any>\n | ProgrammaticLayoutRoute\n | ProgrammaticApiRoute\n | ProgrammaticRedirectRoute;\n\nexport interface ProgrammaticRouteManifest {\n readonly __farmRoutes: true;\n routes: ProgrammaticRouteDefinition[];\n}\n\nexport interface ProgrammaticRouteBuilder {\n page(\n path: string,\n options: Omit<ProgrammaticPageRoute<any, any>, \"kind\" | \"path\">,\n ): ProgrammaticPageRoute;\n layout(\n path: string,\n options: Omit<ProgrammaticLayoutRoute, \"kind\" | \"path\">,\n ): ProgrammaticLayoutRoute;\n api(path: string, options: ProgrammaticApiRouteOptions): ProgrammaticApiRoute;\n redirect(\n source: string,\n destination: string,\n options?: Omit<ProgrammaticRedirectRoute, \"kind\" | \"source\" | \"destination\">,\n ): ProgrammaticRedirectRoute;\n}\n\nexport type ProgrammaticRouteFactory = (\n builder: ProgrammaticRouteBuilder,\n) => readonly ProgrammaticRouteDefinition[];\n\ntype CreateRouteParams<TParamsSchema> = InferProgrammaticRouteSchema<\n TParamsSchema,\n ProgrammaticRouteParamsFallback\n>;\n\ntype CreateRouteSearch<TSearchConfig> = InferProgrammaticRouteSearch<\n TSearchConfig,\n ProgrammaticRouteSearchFallback\n>;\n\ntype CreateRouteSharedOptions<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n> = Omit<\n ProgrammaticPageRoute<CreateRouteParams<TParamsSchema>, CreateRouteSearch<TSearchConfig>>,\n \"kind\" | \"path\" | \"component\" | \"params\" | \"search\" | \"data\" | \"guard\"\n> & {\n params?: TParamsSchema;\n search?: TSearchConfig;\n guard?: ProgrammaticRouteGuard<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>\n >;\n};\n\ntype CreateRouteDataHooksWithBefore<\n TParams,\n TSearch,\n TBeforeResult,\n TMainResult,\n TContext = ProgrammaticRouteContext,\n> = Omit<\n ProgrammaticRouteDataHooks<\n TParams,\n TSearch,\n NoInfer<Awaited<TBeforeResult>>,\n NoInfer<Awaited<TMainResult>>,\n TContext\n >,\n \"before\" | \"main\"\n> & {\n before: (context: ProgrammaticRouteDataContext<TParams, TSearch, TContext>) => TBeforeResult;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: NoInfer<Awaited<TBeforeResult>>;\n },\n ) => TMainResult;\n};\n\ntype CreateRouteDataHooksWithoutBefore<\n TParams,\n TSearch,\n TMainResult,\n TContext = ProgrammaticRouteContext,\n> = Omit<\n ProgrammaticRouteDataHooks<TParams, TSearch, undefined, NoInfer<Awaited<TMainResult>>, TContext>,\n \"before\" | \"main\"\n> & {\n before?: undefined;\n main: (\n context: ProgrammaticRouteDataContext<TParams, TSearch, TContext> & {\n before: undefined;\n },\n ) => TMainResult;\n};\n\ntype CreateRouteOptionsWithBefore<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n TBefore,\n TData,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data: CreateRouteDataHooksWithBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TBefore,\n TData\n >;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n NoInfer<Awaited<TData>>\n >\n >;\n};\n\ntype CreateRouteOptionsWithoutBefore<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n TData,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data: CreateRouteDataHooksWithoutBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TData\n >;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n NoInfer<Awaited<TData>>\n >\n >;\n};\n\ntype CreateRouteOptionsWithoutData<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined,\n> = CreateRouteSharedOptions<TParamsSchema, TSearchConfig> & {\n data?: undefined;\n component: ComponentType<\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n undefined\n >\n >;\n};\n\ntype CreateRouteComponentOption<TComponent extends ComponentType<any>, TProps> = {\n component: TComponent;\n} & (TComponent extends ComponentType<TProps> ? unknown : { component: ComponentType<TProps> });\n\nexport type CreateRouteOptions<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TBefore = unknown,\n TData = unknown,\n> =\n | CreateRouteOptionsWithBefore<TParamsSchema, TSearchConfig, TBefore, TData>\n | CreateRouteOptionsWithoutBefore<TParamsSchema, TSearchConfig, TData>\n | CreateRouteOptionsWithoutData<TParamsSchema, TSearchConfig>;\n\nconst FARM_ROUTES_BRAND = Symbol.for(\"farm.routes\");\nexport const PROGRAMMATIC_ROUTE_FILE_NAMES = [\n \"farm.route.ts\",\n \"farm.route.tsx\",\n \"farm.route.js\",\n \"farm.route.jsx\",\n \"farm.routes.ts\",\n \"farm.routes.tsx\",\n \"farm.routes.js\",\n \"farm.routes.jsx\",\n \"routes.ts\",\n \"routes.tsx\",\n \"routes.js\",\n \"routes.jsx\",\n];\n\nexport function defineRoutes(\n input: readonly ProgrammaticRouteDefinition[] | ProgrammaticRouteFactory,\n): ProgrammaticRouteManifest {\n const routes = typeof input === \"function\" ? input(routesBuilder) : input;\n const manifest = {\n __farmRoutes: true as const,\n routes: routes.map(normalizeProgrammaticRoute),\n };\n\n Object.defineProperty(manifest, FARM_ROUTES_BRAND, {\n value: true,\n enumerable: false,\n });\n\n return manifest;\n}\n\nexport const routesBuilder: ProgrammaticRouteBuilder = {\n page(path, options) {\n return normalizeProgrammaticRoute({\n kind: \"page\",\n path,\n ...options,\n }) as ProgrammaticPageRoute;\n },\n layout(path, options) {\n return normalizeProgrammaticRoute({\n kind: \"layout\",\n path,\n ...options,\n }) as ProgrammaticLayoutRoute;\n },\n api(path, options) {\n const { render, runtime, regions, maxDuration, ...methods } = options;\n return normalizeProgrammaticRoute({\n kind: \"api\",\n path,\n render,\n runtime,\n regions,\n maxDuration,\n methods: normalizeApiMethods(methods),\n }) as ProgrammaticApiRoute;\n },\n redirect(source, destination, options = {}) {\n return normalizeProgrammaticRoute({\n kind: \"redirect\",\n source,\n destination,\n ...options,\n }) as ProgrammaticRedirectRoute;\n },\n};\n\nexport const page = routesBuilder.page;\nexport const layout = routesBuilder.layout;\nexport const api = routesBuilder.api;\nexport const redirect = routesBuilder.redirect;\n\nexport interface ProgrammaticRouteSearchClientOptions {\n stripDefaults?: boolean | readonly string[];\n preserve?: readonly string[];\n temporary?: readonly string[];\n}\n\nexport interface ProgrammaticRouteSearchResolution<TSearch = unknown> {\n search: TSearch;\n canonicalPath?: string;\n}\n\nexport function getProgrammaticRouteSearchSchema<TSearch = unknown>(\n search: ProgrammaticRouteSearchConfig<TSearch> | undefined,\n): ProgrammaticRouteSchema<TSearch> | undefined {\n if (!search) return undefined;\n if (isProgrammaticRouteSchema(search)) return search;\n return search.schema;\n}\n\nexport function getProgrammaticRouteSearchClientOptions(\n search: ProgrammaticRouteSearchConfig<any> | undefined,\n): ProgrammaticRouteSearchClientOptions | undefined {\n if (!search || isProgrammaticRouteSchema(search)) return undefined;\n\n const options: ProgrammaticRouteSearchClientOptions = {};\n if (typeof search.stripDefaults !== \"undefined\") options.stripDefaults = search.stripDefaults;\n if (search.preserve?.length) options.preserve = [...search.preserve];\n if (search.temporary?.length) options.temporary = [...search.temporary];\n\n return Object.keys(options).length > 0 ? options : undefined;\n}\n\nfunction resolveProgrammaticRouteSearch<TSearch>(\n searchConfig: ProgrammaticRouteSearchConfig<TSearch> | undefined,\n rawSearch: ProgrammaticRouteSearchFallback,\n path: string,\n routePath: string,\n): ProgrammaticRouteSearchResolution<TSearch | ProgrammaticRouteSearchFallback> {\n const schema = getProgrammaticRouteSearchSchema(searchConfig);\n const search = parseProgrammaticSchema(schema, rawSearch, \"search\", routePath) as\n | TSearch\n | ProgrammaticRouteSearchFallback;\n const options = getProgrammaticRouteSearchOptions(searchConfig);\n const canonicalPath = resolveProgrammaticRouteCanonicalPath({\n options,\n schema,\n rawSearch,\n parsedSearch: search,\n path,\n });\n\n return { search, canonicalPath };\n}\n\nfunction getProgrammaticRouteSearchOptions(\n search: ProgrammaticRouteSearchConfig<any> | undefined,\n): ProgrammaticRouteSearchOptions<any> | undefined {\n if (!search || isProgrammaticRouteSchema(search)) return undefined;\n return search;\n}\n\nfunction isProgrammaticRouteSchema(value: unknown): value is ProgrammaticRouteSchema<any> {\n return !!value && typeof value === \"object\" && typeof (value as any).parse === \"function\";\n}\n\nfunction resolveProgrammaticRouteCanonicalPath(input: {\n options: ProgrammaticRouteSearchOptions<any> | undefined;\n schema: ProgrammaticRouteSchema<any> | undefined;\n rawSearch: ProgrammaticRouteSearchFallback;\n parsedSearch: unknown;\n path: string;\n}): string | undefined {\n const options = input.options;\n if (!options?.temporary?.length && !options?.stripDefaults) {\n return undefined;\n }\n\n const params = createSearchParams(input.rawSearch);\n const original = params.toString();\n\n for (const key of options.temporary || []) {\n params.delete(key);\n }\n\n if (options.stripDefaults) {\n const defaultSearch = parseDefaultSearch(input.schema);\n if (defaultSearch !== undefined) {\n const keys =\n options.stripDefaults === true\n ? Array.from(new Set(Array.from(params.keys())))\n : [...options.stripDefaults];\n\n for (const key of keys) {\n if (\n params.has(key) &&\n searchValuesEqual(\n readSearchValue(input.parsedSearch, key),\n readSearchValue(defaultSearch, key),\n )\n ) {\n params.delete(key);\n }\n }\n }\n }\n\n const next = params.toString();\n if (next === original) {\n return undefined;\n }\n\n return next ? `${input.path}?${next}` : input.path;\n}\n\nfunction createSearchParams(value: ProgrammaticRouteSearchFallback): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, item] of Object.entries(value)) {\n if (item == null) continue;\n const values = Array.isArray(item) ? item : [item];\n for (const entry of values) {\n if (entry != null) params.append(key, String(entry));\n }\n }\n\n return params;\n}\n\nfunction parseDefaultSearch(\n schema: ProgrammaticRouteSchema<any> | undefined,\n): Record<string, unknown> | undefined {\n if (!schema) return undefined;\n\n try {\n const value = schema.parse({});\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readSearchValue(value: unknown, key: string): unknown {\n return value && typeof value === \"object\" ? (value as Record<string, unknown>)[key] : undefined;\n}\n\nfunction searchValuesEqual(left: unknown, right: unknown): boolean {\n return (\n JSON.stringify(normalizeComparableValue(left)) ===\n JSON.stringify(normalizeComparableValue(right))\n );\n}\n\nfunction normalizeComparableValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(normalizeComparableValue);\n }\n if (value && typeof value === \"object\") {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((output, key) => {\n output[key] = normalizeComparableValue((value as Record<string, unknown>)[key]);\n return output;\n }, {});\n }\n return value;\n}\n\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TBeforeResult = unknown,\n TMainResult = unknown,\n TComponent extends ComponentType<any> = ComponentType<any>,\n>(\n path: string,\n options: Omit<\n CreateRouteOptionsWithBefore<TParamsSchema, TSearchConfig, TBeforeResult, TMainResult>,\n \"component\"\n > &\n CreateRouteComponentOption<\n TComponent,\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n Awaited<TMainResult>\n >\n >,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n CreateRouteDataHooksWithBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TBeforeResult,\n TMainResult\n >\n>;\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n TMainResult = unknown,\n TComponent extends ComponentType<any> = ComponentType<any>,\n>(\n path: string,\n options: Omit<\n CreateRouteOptionsWithoutBefore<TParamsSchema, TSearchConfig, TMainResult>,\n \"component\"\n > &\n CreateRouteComponentOption<\n TComponent,\n ProgrammaticRouteComponentProps<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n Awaited<TMainResult>\n >\n >,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n CreateRouteDataHooksWithoutBefore<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n TMainResult\n >\n>;\nexport function createRoute<\n TParamsSchema extends ProgrammaticRouteSchema<any> | undefined = undefined,\n TSearchConfig extends ProgrammaticRouteSearchConfig<any> | undefined = undefined,\n>(\n path: string,\n options: CreateRouteOptionsWithoutData<TParamsSchema, TSearchConfig>,\n): ProgrammaticPageRoute<\n CreateRouteParams<TParamsSchema>,\n CreateRouteSearch<TSearchConfig>,\n undefined\n>;\nexport function createRoute(path: string, options: any): any {\n return routesBuilder.page(path, options);\n}\n\nexport function isProgrammaticRoutesFileName(fileName: string): boolean {\n const normalized = fileName.replace(/\\\\/g, \"/\");\n const baseName = normalized.split(\"/\").pop() || normalized;\n return PROGRAMMATIC_ROUTE_FILE_NAMES.includes(baseName);\n}\n\nexport function getProgrammaticRouteManifest(\n mod: Record<string, any> | null | undefined,\n): ProgrammaticRouteManifest | null {\n if (!mod) return null;\n\n const candidates = [mod.default, mod.routes, mod.Route];\n for (const candidate of candidates) {\n if (isProgrammaticRouteManifest(candidate)) {\n return candidate;\n }\n if (isProgrammaticRouteDefinition(candidate)) {\n return defineRoutes([candidate]);\n }\n if (Array.isArray(candidate)) {\n return defineRoutes(candidate as ProgrammaticRouteDefinition[]);\n }\n }\n\n const routeDefinitions = Object.values(mod).filter(isProgrammaticRouteDefinition);\n if (routeDefinitions.length > 0) {\n return defineRoutes(routeDefinitions);\n }\n\n return null;\n}\n\nexport function isProgrammaticRouteManifest(value: unknown): value is ProgrammaticRouteManifest {\n return (\n !!value &&\n typeof value === \"object\" &&\n (value as ProgrammaticRouteManifest).__farmRoutes === true &&\n Array.isArray((value as ProgrammaticRouteManifest).routes)\n );\n}\n\nexport function isProgrammaticRouteDefinition(\n value: unknown,\n): value is ProgrammaticRouteDefinition {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const kind = (value as { kind?: unknown }).kind;\n return kind === \"page\" || kind === \"layout\" || kind === \"api\" || kind === \"redirect\";\n}\n\nexport function createProgrammaticRouteModuleId(\n filePath: string,\n kind: \"page\" | \"layout\" | \"api\",\n routePath: string,\n): string {\n return `${filePath}?farm-route=${kind}:${encodeURIComponent(normalizeRoutePath(routePath))}`;\n}\n\nexport function parseProgrammaticRouteModuleId(moduleId: string): {\n filePath: string;\n kind: \"page\" | \"layout\" | \"api\";\n routePath: string;\n} | null {\n const queryIndex = moduleId.indexOf(\"?\");\n if (queryIndex === -1) {\n return null;\n }\n\n const filePath = moduleId.slice(0, queryIndex);\n const params = new URLSearchParams(moduleId.slice(queryIndex + 1));\n const value = params.get(\"farm-route\");\n if (!value) {\n return null;\n }\n\n const separator = value.indexOf(\":\");\n if (separator === -1) {\n return null;\n }\n\n const kind = value.slice(0, separator);\n if (kind !== \"page\" && kind !== \"layout\" && kind !== \"api\") {\n return null;\n }\n\n return {\n filePath,\n kind,\n routePath: normalizeRoutePath(value.slice(separator + 1)),\n };\n}\n\nexport function parseProgrammaticRoutePath(\n routePath: string,\n type: ParsedRoute[\"type\"] = \"page\",\n): ParsedRoute {\n const fileName = type === \"layout\" ? \"layout.tsx\" : \"page.tsx\";\n const normalized = normalizeRoutePath(routePath);\n const filePath =\n normalized === \"/\" ? fileName : `${normalized.slice(1).replace(/\\/+$/, \"\")}/${fileName}`;\n\n return {\n filePath,\n type,\n segments: normalized === \"/\" ? [] : normalized.slice(1).split(\"/\").map(parseRouteSegment),\n };\n}\n\nexport function createRouteModuleFromProgrammaticPage(route: ProgrammaticPageRoute): RouteModule {\n const mod: RouteModule = {\n default: createProgrammaticPageComponent(route),\n ...normalizeFarmRouteRuntimeConfig(route, `Route \"${route.path}\"`),\n };\n\n if (route.params || route.search || route.guard || route.data) {\n (mod as any).__farmRouteSchemas = {\n params: route.params,\n search: getProgrammaticRouteSearchSchema(route.search),\n };\n (mod as any).__farmRouteSearch = getProgrammaticRouteSearchClientOptions(route.search);\n (mod as any).__farmRouteGuard = route.guard;\n (mod as any).__farmRouteData = route.data;\n (mod as any).__farmRouteParsesProps = true;\n (mod as any).__farmResolveRouteProps = (props: PageProps) =>\n resolveProgrammaticRouteProps(route, props);\n (mod as any).__farmResolveRouteCanonicalPath = (\n rawSearch: ProgrammaticRouteSearchFallback,\n path: string,\n ) => resolveProgrammaticRouteSearch(route.search, rawSearch, path, route.path).canonicalPath;\n }\n\n if (route.pending || route.error || route.notFound) {\n (mod as any).__farmRouteComponents = {\n pending: route.pending,\n error: route.error,\n notFound: route.notFound,\n };\n }\n\n if (route.render === \"static\" || route.staticPaths) {\n mod.ssg = true;\n mod.dynamic = \"force-static\";\n } else if (route.render === \"dynamic\") {\n mod.ssg = false;\n mod.dynamic = \"force-dynamic\";\n }\n\n if (typeof route.revalidate !== \"undefined\") {\n mod.revalidate = route.revalidate;\n }\n\n if (route.ppr) {\n mod.ppr = true;\n }\n\n if (route.metadata) {\n mod.metadata = route.metadata;\n }\n\n if (route.generateMetadata) {\n mod.generateMetadata = route.generateMetadata;\n }\n\n if (route.staticPaths) {\n mod.getStaticPaths = async () => normalizeStaticPaths(route.path, await route.staticPaths!());\n }\n\n return mod;\n}\n\nexport function createLayoutModuleFromProgrammaticLayout(route: ProgrammaticLayoutRoute) {\n return {\n default: route.component,\n ...normalizeFarmRouteRuntimeConfig(route, `Layout \"${route.path}\"`),\n metadata: route.metadata,\n generateMetadata: route.generateMetadata,\n };\n}\n\nexport function scanProgrammaticPagePaths(source: string): string[] {\n const paths = new Set<string>();\n const callRe = /\\b(?:page|createRoute)\\s*\\(\\s*([\"'`])([^\"'`]+)\\1/g;\n\n for (const match of source.matchAll(callRe)) {\n if (match[2]) {\n paths.add(normalizeRoutePath(match[2]));\n }\n }\n\n return Array.from(paths);\n}\n\nfunction createProgrammaticPageComponent(route: ProgrammaticPageRoute): ComponentType<PageProps> {\n if (\n !route.params &&\n !route.search &&\n !route.guard &&\n !route.data &&\n !route.pending &&\n !route.error &&\n !route.notFound\n ) {\n return route.component as ComponentType<PageProps>;\n }\n\n const Component = route.component;\n\n if (route.pending) {\n const PendingComponent = route.pending;\n const routePropsResources = new WeakMap<object, ProgrammaticRoutePropsResource>();\n const FarmProgrammaticPageContent = function FarmProgrammaticPageContent(props: PageProps) {\n try {\n const resolvedProps = readProgrammaticRouteProps(route, props, routePropsResources);\n return createElement(Component, stripProgrammaticRoutePropsMarker(resolvedProps));\n } catch (error) {\n if (isPromiseLike(error) || isProgrammaticRedirectSignal(error)) {\n throw error;\n }\n\n if (isProgrammaticNotFoundSignal(error) && route.notFound) {\n return createElement(route.notFound, createProgrammaticRouteErrorProps(error, props));\n }\n\n if (route.error) {\n return createElement(route.error, createProgrammaticRouteErrorProps(error, props));\n }\n\n throw error;\n }\n };\n const PageContent = FarmProgrammaticPageContent as unknown as ComponentType<PageProps>;\n const FarmProgrammaticPage = function FarmProgrammaticPage(props: PageProps) {\n return createElement(\n Suspense,\n {\n fallback: createElement(PendingComponent, createProgrammaticRoutePendingProps(props)),\n },\n createElement(PageContent, props),\n );\n };\n\n return FarmProgrammaticPage as unknown as ComponentType<PageProps>;\n }\n\n const FarmProgrammaticPageContent = async function FarmProgrammaticPageContent(props: PageProps) {\n try {\n const resolvedProps = isProgrammaticRoutePropsResolved(props)\n ? props\n : await resolveProgrammaticRouteProps(route, props);\n\n return createElement(Component, stripProgrammaticRoutePropsMarker(resolvedProps));\n } catch (error) {\n if (isProgrammaticRedirectSignal(error)) {\n throw error;\n }\n\n if (isProgrammaticNotFoundSignal(error) && route.notFound) {\n return createElement(route.notFound, createProgrammaticRouteErrorProps(error, props));\n }\n\n if (route.error) {\n return createElement(route.error, createProgrammaticRouteErrorProps(error, props));\n }\n\n throw error;\n }\n };\n\n return FarmProgrammaticPageContent as unknown as ComponentType<PageProps>;\n}\n\ntype ProgrammaticRoutePropsResource =\n | { status: \"pending\"; promise: Promise<Record<string, any>> }\n | { status: \"resolved\"; value: Record<string, any> }\n | { status: \"rejected\"; error: unknown };\n\nfunction readProgrammaticRouteProps(\n route: ProgrammaticPageRoute,\n props: PageProps,\n resources: WeakMap<object, ProgrammaticRoutePropsResource>,\n): Record<string, any> {\n if (isProgrammaticRoutePropsResolved(props)) {\n return props;\n }\n\n let resource = resources.get(props as object);\n if (!resource) {\n const deferredRouteProps = (props as any).__farmRoutePropsPromise;\n const promise = Promise.resolve<Record<string, any>>(\n isPromiseLike(deferredRouteProps)\n ? (deferredRouteProps as PromiseLike<Record<string, any>>)\n : resolveProgrammaticRouteProps(route, props),\n );\n resource = { status: \"pending\", promise };\n resources.set(props as object, resource);\n promise.then(\n (value) => resources.set(props as object, { status: \"resolved\", value }),\n (error) => resources.set(props as object, { status: \"rejected\", error }),\n );\n }\n\n if (resource.status === \"pending\") throw resource.promise;\n if (resource.status === \"rejected\") throw resource.error;\n return resource.value;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as PromiseLike<unknown>).then === \"function\",\n );\n}\n\nfunction createProgrammaticRoutePendingProps(\n props: PageProps,\n): ProgrammaticRoutePendingComponentProps {\n return {\n params: props.params,\n searchParams: props.searchParams,\n path: props.path,\n };\n}\n\nfunction createProgrammaticRouteErrorProps(\n error: unknown,\n props: PageProps,\n): ProgrammaticRouteErrorComponentProps {\n return {\n error,\n params: props.params,\n searchParams: props.searchParams,\n path: props.path,\n };\n}\n\nfunction isProgrammaticRedirectSignal(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const digest = (error as { digest?: unknown }).digest;\n return typeof digest === \"string\" && digest.startsWith(\"FARM_REDIRECT;\");\n}\n\nfunction isProgrammaticNotFoundSignal(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const digest = (error as { digest?: unknown }).digest;\n return digest === \"FARM_NOT_FOUND\";\n}\n\nasync function resolveProgrammaticRouteProps(\n route: ProgrammaticPageRoute,\n props: PageProps,\n): Promise<Record<string, any> & { __farmRoutePropsResolved: true }> {\n const rawSearch = await props.searchParams;\n const params = parseProgrammaticSchema(route.params, props.params, \"params\", route.path);\n const { search, canonicalPath } = resolveProgrammaticRouteSearch(\n route.search,\n rawSearch,\n props.path,\n route.path,\n );\n const routeContextValue = getFarmRouteContext(props);\n const pluginContext = props.context;\n const baseProps = {\n ...props,\n params,\n search,\n searchParams: Promise.resolve(search),\n };\n const routeContextProps = {\n ...baseProps,\n context: routeContextValue,\n pluginContext,\n };\n\n if (route.guard) {\n await route.guard(routeContextProps as any);\n }\n\n if (!route.data) {\n return markProgrammaticRoutePropsResolved(addCanonicalPath(baseProps, canonicalPath));\n }\n\n const before = route.data.before ? await route.data.before(routeContextProps as any) : undefined;\n const dataContext = {\n ...(routeContextProps as any),\n before,\n };\n const data = await resolveProgrammaticRouteData(route, route.data, dataContext);\n\n if (route.data.after) {\n await route.data.after({\n ...(routeContextProps as any),\n before,\n data,\n });\n }\n\n return markProgrammaticRoutePropsResolved({\n ...baseProps,\n data,\n ...(canonicalPath ? { __farmCanonicalPath: canonicalPath } : {}),\n });\n}\n\nasync function resolveProgrammaticRouteData(\n route: ProgrammaticPageRoute,\n dataHooks: ProgrammaticRouteDataHooks<any, any, any, any>,\n context: ProgrammaticRouteDataCacheContext<any, any, any>,\n): Promise<unknown> {\n if (!dataHooks?.key) {\n return dataHooks.main(context);\n }\n\n const routeDataKey = await dataHooks.key(context);\n if (routeDataKey == null) {\n return dataHooks.main(context);\n }\n\n const cacheKey = createFarmCacheKey([\"route-data\", routeDataKey]);\n const cacheOptions: FarmCacheOptions = {\n tags: [\n createRouteDataCacheTag(routeDataKey),\n ...(await resolveProgrammaticRouteDataKeys(dataHooks.tags, context)),\n ],\n paths: [\n ...(typeof context.path === \"string\" ? [context.path] : []),\n ...(await resolveProgrammaticRouteDataKeys(dataHooks.paths, context)),\n ],\n revalidate: normalizeProgrammaticRouteStaleTime(dataHooks.staleTime),\n };\n\n return getFarmDataCache().getOrSet(cacheKey, () => dataHooks.main(context), cacheOptions);\n}\n\nasync function resolveProgrammaticRouteDataKeys(\n input: ProgrammaticRouteDataCacheKeys<any, any, any> | undefined,\n context: ProgrammaticRouteDataCacheContext<any, any, any>,\n): Promise<readonly string[]> {\n if (!input) return [];\n const value = typeof input === \"function\" ? await input(context) : input;\n return value.filter((item) => typeof item === \"string\" && item.trim().length > 0);\n}\n\nfunction normalizeProgrammaticRouteStaleTime(\n staleTime: ProgrammaticRouteDataStaleTime | undefined,\n): number | false | undefined {\n if (staleTime === undefined) return undefined;\n if (staleTime === false) return false;\n\n if (typeof staleTime === \"number\") {\n if (!Number.isFinite(staleTime) || staleTime <= 0) return undefined;\n return Math.max(1, Math.ceil(staleTime / 1000));\n }\n\n const match = staleTime.match(/^(\\d+(?:\\.\\d+)?)(ms|s|m|h)$/);\n if (!match) return undefined;\n\n const value = Number(match[1]);\n if (!Number.isFinite(value) || value <= 0) return undefined;\n\n const unit = match[2];\n const milliseconds =\n unit === \"ms\"\n ? value\n : unit === \"s\"\n ? value * 1000\n : unit === \"m\"\n ? value * 60000\n : value * 3600000;\n\n return Math.max(1, Math.ceil(milliseconds / 1000));\n}\n\nfunction isProgrammaticRoutePropsResolved(value: unknown): boolean {\n return !!value && typeof value === \"object\" && (value as any).__farmRoutePropsResolved === true;\n}\n\nfunction markProgrammaticRoutePropsResolved<T extends Record<string, any>>(\n props: T,\n): T & { __farmRoutePropsResolved: true } {\n return {\n ...props,\n __farmRoutePropsResolved: true,\n };\n}\n\nfunction addCanonicalPath<T extends Record<string, any>>(\n props: T,\n canonicalPath: string | undefined,\n): T {\n return canonicalPath ? ({ ...props, __farmCanonicalPath: canonicalPath } as T) : props;\n}\n\nfunction stripProgrammaticRoutePropsMarker<TProps>(props: TProps): TProps {\n if (!isProgrammaticRoutePropsResolved(props)) {\n return props;\n }\n\n const {\n __farmRoutePropsResolved,\n __farmCanonicalPath,\n __farmRoutePropsPromise,\n ...componentProps\n } = props as any;\n return componentProps;\n}\n\nfunction parseProgrammaticSchema<TFallback>(\n schema: ProgrammaticRouteSchema<any> | undefined,\n value: TFallback,\n label: string,\n routePath: string,\n): unknown {\n if (!schema) {\n return value;\n }\n\n try {\n return schema.parse(value);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid ${label} for route \"${routePath}\": ${message}`);\n }\n}\n\nfunction normalizeProgrammaticRoute(\n route: ProgrammaticRouteDefinition,\n): ProgrammaticRouteDefinition {\n if (route.kind === \"redirect\") {\n return {\n ...route,\n source: normalizeRoutePath(route.source),\n };\n }\n\n if (route.kind === \"api\") {\n return {\n ...route,\n ...normalizeFarmRouteRuntimeConfig(route, `API route \"${route.path}\"`),\n path: normalizeRoutePath(route.path),\n methods: normalizeApiMethods(route.methods),\n };\n }\n\n return {\n ...route,\n ...normalizeFarmRouteRuntimeConfig(\n route,\n `${route.kind === \"layout\" ? \"Layout\" : \"Route\"} \"${route.path}\"`,\n ),\n path: normalizeRoutePath(route.path),\n };\n}\n\nfunction normalizeRoutePath(routePath: string): string {\n const withSlash = routePath.startsWith(\"/\") ? routePath : `/${routePath}`;\n const withoutTrailing = withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n return withoutTrailing || \"/\";\n}\n\nfunction parseRouteSegment(segment: string): ParsedRoute[\"segments\"][number] {\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n let name = segment.slice(1, -1);\n let isOptional = false;\n let isCatchAll = false;\n\n if (name.startsWith(\"[\") && name.endsWith(\"]\")) {\n isOptional = true;\n name = name.slice(1, -1);\n }\n\n if (name.startsWith(\"...\")) {\n isCatchAll = true;\n name = name.slice(3);\n }\n\n return {\n segment: name,\n isDynamic: true,\n isOptional,\n isCatchAll,\n };\n }\n\n return {\n segment,\n isDynamic: false,\n isOptional: false,\n isCatchAll: false,\n };\n}\n\nfunction normalizeApiMethods(\n methods: Record<string, any>,\n): Partial<Record<ProgrammaticRouteMethod, any>> {\n const normalized: Partial<Record<ProgrammaticRouteMethod, any>> = {};\n\n for (const [method, handler] of Object.entries(methods)) {\n const normalizedMethod = method.toUpperCase() as ProgrammaticRouteMethod;\n if (handler && isProgrammaticRouteMethod(normalizedMethod)) {\n normalized[normalizedMethod] = handler;\n }\n }\n\n return normalized;\n}\n\nfunction isProgrammaticRouteMethod(method: string): method is ProgrammaticRouteMethod {\n return (\n method === \"GET\" ||\n method === \"HEAD\" ||\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"DELETE\" ||\n method === \"PATCH\" ||\n method === \"OPTIONS\"\n );\n}\n\nfunction normalizeStaticPaths(\n routePath: string,\n paths: readonly ProgrammaticStaticPath[],\n): Record<string, string>[] {\n const dynamicSegments = parseProgrammaticRoutePath(routePath).segments.filter(\n (segment) => segment.isDynamic,\n );\n\n return paths.map((entry) => {\n if (typeof entry === \"string\" || Array.isArray(entry)) {\n if (dynamicSegments.length !== 1) {\n throw new Error(\n `staticPaths for \"${routePath}\" must return objects when the route has ${dynamicSegments.length} dynamic params.`,\n );\n }\n\n const value = Array.isArray(entry) ? entry.join(\"/\") : entry;\n return { [dynamicSegments[0].segment]: String(value) };\n }\n\n return Object.fromEntries(\n Object.entries(entry).map(([key, value]) => [\n key,\n Array.isArray(value) ? value.map(String).join(\"/\") : String(value),\n ]),\n );\n });\n}\n","export type FarmEventLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface FarmEventBase {\n type: string;\n timestamp: number;\n level: FarmEventLevel;\n requestId?: string;\n route?: string;\n pathname?: string;\n}\n\nexport type FarmServerEvent =\n | (FarmEventBase & {\n type: \"server.start\";\n mode: \"dev\" | \"preview\" | \"production\";\n port?: number;\n })\n | (FarmEventBase & { type: \"server.ready\"; url?: string })\n | (FarmEventBase & { type: \"server.shutdown\"; reason?: string });\n\nexport type FarmRouteEvent =\n | (FarmEventBase & { type: \"route.discovered\"; route: string; filePath: string })\n | (FarmEventBase & {\n type: \"route.matched\";\n pathname: string;\n route: string;\n params?: Record<string, string>;\n })\n | (FarmEventBase & { type: \"route.notFound\"; pathname: string })\n | (FarmEventBase & { type: \"route.redirect\"; from: string; to: string; status?: number })\n | (FarmEventBase & { type: \"route.rewrite\"; from: string; to: string });\n\nexport type FarmRenderEvent =\n | (FarmEventBase & { type: \"render.start\"; route: string; pathname?: string })\n | (FarmEventBase & {\n type: \"render.complete\";\n route: string;\n durationMs: number;\n status?: number;\n })\n | (FarmEventBase & { type: \"render.error\"; route?: string; error: unknown })\n | (FarmEventBase & { type: \"render.stream.start\"; route: string })\n | (FarmEventBase & { type: \"render.stream.shellReady\"; route: string; durationMs: number })\n | (FarmEventBase & { type: \"render.stream.complete\"; route: string; durationMs: number });\n\nexport type FarmCacheEvent =\n | (FarmEventBase & {\n type: \"cache.hit\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n stale?: boolean;\n })\n | (FarmEventBase & { type: \"cache.miss\"; key: string; route?: string; reason?: string })\n | (FarmEventBase & {\n type: \"cache.set\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n })\n | (FarmEventBase & { type: \"cache.dedupe\"; key: string })\n | (FarmEventBase & { type: \"cache.bypass\"; key?: string; route?: string; reason: string })\n | (FarmEventBase & {\n type: \"cache.stale\";\n key: string;\n route?: string;\n tags?: readonly string[];\n revalidate?: number | false;\n })\n | (FarmEventBase & { type: \"cache.revalidatePath\"; path: string; count: number })\n | (FarmEventBase & {\n type: \"cache.revalidateTag\";\n tag: string;\n profile?: unknown;\n count: number;\n })\n | (FarmEventBase & { type: \"cache.updateTag\"; tag: string; count: number })\n | (FarmEventBase & {\n type: \"cache.invalidated\";\n key?: string;\n route?: string;\n tag?: string;\n reason?: string;\n count?: number;\n })\n | (FarmEventBase & { type: \"cache.delete\"; key: string; deleted: boolean })\n | (FarmEventBase & { type: \"cache.clear\"; count: number })\n | (FarmEventBase & {\n type: \"cache.error\";\n key?: string;\n operation: \"get\" | \"set\" | \"delete\" | \"revalidate\";\n error: unknown;\n });\n\nexport type FarmPPREvent =\n | (FarmEventBase & { type: \"ppr.shell.hit\"; route: string; key: string })\n | (FarmEventBase & { type: \"ppr.shell.miss\"; route: string; key: string })\n | (FarmEventBase & {\n type: \"ppr.shell.cached\";\n route: string;\n key: string;\n revalidate?: number;\n })\n | (FarmEventBase & { type: \"ppr.shell.bypass\"; route: string; reason: string })\n | (FarmEventBase & {\n type: \"ppr.shell.invalidated\";\n route: string;\n reason?: string;\n count?: number;\n })\n | (FarmEventBase & { type: \"ppr.suspense.holeDetected\"; route: string })\n | (FarmEventBase & { type: \"ppr.refresh.start\"; route: string })\n | (FarmEventBase & { type: \"ppr.refresh.complete\"; route: string; durationMs: number })\n | (FarmEventBase & { type: \"ppr.refresh.error\"; route: string; error: unknown });\n\nexport type FarmAPIEvent =\n | (FarmEventBase & { type: \"api.request.start\"; route: string; method: string })\n | (FarmEventBase & {\n type: \"api.request.complete\";\n route: string;\n method: string;\n status: number;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"api.validation.failed\";\n route: string;\n method: string;\n issues?: unknown;\n })\n | (FarmEventBase & { type: \"api.error\"; route: string; method: string; error: unknown });\n\nexport type FarmIntegrationEvent =\n | (FarmEventBase & { type: \"integration.registered\"; name: string })\n | (FarmEventBase & { type: \"integration.config.validated\"; name: string })\n | (FarmEventBase & { type: \"integration.ready\"; name: string })\n | (FarmEventBase & { type: \"integration.disposed\"; name: string })\n | (FarmEventBase & {\n type: \"integration.api.call.start\";\n integration: string;\n operation: string;\n })\n | (FarmEventBase & {\n type: \"integration.api.call.complete\";\n integration: string;\n operation: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"integration.api.call.error\";\n integration: string;\n operation: string;\n error: unknown;\n })\n | (FarmEventBase & { type: \"integration.webhook.received\"; integration: string; event?: string })\n | (FarmEventBase & { type: \"integration.webhook.verified\"; integration: string; event?: string })\n | (FarmEventBase & { type: \"integration.webhook.failed\"; integration: string; reason: string });\n\nexport type FarmMiddlewareEvent =\n | (FarmEventBase & { type: \"middleware.start\"; route?: string; name?: string })\n | (FarmEventBase & {\n type: \"middleware.complete\";\n route?: string;\n name?: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"middleware.shortCircuit\";\n route?: string;\n name?: string;\n status?: number;\n })\n | (FarmEventBase & { type: \"middleware.error\"; route?: string; name?: string; error: unknown });\n\nexport type FarmStorageEvent =\n | (FarmEventBase & { type: \"storage.query.start\"; integration?: string; operation: string })\n | (FarmEventBase & {\n type: \"storage.query.complete\";\n integration?: string;\n operation: string;\n durationMs: number;\n })\n | (FarmEventBase & {\n type: \"storage.query.error\";\n integration?: string;\n operation: string;\n error: unknown;\n })\n | (FarmEventBase & { type: \"storage.schema.ready\"; integration?: string })\n | (FarmEventBase & { type: \"storage.schema.error\"; integration?: string; error: unknown });\n\nexport type FarmBuildEvent =\n | (FarmEventBase & { type: \"build.start\"; target?: string })\n | (FarmEventBase & { type: \"build.complete\"; target?: string; durationMs: number })\n | (FarmEventBase & { type: \"build.error\"; target?: string; error: unknown })\n | (FarmEventBase & { type: \"routes.generated\"; pageCount: number; apiCount?: number })\n | (FarmEventBase & { type: \"types.generated\"; filePath: string })\n | (FarmEventBase & { type: \"manifest.generated\"; routeCount: number });\n\nexport type FarmPluginEvent =\n | (FarmEventBase & { type: \"plugin.hook.start\"; plugin: string; hook: string })\n | (FarmEventBase & {\n type: \"plugin.hook.complete\";\n plugin: string;\n hook: string;\n durationMs: number;\n })\n | (FarmEventBase & { type: \"plugin.hook.error\"; plugin: string; hook: string; error: unknown });\n\nexport type FarmErrorEvent = FarmEventBase & {\n type: \"error\";\n source: string;\n error: unknown;\n route?: string;\n};\n\nexport type FarmEvent =\n | FarmServerEvent\n | FarmRouteEvent\n | FarmRenderEvent\n | FarmCacheEvent\n | FarmPPREvent\n | FarmAPIEvent\n | FarmIntegrationEvent\n | FarmMiddlewareEvent\n | FarmStorageEvent\n | FarmBuildEvent\n | FarmPluginEvent\n | FarmErrorEvent;\n\nexport type FarmEventType = FarmEvent[\"type\"];\nexport type FarmEventHandler = (event: FarmEvent) => void | Promise<void>;\n\nexport type FarmEventInput = FarmEvent extends infer T\n ? T extends FarmEvent\n ? Omit<T, \"timestamp\" | \"level\"> & Partial<Pick<T, \"timestamp\" | \"level\">>\n : never\n : never;\n\nexport type FarmObservabilityUserConfig =\n | boolean\n | {\n logs?: boolean;\n onEvent?: FarmEventHandler | readonly FarmEventHandler[];\n events?: readonly FarmEventType[];\n };\n\nexport interface FarmResolvedObservabilityConfig {\n logs: boolean;\n handlers: FarmEventHandler[];\n events?: Set<FarmEventType>;\n}\n\nconst runtimeHandlers = new Set<FarmEventHandler>();\nlet observabilityState: FarmResolvedObservabilityConfig = {\n logs: false,\n handlers: [],\n};\n\nexport function configureFarmObservability(config: FarmObservabilityUserConfig | undefined): void {\n observabilityState = normalizeFarmObservabilityConfig(config);\n}\n\nexport function normalizeFarmObservabilityConfig(\n config: FarmObservabilityUserConfig | undefined,\n): FarmResolvedObservabilityConfig {\n if (config === undefined || config === false) {\n return { logs: false, handlers: [] };\n }\n\n if (config === true) {\n return { logs: true, handlers: [] };\n }\n\n const handlers = config.onEvent\n ? Array.isArray(config.onEvent)\n ? [...config.onEvent]\n : [config.onEvent]\n : [];\n\n return {\n logs: config.logs ?? false,\n handlers,\n events: config.events ? new Set(config.events) : undefined,\n };\n}\n\nexport function onFarmEvent(handler: FarmEventHandler): () => void {\n runtimeHandlers.add(handler);\n return () => {\n runtimeHandlers.delete(handler);\n };\n}\n\nexport function resetFarmObservability(): void {\n runtimeHandlers.clear();\n observabilityState = {\n logs: false,\n handlers: [],\n };\n}\n\nexport function emitFarmEvent(input: FarmEventInput): FarmEvent {\n const event = {\n timestamp: Date.now(),\n level: inferFarmEventLevel(input.type),\n ...input,\n } as FarmEvent;\n\n if (!shouldEmitFarmEvent(event)) {\n return event;\n }\n\n if (observabilityState.logs) {\n logFarmEvent(event);\n }\n\n for (const handler of [...observabilityState.handlers, ...runtimeHandlers]) {\n try {\n Promise.resolve(handler(event)).catch((error) => {\n console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);\n });\n } catch (error) {\n console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);\n }\n }\n\n return event;\n}\n\nfunction shouldEmitFarmEvent(event: FarmEvent): boolean {\n if (\n !observabilityState.logs &&\n observabilityState.handlers.length === 0 &&\n runtimeHandlers.size === 0\n ) {\n return false;\n }\n\n if (observabilityState.events && !observabilityState.events.has(event.type)) {\n return false;\n }\n\n return true;\n}\n\nfunction inferFarmEventLevel(type: FarmEventType): FarmEventLevel {\n if (type === \"error\" || type.endsWith(\".error\") || type.endsWith(\".failed\")) {\n return \"error\";\n }\n if (\n type.endsWith(\".bypass\") ||\n type.endsWith(\".invalidated\") ||\n type.endsWith(\".stale\") ||\n type.endsWith(\".notFound\")\n ) {\n return \"warn\";\n }\n if (\n type.endsWith(\".hit\") ||\n type.endsWith(\".miss\") ||\n type.endsWith(\".start\") ||\n type.endsWith(\".shellReady\")\n ) {\n return \"debug\";\n }\n return \"info\";\n}\n\nfunction logFarmEvent(event: FarmEvent): void {\n const message = `[farm:${event.level}] ${event.type}${formatFarmEventDetails(event)}`;\n switch (event.level) {\n case \"error\":\n console.error(message);\n break;\n case \"warn\":\n console.warn(message);\n break;\n default:\n console.log(message);\n break;\n }\n}\n\nfunction formatFarmEventDetails(event: FarmEvent): string {\n const details: string[] = [];\n const record = event as unknown as Record<string, unknown>;\n\n for (const key of [\n \"route\",\n \"pathname\",\n \"method\",\n \"status\",\n \"key\",\n \"tag\",\n \"path\",\n \"reason\",\n \"durationMs\",\n \"integration\",\n \"operation\",\n \"plugin\",\n \"hook\",\n \"target\",\n \"count\",\n ]) {\n const value = record[key];\n if (value !== undefined) {\n details.push(`${key}=${formatDetailValue(value)}`);\n }\n }\n\n return details.length > 0 ? ` ${details.join(\" \")}` : \"\";\n}\n\nfunction formatDetailValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","export type FarmCacheInvalidationListener = (key: string) => void;\nexport type FarmCacheTaskListener = (task: Promise<void>) => void;\n\nexport const FARM_CACHE_INVALIDATION_HEADER = \"x-farm-cache-invalidations\";\n\ntype FarmCacheInvalidationState = {\n listeners: Set<FarmCacheInvalidationListener>;\n taskListeners: Set<FarmCacheTaskListener>;\n};\n\nconst FARM_CACHE_INVALIDATION_STATE = Symbol.for(\"farm.cacheInvalidationState\");\nconst globalState = globalThis as typeof globalThis & {\n [FARM_CACHE_INVALIDATION_STATE]?: FarmCacheInvalidationState;\n};\n\nfunction getFarmCacheInvalidationState(): FarmCacheInvalidationState {\n return (globalState[FARM_CACHE_INVALIDATION_STATE] ??= {\n listeners: new Set(),\n taskListeners: new Set(),\n });\n}\n\nexport function notifyFarmCacheInvalidation(key: string): void {\n if (typeof key !== \"string\" || key.length === 0) return;\n\n for (const listener of getFarmCacheInvalidationState().listeners) {\n listener(key);\n }\n}\n\nexport function notifyFarmCacheTask(task: Promise<void>): void {\n for (const listener of getFarmCacheInvalidationState().taskListeners) {\n listener(task);\n }\n}\n\nexport function applyFarmCacheInvalidations(keys: unknown): void {\n if (!Array.isArray(keys)) return;\n\n for (const key of keys) {\n if (typeof key === \"string\") {\n notifyFarmCacheInvalidation(key);\n }\n }\n}\n\nexport function encodeFarmCacheInvalidations(keys: readonly string[]): string | null {\n const normalized = Array.from(\n new Set(keys.filter((key) => typeof key === \"string\" && key.length > 0)),\n );\n if (normalized.length === 0) return null;\n return encodeURIComponent(JSON.stringify(normalized));\n}\n\nexport function decodeFarmCacheInvalidations(value: string | null | undefined): readonly string[] {\n if (!value) return [];\n\n try {\n const parsed = JSON.parse(decodeURIComponent(value));\n return Array.isArray(parsed)\n ? Array.from(\n new Set(parsed.filter((key): key is string => typeof key === \"string\" && key.length > 0)),\n )\n : [];\n } catch {\n return [];\n }\n}\n\nexport function subscribeFarmCacheInvalidation(\n listener: FarmCacheInvalidationListener,\n): () => void {\n const state = getFarmCacheInvalidationState();\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n}\n\nexport function subscribeFarmCacheTask(listener: FarmCacheTaskListener): () => void {\n const state = getFarmCacheInvalidationState();\n state.taskListeners.add(listener);\n return () => state.taskListeners.delete(listener);\n}\n","import type { FarmI18nClientSnapshot } from \"./types\";\n\ntype SnapshotResolver = () => FarmI18nClientSnapshot | undefined;\n\nconst FARM_I18N_SNAPSHOT_RESOLVER = Symbol.for(\"farm.i18n.snapshotResolver\");\ntype GlobalWithI18nResolver = typeof globalThis & {\n [FARM_I18N_SNAPSHOT_RESOLVER]?: SnapshotResolver;\n};\n\nexport function _setFarmI18nSnapshotResolver(resolver: SnapshotResolver | undefined): void {\n (globalThis as GlobalWithI18nResolver)[FARM_I18N_SNAPSHOT_RESOLVER] = resolver;\n}\n\nexport function getActiveFarmI18nSnapshot(): FarmI18nClientSnapshot | undefined {\n if (typeof window !== \"undefined\" && window.__FARM_I18N__) {\n return window.__FARM_I18N__;\n }\n return (globalThis as GlobalWithI18nResolver)[FARM_I18N_SNAPSHOT_RESOLVER]?.();\n}\n","import { emitFarmEvent } from \"./observability\";\nimport { notifyFarmCacheInvalidation, notifyFarmCacheTask } from \"./cache-invalidation\";\nimport { getActiveFarmI18nSnapshot } from \"./i18n/bridge\";\n\nexport { applyFarmCacheInvalidations } from \"./cache-invalidation\";\n\nexport type RevalidateTagProfile =\n | \"max\"\n | \"default\"\n | \"seconds\"\n | \"minutes\"\n | \"hours\"\n | \"days\"\n | \"weeks\"\n | \"months\"\n | { expire?: number };\n\nexport interface FarmCacheOptions {\n /**\n * Tag cached data so it can be invalidated with revalidateTag/updateTag.\n */\n tags?: readonly string[];\n /**\n * Path tags let revalidatePath invalidate data tied to a route.\n */\n paths?: readonly string[];\n /**\n * Time in seconds before the entry becomes stale. False means no TTL.\n */\n revalidate?: number | false;\n}\n\nexport interface FarmCacheSetOptions extends FarmCacheOptions {\n createdAt?: number;\n}\n\nexport type RouteDataCacheKey = string | readonly unknown[];\n\nexport type FarmCacheInvalidationTarget =\n | { key: RouteDataCacheKey }\n | { path: string }\n | { tag: string };\n\ndeclare const FARM_DEFINED_CACHE_KEY_DATA: unique symbol;\n\n/**\n * A regular Farm cache key carrying the data shape stored under that key.\n *\n * The brand exists only in TypeScript. At runtime the value remains the\n * original string or structured array, so all existing cache APIs continue to\n * accept untyped keys.\n */\nexport type DefinedCacheKey<TData, TKey extends RouteDataCacheKey = RouteDataCacheKey> = TKey & {\n readonly [FARM_DEFINED_CACHE_KEY_DATA]: TData;\n};\n\nexport type CacheKeyFactory<\n TData,\n TArguments extends readonly unknown[],\n TKey extends RouteDataCacheKey = RouteDataCacheKey,\n> = (...args: TArguments) => DefinedCacheKey<TData, TKey>;\n\nexport type InferCacheKeyData<TKey> =\n TKey extends DefinedCacheKey<infer TData, RouteDataCacheKey> ? TData : unknown;\n\n/**\n * Optionally add a data type to an existing string/array cache-key factory.\n *\n * This helper does not introduce a new runtime key representation. Calling the\n * returned factory produces the exact key returned by `factory`.\n */\nexport function defineCacheKey<TData>() {\n return <const TArguments extends readonly unknown[], const TKey extends RouteDataCacheKey>(\n factory: (...args: TArguments) => TKey,\n ): CacheKeyFactory<TData, TArguments, TKey> => {\n if (typeof factory !== \"function\") {\n throw new TypeError(\"defineCacheKey expects a key factory function.\");\n }\n\n return ((...args: TArguments) => {\n const key = factory(...args);\n if (typeof key !== \"string\" && !Array.isArray(key)) {\n throw new TypeError(\n \"A defined cache key factory must return a string or structured array.\",\n );\n }\n return key as DefinedCacheKey<TData, TKey>;\n }) as CacheKeyFactory<TData, TArguments, TKey>;\n };\n}\n\nexport interface FarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: readonly string[];\n /**\n * Adapter tag versions captured before the cached value was produced.\n * A later version makes the entry stale across every server instance.\n */\n tagVersions?: Readonly<Record<string, number>>;\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\ninterface InternalFarmCacheEntry<T = unknown> {\n key: string;\n value: T;\n tags: Set<string>;\n tagVersions?: Readonly<Record<string, number>>;\n createdAt: number;\n createdVersion: number;\n revalidate?: number | false;\n}\n\n/**\n * Asynchronous persistence contract used by distributed Farm caches.\n *\n * Implementations are responsible for serializing cache entries and making\n * tag version updates atomic when the backing service supports it.\n */\nexport interface FarmCacheAdapter {\n readonly name?: string;\n get<T = unknown>(key: string): Promise<FarmCacheEntry<T> | null | undefined>;\n set<T = unknown>(key: string, entry: FarmCacheEntry<T>): Promise<void>;\n delete(key: string): Promise<void>;\n clear?(): Promise<void>;\n getTagVersions?(tags: readonly string[]): Promise<Readonly<Record<string, number>>>;\n invalidateTags?(tags: readonly string[]): Promise<void>;\n /** Atomically acquire a short-lived regeneration lease. */\n acquireLease?(key: string, ttlMs: number): Promise<string | null | undefined>;\n /** Release the lease only when the supplied ownership token still matches. */\n releaseLease?(key: string, token: string): Promise<void>;\n}\n\nexport interface FarmCacheUserConfig {\n /** Shared cache implementation, for example a Redis-backed adapter. */\n adapter?: FarmCacheAdapter;\n /** Prefix isolating applications and deployments sharing one adapter. */\n namespace?: string;\n /**\n * Coordinate cache fills across processes when the adapter implements\n * acquireLease/releaseLease. Set false to disable.\n */\n lease?:\n | false\n | {\n ttlMs?: number;\n waitTimeoutMs?: number;\n pollIntervalMs?: number;\n };\n}\n\nexport interface FarmCacheStorage {\n getItem<T = unknown>(key: string): Promise<T | null>;\n setItem<T = unknown>(key: string, value: T): Promise<unknown>;\n removeItem(key: string): Promise<unknown>;\n clear?(base?: string): Promise<unknown>;\n}\n\nexport interface StorageFarmCacheAdapterOptions {\n /** Prefix used inside the supplied storage client. */\n base?: string;\n}\n\n/**\n * Adapt a Farm/unstorage-compatible key-value client to the cache contract.\n *\n * This is a portable baseline adapter. Provider-specific adapters should use\n * their atomic increment/transaction primitives for tag invalidation.\n */\nexport function storageCacheAdapter(\n storage: FarmCacheStorage,\n options: StorageFarmCacheAdapterOptions = {},\n): FarmCacheAdapter {\n if (!storage || typeof storage.getItem !== \"function\" || typeof storage.setItem !== \"function\") {\n throw new TypeError(\"storageCacheAdapter expects a compatible storage client.\");\n }\n\n const base = normalizeCacheNamespace(options.base || \"farm-cache\");\n const entryKey = (key: string) => `${base}:entry:${key}`;\n const tagKey = (tag: string) => `${base}:tag:${tag}`;\n\n return {\n name: \"storage\",\n get: <T>(key: string) => storage.getItem<FarmCacheEntry<T>>(entryKey(key)),\n set: async <T>(key: string, entry: FarmCacheEntry<T>) => {\n await storage.setItem(entryKey(key), entry);\n },\n delete: async (key: string) => {\n await storage.removeItem(entryKey(key));\n },\n clear: storage.clear\n ? async () => {\n await storage.clear!(base);\n }\n : undefined,\n getTagVersions: async (tags) => {\n const versions = await Promise.all(\n tags.map(async (tag) => {\n const value = await storage.getItem<number>(tagKey(tag));\n return [tag, normalizeAdapterVersion(value)] as const;\n }),\n );\n return Object.fromEntries(versions);\n },\n invalidateTags: async (tags) => {\n await Promise.all(\n tags.map(async (tag) => {\n const key = tagKey(tag);\n const current = normalizeAdapterVersion(await storage.getItem<number>(key));\n await storage.setItem(key, Math.max(Date.now(), current + 1));\n }),\n );\n },\n };\n}\n\nexport interface GetFarmCacheEntryOptions {\n allowStale?: boolean;\n now?: number;\n}\n\ninterface FarmCacheStaleEntry {\n tags: Iterable<string>;\n createdAt: number;\n createdVersion?: number;\n revalidate?: number | false;\n}\n\nexport class FarmDataCache {\n private entries = new Map<string, InternalFarmCacheEntry>();\n private inflight = new Map<string, Promise<unknown>>();\n private invalidatedTagVersions = new Map<string, number>();\n private version = 0;\n private adapter?: FarmCacheAdapter;\n private namespace = \"farm\";\n private local = true;\n private lease = {\n enabled: true,\n ttlMs: 10_000,\n waitTimeoutMs: 10_000,\n pollIntervalMs: 25,\n };\n\n constructor(config: FarmCacheUserConfig = {}) {\n this.configure(config);\n }\n\n configure(config: FarmCacheUserConfig = {}): void {\n this.adapter = config.adapter;\n this.namespace = normalizeCacheNamespace(config.namespace || \"farm\");\n this.local = !config.adapter;\n this.lease =\n config.lease === false\n ? { ...this.lease, enabled: false }\n : {\n enabled: true,\n ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 10_000, \"cache.lease.ttlMs\"),\n waitTimeoutMs: normalizePositiveDuration(\n config.lease?.waitTimeoutMs,\n 10_000,\n \"cache.lease.waitTimeoutMs\",\n ),\n pollIntervalMs: normalizePositiveDuration(\n config.lease?.pollIntervalMs,\n 25,\n \"cache.lease.pollIntervalMs\",\n ),\n };\n if (!this.local) {\n this.entries.clear();\n this.inflight.clear();\n this.invalidatedTagVersions.clear();\n this.version = 0;\n }\n }\n\n get adapterName(): string {\n return this.adapter?.name || (this.adapter ? \"custom\" : \"memory\");\n }\n\n get hasAdapter(): boolean {\n return this.adapter !== undefined;\n }\n\n get size(): number {\n return this.entries.size;\n }\n\n get<T>(key: string, options: GetFarmCacheEntryOptions = {}): T | undefined {\n return this.getEntry<T>(key, options)?.value;\n }\n\n getEntry<T = unknown>(\n key: string,\n options: GetFarmCacheEntryOptions = {},\n ): FarmCacheEntry<T> | undefined {\n const entry = this.entries.get(key) as InternalFarmCacheEntry<T> | undefined;\n if (!entry) {\n emitFarmEvent({ type: \"cache.miss\", key });\n return undefined;\n }\n\n const stale = this.isStale(entry, options.now);\n if (stale) {\n emitFarmEvent({\n type: \"cache.stale\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n });\n }\n\n if (!options.allowStale && stale) {\n emitFarmEvent({ type: \"cache.miss\", key, reason: \"stale\" });\n return undefined;\n }\n\n emitFarmEvent({\n type: \"cache.hit\",\n key,\n tags: Array.from(entry.tags),\n revalidate: entry.revalidate,\n stale,\n });\n\n return this.toPublicEntry(entry);\n }\n\n async getEntryAsync<T = unknown>(\n key: string,\n options: GetFarmCacheEntryOptions = {},\n ): Promise<FarmCacheEntry<T> | undefined> {\n if (this.local) {\n const localEntry = this.getEntry<T>(key, options);\n if (localEntry) return localEntry;\n }\n\n if (!this.adapter) {\n return this.local ? undefined : this.getEntry<T>(key, options);\n }\n\n const entry = await this.adapter.get<T>(this.createAdapterKey(key));\n if (!entry) {\n emitFarmEvent({ type: \"cache.miss\", key });\n return undefined;\n }\n\n assertFarmCacheEntry(entry, key);\n const stale = await this.isAdapterEntryStale(entry, options.now);\n if (stale) {\n emitFarmEvent({\n type: \"cache.stale\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n });\n if (!options.allowStale) {\n emitFarmEvent({ type: \"cache.miss\", key, reason: \"stale\" });\n return undefined;\n }\n }\n\n emitFarmEvent({\n type: \"cache.hit\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n stale,\n });\n\n if (this.local && !stale) {\n this.hydrateLocalEntry(entry);\n }\n return { ...entry, key };\n }\n\n set<T>(key: string, value: T, options: FarmCacheSetOptions = {}): FarmCacheEntry<T> {\n const tags = new Set<string>();\n for (const tag of options.tags ?? []) {\n tags.add(normalizeCacheTag(tag));\n }\n for (const routePath of options.paths ?? []) {\n tags.add(createPathCacheTag(routePath));\n }\n\n const entry: InternalFarmCacheEntry<T> = {\n key,\n value,\n tags,\n tagVersions: undefined,\n createdAt: options.createdAt ?? Date.now(),\n createdVersion: ++this.version,\n revalidate: normalizeRevalidate(options.revalidate),\n };\n\n this.entries.set(key, entry);\n emitFarmEvent({\n type: \"cache.set\",\n key,\n tags: Array.from(tags),\n revalidate: entry.revalidate,\n });\n return this.toPublicEntry(entry);\n }\n\n async setAsync<T>(\n key: string,\n value: T,\n options: FarmCacheSetOptions = {},\n tagVersions?: Readonly<Record<string, number>>,\n ): Promise<FarmCacheEntry<T>> {\n const tags = normalizeCacheOptionsTags(options);\n const capturedVersions =\n tagVersions ?? (await this.getAdapterTagVersions(Array.from(tags.values())));\n const entry: FarmCacheEntry<T> = {\n key,\n value,\n tags: Array.from(tags),\n tagVersions: capturedVersions,\n createdAt: options.createdAt ?? Date.now(),\n createdVersion: ++this.version,\n revalidate: normalizeRevalidate(options.revalidate),\n };\n\n if (this.local) {\n this.hydrateLocalEntry(entry);\n }\n if (this.adapter) {\n await this.adapter.set(this.createAdapterKey(key), entry);\n }\n\n emitFarmEvent({\n type: \"cache.set\",\n key,\n tags: [...entry.tags],\n revalidate: entry.revalidate,\n });\n return entry;\n }\n\n delete(key: string): boolean {\n const deleted = this.entries.delete(key);\n emitFarmEvent({ type: \"cache.delete\", key, deleted });\n return deleted;\n }\n\n async deleteAsync(key: string): Promise<boolean> {\n const deleted = this.entries.delete(key);\n if (this.adapter) {\n await this.adapter.delete(this.createAdapterKey(key));\n }\n emitFarmEvent({ type: \"cache.delete\", key, deleted: this.adapter ? true : deleted });\n return this.adapter ? true : deleted;\n }\n\n clear(): void {\n const count = this.entries.size;\n this.entries.clear();\n this.inflight.clear();\n this.invalidatedTagVersions.clear();\n this.version = 0;\n emitFarmEvent({ type: \"cache.clear\", count });\n }\n\n async clearAsync(): Promise<void> {\n this.clear();\n await this.adapter?.clear?.();\n }\n\n isStale(entry: FarmCacheStaleEntry, now = Date.now()): boolean {\n if (\n typeof entry.revalidate === \"number\" &&\n entry.revalidate > 0 &&\n now - entry.createdAt >= entry.revalidate * 1000\n ) {\n return true;\n }\n\n for (const tag of entry.tags) {\n const invalidatedVersion = this.invalidatedTagVersions.get(normalizeCacheTag(tag));\n if (\n typeof invalidatedVersion === \"number\" &&\n typeof entry.createdVersion === \"number\" &&\n invalidatedVersion > entry.createdVersion\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n async isStaleAsync(entry: FarmCacheEntry, now = Date.now()): Promise<boolean> {\n if (this.adapter) {\n return this.isAdapterEntryStale(entry, now);\n }\n return this.isStale(entry, now);\n }\n\n revalidateTag(\n tag: string,\n options: { source?: \"revalidateTag\" | \"updateTag\"; profile?: RevalidateTagProfile } = {},\n ): number {\n const normalized = normalizeCacheTag(tag);\n const count = this.invalidateTag(normalized);\n emitFarmEvent(\n options.source === \"updateTag\"\n ? { type: \"cache.updateTag\", tag: normalized, count }\n : { type: \"cache.revalidateTag\", tag: normalized, profile: options.profile, count },\n );\n return count;\n }\n\n async revalidateTagAsync(\n tag: string,\n options: { source?: \"revalidateTag\" | \"updateTag\"; profile?: RevalidateTagProfile } = {},\n ): Promise<number> {\n const normalized = normalizeCacheTag(tag);\n const count = this.invalidateTag(normalized);\n await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);\n emitFarmEvent(\n options.source === \"updateTag\"\n ? { type: \"cache.updateTag\", tag: normalized, count }\n : { type: \"cache.revalidateTag\", tag: normalized, profile: options.profile, count },\n );\n return count;\n }\n\n revalidatePath(routePath: string): number {\n const normalizedPath = normalizeRevalidatePath(routePath);\n const pathTag = createPathCacheTag(normalizedPath);\n const pprCount = this.countEntriesForTags([pathTag, \"ppr\"]);\n const count = this.invalidateTag(pathTag);\n emitFarmEvent({ type: \"cache.revalidatePath\", path: normalizedPath, count });\n\n if (pprCount > 0) {\n emitFarmEvent({\n type: \"ppr.shell.invalidated\",\n route: normalizedPath,\n reason: \"revalidatePath\",\n count: pprCount,\n });\n }\n\n return count;\n }\n\n async revalidatePathAsync(routePath: string): Promise<number> {\n const normalizedPath = normalizeRevalidatePath(routePath);\n const pathTag = createPathCacheTag(normalizedPath);\n const pprCount = this.countEntriesForTags([pathTag, \"ppr\"]);\n const count = this.invalidateTag(pathTag);\n await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);\n emitFarmEvent({ type: \"cache.revalidatePath\", path: normalizedPath, count });\n\n if (pprCount > 0) {\n emitFarmEvent({\n type: \"ppr.shell.invalidated\",\n route: normalizedPath,\n reason: \"revalidatePath\",\n count: pprCount,\n });\n }\n\n return count;\n }\n\n async getOrSet<T>(\n key: string,\n producer: () => Promise<T> | T,\n options: FarmCacheOptions = {},\n ): Promise<T> {\n const cached = await this.getEntryAsync<T>(key);\n if (cached) {\n return cached.value;\n }\n\n const inflight = this.inflight.get(key) as Promise<T> | undefined;\n if (inflight) {\n emitFarmEvent({ type: \"cache.dedupe\", key });\n return inflight;\n }\n\n const tags = Array.from(normalizeCacheOptionsTags(options));\n const promise = this.fillCacheEntry(key, producer, options, tags)\n .catch((error) => {\n emitFarmEvent({ type: \"cache.error\", key, operation: \"set\", error });\n throw error;\n })\n .finally(() => {\n this.inflight.delete(key);\n });\n\n this.inflight.set(key, promise);\n return promise;\n }\n\n private async fillCacheEntry<T>(\n key: string,\n producer: () => Promise<T> | T,\n options: FarmCacheOptions,\n tags: readonly string[],\n ): Promise<T> {\n const leaseKey = `${this.namespace}:lease:${key}`;\n let leaseToken: string | null | undefined;\n\n if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {\n leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);\n if (!leaseToken) {\n const shared = await this.waitForAdapterEntry<T>(key);\n if (shared) {\n emitFarmEvent({ type: \"cache.dedupe\", key });\n return shared.value;\n }\n leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);\n }\n }\n\n try {\n const initialTagVersions = await this.getAdapterTagVersions(tags);\n const value = await producer();\n await this.setAsync(key, value, options, initialTagVersions);\n return value;\n } finally {\n if (leaseToken && this.adapter?.releaseLease) {\n await this.adapter.releaseLease(leaseKey, leaseToken);\n }\n }\n }\n\n private async waitForAdapterEntry<T>(key: string): Promise<FarmCacheEntry<T> | undefined> {\n const deadline = Date.now() + this.lease.waitTimeoutMs;\n while (Date.now() < deadline) {\n await delay(this.lease.pollIntervalMs);\n const entry = await this.getEntryAsync<T>(key);\n if (entry) return entry;\n }\n return undefined;\n }\n\n private countEntriesForTag(tag: string): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (entry.tags.has(tag)) {\n count++;\n }\n }\n return count;\n }\n\n private countEntriesForTags(tags: readonly string[]): number {\n let count = 0;\n for (const entry of this.entries.values()) {\n if (tags.every((tag) => entry.tags.has(tag))) {\n count++;\n }\n }\n return count;\n }\n\n private invalidateTag(normalizedTag: string): number {\n this.invalidatedTagVersions.set(normalizedTag, ++this.version);\n return this.countEntriesForTag(normalizedTag);\n }\n\n private toPublicEntry<T>(entry: InternalFarmCacheEntry<T>): FarmCacheEntry<T> {\n return {\n key: entry.key,\n value: entry.value,\n tags: Array.from(entry.tags),\n tagVersions: entry.tagVersions,\n createdAt: entry.createdAt,\n createdVersion: entry.createdVersion,\n revalidate: entry.revalidate,\n };\n }\n\n private hydrateLocalEntry<T>(entry: FarmCacheEntry<T>): void {\n this.entries.set(entry.key, {\n key: entry.key,\n value: entry.value,\n tags: new Set(entry.tags.map(normalizeCacheTag)),\n tagVersions: entry.tagVersions,\n createdAt: entry.createdAt,\n createdVersion: entry.createdVersion ?? ++this.version,\n revalidate: normalizeRevalidate(entry.revalidate),\n });\n }\n\n private createAdapterKey(key: string): string {\n return `${this.namespace}:entry:${key}`;\n }\n\n private createAdapterTag(tag: string): string {\n return `${this.namespace}:tag:${tag}`;\n }\n\n private async getAdapterTagVersions(\n tags: readonly string[],\n ): Promise<Readonly<Record<string, number>>> {\n if (!this.adapter?.getTagVersions || tags.length === 0) return {};\n\n const normalized = tags.map(normalizeCacheTag);\n const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));\n const versions = await this.adapter.getTagVersions(physicalTags);\n return Object.fromEntries(\n normalized.map((tag, index) => [\n tag,\n normalizeAdapterVersion(versions[physicalTags[index]!]),\n ]),\n );\n }\n\n private async isAdapterEntryStale(entry: FarmCacheEntry, now = Date.now()): Promise<boolean> {\n if (\n typeof entry.revalidate === \"number\" &&\n entry.revalidate > 0 &&\n now - entry.createdAt >= entry.revalidate * 1000\n ) {\n return true;\n }\n\n const currentVersions = await this.getAdapterTagVersions(entry.tags);\n for (const tag of entry.tags) {\n if (\n normalizeAdapterVersion(currentVersions[tag]) >\n normalizeAdapterVersion(entry.tagVersions?.[tag])\n ) {\n return true;\n }\n }\n return false;\n }\n}\n\nconst FARM_DATA_CACHE_SYMBOL = Symbol.for(\"farm.dataCache\");\nconst farmDataCacheGlobal = globalThis as typeof globalThis & {\n [FARM_DATA_CACHE_SYMBOL]?: FarmDataCache;\n};\nconst sharedFarmDataCache = (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ??= new FarmDataCache());\nconst functionIds = new WeakMap<Function, number>();\nlet nextFunctionId = 0;\n\nexport function getFarmDataCache(): FarmDataCache {\n return sharedFarmDataCache;\n}\n\nexport function configureFarmCache(config: FarmCacheUserConfig | undefined): void {\n sharedFarmDataCache.configure(config);\n}\n\nexport function unstable_cache<Args extends unknown[], Result>(\n fn: (...args: Args) => Result | Promise<Result>,\n keyParts: readonly unknown[] = [],\n options: FarmCacheOptions = {},\n): (...args: Args) => Promise<Result> {\n return async (...args: Args): Promise<Result> => {\n const locale = getActiveFarmI18nSnapshot()?.locale;\n const key = createFarmCacheKey([\n \"unstable_cache\",\n getFunctionCacheIdentity(fn),\n locale ? [\"locale\", locale] : null,\n keyParts,\n args,\n ]);\n return getFarmDataCache().getOrSet<Result>(key, () => fn(...args), options);\n };\n}\n\nexport function revalidateTag(_tag: string, _profile?: RevalidateTagProfile): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache\n .revalidateTagAsync(_tag, {\n source: \"revalidateTag\",\n profile: _profile,\n })\n .then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidateTag(_tag, {\n source: \"revalidateTag\",\n profile: _profile,\n });\n}\n\nexport function updateTag(tag: string): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache.revalidateTagAsync(tag, { source: \"updateTag\" }).then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidateTag(tag, { source: \"updateTag\" });\n}\n\nexport function revalidatePath(routePath: string): void | Promise<void> {\n const cache = getFarmDataCache();\n if (cache.hasAdapter) {\n const task = cache.revalidatePathAsync(routePath).then(() => undefined);\n notifyFarmCacheTask(task);\n return task;\n }\n cache.revalidatePath(routePath);\n}\n\nexport function invalidate(key: RouteDataCacheKey): void | Promise<void> {\n const clientKey = createRouteDataCacheKey(key);\n const task = updateTag(createRouteDataCacheTag(key));\n notifyFarmCacheInvalidation(clientKey);\n return task;\n}\n\nexport function invalidateRouteData(key: RouteDataCacheKey): void | Promise<void> {\n return invalidate(key);\n}\n\n/**\n * Apply a normalized set of invalidation targets and return browser cache keys\n * that should be carried with an action/endpoint response.\n */\nexport async function applyFarmCacheInvalidationTargets(\n targets: readonly FarmCacheInvalidationTarget[],\n): Promise<readonly string[]> {\n if (!Array.isArray(targets)) {\n throw new TypeError(\"Cache invalidations must resolve to an array of targets.\");\n }\n\n const clientKeys: string[] = [];\n for (const target of targets) {\n assertFarmCacheInvalidationTarget(target);\n if (\"key\" in target) {\n await invalidate(target.key);\n clientKeys.push(createRouteDataCacheKey(target.key));\n } else if (\"path\" in target) {\n await revalidatePath(target.path);\n } else {\n await updateTag(target.tag);\n }\n }\n return Array.from(new Set(clientKeys));\n}\n\nexport function createPathCacheTag(routePath: string): string {\n return `path:${normalizeRevalidatePath(routePath)}`;\n}\n\nexport function createRouteDataCacheTag(key: RouteDataCacheKey): string {\n return `route-data:${createRouteDataCacheKey(key)}`;\n}\n\nexport function createRouteDataCacheKey(key: RouteDataCacheKey): string {\n return createFarmCacheKey(Array.isArray(key) ? key : [key]);\n}\n\nexport function normalizeRevalidatePath(routePath: string): string {\n if (typeof routePath !== \"string\") {\n throw new TypeError(\"revalidatePath expects a path string.\");\n }\n\n let normalized = routePath.trim();\n if (!normalized) {\n throw new Error(\"revalidatePath expects a non-empty path.\");\n }\n\n try {\n if (/^https?:\\/\\//.test(normalized)) {\n normalized = new URL(normalized).pathname;\n }\n } catch {\n // Keep the original path if URL parsing fails.\n }\n\n normalized = normalized.split(\"?\")[0] ?? normalized;\n normalized = normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n normalized = normalized.replace(/\\/{2,}/g, \"/\");\n if (normalized.length > 1) {\n normalized = normalized.replace(/\\/+$/, \"\");\n }\n return normalized || \"/\";\n}\n\nexport function createFarmCacheKey(parts: readonly unknown[]): string {\n return stableSerialize(parts);\n}\n\nfunction normalizeRevalidate(revalidate: number | false | undefined): number | false | undefined {\n if (revalidate === false || revalidate === undefined) {\n return revalidate;\n }\n if (!Number.isFinite(revalidate) || revalidate <= 0) {\n return undefined;\n }\n return revalidate;\n}\n\nfunction normalizeCacheTag(tag: string): string {\n if (typeof tag !== \"string\") {\n throw new TypeError(\"Cache tags must be strings.\");\n }\n const normalized = tag.trim();\n if (!normalized) {\n throw new Error(\"Cache tags cannot be empty.\");\n }\n return normalized;\n}\n\nfunction normalizeCacheNamespace(namespace: string): string {\n if (typeof namespace !== \"string\") {\n throw new TypeError(\"Cache namespace must be a string.\");\n }\n const normalized = namespace.trim().replace(/:+$/g, \"\");\n if (!normalized) {\n throw new Error(\"Cache namespace cannot be empty.\");\n }\n return normalized;\n}\n\nfunction normalizeAdapterVersion(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction normalizePositiveDuration(\n value: number | undefined,\n fallback: number,\n name: string,\n): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(`${name} must be a positive number of milliseconds.`);\n }\n return Math.floor(value);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction normalizeCacheOptionsTags(options: FarmCacheOptions): Set<string> {\n const tags = new Set<string>();\n for (const tag of options.tags ?? []) {\n tags.add(normalizeCacheTag(tag));\n }\n for (const routePath of options.paths ?? []) {\n tags.add(createPathCacheTag(routePath));\n }\n return tags;\n}\n\nfunction assertFarmCacheEntry(\n entry: FarmCacheEntry,\n expectedKey: string,\n): asserts entry is FarmCacheEntry {\n if (\n !entry ||\n typeof entry !== \"object\" ||\n entry.key !== expectedKey ||\n !Array.isArray(entry.tags) ||\n typeof entry.createdAt !== \"number\"\n ) {\n throw new TypeError(\n `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`,\n );\n }\n}\n\nfunction assertFarmCacheInvalidationTarget(\n target: unknown,\n): asserts target is FarmCacheInvalidationTarget {\n if (!target || typeof target !== \"object\") {\n throw new TypeError(\"Cache invalidation targets must be { key }, { path }, or { tag }.\");\n }\n\n if (\"key\" in target) {\n const key = (target as { key?: unknown }).key;\n if (typeof key === \"string\" || Array.isArray(key)) return;\n } else if (\"path\" in target && typeof (target as { path?: unknown }).path === \"string\") {\n return;\n } else if (\"tag\" in target && typeof (target as { tag?: unknown }).tag === \"string\") {\n return;\n }\n\n throw new TypeError(\"Cache invalidation targets must contain a string/array key, path, or tag.\");\n}\n\nfunction getFunctionCacheIdentity(fn: Function): string {\n if (fn.name) {\n return `name:${fn.name}`;\n }\n\n let id = functionIds.get(fn);\n if (!id) {\n id = ++nextFunctionId;\n functionIds.set(fn, id);\n }\n return `anonymous:${id}`;\n}\n\nfunction stableSerialize(value: unknown, seen = new WeakSet<object>()): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n\n const valueType = typeof value;\n if (valueType === \"string\") return JSON.stringify(value);\n if (valueType === \"number\" || valueType === \"boolean\" || valueType === \"bigint\") {\n return `${valueType}:${String(value)}`;\n }\n if (valueType === \"symbol\") {\n return `symbol:${String(value)}`;\n }\n if (valueType === \"function\") {\n return `function:${getFunctionCacheIdentity(value as Function)}`;\n }\n\n if (value instanceof Date) {\n return `date:${value.toISOString()}`;\n }\n if (value instanceof URL) {\n return `url:${value.toString()}`;\n }\n if (value instanceof RegExp) {\n return `regexp:${value.toString()}`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerialize(item, seen)).join(\",\")}]`;\n }\n\n if (value && typeof value === \"object\") {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n const serialized = entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`)\n .join(\",\");\n\n seen.delete(value);\n return `{${serialized}}`;\n }\n\n return String(value);\n}\n","export type FarmRouteRuntime = \"auto\" | \"node\" | \"edge\";\nexport type FarmRouteRegions = \"auto\" | readonly string[];\nexport type FarmRouteMaxDuration = \"auto\" | number;\n\n/** Portable execution controls shared by file, programmatic, and config routes. */\nexport interface FarmRouteRuntimeConfig {\n runtime?: FarmRouteRuntime;\n regions?: FarmRouteRegions;\n maxDuration?: FarmRouteMaxDuration;\n}\n\nexport interface ResolvedFarmRouteRuntimeConfig {\n runtime: FarmRouteRuntime;\n regions?: string[];\n maxDuration?: number;\n}\n\nexport type FarmRouteRuntimeEntryKind = \"page\" | \"api\" | \"rule\";\nexport type FarmRouteRenderingMode = \"static\" | \"dynamic\";\n\nexport interface FarmRouteRuntimeManifestEntry extends ResolvedFarmRouteRuntimeConfig {\n kind: FarmRouteRuntimeEntryKind;\n pattern: string;\n rendering: FarmRouteRenderingMode;\n source?: string;\n}\n\nexport interface FarmRouteRuntimeManifest {\n version: 1;\n routes: FarmRouteRuntimeManifestEntry[];\n}\n\nexport function normalizeFarmRouteRuntimeConfig(\n value: FarmRouteRuntimeConfig | null | undefined,\n source = \"Route configuration\",\n): FarmRouteRuntimeConfig {\n if (!value) return {};\n\n const normalized: FarmRouteRuntimeConfig = {};\n\n if (value.runtime !== undefined) {\n if (value.runtime !== \"auto\" && value.runtime !== \"node\" && value.runtime !== \"edge\") {\n throw new TypeError(`${source} runtime must be \"auto\", \"node\", or \"edge\"`);\n }\n normalized.runtime = value.runtime;\n }\n\n if (value.regions !== undefined) {\n if (value.regions === \"auto\") {\n normalized.regions = \"auto\";\n } else {\n if (!Array.isArray(value.regions) || value.regions.length === 0) {\n throw new TypeError(`${source} regions must be \"auto\" or a non-empty string array`);\n }\n\n const regions = Array.from(\n new Set(\n value.regions.map((region) => {\n if (\n typeof region !== \"string\" ||\n !region.trim() ||\n /[\\u0000-\\u001f\\u007f]/.test(region)\n ) {\n throw new TypeError(`${source} regions must contain non-empty region identifiers`);\n }\n return region.trim();\n }),\n ),\n );\n\n normalized.regions = regions;\n }\n }\n\n if (value.maxDuration !== undefined) {\n if (value.maxDuration === \"auto\") {\n normalized.maxDuration = \"auto\";\n } else if (\n typeof value.maxDuration !== \"number\" ||\n !Number.isInteger(value.maxDuration) ||\n value.maxDuration <= 0\n ) {\n throw new TypeError(`${source} maxDuration must be \"auto\" or a positive integer in seconds`);\n } else {\n normalized.maxDuration = value.maxDuration;\n }\n }\n\n return normalized;\n}\n\n/** Merge from lowest to highest precedence. Explicit \"auto\" values reset inherited hints. */\nexport function mergeFarmRouteRuntimeConfigs(\n ...configs: Array<FarmRouteRuntimeConfig | null | undefined>\n): FarmRouteRuntimeConfig {\n const merged: FarmRouteRuntimeConfig = {};\n\n for (const config of configs) {\n if (!config) continue;\n if (config.runtime !== undefined) merged.runtime = config.runtime;\n if (config.regions !== undefined) merged.regions = config.regions;\n if (config.maxDuration !== undefined) merged.maxDuration = config.maxDuration;\n }\n\n return merged;\n}\n\nexport function resolveFarmRouteRuntimeConfig(\n config: FarmRouteRuntimeConfig | null | undefined,\n source?: string,\n): ResolvedFarmRouteRuntimeConfig {\n const normalized = normalizeFarmRouteRuntimeConfig(config, source);\n\n return {\n runtime: normalized.runtime ?? \"auto\",\n ...(normalized.regions && normalized.regions !== \"auto\"\n ? { regions: [...normalized.regions] }\n : {}),\n ...(typeof normalized.maxDuration === \"number\" ? { maxDuration: normalized.maxDuration } : {}),\n };\n}\n\nexport function hasFarmRouteRuntimeControls(\n config: FarmRouteRuntimeConfig | null | undefined,\n): boolean {\n return Boolean(\n config &&\n (config.runtime !== undefined ||\n config.regions !== undefined ||\n config.maxDuration !== undefined),\n );\n}\n\nexport function getFarmRouteRuntimeConfig(value: unknown): FarmRouteRuntimeConfig {\n if (!value || typeof value !== \"object\") return {};\n const route = value as FarmRouteRuntimeConfig;\n return {\n ...(route.runtime !== undefined ? { runtime: route.runtime } : {}),\n ...(route.regions !== undefined ? { regions: route.regions } : {}),\n ...(route.maxDuration !== undefined ? { maxDuration: route.maxDuration } : {}),\n };\n}\n\nexport function createFarmRouteRuntimeKey(config: ResolvedFarmRouteRuntimeConfig): string {\n return JSON.stringify({\n runtime: config.runtime,\n regions: config.regions || null,\n maxDuration: config.maxDuration || null,\n });\n}\n\n/** Resolve matching route rules from broadest to most specific. */\nexport function resolveFarmRouteRuleRuntimeConfig(\n pathname: string,\n routeRules: Record<string, FarmRouteRuntimeConfig> | null | undefined,\n): FarmRouteRuntimeConfig {\n if (!routeRules) return {};\n\n const matches = Object.entries(routeRules)\n .filter(\n ([pattern, rule]) =>\n hasFarmRouteRuntimeControls(rule) && farmRouteRuleMatches(pattern, pathname),\n )\n .sort(([left], [right]) => compareFarmRouteRuleSpecificity(left, right));\n\n return mergeFarmRouteRuntimeConfigs(...matches.map(([, rule]) => rule));\n}\n\nexport function farmRouteRuleMatches(pattern: string, pathname: string): boolean {\n const normalizedPattern = normalizeRoutePattern(pattern);\n const normalizedPathname = normalizeRoutePattern(pathname);\n if (normalizedPattern === normalizedPathname) return true;\n\n const expression = normalizedPattern\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment === \"**\") return \".*\";\n if (segment === \"*\") return \"[^/]+\";\n if (/^\\[\\[\\.\\.\\..+\\]\\]$/.test(segment)) return \".*\";\n if (/^\\[\\.\\.\\..+\\]$/.test(segment)) return \".+\";\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return \"[^/]+\";\n return escapeRegExp(segment);\n })\n .join(\"/\");\n\n return new RegExp(`^/${expression}/?$`).test(normalizedPathname);\n}\n\nfunction compareFarmRouteRuleSpecificity(left: string, right: string): number {\n const leftScore = getFarmRouteRuleSpecificity(left);\n const rightScore = getFarmRouteRuleSpecificity(right);\n return leftScore - rightScore || left.localeCompare(right);\n}\n\nfunction getFarmRouteRuleSpecificity(pattern: string): number {\n return normalizeRoutePattern(pattern)\n .split(\"/\")\n .filter(Boolean)\n .reduce((score, segment) => {\n if (segment === \"**\" || segment.startsWith(\"[[...\")) return score + 1;\n if (segment === \"*\" || segment.startsWith(\"[...\")) return score + 10;\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return score + 50;\n return score + 100;\n }, 0);\n}\n\nfunction normalizeRoutePattern(value: string): string {\n const withSlash = value.trim().startsWith(\"/\") ? value.trim() : `/${value.trim()}`;\n return withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport {\n PROGRAMMATIC_ROUTE_FILE_NAMES,\n getProgrammaticRouteManifest,\n scanProgrammaticPagePaths,\n type ProgrammaticRouteManifest,\n} from \"./routes\";\n\nexport interface LoadedProgrammaticRouteManifest {\n filePath: string;\n manifest: ProgrammaticRouteManifest;\n}\n\nexport async function loadProgrammaticRouteManifests(options: {\n root: string;\n srcDir?: string;\n loadModule: (filePath: string) => Promise<Record<string, any>>;\n}): Promise<LoadedProgrammaticRouteManifest[]> {\n const manifests: LoadedProgrammaticRouteManifest[] = [];\n\n for (const filePath of findProgrammaticRouteFiles(options.root, options.srcDir)) {\n const mod = await options.loadModule(filePath);\n const manifest = getProgrammaticRouteManifest(mod);\n if (manifest) {\n manifests.push({ filePath, manifest });\n }\n }\n\n return manifests;\n}\n\nexport function findProgrammaticRouteFiles(root: string, srcDir = \"src\"): string[] {\n return findProgrammaticRouteFilesInDir(join(root, srcDir));\n}\n\nexport function findProgrammaticRouteFilesInDir(srcRoot: string): string[] {\n const files: string[] = [];\n\n for (const fileName of PROGRAMMATIC_ROUTE_FILE_NAMES) {\n const filePath = join(srcRoot, fileName);\n if (existsSync(filePath)) {\n files.push(filePath);\n }\n }\n\n return files;\n}\n\nexport async function discoverProgrammaticRoutePaths(\n root: string,\n srcDir = \"src\",\n): Promise<string[]> {\n const paths = new Set<string>();\n const files = new Set([\n ...findProgrammaticRouteFiles(root, srcDir),\n ...(await findProgrammaticRouteSourceFiles(join(root, srcDir))),\n ]);\n\n for (const filePath of files) {\n const source = readFileSync(filePath, \"utf8\");\n for (const routePath of scanProgrammaticPagePaths(source)) {\n paths.add(routePath);\n }\n }\n\n return Array.from(paths).sort();\n}\n\nasync function findProgrammaticRouteSourceFiles(srcRoot: string): Promise<string[]> {\n if (!existsSync(srcRoot)) {\n return [];\n }\n\n try {\n const glob = await import(\"fast-glob\");\n return await glob.default(\"**/*.{ts,tsx,js,jsx}\", {\n cwd: srcRoot,\n absolute: true,\n ignore: [\n \"**/*.d.ts\",\n \"**/node_modules/**\",\n \"**/.*/**\",\n \"farm-routes.d.ts\",\n \"farm-env.d.ts\",\n \"lib/api.generated.ts\",\n ],\n });\n } catch {\n return [];\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { FarmLocaleResolution } from \"./resolver\";\nimport { _setFarmI18nSnapshotResolver } from \"./bridge\";\nimport { FarmI18nRuntime, createFarmI18nRuntime } from \"./runtime\";\nimport type {\n FarmI18nClientSnapshot,\n FarmI18nLocale,\n FarmI18nLocaleSource,\n FarmI18nMessageArgs,\n FarmI18nMessageKey,\n FarmTranslator,\n} from \"./types\";\n\ninterface FarmI18nRequestState {\n runtime: FarmI18nRuntime;\n resolution: FarmLocaleResolution;\n snapshot: FarmI18nClientSnapshot;\n}\n\ninterface FarmListFormatOptions {\n localeMatcher?: \"lookup\" | \"best fit\";\n type?: \"conjunction\" | \"disjunction\" | \"unit\";\n style?: \"long\" | \"short\" | \"narrow\";\n}\n\nconst FARM_I18N_REQUEST_STORE = Symbol.for(\"farm.i18n.requestStore\");\nconst FARM_I18N_DEFAULT_RUNTIME = Symbol.for(\"farm.i18n.defaultRuntime\");\n\ntype GlobalFarmI18nState = typeof globalThis & {\n [FARM_I18N_REQUEST_STORE]?: AsyncLocalStorage<FarmI18nRequestState>;\n [FARM_I18N_DEFAULT_RUNTIME]?: FarmI18nRuntime;\n};\n\nfunction getRequestStore(): AsyncLocalStorage<FarmI18nRequestState> {\n const state = globalThis as GlobalFarmI18nState;\n return (state[FARM_I18N_REQUEST_STORE] ??= new AsyncLocalStorage<FarmI18nRequestState>());\n}\n\nfunction getState(): FarmI18nRequestState {\n const state = getRequestStore().getStore();\n if (!state) {\n throw new Error(\n \"No Farm i18n request context is active. Use this API while rendering, inside an API route, or use createTranslator(locale).\",\n );\n }\n return state;\n}\n\nexport function _setDefaultFarmI18nRuntime(runtime: FarmI18nRuntime | undefined): void {\n (globalThis as GlobalFarmI18nState)[FARM_I18N_DEFAULT_RUNTIME] = runtime;\n}\n\nexport async function _runWithFarmI18nRequest<T>(\n runtime: FarmI18nRuntime,\n request: Request,\n fn: (resolution: FarmLocaleResolution) => T | Promise<T>,\n options: { redirect?: boolean } = {},\n): Promise<T> {\n const resolution = runtime.resolveRequest(request, options);\n const state: FarmI18nRequestState = {\n runtime,\n resolution,\n snapshot: runtime.getClientSnapshot(resolution),\n };\n return getRequestStore().run(state, () => fn(resolution));\n}\n\nexport async function runWithLocale<T>(\n locale: FarmI18nLocale,\n fn: () => T | Promise<T>,\n): Promise<T> {\n const runtime = getDefaultRuntime();\n assertLocale(runtime, locale);\n const resolution: FarmLocaleResolution = {\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n };\n const state: FarmI18nRequestState = {\n runtime,\n resolution,\n snapshot: runtime.getClientSnapshot(resolution),\n };\n return getRequestStore().run(state, fn);\n}\n\nexport function getLocale(): FarmI18nLocale {\n return getState().resolution.locale as FarmI18nLocale;\n}\n\nexport function getLocaleSource(): FarmI18nLocaleSource {\n return getState().resolution.source;\n}\n\nexport const t = createTranslatorFromState(() => getState());\n\nexport function createTranslator(locale: FarmI18nLocale): FarmTranslator {\n const runtime = getDefaultRuntime();\n assertLocale(runtime, locale);\n return createTranslatorFromState(() => ({\n runtime,\n resolution: {\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n },\n snapshot: runtime.getClientSnapshot({\n locale,\n source: \"explicit\",\n pathname: \"/\",\n persist: false,\n }),\n }));\n}\n\nexport function getFarmI18nClientSnapshot(): FarmI18nClientSnapshot | undefined {\n return getRequestStore().getStore()?.snapshot;\n}\n\nexport const format = {\n number(value: number, options?: Intl.NumberFormatOptions): string {\n return new Intl.NumberFormat(getLocale(), options).format(value);\n },\n currency(\n value: number,\n currency: string,\n options: Omit<Intl.NumberFormatOptions, \"style\" | \"currency\"> = {},\n ): string {\n return new Intl.NumberFormat(getLocale(), {\n ...options,\n style: \"currency\",\n currency,\n }).format(value);\n },\n date(value: Date | number, options?: Intl.DateTimeFormatOptions): string {\n return new Intl.DateTimeFormat(getLocale(), options).format(value);\n },\n relativeTime(\n value: number,\n unit: Intl.RelativeTimeFormatUnit,\n options?: Intl.RelativeTimeFormatOptions,\n ): string {\n return new Intl.RelativeTimeFormat(getLocale(), options).format(value, unit);\n },\n list(values: Iterable<string>, options?: FarmListFormatOptions): string {\n const ListFormat = (Intl as any).ListFormat;\n return new ListFormat(getLocale(), options).format(Array.from(values));\n },\n};\n\nfunction getDefaultRuntime(): FarmI18nRuntime {\n const runtime = (globalThis as GlobalFarmI18nState)[FARM_I18N_DEFAULT_RUNTIME];\n if (!runtime?.config.enabled) {\n throw new Error(\"Farm i18n is not configured for this application.\");\n }\n return runtime;\n}\n\nfunction assertLocale(runtime: FarmI18nRuntime, locale: string): void {\n if (!runtime.config.locales.includes(locale)) {\n throw new Error(`Unsupported Farm i18n locale \"${locale}\".`);\n }\n}\n\nfunction createTranslatorFromState(resolveState: () => FarmI18nRequestState): FarmTranslator {\n const translator = ((key: string, values?: Record<string, unknown>) => {\n const state = resolveState();\n return state.runtime.translate(state.resolution.locale, key, values);\n }) as FarmTranslator;\n translator.rich = (key: string, values?: Record<string, unknown>) => {\n const state = resolveState();\n return state.runtime.translateRich(state.resolution.locale, key, values);\n };\n translator.raw = (key: string) => {\n const state = resolveState();\n return state.runtime.getRawMessage(state.resolution.locale, key);\n };\n translator.has = (key: string) => {\n const state = resolveState();\n return state.runtime.hasMessage(state.resolution.locale, key);\n };\n return translator;\n}\n\n_setFarmI18nSnapshotResolver(() => getFarmI18nClientSnapshot());\n\nexport { FarmI18nRuntime, createFarmI18nRuntime };\nexport type { FarmI18nClientSnapshot, FarmI18nLocale, FarmI18nMessageArgs, FarmI18nMessageKey };\n","import IntlMessageFormat from \"intl-messageformat\";\nimport { readFarmI18nCatalogs } from \"./catalog\";\nimport { getFarmLocaleDirection } from \"./routing\";\nimport { resolveFarmLocaleRequest, type FarmLocaleResolution } from \"./resolver\";\nimport type { FarmI18nCatalogs, FarmI18nClientSnapshot, ResolvedFarmI18nConfig } from \"./types\";\n\nexport class FarmI18nRuntime {\n readonly config: ResolvedFarmI18nConfig;\n private catalogs: FarmI18nCatalogs;\n private compiled = new Map<string, IntlMessageFormat>();\n private warnedMissing = new Set<string>();\n\n constructor(config: ResolvedFarmI18nConfig, catalogs: FarmI18nCatalogs = {}) {\n this.config = config;\n this.catalogs = catalogs;\n }\n\n async initialize(): Promise<void> {\n if (!this.config.enabled) return;\n const bundle = await readFarmI18nCatalogs(this.config);\n this.replaceCatalogs(bundle.catalogs);\n }\n\n async reload(): Promise<void> {\n await this.initialize();\n }\n\n replaceCatalogs(catalogs: FarmI18nCatalogs): void {\n this.catalogs = catalogs;\n this.compiled.clear();\n this.warnedMissing.clear();\n }\n\n getCatalogs(): FarmI18nCatalogs {\n return Object.fromEntries(\n Object.entries(this.catalogs).map(([locale, catalog]) => [locale, { ...catalog }]),\n );\n }\n\n resolveRequest(request: Request, options: { redirect?: boolean } = {}): FarmLocaleResolution {\n return resolveFarmLocaleRequest(request, this.config, options);\n }\n\n translate(locale: string, key: string, values?: Record<string, unknown>): string {\n const result = this.formatMessage(locale, key, values);\n if (Array.isArray(result) && result.some((part) => typeof part !== \"string\")) {\n throw new Error(`Farm i18n message \"${key}\" contains rich content. Render it with t.rich().`);\n }\n return Array.isArray(result) ? result.join(\"\") : String(result);\n }\n\n translateRich(locale: string, key: string, values?: Record<string, unknown>): unknown {\n const result = this.formatMessage(locale, key, values);\n return Array.isArray(result) && result.length === 1 ? result[0] : result;\n }\n\n getRawMessage(locale: string, key: string): string {\n return this.resolveMessage(locale, key);\n }\n\n hasMessage(locale: string, key: string): boolean {\n return (\n (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !==\n undefined\n );\n }\n\n getClientSnapshot(resolution: FarmLocaleResolution): FarmI18nClientSnapshot {\n return {\n locale: resolution.locale,\n source: resolution.source,\n locales: this.config.locales,\n defaultLocale: this.config.defaultLocale,\n routing: this.config.routing,\n cookie: this.config.cookie,\n direction: getFarmLocaleDirection(resolution.locale, this.config.direction),\n messages: {\n ...this.catalogs[this.config.fallbackLocale],\n ...this.catalogs[resolution.locale],\n },\n };\n }\n\n private formatMessage(locale: string, key: string, values?: Record<string, unknown>): unknown {\n const message = this.resolveMessage(locale, key);\n const cacheKey = `${locale}\\u0000${key}\\u0000${message}`;\n let formatter = this.compiled.get(cacheKey);\n if (!formatter) {\n formatter = new IntlMessageFormat(message, locale);\n this.compiled.set(cacheKey, formatter);\n }\n return formatter.format(values as any);\n }\n\n private resolveMessage(locale: string, key: string): string {\n const message =\n this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];\n if (message !== undefined) return message;\n if (this.config.strict) {\n throw new Error(`Missing Farm i18n message \"${key}\" for locale \"${locale}\".`);\n }\n const warningKey = `${locale}:${key}`;\n if (!this.warnedMissing.has(warningKey)) {\n this.warnedMissing.add(warningKey);\n console.warn(`[Farm.js] Missing i18n message \"${key}\" for locale \"${locale}\".`);\n }\n return key;\n }\n}\n\nexport function createFarmI18nRuntime(\n config: ResolvedFarmI18nConfig,\n catalogs?: FarmI18nCatalogs,\n): FarmI18nRuntime {\n return new FarmI18nRuntime(config, catalogs);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { TYPE, parse, type MessageFormatElement } from \"@formatjs/icu-messageformat-parser\";\nimport { resolveFarmI18nMessagePath } from \"./config\";\nimport type { FarmI18nCatalog, FarmI18nCatalogs, ResolvedFarmI18nConfig } from \"./types\";\n\nexport type FarmI18nArgumentKind = \"string\" | \"number\" | \"date\" | \"select\" | \"rich\";\nexport type FarmI18nMessageSignature = Record<string, FarmI18nArgumentKind>;\n\nexport interface FarmI18nCatalogBundle {\n catalogs: FarmI18nCatalogs;\n signatures: Record<string, FarmI18nMessageSignature>;\n}\n\nexport async function readFarmI18nCatalogs(\n config: ResolvedFarmI18nConfig,\n): Promise<FarmI18nCatalogBundle> {\n if (!config.enabled) {\n return { catalogs: {}, signatures: {} };\n }\n\n const catalogs: FarmI18nCatalogs = {};\n for (const locale of config.locales) {\n const filePath = resolveFarmI18nMessagePath(config, locale);\n let source: string;\n try {\n source = await readFile(filePath, \"utf8\");\n } catch (error) {\n throw new Error(\n `Unable to read Farm i18n catalog for \"${locale}\" at ${filePath}: ${messageOf(error)}`,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (error) {\n throw new Error(`Invalid JSON in Farm i18n catalog ${filePath}: ${messageOf(error)}`);\n }\n catalogs[locale] = flattenFarmI18nCatalog(parsed, filePath);\n }\n\n const reference = catalogs[config.defaultLocale] || {};\n const signatures: Record<string, FarmI18nMessageSignature> = {};\n for (const [key, message] of Object.entries(reference)) {\n signatures[key] = analyzeFarmI18nMessage(message, `${config.defaultLocale}:${key}`);\n }\n\n validateFarmI18nCatalogs(config, catalogs, signatures);\n return { catalogs, signatures };\n}\n\nexport function flattenFarmI18nCatalog(input: unknown, source = \"i18n catalog\"): FarmI18nCatalog {\n if (!isPlainObject(input)) {\n throw new Error(`${source} must contain a JSON object at its root.`);\n }\n\n const output: FarmI18nCatalog = {};\n const visit = (value: unknown, segments: string[]) => {\n if (typeof value === \"string\") {\n const key = segments.join(\".\");\n if (!key) throw new Error(`${source} contains an empty message key.`);\n if (key in output) throw new Error(`${source} contains duplicate message key \"${key}\".`);\n output[key] = value;\n return;\n }\n\n if (!isPlainObject(value)) {\n const key = segments.join(\".\") || \"<root>\";\n throw new Error(`${source} message \"${key}\" must be a string or nested object.`);\n }\n\n for (const [key, nested] of Object.entries(value)) {\n if (!key.trim()) throw new Error(`${source} contains an empty message key.`);\n visit(nested, [...segments, key]);\n }\n };\n\n visit(input, []);\n return output;\n}\n\nexport function analyzeFarmI18nMessage(\n message: string,\n label = \"message\",\n): FarmI18nMessageSignature {\n let ast: MessageFormatElement[];\n try {\n ast = parse(message, { captureLocation: false });\n } catch (error) {\n throw new Error(`Invalid ICU syntax in ${label}: ${messageOf(error)}`);\n }\n\n const signature: FarmI18nMessageSignature = {};\n collectArguments(ast, signature, label);\n return signature;\n}\n\nfunction validateFarmI18nCatalogs(\n config: ResolvedFarmI18nConfig,\n catalogs: FarmI18nCatalogs,\n signatures: Record<string, FarmI18nMessageSignature>,\n): void {\n const referenceKeys = Object.keys(catalogs[config.defaultLocale] || {}).sort();\n\n for (const locale of config.locales) {\n const catalog = catalogs[locale] || {};\n const localeKeys = Object.keys(catalog).sort();\n const missing = referenceKeys.filter((key) => !(key in catalog));\n const extra = localeKeys.filter((key) => !(key in signatures));\n\n if (config.strict && (missing.length > 0 || extra.length > 0)) {\n const details = [\n missing.length ? `missing: ${missing.join(\", \")}` : \"\",\n extra.length ? `extra: ${extra.join(\", \")}` : \"\",\n ]\n .filter(Boolean)\n .join(\"; \");\n throw new Error(\n `Farm i18n catalog \"${locale}\" does not match the default catalog (${details}).`,\n );\n }\n\n for (const [key, message] of Object.entries(catalog)) {\n const actual = analyzeFarmI18nMessage(message, `${locale}:${key}`);\n const expected = signatures[key];\n if (!expected || sameSignature(expected, actual)) continue;\n throw new Error(\n `Farm i18n message \"${key}\" in \"${locale}\" uses different variables than \"${config.defaultLocale}\".`,\n );\n }\n }\n}\n\nfunction collectArguments(\n elements: MessageFormatElement[],\n signature: FarmI18nMessageSignature,\n label: string,\n): void {\n for (const element of elements) {\n switch (element.type) {\n case TYPE.argument:\n addArgument(signature, element.value, \"string\", label);\n break;\n case TYPE.number:\n case TYPE.plural:\n addArgument(signature, element.value, \"number\", label);\n break;\n case TYPE.date:\n case TYPE.time:\n addArgument(signature, element.value, \"date\", label);\n break;\n case TYPE.select:\n addArgument(signature, element.value, \"select\", label);\n break;\n case TYPE.tag:\n addArgument(signature, element.value, \"rich\", label);\n collectArguments(element.children, signature, label);\n break;\n }\n\n if (element.type === TYPE.plural || element.type === TYPE.select) {\n for (const option of Object.values(element.options)) {\n collectArguments(option.value, signature, label);\n }\n }\n }\n}\n\nfunction addArgument(\n signature: FarmI18nMessageSignature,\n name: string,\n kind: FarmI18nArgumentKind,\n label: string,\n): void {\n const existing = signature[name];\n if (existing && existing !== kind) {\n throw new Error(`Farm i18n ${label} uses variable \"${name}\" as both ${existing} and ${kind}.`);\n }\n signature[name] = kind;\n}\n\nfunction sameSignature(\n expected: FarmI18nMessageSignature,\n actual: FarmI18nMessageSignature,\n): boolean {\n const expectedEntries = Object.entries(expected).sort(([a], [b]) => a.localeCompare(b));\n const actualEntries = Object.entries(actual).sort(([a], [b]) => a.localeCompare(b));\n return JSON.stringify(expectedEntries) === JSON.stringify(actualEntries);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import path from \"node:path\";\nimport type {\n FarmI18nDetectionSignal,\n FarmI18nDirection,\n FarmI18nUserConfig,\n ResolvedFarmI18nConfig,\n} from \"./types\";\n\nexport const DEFAULT_FARM_I18N_COOKIE = \"farm_locale\";\nexport const DEFAULT_FARM_I18N_COOKIE_MAX_AGE = 60 * 60 * 24 * 365;\n\nconst DEFAULT_DETECTION: readonly FarmI18nDetectionSignal[] = [\"url\", \"cookie\", \"accept-language\"];\n\nexport function resolveFarmI18nConfig(\n input: FarmI18nUserConfig | false | undefined,\n options: { root?: string; mode?: \"development\" | \"production\" } = {},\n): ResolvedFarmI18nConfig {\n const root = options.root || process.cwd();\n const strictByDefault = options.mode === \"production\";\n\n if (!input) {\n return {\n enabled: false,\n locales: [\"en\"],\n defaultLocale: \"en\",\n messages: path.join(root, \"src/messages\"),\n routing: \"none\",\n detection: [],\n fallbackLocale: \"en\",\n strict: strictByDefault,\n cookie: {\n name: DEFAULT_FARM_I18N_COOKIE,\n maxAge: DEFAULT_FARM_I18N_COOKIE_MAX_AGE,\n path: \"/\",\n sameSite: \"lax\",\n secure: options.mode === \"production\",\n },\n direction: {},\n };\n }\n\n if (!Array.isArray(input.locales) || input.locales.length === 0) {\n throw new Error(\"i18n.locales must contain at least one locale.\");\n }\n\n const locales = input.locales.map(canonicalizeLocale);\n if (new Set(locales).size !== locales.length) {\n throw new Error(\"i18n.locales must not contain duplicate locales.\");\n }\n\n const defaultLocale = canonicalizeLocale(input.defaultLocale);\n if (!locales.includes(defaultLocale)) {\n throw new Error(`i18n.defaultLocale \"${defaultLocale}\" must be included in i18n.locales.`);\n }\n\n const fallbackLocale = canonicalizeLocale(input.fallbackLocale || defaultLocale);\n if (!locales.includes(fallbackLocale)) {\n throw new Error(`i18n.fallbackLocale \"${fallbackLocale}\" must be included in i18n.locales.`);\n }\n\n const detection = resolveDetection(input);\n const direction: Record<string, FarmI18nDirection> = {};\n for (const [rawLocale, value] of Object.entries(input.direction || {})) {\n const locale = canonicalizeLocale(rawLocale);\n if (!locales.includes(locale)) {\n throw new Error(`i18n.direction contains unknown locale \"${rawLocale}\".`);\n }\n if (value !== \"ltr\" && value !== \"rtl\") {\n throw new Error(`i18n.direction.${rawLocale} must be \"ltr\" or \"rtl\".`);\n }\n direction[locale] = value;\n }\n\n return {\n enabled: true,\n locales,\n defaultLocale,\n messages: path.resolve(root, input.messages || \"src/messages\"),\n routing: input.routing || \"prefix-except-default\",\n detection,\n fallbackLocale,\n strict: input.strict ?? strictByDefault,\n cookie: {\n name: input.cookie?.name?.trim() || DEFAULT_FARM_I18N_COOKIE,\n maxAge: normalizePositiveInteger(\n input.cookie?.maxAge,\n DEFAULT_FARM_I18N_COOKIE_MAX_AGE,\n \"i18n.cookie.maxAge\",\n ),\n path: input.cookie?.path || \"/\",\n sameSite: input.cookie?.sameSite || \"lax\",\n secure: input.cookie?.secure ?? options.mode === \"production\",\n },\n direction,\n };\n}\n\nexport function resolveFarmI18nMessagePath(\n config: Pick<ResolvedFarmI18nConfig, \"messages\">,\n locale: string,\n): string {\n return config.messages.includes(\"{locale}\")\n ? config.messages.split(\"{locale}\").join(locale)\n : path.join(config.messages, `${locale}.json`);\n}\n\nexport function canonicalizeLocale(locale: string): string {\n if (!locale || typeof locale !== \"string\") {\n throw new Error(\"Farm i18n locales must be non-empty strings.\");\n }\n\n try {\n return Intl.getCanonicalLocales(locale)[0]!;\n } catch {\n throw new Error(`Invalid i18n locale \"${locale}\".`);\n }\n}\n\nfunction resolveDetection(input: FarmI18nUserConfig): readonly FarmI18nDetectionSignal[] {\n if (input.detection === false || input.localeDetection === false) {\n return [\"url\"];\n }\n\n const detection = input.detection || DEFAULT_DETECTION;\n const allowed = new Set<FarmI18nDetectionSignal>([\"url\", \"cookie\", \"accept-language\"]);\n const unique: FarmI18nDetectionSignal[] = [];\n\n for (const signal of detection) {\n if (!allowed.has(signal)) {\n throw new Error(`Unsupported i18n detection signal \"${signal}\".`);\n }\n if (!unique.includes(signal)) unique.push(signal);\n }\n\n return unique;\n}\n\nfunction normalizePositiveInteger(\n value: number | undefined,\n fallback: number,\n name: string,\n): number {\n if (value === undefined) return fallback;\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} must be a positive integer.`);\n }\n return value;\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { FarmRequest } from \"../types\";\nimport { _setCurrentRequestResolver } from \"./request-bridge\";\n\nconst REQUEST_STORAGE_KEY = Symbol.for(\"@farm.js/core/request-storage\");\n\nfunction getRequestStore(): AsyncLocalStorage<Request> {\n const runtime = globalThis as typeof globalThis & Record<PropertyKey, unknown>;\n const existing = runtime[REQUEST_STORAGE_KEY];\n if (existing instanceof AsyncLocalStorage) {\n return existing as AsyncLocalStorage<Request>;\n }\n\n const storage = new AsyncLocalStorage<Request>();\n runtime[REQUEST_STORAGE_KEY] = storage;\n return storage;\n}\n\nconst requestStore = getRequestStore();\n\n_setCurrentRequestResolver(() => requestStore.getStore());\n\nexport function createWebRequestFromFarmRequest(req: FarmRequest): Request {\n const forwardedHost = req.headers[\"x-forwarded-host\"];\n const host = Array.isArray(forwardedHost)\n ? forwardedHost[0]\n : forwardedHost || req.headers.host || \"localhost\";\n const forwardedProto = req.headers[\"x-forwarded-proto\"];\n const proto = Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto || \"http\";\n const fullUrl = new URL(req.url || \"/\", `${proto}://${host}`).toString();\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value == null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(key, item);\n }\n continue;\n }\n\n headers.set(key, value);\n }\n\n return new Request(fullUrl, {\n method: req.method,\n headers,\n });\n}\n\nexport async function _runWithCurrentRequest<T>(\n request: Request,\n fn: () => Promise<T> | T,\n): Promise<T> {\n return requestStore.run(request, fn);\n}\n\nexport function getCurrentRequest(): Request {\n const request = requestStore.getStore();\n if (!request) {\n throw new Error(\n \"No current request is available. getCurrentRequest() can only be used during server rendering.\",\n );\n }\n\n return request;\n}\n","type CurrentRequestResolver = () => Request | undefined;\n\nconst CURRENT_REQUEST_RESOLVER_KEY = Symbol.for(\"farm.currentRequestResolver\");\n\ntype GlobalWithCurrentRequestResolver = typeof globalThis & {\n [CURRENT_REQUEST_RESOLVER_KEY]?: CurrentRequestResolver;\n};\n\nfunction getGlobalState(): GlobalWithCurrentRequestResolver {\n return globalThis as GlobalWithCurrentRequestResolver;\n}\n\nexport function _setCurrentRequestResolver(resolver: CurrentRequestResolver | undefined): void {\n getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY] = resolver;\n}\n\nexport function _resolveCurrentRequest(): Request | undefined {\n return getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY]?.();\n}\n","import { createEndpoint as betterCallEndpoint } from \"better-call\";\nimport { applyFarmCacheInvalidationTargets, type FarmCacheInvalidationTarget } from \"../cache\";\nimport { isMultipartSchema, type MultipartSchema, type TypedFormData } from \"./transport\";\n\n// Generic schema type that works with both Zod v3 and v4\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySchema = { _output?: any; _input?: any; parse?: (data: unknown) => any };\n\ntype MaybePromise<T> = T | Promise<T>;\ntype Simplify<T> = { [TKey in keyof T]: T[TKey] } & {};\ntype UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (\n value: infer TIntersection,\n) => void\n ? TIntersection\n : never;\n\n// Infer output type from schema (works with Zod v3 and v4)\ntype InferOutput<T> = T extends { _output: infer O }\n ? O\n : T extends { parse: (data: unknown) => infer R }\n ? R\n : unknown;\n\ntype InferBodyInput<T> =\n T extends MultipartSchema<AnySchema> ? TypedFormData<InferOutput<T>> : InferOutput<T>;\n\ntype InferHeadersOutput<T> = [T] extends [never]\n ? Record<string, string>\n : T extends AnySchema\n ? InferOutput<T>\n : Record<string, string>;\n\nexport type EndpointErrorDefinition<\n TSchema extends AnySchema = AnySchema,\n TStatus extends number = number,\n> = {\n status: TStatus;\n schema: TSchema;\n /** Public message safe to expose to API callers. */\n message?: string;\n};\n\nexport type EndpointErrorDefinitions = Record<string, EndpointErrorDefinition<AnySchema, number>>;\n\nexport type EndpointErrorContracts<TErrors extends EndpointErrorDefinitions> = {\n [TCode in keyof TErrors]: {\n data: InferOutput<TErrors[TCode][\"schema\"]>;\n status: TErrors[TCode][\"status\"];\n };\n};\n\nexport type EndpointFail<TErrors extends EndpointErrorDefinitions> = <\n TCode extends keyof TErrors & string,\n>(\n code: TCode,\n data: InferOutput<TErrors[TCode][\"schema\"]>,\n) => never;\n\nexport class EndpointFailure<TCode extends string = string, TData = unknown> extends Error {\n readonly code: TCode;\n readonly data: TData;\n readonly status: number;\n\n constructor(\n code: TCode,\n data: TData,\n options: {\n status: number;\n message: string;\n },\n ) {\n super(options.message);\n this.name = \"EndpointFailure\";\n this.code = code;\n this.data = data;\n this.status = options.status;\n }\n}\n\nexport function isEndpointFailure(value: unknown): value is EndpointFailure<string, unknown> {\n return value instanceof EndpointFailure;\n}\n\nexport type EndpointParamValue = string | string[];\nexport type EndpointParams = Record<string, EndpointParamValue>;\n\nexport type EndpointMiddlewareContext<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = {\n body: TBody;\n query: TQuery;\n headers: THeaders;\n request: Request;\n /** Context accumulated from middleware that ran earlier in the chain. */\n context: Readonly<TContext>;\n params: EndpointParams;\n};\n\nexport type EndpointMiddlewareResult<TProvidedContext extends object = object> =\n | TProvidedContext\n | true\n | false\n | Response;\n\n/** A plain async function. No wrapper or `next()` callback is required. */\nexport type EndpointMiddleware<\n TProvidedContext extends object = object,\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = (\n ctx: EndpointMiddlewareContext<TContext, TBody, TQuery, THeaders>,\n) => MaybePromise<EndpointMiddlewareResult<TProvidedContext>>;\n\nexport type AnyEndpointMiddleware = (ctx: EndpointMiddlewareContext<any, any, any, any>) => unknown;\n\nexport type EndpointInvalidationTarget = FarmCacheInvalidationTarget;\n\nexport type EndpointInvalidationContext<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> = EndpointMiddlewareContext<TContext, TBody, TQuery, THeaders> & {\n /** The raw value returned by the endpoint handler. */\n result: unknown;\n};\n\nexport type EndpointInvalidations<\n TContext extends object = {},\n TBody = unknown,\n TQuery = unknown,\n THeaders = Record<string, string>,\n> =\n | readonly EndpointInvalidationTarget[]\n | ((\n context: EndpointInvalidationContext<TContext, TBody, TQuery, THeaders>,\n ) => readonly EndpointInvalidationTarget[] | Promise<readonly EndpointInvalidationTarget[]>);\n\ntype ValidateEndpointMiddlewares<TMiddlewares extends readonly AnyEndpointMiddleware[]> = {\n readonly [TIndex in keyof TMiddlewares]: TMiddlewares[TIndex] extends AnyEndpointMiddleware\n ? [Awaited<ReturnType<TMiddlewares[TIndex]>>] extends [EndpointMiddlewareResult<object>]\n ? TMiddlewares[TIndex]\n : never\n : never;\n};\n\ntype ContextFromMiddlewareResult<TResult> =\n Exclude<TResult, Response | boolean> extends infer TContext\n ? [TContext] extends [never]\n ? {}\n : TContext extends object\n ? TContext\n : {}\n : {};\n\ntype ContextFromMiddleware<TMiddleware> = TMiddleware extends (...args: any[]) => infer TResult\n ? ContextFromMiddlewareResult<Awaited<TResult>>\n : {};\n\nexport type InferEndpointMiddlewareContext<\n TMiddlewares extends readonly ((...args: any[]) => any)[],\n TContext extends object = {},\n> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest]\n ? TMiddleware extends (...args: any[]) => any\n ? TRest extends readonly ((...args: any[]) => any)[]\n ? InferEndpointMiddlewareContext<\n TRest,\n Simplify<TContext & ContextFromMiddleware<TMiddleware>>\n >\n : Simplify<TContext>\n : Simplify<TContext>\n : number extends TMiddlewares[\"length\"]\n ? Simplify<TContext & UnionToIntersection<ContextFromMiddleware<TMiddlewares[number]>>>\n : Simplify<TContext>;\n\nexport type EndpointOptions<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TMiddlewares extends readonly AnyEndpointMiddleware[] = readonly [],\n TErrors extends EndpointErrorDefinitions = {},\n> = {\n method?: \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\";\n body?: TBody;\n query?: TQuery;\n headers?: THeaders;\n middleware?: TMiddlewares;\n /**\n * Cache keys, tags, and route paths made stale after a successful handler result.\n * The resolver receives validated input and middleware context.\n */\n invalidates?: EndpointInvalidations<\n InferEndpointMiddlewareContext<TMiddlewares>,\n InferOutput<TBody>,\n InferOutput<TQuery>,\n InferHeadersOutput<THeaders>\n >;\n errors?: TErrors;\n /** @deprecated Use plain functions in `middleware` for Farm endpoint middleware. */\n use?: any[];\n};\n\nexport type EndpointHandler<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n TContext extends object = {},\n TErrors extends EndpointErrorDefinitions = {},\n> = (ctx: {\n body: InferOutput<TBody>;\n query: InferOutput<TQuery>;\n headers: InferHeadersOutput<THeaders>;\n request: Request;\n context: Readonly<TContext>;\n params: EndpointParams;\n fail: EndpointFail<TErrors>;\n}) => Promise<TResponse> | TResponse;\n\n// Type to represent an endpoint with its input/output types\nexport type TypedEndpoint<\n TBody = never,\n TQuery = never,\n TResponse = any,\n THeaders = Record<string, string>,\n TErrors = never,\n TBodyInput = TBody,\n> = {\n __types: {\n body: TBody;\n inputBody: TBodyInput;\n query: TQuery;\n headers: THeaders;\n response: TResponse;\n errors: TErrors;\n };\n __path?: string;\n __method?: string;\n} & ((options?: { body?: TBody; query?: TQuery }) => Promise<TResponse>);\n\ntype CreatedEndpoint<\n TBody extends AnySchema,\n TQuery extends AnySchema,\n THeaders extends AnySchema,\n TResponse,\n TErrors extends EndpointErrorDefinitions = {},\n> = TypedEndpoint<\n InferOutput<TBody>,\n InferOutput<TQuery>,\n Awaited<TResponse>,\n InferHeadersOutput<THeaders>,\n EndpointErrorContracts<TErrors>,\n InferBodyInput<TBody>\n>;\n\ntype AnyEndpointOptions = EndpointOptions<\n AnySchema,\n AnySchema,\n AnySchema,\n readonly AnyEndpointMiddleware[],\n EndpointErrorDefinitions\n>;\ntype EndpointBodyFromOptions<TOptions> = TOptions extends {\n body: infer TBody extends AnySchema;\n}\n ? TBody\n : never;\ntype EndpointQueryFromOptions<TOptions> = TOptions extends {\n query: infer TQuery extends AnySchema;\n}\n ? TQuery\n : never;\ntype EndpointHeadersFromOptions<TOptions> = TOptions extends {\n headers: infer THeaders extends AnySchema;\n}\n ? THeaders\n : never;\ntype EndpointMiddlewaresFromOptions<TOptions> = TOptions extends {\n middleware: infer TMiddlewares extends readonly AnyEndpointMiddleware[];\n}\n ? TMiddlewares\n : readonly [];\ntype EndpointErrorsFromOptions<TOptions> = TOptions extends {\n errors: infer TErrors extends EndpointErrorDefinitions;\n}\n ? TErrors\n : {};\ntype MethodlessEndpointOptions = Omit<AnyEndpointOptions, \"method\">;\ntype EndpointHandlerFromOptions<TOptions, TResponse> = EndpointHandler<\n EndpointBodyFromOptions<TOptions>,\n EndpointQueryFromOptions<TOptions>,\n EndpointHeadersFromOptions<TOptions>,\n TResponse,\n InferEndpointMiddlewareContext<EndpointMiddlewaresFromOptions<TOptions>>,\n EndpointErrorsFromOptions<TOptions>\n>;\ntype ValidatedEndpointHandlerFromOptions<TOptions, TResponse> = EndpointHandlerFromOptions<\n TOptions,\n TResponse\n> &\n (EndpointMiddlewaresFromOptions<TOptions> extends ValidateEndpointMiddlewares<\n EndpointMiddlewaresFromOptions<TOptions>\n >\n ? unknown\n : never);\ntype CreatedEndpointFromOptions<TOptions, TResponse> = CreatedEndpoint<\n EndpointBodyFromOptions<TOptions>,\n EndpointQueryFromOptions<TOptions>,\n EndpointHeadersFromOptions<TOptions>,\n TResponse,\n EndpointErrorsFromOptions<TOptions>\n>;\n\n/**\n * Create a Farm.js API endpoint\n *\n * Supports two patterns:\n * 1. File-based routing (path auto-inferred from file location):\n * `export const POST = createEndpoint({ method: 'POST', body: schema }, handler)`\n * `createEndpoint({ method: 'GET', query: z.object({...}) }, handler)`\n *\n * 2. Explicit path (for routes.ts at project root):\n * `createEndpoint('/api/hello', { method: 'GET', query: z.object({...}) }, handler)`\n */\nexport function createEndpoint<const TOptions extends AnyEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function createEndpoint<const TOptions extends AnyEndpointOptions, TResponse = any>(\n path: string,\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function createEndpoint<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: EndpointOptions<TBody, TQuery, THeaders, readonly []>,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function createEndpoint<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n path: string,\n options: EndpointOptions<TBody, TQuery, THeaders, readonly []>,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function createEndpoint(\n pathOrOptions:\n | string\n | EndpointOptions<any, any, any, readonly AnyEndpointMiddleware[], EndpointErrorDefinitions>,\n optionsOrHandler:\n | EndpointOptions<any, any, any, readonly AnyEndpointMiddleware[], EndpointErrorDefinitions>\n | EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n maybeHandler?: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n): TypedEndpoint<any, any, any, any> {\n // Determine if first arg is path or options\n let path: string;\n let options: EndpointOptions<\n any,\n any,\n any,\n readonly AnyEndpointMiddleware[],\n EndpointErrorDefinitions\n >;\n let handler: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>;\n\n if (typeof pathOrOptions === \"string\") {\n // createEndpoint('/path', options, handler)\n path = pathOrOptions;\n options = optionsOrHandler as typeof options;\n handler = maybeHandler as typeof handler;\n } else {\n // createEndpoint(options, handler) - path will be set by API plugin from file location\n path = \"\";\n options = pathOrOptions;\n handler = optionsOrHandler as typeof handler;\n }\n\n if (typeof handler !== \"function\") {\n throw new TypeError(\"createEndpoint requires a handler function\");\n }\n\n const middleware = normalizeEndpointMiddleware(options.middleware);\n const errors = normalizeEndpointErrors(options.errors);\n const fail = createEndpointFail(errors);\n const wrappedHandler = (async (ctx: EndpointMiddlewareContext<any, any, any, any>) => {\n const execution = await runEndpointMiddleware(\n middleware,\n ctx,\n handler,\n fail,\n options.invalidates,\n );\n return execution.result;\n }) as typeof handler;\n const {\n middleware: _middleware,\n errors: _errors,\n invalidates: _invalidates,\n ...betterCallOptions\n } = options;\n\n // Create the endpoint - path will be set later by API plugin if not provided\n // We use a temporary path that will be replaced when the router is created\n const endpoint = betterCallEndpoint(\n path || \"/__farm_auto_path__\",\n betterCallOptions as any,\n wrappedHandler as any,\n ) as any;\n\n // Store the path and type information on the endpoint for later access\n // Empty/undefined path means it will be inferred from file location by the API plugin\n endpoint.__path = path || undefined;\n endpoint.__method = options.method || \"GET\";\n endpoint.__autoPath = !path; // Flag to indicate path should be auto-inferred\n endpoint.__handler = wrappedHandler; // Used by Farm's route runtime.\n endpoint.__farmInvoke = (ctx: EndpointMiddlewareContext<any, any, any, any>) =>\n runEndpointMiddleware(middleware, ctx, handler, fail, options.invalidates);\n endpoint.__middleware = middleware;\n endpoint.__sourceHandler = handler;\n endpoint.__invalidates = options.invalidates;\n endpoint.__errors = errors;\n\n // Store type information for inference\n endpoint.__types = {\n body: options.body,\n inputBody: isMultipartSchema(options.body) ? \"form-data\" : options.body,\n query: options.query,\n headers: options.headers,\n response: null as any,\n errors,\n };\n\n return endpoint as any;\n}\n\nconst EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]) as readonly AnyEndpointMiddleware[];\nconst EMPTY_ENDPOINT_CONTEXT = Object.freeze(Object.create(null)) as Readonly<\n Record<string | symbol, unknown>\n>;\nconst UNSAFE_ENDPOINT_CONTEXT_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nfunction normalizeEndpointErrors(\n definitions: EndpointErrorDefinitions | undefined,\n): Readonly<EndpointErrorDefinitions> {\n if (definitions === undefined) return Object.freeze({});\n if (!isPlainEndpointContext(definitions)) {\n throw new TypeError(\"createEndpoint errors must be an object\");\n }\n\n const normalized: EndpointErrorDefinitions = Object.create(null);\n for (const [code, definition] of Object.entries(definitions)) {\n if (!code.trim()) {\n throw new TypeError(\"Endpoint error codes cannot be empty\");\n }\n if (!definition || typeof definition !== \"object\") {\n throw new TypeError(`Endpoint error \"${code}\" must be an object`);\n }\n if (\n !Number.isInteger(definition.status) ||\n definition.status < 400 ||\n definition.status > 599\n ) {\n throw new TypeError(`Endpoint error \"${code}\" status must be an integer between 400 and 599`);\n }\n if (!definition.schema || typeof definition.schema.parse !== \"function\") {\n throw new TypeError(`Endpoint error \"${code}\" requires a schema with parse()`);\n }\n if (definition.message !== undefined && typeof definition.message !== \"string\") {\n throw new TypeError(`Endpoint error \"${code}\" message must be a string`);\n }\n\n normalized[code] = Object.freeze({ ...definition });\n }\n\n return Object.freeze(normalized);\n}\n\nfunction createEndpointFail(\n definitions: Readonly<EndpointErrorDefinitions>,\n): EndpointFail<EndpointErrorDefinitions> {\n return ((code: string, data: unknown): never => {\n const definition = definitions[code];\n if (!definition) {\n throw new TypeError(`Endpoint error \"${code}\" is not declared`);\n }\n\n const parsed = definition.schema.parse!(data);\n throw new EndpointFailure(code, parsed, {\n status: definition.status,\n message: definition.message ?? \"Request failed\",\n });\n }) as EndpointFail<EndpointErrorDefinitions>;\n}\n\nfunction normalizeEndpointMiddleware(\n middleware: readonly AnyEndpointMiddleware[] | undefined,\n): readonly AnyEndpointMiddleware[] {\n if (middleware === undefined) return EMPTY_ENDPOINT_MIDDLEWARE;\n if (!Array.isArray(middleware)) {\n throw new TypeError(\"createEndpoint middleware must be an array of functions\");\n }\n\n const normalized = [...middleware];\n for (const entry of normalized) {\n if (typeof entry !== \"function\") {\n throw new TypeError(\"createEndpoint middleware entries must be functions\");\n }\n }\n\n return Object.freeze(normalized);\n}\n\nasync function runEndpointMiddleware(\n middleware: readonly AnyEndpointMiddleware[],\n handlerContext: EndpointMiddlewareContext<any, any, any, any>,\n handler: EndpointHandler<any, any, any, any, any, EndpointErrorDefinitions>,\n fail: EndpointFail<EndpointErrorDefinitions>,\n invalidations: EndpointInvalidations<any, any, any, any> | undefined,\n): Promise<{\n result: unknown;\n context: Readonly<Record<string | symbol, unknown>>;\n handlerExecuted: boolean;\n invalidations: readonly string[];\n}> {\n let context = createInitialEndpointContext(handlerContext.context);\n\n for (let index = 0; index < middleware.length; index++) {\n const result = await middleware[index]({ ...handlerContext, context });\n\n if (isEndpointResponse(result)) {\n return {\n result,\n context,\n handlerExecuted: false,\n invalidations: [],\n };\n }\n if (result === false) {\n return {\n result: forbiddenEndpointResponse(),\n context,\n handlerExecuted: false,\n invalidations: [],\n };\n }\n if (result === true) continue;\n\n if (!isPlainEndpointContext(result)) {\n throw new TypeError(\n `Endpoint middleware ${index + 1} must return an object, true, false, or a Response`,\n );\n }\n\n context = mergeEndpointContext(context, result, index);\n }\n\n const result = await handler({ ...handlerContext, context, fail });\n return {\n result,\n context,\n handlerExecuted: true,\n invalidations: await applyEndpointInvalidations(\n invalidations,\n {\n ...handlerContext,\n context,\n result,\n },\n result,\n ),\n };\n}\n\nasync function applyEndpointInvalidations(\n declaration: EndpointInvalidations<any, any, any, any> | undefined,\n context: EndpointInvalidationContext<any, any, any, any>,\n result: unknown,\n): Promise<readonly string[]> {\n if (!declaration || (isEndpointResponse(result) && result.status >= 400)) {\n return [];\n }\n\n const targets = typeof declaration === \"function\" ? await declaration(context) : declaration;\n if (!Array.isArray(targets)) {\n throw new TypeError(\n \"Endpoint invalidates must resolve to an array of { key }, { path }, or { tag } targets\",\n );\n }\n\n return applyFarmCacheInvalidationTargets(targets);\n}\n\nfunction createInitialEndpointContext(value: unknown) {\n if (value === undefined || value === null) return EMPTY_ENDPOINT_CONTEXT;\n if (!isPlainEndpointContext(value)) {\n throw new TypeError(\"Endpoint context must be a plain object\");\n }\n\n return mergeEndpointContext(EMPTY_ENDPOINT_CONTEXT, value);\n}\n\nfunction mergeEndpointContext(\n current: Readonly<Record<string | symbol, unknown>>,\n added: object,\n middlewareIndex?: number,\n) {\n const next = Object.assign(Object.create(null), current) as Record<string | symbol, unknown>;\n\n for (const key of Reflect.ownKeys(added)) {\n if (!Object.prototype.propertyIsEnumerable.call(added, key)) continue;\n if (typeof key === \"string\" && UNSAFE_ENDPOINT_CONTEXT_KEYS.has(key)) {\n throw new TypeError(`Endpoint middleware cannot provide the unsafe context key \"${key}\"`);\n }\n if (Object.prototype.hasOwnProperty.call(current, key)) {\n const source =\n middlewareIndex === undefined\n ? \"Endpoint context\"\n : `Endpoint middleware ${middlewareIndex + 1}`;\n throw new TypeError(`${source} cannot replace the existing context key \"${String(key)}\"`);\n }\n next[key] = (added as Record<string | symbol, unknown>)[key];\n }\n\n return Object.freeze(next);\n}\n\nfunction isPlainEndpointContext(value: unknown): value is object {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isEndpointResponse(value: unknown): value is Response {\n return (\n value instanceof Response ||\n (typeof value === \"object\" &&\n value !== null &&\n \"headers\" in value &&\n \"status\" in value &&\n typeof (value as Response).arrayBuffer === \"function\")\n );\n}\n\nfunction forbiddenEndpointResponse() {\n return new Response(JSON.stringify({ error: \"Forbidden\" }), {\n status: 403,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\n/**\n * Convenience method for GET requests\n */\nexport function GET<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function GET<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function GET<\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<never, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<never, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<never, TQuery, THeaders, TResponse>;\nexport function GET(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"GET\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"GET\" }, args[1]);\n}\n\n/**\n * Convenience method for HEAD requests\n */\nexport function HEAD<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function HEAD<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function HEAD<\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<never, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<never, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<never, TQuery, THeaders, TResponse>;\nexport function HEAD(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"HEAD\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"HEAD\" }, args[1]);\n}\n\n/**\n * Convenience method for POST requests\n */\nexport function POST<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function POST<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function POST<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function POST(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"POST\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"POST\" }, args[1]);\n}\n\n/**\n * Convenience method for PUT requests\n */\nexport function PUT<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function PUT<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function PUT<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function PUT(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"PUT\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"PUT\" }, args[1]);\n}\n\n/**\n * Convenience method for DELETE requests\n */\nexport function DELETE<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function DELETE<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function DELETE<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function DELETE(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"DELETE\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"DELETE\" }, args[1]);\n}\n\n/**\n * Convenience method for PATCH requests\n */\nexport function PATCH<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function PATCH<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function PATCH<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function PATCH(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"PATCH\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"PATCH\" }, args[1]);\n}\n\n/**\n * Convenience method for OPTIONS requests\n */\nexport function OPTIONS<T = any>(\n handler: EndpointHandler<never, never, never, T>,\n): CreatedEndpoint<never, never, never, T>;\nexport function OPTIONS<const TOptions extends MethodlessEndpointOptions, TResponse = any>(\n options: TOptions,\n handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>,\n): CreatedEndpointFromOptions<TOptions, TResponse>;\nexport function OPTIONS<\n TBody extends AnySchema = never,\n TQuery extends AnySchema = never,\n THeaders extends AnySchema = never,\n TResponse = any,\n>(\n options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, \"method\">,\n handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>,\n): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;\nexport function OPTIONS(...args: any[]): any {\n if (args.length === 1) {\n return createEndpoint(\"\", { method: \"OPTIONS\" }, args[0]);\n }\n return createEndpoint(\"\", { ...args[0], method: \"OPTIONS\" }, args[1]);\n}\n","import { _runWithCurrentRequest } from \"../server/request\";\nimport {\n decodeFarmCacheInvalidations,\n encodeFarmCacheInvalidations,\n FARM_CACHE_INVALIDATION_HEADER,\n} from \"../cache-invalidation\";\nimport { isEndpointFailure, type EndpointFailure } from \"./endpoint\";\n\nexport type APIRouteParamValue = string | string[];\nexport type APIRouteParams = Record<string, APIRouteParamValue>;\n\nexport interface APIRouteMatch<T extends { path: string }> {\n route: T;\n params: APIRouteParams;\n}\n\nexport function matchAPIRoute<T extends { path: string }>(\n routes: Map<string, T>,\n pathname: string,\n): APIRouteMatch<T> | null {\n const exactRoute = routes.get(pathname);\n if (exactRoute) {\n return { route: exactRoute, params: {} };\n }\n\n const normalizedPathname = normalizePathname(pathname);\n if (normalizedPathname !== pathname) {\n const normalizedRoute = routes.get(normalizedPathname);\n if (normalizedRoute) {\n return { route: normalizedRoute, params: {} };\n }\n }\n\n for (const route of routes.values()) {\n const params = matchRoutePath(route.path, pathname);\n if (params) {\n return { route, params };\n }\n }\n\n return null;\n}\n\nexport async function invokeAPIRouteEndpoint(\n endpoint: any,\n request: Request,\n params: APIRouteParams = {},\n): Promise<Response> {\n return _runWithCurrentRequest(request, () =>\n invokeAPIRouteEndpointInContext(endpoint, request, params),\n );\n}\n\nasync function invokeAPIRouteEndpointInContext(\n endpoint: any,\n request: Request,\n params: APIRouteParams,\n): Promise<Response> {\n const farmHandler = endpoint.__handler || (isFarmContextHandler(endpoint) ? endpoint : null);\n\n if (!farmHandler) {\n const result = await endpoint(request, {\n params: Promise.resolve(params),\n });\n return normalizeRouteResponse(result);\n }\n\n const url = new URL(request.url);\n const query: Record<string, string> = {};\n url.searchParams.forEach((value, key) => {\n query[key] = value;\n });\n\n let body: any = undefined;\n if (request.method.toUpperCase() !== \"GET\" && request.method.toUpperCase() !== \"HEAD\") {\n body = await readRequestBody(request);\n }\n\n const headers = Object.fromEntries(request.headers.entries());\n const types = endpoint.__types || {};\n\n const queryValidation = validateInput(types.query, query, \"Invalid query parameters\");\n if (queryValidation instanceof Response) {\n return queryValidation;\n }\n\n const bodyValidation = validateInput(types.body, body, \"Invalid request body\");\n if (bodyValidation instanceof Response) {\n return bodyValidation;\n }\n\n const headersValidation = validateInput(types.headers, headers, \"Invalid request headers\");\n if (headersValidation instanceof Response) {\n return headersValidation;\n }\n\n const handlerContext = {\n query: queryValidation,\n body: bodyValidation,\n headers: headersValidation,\n request,\n context: {},\n params,\n };\n let execution: {\n result: unknown;\n context: unknown;\n handlerExecuted: boolean;\n invalidations: readonly string[];\n };\n try {\n execution =\n typeof endpoint.__farmInvoke === \"function\"\n ? await endpoint.__farmInvoke(handlerContext)\n : {\n result: await farmHandler(handlerContext),\n context: handlerContext.context,\n handlerExecuted: true,\n invalidations: [],\n };\n } catch (error) {\n if (isEndpointFailure(error)) {\n return createEndpointFailureResponse(error);\n }\n throw error;\n }\n\n const response = normalizeRouteResponse(execution.result);\n return attachEndpointInvalidations(response, execution.invalidations);\n}\n\nexport function normalizeRouteResponse(result: unknown): Response {\n if (isWebResponse(result)) {\n return result;\n }\n\n if (result === undefined) {\n return new Response(null, { status: 204 });\n }\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nexport function isWebResponse(value: unknown): value is Response {\n return (\n value instanceof Response ||\n (typeof value === \"object\" &&\n value !== null &&\n \"headers\" in value &&\n \"status\" in value &&\n typeof (value as Response).arrayBuffer === \"function\")\n );\n}\n\nfunction attachEndpointInvalidations(response: Response, keys: readonly string[]): Response {\n const existing = decodeFarmCacheInvalidations(\n response.headers.get(FARM_CACHE_INVALIDATION_HEADER),\n );\n const encoded = encodeFarmCacheInvalidations([...existing, ...keys]);\n if (!encoded) return response;\n\n const headers = new Headers(response.headers);\n headers.set(FARM_CACHE_INVALIDATION_HEADER, encoded);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nexport function createEndpointFailureResponse(failure: EndpointFailure<string, unknown>): Response {\n return new Response(\n JSON.stringify({\n error: {\n code: failure.code,\n message: failure.message,\n data: failure.data,\n },\n }),\n {\n status: failure.status,\n headers: {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json\",\n },\n },\n );\n}\n\nfunction isFarmContextHandler(endpoint: unknown): boolean {\n if (typeof endpoint !== \"function\") {\n return false;\n }\n\n const source = Function.prototype.toString.call(endpoint).trim();\n const arrowMatch = source.match(/^(?:async\\s*)?(?:\\(([^)]*)\\)|([A-Za-z_$][\\w$]*))\\s*=>/);\n const functionMatch = source.match(/^(?:async\\s*)?function[^(]*\\(([^)]*)\\)/);\n const firstParameter = (arrowMatch?.[1] || arrowMatch?.[2] || functionMatch?.[1] || \"\")\n .split(\",\")[0]\n .trim();\n\n return firstParameter === \"ctx\" || firstParameter === \"context\" || firstParameter.startsWith(\"{\");\n}\n\nasync function readRequestBody(request: Request): Promise<unknown> {\n const contentType = request.headers.get(\"content-type\")?.split(\";\", 1)[0]?.trim().toLowerCase();\n\n try {\n if (contentType === \"multipart/form-data\") {\n return formDataToObject(await request.clone().formData());\n }\n\n const text = await request.clone().text();\n if (!text) return undefined;\n if (contentType === \"application/x-www-form-urlencoded\") {\n return searchParamsToObject(new URLSearchParams(text));\n }\n if (contentType === \"application/json\" || contentType?.endsWith(\"+json\")) {\n return JSON.parse(text);\n }\n\n // Preserve the previous permissive behavior for callers that omit the\n // content type but still send JSON.\n return JSON.parse(text);\n } catch {\n // The body format is unsupported or malformed. Schema validation below\n // will turn the missing value into a typed 400 response when applicable.\n }\n\n return undefined;\n}\n\nfunction formDataToObject(\n formData: FormData,\n): Record<string, FormDataEntryValue | FormDataEntryValue[]> {\n return entriesToObject(formData.entries());\n}\n\nfunction searchParamsToObject(searchParams: URLSearchParams): Record<string, string | string[]> {\n return entriesToObject(searchParams.entries());\n}\n\nfunction entriesToObject<TValue>(\n entries: IterableIterator<[string, TValue]>,\n): Record<string, TValue | TValue[]> {\n const output: Record<string, TValue | TValue[]> = Object.create(null);\n for (const [key, value] of entries) {\n if (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") continue;\n const current = output[key];\n if (current === undefined) {\n output[key] = value;\n } else if (Array.isArray(current)) {\n current.push(value);\n } else {\n output[key] = [current, value];\n }\n }\n return output;\n}\n\nfunction validateInput(schema: any, value: unknown, error: string): unknown | Response {\n if (!schema || typeof schema.parse !== \"function\") {\n return value;\n }\n\n try {\n return schema.parse(value);\n } catch (validationError: any) {\n return new Response(\n JSON.stringify({\n error,\n details: validationError.errors || validationError.issues || validationError.message,\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nfunction matchRoutePath(routePath: string, pathname: string): APIRouteParams | null {\n const routeSegments = getPathSegments(routePath);\n const pathnameSegments = getPathSegments(pathname);\n const params: APIRouteParams = {};\n let pathIndex = 0;\n\n for (const routeSegment of routeSegments) {\n const dynamicSegment = parseDynamicSegment(routeSegment);\n\n if (dynamicSegment?.catchAll) {\n const remainingSegments = pathnameSegments.slice(pathIndex).map(decodePathSegment);\n if (remainingSegments.length === 0 && !dynamicSegment.optional) {\n return null;\n }\n if (remainingSegments.length > 0) {\n params[dynamicSegment.name] = remainingSegments;\n }\n pathIndex = pathnameSegments.length;\n continue;\n }\n\n const pathnameSegment = pathnameSegments[pathIndex];\n if (pathnameSegment === undefined) {\n return null;\n }\n\n if (dynamicSegment) {\n params[dynamicSegment.name] = decodePathSegment(pathnameSegment);\n pathIndex++;\n continue;\n }\n\n if (routeSegment !== pathnameSegment) {\n return null;\n }\n\n pathIndex++;\n }\n\n return pathIndex === pathnameSegments.length ? params : null;\n}\n\nfunction getPathSegments(pathname: string): string[] {\n return normalizePathname(pathname)\n .split(\"/\")\n .filter((segment) => segment.length > 0);\n}\n\nfunction normalizePathname(pathname: string): string {\n if (pathname.length > 1 && pathname.endsWith(\"/\")) {\n return pathname.replace(/\\/+$/, \"\");\n }\n\n return pathname;\n}\n\nfunction parseDynamicSegment(\n segment: string,\n): { name: string; catchAll: boolean; optional: boolean } | null {\n const optionalCatchAll = segment.match(/^\\[\\[\\.\\.\\.(.+)\\]\\]$/);\n if (optionalCatchAll?.[1]) {\n return { name: optionalCatchAll[1], catchAll: true, optional: true };\n }\n\n const catchAll = segment.match(/^\\[\\.\\.\\.(.+)\\]$/);\n if (catchAll?.[1]) {\n return { name: catchAll[1], catchAll: true, optional: false };\n }\n\n const dynamic = segment.match(/^\\[(.+)\\]$/);\n if (dynamic?.[1]) {\n return { name: dynamic[1], catchAll: false, optional: false };\n }\n\n return null;\n}\n\nfunction decodePathSegment(segment: string): string {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n}\n"],"mappings":"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","names":["path","path","import_node_async_hooks","getRequestStore"]}