{"version":3,"sources":["../src/route-runtime.ts"],"sourcesContent":["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\" | \"metadata\" | \"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"],"mappings":"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","names":[]}