UNPKG

@maple-billing/csv-import-react

Version:

Open-source CSV and XLS/XLSX file importer for React and JavaScript

1,282 lines (1,259 loc) 1.93 MB
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime'; import * as React from 'react'; import React__default, { createContext as createContext$2, useContext, useState, useRef, useEffect, useCallback, forwardRef as forwardRef$2, isValidElement, cloneElement, useMemo, createElement, useLayoutEffect, useReducer, useImperativeHandle, Fragment as Fragment$2, useInsertionEffect as useInsertionEffect$1, useId, Children, memo as memo$1, useSyncExternalStore as useSyncExternalStore$1 } from 'react'; import { ThemeContext, withEmotionCache, keyframes as keyframes$1, Global, ThemeProvider as ThemeProvider$2, CacheProvider } from '@emotion/react'; import { createPortal } from 'react-dom'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign$1 = function() { __assign$1 = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$1.apply(this, arguments); }; function __rest$1(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; function warn() { if (console && console.warn) { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (isString$2(args[0])) args[0] = `react-i18next:: ${args[0]}`; console.warn(...args); } } const alreadyWarned = {}; function warnOnce$1() { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (isString$2(args[0]) && alreadyWarned[args[0]]) return; if (isString$2(args[0])) alreadyWarned[args[0]] = new Date(); warn(...args); } const loadedClb = (i18n, cb) => () => { if (i18n.isInitialized) { cb(); } else { const initialized = () => { setTimeout(() => { i18n.off('initialized', initialized); }, 0); cb(); }; i18n.on('initialized', initialized); } }; const loadNamespaces = (i18n, ns, cb) => { i18n.loadNamespaces(ns, loadedClb(i18n, cb)); }; const loadLanguages = (i18n, lng, ns, cb) => { if (isString$2(ns)) ns = [ns]; ns.forEach(n => { if (i18n.options.ns.indexOf(n) < 0) i18n.options.ns.push(n); }); i18n.loadLanguages(lng, loadedClb(i18n, cb)); }; const oldI18nextHasLoadedNamespace = function (ns, i18n) { let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; const lng = i18n.languages[0]; const fallbackLng = i18n.options ? i18n.options.fallbackLng : false; const lastLng = i18n.languages[i18n.languages.length - 1]; if (lng.toLowerCase() === 'cimode') return true; const loadNotPending = (l, n) => { const loadState = i18n.services.backendConnector.state[`${l}|${n}`]; return loadState === -1 || loadState === 2; }; if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18n.services.backendConnector.backend && i18n.isLanguageChangingTo && !loadNotPending(i18n.isLanguageChangingTo, ns)) return false; if (i18n.hasResourceBundle(lng, ns)) return true; if (!i18n.services.backendConnector.backend || i18n.options.resources && !i18n.options.partialBundledLanguages) return true; if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true; return false; }; const hasLoadedNamespace = function (ns, i18n) { let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (!i18n.languages || !i18n.languages.length) { warnOnce$1('i18n.languages were undefined or empty', i18n.languages); return true; } const isNewerI18next = i18n.options.ignoreJSONStructure !== undefined; if (!isNewerI18next) { return oldI18nextHasLoadedNamespace(ns, i18n, options); } return i18n.hasLoadedNamespace(ns, { lng: options.lng, precheck: (i18nInstance, loadNotPending) => { if (options.bindI18n && options.bindI18n.indexOf('languageChanging') > -1 && i18nInstance.services.backendConnector.backend && i18nInstance.isLanguageChangingTo && !loadNotPending(i18nInstance.isLanguageChangingTo, ns)) return false; } }); }; const isString$2 = obj => typeof obj === 'string'; const isObject$3 = obj => typeof obj === 'object' && obj !== null; const matchHtmlEntity = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g; const htmlEntities = { '&amp;': '&', '&#38;': '&', '&lt;': '<', '&#60;': '<', '&gt;': '>', '&#62;': '>', '&apos;': "'", '&#39;': "'", '&quot;': '"', '&#34;': '"', '&nbsp;': ' ', '&#160;': ' ', '&copy;': '©', '&#169;': '©', '&reg;': '®', '&#174;': '®', '&hellip;': '…', '&#8230;': '…', '&#x2F;': '/', '&#47;': '/' }; const unescapeHtmlEntity = m => htmlEntities[m]; const unescape = text => text.replace(matchHtmlEntity, unescapeHtmlEntity); let defaultOptions = { bindI18n: 'languageChanged', bindI18nStore: '', transEmptyNodeValue: '', transSupportBasicHtmlNodes: true, transWrapTextNodes: '', transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p'], useSuspense: true, unescape }; const setDefaults = function () { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; defaultOptions = { ...defaultOptions, ...options }; }; const getDefaults$1 = () => defaultOptions; let i18nInstance; const setI18n = instance => { i18nInstance = instance; }; const getI18n = () => i18nInstance; const initReactI18next = { type: '3rdParty', init(instance) { setDefaults(instance.options.react); setI18n(instance); } }; const I18nContext = createContext$2(); class ReportNamespaces { constructor() { this.usedNamespaces = {}; } addUsedNamespaces(namespaces) { namespaces.forEach(ns => { if (!this.usedNamespaces[ns]) this.usedNamespaces[ns] = true; }); } getUsedNamespaces = () => Object.keys(this.usedNamespaces); } const usePrevious = (value, ignore) => { const ref = useRef(); useEffect(() => { ref.current = ignore ? ref.current : value; }, [value, ignore]); return ref.current; }; const alwaysNewT = (i18n, language, namespace, keyPrefix) => i18n.getFixedT(language, namespace, keyPrefix); const useMemoizedT = (i18n, language, namespace, keyPrefix) => useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]); const useTranslation = function (ns) { let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; const { i18n: i18nFromProps } = props; const { i18n: i18nFromContext, defaultNS: defaultNSFromContext } = useContext(I18nContext) || {}; const i18n = i18nFromProps || i18nFromContext || getI18n(); if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces(); if (!i18n) { warnOnce$1('You will need to pass in an i18next instance by using initReactI18next'); const notReadyT = (k, optsOrDefaultValue) => { if (isString$2(optsOrDefaultValue)) return optsOrDefaultValue; if (isObject$3(optsOrDefaultValue) && isString$2(optsOrDefaultValue.defaultValue)) return optsOrDefaultValue.defaultValue; return Array.isArray(k) ? k[k.length - 1] : k; }; const retNotReady = [notReadyT, {}, false]; retNotReady.t = notReadyT; retNotReady.i18n = {}; retNotReady.ready = false; return retNotReady; } if (i18n.options.react && i18n.options.react.wait !== undefined) warnOnce$1('It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.'); const i18nOptions = { ...getDefaults$1(), ...i18n.options.react, ...props }; const { useSuspense, keyPrefix } = i18nOptions; let namespaces = ns || defaultNSFromContext || i18n.options && i18n.options.defaultNS; namespaces = isString$2(namespaces) ? [namespaces] : namespaces || ['translation']; if (i18n.reportNamespaces.addUsedNamespaces) i18n.reportNamespaces.addUsedNamespaces(namespaces); const ready = (i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions)); const memoGetT = useMemoizedT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix); const getT = () => memoGetT; const getNewT = () => alwaysNewT(i18n, props.lng || null, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix); const [t, setT] = useState(getT); let joinedNS = namespaces.join(); if (props.lng) joinedNS = `${props.lng}${joinedNS}`; const previousJoinedNS = usePrevious(joinedNS); const isMounted = useRef(true); useEffect(() => { const { bindI18n, bindI18nStore } = i18nOptions; isMounted.current = true; if (!ready && !useSuspense) { if (props.lng) { loadLanguages(i18n, props.lng, namespaces, () => { if (isMounted.current) setT(getNewT); }); } else { loadNamespaces(i18n, namespaces, () => { if (isMounted.current) setT(getNewT); }); } } if (ready && previousJoinedNS && previousJoinedNS !== joinedNS && isMounted.current) { setT(getNewT); } const boundReset = () => { if (isMounted.current) setT(getNewT); }; if (bindI18n && i18n) i18n.on(bindI18n, boundReset); if (bindI18nStore && i18n) i18n.store.on(bindI18nStore, boundReset); return () => { isMounted.current = false; if (bindI18n && i18n) bindI18n.split(' ').forEach(e => i18n.off(e, boundReset)); if (bindI18nStore && i18n) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, boundReset)); }; }, [i18n, joinedNS]); useEffect(() => { if (isMounted.current && ready) { setT(getT); } }, [i18n, keyPrefix, ready]); const ret = [t, i18n, ready]; ret.t = t; ret.i18n = i18n; ret.ready = ready; if (ready) return ret; if (!ready && !useSuspense) return ret; throw new Promise(resolve => { if (props.lng) { loadLanguages(i18n, props.lng, namespaces, () => resolve()); } else { loadNamespaces(i18n, namespaces, () => resolve()); } }); }; const isString$1 = obj => typeof obj === 'string'; const defer = () => { let res; let rej; const promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); promise.resolve = res; promise.reject = rej; return promise; }; const makeString = object => { if (object == null) return ''; return '' + object; }; const copy$1 = (a, s, t) => { a.forEach(m => { if (s[m]) t[m] = s[m]; }); }; const lastOfPathSeparatorRegExp = /###/g; const cleanKey = key => key && key.indexOf('###') > -1 ? key.replace(lastOfPathSeparatorRegExp, '.') : key; const canNotTraverseDeeper = object => !object || isString$1(object); const getLastOfPath = (object, path, Empty) => { const stack = !isString$1(path) ? path : path.split('.'); let stackIndex = 0; while (stackIndex < stack.length - 1) { if (canNotTraverseDeeper(object)) return {}; const key = cleanKey(stack[stackIndex]); if (!object[key] && Empty) object[key] = new Empty(); if (Object.prototype.hasOwnProperty.call(object, key)) { object = object[key]; } else { object = {}; } ++stackIndex; } if (canNotTraverseDeeper(object)) return {}; return { obj: object, k: cleanKey(stack[stackIndex]) }; }; const setPath = (object, path, newValue) => { const { obj, k } = getLastOfPath(object, path, Object); if (obj !== undefined || path.length === 1) { obj[k] = newValue; return; } let e = path[path.length - 1]; let p = path.slice(0, path.length - 1); let last = getLastOfPath(object, p, Object); while (last.obj === undefined && p.length) { e = `${p[p.length - 1]}.${e}`; p = p.slice(0, p.length - 1); last = getLastOfPath(object, p, Object); if (last && last.obj && typeof last.obj[`${last.k}.${e}`] !== 'undefined') { last.obj = undefined; } } last.obj[`${last.k}.${e}`] = newValue; }; const pushPath = (object, path, newValue, concat) => { const { obj, k } = getLastOfPath(object, path, Object); obj[k] = obj[k] || []; obj[k].push(newValue); }; const getPath = (object, path) => { const { obj, k } = getLastOfPath(object, path); if (!obj) return undefined; return obj[k]; }; const getPathWithDefaults = (data, defaultData, key) => { const value = getPath(data, key); if (value !== undefined) { return value; } return getPath(defaultData, key); }; const deepExtend = (target, source, overwrite) => { for (const prop in source) { if (prop !== '__proto__' && prop !== 'constructor') { if (prop in target) { if (isString$1(target[prop]) || target[prop] instanceof String || isString$1(source[prop]) || source[prop] instanceof String) { if (overwrite) target[prop] = source[prop]; } else { deepExtend(target[prop], source[prop], overwrite); } } else { target[prop] = source[prop]; } } } return target; }; const regexEscape = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); var _entityMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;', '/': '&#x2F;' }; const escape$2 = data => { if (isString$1(data)) { return data.replace(/[&<>"'\/]/g, s => _entityMap[s]); } return data; }; class RegExpCache { constructor(capacity) { this.capacity = capacity; this.regExpMap = new Map(); this.regExpQueue = []; } getRegExp(pattern) { const regExpFromCache = this.regExpMap.get(pattern); if (regExpFromCache !== undefined) { return regExpFromCache; } const regExpNew = new RegExp(pattern); if (this.regExpQueue.length === this.capacity) { this.regExpMap.delete(this.regExpQueue.shift()); } this.regExpMap.set(pattern, regExpNew); this.regExpQueue.push(pattern); return regExpNew; } } const chars = [' ', ',', '?', '!', ';']; const looksLikeObjectPathRegExpCache = new RegExpCache(20); const looksLikeObjectPath = (key, nsSeparator, keySeparator) => { nsSeparator = nsSeparator || ''; keySeparator = keySeparator || ''; const possibleChars = chars.filter(c => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0); if (possibleChars.length === 0) return true; const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map(c => c === '?' ? '\\?' : c).join('|')})`); let matched = !r.test(key); if (!matched) { const ki = key.indexOf(keySeparator); if (ki > 0 && !r.test(key.substring(0, ki))) { matched = true; } } return matched; }; const deepFind = function (obj, path) { let keySeparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '.'; if (!obj) return undefined; if (obj[path]) return obj[path]; const tokens = path.split(keySeparator); let current = obj; for (let i = 0; i < tokens.length;) { if (!current || typeof current !== 'object') { return undefined; } let next; let nextPath = ''; for (let j = i; j < tokens.length; ++j) { if (j !== i) { nextPath += keySeparator; } nextPath += tokens[j]; next = current[nextPath]; if (next !== undefined) { if (['string', 'number', 'boolean'].indexOf(typeof next) > -1 && j < tokens.length - 1) { continue; } i += j - i + 1; break; } } current = next; } return current; }; const getCleanedCode = code => code && code.replace('_', '-'); const consoleLogger = { type: 'logger', log(args) { this.output('log', args); }, warn(args) { this.output('warn', args); }, error(args) { this.output('error', args); }, output(type, args) { if (console && console[type]) console[type].apply(console, args); } }; class Logger { constructor(concreteLogger) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.init(concreteLogger, options); } init(concreteLogger) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.prefix = options.prefix || 'i18next:'; this.logger = concreteLogger || consoleLogger; this.options = options; this.debug = options.debug; } log() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return this.forward(args, 'log', '', true); } warn() { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return this.forward(args, 'warn', '', true); } error() { for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } return this.forward(args, 'error', ''); } deprecate() { for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true); } forward(args, lvl, prefix, debugOnly) { if (debugOnly && !this.debug) return null; if (isString$1(args[0])) args[0] = `${prefix}${this.prefix} ${args[0]}`; return this.logger[lvl](args); } create(moduleName) { return new Logger(this.logger, { ...{ prefix: `${this.prefix}:${moduleName}:` }, ...this.options }); } clone(options) { options = options || this.options; options.prefix = options.prefix || this.prefix; return new Logger(this.logger, options); } } var baseLogger = new Logger(); class EventEmitter { constructor() { this.observers = {}; } on(events, listener) { events.split(' ').forEach(event => { if (!this.observers[event]) this.observers[event] = new Map(); const numListeners = this.observers[event].get(listener) || 0; this.observers[event].set(listener, numListeners + 1); }); return this; } off(event, listener) { if (!this.observers[event]) return; if (!listener) { delete this.observers[event]; return; } this.observers[event].delete(listener); } emit(event) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (this.observers[event]) { const cloned = Array.from(this.observers[event].entries()); cloned.forEach(_ref => { let [observer, numTimesAdded] = _ref; for (let i = 0; i < numTimesAdded; i++) { observer(...args); } }); } if (this.observers['*']) { const cloned = Array.from(this.observers['*'].entries()); cloned.forEach(_ref2 => { let [observer, numTimesAdded] = _ref2; for (let i = 0; i < numTimesAdded; i++) { observer.apply(observer, [event, ...args]); } }); } } } class ResourceStore extends EventEmitter { constructor(data) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { ns: ['translation'], defaultNS: 'translation' }; super(); this.data = data || {}; this.options = options; if (this.options.keySeparator === undefined) { this.options.keySeparator = '.'; } if (this.options.ignoreJSONStructure === undefined) { this.options.ignoreJSONStructure = true; } } addNamespaces(ns) { if (this.options.ns.indexOf(ns) < 0) { this.options.ns.push(ns); } } removeNamespaces(ns) { const index = this.options.ns.indexOf(ns); if (index > -1) { this.options.ns.splice(index, 1); } } getResource(lng, ns, key) { let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure; let path; if (lng.indexOf('.') > -1) { path = lng.split('.'); } else { path = [lng, ns]; if (key) { if (Array.isArray(key)) { path.push(...key); } else if (isString$1(key) && keySeparator) { path.push(...key.split(keySeparator)); } else { path.push(key); } } } const result = getPath(this.data, path); if (!result && !ns && !key && lng.indexOf('.') > -1) { lng = path[0]; ns = path[1]; key = path.slice(2).join('.'); } if (result || !ignoreJSONStructure || !isString$1(key)) return result; return deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator); } addResource(lng, ns, key, value) { let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : { silent: false }; const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; let path = [lng, ns]; if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key); if (lng.indexOf('.') > -1) { path = lng.split('.'); value = ns; ns = path[1]; } this.addNamespaces(ns); setPath(this.data, path, value); if (!options.silent) this.emit('added', lng, ns, key, value); } addResources(lng, ns, resources) { let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : { silent: false }; for (const m in resources) { if (isString$1(resources[m]) || Array.isArray(resources[m])) this.addResource(lng, ns, m, resources[m], { silent: true }); } if (!options.silent) this.emit('added', lng, ns, resources); } addResourceBundle(lng, ns, resources, deep, overwrite) { let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : { silent: false, skipCopy: false }; let path = [lng, ns]; if (lng.indexOf('.') > -1) { path = lng.split('.'); deep = resources; resources = ns; ns = path[1]; } this.addNamespaces(ns); let pack = getPath(this.data, path) || {}; if (!options.skipCopy) resources = JSON.parse(JSON.stringify(resources)); if (deep) { deepExtend(pack, resources, overwrite); } else { pack = { ...pack, ...resources }; } setPath(this.data, path, pack); if (!options.silent) this.emit('added', lng, ns, resources); } removeResourceBundle(lng, ns) { if (this.hasResourceBundle(lng, ns)) { delete this.data[lng][ns]; } this.removeNamespaces(ns); this.emit('removed', lng, ns); } hasResourceBundle(lng, ns) { return this.getResource(lng, ns) !== undefined; } getResourceBundle(lng, ns) { if (!ns) ns = this.options.defaultNS; if (this.options.compatibilityAPI === 'v1') return { ...{}, ...this.getResource(lng, ns) }; return this.getResource(lng, ns); } getDataByLanguage(lng) { return this.data[lng]; } hasLanguageSomeTranslations(lng) { const data = this.getDataByLanguage(lng); const n = data && Object.keys(data) || []; return !!n.find(v => data[v] && Object.keys(data[v]).length > 0); } toJSON() { return this.data; } } var postProcessor = { processors: {}, addPostProcessor(module) { this.processors[module.name] = module; }, handle(processors, value, key, options, translator) { processors.forEach(processor => { if (this.processors[processor]) value = this.processors[processor].process(value, key, options, translator); }); return value; } }; const checkedLoadedFor = {}; class Translator extends EventEmitter { constructor(services) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; super(); copy$1(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector', 'i18nFormat', 'utils'], services, this); this.options = options; if (this.options.keySeparator === undefined) { this.options.keySeparator = '.'; } this.logger = baseLogger.create('translator'); } changeLanguage(lng) { if (lng) this.language = lng; } exists(key) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { interpolation: {} }; if (key === undefined || key === null) { return false; } const resolved = this.resolve(key, options); return resolved && resolved.res !== undefined; } extractFromKey(key, options) { let nsSeparator = options.nsSeparator !== undefined ? options.nsSeparator : this.options.nsSeparator; if (nsSeparator === undefined) nsSeparator = ':'; const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; let namespaces = options.ns || this.options.defaultNS || []; const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1; const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !options.keySeparator && !this.options.userDefinedNsSeparator && !options.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator); if (wouldCheckForNsInKey && !seemsNaturalLanguage) { const m = key.match(this.interpolator.nestingRegexp); if (m && m.length > 0) { return { key, namespaces: isString$1(namespaces) ? [namespaces] : namespaces }; } const parts = key.split(nsSeparator); if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift(); key = parts.join(keySeparator); } return { key, namespaces: isString$1(namespaces) ? [namespaces] : namespaces }; } translate(keys, options, lastKey) { if (typeof options !== 'object' && this.options.overloadTranslationOptionHandler) { options = this.options.overloadTranslationOptionHandler(arguments); } if (typeof options === 'object') options = { ...options }; if (!options) options = {}; if (keys === undefined || keys === null) return ''; if (!Array.isArray(keys)) keys = [String(keys)]; const returnDetails = options.returnDetails !== undefined ? options.returnDetails : this.options.returnDetails; const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; const { key, namespaces } = this.extractFromKey(keys[keys.length - 1], options); const namespace = namespaces[namespaces.length - 1]; const lng = options.lng || this.language; const appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode; if (lng && lng.toLowerCase() === 'cimode') { if (appendNamespaceToCIMode) { const nsSeparator = options.nsSeparator || this.options.nsSeparator; if (returnDetails) { return { res: `${namespace}${nsSeparator}${key}`, usedKey: key, exactUsedKey: key, usedLng: lng, usedNS: namespace, usedParams: this.getUsedParamsDetails(options) }; } return `${namespace}${nsSeparator}${key}`; } if (returnDetails) { return { res: key, usedKey: key, exactUsedKey: key, usedLng: lng, usedNS: namespace, usedParams: this.getUsedParamsDetails(options) }; } return key; } const resolved = this.resolve(keys, options); let res = resolved && resolved.res; const resUsedKey = resolved && resolved.usedKey || key; const resExactUsedKey = resolved && resolved.exactUsedKey || key; const resType = Object.prototype.toString.apply(res); const noObject = ['[object Number]', '[object Function]', '[object RegExp]']; const joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays; const handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject; const handleAsObject = !isString$1(res) && typeof res !== 'boolean' && typeof res !== 'number'; if (handleAsObjectInI18nFormat && res && handleAsObject && noObject.indexOf(resType) < 0 && !(isString$1(joinArrays) && Array.isArray(res))) { if (!options.returnObjects && !this.options.returnObjects) { if (!this.options.returnedObjectHandler) { this.logger.warn('accessing an object - but returnObjects options is not enabled!'); } const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, res, { ...options, ns: namespaces }) : `key '${key} (${this.language})' returned an object instead of string.`; if (returnDetails) { resolved.res = r; resolved.usedParams = this.getUsedParamsDetails(options); return resolved; } return r; } if (keySeparator) { const resTypeIsArray = Array.isArray(res); const copy = resTypeIsArray ? [] : {}; const newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey; for (const m in res) { if (Object.prototype.hasOwnProperty.call(res, m)) { const deepKey = `${newKeyToUse}${keySeparator}${m}`; copy[m] = this.translate(deepKey, { ...options, ...{ joinArrays: false, ns: namespaces } }); if (copy[m] === deepKey) copy[m] = res[m]; } } res = copy; } } else if (handleAsObjectInI18nFormat && isString$1(joinArrays) && Array.isArray(res)) { res = res.join(joinArrays); if (res) res = this.extendTranslation(res, keys, options, lastKey); } else { let usedDefault = false; let usedKey = false; const needsPluralHandling = options.count !== undefined && !isString$1(options.count); const hasDefaultValue = Translator.hasDefaultValue(options); const defaultValueSuffix = needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, options) : ''; const defaultValueSuffixOrdinalFallback = options.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, { ordinal: false }) : ''; const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi(); const defaultValue = needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] || options[`defaultValue${defaultValueSuffix}`] || options[`defaultValue${defaultValueSuffixOrdinalFallback}`] || options.defaultValue; if (!this.isValidLookup(res) && hasDefaultValue) { usedDefault = true; res = defaultValue; } if (!this.isValidLookup(res)) { usedKey = true; res = key; } const missingKeyNoValueFallbackToKey = options.missingKeyNoValueFallbackToKey || this.options.missingKeyNoValueFallbackToKey; const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? undefined : res; const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing; if (usedKey || usedDefault || updateMissing) { this.logger.log(updateMissing ? 'updateKey' : 'missingKey', lng, namespace, key, updateMissing ? defaultValue : res); if (keySeparator) { const fk = this.resolve(key, { ...options, keySeparator: false }); if (fk && fk.res) this.logger.warn('Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.'); } let lngs = []; const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language); if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) { for (let i = 0; i < fallbackLngs.length; i++) { lngs.push(fallbackLngs[i]); } } else if (this.options.saveMissingTo === 'all') { lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language); } else { lngs.push(options.lng || this.language); } const send = (l, k, specificDefaultValue) => { const defaultForMissing = hasDefaultValue && specificDefaultValue !== res ? specificDefaultValue : resForMissing; if (this.options.missingKeyHandler) { this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing, options); } else if (this.backendConnector && this.backendConnector.saveMissing) { this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing, options); } this.emit('missingKey', l, namespace, k, res); }; if (this.options.saveMissing) { if (this.options.saveMissingPlurals && needsPluralHandling) { lngs.forEach(language => { const suffixes = this.pluralResolver.getSuffixes(language, options); if (needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) { suffixes.push(`${this.options.pluralSeparator}zero`); } suffixes.forEach(suffix => { send([language], key + suffix, options[`defaultValue${suffix}`] || defaultValue); }); }); } else { send(lngs, key, defaultValue); } } } res = this.extendTranslation(res, keys, options, resolved, lastKey); if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = `${namespace}:${key}`; if ((usedKey || usedDefault) && this.options.parseMissingKeyHandler) { if (this.options.compatibilityAPI !== 'v1') { res = this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey ? `${namespace}:${key}` : key, usedDefault ? res : undefined); } else { res = this.options.parseMissingKeyHandler(res); } } } if (returnDetails) { resolved.res = res; resolved.usedParams = this.getUsedParamsDetails(options); return resolved; } return res; } extendTranslation(res, key, options, resolved, lastKey) { var _this = this; if (this.i18nFormat && this.i18nFormat.parse) { res = this.i18nFormat.parse(res, { ...this.options.interpolation.defaultVariables, ...options }, options.lng || this.language || resolved.usedLng, resolved.usedNS, resolved.usedKey, { resolved }); } else if (!options.skipInterpolation) { if (options.interpolation) this.interpolator.init({ ...options, ...{ interpolation: { ...this.options.interpolation, ...options.interpolation } } }); const skipOnVariables = isString$1(res) && (options && options.interpolation && options.interpolation.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables); let nestBef; if (skipOnVariables) { const nb = res.match(this.interpolator.nestingRegexp); nestBef = nb && nb.length; } let data = options.replace && !isString$1(options.replace) ? options.replace : options; if (this.options.interpolation.defaultVariables) data = { ...this.options.interpolation.defaultVariables, ...data }; res = this.interpolator.interpolate(res, data, options.lng || this.language || resolved.usedLng, options); if (skipOnVariables) { const na = res.match(this.interpolator.nestingRegexp); const nestAft = na && na.length; if (nestBef < nestAft) options.nest = false; } if (!options.lng && this.options.compatibilityAPI !== 'v1' && resolved && resolved.res) options.lng = this.language || resolved.usedLng; if (options.nest !== false) res = this.interpolator.nest(res, function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (lastKey && lastKey[0] === args[0] && !options.context) { _this.logger.warn(`It seems you are nesting recursively key: ${args[0]} in key: ${key[0]}`); return null; } return _this.translate(...args, key); }, options); if (options.interpolation) this.interpolator.reset(); } const postProcess = options.postProcess || this.options.postProcess; const postProcessorNames = isString$1(postProcess) ? [postProcess] : postProcess; if (res !== undefined && res !== null && postProcessorNames && postProcessorNames.length && options.applyPostProcessor !== false) { res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? { i18nResolved: { ...resolved, usedParams: this.getUsedParamsDetails(options) }, ...options } : options, this); } return res; } resolve(keys) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; let found; let usedKey; let exactUsedKey; let usedLng; let usedNS; if (isString$1(keys)) keys = [keys]; keys.forEach(k => { if (this.isValidLookup(found)) return; const extracted = this.extractFromKey(k, options); const key = extracted.key; usedKey = key; let namespaces = extracted.namespaces; if (this.options.fallbackNS) namespaces = namespaces.concat(this.options.fallbackNS); const needsPluralHandling = options.count !== undefined && !isString$1(options.count); const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi(); const needsContextHandling = options.context !== undefined && (isString$1(options.context) || typeof options.context === 'number') && options.context !== ''; const codes = options.lngs ? options.lngs : this.languageUtils.toResolveHierarchy(options.lng || this.language, options.fallbackLng); namespaces.forEach(ns => { if (this.isValidLookup(found)) return; usedNS = ns; if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils && this.utils.hasLoadedNamespace && !this.utils.hasLoadedNamespace(usedNS)) { checkedLoadedFor[`${codes[0]}-${ns}`] = true; this.logger.warn(`key "${usedKey}" for languages "${codes.join(', ')}" won't get resolved as namespace "${usedNS}" was not yet loaded`, 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!'); } codes.forEach(code => { if (this.isValidLookup(found)) return; usedLng = code; const finalKeys = [key]; if (this.i18nFormat && this.i18nFormat.addLookupKeys) { this.i18nFormat.addLookupKeys(finalKeys, key, code, ns, options); } else { let pluralSuffix; if (needsPluralHandling) pluralSuffix = this.pluralResolver.getSuffix(code, options.count, options); const zeroSuffix = `${this.options.pluralSeparator}zero`; const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`; if (needsPluralHandling) { finalKeys.push(key + pluralSuffix); if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) { finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator)); } if (needsZeroSuffixLookup) { finalKeys.push(key + zeroSuffix); } } if (needsContextHandling) { const contextKey = `${key}${this.options.contextSeparator}${options.context}`; finalKeys.push(contextKey); if (needsPluralHandling) { finalKeys.push(contextKey + pluralSuffix); if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) { finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator)); } if (needsZeroSuffixLookup) { finalKeys.push(contextKey + zeroSuffix); } } } } let possibleKey; while (possibleKey = finalKeys.pop()) { if (!this.isValidLookup(found)) { exactUsedKey = possibleKey; found = this.getResource(code, ns, possibleKey, options); } } }); }); }); return { res: found, usedKey, exactUsedKey, usedLng, usedNS }; } isValidLookup(res) { return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === ''); } getResource(code, ns, key) { let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; if (this.i18nFormat && this.i18nFormat.getResource) return this.i18nFormat.getResource(code, ns, key, options); return this.resourceStore.getResource(code, ns, key, options); } getUsedParamsDetails() { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; const optionsKeys = ['defaultValue', 'ordinal', 'context', 'replace', 'lng', 'lngs', 'fallbackLng', 'ns', 'keySeparator', 'nsSeparator', 'returnObjects', 'returnDetails', 'joinArrays', 'postProcess', 'interpolation']; const useOptionsReplaceForData = options.replace && !isString$1(options.replace); let data = useOptionsReplaceForData ? options.replace : options; if (useOptionsReplaceForData && typeof options.count !== 'undefined') { data.count = options.count; } if (this.options.interpolation.defaultVariables) { data = { ...this.options.interpolation.defaultVariables, ...data }; } if (!useOptionsReplaceForData) { data = { ...data }; for (const key of optionsKeys) { delete data[key]; } } return data; } static hasDefaultValue(options) { const prefix = 'defaultValue'; for (const option in options) { if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && undefined !== options[option]) { return true; } } return false; } } const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1); class LanguageUtil { constructor(options) { this.options = options; this.supportedLngs = this.options.supportedLngs || false; this.logger = baseLogger.create('languageUtils'); } getScriptPartFromCode(code) { code = getCleanedCode(code); if (!code || code.indexOf('-') < 0) return null; const p = code.split('-'); if (p.length === 2) return null; p.pop(); if (p[p.length - 1].toLowerCase() === 'x') return null; return this.formatLanguageCode(p.join('-')); } getLanguagePartFromCode(code) { code = getCleanedCode(code); if (!code || code.indexOf('-') < 0) return code; const p = code.split('-'); return this.formatLanguageCode(p[0]); } formatLanguageCode(code) { if (isString$1(code) && code.indexOf('-') > -1) { if (typeof Intl !== 'undefined' && typeof Intl.getCanonicalLocales !== 'undefined') { try { let formattedCode = Intl.getCanonicalLocales(code)[0]; if (formattedCode && this.options.lowerCaseLng) { formattedCode = formattedCode.toLowerCase(); } if (formattedCode) return formattedCode; } catch (e) {} } const specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab']; let p = code.split('-'); if (this.options.lowerCaseLng) { p = p.map(part => part.toLowerCase()); } else if (p.length === 2) { p[0] = p[0].toLowerCase(); p[1] = p[1].toUpperCase(); if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase()); } else if (p.length === 3) { p[0] = p[0].toLowerCase(); if (p[1].length === 2) p[1] = p[1].toUpperCase(); if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase(); if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase()); if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase()); } return p.join('-'); } return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code; } isSupportedCode(code) { if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) { code = this.getLanguagePartFromCode(code); } return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1; } getBestMatchFromCodes(codes) { if (!codes) return null; let found; codes.forEach(code => { if