UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

85 lines (80 loc) 3.11 kB
import "core-js/modules/es.array.reduce.js"; import IntlMessageFormat from 'intl-messageformat'; import curry from 'lodash/curry'; // eslint-disable-next-line import/no-named-default import { default as getPath } from 'lodash/get'; import moment from 'moment'; import messageCache from "./messageCache"; /** * Pure function to return original key whet Intl message not found * @param {*} key origin intl key to return * @returns {*} */ const pureReturn = key => ({ format: () => key }); /** * Returns an instance of IntlMessageFormat from cache based on a hash. * The hash is generated from given language code and translation key. * If no instance exists yet, a new instance will be created and returned. * @param {Object} locales A locales object. * @param {string} langCode A language code. * @param {string} key A translation key. * @param {Object} options Additional options for the translator * @param {boolean} [options.acceptPlainTextWithPlaceholders = false] When set to TRUE, the * translator can also handle human readable texts that contain text replacement placeholders. * @returns {IntlMessageFormat} */ const getMessageFromCache = (locales, langCode, key, options = {}) => { const { acceptPlainTextWithPlaceholders = false } = options; const hash = `${langCode}_${key}_${acceptPlainTextWithPlaceholders ? 1 : 0}`; // Check if a cached instance already exists. if (messageCache[hash]) { return messageCache[hash]; } const message = getPath(locales, key, acceptPlainTextWithPlaceholders ? key : undefined); if (typeof message !== 'string' || message.length === 0) { return pureReturn(key); } // Prevent the app from crashing when strings (like product names) don't comply with the format try { messageCache[hash] = new IntlMessageFormat(message, langCode, getPath(locales, 'formats')); } catch (e) { messageCache[hash] = pureReturn(key); } return messageCache[hash]; }; /** * Get a translation for a given key. * @param {Object} locales A locales object. * @param {string} langCode A language code. * @param {string} key A translation key. * @param {Object} [args] Arguments for the translation. * @param {Object} options Additional options for the translator * @param {boolean} [options.acceptPlainTextWithPlaceholders = false] When set to TRUE, the * translator can also handle human readable texts that contain text replacement placeholders. * @returns {string} */ const translate = (locales, langCode, key, args = {}, options = {}) => { /** * @returns {Object} */ const sanitizeArgs = () => { if (typeof args !== 'object' || args === null) { return args; } return Object.keys(args).reduce((acc, arg) => { const date = moment(args[arg], moment.ISO_8601, true); if (date.isValid() && date.toISOString() === args[arg]) { acc[arg] = new Date(args[arg]).getTime(); } else { acc[arg] = args[arg]; } return acc; }, {}); }; return getMessageFromCache(locales, langCode, key, options).format(sanitizeArgs()); }; export default curry(translate);