1 | "use strict";
|
2 |
|
3 | const EXCEPTION_MSGS = {
|
4 | array: `Doesn't support Array in template yet. The meaning might differ in different context. Please use custom function instead.\nTreating as ${true}`,
|
5 | mergeTypeChecking: "Using Type Checking in template but object target object doesn't match.\nReturning template Type as result.",
|
6 | existTypeChecking: "Using Type Checking in template but object target object doesn't match.\nReturning undefined.",
|
7 | arrayIterFirstArg: "First argument of ArrayIter must be a function of obj-filter",
|
8 | };
|
9 |
|
10 | const getExceptionMsg = (type, second = false) => `obj-filter: ${second ? second + ": " : ""}${EXCEPTION_MSGS[type]}`;
|
11 |
|
12 | function _isType (template) {
|
13 | if (
|
14 | (template === String)
|
15 | || (template === Number)
|
16 | || (template === Boolean)
|
17 | || (template === Array)
|
18 | || (template === Symbol)
|
19 | || (template === Map)
|
20 | || (template === Set)
|
21 | || (template === WeakMap)
|
22 | || (template === WeakSet)
|
23 | || (template === Object)
|
24 | || (template === Function)
|
25 | ) {
|
26 | return true;
|
27 | }
|
28 |
|
29 | return false;
|
30 | }
|
31 |
|
32 | function _sameType (template, obj) {
|
33 | if (
|
34 | (template === String && typeof obj === "string")
|
35 | || (template === Number && typeof obj === "number")
|
36 | || (template === Boolean && typeof obj === "boolean")
|
37 | || (template === Array && Array.isArray(obj))
|
38 | || (template === Symbol && obj instanceof Symbol)
|
39 | || (template === Map && obj instanceof Map)
|
40 | || (template === Set && obj instanceof Set)
|
41 | || (template === WeakMap && obj instanceof WeakMap)
|
42 | || (template === WeakSet && obj instanceof WeakSet)
|
43 | || (template === Function && typeof obj === "function")
|
44 | || (template === Object && typeof obj === "object")
|
45 | ) {
|
46 | return true;
|
47 | }
|
48 |
|
49 | return false;
|
50 | }
|
51 |
|
52 |
|
53 | function filter (template, obj, onException) {
|
54 |
|
55 |
|
56 | if (typeof template === "undefined") {
|
57 | return undefined;
|
58 | }
|
59 |
|
60 |
|
61 | if ( _isType(template) ) {
|
62 | if ( _sameType(template, obj) ) {
|
63 | return obj;
|
64 | }
|
65 |
|
66 |
|
67 | if (onException) {
|
68 | return onException(template, obj);
|
69 | }
|
70 | return undefined;
|
71 | }
|
72 |
|
73 |
|
74 | if (template instanceof Array) {
|
75 | if (onException) {
|
76 | return onException(
|
77 | template,
|
78 | obj,
|
79 | getExceptionMsg("array")
|
80 | );
|
81 | }
|
82 | return obj;
|
83 | }
|
84 |
|
85 |
|
86 | if ( typeof template === "object" ){
|
87 | if (typeof obj === "object") {
|
88 | return Object.keys(template).reduce((result, key) => {
|
89 | const tmp = filter(template[key], obj[key], onException);
|
90 |
|
91 | if (typeof tmp !== "undefined") {
|
92 | result[key] = tmp;
|
93 | }
|
94 | return result;
|
95 | }, {});
|
96 | }
|
97 |
|
98 |
|
99 | if (onException) {
|
100 | return onException(template, obj);
|
101 | }
|
102 | return undefined;
|
103 | }
|
104 |
|
105 |
|
106 | if ( typeof template === "function" ) {
|
107 | return template(obj);
|
108 | }
|
109 |
|
110 | return obj;
|
111 | }
|
112 |
|
113 | function merge (template, obj, onException) {
|
114 |
|
115 |
|
116 | if (typeof template === "undefined") {
|
117 | return undefined;
|
118 | }
|
119 |
|
120 |
|
121 | if ( _isType(template) ) {
|
122 | if ( _sameType(template, obj) ) {
|
123 | return obj;
|
124 | }
|
125 |
|
126 |
|
127 | if (onException) {
|
128 | return onException(
|
129 | template,
|
130 | obj,
|
131 | getExceptionMsg("mergeTypeChecking", "merge")
|
132 | );
|
133 | }
|
134 | return template;
|
135 | }
|
136 |
|
137 |
|
138 | if (template instanceof Array) {
|
139 | if (onException) {
|
140 | return onException(
|
141 | template,
|
142 | obj,
|
143 | getExceptionMsg("array", "merge")
|
144 | );
|
145 | }
|
146 | return obj;
|
147 | }
|
148 |
|
149 |
|
150 | if ( typeof template === "object" ){
|
151 | if (typeof obj === "object") {
|
152 | return Object.keys(template).reduce((result, key) => {
|
153 | const ret = merge(template[key], obj[key], onException);
|
154 |
|
155 | if (typeof ret !== "undefined") {
|
156 | result[key] = ret;
|
157 | } else if (typeof template[key] !== "undefined") {
|
158 | result[key] = template[key];
|
159 | }
|
160 | return result;
|
161 | }, {});
|
162 | } else {
|
163 |
|
164 | if (onException) {
|
165 | return onException(
|
166 | template,
|
167 | obj,
|
168 | getExceptionMsg("mergeTypeChecking", "merge")
|
169 | );
|
170 | }
|
171 | return template;
|
172 | }
|
173 | }
|
174 |
|
175 |
|
176 | if ( typeof template === "function" ) {
|
177 | return template(obj);
|
178 | }
|
179 |
|
180 |
|
181 | if (typeof obj === "undefined") {
|
182 | return template;
|
183 | }
|
184 |
|
185 | return obj;
|
186 | }
|
187 |
|
188 | function exist (template, obj, onException) {
|
189 |
|
190 |
|
191 | if (typeof template === "undefined") {
|
192 | return undefined;
|
193 | }
|
194 |
|
195 |
|
196 | if ( _isType(template) ) {
|
197 | if ( _sameType(template, obj) ) {
|
198 | return obj;
|
199 | }
|
200 |
|
201 |
|
202 | if (onException) {
|
203 | return onException(
|
204 | template,
|
205 | obj,
|
206 | getExceptionMsg("existTypeChecking")
|
207 | );
|
208 | }
|
209 |
|
210 | return undefined;
|
211 | }
|
212 |
|
213 |
|
214 | if (template instanceof Array) {
|
215 | if (onException) {
|
216 | return onException(
|
217 | template,
|
218 | obj,
|
219 | getExceptionMsg("array", "exist")
|
220 | );
|
221 | }
|
222 | return obj;
|
223 | }
|
224 |
|
225 |
|
226 | if (typeof template === "function") {
|
227 | return template(obj);
|
228 | }
|
229 |
|
230 |
|
231 | if (typeof obj === "undefined") {
|
232 | return undefined;
|
233 | }
|
234 |
|
235 |
|
236 | if (typeof template === "object") {
|
237 | return Object.keys(template).reduce((result, key) => {
|
238 | if (template[key] === undefined) {
|
239 |
|
240 | return result;
|
241 | }
|
242 |
|
243 | const tmp = exist(template[key], obj[key], onException);
|
244 |
|
245 | if (typeof tmp === "undefined") {
|
246 | return undefined;
|
247 | }
|
248 |
|
249 | result[key] = tmp;
|
250 |
|
251 | return result;
|
252 | }, {});
|
253 | }
|
254 |
|
255 |
|
256 | return obj;
|
257 | }
|
258 |
|
259 |
|
260 | function ArrayIter (checker, template, {min = 0, onException} = {}) {
|
261 |
|
262 | if (typeof(checker) !== "function") {
|
263 | if (onException) {
|
264 | return onException(undefined, undefined, getExceptionMsg("arrayIterFirstArg"));
|
265 | }
|
266 |
|
267 | throw new Error(getExceptionMsg("arrayIterFirstArg"));
|
268 | }
|
269 |
|
270 | return function (array) {
|
271 | if (!(array instanceof Array)) {
|
272 | return undefined;
|
273 | }
|
274 |
|
275 | const result = array.map((value) => checker(template, value, onException))
|
276 | .filter((x) => x !== undefined);
|
277 |
|
278 | return result.length >= min ? result : undefined;
|
279 | };
|
280 | }
|
281 |
|
282 | module.exports = filter;
|
283 | module.exports.filter = filter;
|
284 | module.exports.merge = merge;
|
285 | module.exports.exist = exist;
|
286 | module.exports.ArrayIter = ArrayIter;
|