@sagold/json-pointer
Advanced tools
Comparing version 1.0.1 to 5.0.0
{ | ||
"name": "@sagold/json-pointer", | ||
"version": "1.0.1", | ||
"description": "json pointer - failsafe data retrieval on js or json objects", | ||
"main": "lib/index.js", | ||
"version": "5.0.0", | ||
"description": "json pointer - failsafe data retrieval from js and json objects", | ||
"main": "dist/jsonPointer.js", | ||
"types": "dist/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sagold/json-pointer.git" | ||
}, | ||
"pre-push": [ | ||
"test" | ||
], | ||
"scripts": { | ||
"test": "mocha --recursive 'test/unit/*.test.js' -R spec; exit 0", | ||
"tdd": "watch 'npm run test' lib/ app/ test/; exit 0", | ||
"publish": "npm publish --access public" | ||
"dist": "rm -rf dist; NODE_ENV=production webpack", | ||
"test": "TS_NODE_PROJECT=./test/tsconfig.json mocha -r ts-node/register 'test/**/*.test.ts'", | ||
"prepublish": "yarn test && yarn dist", | ||
"lint": "eslint lib", | ||
"coverage": "nyc yarn test" | ||
}, | ||
"keywords": [], | ||
"author": "Sascha Goldhofer <noreply@saschagoldhofer.de> (https://github.com/sagold/)", | ||
"license": "ISC", | ||
"keywords": [ | ||
"json-pointer", | ||
"json path", | ||
"data retrieval", | ||
"typescript", | ||
"RFC 6901", | ||
"make my day" | ||
], | ||
"author": "Sascha Goldhofer <github@saschagoldhofer.de> (https://github.com/sagold/)", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"mocha": "^3.1.2", | ||
"watch": "^1.0.1" | ||
"@types/chai": "^4.3.4", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "^16.14.2", | ||
"@typescript-eslint/eslint-plugin": "^5.45.0", | ||
"@typescript-eslint/parser": "^5.45.0", | ||
"chai": "^4.3.7", | ||
"eslint": "^8.28.0", | ||
"eslint-plugin-array-func": "^3.1.7", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-optimize-regex": "^1.2.1", | ||
"eslint-plugin-promise": "^6.1.1", | ||
"mocha": "^10.1.0", | ||
"nyc": "^15.1.0", | ||
"terser-webpack-plugin": "^5.3.6", | ||
"ts-loader": "^9.4.2", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^4.9.3", | ||
"webpack": "^5.75.0", | ||
"webpack-cli": "^5.0.0" | ||
} | ||
} |
271
README.md
@@ -1,80 +0,257 @@ | ||
# Json Pointer | ||
<h1 align="left"><img src="./docs/json-pointer.png" width="296" alt="@sagold/json-pointer"></h1> | ||
Here is a [solid json-pointer implementation](https://github.com/manuelstofer/json-pointer). | ||
The main differences to this implementation are | ||
This is a json-pointer implementation following [RFC 6901](https://tools.ietf.org/html/rfc6901). | ||
As the _error handling_ is not further specified, this implementation will return `undefined` for any invalid | ||
pointer/missing data, making it very convenient to check uncertain data, i.e. | ||
- conforms to [RFC 6901](https://tools.ietf.org/html/rfc6901) | ||
- throws an error when a value is not found / the pointer is invalid | ||
- additional utilities | ||
install | ||
This json-pointer implementation will return `undefined` if the pointer could not be resolved, which allows checks like | ||
`if (pointer.get(data, "#/path/to/nested/item") {...}` | ||
instead of | ||
`if (path && path.to && path.to.nested ...`. | ||
`yarn add @sagold/json-pointer` | ||
This library exposes | ||
usage | ||
- jsonpointer.get | ||
- jsonpointer.set and | ||
- jsonpointer.delete | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const data = {}; | ||
if (pointer.get(data, '/path/to/nested/item') !== undefined) { | ||
// value is set, do something | ||
} | ||
// instead of | ||
if (data.path && data.path.to && data.path.to.nested && data.path.to.nested.item) { | ||
// value is set, do something | ||
} | ||
``` | ||
## install | ||
`npm i @sagold/json-pointer` | ||
## Breaking Changes | ||
- 2022/12/02 with `v5`, package has been renamed to `json-pointer` and published under `@sagold/json-pointer` | ||
- 2020/11/09 with `v4`, `pointer.delete` has been renamed to `remove` | ||
## pointer.get | ||
## API | ||
| method | description | ||
| ----------------------------------------- | ------------------------------------------------------------- | ||
| get(data, pointer) -> value | returns the value at given pointer | ||
| set(data, pointer, value) -> data | sets the value at the given path | ||
| remove(data, pointer) -> data | removes a property from data | ||
| join(...pointers) -> pointer | joins multiple pointers to a single one | ||
| split(pointer) -> [array] | returns a json-pointer as an array | ||
| splitLast(pointer) -> [pointer, property] | returns parent-pointer and last property | ||
> The methods `get`, `set`, `remove` and `join` also accept a list of properties as pointer. Using join with a list | ||
> of properties, its signature changes to `join(properties:string[], isURI=false) -> string` | ||
## Usage Examples | ||
### get | ||
> get(data:object|array, pointer:string|array, defaultValue:any) -> value:any | ||
returns nested values | ||
```js | ||
var data = { | ||
parent: { | ||
child: { | ||
title: "title of child" | ||
} | ||
} | ||
} | ||
import pointer from '@sagold/json-pointer'; | ||
const data = { | ||
parent: { | ||
child: { | ||
title: 'title of child' | ||
} | ||
} | ||
} | ||
var titleOfChild = pointer.get(data, "#/parent/child/title"); // "title of child" | ||
const titleOfChild = pointer.get(data, '/parent/child/title'); // output: 'title of child' | ||
console.log(pointer.get(data, '/parent/missing/path')); // output: undefined | ||
``` | ||
and may optionally return a default value with | ||
## pointer.set | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const value = pointer.get({}, "/invalid/value", 42); | ||
console.log(value); // output: 42 | ||
``` | ||
set values on an object | ||
`get` also accepts a list of properties as pointer (e.g. split-result) | ||
```js | ||
var data = { | ||
parent: { | ||
children: [ | ||
{ | ||
title: "title of child" | ||
} | ||
] | ||
} | ||
}; | ||
const titleOfChild = pointer.get(data, ['parent', 'child', 'title']); // output: 'title of child' | ||
console.log(pointer.get(data, ['parent', 'missing', 'path'])); // output: undefined | ||
``` | ||
pointer.set(data, "#/parent/children/1", {title: "second child"}); | ||
console.log(data.parent.children.length); // 2 | ||
### set | ||
> set(data:object|array, pointer:string|array, value:any) -> data:object|array | ||
changes a nested value | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
var data = { | ||
parent: { | ||
children: [ | ||
{ | ||
title: 'title of child' | ||
} | ||
] | ||
} | ||
}; | ||
pointer.set(data, '/parent/children/1', { title: 'second child' }); | ||
console.log(data.parent.children.length); // output: 2 | ||
``` | ||
and may be used to build data | ||
## pointer.delete | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const data = pointer.set({}, '/list/[]/value', 42); | ||
console.log(data); // output: { list: [ { value: 42 } ] } | ||
``` | ||
delete properties or array items | ||
`set` also accepts a list of properties as pointer (e.g. split-result) | ||
```js | ||
pointer.delete(data, "#/parent/arrayOrObject/1"); | ||
import pointer from '@sagold/json-pointer'; | ||
const data = pointer.set({}, ['list', '[]', 'value'], 42); | ||
console.log(data); // output: { list: [ { value: 42 } ] } | ||
``` | ||
## Helpers | ||
### remove | ||
### pointer.join | ||
> remove(data:object|array, pointer:string|array) -> data:object|array | ||
`pointer.join` joins all arguments to a valid json pointer: | ||
deletes a nested property or item | ||
```js | ||
var key = "child"; | ||
var target = pointer.join("parent", key, "title"); // "#/parent/child/title" | ||
``` | ||
import pointer from '@sagold/json-pointer'; | ||
const data = pointer.remove({ parent: { arrayOrObject: [ 0, 1 ] }}, '/parent/arrayOrObject/1'); | ||
console.log(data.parent.arrayOrObject); // output: [0] | ||
``` | ||
`remove` also accepts a list of properties as pointer (e.g. split-result) | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const data = pointer.remove({ parent: { arrayOrObject: [ 0, 1 ] }}, ['parent', 'arrayOrObject', '1']); | ||
console.log(data.parent.arrayOrObject); // output: [0] | ||
``` | ||
### split | ||
> split(pointer:string) -> properties:array | ||
returns a json-pointer as a list of (escaped) properties | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const list = pointer.split('/parent/arrayOrObject/1'); | ||
console.log(list); // output: ['parent', 'arrayOrObject', '1'] | ||
``` | ||
In order to resolve a list of properties, you can directly pass the list to `get`, `set` or `remove` | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const data = { a: { b: true } }; | ||
const list = pointer.split('/a/b'); | ||
console.log(pointer.get(data, list)); // output: true | ||
``` | ||
### splitLast | ||
> splitLast(pointer:string) -> [pointer, property] | ||
separates json-pointers last property and returns both values as [parent-pointer, property] | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const [parent, property] = pointer.splitLast('/parent/arrayOrObject/1'); | ||
console.log(parent); // output: '/parent/arrayOrObject' | ||
console.log(property); // output: '1' | ||
``` | ||
### join | ||
> join(...pointers:string[]) -> pointer:string | ||
joins all arguments to a valid json pointer | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const key = 'my key'; | ||
console.log(pointer.join('root', key, '/to/target')); // output: '/root/my key/to/target' | ||
``` | ||
and joins relative pointers as expected | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
console.log(pointer.join('/path/to/value', '../object')); // output: '/path/to/object' | ||
``` | ||
in order to join an array received from split, you can use `join(properties:string[], isURI=false) -> string` to | ||
retrieve a valid pointer | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const list = pointer.split('/my/path/to/child'); | ||
list.pop(); | ||
console.log(pointer.join(list)); // output: '/my/path/to' | ||
``` | ||
To join an array of pointers, you must use it with `join(...pointers)` or all pointers will be treated as properties: | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
const path = pointer.join(...['/path/to/value', '../object']); | ||
console.log(path); // output: '/path/to/object' | ||
// passing the array directly, will treat each entry as a property, which will be escaped and resolves to: | ||
pointer.join(['/path/to/value', '../object']); // output: '/~1path~1to~1value/..~1object' | ||
``` | ||
## Fragment identifier | ||
All methods support a leading uri fragment identifier (#), which will ensure that property-values are uri decoded | ||
when resolving the path within data. This also ensures that any pointer is returned uri encoded with a leading `#`. e.g. | ||
```js | ||
import pointer from '@sagold/json-pointer'; | ||
// get | ||
const value = pointer.get({ 'my value': true }, '#/my%20value'); | ||
console.log(value); // output: true | ||
// join | ||
const pointer = pointer.join('#/my value/to%20parent', '../to~1child'); | ||
console.log(pointer); // output: '#/my%20value/to~1child' | ||
// join an array of properties | ||
const uriPointer = pointer.join(['my value', 'to~1child'], isURI = true); | ||
console.log(uriPointer); // output: '#/my%20value/to~1child' | ||
``` | ||
Additionally `join(...pointers, isURI)` may be used to enforce the pointer type, which is helpful in sanitizing inputs | ||
```js | ||
const uriPointer = pointer.join('my pointer', 'to', 'property', isURI = true); | ||
console.log(uriPointer); // output: '#/my%20pointer/to/property' | ||
const uriSimple = pointer.join('/my pointer/to/property', isURI = true); | ||
console.log(uriSimple); // output: '#/my%20pointer/to/property' | ||
const pointer = pointer.join('#/my pointer', 'to', 'property', isURI = false); | ||
console.log(pointer); // output: '/my pointer/to/property' | ||
``` | ||
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
24761
23
404
258
0
19
1