UNPKG

10.3 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, 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, 1) + (arr ? "i" : "j") + "(o)&&" + v + (
130 sub[1] ? (arr ? "o" : "K(o)") + (sub[0] === "*" ? "" : ".length") :
131 +arr == arr ? "o[" + (arr < 0 ? "o.length" + arr : arr) + "]" :
132 (arr ? "I" : "J") + "(o,f('" + sub[0] + "'))"
133 ) + ")" :
134 v + "o['" + path + (
135 arr === "" ? "'])&&i(c)&&c" :
136 obj === "" ? "'])&&j(c)&&c" :
137 "'])"
138 )
139 ) + (dot ? "&&" : "")
140 }
141
142 function pathSet(str, path, arr, obj, dot) {
143 var op = "o['" + path + "']"
144 , out = ""
145 , sub = arr || obj
146 if (sub) {
147 out = "(o="+(arr?"i":"j")+"(o['" + path + "'])?o['" + path + "']:(o['" + path + "']="+(arr?"[]":"{}")+"))&&"
148 if (arr === "-") {
149 op = "o[o.length]"
150 } else if (+arr == arr) {
151 op = "o[" + (arr < 0 ? "o.length" + arr : arr) + "]"
152 } else {
153 if (!onlyFilterRe.test(arr)) throw Error(FILTER_ERR + str)
154 op = "o[t]"
155 out += "(t="+(arr?"I":"J")+"(o,f('" + sub + "'),1))!=null&&"
156 }
157 }
158 return out + (dot ?
159 "(o=typeof " + op + "==='object'&&" + op + "||(" + op + "={}))&&" :
160 "((c=" + op + "),(" + op + "=v),c)"
161 )
162 }
163
164 function pathFn(str, set) {
165 var map = set === true ? setFns : getFns
166 return map[str] || (map[str] = Function(
167 "i,j,I,J,K,f",
168 "return function(d,v,b){var c,o,t;return (o=d)&&" +
169 pathStr(str, set) +
170 (set ? ",c}": "!==void 0?c:v}")
171 )(isArray, isObject, inArray, inObject, KEYS, matcher))
172 }
173
174 function clone(obj) {
175 var temp, key
176 if (obj && typeof obj == "object") {
177 // new Date().constructor() returns a string
178 temp = obj instanceof Date ? new Date(+obj) :
179 obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
180 obj.constructor()
181 for (key in obj) if (hasOwn.call(obj, key)) {
182 temp[key] = clone(obj[key])
183 }
184 obj = temp
185 }
186 return obj
187 }
188
189 function matcher(str, prefix, opts, getter, tmp) {
190 var optimized
191 , arr = []
192 , key = (prefix || "") + (fns[str] || filterStr(str, opts, arr, getter))
193 , fn = filterFns[key]
194 if (!fn) {
195 for (optimized = key; optimized != (optimized = optimized.replace(cleanRe, "$1")); );
196 fn = filterFns[key] = Function(
197 fns[str] ? "a" : "a,i,j,I,J,K,f,p,t",
198 "return function(d,b){var o;return " + optimized + "}"
199 )
200 fn.source = optimized
201 }
202 return fns[str] ? fn : fn(
203 arr, isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, tmp
204 )
205 }
206
207 // Date{day=1,2}
208 // sliceable[start:stop:step]
209 // Geo{distance=200km&lat=40&lon=-70}
210 // ?pos=Geo{distance=200km&lat=@lat&lon=@lon}
211 // [lon, lat] in The GeoJSON Format RFC 7946
212 // IP{net=127.0.0.1/30}
213 // var re = /^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?:\.(?=.)|$)){4}$/
214 // ["1.2.3.4", "127.0.0.1", "192.175.255.254."].map(re.test, re)
215
216 matcher.date = function(str) {
217 return matcher(str, "(t.setTime(+d)>=0)&&", null, dateGetter, tmpDate)
218 }
219
220 function dateGetter(name) {
221 return "(t.get" + fnMap[name] + ")"
222 }
223
224 function filterStr(qs, opts, arr, getter) {
225 return qs.replace(filterRe, worker).replace(/^[1&]&+|&+1?$/g, "") || "1"
226
227 function worker(all, not, isOption, attr, isArray, op, val, q1, q2, q3, ext, ok2, ok1) {
228 if (ext) {
229 if (!ok2 && !ok1) {
230 throw Error(FILTER_ERR + qs)
231 }
232 return ok1 ? ok1 : ok2 == ";" ? "&&" : ok2 + ok2
233 }
234 if (isOption) {
235 if (opts) opts[attr] = val
236 return "1"
237 }
238
239 var idd, m, v, isRe
240 , a = []
241 , pre = "(o=d)&&"
242
243 attr = (getter || pathStr)(attr)
244
245 if (m = attr.match(/\(c=(.*?)\)$/)) {
246 if (m[1] == "K(o)") {
247 pre += attr + "&&"
248 attr = "c"
249 } else {
250 if (m.index) pre += attr.slice(0, m.index)
251 attr = m[1]
252 }
253 }
254
255 if (op == "!=" || op == "!==") {
256 not = "!"
257 op = op.slice(1)
258 }
259 if (isArray) {
260 pre += not + (isArray === "[]" ? "i(" : "j(") + attr + ")"
261 }
262
263 if (!op) {
264 return isArray === "" ? pre + not + attr : pre
265 }
266
267 if (op == "=" || op == "==") op += "="
268 if (val === "") val="''"
269 for (; m = valRe.exec(val); ) {
270 // quote, extension, subquery, subQuote, subSubQuote, at
271 // Parameterized query ?name=$name|name=:name
272 isRe = 0
273 v = m[6] == "$" ? "b['"+ m[7] +"']" : arrIdx(arr,
274 m[1] || m[3] ? m[0].slice(m[3] ? m[2].length + 1 : 1, -1) :
275 m[6] ? m[7] :
276 primitiveRe.test(m[0]) ? JSON.parse(m[0]) :
277 (isRe = globRe.test(m[0])) ? RegExp(
278 "^" + m[0]
279 .replace(reEscRe, "\\$&")
280 .replace(globReplace, ".")
281 .replace(globGroup, "[^") + "$",
282 op === "==" ? "i" : ""
283 ) :
284 m[0]
285 )
286 idd = (
287 m[2] ? "f." + m[2].toLowerCase() :
288 m[3] ? "f" :
289 isArray || attr === "c" ? arrIdx(arr, matcher(isRe ? "~" : op)) :
290 ""
291 ) + "(" + v
292 a.push(
293 isArray || attr === "c" ? (isArray == "{}" ? "J(" : "I(") + attr + "," + idd + "))" :
294 m[2] || m[3] ? idd + ")(" + attr + ")" :
295 isRe ? "typeof " + attr + "==='string'&&" + v + ".test(" + attr + ")" :
296 m[6] ? attr + "!==void 0&&" + attr + op + (
297 m[6] == "$" ? "b['"+ m[7] +"']" : "p(" + v + ")(o)"
298 ) :
299 attr + op + v
300 )
301 }
302
303 return pre + (
304 isArray ? (not ? "||" : "&&") : ""
305 ) + not + "(" + a.join("||") + ")"
306 }
307 }
308
309 function arrIdx(arr, val) {
310 for (
311 var i = arr.length;
312 0 <= --i && !(
313 arr[i] === val ||
314 val && val.source && val.source === arr[i].source
315 );
316 );
317 return "a[" + (-1 < i ? i : arr.push(val) - 1) + "]"
318 }
319
320 function setForm(map, key_, val) {
321 for (var match, key = key_, step = map; match = keyRe.exec(key_); ) {
322 if (step === map) key = key.slice(0, match.index)
323 match = match[1]
324 step = step[key] || (
325 step[key] = match && +match != match ? {} : []
326 )
327 key = match
328 }
329 if (isArray(step)) {
330 step.push(val)
331 } else if (isArray(step[key])) {
332 step[key].push(val)
333 } else {
334 step[key] = step[key] != null ? [step[key], val] : val
335 }
336 }
337
338 function tr(attrs, aclFn) {
339 var attr, tmp
340 , arr = []
341 , map = {}
342 , i = 0
343 for (; attr = valRe.exec(attrs); ) {
344 tmp = attr[0].split(":")
345 exports.set(map, tmp[0], i)
346 arr[i++] = pathFn(tmp[1] ? attr[0].slice(tmp[0].length+1) : tmp[0])
347 }
348 return Function(
349 "g,a",
350 "return function(o,a){return " +
351 JSON.stringify(map).replace(/:(\d+)/g,":g[$1](o)") + "}"
352 )(arr, aclFn)
353 }
354
355 function isObject(obj) {
356 return !!obj && obj.constructor === Object
357 }
358
359 function inArray(a, fn, idx) {
360 for (var i = -1, len = a.length; ++i < len; ) {
361 if (fn(a[i])) return idx == null ? a[i] : i
362 }
363 return idx != null && len
364 }
365
366 function inObject(o, fn, idx) {
367 for (var key in o) {
368 if (fn(o[key])) return idx == null ? o[key] : key
369 }
370 return null
371 }
372// `this` refers to the `window` in browser and to the `exports` in Node.js.
373}(JSON, Object)
374
375