{"version":3,"file":"index.cjs","names":["NextResponse"],"sources":["../../../src/appRouter/config.ts","../../../src/appRouter/proxy/languageDetector.ts","../../../src/appRouter/proxy/index.ts"],"sourcesContent":["import type { I18nConfig, NormalizedConfig } from './types'\n\nexport function defineConfig(config: I18nConfig): I18nConfig {\n  return config\n}\n\nexport function normalizeConfig(userConfig: I18nConfig): NormalizedConfig {\n  // Support legacy format: { i18n: { defaultLocale, locales } }\n  const supportedLngs = userConfig.supportedLngs ??\n    userConfig.i18n?.locales?.filter((l: string) => l !== 'default') ??\n    ['en']\n  const fallbackLng = userConfig.fallbackLng ??\n    userConfig.i18n?.defaultLocale ??\n    supportedLngs[0]\n\n  if (!fallbackLng) {\n    throw new Error('next-i18next: fallbackLng (or i18n.defaultLocale) is required')\n  }\n  if (supportedLngs.length === 0) {\n    throw new Error('next-i18next: supportedLngs (or i18n.locales) must contain at least one language')\n  }\n\n  const defaultNS = userConfig.defaultNS ?? 'common'\n\n  return {\n    supportedLngs,\n    fallbackLng,\n    defaultNS,\n    ns: userConfig.ns ?? [defaultNS],\n    localeInPath: userConfig.localeInPath ?? true,\n    hideDefaultLocale: userConfig.hideDefaultLocale ?? false,\n    localePath: userConfig.localePath ?? '/locales',\n    localeStructure: userConfig.localeStructure ?? '{{lng}}/{{ns}}',\n    localeExtension: userConfig.localeExtension ?? 'json',\n    cookieName: userConfig.cookieName ?? 'i18next',\n    headerName: userConfig.headerName ?? 'x-i18next-current-language',\n    cookieMaxAge: userConfig.cookieMaxAge ?? 365 * 24 * 60 * 60,\n    ignoredPaths: userConfig.ignoredPaths ?? ['/api', '/_next', '/static'],\n    basePath: userConfig.basePath,\n    resources: userConfig.resources,\n    resourceLoader: userConfig.resourceLoader,\n    use: userConfig.use ?? [],\n    i18nextOptions: (userConfig.i18nextOptions ?? {}) as Record<string, any>,\n    nonExplicitSupportedLngs: userConfig.nonExplicitSupportedLngs ?? false,\n    // Preserve legacy fields\n    i18n: userConfig.i18n,\n    serializeConfig: userConfig.serializeConfig,\n    reloadOnPrerender: userConfig.reloadOnPrerender,\n  }\n}\n","/**\n * Edge-safe Accept-Language parser and language matcher.\n * No external dependencies — runs in Edge Runtime, Node.js, and browser.\n */\n\nexport function parseAcceptLanguage(header: string | null | undefined): string[] {\n  if (!header) return []\n  return header\n    .split(',')\n    .map(part => {\n      const [lang, qPart] = part.trim().split(';')\n      const q = qPart?.trim().startsWith('q=')\n        ? parseFloat(qPart.trim().slice(2))\n        : 1.0\n      return { lang: lang.trim(), q: isNaN(q) ? 0 : q }\n    })\n    .filter(item => item.lang && item.q > 0)\n    .sort((a, b) => b.q - a.q)\n    .map(item => item.lang)\n}\n\n/**\n * Find a matching supported language for a given code, respecting nonExplicitSupportedLngs.\n *\n * Matching order (mirrors i18next's LanguageUtils.getBestMatchFromCodes):\n * 1. Exact match (case-insensitive)\n * 2. Preferred prefix → supported base (e.g. preferred 'en-US' matches supported 'en')\n * 3. If nonExplicitSupportedLngs: preferred base → supported region\n *    (e.g. preferred 'en' matches supported 'en-US')\n */\nexport function findSupportedMatch(\n  code: string,\n  supportedLanguages: readonly string[],\n  nonExplicitSupportedLngs: boolean,\n): string | undefined {\n  const lower = code.toLowerCase()\n\n  // 1. Exact match (case-insensitive)\n  const exact = supportedLanguages.find(l => l.toLowerCase() === lower)\n  if (exact) return exact\n\n  // 2. Preferred prefix → supported base (e.g. 'en-US' → 'en')\n  const prefix = lower.split('-')[0]\n  const partial = supportedLanguages.find(l => l.toLowerCase() === prefix)\n  if (partial) return partial\n\n  // 3. Reverse match: preferred base → supported region (e.g. 'en' → 'en-US')\n  if (nonExplicitSupportedLngs) {\n    const reverse = supportedLanguages.find(\n      l => l.toLowerCase().split('-')[0] === prefix\n    )\n    if (reverse) return reverse\n  }\n\n  return undefined\n}\n\nexport function matchLanguage(\n  acceptLanguages: string[],\n  supportedLanguages: readonly string[],\n  defaultLanguage: string,\n  nonExplicitSupportedLngs = false,\n): string {\n  for (const preferred of acceptLanguages) {\n    const match = findSupportedMatch(preferred, supportedLanguages, nonExplicitSupportedLngs)\n    if (match) return match\n  }\n  return defaultLanguage\n}\n","import { NextRequest, NextResponse } from 'next/server'\nimport type { I18nConfig } from '../types'\nimport { normalizeConfig } from '../config'\nimport { parseAcceptLanguage, matchLanguage, findSupportedMatch } from './languageDetector'\n\n// Re-export config utilities for Edge-safe usage (no react-i18next dependency)\nexport { defineConfig, normalizeConfig } from '../config'\nexport type { I18nConfig, NormalizedConfig, ResourceLoader } from '../types'\n\nfunction findLocaleInPath(\n  pathname: string,\n  supportedLngs: readonly string[],\n  nonExplicitSupportedLngs: boolean,\n): string | undefined {\n  // Extract the first path segment\n  const match = pathname.match(/^\\/([^/]+)/)\n  if (!match) return undefined\n  return findSupportedMatch(match[1], supportedLngs, nonExplicitSupportedLngs)\n}\n\nexport function createProxy(userConfig: I18nConfig) {\n  const config = normalizeConfig(userConfig)\n  const nonExplicit = config.nonExplicitSupportedLngs\n  // Normalize basePath: ensure leading slash, strip trailing slash\n  const basePath = config.basePath\n    ? ('/' + config.basePath.replace(/^\\/+/, '').replace(/\\/+$/, ''))\n    : undefined\n\n  return function middleware(req: NextRequest): NextResponse {\n    const { pathname, search } = req.nextUrl\n\n    // When basePath is set, only handle requests under that prefix\n    if (basePath) {\n      if (pathname !== basePath && !pathname.startsWith(basePath + '/')) {\n        return NextResponse.next()\n      }\n    }\n\n    // Skip ignored paths\n    for (const ignored of config.ignoredPaths) {\n      if (pathname.startsWith(ignored)) {\n        return NextResponse.next()\n      }\n    }\n\n    // Skip common static file extensions\n    if (/\\.(ico|png|jpg|jpeg|svg|gif|webp|css|js|map|woff2?|ttf|eot)$/.test(pathname)) {\n      return NextResponse.next()\n    }\n\n    // Detect language from cookie, then Accept-Language header, then default\n    let lng: string | undefined\n    const cookieValue = req.cookies.get(config.cookieName)?.value\n    if (cookieValue) {\n      lng = matchLanguage([cookieValue], config.supportedLngs, config.fallbackLng, nonExplicit)\n    }\n    if (!lng) {\n      lng = matchLanguage(\n        parseAcceptLanguage(req.headers.get('Accept-Language')),\n        config.supportedLngs,\n        config.fallbackLng,\n        nonExplicit,\n      )\n    }\n    if (!lng) {\n      lng = config.fallbackLng\n    }\n\n    // For locale-in-path detection, strip basePath prefix so we look at the right segment\n    const pathForLocale = basePath ? pathname.slice(basePath.length) || '/' : pathname\n    const lngInPath = findLocaleInPath(pathForLocale, config.supportedLngs, nonExplicit)\n\n    if (config.localeInPath) {\n      const prefix = basePath ?? ''\n      const pathAfterBase = basePath ? pathname.slice(basePath.length) : pathname\n\n      // hideDefaultLocale: redirect explicit default-locale paths to the clean URL\n      if (config.hideDefaultLocale && lngInPath === config.fallbackLng) {\n        const pathWithoutLocale = pathAfterBase.replace(/^\\/[^/]+/, '') || '/'\n        const redirectUrl = new URL(`${prefix}${pathWithoutLocale}${search}`, req.url)\n        const response = NextResponse.redirect(redirectUrl)\n        response.cookies.set(config.cookieName, config.fallbackLng, {\n          path: '/',\n          maxAge: config.cookieMaxAge,\n          sameSite: 'lax',\n        })\n        return response\n      }\n\n      // Set custom header for server components to read\n      const headers = new Headers(req.headers)\n      headers.set(config.headerName, lngInPath || lng)\n\n      // Redirect if no locale in path\n      if (!lngInPath) {\n        if (config.hideDefaultLocale) {\n          // Rewrite internally to the default-locale path, keeping the clean URL\n          const rewriteUrl = new URL(`${prefix}/${config.fallbackLng}${pathAfterBase}${search}`, req.url)\n          headers.set(config.headerName, config.fallbackLng)\n          const response = NextResponse.rewrite(rewriteUrl, { request: { headers } })\n          response.cookies.set(config.cookieName, config.fallbackLng, {\n            path: '/',\n            maxAge: config.cookieMaxAge,\n            sameSite: 'lax',\n          })\n          return response\n        }\n\n        const redirectUrl = new URL(`${prefix}/${lng}${pathAfterBase}${search}`, req.url)\n        const response = NextResponse.redirect(redirectUrl)\n        response.cookies.set(config.cookieName, lng, {\n          path: '/',\n          maxAge: config.cookieMaxAge,\n          sameSite: 'lax',\n        })\n        return response\n      }\n\n      // Persist language from referer URL into cookie\n      const response = NextResponse.next({ request: { headers } })\n      if (req.headers.has('referer')) {\n        const refererUrl = new URL(req.headers.get('referer')!)\n        const refererPathForLocale = basePath\n          ? refererUrl.pathname.slice(basePath.length) || '/'\n          : refererUrl.pathname\n        const lngInReferer = findLocaleInPath(refererPathForLocale, config.supportedLngs, nonExplicit)\n        if (lngInReferer) {\n          response.cookies.set(config.cookieName, lngInReferer, {\n            path: '/',\n            maxAge: config.cookieMaxAge,\n            sameSite: 'lax',\n          })\n        }\n      }\n\n      return response\n    } else {\n      // No-locale-path mode: don't redirect, just set the header\n      const headers = new Headers(req.headers)\n      headers.set(config.headerName, lng)\n\n      const response = NextResponse.next({ request: { headers } })\n      return response\n    }\n  }\n}\n\n/**\n * Backwards-compatible alias for createProxy.\n * Use `createProxy` for new projects with Next.js 16+ `proxy.ts`.\n */\nexport const createMiddleware = createProxy\n"],"mappings":"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"}