UNPKG

14.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = exports.HydrationStateToken = void 0;
7
8var _fusionTokens = require("fusion-tokens");
9
10var _fusionCore = require("fusion-core");
11
12var _fusionPluginUniversalEvents = require("fusion-plugin-universal-events");
13
14/** Copyright (c) 2018 Uber Technologies, Inc.
15 *
16 * This source code is licensed under the MIT license found in the
17 * LICENSE file in the root directory of this source tree.
18 *
19 *
20 */
21
22/* eslint-env browser */
23function loadTranslations() {
24 const element = document.getElementById('__TRANSLATIONS__');
25
26 if (!element) {
27 throw new Error('[fusion-plugin-i18n] - Could not find a __TRANSLATIONS__ element');
28 }
29
30 try {
31 return JSON.parse((0, _fusionCore.unescape)(element.textContent));
32 } catch (e) {
33 throw new Error('[fusion-plugin-i18n] - Error parsing __TRANSLATIONS__ element content');
34 }
35}
36
37const HydrationStateToken = (0, _fusionCore.createToken)('HydrationStateToken');
38exports.HydrationStateToken = HydrationStateToken;
39
40const pluginFactory = () => (0, _fusionCore.createPlugin)({
41 deps: {
42 fetch: _fusionTokens.FetchToken.optional,
43 hydrationState: HydrationStateToken.optional,
44 events: _fusionPluginUniversalEvents.UniversalEventsToken.optional
45 },
46 provides: ({
47 fetch = window.fetch,
48 hydrationState,
49 events
50 } = {}) => {
51 class I18n {
52 constructor() {
53 const {
54 localeCode,
55 translations
56 } = hydrationState || loadTranslations();
57 this.requestedKeys = new Set();
58 this.translations = translations || {};
59
60 if (localeCode) {
61 this.locale = localeCode;
62 }
63 }
64
65 async load(translationKeys) {
66 const loadedKeys = Object.keys(this.translations);
67 const unloaded = translationKeys.filter(key => {
68 return loadedKeys.indexOf(key) < 0 && !this.requestedKeys.has(key);
69 });
70
71 if (unloaded.length > 0) {
72 // Don't try to load translations again if a request is already in
73 // flight. This means that we need to add unloaded chunks to
74 // loadedChunks optimistically and remove them if some error happens
75 unloaded.forEach(key => {
76 this.requestedKeys.add(key);
77 });
78 const fetchOpts = {
79 method: 'POST',
80 headers: {
81 Accept: '*/*',
82 'Content-Type': 'application/json',
83 ...(this.locale ? {
84 'X-Fusion-Locale-Code': this.locale
85 } : {})
86 },
87 body: JSON.stringify(unloaded)
88 }; // TODO(#3) don't append prefix if injected fetch also injects prefix
89
90 return fetch(`/_translations${this.locale ? `?localeCode=${this.locale}` : ''}`, fetchOpts).then(r => r.json()).then(data => {
91 for (const key in data) {
92 this.translations[key] = data[key];
93 this.requestedKeys.delete(key);
94 }
95 }).catch(err => {
96 // An error occurred, so remove the chunks we were trying to load
97 // from loadedChunks. This allows us to try to load those chunk
98 // translations again
99 unloaded.forEach(key => {
100 this.requestedKeys.delete(key);
101 });
102 throw err;
103 });
104 }
105 }
106
107 translate(key, interpolations = {}) {
108 const template = this.translations[key];
109
110 if (typeof template !== 'string') {
111 events && events.emit('i18n-translate-miss', {
112 key
113 });
114 return key;
115 }
116
117 return template.replace(/\${(.*?)}/g, (_, k) => interpolations[k] === void 0 ? '${' + k + '}' : String(interpolations[k]));
118 }
119
120 }
121
122 const i18n = new I18n();
123 return {
124 from: () => i18n
125 };
126 }
127});
128
129var _default = false && pluginFactory();
130
131exports.default = _default;
132//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJyb3dzZXIuanMiXSwibmFtZXMiOlsibG9hZFRyYW5zbGF0aW9ucyIsImVsZW1lbnQiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiRXJyb3IiLCJKU09OIiwicGFyc2UiLCJ0ZXh0Q29udGVudCIsImUiLCJIeWRyYXRpb25TdGF0ZVRva2VuIiwicGx1Z2luRmFjdG9yeSIsImRlcHMiLCJmZXRjaCIsIkZldGNoVG9rZW4iLCJvcHRpb25hbCIsImh5ZHJhdGlvblN0YXRlIiwiZXZlbnRzIiwiVW5pdmVyc2FsRXZlbnRzVG9rZW4iLCJwcm92aWRlcyIsIndpbmRvdyIsIkkxOG4iLCJjb25zdHJ1Y3RvciIsImxvY2FsZUNvZGUiLCJ0cmFuc2xhdGlvbnMiLCJyZXF1ZXN0ZWRLZXlzIiwiU2V0IiwibG9jYWxlIiwibG9hZCIsInRyYW5zbGF0aW9uS2V5cyIsImxvYWRlZEtleXMiLCJPYmplY3QiLCJrZXlzIiwidW5sb2FkZWQiLCJmaWx0ZXIiLCJrZXkiLCJpbmRleE9mIiwiaGFzIiwibGVuZ3RoIiwiZm9yRWFjaCIsImFkZCIsImZldGNoT3B0cyIsIm1ldGhvZCIsImhlYWRlcnMiLCJBY2NlcHQiLCJib2R5Iiwic3RyaW5naWZ5IiwidGhlbiIsInIiLCJqc29uIiwiZGF0YSIsImRlbGV0ZSIsImNhdGNoIiwiZXJyIiwidHJhbnNsYXRlIiwiaW50ZXJwb2xhdGlvbnMiLCJ0ZW1wbGF0ZSIsImVtaXQiLCJyZXBsYWNlIiwiXyIsImsiLCJTdHJpbmciLCJpMThuIiwiZnJvbSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBOztBQUNBOztBQUVBOztBQVpBOzs7Ozs7OztBQVFBO0FBZ0JBLFNBQVNBLGdCQUFULEdBQW9EO0FBQ2xELFFBQU1DLE9BQU8sR0FBR0MsUUFBUSxDQUFDQyxjQUFULENBQXdCLGtCQUF4QixDQUFoQjs7QUFDQSxNQUFJLENBQUNGLE9BQUwsRUFBYztBQUNaLFVBQU0sSUFBSUcsS0FBSixDQUNKLGtFQURJLENBQU47QUFHRDs7QUFDRCxN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WkksRUFhSmlCLEtBYkksQ0FhR0MsR0FBRCxJQUFnQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQXBCLFlBQUFBLFFBQVEsQ0FBQ00sT0FBVCxDQUFpQkosR0FBRyxJQUFJO0FBQ3RCLG1CQUFLVixhQUFMLENBQW1CMEIsTUFBbkIsQ0FBMEJoQixHQUExQjtBQUNELGFBRkQ7QUFHQSxrQkFBTWtCLEdBQU47QUFDRCxXQXJCSSxDQUFQO0FBc0JEO0FBQ0Y7O0FBQ0RDLE1BQUFBLFNBQVMsQ0FBQ25CLEdBQUQsRUFBTW9CLGNBQWMsR0FBRyxFQUF2QixFQUEyQjtBQUNsQyxjQUFNQyxRQUFRLEdBQUcsS0FBS2hDLFlBQUwsQ0FBa0JXLEdBQWxCLENBQWpCOztBQUVBLFlBQUksT0FBT3FCLFFBQVAsS0FBb0IsUUFBeEIsRUFBa0M7QUFDaEN2QyxVQUFBQSxNQUFNLElBQUlBLE1BQU0sQ0FBQ3dDLElBQVAsQ0FBWSxxQkFBWixFQUFtQztBQUFDdEIsWUFBQUE7QUFBRCxXQUFuQyxDQUFWO0FBQ0EsaUJBQU9BLEdBQVA7QUFDRDs7QUFFRCxlQUFPcUIsUUFBUSxDQUFDRSxPQUFULENBQWlCLFlBQWpCLEVBQStCLENBQUNDLENBQUQsRUFBSUMsQ0FBSixLQUNwQ0wsY0FBYyxDQUFDSyxDQUFELENBQWQsS0FBc0IsS0FBSyxDQUEzQixHQUNJLE9BQU9BLENBQVAsR0FBVyxHQURmLEdBRUlDLE1BQU0sQ0FBQ04sY0FBYyxDQUFDSyxDQUFELENBQWYsQ0FITCxDQUFQO0FBS0Q7O0FBekVROztBQTJFWCxVQUFNRSxJQUFJLEdBQUcsSUFBSXpDLElBQUosRUFBYjtBQUNBLFdBQU87QUFBQzBDLE1BQUFBLElBQUksRUFBRSxNQUFNRDtBQUFiLEtBQVA7QUFDRDtBQXBGVSxDQUFiLENBREY7O2VBd0ZpQixTQUFlbkQsYUFBYSxFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIENvcHlyaWdodCAoYykgMjAxOCBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqIEBmbG93XG4gKi9cblxuLyogZXNsaW50LWVudiBicm93c2VyICovXG5pbXBvcnQge0ZldGNoVG9rZW59IGZyb20gJ2Z1c2lvbi10b2tlbnMnO1xuaW1wb3J0IHtjcmVhdGVQbHVnaW4sIHVuZXNjYXBlLCBjcmVhdGVUb2tlbn0gZnJvbSAnZnVzaW9uLWNvcmUnO1xuaW1wb3J0IHR5cGUge0Z1c2lvblBsdWdpbiwgVG9rZW59IGZyb20gJ2Z1c2lvbi1jb3JlJztcbmltcG9ydCB7VW5pdmVyc2FsRXZlbnRzVG9rZW59IGZyb20gJ2Z1c2lvbi1wbHVnaW4tdW5pdmVyc2FsLWV2ZW50cyc7XG5cbmltcG9ydCB0eXBlIHtcbiAgSTE4bkRlcHNUeXBlLFxuICBJMThuU2VydmljZVR5cGUsXG4gIFRyYW5zbGF0aW9uc09iamVjdFR5cGUsXG59IGZyb20gJy4vdHlwZXMuanMnO1xuXG50eXBlIExvYWRlZFRyYW5zbGF0aW9uc1R5cGUgPSB7XG4gIGxvY2FsZUNvZGU/OiBzdHJpbmcsXG4gIHRyYW5zbGF0aW9ucz86IFRyYW5zbGF0aW9uc09iamVjdFR5cGUsXG59O1xuZnVuY3Rpb24gbG9hZFRyYW5zbGF0aW9ucygpOiBMb2FkZWRUcmFuc2xhdGlvbnNUeXBlIHtcbiAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdfX1RSQU5TTEFUSU9OU19fJyk7XG4gIGlmICghZWxlbWVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdbZnVzaW9uLXBsdWdpbi1pMThuXSAtIENvdWxkIG5vdCBmaW5kIGEgX19UUkFOU0xBVElPTlNfXyBlbGVtZW50J1xuICAgICk7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZSh1bmVzY2FwZShlbGVtZW50LnRleHRDb250ZW50KSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnW2Z1c2lvbi1wbHVnaW4taTE4bl0gLSBFcnJvciBwYXJzaW5nIF9fVFJBTlNMQVRJT05TX18gZWxlbWVudCBjb250ZW50J1xuICAgICk7XG4gIH1cbn1cblxudHlwZSBIeWRyYXRpb25TdGF0ZVR5cGUgPSB7XG4gIGxvY2FsZUNvZGU/OiBzdHJpbmcsXG4gIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zT2JqZWN0VHlwZSxcbn07XG5leHBvcnQgY29uc3QgSHlkcmF0aW9uU3RhdGVUb2tlbjogVG9rZW48SHlkcmF0aW9uU3RhdGVUeXBlPiA9IGNyZWF0ZVRva2VuKFxuICAnSHlkcmF0aW9uU3RhdGVUb2tlbidcbik7XG5cbnR5cGUgUGx1Z2luVHlwZSA9IEZ1c2lvblBsdWdpbjxJMThuRGVwc1R5cGUsIEkxOG5TZXJ2aWNlVHlwZT47XG5jb25zdCBwbHVnaW5GYWN0b3J5OiAoKSA9PiBQbHVnaW5UeXBlID0gKCkgPT5cbiAgY3JlYXRlUGx1Z2luKHtcbiAgICBkZXBzOiB7XG4gICAgICBmZXRjaDogRmV0Y2hUb2tlbi5vcHRpb25hbCxcbiAgICAgIGh5ZHJhdGlvblN0YXRlOiBIeWRyYXRpb25TdGF0ZVRva2VuLm9wdGlvbmFsLFxuICAgICAgZXZlbnRzOiBVbml2ZXJzYWxFdmVudHNUb2tlbi5vcHRpb25hbCxcbiAgICB9LFxuICAgIHByb3ZpZGVzOiAoe2ZldGNoID0gd2luZG93LmZldGNoLCBoeWRyYXRpb25TdGF0ZSwgZXZlbnRzfSA9IHt9KSA9PiB7XG4gICAgICBjbGFzcyBJMThuIHtcbiAgICAgICAgbG9jYWxlOiBzdHJpbmc7XG4gICAgICAgIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zT2JqZWN0VHlwZTtcbiAgICAgICAgcmVxdWVzdGVkS2V5czogU2V0PHN0cmluZz47XG5cbiAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgY29uc3Qge2xvY2FsZUNvZGUsIHRyYW5zbGF0aW9uc30gPVxuICAgICAgICAgICAgaHlkcmF0aW9uU3RhdGUgfHwgbG9hZFRyYW5zbGF0aW9ucygpO1xuICAgICAgICAgIHRoaXMucmVxdWVzdGVkS2V5cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0aW9ucyA9IHRyYW5zbGF0aW9ucyB8fCB7fTtcbiAgICAgICAgICBpZiAobG9jYWxlQ29kZSkge1xuICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGVDb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhc3luYyBsb2FkKHRyYW5zbGF0aW9uS2V5cykge1xuICAgICAgICAgIGNvbnN0IGxvYWRlZEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnRyYW5zbGF0aW9ucyk7XG4gICAgICAgICAgY29uc3QgdW5sb2FkZWQgPSB0cmFuc2xhdGlvbktleXMuZmlsdGVyKGtleSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbG9hZGVkS2V5cy5pbmRleE9mKGtleSkgPCAwICYmICF0aGlzLnJlcXVlc3RlZEtleXMuaGFzKGtleSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKHVubG9hZGVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIERvbid0IHRyeSB0byBsb2FkIHRyYW5zbGF0aW9ucyBhZ2FpbiBpZiBhIHJlcXVlc3QgaXMgYWxyZWFkeSBpblxuICAgICAgICAgICAgLy8gZmxpZ2h0LiBUaGlzIG1lYW5zIHRoYXQgd2UgbmVlZCB0byBhZGQgdW5sb2FkZWQgY2h1bmtzIHRvXG4gICAgICAgICAgICAvLyBsb2FkZWRDaHVua3Mgb3B0aW1pc3RpY2FsbHkgYW5kIHJlbW92ZSB0aGVtIGlmIHNvbWUgZXJyb3IgaGFwcGVuc1xuICAgICAgICAgICAgdW5sb2FkZWQuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RlZEtleXMuYWRkKGtleSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGZldGNoT3B0cyA9IHtcbiAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICBBY2NlcHQ6ICcqLyonLFxuICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgICAgLi4uKHRoaXMubG9jYWxlID8geydYLUZ1c2lvbi1Mb2NhbGUtQ29kZSc6IHRoaXMubG9jYWxlfSA6IHt9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkodW5sb2FkZWQpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE8oIzMpIGRvbid0IGFwcGVuZCBwcmVmaXggaWYgaW5qZWN0ZWQgZmV0Y2ggYWxzbyBpbmplY3RzIHByZWZpeFxuICAgICAgICAgICAgcmV0dXJuIGZldGNoKFxuICAgICAgICAgICAgICBgL190cmFuc2xhdGlvbnMke1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlID8gYD9sb2NhbGVDb2RlPSR7dGhpcy5sb2NhbGV9YCA6ICcnXG4gICAgICAgICAgICAgIH1gLFxuICAgICAgICAgICAgICBmZXRjaE9wdHNcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnRoZW4ociA9PiByLmpzb24oKSlcbiAgICAgICAgICAgICAgLnRoZW4oKGRhdGE6IHtbc3RyaW5nXTogc3RyaW5nfSkgPT4ge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRpb25zW2tleV0gPSBkYXRhW2tleV07XG4gICAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RlZEtleXMuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuY2F0Y2goKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBBbiBlcnJvciBvY2N1cnJlZCwgc28gcmVtb3ZlIHRoZSBjaHVua3Mgd2Ugd2VyZSB0cnlpbmcgdG8gbG9hZFxuICAgICAgICAgICAgICAgIC8vIGZyb20gbG9hZGVkQ2h1bmtzLiBUaGlzIGFsbG93cyB1cyB0byB0cnkgdG8gbG9hZCB0aG9zZSBjaHVua1xuICAgICAgICAgICAgICAgIC8vIHRyYW5zbGF0aW9ucyBhZ2FpblxuICAgICAgICAgICAgICAgIHVubG9hZGVkLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVxdWVzdGVkS2V5cy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cmFuc2xhdGUoa2V5LCBpbnRlcnBvbGF0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLnRyYW5zbGF0aW9uc1trZXldO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGV2ZW50cyAmJiBldmVudHMuZW1pdCgnaTE4bi10cmFuc2xhdGUtbWlzcycsIHtrZXl9KTtcbiAgICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL1xcJHsoLio/KX0vZywgKF8sIGspID0+XG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uc1trXSA9PT0gdm9pZCAwXG4gICAgICAgICAgICAgID8gJyR7JyArIGsgKyAnfSdcbiAgICAgICAgICAgICAgOiBTdHJpbmcoaW50ZXJwb2xhdGlvbnNba10pXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgaTE4biA9IG5ldyBJMThuKCk7XG4gICAgICByZXR1cm4ge2Zyb206ICgpID0+IGkxOG59O1xuICAgIH0sXG4gIH0pO1xuXG5leHBvcnQgZGVmYXVsdCAoKF9fQlJPV1NFUl9fICYmIHBsdWdpbkZhY3RvcnkoKTogYW55KTogUGx1Z2luVHlwZSk7XG4iXX0=
\No newline at end of file