Skip to content

Repository files navigation

Npm package versionCITypes

@sagold/json-pointer

json-pointer implementation following RFC 6901 to work with serializable paths into javascript data structures.

api | usage examples | fragment identifier | breaking changes

install

yarn add @sagold/json-pointer

usage

import{get,set,remove}from'@sagold/json-pointer';constdata={};get(data,'/path/to/nested/item');// undefinedset(data,'/path/to/nested/item',123);// { path: { to: { nested: { item: 123 }}}remove(data,'/path/to/nested/item');// { path: { to: { nested: { }}}

API

As the error handling is not further specified, this implementation will return undefined for any invalid pointer/missing data, making it very convenient to work with uncertain data.

methoddescription
get(data, pointer) -> valuereturns the value at given pointer
set(data, pointer, value) -> datasets the value at the given path
remove(data, pointer) -> dataremoves a property from data
join(...pointers) -> pointerjoins 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

importpointerfrom'@sagold/json-pointer';constdata={parent: {child: {title: 'title of child'}}}consttitleOfChild=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

importpointerfrom'@sagold/json-pointer';constvalue=pointer.get({},"/invalid/value",42);console.log(value);// output: 42

get also accepts a list of properties as pointer (e.g. split-result)

consttitleOfChild=pointer.get(data,['parent','child','title']);// output: 'title of child'console.log(pointer.get(data,['parent','missing','path']));// output: undefined

set

set(data:object|array, pointer:string|array, value:any) -> data:object|array

changes a nested value

importpointerfrom'@sagold/json-pointer';vardata={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

importpointerfrom'@sagold/json-pointer';constdata=pointer.set({},'/list/[]/value',42);console.log(data);// output: { list: [ { value: 42 } ] }

set also accepts a list of properties as pointer (e.g. split-result)

importpointerfrom'@sagold/json-pointer';constdata=pointer.set({},['list','[]','value'],42);console.log(data);// output: { list: [ { value: 42 } ] }

behaviour using set

set will create arrays when encountering a number

pointer.set({},['list','1','value'],42);// { list: [undefined, { value: 42 }] }

alternatively you may use array-syntax [index]

pointer.set({},['list','[1]','value'],42);// { list: [undefined, { value: 42 }] }

append items using empty array syntax []

pointer.set({list: [1,2]},['list','[]','value'],42);// { list: [1, 2, { value: 42 }] }

create object using object syntax {index}

pointer.set({},['list','{1}','value'],42);// { list: { 1: { value: 42 }}

⚠️set prefers existing data-type over specified data-types. For example: Setting an object for an existing array, will keep the object intact:

pointer.set({list: []},['list','{0}','value'],42);// { list: [{ value: 42 }] }

remove

remove(data:object|array, pointer:string|array) -> data:object|array

deletes a nested property or item

importpointerfrom'@sagold/json-pointer';constdata=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)

importpointerfrom'@sagold/json-pointer';constdata=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

importpointerfrom'@sagold/json-pointer';constlist=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

importpointerfrom'@sagold/json-pointer';constdata={a: {b: true}};constlist=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]

importpointerfrom'@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

importpointerfrom'@sagold/json-pointer';constkey='my key';console.log(pointer.join('root',key,'/to/target'));// output: '/root/my key/to/target'

and joins relative pointers as expected

importpointerfrom'@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

importpointerfrom'@sagold/json-pointer';constlist=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:

importpointerfrom'@sagold/json-pointer';constpath=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.

importpointerfrom'@sagold/json-pointer';// getconstvalue=pointer.get({'my value': true},'#/my%20value');console.log(value);// output: true// joinconstpointer=pointer.join('#/my value/to%20parent','../to~1child');console.log(pointer);// output: '#/my%20value/to~1child'// join an array of propertiesconsturiPointer=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

consturiPointer=pointer.join('my pointer','to','property',isURI=true);console.log(uriPointer);// output: '#/my%20pointer/to/property'consturiSimple=pointer.join('/my pointer/to/property',isURI=true);console.log(uriSimple);// output: '#/my%20pointer/to/property'constpointer=pointer.join('#/my pointer','to','property',isURI=false);console.log(pointer);// output: '/my pointer/to/property'

Breaking Changes

  • 2025/10/27 v7.2.0
    • changed exports to support esm
  • 2025/01/14 with v7
    • pointer.set creates arrays using numbers as properties /1 when the data is null or an array (previously created objects)
    • pointer.set creates objects for numbers when using object-syntax /{1} (previously unsupported)
  • 2024/04/06 with v6, selection of empty properties is supported:
    • "/" now selects an empty property (previously root-pointer)
    • "a//b" is now a valid pointer to "a" » "" » "b"
    • join no longer removes double slashes when joining join("/a/", "/b") » "/a//b"
  • 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

About

Failsafe value retrieval, modification and utils using json-pointer spec

Topics

Resources

Stars

14 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages