@atlassian/wrm-react-i18n
Version: 
An internationalization i18n helper for WRM and React that can be used in Atlassian Server products
90 lines (85 loc) • 4.47 kB
JavaScript
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('wrm/format')) :
    typeof define === 'function' && define.amd ? define(['exports', 'react', 'wrm/format'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@atlassian/wrm-react-i18n"] = {}, global.React, global.wrmFormat));
})(this, (function (exports, React, wrmFormat) { 'use strict';
    // backward-compatibility with WRM < 4.2 where wrm/i18n is not available yet
    const WrmI18n = function () {
      try {
        // eslint-disable-next-line @typescript-eslint/no-var-requires
        return require('wrm/i18n'); // A module provided in browser runtime by WRM >= 4.2
      } catch (e) {
        return null;
      }
    }();
    function format(translation, ...args) {
      let i = 0;
      const mapping = {};
      const mappedArgs = args.map(arg => {
        if (/*#__PURE__*/React.isValidElement(arg)) {
          const str = `!PLACEHOLDER_${++i}!`;
          mapping[str] = arg;
          return str;
        }
        return arg;
      });
      const strParts = wrmFormat(translation, ...mappedArgs).split(/(!PLACEHOLDER_\d+!)/g);
      if (strParts.length === 1) {
        return strParts.join('');
      }
      const asReactEls = strParts.map((str, idx) => {
        return /*#__PURE__*/React.createElement(React.Fragment, {
          key: idx
        }, idx % 2 ? mapping[str] : str);
      });
      return /*#__PURE__*/React.createElement(React.Fragment, null, asReactEls);
    }
    const getText = (key, ...args) => {
      /**
       * What's going on here? There are two scenarios to consider:
       * 1) Regular i18n mechanism replacing "<>.getText(...)" at run-time on the back-end side;
       *    it's an error when the execution enters this function and a message in the console
       *    will be printed (coming from WRM code), in the UI raw i18n key will be displayed.
       * 2) When WRM two-phases i18n mechanism is used, it's expected that execution enters
       *    this function and we need to call the original WRM's getText function, because
       *    it holds the i18n->translation Map (the translation is done at the client-side);
       *    however this package 'wrm-react-i18n' adds a support for React components by
       *    providing a different 'format' function; hence a problem in 2) scenario, because
       *    by calling the original WRM's getText function, the original WRM's format function
       *    is also called. That's why we're swapping the WRM's format function to the
       *    React-enhanced version of it, due to the lack of a better alternative atm.
       *    The swap is done just for a single execution of WRM's getText function;
       *    all the code is synchronous, hence there's no chance of affecting other places;
       *    in other words the swap is atomic / completely transparent to the outside world.
       * 3) At run-times with WRM < 4.2, "wrm/i18n" module is not available yet, in this case
       *    falling back to the previous implementation: calling enhanced 'format' function.
       */
      // for WRM < 4.2
      if (!WrmI18n) {
        // The warning should be kept in production bundle
        if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') {
          console.warn('Call to "getText" function was not replaced with either raw translation or call to "format" function. Have you included the "jsI18n" transformation in Web Resource Manager?');
        }
        return format(key, ...args);
      }
      // for WRM >= 4.2
      let result;
      try {
        WRM.I18n.format = format;
        result = WrmI18n.getText.apply(null, [key, ...args]);
      } finally {
        WRM.I18n.format = wrmFormat;
      }
      return result;
    };
    // We need to re-export the fake "getText" since "<<namespace>>.I18n.getText()" is used in the source code and then
    // replaced to "<<namespace>>.format()" by either jsI18n transformer or @atlassian/i18n-properties-loader webpack loader.
    // However, when two-phases i18n is used (since WRM 5.3+/AMPS 8.3+) "<<namespace>>.I18n.getText()" is not replaced and
    // "getText" should call the original "getText" function from WRM.
    const I18n = {
      getText
    };
    exports.I18n = I18n;
    exports.format = format;
}));
//# sourceMappingURL=wrm-react-i18n.js.map