{"size": 3021, "ext": "js", "max_stars_repo_path": "src/Dictionary.js", "max_stars_repo_name": "devbridge/reword-js", "max_stars_repo_stars_event_min_datetime": "2018-11-09T13:43:16.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-11T15:51:43.000Z", "max_issues_repo_path": "src/Dictionary.js", "max_issues_repo_name": "devbridge/reword-js", "max_issues_repo_issues_event_min_datetime": "2022-01-22T03:06:46.000Z", "max_issues_repo_issues_event_max_datetime": "2022-01-22T03:06:46.000Z", "max_forks_repo_path": "src/Dictionary.js", "max_forks_repo_name": "devbridge/reword-js", "max_forks_repo_forks_event_min_datetime": "2018-11-12T13:46:35.000Z", "max_forks_repo_forks_event_max_datetime": "2020-04-19T19:39:37.000Z"}
{"max_stars_count": 13, "max_issues_count": 1, "max_forks_count": 4, "avg_line_length": 30.5151515152, "max_line_length": 106, "alphanum_fraction": 0.6961271102}
import {
  DEFAULT_LOCALE, VAR_REGEX, PLACEHOLDER, PLACEHOLDER_REGEX, TEXT,
} from './constants';
import { isDevelopment } from './env';
import { getTextWithPlaceholders, generateTranslationMap } from './mapUtilities';
import Reporting from './Reporting';
import validateTranslations from './validateTranslations';
import get from './utils/get';

function fillWithValues(text, interpolations = [], positions = []) {
  let index = 0;

  return text.replace(PLACEHOLDER_REGEX, () => {
    const position = typeof positions[index] === 'undefined' ? index : positions[index];
    const interpolation = typeof interpolations[position] === 'undefined' ? '' : interpolations[position];
    index += 1;

    return interpolation;
  });
}

const defaultOptions = {
  defaultLocale: DEFAULT_LOCALE,
  locale: DEFAULT_LOCALE,
  variableMatcher: VAR_REGEX,
  placeholderMatcher: PLACEHOLDER_REGEX,
  placeholder: PLACEHOLDER,
  debug: isDevelopment(),
  translationNotFoundMessage: TEXT.TRANSLATION_NOT_FOUND,
};

export default class Dictionary {
  constructor(dictionary = {}, options = {}) {
    this.config(dictionary, options);
    this.initialised = true;
  }

  config = (dictionary = {}, options = {}) => {
    this.options = { ...defaultOptions, ...options };
    this.reporting = new Reporting({ debug: this.options.debug });
    this.updateDictionary(dictionary);
    this.translationMap = generateTranslationMap(this.dictionary, this.options);
  };

  changeLocale = (locale) => {
    this.options.locale = locale;
    this.translationMap = generateTranslationMap(this.dictionary, this.options);
  };

  updateDictionary = (dictionary) => {
    this.dictionary = dictionary;

    const errors = validateTranslations(dictionary);

    if (errors.length) {
      this.reporting.table(errors);
    }

    this.translationMap = generateTranslationMap(this.dictionary, this.options);
  };

  translate = (strings, ...interpolations) => {
    const fragments = Array.isArray(strings)
      ? strings
      : [getTextWithPlaceholders(strings, this.options)];
    const template = fragments.join(PLACEHOLDER).trim();
    const translation = this.translationMap[template];

    if (!translation && this.initialised) {
      this.reporting.warn(
        `Translation not found for template "${template}" current locale "${this.options.locale}"`,
      );
    }

    if (!translation) {
      return fillWithValues(fragments.join(PLACEHOLDER), interpolations);
    }

    const { text, positions } = translation;

    return fillWithValues(text, interpolations, positions);
  };

  translateKey = (key, ...interpolations) => {
    const defaultTranslation = get(this.dictionary[this.options.defaultLocale], key, '');
    const translation = this.translationMap[
      getTextWithPlaceholders(defaultTranslation, this.options)
    ];

    if (!translation) {
      return this.options.translationNotFoundMessage;
    }

    const { text, positions } = translation;

    return fillWithValues(text, interpolations, positions);
  };
}
