Initial commit
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
language: "node_js"
|
||||
node_js:
|
||||
- 0.10
|
||||
- 0.11
|
||||
- 0.12
|
||||
- 4.0
|
||||
- node
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2015 Jan Lehnardt <jan@apache.org> & Marc Bachmann <https://github.com/marcbachmann>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
# JSON Pointer for nodejs
|
||||
|
||||
This is an implementation of [JSON Pointer](http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-08).
|
||||
|
||||
## Usage
|
||||
```javascript
|
||||
var jsonpointer = require('jsonpointer');
|
||||
var obj = { foo: 1, bar: { baz: 2}, qux: [3, 4, 5]};
|
||||
|
||||
jsonpointer.get(obj, '/foo'); // returns 1
|
||||
jsonpointer.get(obj, '/bar/baz'); // returns 2
|
||||
jsonpointer.get(obj, '/qux/0'); // returns 3
|
||||
jsonpointer.get(obj, '/qux/1'); // returns 4
|
||||
jsonpointer.get(obj, '/qux/2'); // returns 5
|
||||
jsonpointer.get(obj, '/quo'); // returns null
|
||||
|
||||
jsonpointer.set(obj, '/foo', 6); // sets obj.foo = 6;
|
||||
jsonpointer.set(obj, '/qux/-', 6) // sets obj.qux = [3, 4, 5, 6]
|
||||
|
||||
var pointer = jsonpointer.compile('/foo')
|
||||
pointer.get(obj) // returns 1
|
||||
pointer.set(obj, 1) // sets obj.foo = 1
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
$ node test.js
|
||||
All tests pass.
|
||||
$
|
||||
|
||||
[](https://travis-ci.org/janl/node-jsonpointer)
|
||||
|
||||
## Author
|
||||
|
||||
(c) 2011-2015 Jan Lehnardt <jan@apache.org> & Marc Bachmann <https://github.com/marcbachmann>
|
||||
|
||||
## License
|
||||
|
||||
MIT License.
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
var jsonpointer = require('./')
|
||||
|
||||
var i
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 2
|
||||
},
|
||||
d: {
|
||||
e: [{ a: 3 }, { b: 4 }, { c: 5 }]
|
||||
}
|
||||
}
|
||||
|
||||
// Get
|
||||
console.time('get first level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.get(obj, '/a')
|
||||
}
|
||||
console.timeEnd('get first level property')
|
||||
|
||||
console.time('get second level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.get(obj, '/d/e')
|
||||
}
|
||||
console.timeEnd('get second level property')
|
||||
|
||||
console.time('get third level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.get(obj, '/d/e/0')
|
||||
}
|
||||
console.timeEnd('get third level property')
|
||||
|
||||
// Set
|
||||
console.time('set first level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.set(obj, '/a', 'bla')
|
||||
}
|
||||
console.timeEnd('set first level property')
|
||||
|
||||
console.time('set second level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.set(obj, '/d/e', 'bla')
|
||||
}
|
||||
console.timeEnd('set second level property')
|
||||
|
||||
console.time('set third level property')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.set(obj, '/d/e/0', 'bla')
|
||||
}
|
||||
console.timeEnd('set third level property')
|
||||
|
||||
console.time('push property into array')
|
||||
for (i = 0; i < 1e6; i++) {
|
||||
jsonpointer.set(obj, '/d/e/-', 'bla')
|
||||
}
|
||||
console.timeEnd('push property into array')
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
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;) {
|
||||
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)) {
|
||||
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') 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
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"jsonpointer@^4.0.0",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/is-my-json-valid"
|
||||
]
|
||||
],
|
||||
"_from": "jsonpointer@>=4.0.0 <5.0.0",
|
||||
"_id": "jsonpointer@4.0.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/jsonpointer",
|
||||
"_nodeVersion": "6.1.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-16-east.internal.npmjs.com",
|
||||
"tmp": "tmp/jsonpointer-4.0.0.tgz_1463651460494_0.02921536797657609"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "marc.brookman@gmail.com",
|
||||
"name": "marcbachmann"
|
||||
},
|
||||
"_npmVersion": "3.8.6",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "jsonpointer",
|
||||
"raw": "jsonpointer@^4.0.0",
|
||||
"rawSpec": "^4.0.0",
|
||||
"scope": null,
|
||||
"spec": ">=4.0.0 <5.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/is-my-json-valid"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz",
|
||||
"_shasum": "6661e161d2fc445f19f98430231343722e1fcbd5",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "jsonpointer@^4.0.0",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/is-my-json-valid",
|
||||
"author": {
|
||||
"email": "jan@apache.org",
|
||||
"name": "Jan Lehnardt"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://github.com/janl/node-jsonpointer/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Joe Hildebrand",
|
||||
"email": "joe-github@cursive.net"
|
||||
},
|
||||
{
|
||||
"name": "Marc Bachmann",
|
||||
"email": "marc.brookman@gmail.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "Simple JSON Addressing.",
|
||||
"devDependencies": {
|
||||
"standard": "^5.3.1"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "6661e161d2fc445f19f98430231343722e1fcbd5",
|
||||
"tarball": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"gitHead": "2d46030ba6df41b566934c7202e31fb65058de71",
|
||||
"homepage": "https://github.com/janl/node-jsonpointer#readme",
|
||||
"license": "MIT",
|
||||
"main": "./jsonpointer",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jan",
|
||||
"email": "jan@apache.org"
|
||||
},
|
||||
{
|
||||
"name": "marcbachmann",
|
||||
"email": "marc.brookman@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "jsonpointer",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/janl/node-jsonpointer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && node test.js"
|
||||
},
|
||||
"tags": [
|
||||
"simple",
|
||||
"util",
|
||||
"util",
|
||||
"utility"
|
||||
],
|
||||
"version": "4.0.0"
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
var assert = require('assert')
|
||||
var jsonpointer = require('./jsonpointer')
|
||||
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 2
|
||||
},
|
||||
d: {
|
||||
e: [{ a: 3 }, { b: 4 }, { c: 5 }]
|
||||
}
|
||||
}
|
||||
|
||||
assert.equal(jsonpointer.get(obj, '/a'), 1)
|
||||
assert.equal(jsonpointer.get(obj, '/b/c'), 2)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/0/a'), 3)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/1/b'), 4)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/2/c'), 5)
|
||||
|
||||
// set returns old value
|
||||
assert.equal(jsonpointer.set(obj, '/a', 2), 1)
|
||||
assert.equal(jsonpointer.set(obj, '/b/c', 3), 2)
|
||||
assert.equal(jsonpointer.set(obj, '/d/e/0/a', 4), 3)
|
||||
assert.equal(jsonpointer.set(obj, '/d/e/1/b', 5), 4)
|
||||
assert.equal(jsonpointer.set(obj, '/d/e/2/c', 6), 5)
|
||||
|
||||
// set nested properties
|
||||
assert.equal(jsonpointer.set(obj, '/f/g/h/i', 6), undefined)
|
||||
assert.equal(jsonpointer.get(obj, '/f/g/h/i'), 6)
|
||||
|
||||
// set an array
|
||||
assert.equal(jsonpointer.set(obj, '/f/g/h/foo/-', 'test'), undefined)
|
||||
var arr = jsonpointer.get(obj, '/f/g/h/foo')
|
||||
assert(Array.isArray(arr), 'set /- creates an array.')
|
||||
assert.equal(arr[0], 'test')
|
||||
|
||||
assert.equal(jsonpointer.get(obj, '/a'), 2)
|
||||
assert.equal(jsonpointer.get(obj, '/b/c'), 3)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/0/a'), 4)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/1/b'), 5)
|
||||
assert.equal(jsonpointer.get(obj, '/d/e/2/c'), 6)
|
||||
|
||||
// can set `null` as a value
|
||||
assert.equal(jsonpointer.set(obj, '/f/g/h/foo/0', null), 'test')
|
||||
assert.strictEqual(jsonpointer.get(obj, '/f/g/h/foo/0'), null)
|
||||
assert.equal(jsonpointer.set(obj, '/b/c', null), 3)
|
||||
assert.strictEqual(jsonpointer.get(obj, '/b/c'), null)
|
||||
|
||||
assert.equal(jsonpointer.get(obj, ''), obj)
|
||||
assert.throws(function () { jsonpointer.get(obj, 'a') }, validateError)
|
||||
assert.throws(function () { jsonpointer.get(obj, 'a/') }, validateError)
|
||||
|
||||
// can unset values with `undefined`
|
||||
jsonpointer.set(obj, '/a', undefined)
|
||||
assert.strictEqual(jsonpointer.get(obj, '/a'), undefined)
|
||||
jsonpointer.set(obj, '/d/e/1', undefined)
|
||||
assert.strictEqual(jsonpointer.get(obj, '/d/e/1'), undefined)
|
||||
|
||||
// returns `undefined` when path extends beyond any existing objects
|
||||
assert.strictEqual(jsonpointer.get(obj, '/x/y/z'), undefined)
|
||||
|
||||
function validateError (err) {
|
||||
if ((err instanceof Error) && /Invalid JSON pointer/.test(err.message)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var complexKeys = {
|
||||
'a/b': {
|
||||
c: 1
|
||||
},
|
||||
d: {
|
||||
'e/f': 2
|
||||
},
|
||||
'~1': 3,
|
||||
'01': 4
|
||||
}
|
||||
|
||||
assert.equal(jsonpointer.get(complexKeys, '/a~1b/c'), 1)
|
||||
assert.equal(jsonpointer.get(complexKeys, '/d/e~1f'), 2)
|
||||
assert.equal(jsonpointer.get(complexKeys, '/~01'), 3)
|
||||
assert.equal(jsonpointer.get(complexKeys, '/01'), 4)
|
||||
assert.equal(jsonpointer.get(complexKeys, '/a/b/c'), null)
|
||||
assert.equal(jsonpointer.get(complexKeys, '/~1'), null)
|
||||
|
||||
// draft-ietf-appsawg-json-pointer-08 has special array rules
|
||||
var ary = [ 'zero', 'one', 'two' ]
|
||||
assert.equal(jsonpointer.get(ary, '/01'), null)
|
||||
|
||||
assert.equal(jsonpointer.set(ary, '/-', 'three'), null)
|
||||
assert.equal(ary[3], 'three')
|
||||
|
||||
// Examples from the draft:
|
||||
var example = {
|
||||
'foo': ['bar', 'baz'],
|
||||
'': 0,
|
||||
'a/b': 1,
|
||||
'c%d': 2,
|
||||
'e^f': 3,
|
||||
'g|h': 4,
|
||||
'i\\j': 5,
|
||||
'k\'l': 6,
|
||||
' ': 7,
|
||||
'm~n': 8
|
||||
}
|
||||
|
||||
assert.equal(jsonpointer.get(example, ''), example)
|
||||
var ans = jsonpointer.get(example, '/foo')
|
||||
assert.equal(ans.length, 2)
|
||||
assert.equal(ans[0], 'bar')
|
||||
assert.equal(ans[1], 'baz')
|
||||
assert.equal(jsonpointer.get(example, '/foo/0'), 'bar')
|
||||
assert.equal(jsonpointer.get(example, '/'), 0)
|
||||
assert.equal(jsonpointer.get(example, '/a~1b'), 1)
|
||||
assert.equal(jsonpointer.get(example, '/c%d'), 2)
|
||||
assert.equal(jsonpointer.get(example, '/e^f'), 3)
|
||||
assert.equal(jsonpointer.get(example, '/g|h'), 4)
|
||||
assert.equal(jsonpointer.get(example, '/i\\j'), 5)
|
||||
assert.equal(jsonpointer.get(example, '/k\'l'), 6)
|
||||
assert.equal(jsonpointer.get(example, '/ '), 7)
|
||||
assert.equal(jsonpointer.get(example, '/m~0n'), 8)
|
||||
|
||||
// jsonpointer.compile(path)
|
||||
var a = {foo: 'bar'}
|
||||
var pointer = jsonpointer.compile('/foo')
|
||||
assert.equal(pointer.get(a), 'bar')
|
||||
assert.equal(pointer.set(a, 'test'), 'bar')
|
||||
assert.equal(pointer.get(a), 'test')
|
||||
assert.deepEqual(a, {foo: 'test'})
|
||||
|
||||
console.log('All tests pass.')
|
||||
Reference in New Issue
Block a user