-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.js
102 lines (85 loc) · 2.63 KB
/
index.js
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
import { createTransform } from 'redux-persist';
import get from 'lodash/get';
import set from 'lodash/set';
import unset from 'lodash/unset';
import pickBy from 'lodash/pickBy';
import isEmpty from 'lodash/isEmpty';
import forIn from 'lodash/forIn';
import cloneDeep from 'lodash/cloneDeep';
export function createFilter (reducerName, inboundPaths, outboundPaths, transformType = 'whitelist') {
return createTransform(
// inbound
(inboundState, key) => {
return inboundPaths
? persistFilter(inboundState, inboundPaths, transformType)
: inboundState;
},
// outbound
(outboundState, key) => {
return outboundPaths
? persistFilter(outboundState, outboundPaths, transformType)
: outboundState;
},
{'whitelist': [reducerName]}
);
};
export function createWhitelistFilter (reducerName, inboundPaths, outboundPaths) {
return createFilter(reducerName, inboundPaths, outboundPaths, 'whitelist');
}
export function createBlacklistFilter (reducerName, inboundPaths, outboundPaths) {
return createFilter(reducerName, inboundPaths, outboundPaths, 'blacklist');
}
function filterObject({ path, filterFunction = () => true }, state) {
const value = get(state, path, state);
if (value instanceof Array) {
return value.filter(filterFunction)
}
return pickBy(value, filterFunction);
}
export function persistFilter (state, paths = [], transformType = 'whitelist') {
let subset = {};
// support only one key
if (typeof paths === 'string') {
paths = [paths];
}
if (transformType === 'whitelist') {
paths.forEach((path) => {
if (typeof path === 'object' && !(path instanceof Array)) {
const value = filterObject(path, state);
if (!isEmpty(value)) {
set(subset, path.path, value);
}
} else {
const value = get(state, path);
if (typeof value !== 'undefined') {
set(subset, path, value);
}
}
});
} else if (transformType === 'blacklist') {
subset = cloneDeep(state);
paths.forEach((path) => {
if (typeof path === 'object' && !(path instanceof Array)) {
const value = filterObject(path, state);
if (!isEmpty(value)) {
if (value instanceof Array) {
set(subset, path.path, get(subset, path.path, subset).filter((x) => false));
} else {
forIn(value, (value, key) => { unset(subset, `${path.path}[${key}]`) });
}
} else {
subset = value;
}
} else {
const value = get(state, path);
if (typeof value !== 'undefined') {
unset(subset, path);
}
}
});
} else {
subset = state;
}
return subset;
}
export default createFilter;