{"version":3,"sources":["../../../src/middleware/intlayerMiddleware.ts"],"sourcesContent":["import { type Locales } from '@intlayer/config/client';\nimport configuration from '@intlayer/config/built';\n\nimport {\n  type NextFetchEvent,\n  type NextRequest,\n  NextResponse,\n} from 'next/server';\nimport { localeDetector } from './localeDetector';\n\nconst { internationalization, middleware } = configuration;\nconst { locales, defaultLocale } = internationalization;\nconst {\n  headerName,\n  cookieName,\n  prefixDefault,\n  basePath,\n  serverSetCookie,\n  noPrefix,\n} = middleware;\n\n/**\n * Middleware that handles the internationalization layer\n *\n * Usage:\n *\n * ```ts\n * // ./src/middleware.ts\n *\n * export { intlayerMiddleware as middleware } from '@intlayer/next/middleware';\n *\n * // applies this middleware only to files in the app directory\n * export const config = {\n *   matcher: '/((?!api|static|.*\\\\..*|_next).*)',\n * };\n * ```\n *\n * Main middleware 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 intlayerMiddleware = (\n  request: NextRequest,\n  _event?: NextFetchEvent,\n  _response?: NextResponse\n): NextResponse => {\n  const pathname = request.nextUrl.pathname;\n  const cookieLocale = getCookieLocale(request);\n  const basePathTrailingSlash = basePath.endsWith('/');\n\n  if (\n    noPrefix // If the application is configured not to use locale prefixes in URLs\n  ) {\n    return handleNoPrefix(\n      request,\n      cookieLocale,\n      pathname,\n      basePathTrailingSlash\n    );\n  }\n\n  const pathLocale = getPathLocale(pathname);\n\n  return handlePrefix(\n    request,\n    cookieLocale,\n    pathLocale,\n    pathname,\n    basePathTrailingSlash\n  );\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 getCookieLocale = (request: NextRequest): Locales | undefined => {\n  if (!cookieName) return undefined;\n  const cookieValue = request.cookies.get(cookieName)?.value as Locales;\n  if (cookieValue && locales.includes(cookieValue)) {\n    return cookieValue;\n  }\n};\n\n/**\n * Handles the case where URLs do not have locale prefixes.\n *\n * @param request - The incoming Next.js request object.\n * @param cookieLocale - 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 rewritten response with the locale applied.\n */\nconst handleNoPrefix = (\n  request: NextRequest,\n  cookieLocale: Locales | undefined,\n  pathname: string,\n  basePathTrailingSlash: boolean\n): NextResponse => {\n  const locale = cookieLocale ?? defaultLocale;\n  const newPath = constructPath(\n    locale,\n    pathname,\n    basePath,\n    basePathTrailingSlash,\n    request.nextUrl.search\n  );\n  return rewriteUrl(request, newPath, 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): Locales | undefined =>\n  locales.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 cookieLocale - 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  cookieLocale: Locales | undefined,\n  pathLocale: Locales | undefined,\n  pathname: string,\n  basePathTrailingSlash: boolean\n): NextResponse => {\n  if (\n    !pathLocale // If the URL does not contain a locale prefix\n  ) {\n    return handleMissingPathLocale(\n      request,\n      cookieLocale,\n      pathname,\n      basePathTrailingSlash\n    );\n  }\n\n  // If the URL contains a locale prefix\n  return handleExistingPathLocale(\n    request,\n    cookieLocale,\n    pathLocale,\n    pathname,\n    basePathTrailingSlash\n  );\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 cookieLocale - 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  cookieLocale: Locales | undefined,\n  pathname: string,\n  basePathTrailingSlash: boolean\n): NextResponse => {\n  let locale = (cookieLocale ??\n    localeDetector?.(request) ??\n    defaultLocale) as Locales;\n  if (!locales.includes(locale)) {\n    console.warn(\n      'The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'\n    );\n    locale = defaultLocale;\n  }\n  const newPath = constructPath(\n    locale,\n    pathname,\n    basePath,\n    basePathTrailingSlash,\n    request.nextUrl.search\n  );\n\n  return prefixDefault || locale !== defaultLocale\n    ? redirectUrl(request, newPath)\n    : rewriteUrl(request, newPath, locale);\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 cookieLocale - 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 handleExistingPathLocale = (\n  request: NextRequest,\n  cookieLocale: Locales | undefined,\n  pathLocale: Locales,\n  pathname: string,\n  basePathTrailingSlash: boolean\n): NextResponse => {\n  if (\n    // If the cookie locale is set and differs from the locale in the URL, and server should not always set cookie\n    cookieLocale &&\n    cookieLocale !== pathLocale &&\n    serverSetCookie !== 'always'\n  ) {\n    const newPath = handleCookieLocaleMismatch(\n      request,\n      pathname,\n      pathLocale,\n      cookieLocale,\n      basePath,\n      basePathTrailingSlash\n    );\n    return redirectUrl(request, newPath);\n  }\n\n  // If the cookie locale matches the path locale, or cookie locale is not set, or serverSetCookie is 'always'\n  return handleDefaultLocaleRedirect(\n    request,\n    pathLocale,\n    pathname,\n    basePathTrailingSlash\n  );\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 cookieLocale - The locale from the cookie.\n * @param basePath - The base path of the application.\n * @param basePathTrailingSlash - Indicates if the basePath ends with a slash.\n * @returns - The new URL path with the correct locale.\n */\nconst handleCookieLocaleMismatch = (\n  request: NextRequest,\n  pathname: string,\n  pathLocale: Locales,\n  cookieLocale: Locales,\n  basePath: string,\n  basePathTrailingSlash: boolean\n): string => {\n  // Replace the pathLocale in the pathname with the cookieLocale\n  const newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`);\n\n  return constructPath(\n    cookieLocale,\n    newPath,\n    basePath,\n    basePathTrailingSlash,\n    request.nextUrl.search\n  );\n};\n\n/**\n * Handles redirection when the default locale is used and prefixing is not required.\n *\n * @param request - The incoming Next.js request object.\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 rewritten response without the locale prefix.\n */\nconst handleDefaultLocaleRedirect = (\n  request: NextRequest,\n  pathLocale: Locales,\n  pathname: string,\n  basePathTrailingSlash: boolean\n): NextResponse => {\n  if (\n    // If default locale should not be prefixed and the pathLocale is the defaultLocale\n    !prefixDefault &&\n    pathLocale === defaultLocale\n  ) {\n    let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) ?? '/';\n\n    if (basePathTrailingSlash) {\n      pathWithoutLocale = pathWithoutLocale.slice(1);\n    }\n\n    if (request.nextUrl.search) {\n      pathWithoutLocale += request.nextUrl.search;\n    }\n\n    return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);\n  }\n\n  // If prefixing default locale is required or pathLocale is not the defaultLocale\n\n  return rewriteUrl(request, pathname, 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 basePathTrailingSlash - Indicates if the basePath ends with a slash.\n * @param [search] - The query string from the request URL (optional).\n * @returns - The constructed new path.\n */\nconst constructPath = (\n  locale: Locales,\n  path: string,\n  basePath: string,\n  basePathTrailingSlash: boolean,\n  search?: string\n): string => {\n  let newPath = `${locale}${path}`;\n\n  newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`;\n  if (search) {\n    newPath += search;\n  }\n  return newPath;\n};\n\n/**\n * Rewrites the URL to the new path and sets the locale header.\n *\n * @param request - The incoming Next.js request object.\n * @param newPath - The new path to rewrite to.\n * @param locale - The locale to set in the response header.\n * @returns - The rewritten response.\n */\nconst rewriteUrl = (\n  request: NextRequest,\n  newPath: string,\n  locale: Locales\n): NextResponse => {\n  const response = NextResponse.rewrite(new URL(newPath, request.url));\n  response.headers.set(headerName, locale);\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  NextResponse.redirect(new URL(newPath, request.url));\n"],"mappings":"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","names":["configuration","basePath"]}