express-intlayer
Version:
Manage internationalization i18n in a simple way for express application.
134 lines (132 loc) • 5.96 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
let _intlayer_config_node = require("@intlayer/config/node");
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
let _intlayer_core_localization = require("@intlayer/core/localization");
let _intlayer_core_utils = require("@intlayer/core/utils");
let _intlayer_engine_build = require("@intlayer/engine/build");
let cls_hooked = require("cls-hooked");
//#region src/index.ts
let debug = () => {};
const configuration = (0, _intlayer_config_node.getConfiguration)();
const { internationalization } = configuration;
if (process.env["NODE_ENV"] === "development") debug = (msg) => console.debug(msg);
/**
* Retrieves the locale from storage (cookies, localStorage, sessionStorage).
*/
const getStorageLocale = (req) => (0, _intlayer_core_utils.getLocaleFromStorageServer)({
getCookie: (name) => req.cookies?.[name],
getHeader: (name) => req.headers?.[name]
});
const appNamespace = (0, cls_hooked.createNamespace)("app");
(0, _intlayer_engine_build.prepareIntlayer)(configuration);
const translateFunction = (_req, res, _next) => (content, locale) => {
const { locale: currentLocale, defaultLocale } = res.locals;
const targetLocale = locale ?? currentLocale;
if (typeof content === "undefined") return "";
if (typeof content === "string") return content;
if (typeof content?.[targetLocale] === "undefined") if (typeof content?.[defaultLocale] === "undefined") return content;
else return (0, _intlayer_core_interpreter.getTranslation)(content, defaultLocale);
return (0, _intlayer_core_interpreter.getTranslation)(content, targetLocale);
};
/**
* Express middleware that detects the user's locale and populates `res.locals` with Intlayer data.
*
* It performs:
* 1. Locale detection from cookies, headers, or default settings.
* 2. Injects `t`, `getIntlayer`, and `getDictionary` functions into `res.locals`.
* 3. Sets up a `cls-hooked` namespace for accessing these functions anywhere in the request lifecycle.
*
* @returns An Express middleware function.
*
* @example
* ```ts
* import express from 'express';
* import { intlayer } from 'express-intlayer';
*
* const app = express();
* app.use(intlayer());
* ```
*/
const intlayer = () => async (req, res, next) => {
const localeFromStorage = getStorageLocale(req);
const negotiatorHeaders = {};
if (req && typeof req.headers === "object") {
for (const key in req.headers) if (typeof req.headers[key] === "string") negotiatorHeaders[key] = req.headers[key];
}
const localeDetected = (0, _intlayer_core_localization.localeDetector)(negotiatorHeaders, internationalization.locales, internationalization.defaultLocale);
res.locals.locale_storage = localeFromStorage;
res.locals.locale_detected = localeDetected;
res.locals.locale = localeFromStorage ?? localeDetected;
res.locals.defaultLocale = internationalization.defaultLocale;
const t = translateFunction(req, res, next);
const getIntlayer = (key, localeArg = localeDetected, ...props) => (0, _intlayer_core_interpreter.getIntlayer)(key, localeArg, ...props);
const getDictionary = (key, localeArg = localeDetected, ...props) => (0, _intlayer_core_interpreter.getDictionary)(key, localeArg, ...props);
res.locals.t = t;
res.locals.getIntlayer = getIntlayer;
res.locals.getDictionary = getDictionary;
appNamespace.run(() => {
appNamespace.set("t", t);
appNamespace.set("getIntlayer", getIntlayer);
appNamespace.set("getDictionary", getDictionary);
next();
});
};
/**
* Translation function to retrieve content for the current locale.
*
* This function works within the request lifecycle managed by the `intlayer` middleware.
*
* @param content - A map of locales to content.
* @param locale - Optional locale override.
* @returns The translated content.
*
* @example
* ```ts
* import { t } from 'express-intlayer';
*
* app.get('/', (req, res) => {
* const greeting = t({
* en: 'Hello',
* fr: 'Bonjour',
* });
* res.send(greeting);
* });
* ```
*/
const t = (content, locale) => {
try {
if (typeof appNamespace === "undefined") throw new Error("Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.");
if (typeof appNamespace.get("t") !== "function") throw new Error("Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.");
return appNamespace.get("t")(content, locale);
} catch (error) {
debug(error.message);
return (0, _intlayer_core_interpreter.getTranslation)(content, locale ?? internationalization.defaultLocale);
}
};
const getIntlayer = (...args) => {
try {
if (typeof appNamespace === "undefined") throw new Error("Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.");
if (typeof appNamespace.get("getIntlayer") !== "function") throw new Error("Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.");
return appNamespace.get("getIntlayer")(...args);
} catch (error) {
debug(error.message);
return (0, _intlayer_core_interpreter.getIntlayer)(...args);
}
};
const getDictionary = (...args) => {
try {
if (typeof appNamespace === "undefined") throw new Error("Intlayer is not initialized. Add the `app.use(intlayer());` middleware before using this function.");
if (typeof appNamespace.get("getDictionary") !== "function") throw new Error("Using the import { t } from \"express-intlayer\" is not supported in your environment. Use the res.locals.t syntax instead.");
return appNamespace.get("getDictionary")(...args);
} catch (error) {
debug(error.message);
return (0, _intlayer_core_interpreter.getDictionary)(...args);
}
};
//#endregion
exports.getDictionary = getDictionary;
exports.getIntlayer = getIntlayer;
exports.intlayer = intlayer;
exports.t = t;
exports.translateFunction = translateFunction;
//# sourceMappingURL=index.cjs.map