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 | 1×
1×
68×
68×
68×
68×
68×
68×
68×
68×
16×
16×
16×
13×
52×
17×
17×
35×
68×
1×
68×
18×
14×
14×
14×
14×
14×
14×
4×
4×
4×
50×
19×
19×
19×
19×
31×
31×
31×
31×
1×
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
};
}
|