<commit_before>'use strict';

import { L10nError } from '../../lib/errors';

export function serializeContext(ctx, lang) {
  const cache = ctx._env._resCache;
  return ctx._resIds.reduceRight(([errorsSeq, entriesSeq], cur) => {
    const sourceRes = cache[cur + 'en-USapp'];
    const langRes = cache[cur + lang.code + lang.src];
    const [errors, entries] = serializeEntries(
      lang,
      langRes instanceof L10nError ? {} : langRes,
      sourceRes instanceof L10nError ? {} : sourceRes);
    return [errorsSeq.concat(errors), extend(entriesSeq, entries)];
  }, [[], Object.create(null)]);
}

function serializeEntries(lang, langEntries, sourceEntries) {
  const errors = [];
  const entries = Object.create(null);

  for (let id in sourceEntries) {
    const sourceEntry = sourceEntries[id];
    const langEntry = langEntries[id];

    if (!langEntry) {
      errors.push(new L10nError(
        '"' + id + '"' + ' not found in ' + lang.code, id, lang));
      entries[id] = sourceEntry;
      continue;
    }

    if (!areEntityStructsEqual(sourceEntry, langEntry)) {
      errors.push(new L10nError(
        '"' + id + '"' + ' is malformed in ' + lang.code, id, lang));
      entries[id] = sourceEntry;
      continue;
    }

    entries[id] = langEntry;
  }

  return [errors, entries];
}

function extend(target, source) {
  for (let key in source) {
    // overwrite existing keys for reduceRight
    target[key] = source[key];
  }
  return target;
}

function resolvesToString(entity) {
  return typeof entity === 'string' ||  // a simple string
    typeof entity.value === 'string' || // a simple string, entity with attrs
    Array.isArray(entity.value) ||      // a complex string
    entity.index !== null;              // a dict with an index
}

function areEntityStructsEqual(entity1, entity2) {
  if (resolvesToString(entity1) && resolvesToString(entity2)) {
    return true;
  }

  const keys1 = Object.keys(entity1);
  const keys2 = Object.keys(entity2);<commit_msg>Use Object.assign<commit_after>'use strict';

import { L10nError } from '../../lib/errors';

export function serializeContext(ctx, lang) {
  const cache = ctx._env._resCache;
  return ctx._resIds.reduceRight(([errorsSeq, entriesSeq], cur) => {
    const sourceRes = cache[cur + 'en-USapp'];
    const langRes = cache[cur + lang.code + lang.src];
    const [errors, entries] = serializeEntries(
      lang,
      langRes instanceof L10nError ? {} : langRes,
      sourceRes instanceof L10nError ? {} : sourceRes);
    return [errorsSeq.concat(errors), Object.assign(entriesSeq, entries)];
  }, [[], Object.create(null)]);
}

function serializeEntries(lang, langEntries, sourceEntries) {
  const errors = [];
  const entries = Object.create(null);

  for (let id in sourceEntries) {
    const sourceEntry = sourceEntries[id];
    const langEntry = langEntries[id];

    if (!langEntry) {
      errors.push(new L10nError(
        '"' + id + '"' + ' not found in ' + lang.code, id, lang));
      entries[id] = sourceEntry;
      continue;
    }

    if (!areEntityStructsEqual(sourceEntry, langEntry)) {
      errors.push(new L10nError(
        '"' + id + '"' + ' is malformed in ' + lang.code, id, lang));
      entries[id] = sourceEntry;
      continue;
    }

    entries[id] = langEntry;
  }

  return [errors, entries];
}

function resolvesToString(entity) {
  return typeof entity === 'string' ||  // a simple string
    typeof entity.value === 'string' || // a simple string, entity with attrs
    Array.isArray(entity.value) ||      // a complex string
    entity.index !== null;              // a dict with an index
}

function areEntityStructsEqual(entity1, entity2) {
  if (resolvesToString(entity1) && resolvesToString(entity2)) {
    return true;
  }

  const keys1 = Object.keys(entity1);
  const keys2 = Object.keys(entity2);
{'fraction_non_alphanumeric': 0.14013071895424836, 'fraction_numerical': 0.009411764705882352, 'mean_word_length': 3.2136563876651985, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3205644', 'n_tokens_mistral': 1189, 'n_tokens_neox': 1169, 'n_words': 299}