UNPKG

10.5 kBJavaScriptView Raw
1
2
3
4!function(exports, Object) {
5 "use strict";
6 var getFns = Object.create(null)
7 , setFns = Object.create(null)
8 , filterFns = Object.create(null)
9 , KEYS = Object.keys
10 , FILTER_ERR = "Invalid filter: "
11 , escRe = /['\n\r\u2028\u2029]|\\(?!x2e)/g
12 , pathRe = /(^$|.+?)(?:\[([^\]]*)\](\*.*)?|\{([^}]*)})?(\.(?=[^.])|$)/g
13 , reEscRe = /[.+^=:${}()|\/\\]/g
14 , keyRe = /\[(.*?)\]/g
15 , globRe = /\[.+?\]|[?*]/
16 , globReplace = /\?|(?=\*)/g
17 , globGroup = /\[!(?=.*\])/g
18 , primitiveRe = /^(-?(\d*\.)?\d+|true|false|null)$/
19 , valRe = /("|')(?:\\?[^\\])*?\1|(\w*)\{((?:("|')(?:\\?[^\\])*?\4|\w*\{(?:("|')(?:\\?[^\\])*?\5|[^}])*?\}|.)*?)\}|([@$]?)([^,]+)/g
20 , filterRe = /(!?)(\$?)((?:[-+:.\/\w]+|\[[^\]]+\]|\{[^}]+}|\\x2e)+)(\[]|\{}|)(?:(!(?=\1)==?|(?=\1)[<>=]=?)((?:("|')(?:\\?[^\\])*?\7|\w*\{(?:("|')(?:\\?[^\\])*?\8|\w*\{(?:("|')(?:\\?[^\\])*?\9|[^}])*?\}|.)*?\}|[^|&()])*))?(?=[;)|&]|$)|(([;&|])\11*|([()])|.)/g
21 , onlyFilterRe = RegExp("^(?:([@*])|" + filterRe.source.slice(0, -10) + "))+$")
22 , cleanRe = /(\(o=d\)&&(?!.*o=o).*)\(o=d\)&&/g
23 , fns = {
24 "==": "a==d",
25 "===": "a===d",
26 ">": "a<d",
27 ">=": "a<=d",
28 "<": "a>d",
29 "<=": "a>=d",
30 "~": "typeof d==='string'&&a.test(d)"
31 }
32 , fnMap = {
33 w: "Day()||7",
34 Y: "FullYear()%100",
35 M: "Month()+1",
36 D: "Date()",
37 h: "Hours()",
38 H: "Hours()%12||12",
39 m: "Minutes()",
40 s: "Seconds()",
41 S: "Milliseconds()"
42 }
43 , hasOwn = fns.hasOwnProperty
44 , tmpDate = new Date()
45 , isArray = Array.isArray
46
47 exports.clone = clone
48 exports.matcher = matcher
49 exports.get = function(obj, pointer, fallback) { return pathFn(pointer)(obj, fallback) }
50 exports.isObject = isObject
51 exports.mergePatch = mergePatch
52 exports.set = function(obj, pointer, value) { return pathFn(pointer, true)(obj, value) }
53 exports.setForm = setForm
54 exports.tr = tr
55
56 exports.get.str = pathStr
57 matcher.re = filterRe
58 matcher.str = filterStr
59 matcher.valRe = valRe
60
61 /**
62 * JSON Merge Patch
63 * @see https://tools.ietf.org/html/rfc7396
64 */
65
66 function mergePatch(target, patch, changed, previous, pointer) {
67 var undef, key, oldVal, val, len, nextPointer
68 if (isObject(patch)) {
69 if (!pointer) {
70 pointer = ""
71 }
72 if (!isObject(target)) {
73 target = {}
74 }
75 for (key in patch) if (
76 undef !== (oldVal = target[key], val = patch[key]) &&
77 hasOwn.call(patch, key) &&
78 (
79 undef == val ?
80 undef !== oldVal && delete target[key] :
81 target[key] !== val
82 )
83 ) {
84 nextPointer = pointer + "/" + key.replace(/~/g, "~0").replace(/\//g, "~1")
85 len = changed && isObject(target[key]) && changed.length
86 if (undef != val) {
87 target[key] = mergePatch(target[key], val, changed, previous, nextPointer)
88 }
89 if (len === false || changed && len != changed.length) {
90 changed.push(nextPointer)
91 if (previous && !isObject(oldVal)) {
92 previous[nextPointer] = oldVal
93 }
94 }
95 }
96 } else {
97 if (changed && isObject(target)) {
98 val = {}
99 for (key in target) if (hasOwn.call(target, key)) {
100 val[key] = null
101 }
102 mergePatch(target, val, changed, previous, pointer)
103 }
104 target = patch
105 }
106 return target
107 }
108
109 function escFn(str) {
110 return escape(str).replace(/%u/g, "\\u").replace(/%/g, "\\x")
111 }
112
113 function pathStr(str, set) {
114 return (
115 str.charAt(0) === "/" ?
116 str.slice(1).replace(/\./g, "\\x2e").replace(/\//g, ".").replace(/~1/g, "/").replace(/~0/g, "~") :
117 str
118 )
119 .replace(escRe, escFn)
120 .replace(pathRe, set === true ? pathSet : pathGet)
121 }
122
123 function pathGet(str, path, arr, arrExt, obj, dot) {
124 var v = dot ? "(o=" : "(c="
125 , sub = arr || obj
126 if (sub && !(sub = onlyFilterRe.exec(sub))) throw Error(FILTER_ERR + str)
127 return (
128 sub ?
129 pathGet(0, path, 0, 0, 0, 1) + (arr ? "i" : "j") + "(o)&&" + v + (
130 // TODO:2021-01-22:lauri:Filter with single loop
131 arrExt ? "o.filter(m('" + sub[0] + "'))" + (arrExt === "*" ? "" : ".map(p('" + arrExt.slice(1) + "'))") :
132 sub[1] ? (arr ? "o" : "K(o)") + (sub[0] === "*" ? "" : ".length") :
133 +arr == arr ? "o[" + (arr < 0 ? "o.length" + arr : arr) + "]" :
134 (arr ? "I" : "J") + "(o,m('" + sub[0] + "'))"
135 ) + ")" :
136 v + "o['" + path + "'])" + (
137 arr === "" ? "&&i(c)&&c" :
138 obj === "" ? "&&j(c)&&c" :
139 ""
140 )
141 ) + (dot ? "&&" : "")
142 }
143
144 function pathSet(str, path, arr, arrExt, obj, dot) {
145 var op = "o['" + path + "']"
146 , out = ""
147 , sub = arr || obj
148 if (sub) {
149 out = "(o=" + (arr ? "i(" : "j(") + op + ")?" + op + ":(" + op + (arr ? "=[]" : "={}") +"))&&"
150 if (arr === "-") {
151 op = "o[o.length]"
152 } else if (+arr == arr) {
153 op = "o[" + (arr < 0 ? "o.length" + arr : arr) + "]"
154 } else {
155 if (!onlyFilterRe.test(arr)) throw Error(FILTER_ERR + str)
156 op = "o[t]"
157 out += "(t=" + (arr ? "I" : "J") + "(o,m('" + sub + "'),1))!=null&&"
158 }
159 }
160 return out + (dot ?
161 "(o=typeof " + op + "==='object'&&" + op + "||(" + op + "={}))&&" :
162 "((c=" + op + "),(" + op + "=v),c)"
163 )
164 }
165
166 function pathFn(str, set) {
167 var map = set === true ? setFns : getFns
168 return map[str] || (map[str] = Function(
169 "i,j,I,J,K,m,p",
170 "return function(d,v,b){var c,o,t;return (o=d)&&" +
171 pathStr(str, set) +
172 (set ? ",c}": "!==void 0?c:v}")
173 )(isArray, isObject, inArray, inObject, KEYS, matcher, pathFn))
174 }
175
176 function clone(obj) {
177 var temp, key
178 if (obj && typeof obj == "object") {
179 // new Date().constructor() returns a string
180 temp = obj instanceof Date ? new Date(+obj) :
181 obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
182 obj.constructor()
183 for (key in obj) if (hasOwn.call(obj, key)) {
184 temp[key] = clone(obj[key])
185 }
186 obj = temp
187 }
188 return obj
189 }
190
191 function matcher(str, prefix, opts, getter, tmp) {
192 var optimized
193 , arr = []
194 , key = (prefix || "") + (fns[str] || filterStr(str, opts, arr, getter))
195 , fn = filterFns[key]
196 if (!fn) {
197 for (optimized = key; optimized != (optimized = optimized.replace(cleanRe, "$1")); );
198 fn = filterFns[key] = Function(
199 fns[str] ? "a" : "a,i,j,I,J,K,m,p,t",
200 "return function(d,b){var o;return " + optimized + "}"
201 )
202 fn.source = optimized
203 }
204 return fns[str] ? fn : fn(
205 arr, isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, tmp
206 )
207 }
208
209 // Date{day=1,2}
210 // sliceable[start:stop:step]
211 // Geo{distance=200km&lat=40&lon=-70}
212 // ?pos=Geo{distance=200km&lat=@lat&lon=@lon}
213 // [lon, lat] in The GeoJSON Format RFC 7946
214 // IP{net=127.0.0.1/30}
215 // var re = /^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?:\.(?=.)|$)){4}$/
216 // ["1.2.3.4", "127.0.0.1", "192.175.255.254."].map(re.test, re)
217
218 matcher.date = function(str) {
219 return matcher(str, "(t.setTime(+d)>=0)&&", null, dateGetter, tmpDate)
220 }
221
222 function dateGetter(name) {
223 return "(t.get" + fnMap[name] + ")"
224 }
225
226 function filterStr(qs, opts, arr, getter) {
227 return qs.replace(filterRe, worker).replace(/^[1&]&+|&+1?$/g, "") || "1"
228
229 function worker(all, not, isOption, attr, isArray, op, val, q1, q2, q3, ext, ok2, ok1) {
230 if (ext) {
231 if (!ok2 && !ok1) {
232 throw Error(FILTER_ERR + qs)
233 }
234 return ok1 ? ok1 : ok2 == ";" ? "&&" : ok2 + ok2
235 }
236 if (isOption) {
237 if (opts) opts[attr] = val
238 return "1"
239 }
240
241 var idd, m, v, isRe
242 , a = []
243 , pre = "(o=d)&&"
244
245 attr = (getter || pathStr)(attr)
246
247 if (m = attr.match(/\(c=(.*?)\)$/)) {
248 if (m[1] == "K(o)") {
249 pre += attr + "&&"
250 attr = "c"
251 } else {
252 if (m.index) pre += attr.slice(0, m.index)
253 attr = m[1]
254 }
255 }
256
257 if (op == "!=" || op == "!==") {
258 not = "!"
259 op = op.slice(1)
260 }
261 if (isArray) {
262 pre += not + (isArray === "[]" ? "i(" : "j(") + attr + ")"
263 }
264
265 if (!op) {
266 return isArray === "" ? pre + not + attr : pre
267 }
268
269 if (op == "=" || op == "==") op += "="
270 if (val === "") val="''"
271 for (; m = valRe.exec(val); ) {
272 // quote, extension, subquery, subQuote, subSubQuote, at
273 // Parameterized query ?name=$name|name=:name
274 isRe = 0
275 v = m[6] == "$" ? "b['"+ m[7] +"']" : arrIdx(arr,
276 m[1] || m[3] ? m[0].slice(m[3] ? m[2].length + 1 : 1, -1) :
277 m[6] ? m[7] :
278 primitiveRe.test(m[0]) ? exports.parse(m[0]) :
279 (isRe = globRe.test(m[0])) ? RegExp(
280 "^" + m[0]
281 .replace(reEscRe, "\\$&")
282 .replace(globReplace, ".")
283 .replace(globGroup, "[^") + "$",
284 op === "==" ? "i" : ""
285 ) :
286 m[0]
287 )
288 idd = (
289 m[2] ? "m." + m[2].toLowerCase() :
290 m[3] ? "m" :
291 isArray || attr === "c" ? arrIdx(arr, matcher(isRe ? "~" : op)) :
292 ""
293 ) + "(" + v
294 a.push(
295 isArray || attr === "c" ? (isArray == "{}" ? "J(" : "I(") + attr + "," + idd + "))" :
296 m[2] || m[3] ? idd + ")(" + attr + ")" :
297 isRe ? "typeof " + attr + "==='string'&&" + v + ".test(" + attr + ")" :
298 m[6] ? attr + "!==void 0&&" + attr + op + (
299 m[6] == "$" ? "b['"+ m[7] +"']" : "p(" + v + ")(o)"
300 ) :
301 attr + op + v
302 )
303 }
304
305 return pre + (
306 isArray ? (not ? "||" : "&&") : ""
307 ) + not + "(" + a.join("||") + ")"
308 }
309 }
310
311 function arrIdx(arr, val) {
312 for (
313 var i = arr.length;
314 0 <= --i && !(
315 arr[i] === val ||
316 val && val.source && val.source === arr[i].source
317 );
318 );
319 return "a[" + (-1 < i ? i : arr.push(val) - 1) + "]"
320 }
321
322 function setForm(map, key_, val) {
323 for (var match, key = key_, step = map; match = keyRe.exec(key_); ) {
324 if (step === map) key = key.slice(0, match.index)
325 match = match[1]
326 step = step[key] || (
327 step[key] = match && +match != match ? {} : []
328 )
329 key = match
330 }
331 if (isArray(step)) {
332 step.push(val)
333 } else if (isArray(step[key])) {
334 step[key].push(val)
335 } else {
336 step[key] = step[key] != null ? [step[key], val] : val
337 }
338 }
339
340 function tr(attrs, aclFn) {
341 var attr, tmp
342 , arr = []
343 , map = {}
344 , i = 0
345 for (; attr = valRe.exec(attrs); ) {
346 tmp = attr[0].split(":")
347 exports.set(map, tmp[0], i)
348 arr[i++] = pathFn(tmp[1] ? attr[0].slice(tmp[0].length+1) : tmp[0])
349 }
350 return Function(
351 "g,a",
352 "return function(o,a){return " +
353 exports.stringify(map).replace(/:(\d+)/g,":g[$1](o)") + "}"
354 )(arr, aclFn)
355 }
356
357 function isObject(obj) {
358 return !!obj && obj.constructor === Object
359 }
360
361 function inArray(a, fn, idx) {
362 for (var i = -1, len = a.length; ++i < len; ) {
363 if (fn(a[i])) return idx == null ? a[i] : i
364 }
365 return idx != null && len
366 }
367
368 function inObject(o, fn, idx) {
369 for (var key in o) {
370 if (fn(o[key])) return idx == null ? o[key] : key
371 }
372 return null
373 }
374// `this` refers to the `window` in browser and to the `exports` in Node.js.
375}(JSON, Object)
376
377