UNPKG

nano-i18n

Version:

Tiny experimental i18n library for JavaScript using tagged template literals.

135 lines (110 loc) 2.77 kB
/* The translation store. Add things to it with load(), and empty it with clear(). */ let db = {}; const PLACEHOLDER = '{}'; let _placeholder = PLACEHOLDER; // ignores missing translation const LOG_SILENT = 0; // logs warning in console on missing translation const LOG_WARN = 1; // throws error on missing translation const LOG_ERROR = 2; /* Log level. Configurable from config() */ let _log = LOG_SILENT; /* Combines two arrays of strings of (mostly) the same length into a single string, through interpolation. */ function interpolate(strings, values) { return strings.reduce(function (result, current_str, idx) { return result + current_str + (idx < values.length ? values[idx] : ''); }, ''); } /* Generate a key for a certain literal. Interpolated values from the template literal are ignored, and replaced with the `{}` placeholder. E.g. key`Hello, ${'World'}` => "Hello, {}" */ function key(strings) { return strings.join(_placeholder); } /* Provide a translation for a string. Used in conjunction with `key` and `load`. */ function value(strings, ...placeholders) { return values => placeholders.length ? interpolate( strings, placeholders.map(i => values[i]) ) : strings.join(''); } /* Translate a string. E.g. t`Hello, ${'World'}!` => "Salut, World!" If no translation can be found, a simple interpolation is returned instead. */ function translate(strings, ...values) { let isString = typeof strings === 'string'; let k = isString ? strings : key(strings); let val = db[k]; if (!val) { exceptional(`No translation found for ${k}`, k); return isString ? strings : interpolate(strings, values); } return typeof val === 'string' ? val : val(values); } /* Load translations into the store. You can either load them in bulk by sending an object as the first argument, or one by one: load(k`Hello, ${'World'}`, v`Salut, ${0}`); You can also use static strings as translations: load('Hello, World!', 'Salut, lume!'); */ function load(k, v) { if (typeof k === 'object') { Object.keys(k).forEach(i => { db[i] = k[i]; }); } db[k] = v; } /* Empty the translations store. */ function clear() { db = {}; } /* Keep track of exceptions. Currently, only missing translations are exceptions. Decide what to do based on the log level. */ function exceptional(str, key) { if (_log === LOG_WARN) { console.warn(str); } else if (_log === LOG_ERROR) { throw new Error(str); } else if (typeof _log === 'function') { _log(str, key); } } function config(opts) { if (opts.log !== undefined) { _log = opts.log; } if (opts.placeholder !== undefined) { _placeholder = opts.placeholder; } } export { translate as t, value as v, key as k, load, clear, config };