all files / src/ normalizeFields.js

98.31% Statements 58/59
94% Branches 47/50
100% Functions 7/7
97.92% Lines 47/48
6 statements, 1 function, 3 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116   68× 68× 68×   68×       68× 68× 68×   68× 16× 16×   16× 13×   52× 17× 17×   35×     68×     68× 18× 14× 14× 14×   14× 14×                   14×                   50× 19× 19×   19×                   19×     31× 31×   31×             31×     10× 35×   35×                   35×     10×          
import {makeFieldValue} from './fieldValue';
 
function extractKey(field) {
  const dotIndex = field.indexOf('.');
  const openIndex = field.indexOf('[');
  const closeIndex = field.indexOf(']');
 
  Iif (openIndex > 0 && closeIndex !== openIndex + 1) {
    throw new Error('found [ not followed by ]');
  }
 
  const isArray = openIndex > 0 && (dotIndex < 0 || openIndex < dotIndex);
  let key;
  let nestedPath;
 
  if (isArray) {
    key = field.substring(0, openIndex);
    nestedPath = field.substring(closeIndex + 1);
 
    if (nestedPath[0] === '.') {
      nestedPath = nestedPath.substring(1);
    }
  } else if (dotIndex > 0) {
    key = field.substring(0, dotIndex);
    nestedPath = field.substring(dotIndex + 1);
  } else {
    key = field;
  }
 
  return { isArray, key, nestedPath };
}
 
function normalizeField(field, fullFieldPath, state, previousState, values, previousValues, normalizers) {
  if (field.isArray) {
    if (field.nestedPath) E{
      const array = state && state[field.key] || [];
      const previousArray = previousState && previousState[field.key] || [];
      const nestedField = extractKey(field.nestedPath);
 
      return array.map((nestedState, i) => {
        nestedState[nestedField.key] = normalizeField(
          nestedField,
          fullFieldPath,
          nestedState,
          previousArray[i],
          values,
          previousValues,
          normalizers
        );
 
        return nestedState;
      });
    }
 
    const normalizer = normalizers[fullFieldPath];
 
    const result = normalizer(
      state && state[field.key],
      previousState && previousState[field.key],
      values,
      previousValues
    );
    return field.isArray ? result && result.map(makeFieldValue) : result;
  } else if (field.nestedPath) {
    const nestedState = state && state[field.key] || {};
    const nestedField = extractKey(field.nestedPath);
 
    nestedState[nestedField.key] = normalizeField(
      nestedField,
      fullFieldPath,
      nestedState,
      previousState && previousState[field.key],
      values,
      previousValues,
      normalizers
    );
 
    return nestedState;
  }
 
  const finalField = state && state[field.key] || {};
  const normalizer = normalizers[fullFieldPath];
 
  finalField.value = normalizer(
    finalField.value,
    previousState && previousState[field.key] && previousState[field.key].value,
    values,
    previousValues
  );
 
  return makeFieldValue(finalField);
}
 
export default function normalizeFields(normalizers, state, previousState, values, previousValues) {
  const newState = Object.keys(normalizers).reduce((accumulator, field) => {
    const extracted = extractKey(field);
 
    accumulator[extracted.key] = normalizeField(
      extracted,
      field,
      state,
      previousState,
      values,
      previousValues,
      normalizers
    );
 
    return accumulator;
  }, {});
 
  return {
    ...state,
    ...newState
  };
}