import { get } from '../objects/get'; import type { ObjectPathLike } from '../objects/parseObjectPath'; import { renderTemplate } from '../strings/renderTemplate'; export interface Translate { /** Get/Set the language key */ locale(lang?: string): string; /** Define the dict of translations for a language */ dict(lang: string, dict: T): void; /** Get the dict of translations for a language */ dict(lang: string): T; /** Retrieve a translation segment for the current language */ t | any[]>(key: ObjectPathLike, params?: X, lang?: string): string; } export function createTranslate(obj?: Record): Translate { let locale = ''; const tree = obj || {}; // en-US -> en-US,en const keyOfDict = (s: string | string[]) => { if (Array.isArray(s)) { return s; } const sp = s.split(/[_-]/); if (sp.length > 1) { return [s, sp[0]]; } return [s]; }; return { locale(lang) { return (locale = lang || locale); }, dict: ((lang, dict?) => { if (dict) { tree[lang] = Object.assign(tree[lang] || {}, dict); return; } return tree[lang]; }) as Translate['dict'], t(key, params, lang) { let val: any; for (const k of keyOfDict(lang || locale)) { val = get(tree[k], key, ''); if (val) { break; } } if (process.env.NODE_ENV === 'development') { if (val == null) { console.error( `[Translate] Missing the "${[].concat(key as any).join('.')}" key within the "${ lang || locale }" dictionary`, ); return; } } if (typeof val === 'function') return val(params); if (typeof val === 'string') return renderTemplate(val, params, 'common'); return val; }, }; }