-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
113 lines (104 loc) · 3.47 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
103
104
105
106
107
108
109
110
111
112
113
import { normalize } from 'normalizr';
const debug = require('debug')('redux-normalizr');
const debugData = require('debug')('redux-normalizr-data');
/**
* Check if action should be processed
* @param {Object} action redux action
* @param {String|Regex} filter filter of action type to match
* @return {Boolean} shouldBeProcessed
*/
const shouldProcessAction = (action, filter) => {
const {
error,
payload,
meta,
type,
} = action;
return (!!(
!error && payload && meta && meta.schema
&& (!filter
|| (
typeof filter === 'function'
? filter(action)
: (type && type.match(filter)
)
)
)
));
};
/**
* This callback fetch the data to normalize in the action
*
* @callback GetDataCb
* @param {ReduxStore} store redux store
* @param {ReduxAction} action redux action
* @return {Object} data to normalize
*/
/**
* This callback trigger after normalization and can mutate data
*
* @callback PostNormalizeCb
* @param {ReduxAction} normalizedData redux action
* @return {Object} mutated data
*/
/**
* This callback trigger just before leaving for mutate the action or dispatch actions
*
* @callback OnNextCb
* @param {ReduxStore} store redux store
* @param {ReduxAction} action redux action
* @param {Object} normalizedData redux action
* @param {Object} original data
* @return {Object} normalized data
*/
/**
* Generate the midleware by default it handle every action with a data.meta.schema field
* normalize action.payload and replace the payload by normalized payload before p
* @param {Object} action redux action
* @param {String} action.type type used by actionFilter option
* @param {Object} options middleware options
* @param {String|Regex|Function} [options.actionFilter] pattern of action type to handle
* * or function taking action and return if should be treated
* @param {GetDataCb} [options.getActionData] get data to normalize in action
* @param {OnNextCb} [options.onNextAction] get data to normalize in action
* @param {PostNormalizeCb} [options.onNormalizeData] update normalized data before sending action
* @return {ReduxMiddleware} redux normalizr middleware
*/
export default (options) => {
const opts = {
actionFilter: null,
getActionData: (store, action) => action.payload,
onNormalizeData: normalizedData => normalizedData,
onNextAction: (store, action, normalizedData) => ({
...action,
payload: normalizedData,
}),
...options,
};
return (store => next => (action) => {
debug('Action received', action.type);
debugData(action);
if (shouldProcessAction(action, opts.filter)) {
debug('Processing action');
debug(' getActionData');
const data = opts.getActionData(store, action);
debugData(data);
if (!data || typeof data !== 'object') {
debug(' Data returned is not an object or null');
return next(action);
}
debug(' Normalize data');
let normalizedData = normalize(data, action.meta.schema);
debugData(normalizedData);
debug(' onNormalizeData');
normalizedData = opts.onNormalizeData(normalizedData);
debugData(normalizedData);
debug(' onNextAction');
const mutatedAction = opts.onNextAction(store, action, normalizedData, data);
debugData(normalizedData);
return next(mutatedAction);
}
debug('Action not processed');
return next(action);
});
};