lang-tag
Version:
A professional solution for managing translations in modern JavaScript/TypeScript projects, especially those using component-based architectures. `lang-tag` simplifies internationalization by allowing you to define translation keys directly within the com
111 lines (110 loc) • 4.36 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
function transformTranslationsToFunctions(config, strategy, input, currentParentPath, currentRelativeParentPath) {
const result = {};
for (const [originalKey, originalValue] of Object.entries(input)) {
const currentFullPath = `${currentParentPath}${originalKey}`;
const currentRelativePath = currentRelativeParentPath ? `${currentRelativeParentPath}.${originalKey}` : originalKey;
if (typeof originalValue === "object" && originalValue !== null) {
result[originalKey] = transformTranslationsToFunctions(config, strategy, originalValue, `${currentFullPath}.`, currentRelativePath);
} else if (typeof originalValue === "string") {
const createTranslationFunction = (pathForFunc, unprefixedPathForFunc, keyForFunc, valueForFunc) => {
return (params) => strategy.transform({
config,
parentPath: currentParentPath,
path: pathForFunc,
unprefixedPath: unprefixedPathForFunc,
key: keyForFunc,
value: valueForFunc,
params
});
};
if (strategy.processKey) {
const keyProcessingContext = {
config,
parentPath: currentParentPath,
path: currentFullPath,
unprefixedPath: currentRelativePath,
key: originalKey,
value: originalValue
};
strategy.processKey(
keyProcessingContext,
(newKeyToAdd, valueForNewKey) => {
const pathForNewKey = currentParentPath + newKeyToAdd;
const unprefixedPathForNewKey = currentRelativeParentPath ? `${currentRelativeParentPath}.${newKeyToAdd}` : newKeyToAdd;
result[newKeyToAdd] = createTranslationFunction(pathForNewKey, unprefixedPathForNewKey, newKeyToAdd, valueForNewKey);
}
);
if (!result.hasOwnProperty(originalKey)) {
result[originalKey] = createTranslationFunction(currentFullPath, currentRelativePath, originalKey, originalValue);
}
} else {
result[originalKey] = createTranslationFunction(currentFullPath, currentRelativePath, originalKey, originalValue);
}
}
}
return result;
}
function createCallableTranslations(translations, config, strategy) {
let basePath = config?.path || "";
if (basePath && !basePath.endsWith(".")) basePath += ".";
return transformTranslationsToFunctions(
config,
strategy,
translations,
basePath,
""
);
}
function normalizeTranslations(translations) {
const result = {};
for (const key in translations) {
if (Object.prototype.hasOwnProperty.call(translations, key)) {
const value = translations[key];
if (value === null || value === void 0) {
continue;
}
if (typeof value === "object" && !Array.isArray(value) && !(value instanceof Function)) {
result[key] = normalizeTranslations(value);
} else if (typeof value === "string") {
result[key] = (_params) => value;
} else if (typeof value === "function") {
result[key] = value;
}
}
}
return result;
}
function resolveTranslationFunction(translations, path) {
let current = translations;
for (const key of path) {
if (current && typeof current === "object" && key in current) {
current = current[key];
} else {
return null;
}
}
return typeof current === "function" ? current : null;
}
function lookupTranslation(translations, dottedPath) {
const pathSegments = dottedPath.split(".");
return resolveTranslationFunction(translations, pathSegments);
}
function processPlaceholders(translation, params) {
if (typeof translation !== "string") {
return "";
}
return translation.replace(/{{(.*?)}}/g, (_, placeholder) => {
const trimmedPlaceholder = placeholder.trim();
return params?.[trimmedPlaceholder] !== void 0 ? String(params[trimmedPlaceholder]) : "";
});
}
const defaultTranslationTransformer = ({ value, params }) => {
return processPlaceholders(value, params);
};
exports.createCallableTranslations = createCallableTranslations;
exports.defaultTranslationTransformer = defaultTranslationTransformer;
exports.lookupTranslation = lookupTranslation;
exports.normalizeTranslations = normalizeTranslations;
exports.processPlaceholders = processPlaceholders;