UNPKG

5.79 kBJavaScriptView Raw
1// @flow
2"use strict";
3
4function filter (template, obj, onException) {
5
6 // exclude what's undefined in template
7 if (typeof template === "undefined") {
8 return undefined;
9 }
10
11 // only check Type
12 if ( _isType(template) ) {
13 if ( _sameType(template, obj) ) {
14 return obj;
15 }
16
17 // type mismatch
18 if (onException) {
19 return onException(template, obj);
20 }
21 return undefined;
22 }
23
24 // handle Array as True
25 if (template instanceof Array) {
26 if (onException) {
27 return onException(
28 template,
29 obj,
30 "obj-filter: Doesn't support Array in template yet. The meaning might differ in different context. Please use custom function instead.\nTreating as `true`"
31 );
32 }
33 return obj;
34 }
35
36 // filtering
37 if ( typeof template === "object" ){
38 if (typeof obj === "object") {
39 var result = {};
40 Object.keys(template).forEach( function (key) {
41 var tmp = filter(template[key], obj[key], onException);
42
43 if (typeof tmp !== "undefined") {
44 result[key] = tmp;
45 }
46 });
47 return result;
48 }
49
50 // type mismatch
51 if (onException) {
52 return onException(template, obj);
53 }
54 return undefined;
55 }
56
57
58 if ( typeof template === "function" ) {
59 return template(obj);
60 }
61
62 return obj;
63}
64
65filter.prototype.merge = merge;
66function merge (template, obj, onException) {
67
68 // exclude what's undefined in template
69 if (typeof template === "undefined") {
70 return undefined;
71 }
72
73 // only check Type
74 if ( _isType(template) ) {
75 if ( _sameType(template, obj) ) {
76 return obj;
77 }
78
79 // type mismatch
80 if (onException) {
81 return onException(
82 template,
83 obj,
84 "obj-filter: merge: Using Type Checking in template but object target object doesn't match.\nReturning template Type as result."
85 );
86 }
87 return template;
88 }
89
90 // handle Array as True
91 if (template instanceof Array) {
92 if (onException) {
93 return onException(
94 template,
95 obj,
96 "obj-filter: merge: Doesn't support Array in template yet. The meaning might differ in different context. Please use custom function instead.\nTreating as `true`"
97 );
98 }
99 return obj;
100 }
101
102 // obj ? obj : template ;
103 if ( typeof template === "object" ){
104 if (typeof obj === "object") {
105 var result = {};
106 Object.keys(template).forEach( function (key) {
107 var ret = merge(template[key], obj[key], onException);
108
109 if (typeof ret !== "undefined") {
110 result[key] = ret;
111 } else if (typeof template[key] !== "undefined") {
112 result[key] = template[key];
113 }
114 });
115 return result;
116 } else {
117 // type mismatch
118 if (onException) {
119 return onException(
120 template,
121 obj,
122 "obj-filter: merge: template is object but target is not.\nReturning template as result."
123 );
124 }
125 return template;
126 }
127 }
128
129 // must before "undefined" handling, so user can handle undefined if they wanted
130 if ( typeof template === "function" ) {
131 return template(obj);
132 }
133
134 // must after typeof template === 'function', so user can handle it if they wanted
135 if (typeof obj === "undefined") {
136 return template;
137 }
138
139 return obj;
140}
141
142filter.prototype.exist = exist;
143function exist (template, obj, onException) {
144
145 // exclude what's undefined in template
146 if (typeof template === "undefined") {
147 return undefined;
148 }
149
150 // only check Type
151 if ( _isType(template) ) {
152 if ( _sameType(template, obj) ) {
153 return obj;
154 }
155
156 // type mismatch
157 if (onException) {
158 return onException(
159 template,
160 obj,
161 "obj-filter: exist: Using Type Checking in template but object target object doesn't match.\nReturning undefined."
162 );
163 }
164
165 return undefined;
166 }
167
168 // handle Array as True
169 if (template instanceof Array) {
170 if (onException) {
171 return onException(
172 template,
173 obj,
174 "obj-filter: exist: Doesn't support Array in template yet. The meaning might differ in different context. Please use custom function instead.\nTreating as `true`"
175 );
176 }
177 return obj;
178 }
179
180 // must before "undefined" handling, so user can handle undefined if they wanted
181 if (typeof template === "function") {
182 return template(obj);
183 }
184
185 // must after typeof template === 'function', so user can handle it if they wanted
186 if (typeof obj === "undefined") {
187 return undefined;
188 }
189
190 // check if all keys exists recursively
191 if (typeof template === "object") {
192 var result = {};
193
194 for (const key in template) {
195 if (template[key] === undefined) {
196 // value 'undefined' means skip
197 continue;
198 }
199
200 var tmp = exist(template[key], obj[key], onException);
201
202 if (typeof tmp !== "undefined") {
203 result[key] = tmp;
204 } else {
205 return undefined;
206 }
207 }
208
209 return result;
210 }
211
212 // return whatever obj has
213 return obj;
214}
215
216
217function _isType (template) {
218 if (
219 (template === String)
220 || (template === Number)
221 || (template === Boolean)
222 || (template === Array)
223 || (template === Symbol)
224 || (template === Map)
225 || (template === Set)
226 || (template === WeakMap)
227 || (template === WeakSet)
228 || (template === Object)
229 || (template === Function)
230 ) {
231 return true;
232 }
233
234 return false;
235}
236
237function _sameType (template, obj) {
238 if (
239 (template === String && typeof obj === "string")
240 || (template === Number && typeof obj === "number")
241 || (template === Boolean && typeof obj === "boolean")
242 || (template === Array && Array.isArray(obj))
243 || (template === Symbol && obj instanceof Symbol)
244 || (template === Map && obj instanceof Map)
245 || (template === Set && obj instanceof Set)
246 || (template === WeakMap && obj instanceof WeakMap)
247 || (template === WeakSet && obj instanceof WeakSet)
248 || (template === Object && typeof obj === "object")
249 || (template === Function && typeof obj === "function")
250 ) {
251 return true;
252 }
253
254 return false;
255}
256
257
258module.exports = filter;
259module.exports.filter = filter;
260module.exports.merge = merge;
261module.exports.exist = exist;
\No newline at end of file