UNPKG

@intlayer/core

Version:

Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.

109 lines (108 loc) 4.25 kB
//#region src/interpreter/getTranslation.ts /** * Check if a value is a plain object that can be safely processed. * Returns false for Promises, React elements, class instances, etc. */ const isPlainObject = (value) => { if (value === null || typeof value !== "object") return false; if (value instanceof Promise || typeof value.then === "function") return false; if (value.$$typeof !== void 0) return false; const proto = Object.getPrototypeOf(value); return proto === Object.prototype || proto === null || Array.isArray(value); }; /** * Recursively merges two objects. * Resembles the behavior of `defu` but respects `isPlainObject` to avoid merging React elements. * Arrays are replaced, not merged. */ const deepMergeObjects = (target, source) => { if (target === void 0) return source; if (source === void 0) return target; if (Array.isArray(target)) return target; if (isPlainObject(target) && isPlainObject(source)) { const result = { ...target }; for (const key of Object.keys(source)) { if (key === "__proto__" || key === "constructor") continue; if (Object.hasOwn(target, key)) result[key] = deepMergeObjects(target[key], source[key]); else result[key] = source[key]; } return result; } return target; }; /** * Recursively removes undefined values from an object. * Handles circular references by tracking visited objects. */ const removeUndefinedValues = (object, visited = /* @__PURE__ */ new WeakSet()) => { if (typeof object !== "object" || object === null) return object; if (visited.has(object)) return object; visited.add(object); if (!isPlainObject(object)) return object; if (Array.isArray(object)) return object.map((item) => removeUndefinedValues(item, visited)); const result = {}; for (const [key, value] of Object.entries(object)) if (value !== void 0) result[key] = removeUndefinedValues(value, visited); return result; }; /** * * Allow to pick a content based on a locale. * If not locale found, it will return the content related to the default locale. * * Return either the content editor, or the content itself depending on the configuration. * * Usage: * * ```ts * const content = getTranslation<string>({ * en: 'Hello', * fr: 'Bonjour', * }, 'fr'); * // 'Bonjour' * ``` * * Using TypeScript: * - this function will require each locale to be defined if defined in the project configuration. * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found. */ const getTranslation = (languageContent, locale, fallback) => { const results = []; const getContent = (loc) => languageContent[loc]; const content = getContent(locale); if (typeof content === "string") return content; else if (content !== void 0) results.push(content); if (locale.includes("-")) { const genericLocale = locale.split("-")[0]; if (genericLocale in languageContent) { const genericContent = getContent(genericLocale); if (typeof genericContent === "string") { if (results.length === 0) return genericContent; } else if (genericContent !== void 0) results.push(genericContent); } } if (fallback !== void 0 && fallback !== locale) { if (fallback in languageContent) { const fallbackContent = getContent(fallback); if (typeof fallbackContent === "string") { if (results.length === 0) return fallbackContent; } else if (fallbackContent !== void 0) results.push(fallbackContent); } if (fallback.includes("-")) { const genericFallback = fallback.split("-")[0]; if (genericFallback !== locale.split("-")[0] && genericFallback in languageContent) { const genericFallbackContent = getContent(genericFallback); if (typeof genericFallbackContent === "string") { if (results.length === 0) return genericFallbackContent; } else if (genericFallbackContent !== void 0) results.push(genericFallbackContent); } } } if (results.length === 0) return; const cleanResults = results.map((item) => removeUndefinedValues(item)); if (cleanResults.length === 1) return cleanResults[0]; if (Array.isArray(cleanResults[0])) return cleanResults[0]; return cleanResults.reduce((acc, curr) => deepMergeObjects(acc, curr)); }; //#endregion export { getTranslation }; //# sourceMappingURL=getTranslation.mjs.map