{"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport {\n  getDictionary as getDictionaryFunction,\n  getIntlayer as getIntlayerFunction,\n  getTranslation,\n} from '@intlayer/core/interpreter';\nimport { localeDetector } from '@intlayer/core/localization';\nimport { getLocaleFromStorage } from '@intlayer/core/utils';\nimport type { Locale, StrictModeLocaleMap } from '@intlayer/types';\nimport { createNamespace } from 'cls-hooked';\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\n\nconst configuration = getConfiguration();\nconst { internationalization } = configuration;\n\n/**\n * Retrieves the locale from storage (cookies, localStorage, sessionStorage).\n */\nconst getStorageLocale = (req: Request): Locale | undefined =>\n  getLocaleFromStorage({\n    getCookie: (name: string) => req.cookies?.[name],\n    getHeader: (name: string) => req.headers?.[name] as string | undefined,\n  });\n\nconst appNamespace = createNamespace('app');\n\nprepareIntlayer(configuration);\n\nexport const translateFunction =\n  (_req: Request, res: Response, _next?: NextFunction) =>\n  <T extends string>(\n    content: StrictModeLocaleMap<T> | string,\n    locale?: Locale\n  ): T => {\n    const { locale: currentLocale, defaultLocale } = res.locals as {\n      locale: Locale;\n      defaultLocale: Locale;\n    };\n\n    const targetLocale = locale ?? currentLocale;\n\n    if (typeof content === 'undefined') {\n      return '' as unknown as T;\n    }\n\n    if (typeof content === 'string') {\n      return content as unknown as T;\n    }\n\n    if (\n      typeof content?.[\n        targetLocale as unknown as keyof StrictModeLocaleMap<T>\n      ] === 'undefined'\n    ) {\n      if (\n        typeof content?.[\n          defaultLocale as unknown as keyof StrictModeLocaleMap<T>\n        ] === 'undefined'\n      ) {\n        return content as unknown as T;\n      } else {\n        return getTranslation(content, defaultLocale);\n      }\n    }\n\n    return getTranslation(content, targetLocale);\n  };\n\n/**\n * Express middleware that detects the user's locale and populates `res.locals` with Intlayer data.\n *\n * It performs:\n * 1. Locale detection from cookies, headers, or default settings.\n * 2. Injects `t`, `getIntlayer`, and `getDictionary` functions into `res.locals`.\n * 3. Sets up a `cls-hooked` namespace for accessing these functions anywhere in the request lifecycle.\n *\n * @returns An Express middleware function.\n *\n * @example\n * ```ts\n * import express from 'express';\n * import { intlayer } from 'express-intlayer';\n *\n * const app = express();\n * app.use(intlayer());\n * ```\n */\nexport const intlayer = (): RequestHandler => async (req, res, next) => {\n  // Detect if locale is set by intlayer frontend lib in the headers\n  const localeFromStorage = getStorageLocale(req);\n  // Interpret browser locale\n\n  const negotiatorHeaders: Record<string, string> = {};\n\n  // // Check if req.headers exists and is an object\n  if (req && typeof req.headers === 'object') {\n    // Copy all headers from the request to negotiatorHeaders\n    for (const key in req.headers) {\n      if (typeof req.headers[key] === 'string') {\n        negotiatorHeaders[key] = req.headers[key];\n      }\n    }\n  }\n\n  const localeDetected = localeDetector(\n    negotiatorHeaders,\n    internationalization.locales,\n    internationalization.defaultLocale\n  );\n\n  res.locals.locale_storage = localeFromStorage;\n  res.locals.locale_detected = localeDetected;\n  res.locals.locale = localeFromStorage ?? localeDetected;\n  res.locals.defaultLocale = internationalization.defaultLocale;\n\n  const t = translateFunction(req, res, next);\n\n  const getIntlayer: typeof getIntlayerFunction = (\n    key,\n    localeArg = localeDetected as Parameters<typeof getIntlayerFunction>[1],\n    ...props\n  ) => getIntlayerFunction(key, localeArg, ...props);\n\n  const getDictionary: typeof getDictionaryFunction = (\n    key,\n    localeArg = localeDetected as Parameters<typeof getDictionaryFunction>[1],\n    ...props\n  ) => getDictionaryFunction(key, localeArg, ...props);\n\n  res.locals.t = t;\n  res.locals.getIntlayer = getIntlayer;\n  res.locals.getDictionary = getDictionary;\n\n  appNamespace.run(() => {\n    appNamespace.set('t', t);\n    appNamespace.set('getIntlayer', getIntlayer);\n    appNamespace.set('getDictionary', getDictionary);\n\n    next();\n  });\n};\n\n/**\n * Translation function to retrieve content for the current locale.\n *\n * This function works within the request lifecycle managed by the `intlayer` middleware.\n *\n * @param content - A map of locales to content.\n * @param locale - Optional locale override.\n * @returns The translated content.\n *\n * @example\n * ```ts\n * import { t } from 'express-intlayer';\n *\n * app.get('/', (req, res) => {\n *   const greeting = t({\n *     en: 'Hello',\n *     fr: 'Bonjour',\n *   });\n *   res.send(greeting);\n * });\n * ```\n */\nexport const t = <Content = string>(\n  content: StrictModeLocaleMap<Content>,\n  locale?: Locale\n): Content => {\n  try {\n    if (typeof appNamespace === 'undefined') {\n      throw new Error(\n        'Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.'\n      );\n    }\n\n    if (typeof appNamespace.get('t') !== 'function') {\n      throw new Error(\n        'Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.'\n      );\n    }\n\n    return appNamespace.get('t')(content, locale);\n  } catch (error) {\n    if (process.env.NODE_ENV === 'development') {\n      console.error((error as Error).message);\n    }\n\n    return getTranslation(\n      content,\n      locale ?? internationalization.defaultLocale\n    );\n  }\n};\n\nexport const getIntlayer: typeof getIntlayerFunction = (...args) => {\n  try {\n    if (typeof appNamespace === 'undefined') {\n      throw new Error(\n        'Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.'\n      );\n    }\n\n    if (typeof appNamespace.get('getIntlayer') !== 'function') {\n      throw new Error(\n        'Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.'\n      );\n    }\n\n    return appNamespace.get('getIntlayer')(...args);\n  } catch (error) {\n    if (process.env.NODE_ENV === 'development') {\n      console.error((error as Error).message);\n    }\n    return getIntlayerFunction(...args);\n  }\n};\n\nexport const getDictionary: typeof getDictionaryFunction = (...args) => {\n  try {\n    if (typeof appNamespace === 'undefined') {\n      throw new Error(\n        'Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.'\n      );\n    }\n\n    if (typeof appNamespace.get('getDictionary') !== 'function') {\n      throw new Error(\n        'Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.'\n      );\n    }\n\n    return appNamespace.get('getDictionary')(...args);\n  } catch (error) {\n    if (process.env.NODE_ENV === 'development') {\n      console.error((error as Error).message);\n    }\n    return getDictionaryFunction(...args);\n  }\n};\n"],"mappings":"2RAaA,MAAM,GAAA,EAAA,EAAA,mBAAkC,CAClC,CAAE,wBAAyB,EAK3B,EAAoB,IAAA,EAAA,EAAA,sBACH,CACnB,UAAY,GAAiB,EAAI,UAAU,GAC3C,UAAY,GAAiB,EAAI,UAAU,GAC5C,CAAC,CAEE,GAAA,EAAA,EAAA,iBAA+B,MAAM,uBAE3B,EAAc,CAE9B,MAAa,GACV,EAAe,EAAe,KAE7B,EACA,IACM,CACN,GAAM,CAAE,OAAQ,EAAe,iBAAkB,EAAI,OAK/C,EAAe,GAAU,EA0B/B,OAxBW,IAAY,OACd,GAGL,OAAO,GAAY,SACd,EAIA,IACL,KACI,OAGG,IACL,KACI,OAEC,GAEP,EAAA,EAAA,gBAAsB,EAAS,EAAc,EAIjD,EAAA,EAAA,gBAAsB,EAAS,EAAa,EAsBnC,MAAiC,MAAO,EAAK,EAAK,IAAS,CAEtE,IAAM,EAAoB,EAAiB,EAAI,CAGzC,EAA4C,EAAE,CAGpD,GAAI,GAAO,OAAO,EAAI,SAAY,aAE3B,IAAM,KAAO,EAAI,QAChB,OAAO,EAAI,QAAQ,IAAS,WAC9B,EAAkB,GAAO,EAAI,QAAQ,IAK3C,IAAM,GAAA,EAAA,EAAA,gBACJ,EACA,EAAqB,QACrB,EAAqB,cACtB,CAED,EAAI,OAAO,eAAiB,EAC5B,EAAI,OAAO,gBAAkB,EAC7B,EAAI,OAAO,OAAS,GAAqB,EACzC,EAAI,OAAO,cAAgB,EAAqB,cAEhD,IAAM,EAAI,EAAkB,EAAK,EAAK,EAAK,CAErC,GACJ,EACA,EAAY,EACZ,GAAG,KAAA,EAAA,EAAA,aACoB,EAAK,EAAW,GAAG,EAAM,CAE5C,GACJ,EACA,EAAY,EACZ,GAAG,KAAA,EAAA,EAAA,eACsB,EAAK,EAAW,GAAG,EAAM,CAEpD,EAAI,OAAO,EAAI,EACf,EAAI,OAAO,YAAc,EACzB,EAAI,OAAO,cAAgB,EAE3B,EAAa,QAAU,CACrB,EAAa,IAAI,IAAK,EAAE,CACxB,EAAa,IAAI,cAAe,EAAY,CAC5C,EAAa,IAAI,gBAAiB,EAAc,CAEhD,GAAM,EACN,EAyBS,GACX,EACA,IACY,CACZ,GAAI,CACF,GAAW,IAAiB,OAC1B,MAAU,MACR,qGACD,CAGH,GAAI,OAAO,EAAa,IAAI,IAAI,EAAK,WACnC,MAAU,MACR,4HACD,CAGH,OAAO,EAAa,IAAI,IAAI,CAAC,EAAS,EAAO,OACtC,EAAO,CAKd,OAJI,QAAQ,IAAI,WAAa,eAC3B,QAAQ,MAAO,EAAgB,QAAQ,EAGzC,EAAA,EAAA,gBACE,EACA,GAAU,EAAqB,cAChC,GAIQ,GAA2C,GAAG,IAAS,CAClE,GAAI,CACF,GAAW,IAAiB,OAC1B,MAAU,MACR,qGACD,CAGH,GAAI,OAAO,EAAa,IAAI,cAAc,EAAK,WAC7C,MAAU,MACR,4HACD,CAGH,OAAO,EAAa,IAAI,cAAc,CAAC,GAAG,EAAK,OACxC,EAAO,CAId,OAHI,QAAQ,IAAI,WAAa,eAC3B,QAAQ,MAAO,EAAgB,QAAQ,EAEzC,EAAA,EAAA,aAA2B,GAAG,EAAK,GAI1B,GAA+C,GAAG,IAAS,CACtE,GAAI,CACF,GAAW,IAAiB,OAC1B,MAAU,MACR,qGACD,CAGH,GAAI,OAAO,EAAa,IAAI,gBAAgB,EAAK,WAC/C,MAAU,MACR,4HACD,CAGH,OAAO,EAAa,IAAI,gBAAgB,CAAC,GAAG,EAAK,OAC1C,EAAO,CAId,OAHI,QAAQ,IAAI,WAAa,eAC3B,QAAQ,MAAO,EAAgB,QAAQ,EAEzC,EAAA,EAAA,eAA6B,GAAG,EAAK"}