{"version":3,"file":"intlayerProxy.mjs","names":["localeDetector"],"sources":["../../../src/proxy/intlayerProxy.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport { ROUTING_MODE } from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport {\n  getCanonicalPath,\n  getLocalizedPath,\n  getRewriteRules,\n} from '@intlayer/core/localization';\nimport {\n  getLocaleFromStorageServer,\n  setLocaleInStorageServer,\n} from '@intlayer/core/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport {\n  type NextFetchEvent,\n  type NextRequest,\n  NextResponse,\n} from 'next/server';\nimport { localeDetector } from './localeDetector';\n\n/**\n * Controls whether locale detection occurs during Next.js prefetch requests\n * - true: Detect and apply locale during prefetch\n * - false: Use default locale during prefetch (recommended)\n *\n * This setting affects how Next.js handles locale prefetching:\n *\n * Example scenario:\n * - User's browser language is 'fr'\n * - Current page is /fr/about\n * - Link prefetches /about\n *\n * With `detectLocaleOnPrefetchNoPrefix:true`\n * - Prefetch detects 'fr' locale from browser\n * - Redirects prefetch to /fr/about\n *\n * With `detectLocaleOnPrefetchNoPrefix:false` (default)\n * - Prefetch uses default locale\n * - Redirects prefetch to /en/about (assuming 'en' is default)\n *\n * When to use true:\n * - Your app uses non-localized internal links (e.g. <a href=\"/about\">)\n * - You want consistent locale detection behavior between regular and prefetch requests\n *\n * When to use false (default):\n * - Your app uses locale-prefixed links (e.g. <a href=\"/fr/about\">)\n * - You want to optimize prefetching performance\n * - You want to avoid potential redirect loops\n */\nconst DEFAULT_DETECT_LOCALE_ON_PREFETCH_NO_PREFIX = false;\n\nconst { locales, defaultLocale } = internationalization ?? {};\nconst { basePath, mode, rewrite, domains } = routing ?? {};\n\n// Note: cookie names are resolved inside LocaleStorage based on configuration\n\n// Derived flags from routing.mode\nconst effectiveMode = mode ?? ROUTING_MODE;\nconst noPrefix =\n  (!(\n    process.env['INTLAYER_ROUTING_MODE'] &&\n    process.env['INTLAYER_ROUTING_MODE'] !== 'no-prefix'\n  ) &&\n    effectiveMode === 'no-prefix') ||\n  (!(\n    process.env['INTLAYER_ROUTING_MODE'] &&\n    process.env['INTLAYER_ROUTING_MODE'] !== 'search-params'\n  ) &&\n    effectiveMode === 'search-params');\nconst prefixDefault =\n  !(\n    process.env['INTLAYER_ROUTING_MODE'] &&\n    process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n    process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default'\n  ) && effectiveMode === 'prefix-all';\n\nconst internalPrefix = !noPrefix;\n\nconst rewriteRules =\n  process.env['INTLAYER_ROUTING_REWRITE_RULES'] !== 'false'\n    ? getRewriteRules(rewrite, 'url')\n    : undefined;\n\n/**\n * Strips the protocol from a domain string and returns only the hostname.\n * e.g. 'https://intlayer.zh' → 'intlayer.zh', 'intlayer.zh' → 'intlayer.zh'\n */\nconst normalizeDomainHostname = (domain: string): string => {\n  try {\n    return /^https?:\\/\\//.test(domain) ? new URL(domain).hostname : domain;\n  } catch {\n    return domain;\n  }\n};\n\n/**\n * Returns the locale exclusively mapped to a given hostname via `routing.domains`,\n * or undefined if zero or more than one locale share that hostname.\n *\n * Example: with domains = { zh: 'intlayer.zh', fr: 'intlayer.org' }\n *   getLocaleFromDomain('intlayer.zh')  → 'zh'\n *   getLocaleFromDomain('intlayer.org') → undefined  (multiple locales share it)\n */\nconst getLocaleFromDomain = (hostname: string): Locale | undefined => {\n  if (!domains) return undefined;\n  const matching = Object.entries(domains).filter(\n    ([, domain]) => normalizeDomainHostname(domain!) === hostname\n  );\n  return matching.length === 1 ? (matching[0][0] as Locale) : undefined;\n};\n\n/**\n * Detects if the request is a prefetch request from Next.js.\n *\n * Next.js prefetch requests can be identified by several headers:\n * - purpose: 'prefetch' (standard prefetch header)\n * - next-router-prefetch: '1' (Next.js router prefetch)\n * - next-url: present (Next.js internal navigation)\n *\n * During prefetch, we should ignore cookie-based locale detection\n * to prevent unwanted redirects when users are switching locales.\n *\n * @param request - The incoming Next.js request object.\n * @returns - True if the request is a prefetch request, false otherwise.\n */\nconst isPrefetchRequest = (request: NextRequest): boolean => {\n  const purpose = request.headers.get('purpose');\n  const nextRouterPrefetch = request.headers.get('next-router-prefetch');\n  const nextUrl = request.headers.get('next-url');\n  const xNextjsData = request.headers.get('x-nextjs-data');\n\n  return (\n    purpose === 'prefetch' ||\n    nextRouterPrefetch === '1' ||\n    !!nextUrl ||\n    !!xNextjsData\n  );\n};\n\n// Ensure locale is reflected in search params when routing mode is 'search-params'\nconst appendLocaleSearchIfNeeded = (\n  search: string | undefined,\n  locale: Locale\n): string | undefined => {\n  if (\n    (process.env['INTLAYER_ROUTING_MODE'] &&\n      process.env['INTLAYER_ROUTING_MODE'] !== 'search-params') ||\n    effectiveMode !== 'search-params'\n  )\n    return search;\n  const params = new URLSearchParams(search ?? '');\n  params.set('locale', locale);\n  return `?${params.toString()}`;\n};\n\n/**\n * Proxy that handles the internationalization layer\n *\n * Usage:\n *\n * ```ts\n * // ./src/proxy.ts\n *\n * export { intlayerProxy as proxy } from '@intlayer/next/proxy';\n *\n * // applies this proxy only to files in the app directory\n * export const config = {\n *   matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n * Main proxy function for handling internationalization.\n *\n * @param request - The incoming Next.js request object.\n * @param event - The Next.js fetch event (optional).\n * @param response - The Next.js response object (optional).\n * @returns - The response to be returned to the client.\n */\nexport const intlayerProxy = (\n  request: NextRequest,\n  _event?: NextFetchEvent,\n  _response?: NextResponse\n): NextResponse => {\n  const pathname = request.nextUrl.pathname;\n\n  const localLocale = getLocalLocale(request);\n\n  if (noPrefix) {\n    return handleNoPrefix(request, localLocale, pathname);\n  }\n\n  const pathLocale = getPathLocale(pathname);\n\n  // Domain routing: if the path locale is mapped to a different domain, redirect there.\n  // e.g. intlayer.org/zh/about → https://intlayer.zh/about\n  if (\n    process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' &&\n    pathLocale &&\n    domains\n  ) {\n    const localeDomain = domains[pathLocale];\n\n    if (localeDomain) {\n      const domainHost = normalizeDomainHostname(localeDomain);\n\n      if (domainHost !== request.nextUrl.hostname) {\n        const rawPath = pathname.slice(`/${pathLocale}`.length) || '/';\n        const targetOrigin = /^https?:\\/\\//.test(localeDomain)\n          ? localeDomain\n          : `https://${localeDomain}`;\n\n        return NextResponse.redirect(\n          new URL(`${rawPath}${request.nextUrl.search}`, targetOrigin)\n        );\n      }\n    }\n  }\n\n  // Domain routing: if the current hostname is exclusively mapped to one locale,\n  // treat it as that locale's domain — no URL prefix needed.\n  // e.g. intlayer.zh/about → internally rewrite to /zh/about\n  if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && !pathLocale) {\n    const domainLocale = getLocaleFromDomain(request.nextUrl.hostname);\n\n    if (domainLocale) {\n      const canonicalPath = getCanonicalPath(\n        pathname,\n        domainLocale,\n        rewriteRules\n      );\n      const internalPath = `/${domainLocale}${canonicalPath}`;\n\n      return rewriteUrl(\n        request,\n        internalPath + (request.nextUrl.search ?? ''),\n        domainLocale\n      );\n    }\n  }\n\n  return handlePrefix(request, localLocale, pathLocale, pathname);\n};\n\n/**\n * Retrieves the locale from the request cookies if available and valid.\n *\n * @param request - The incoming Next.js request object.\n * @returns - The locale found in the cookies, or undefined if not found or invalid.\n */\nconst getLocalLocale = (request: NextRequest): Locale | undefined =>\n  getLocaleFromStorageServer({\n    getCookie: (name: string) => request.cookies.get(name)?.value ?? null,\n    getHeader: (name: string) => request.headers.get(name) ?? null,\n  });\n\n/**\n * Handles the case where URLs do not have locale prefixes.\n */\nconst handleNoPrefix = (\n  request: NextRequest,\n  localLocale: Locale | undefined,\n  pathname: string\n): NextResponse => {\n  const pathLocale = getPathLocale(pathname);\n\n  if (pathLocale) {\n    const pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/';\n\n    const canonicalPath = getCanonicalPath(\n      pathWithoutLocale,\n      pathLocale,\n      rewriteRules\n    );\n\n    const search = appendLocaleSearchIfNeeded(\n      request.nextUrl.search,\n      pathLocale\n    );\n\n    const redirectPath = search\n      ? `${canonicalPath}${search}`\n      : `${canonicalPath}${request.nextUrl.search ?? ''}`;\n\n    return redirectUrl(request, redirectPath);\n  }\n\n  if (\n    !(\n      process.env['INTLAYER_ROUTING_MODE'] &&\n      process.env['INTLAYER_ROUTING_MODE'] !== 'search-params'\n    ) &&\n    effectiveMode === 'search-params'\n  ) {\n    const existingSearchParams = new URLSearchParams(request.nextUrl.search);\n    const existingLocale = existingSearchParams.get('locale');\n\n    const isExistingValid = locales?.includes(existingLocale as Locale);\n\n    let locale = (localLocale ??\n      (isExistingValid ? (existingLocale as Locale) : undefined) ??\n      localLocale ??\n      localeDetector?.(request) ??\n      defaultLocale) as Locale;\n\n    if (!locales?.includes(locale as Locale)) {\n      locale = defaultLocale as Locale;\n    }\n\n    const canonicalPath = getCanonicalPath(\n      pathname,\n      locale as Locale,\n      rewriteRules\n    );\n\n    if (existingLocale === locale) {\n      const internalPath = internalPrefix\n        ? `/${locale}${canonicalPath}`\n        : canonicalPath;\n      const rewritePath = `${internalPath}${request.nextUrl.search ?? ''}`;\n      return rewriteUrl(request, rewritePath, locale as Locale);\n    }\n\n    const search = appendLocaleSearchIfNeeded(\n      request.nextUrl.search,\n      locale as Locale\n    );\n    // Use original pathname for redirect to preserve user's URL input, just adding params\n    const redirectPath = search\n      ? `${pathname}${search}`\n      : `${pathname}${request.nextUrl.search ?? ''}`;\n\n    return redirectUrl(request, redirectPath);\n  }\n\n  // effectiveMode === 'no-prefix'\n  let locale = (localLocale ??\n    localeDetector?.(request) ??\n    defaultLocale) as Locale;\n\n  if (!locales?.includes(locale as Locale)) {\n    locale = defaultLocale as Locale;\n  }\n\n  const canonicalPath = getCanonicalPath(\n    pathname,\n    locale as Locale,\n    rewriteRules\n  );\n\n  const internalPath = internalPrefix\n    ? `/${locale}${canonicalPath}`\n    : canonicalPath;\n  const search = appendLocaleSearchIfNeeded(\n    request.nextUrl.search,\n    locale as Locale\n  );\n  const rewritePath = search\n    ? `${internalPath}${search}`\n    : `${internalPath}${request.nextUrl.search ?? ''}`;\n\n  return rewriteUrl(request, rewritePath, locale as Locale);\n};\n\n/**\n * Extracts the locale from the URL pathname if present.\n *\n * @param pathname - The pathname from the request URL.\n * @returns - The locale found in the pathname, or undefined if not found.\n */\nconst getPathLocale = (pathname: string): Locale | undefined =>\n  (locales as Locale[]).find(\n    (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`\n  );\n\n/**\n * Handles the case where URLs have locale prefixes.\n *\n * @param request - The incoming Next.js request object.\n * @param localLocale - The locale from the cookie.\n * @param pathLocale - The locale extracted from the pathname.\n * @param pathname - The pathname from the request URL.\n * @param basePathTrailingSlash - Indicates if the basePath ends with a slash.\n * @returns - The response to be returned to the client.\n */\nconst handlePrefix = (\n  request: NextRequest,\n  localLocale: Locale | undefined,\n  pathLocale: Locale | undefined,\n  pathname: string\n): NextResponse => {\n  if (!pathLocale) {\n    const isPrefetch = isPrefetchRequest(request);\n    if (isPrefetch && !DEFAULT_DETECT_LOCALE_ON_PREFETCH_NO_PREFIX) {\n      return handleMissingPathLocale(\n        request,\n        defaultLocale as Locale,\n        pathname\n      );\n    }\n    return handleMissingPathLocale(request, localLocale, pathname);\n  }\n\n  return handleExistingPathLocale(request, pathLocale, pathname);\n};\n\n/**\n * Handles requests where the locale is missing from the URL pathname.\n *\n * @param request - The incoming Next.js request object.\n * @param localLocale - The locale from the cookie.\n * @param pathname - The pathname from the request URL.\n * @param basePathTrailingSlash - Indicates if the basePath ends with a slash.\n * @returns - The response to be returned to the client.\n */\nconst handleMissingPathLocale = (\n  request: NextRequest,\n  localLocale: Locale | undefined,\n  pathname: string\n): NextResponse => {\n  let locale = (localLocale ??\n    localeDetector?.(request) ??\n    defaultLocale) as Locale;\n\n  if (!(locales as Locale[]).includes(locale)) {\n    locale = defaultLocale as Locale;\n  }\n\n  // Resolve to canonical path.\n  // If user visits /a-propos (implied 'fr'), we resolve to /about\n  const canonicalPath = getCanonicalPath(pathname, locale, rewriteRules);\n\n  // Determine target localized path for redirection\n  // /about + 'fr' -> /a-propos\n  const targetLocalizedPathResult = getLocalizedPath(\n    canonicalPath,\n    locale,\n    rewriteRules\n  );\n  const targetLocalizedPath =\n    typeof targetLocalizedPathResult === 'string'\n      ? targetLocalizedPathResult\n      : targetLocalizedPathResult.path;\n\n  const newPath = constructPath(\n    locale,\n    targetLocalizedPath,\n    basePath as string,\n    appendLocaleSearchIfNeeded(request.nextUrl.search, locale)\n  );\n\n  return prefixDefault || locale !== defaultLocale\n    ? redirectUrl(request, newPath)\n    : rewriteUrl(\n        request,\n        internalPrefix ? `/${locale}${canonicalPath}` : canonicalPath,\n        locale\n      ); // Rewrite must use Canonical\n};\n\n/**\n * Handles requests where the locale exists in the URL pathname.\n *\n * @param request - The incoming Next.js request object.\n * @param localLocale - The locale from the cookie.\n * @param pathLocale - The locale extracted from the pathname.\n * @param pathname - The pathname from the request URL.\n * @returns - The response to be returned to the client.\n */\nconst handleExistingPathLocale = (\n  request: NextRequest,\n  pathLocale: Locale,\n  pathname: string\n): NextResponse => {\n  const rawPath = pathname.slice(`/${pathLocale}`.length) || '/';\n\n  // 1. Identify the Canonical Path (Internal Next.js path)\n  // Ex: /a-propos (from URL) -> /about (Canonical)\n  const canonicalPath = getCanonicalPath(rawPath, pathLocale, rewriteRules);\n\n  // By skipping the forced localLocale check, we allow the explicit pathLocale\n  // to take precedence, which correctly updates the header/cookie when navigating.\n\n  // Rewrite Logic\n  // We must rewrite to the Next.js internal structure: /[locale]/[canonicalPath]\n  // Ex: Rewrite /fr/a-propos -> /fr/about\n\n  // 2. Redirect to localized path if needed (Canonical -> Localized)\n  // Ex: /fr/about -> /fr/a-propos\n  const targetLocalizedPathResult = getLocalizedPath(\n    canonicalPath,\n    pathLocale,\n    rewriteRules\n  );\n  const targetLocalizedPath =\n    typeof targetLocalizedPathResult === 'string'\n      ? targetLocalizedPathResult\n      : targetLocalizedPathResult.path;\n  const isRewritten =\n    typeof targetLocalizedPathResult === 'string'\n      ? false\n      : targetLocalizedPathResult.isRewritten;\n\n  if (isRewritten && targetLocalizedPath !== rawPath) {\n    const newPath = constructPath(\n      pathLocale,\n      targetLocalizedPath,\n      basePath as string,\n      appendLocaleSearchIfNeeded(request.nextUrl.search, pathLocale)\n    );\n    return redirectUrl(request, newPath);\n  }\n\n  const internalUrl = internalPrefix\n    ? `/${pathLocale}${canonicalPath}`\n    : canonicalPath;\n\n  // Only handle redirect if we are strictly managing default locale prefixing\n  // Fix: pass `canonicalPath` (the path *without* the locale prefix, e.g. /pricing)\n  // instead of `pathname` (the full path including prefix, e.g. /en/pricing).\n  // Previously this caused an infinite redirect loop in prefix-no-default mode\n  // because handleDefaultLocaleRedirect built the redirect target from its third\n  // argument, which reproduced the same URL on every response.\n  if (!prefixDefault && pathLocale === defaultLocale) {\n    return handleDefaultLocaleRedirect(request, pathLocale, canonicalPath);\n  }\n\n  const search = request.nextUrl.search;\n  return rewriteUrl(request, internalUrl + (search ?? ''), pathLocale);\n};\n\n/**\n * Handles the scenario where the locale in the cookie does not match the locale in the URL pathname.\n *\n * @param request - The incoming Next.js request object.\n * @param pathname - The pathname from the request URL.\n * @param pathLocale - The locale extracted from the pathname.\n * @param localLocale - The locale from the cookie.\n * @param basePath - The base path of the application.\n * @returns - The new URL path with the correct locale.\n */\n// Function handleCookieLocaleMismatch was removed because the URL locale should take precedence over the stored locale.\n\n/**\n * The key fix for 404s without [locale] folders\n */\nconst handleDefaultLocaleRedirect = (\n  request: NextRequest,\n  pathLocale: Locale,\n  canonicalPath: string // Internal path (e.g. /about)\n): NextResponse => {\n  if (!prefixDefault && pathLocale === defaultLocale) {\n    // Redirect to remove prefix\n    // We use canonicalPath because in no-prefix default mode, the URL is usually just the path\n    // But wait, if we are in this function, the URL *has* a prefix.\n    // We want to redirect to /about (localized for EN).\n\n    const targetLocalizedPathResult = getLocalizedPath(\n      canonicalPath,\n      pathLocale,\n      rewriteRules\n    );\n    const targetLocalizedPath =\n      typeof targetLocalizedPathResult === 'string'\n        ? targetLocalizedPathResult\n        : targetLocalizedPathResult.path;\n\n    // Construct path without prefix\n    const basePathTrailingSlash = (basePath as string).endsWith('/');\n    let finalPath = targetLocalizedPath;\n    if (finalPath.startsWith('/')) finalPath = finalPath.slice(1);\n\n    const fullPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${finalPath}`;\n\n    const searchWithLocale = appendLocaleSearchIfNeeded(\n      request.nextUrl.search,\n      pathLocale\n    );\n\n    return redirectUrl(\n      request,\n      fullPath + (searchWithLocale ?? request.nextUrl.search ?? '')\n    );\n  }\n\n  const searchWithLocale = appendLocaleSearchIfNeeded(\n    request.nextUrl.search,\n    pathLocale\n  );\n\n  // If no redirect needed, we rewrite to the internal canonical path\n  const internalPath = internalPrefix\n    ? `/${pathLocale}${canonicalPath}`\n    : canonicalPath;\n\n  const rewriteTarget = searchWithLocale\n    ? `${internalPath}${searchWithLocale}`\n    : `${internalPath}${request.nextUrl.search ?? ''}`;\n\n  return rewriteUrl(request, rewriteTarget, pathLocale);\n};\n\n/**\n * Constructs a new path by combining the locale, path, basePath, and search parameters.\n *\n * @param locale - The locale to include in the path.\n * @param path - The original path from the request.\n * @param basePath - The base path of the application.\n * @param [search] - The query string from the request URL (optional).\n * @returns - The constructed new path.\n */\nconst constructPath = (\n  locale: Locale,\n  path: string,\n  basePath: string,\n  search?: string\n): string => {\n  // Remove existing locale prefix from path if it was passed by mistake,\n  // though we usually pass localized paths here now.\n  const pathWithoutPrefix = path.startsWith(`/${locale}`)\n    ? path.slice(`/${locale}`.length) || '/'\n    : path;\n\n  if (\n    (!(\n      process.env['INTLAYER_ROUTING_MODE'] &&\n      process.env['INTLAYER_ROUTING_MODE'] !== 'no-prefix'\n    ) &&\n      effectiveMode === 'no-prefix') ||\n    (!(\n      process.env['INTLAYER_ROUTING_MODE'] &&\n      process.env['INTLAYER_ROUTING_MODE'] !== 'search-params'\n    ) &&\n      effectiveMode === 'search-params')\n  ) {\n    return `${pathWithoutPrefix}${search ? `?${search}` : ''}`;\n  }\n\n  // Prefix handling\n  const pathWithLocalePrefix = path.startsWith(`/${locale}`)\n    ? path\n    : `${locale}${path.startsWith('/') ? '' : '/'}${path}`;\n\n  const basePathTrailingSlash = basePath.endsWith('/');\n  const newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${pathWithLocalePrefix}`;\n\n  // Clean double slashes\n  const cleanPath = newPath.replace(/\\/+/g, '/');\n\n  return cleanPath;\n};\n\n/**\n * This handles the internal path Next.js sees.\n * To support optional [locale] folders, we need to decide if we\n * keep the locale prefix or strip it.\n */\nconst rewriteUrl = (\n  request: NextRequest,\n  newPath: string,\n  locale: Locale\n): NextResponse => {\n  const search = request.nextUrl.search;\n  const pathWithSearch =\n    search && !newPath.includes('?') ? `${newPath}${search}` : newPath;\n\n  const requestHeaders = new Headers(request.headers);\n  setLocaleInStorageServer(locale, {\n    setHeader: (name: string, value: string) => {\n      requestHeaders.set(name, value);\n    },\n  });\n\n  const targetUrl = new URL(pathWithSearch, request.url);\n\n  // If the target URL is exactly the current request URL,\n  // we just want to `next()` to avoid losing headers on a redundant rewrite.\n  const response =\n    targetUrl.href === request.nextUrl.href\n      ? NextResponse.next({\n          request: {\n            headers: requestHeaders,\n          },\n        })\n      : NextResponse.rewrite(targetUrl, {\n          request: {\n            headers: requestHeaders,\n          },\n        });\n\n  setLocaleInStorageServer(locale, {\n    setHeader: (name: string, value: string) => {\n      response.headers.set(name, value);\n    },\n  });\n  return response;\n};\n\n/**\n * Redirects the request to the new path.\n *\n * @param request - The incoming Next.js request object.\n * @param newPath - The new path to redirect to.\n * @returns - The redirect response.\n */\nconst redirectUrl = (request: NextRequest, newPath: string): NextResponse => {\n  const search = request.nextUrl.search;\n  const pathWithSearch =\n    search && !newPath.includes('?') ? `${newPath}${search}` : newPath;\n\n  const target = new URL(pathWithSearch, request.url);\n\n  // Prevent open redirect: if the resolved origin differs from the request\n  // origin, strip it back to a same-origin URL using only the path/search/hash.\n  const safeTarget =\n    target.origin === request.nextUrl.origin\n      ? target\n      : new URL(\n          `${target.pathname}${target.search}${target.hash}`,\n          request.url\n        );\n\n  return NextResponse.redirect(safeTarget);\n};\n"],"mappings":"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"}