You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					101 lines
				
				2.5 KiB
			
		
		
			
		
	
	
					101 lines
				
				2.5 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var hasExcape = /~/
							 | 
						||
| 
								 | 
							
								var escapeMatcher = /~[01]/g
							 | 
						||
| 
								 | 
							
								function escapeReplacer (m) {
							 | 
						||
| 
								 | 
							
								  switch (m) {
							 | 
						||
| 
								 | 
							
								    case '~1': return '/'
							 | 
						||
| 
								 | 
							
								    case '~0': return '~'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  throw new Error('Invalid tilde escape: ' + m)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function untilde (str) {
							 | 
						||
| 
								 | 
							
								  if (!hasExcape.test(str)) return str
							 | 
						||
| 
								 | 
							
								  return str.replace(escapeMatcher, escapeReplacer)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function setter (obj, pointer, value) {
							 | 
						||
| 
								 | 
							
								  var part
							 | 
						||
| 
								 | 
							
								  var hasNextPart
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (var p = 1, len = pointer.length; p < len;) {
							 | 
						||
| 
								 | 
							
								    if (pointer[p] === 'constructor' || pointer[p] === 'prototype' || pointer[p] === '__proto__') return obj
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    part = untilde(pointer[p++])
							 | 
						||
| 
								 | 
							
								    hasNextPart = len > p
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (typeof obj[part] === 'undefined') {
							 | 
						||
| 
								 | 
							
								      // support setting of /-
							 | 
						||
| 
								 | 
							
								      if (Array.isArray(obj) && part === '-') {
							 | 
						||
| 
								 | 
							
								        part = obj.length
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // support nested objects/array when setting values
							 | 
						||
| 
								 | 
							
								      if (hasNextPart) {
							 | 
						||
| 
								 | 
							
								        if ((pointer[p] !== '' && pointer[p] < Infinity) || pointer[p] === '-') obj[part] = []
							 | 
						||
| 
								 | 
							
								        else obj[part] = {}
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!hasNextPart) break
							 | 
						||
| 
								 | 
							
								    obj = obj[part]
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var oldValue = obj[part]
							 | 
						||
| 
								 | 
							
								  if (value === undefined) delete obj[part]
							 | 
						||
| 
								 | 
							
								  else obj[part] = value
							 | 
						||
| 
								 | 
							
								  return oldValue
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function compilePointer (pointer) {
							 | 
						||
| 
								 | 
							
								  if (typeof pointer === 'string') {
							 | 
						||
| 
								 | 
							
								    pointer = pointer.split('/')
							 | 
						||
| 
								 | 
							
								    if (pointer[0] === '') return pointer
							 | 
						||
| 
								 | 
							
								    throw new Error('Invalid JSON pointer.')
							 | 
						||
| 
								 | 
							
								  } else if (Array.isArray(pointer)) {
							 | 
						||
| 
								 | 
							
								    for (const part of pointer) {
							 | 
						||
| 
								 | 
							
								      if (typeof part !== 'string' && typeof part !== 'number') {
							 | 
						||
| 
								 | 
							
								        throw new Error('Invalid JSON pointer. Must be of type string or number.')
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pointer
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  throw new Error('Invalid JSON pointer.')
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function get (obj, pointer) {
							 | 
						||
| 
								 | 
							
								  if (typeof obj !== 'object') throw new Error('Invalid input object.')
							 | 
						||
| 
								 | 
							
								  pointer = compilePointer(pointer)
							 | 
						||
| 
								 | 
							
								  var len = pointer.length
							 | 
						||
| 
								 | 
							
								  if (len === 1) return obj
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (var p = 1; p < len;) {
							 | 
						||
| 
								 | 
							
								    obj = obj[untilde(pointer[p++])]
							 | 
						||
| 
								 | 
							
								    if (len === p) return obj
							 | 
						||
| 
								 | 
							
								    if (typeof obj !== 'object' || obj === null) return undefined
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function set (obj, pointer, value) {
							 | 
						||
| 
								 | 
							
								  if (typeof obj !== 'object') throw new Error('Invalid input object.')
							 | 
						||
| 
								 | 
							
								  pointer = compilePointer(pointer)
							 | 
						||
| 
								 | 
							
								  if (pointer.length === 0) throw new Error('Invalid JSON pointer for set.')
							 | 
						||
| 
								 | 
							
								  return setter(obj, pointer, value)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function compile (pointer) {
							 | 
						||
| 
								 | 
							
								  var compiled = compilePointer(pointer)
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    get: function (object) {
							 | 
						||
| 
								 | 
							
								      return get(object, compiled)
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    set: function (object, value) {
							 | 
						||
| 
								 | 
							
								      return set(object, compiled, value)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.get = get
							 | 
						||
| 
								 | 
							
								exports.set = set
							 | 
						||
| 
								 | 
							
								exports.compile = compile
							 |