ID | Title | Duration (ms) |
---|---|---|
1 | Basic throws an error if the operation is invalid | 5 |
2 | Basic allows overriding existing operators | 1 |
3 | Basic works with custom operations | 1 |
4 | Basic returns a valid matcher if not passed something to compare against | 0 |
5 | Basic returns true for a basic match | 1 |
6 | Basic returns false for no basic match | 0 |
7 | Basic returns true for a basic curried match | 0 |
8 | Basic returns false for no basic curried match | 1 |
9 | Basic can match empty objects | 0 |
10 | Basic $ne: null returns true when field is different | 0 |
11 | Basic $ne: null returns false when field is not present | 1 |
12 | Basic $ne: null returns false when field is null | 0 |
13 | Basic can be used with Array.filter to create something that looks like sift | 1 |
14 | Basic accepts a regular expression as a filter | 0 |
15 | Basic suports get | 0 |
16 | Basic $eq takes function | 1 |
17 | Basic $eq works for empty arrays | 0 |
18 | Basic $eq works for empty arrays against false | 0 |
19 | Basic works with multiple nested values | 1 |
20 | Basic works with multiple nested objects with values | 0 |
21 | Filter curry basic should return object against object | 1 |
22 | Filter curry basic should return empty array for no match | 0 |
23 | Filter curry basic should return only matches | 0 |
24 | Filter curry basic should return empty array when no matches | 1 |
25 | Filter basic should return object against object | 0 |
26 | Filter basic should return empty array for no match | 0 |
27 | Filter basic should return only matches | 0 |
28 | Filter basic should return empty array when no matches | 1 |
29 | Sift-Filter 0: {"$eq":5} | 0 |
30 | Sift-Filter 1: "5" | 0 |
31 | Sift-Filter 2: false | 0 |
32 | Sift-Filter 3: true | 0 |
33 | Sift-Filter 4: 0 | 1 |
34 | Sift-Filter 5: null | 0 |
35 | Sift-Filter 6: undefined | 0 |
36 | Sift-Filter 7: 1 | 0 |
37 | Sift-Filter 8: 1 | 1 |
38 | Sift-Filter 9: "1970-01-01T00:00:00.001Z" | 0 |
39 | Sift-Filter 10: {} | 0 |
40 | Sift-Filter 11: {"$ne":5} | 0 |
41 | Sift-Filter 12: {"$ne":"5"} | 1 |
42 | Sift-Filter 13: {"$ne":false} | 0 |
43 | Sift-Filter 14: {} | 0 |
44 | Sift-Filter 15: {"$ne":{}} | 1 |
45 | Sift-Filter 16: {"$ne":1} | 0 |
46 | Sift-Filter 17: {"groups":{"$ne":111}} | 1 |
47 | Sift-Filter 18: {"$lt":5} | 0 |
48 | Sift-Filter 19: {"$lt":"c"} | 0 |
49 | Sift-Filter 20: {"$lt":null} | 0 |
50 | Sift-Filter 21: {"$lt":"1970-01-01T00:00:00.003Z"} | 0 |
51 | Sift-Filter 22: {"$lte":5} | 1 |
52 | Sift-Filter 23: {"groups":{"$lt":5}} | 0 |
53 | Sift-Filter 24: {"$gt":5} | 0 |
54 | Sift-Filter 25: {"$gt":null} | 0 |
55 | Sift-Filter 26: {"groups":{"$gt":5}} | 0 |
56 | Sift-Filter 27: {"$gte":5} | 1 |
57 | Sift-Filter 28: {"groups":{"$gte":5}} | 1 |
58 | Sift-Filter 29: {"$mod":[2,1]} | 0 |
59 | Sift-Filter 30: {"groups":{"$mod":[2,0]}} | 0 |
60 | Sift-Filter 31: {"$exists":false} | 1 |
61 | Sift-Filter 32: {"$exists":true} | 0 |
62 | Sift-Filter 33: {"$in":[0,false,1,"1"]} | 0 |
63 | Sift-Filter 34: {"$in":[1,"1","2"]} | 0 |
64 | Sift-Filter 35: {"$in":["1970-01-01T00:00:00.001Z"]} | 1 |
65 | Sift-Filter 36: {"a.b.status":{"$in":[0]}} | 0 |
66 | Sift-Filter 37: {"a.b.status":{"$in":[0,2]}} | 0 |
67 | Sift-Filter 38: {"$nin":[0,false,1,"1"]} | 1 |
68 | Sift-Filter 39: {"$nin":[1,"1","2"]} | 0 |
69 | Sift-Filter 40: {"$nin":["1970-01-01T00:00:00.001Z"]} | 0 |
70 | Sift-Filter 41: {"$not":false} | 0 |
71 | Sift-Filter 42: {"$not":0} | 0 |
72 | Sift-Filter 43: {"$not":{"$in":[1,2,3]}} | 0 |
73 | Sift-Filter 44: {} | 1 |
74 | Sift-Filter 45: {} | 0 |
75 | Sift-Filter 46: {} | 0 |
76 | Sift-Filter 47: {} | 0 |
77 | Sift-Filter 48: {"$all":[1,2,3]} | 0 |
78 | Sift-Filter 49: {"$all":[0,false]} | 1 |
79 | Sift-Filter 50: {"$all":["1"]} | 0 |
80 | Sift-Filter 51: {"$all":["1970-01-01T00:00:00.001Z","1970-01-01T00:00:00.002Z"]} | 0 |
81 | Sift-Filter 52: {"$size":3} | 0 |
82 | Sift-Filter 53: {"$size":1} | 0 |
83 | Sift-Filter 54: {"$or":[1,2,3]} | 1 |
84 | Sift-Filter 55: {"$or":[{"$ne":1},2]} | 0 |
85 | Sift-Filter 56: {"$nor":[1,2,3]} | 0 |
86 | Sift-Filter 57: {"$nor":[{"$ne":1},2]} | 1 |
87 | Sift-Filter 58: {"$and":[{"$gt":1},{"$lt":4}]} | 0 |
88 | Sift-Filter 59: {"$regex":"^a"} | 0 |
89 | Sift-Filter 60: {"a":{"$regex":"b|c"}} | 1 |
90 | Sift-Filter 61: {"folder":{"$regex":"^[0-9]{4}$"}} | 0 |
91 | Sift-Filter 62: {"$regex":"^a","$options":"i"} | 0 |
92 | Sift-Filter 63: {"text":{"$regex":".*lis.*","$options":"i"}} | 0 |
93 | Sift-Filter 64: {"$regex":"a"} | 0 |
94 | Sift-Filter 65: {} | 1 |
95 | Sift-Filter 66: {} | 0 |
96 | Sift-Filter 67: {} | 0 |
97 | Sift-Filter 68: {"$where":"this.v === 1"} | 0 |
98 | Sift-Filter 69: {"$where":"obj.v === 1"} | 0 |
99 | Sift-Filter 70: {"a":{"$elemMatch":{"b":1,"c":2}}} | 1 |
100 | Sift-Filter 71: {"a":{"$elemMatch":{"b":2,"c":{"$gt":2}}}} | 0 |
101 | Sift-Filter 72: {"a.b":{}} | 0 |
102 | Sift-Filter 73: {"foo.0":"baz"} | 1 |
103 | Sift-Filter 74: {"foo.0.name":"baz"} | 0 |
104 | Sift 0: {"$eq":5} | 0 |
105 | Sift 1: "5" | 1 |
106 | Sift 2: false | 0 |
107 | Sift 3: true | 0 |
108 | Sift 4: 0 | 0 |
109 | Sift 5: null | 0 |
110 | Sift 6: undefined | 0 |
111 | Sift 7: 1 | 0 |
112 | Sift 8: 1 | 1 |
113 | Sift 9: "1970-01-01T00:00:00.001Z" | 0 |
114 | Sift 10: {} | 0 |
115 | Sift 11: {"$ne":5} | 0 |
116 | Sift 12: {"$ne":"5"} | 0 |
117 | Sift 13: {"$ne":false} | 1 |
118 | Sift 14: {} | 0 |
119 | Sift 15: {"$ne":{}} | 0 |
120 | Sift 16: {"$ne":1} | 0 |
121 | Sift 17: {"groups":{"$ne":111}} | 0 |
122 | Sift 18: {"$lt":5} | 0 |
123 | Sift 19: {"$lt":"c"} | 1 |
124 | Sift 20: {"$lt":null} | 0 |
125 | Sift 21: {"$lt":"1970-01-01T00:00:00.003Z"} | 0 |
126 | Sift 22: {"$lte":5} | 0 |
127 | Sift 23: {"groups":{"$lt":5}} | 0 |
128 | Sift 24: {"$gt":5} | 1 |
129 | Sift 25: {"$gt":null} | 0 |
130 | Sift 26: {"groups":{"$gt":5}} | 1 |
131 | Sift 27: {"$gte":5} | 0 |
132 | Sift 28: {"groups":{"$gte":5}} | 2 |
133 | Sift 29: {"$mod":[2,1]} | 0 |
134 | Sift 30: {"groups":{"$mod":[2,0]}} | 1 |
135 | Sift 31: {"$exists":false} | 0 |
136 | Sift 32: {"$exists":true} | 0 |
137 | Sift 33: {"$in":[0,false,1,"1"]} | 0 |
138 | Sift 34: {"$in":[1,"1","2"]} | 0 |
139 | Sift 35: {"$in":["1970-01-01T00:00:00.001Z"]} | 0 |
140 | Sift 36: {"a.b.status":{"$in":[0]}} | 1 |
141 | Sift 37: {"a.b.status":{"$in":[0,2]}} | 0 |
142 | Sift 38: {"$nin":[0,false,1,"1"]} | 0 |
143 | Sift 39: {"$nin":[1,"1","2"]} | 0 |
144 | Sift 40: {"$nin":["1970-01-01T00:00:00.001Z"]} | 1 |
145 | Sift 41: {"$not":false} | 0 |
146 | Sift 42: {"$not":0} | 1 |
147 | Sift 43: {"$not":{"$in":[1,2,3]}} | 0 |
148 | Sift 44: {} | 0 |
149 | Sift 45: {} | 0 |
150 | Sift 46: {} | 0 |
151 | Sift 47: {} | 0 |
152 | Sift 48: {"$all":[1,2,3]} | 1 |
153 | Sift 49: {"$all":[0,false]} | 0 |
154 | Sift 50: {"$all":["1"]} | 0 |
155 | Sift 51: {"$all":["1970-01-01T00:00:00.001Z","1970-01-01T00:00:00.002Z"]} | 0 |
156 | Sift 52: {"$size":3} | 0 |
157 | Sift 53: {"$size":1} | 0 |
158 | Sift 54: {"$or":[1,2,3]} | 0 |
159 | Sift 55: {"$or":[{"$ne":1},2]} | 1 |
160 | Sift 56: {"$nor":[1,2,3]} | 0 |
161 | Sift 57: {"$nor":[{"$ne":1},2]} | 0 |
162 | Sift 58: {"$and":[{"$gt":1},{"$lt":4}]} | 0 |
163 | Sift 59: {"$regex":"^a"} | 0 |
164 | Sift 60: {"a":{"$regex":"b|c"}} | 1 |
165 | Sift 61: {"folder":{"$regex":"^[0-9]{4}$"}} | 0 |
166 | Sift 62: {"$regex":"^a","$options":"i"} | 0 |
167 | Sift 63: {"text":{"$regex":".*lis.*","$options":"i"}} | 0 |
168 | Sift 64: {"$regex":"a"} | 0 |
169 | Sift 65: {} | 0 |
170 | Sift 66: {} | 0 |
171 | Sift 67: {} | 1 |
172 | Sift 68: {"$where":"this.v === 1"} | 0 |
173 | Sift 69: {"$where":"obj.v === 1"} | 0 |
174 | Sift 70: {"a":{"$elemMatch":{"b":1,"c":2}}} | 0 |
175 | Sift 71: {"a":{"$elemMatch":{"b":2,"c":{"$gt":2}}}} | 0 |
176 | Sift 72: {"a.b":{}} | 1 |
177 | Sift 73: {"foo.0":"baz"} | 0 |
178 | Sift 74: {"foo.0.name":"baz"} | 0 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const { | |
2 | Bout, | ||
3 | matches, | ||
4 | filter, | ||
5 | } = require('./lib/bout'); | ||
6 | |||
7 | 1 | module.exports = { | |
8 | curry: require('./lib/curry'), | ||
9 | utils: require('./lib/utils'), | ||
10 | Parser: require('./lib/parser'), | ||
11 | Bout, | ||
12 | matches, | ||
13 | filter, | ||
14 | }; | ||
15 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const { | |
2 | parse, | ||
3 | } = require('./parser'); | ||
4 | 1 | const { | |
5 | validate, | ||
6 | } = require('./utils'); | ||
7 | 1 | const { | |
8 | OPERATORS, | ||
9 | } = require('./operators'); | ||
10 | 1 | const { | |
11 | PREPARERS, | ||
12 | } = require('./preparers'); | ||
13 | 1 | const curry = require('./curry'); | |
14 | |||
15 | class Bout{ | ||
16 | constructor({pattern = {}, operators = {}, preparers = {}} = {}){ | ||
17 | this.operators = Object.assign({}, OPERATORS, operators); | ||
18 | 3 | this.preparers = Object.assign({}, PREPARERS, preparers); | |
19 | } | ||
20 | |||
21 | matches(pattern, ...args){ | ||
22 | const { | ||
23 | operators, | ||
24 | preparers, | ||
25 | } = this; | ||
26 | 179 | const tree = parse(pattern, {operators, preparers}); | |
27 | 178 | if(args.length > 0){ | |
28 | 14 | return validate(tree, args[0]); | |
29 | } | ||
30 | 164 | return curry(validate, tree); | |
31 | } | ||
32 | |||
33 | filter(pattern, ...args){ | ||
34 | const matcher = this.matches(pattern); | ||
35 | 85 | if(args.length > 0){ | |
36 | 81 | const arr = Array.isArray(args[0])?args[0]:[args[0]]; | |
37 | 81 | return arr.filter(matcher); | |
38 | } | ||
39 | 4 | return (arr)=>Array.isArray(arr)?arr.filter(matcher):[arr].filter(matcher); | |
40 | } | ||
41 | } | ||
42 | |||
43 | 1 | const bout = new Bout(); | |
44 | 1 | const matches = (pattern, ...args)=>bout.matches(pattern, ...args); | |
45 | 1 | const filter = (pattern, ...args)=>bout.filter(pattern, ...args); | |
46 | |||
47 | 1 | module.exports = { | |
48 | Bout, | ||
49 | matches, | ||
50 | filter, | ||
51 | }; | ||
52 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const curry = (fn, ...args1)=>(...args2)=>fn(...args1, ...args2); | |
2 | |||
3 | 1 | module.exports = curry; | |
4 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const { | |
2 | compare, | ||
3 | comparable, | ||
4 | search, | ||
5 | validate, | ||
6 | and, | ||
7 | or, | ||
8 | isString, | ||
9 | } = require('./utils'); | ||
10 | |||
11 | 1 | const OPERATORS = { | |
12 | $eq: or((a, b)=>a(b)), | ||
13 | |||
14 | $ne: and((a, b)=>!a(b)), | ||
15 | |||
16 | $or(a, b){ | ||
17 | return a.find((elem)=>{ | ||
18 | return validate(elem, b); | ||
19 | })!==undefined; | ||
20 | }, | ||
21 | |||
22 | $gt: or((a, b)=>compare(comparable(b), a)>0), | ||
23 | |||
24 | $gte: or((a, b)=>compare(comparable(b), a)>=0), | ||
25 | |||
26 | $lt: or((a, b)=>compare(comparable(b), a)<0), | ||
27 | |||
28 | $lte: or((a, b)=>compare(comparable(b), a)<=0), | ||
29 | |||
30 | $mod: or((a, b)=>b%a[0] == a[1]), | ||
31 | |||
32 | $in(a, b){ | ||
33 | if(Array.isArray(b)){ | ||
34 | 8 | return b.find((elem)=>~a.indexOf(comparable(elem)))!==undefined; | |
35 | } | ||
36 | 56 | return !!~a.indexOf(comparable(b)); | |
37 | }, | ||
38 | |||
39 | $nin(a, b){ | ||
40 | return !OPERATORS.$in(a, b); | ||
41 | }, | ||
42 | |||
43 | $not(a, b){ | ||
44 | return !validate(a, b); | ||
45 | }, | ||
46 | |||
47 | $type(a, b){ | ||
48 | return b!=void(0)?b instanceof a || b.constructor == a : false; | ||
49 | }, | ||
50 | |||
51 | $all(a, b){ | ||
52 | if(!b){ | ||
53 | 2 | b = []; | |
54 | } | ||
55 | 18 | return a.every((elem)=>comparable(b).indexOf(elem)>-1); | |
56 | }, | ||
57 | |||
58 | $size(a, b){ | ||
59 | return b ? a === b.length : false; | ||
60 | }, | ||
61 | |||
62 | $nor(a, b){ | ||
63 | //return !OPERATORS.$in(a, b); | ||
64 | for(let i = 0, n = a.length; i<n; i++){ | ||
65 | 32 | if(validate(a[i], b)){ | |
66 | 16 | return false; | |
67 | } | ||
68 | } | ||
69 | 4 | return true; | |
70 | }, | ||
71 | |||
72 | $and(a, b){ | ||
73 | return a.every((elem)=>validate(elem, b)); | ||
74 | }, | ||
75 | |||
76 | $regex: or((a, b)=>{ | ||
77 | return isString(b) && a.test(b); | ||
78 | }), | ||
79 | |||
80 | $where(a, b){ | ||
81 | return a.call(b, b); | ||
82 | }, | ||
83 | |||
84 | $elemMatch(a, b){ | ||
85 | if(Array.isArray(b)){ | ||
86 | 4 | return search(b, a)!==-1; | |
87 | } | ||
88 | 8 | return validate(a, b); | |
89 | }, | ||
90 | |||
91 | $exists(a, b){ | ||
92 | return (b != void 0) === a; | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | 1 | module.exports = { | |
97 | and, | ||
98 | or, | ||
99 | OPERATORS, | ||
100 | }; | ||
101 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const { | |
2 | isFunction, | ||
3 | comparable, | ||
4 | search, | ||
5 | validate, | ||
6 | findValues, | ||
7 | } = require('./utils'); | ||
8 | 1 | const { | |
9 | OPERATORS, | ||
10 | } = require('./operators'); | ||
11 | 1 | const { | |
12 | PREPARERS, | ||
13 | } = require('./preparers'); | ||
14 | |||
15 | 1 | const getQuery = (query)=>{ | |
16 | const cQuery = comparable(query); | ||
17 | 271 | if (!cQuery || (cQuery.constructor.toString().replace(/\n/g,'').replace(/ /g, '') !== 'functionObject(){[nativecode]}')) { // cross browser support | |
18 | 74 | return { $eq: cQuery }; | |
19 | } | ||
20 | 197 | return cQuery; | |
21 | }; | ||
22 | |||
23 | 1 | const createValidator = (a, validate)=>{ | |
24 | return { | ||
25 | a, | ||
26 | validate | ||
27 | }; | ||
28 | }; | ||
29 | |||
30 | 1 | const nestedValidator = (a, b)=>{ | |
31 | const values = findValues(b, a.k, 0); | ||
32 | 110 | if(values.length === 1){ | |
33 | 109 | return validate(a.nv, values[0]); | |
34 | } | ||
35 | 1 | return !!~search(values, a.nv); | |
36 | }; | ||
37 | |||
38 | 1 | const createNestedValidator = (path, a)=>{ | |
39 | return { | ||
40 | a: { | ||
41 | k: path, | ||
42 | nv: a | ||
43 | }, | ||
44 | validate: nestedValidator | ||
45 | } | ||
46 | }; | ||
47 | |||
48 | 1 | const getValidator = ({key, value, query, parse, operators = OPERATORS, preparers = PREPARERS})=>{ | |
49 | if(key === '$options'){ | ||
50 | 4 | return false; | |
51 | } | ||
52 | 274 | if(operators[key]){ | |
53 | 215 | if(preparers[key]){ | |
54 | 142 | const prepared = preparers[key](value, {query, parse}); | |
55 | 142 | return createValidator(comparable(prepared), operators[key]); | |
56 | } | ||
57 | 73 | return createValidator(comparable(value), operators[key]); | |
58 | } | ||
59 | 59 | if(key.charCodeAt(0)===36){ | |
60 | 1 | throw new Error(`Unkonwn operation ${key}`); | |
61 | } | ||
62 | 58 | return createNestedValidator(key.split('.'), parse(value, {operators, preparers})); | |
63 | }; | ||
64 | |||
65 | 1 | const parse = (query, {operators = OPERATORS, preparers = PREPARERS} = {})=>{ | |
66 | const cQuery = getQuery(query); | ||
67 | 271 | const validators = Object.keys(cQuery) | |
68 | .map((key)=>getValidator({key, value: cQuery[key], query: cQuery, parse, operators, preparers})) | ||
69 | .filter((v)=>v!==false); | ||
70 | |||
71 | 270 | return validators.length === 1?validators[0] : createValidator(validators, operators.$and); | |
72 | }; | ||
73 | |||
74 | 1 | module.exports = { | |
75 | parse, | ||
76 | }; | ||
77 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const { | |
2 | compare, | ||
3 | comparable, | ||
4 | isString, | ||
5 | } = require('./utils'); | ||
6 | |||
7 | 1 | const PREPARERS = { | |
8 | $eq(a){ | ||
9 | if(a instanceof RegExp){ | ||
10 | 12 | return (b)=>typeof(b)==='string' && a.test(b); | |
11 | } | ||
12 | 88 | if(a instanceof Function){ | |
13 | 1 | return a; | |
14 | } | ||
15 | 87 | if(Array.isArray(a) && !a.length){ | |
16 | 2 | return (b)=>Array.isArray(b) && !b.length; | |
17 | } | ||
18 | 85 | if(a === null){ | |
19 | 5 | return (b)=>b == null; | |
20 | } | ||
21 | 80 | return (b)=>compare(comparable(b), a)===0; | |
22 | }, | ||
23 | |||
24 | $ne(a){ | ||
25 | return PREPARERS.$eq(a); | ||
26 | }, | ||
27 | |||
28 | $and(a, {parse}){ | ||
29 | return a.map(parse); | ||
30 | }, | ||
31 | |||
32 | $or(a, {parse}){ | ||
33 | return a.map(parse); | ||
34 | }, | ||
35 | |||
36 | $nor(a, {parse}){ | ||
37 | return a.map(parse); | ||
38 | }, | ||
39 | |||
40 | $not(a, {parse}){ | ||
41 | return parse(a); | ||
42 | }, | ||
43 | |||
44 | $regex(a, {query}){ | ||
45 | return new RegExp(a, query.$options); | ||
46 | }, | ||
47 | |||
48 | $where(a){ | ||
49 | return isString(a)?new Function('obj', `return ${a}`):a; | ||
50 | }, | ||
51 | |||
52 | $elemMatch(a, {parse}){ | ||
53 | return parse(a); | ||
54 | }, | ||
55 | |||
56 | $exists(a){ | ||
57 | return !!a; | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | 1 | module.exports = { | |
62 | PREPARERS, | ||
63 | }; | ||
64 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | 1 | const curry = require('./curry'); | |
2 | |||
3 | 1 | const isType = (type, val)=>typeof(val)===type; | |
4 | |||
5 | 1 | const isFunction = curry(isType, 'function'); | |
6 | 1 | const isString = curry(isType, 'string'); | |
7 | |||
8 | 1 | const compare = (a, b)=>{ | |
9 | if(a === b){ | ||
10 | 88 | return 0; | |
11 | } | ||
12 | 214 | if(typeof(a) === typeof(b)){ | |
13 | 171 | return (a > b)?1:-1; | |
14 | } | ||
15 | }; | ||
16 | |||
17 | 1 | const comparable = (value)=>{ | |
18 | if(value instanceof Date){ | ||
19 | 46 | return value.getTime(); | |
20 | } | ||
21 | 1015 | if(Array.isArray(value)){ | |
22 | 75 | return value.map(comparable); | |
23 | } | ||
24 | 940 | return value; | |
25 | }; | ||
26 | |||
27 | 1 | const search = (arr, validator)=>{ | |
28 | return arr.findIndex((item)=>validate(validator, item)); | ||
29 | }; | ||
30 | |||
31 | 1 | const validate = (validator, b)=>{ | |
32 | return validator.validate(validator.a, b); | ||
33 | }; | ||
34 | |||
35 | 1 | const get = (obj, key)=>{ | |
36 | if(isFunction(obj.get)){ | ||
37 | 1 | return obj.get(key); | |
38 | } | ||
39 | 209 | return obj[key]; | |
40 | }; | ||
41 | |||
42 | 1 | const or = (predicate)=>(a, b)=>{ | |
43 | if(!Array.isArray(b)){ | ||
44 | 312 | return predicate(a, b); | |
45 | } | ||
46 | 31 | for(let i = 0, n = b.length; i<n; i++){ | |
47 | 51 | if(predicate(a, get(b, i))){ | |
48 | 21 | return true; | |
49 | } | ||
50 | } | ||
51 | 10 | return false; | |
52 | }; | ||
53 | |||
54 | 1 | const and = (predicate)=>(a, b)=>{ | |
55 | if(!Array.isArray(b) || !b.length){ | ||
56 | 57 | return predicate(a, b); | |
57 | } | ||
58 | 8 | for(let i = 0, n = b.length; i<n; i++){ | |
59 | 12 | if(!predicate(a, get(b, i))){ | |
60 | 4 | return false; | |
61 | } | ||
62 | } | ||
63 | 4 | return true; | |
64 | }; | ||
65 | |||
66 | 1 | const findValues = (current, path, index, values = [])=>{ | |
67 | if(index === path.length || current == void 0){ | ||
68 | 111 | return [...values, current]; | |
69 | } | ||
70 | 158 | const key = path[index]; | |
71 | |||
72 | 158 | if(Array.isArray(current) && isNaN(Number(key))){ | |
73 | 11 | return [...values, ...current.map((item)=>findValues(item, path, index, values)).filter((v)=>v !== void 0)]; | |
74 | } | ||
75 | 147 | return findValues(get(current, key), path, index+1, values); | |
76 | }; | ||
77 | |||
78 | 1 | module.exports = { | |
79 | get, | ||
80 | curry, | ||
81 | isType, | ||
82 | isFunction, | ||
83 | isString, | ||
84 | compare, | ||
85 | comparable, | ||
86 | search, | ||
87 | validate, | ||
88 | and, | ||
89 | or, | ||
90 | findValues, | ||
91 | }; | ||
92 |