GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - sagold/json-pointer: Failsafe value retrieval, modification and utils using json-pointer spec

BranchesTags
Open more actions menu

Latest commit

 

History

194 Commits
194 Commits

Folders and files

NameName
Last commit message
Last commit date
.github/workflows
.github/workflows
 
 
dist
dist
 
 
docs
docs
 
 
lib
lib
 
 
test
test
 
 
.eslintignore
.eslintignore
 
 
.gitignore
.gitignore
 
 
.mocharc.json
.mocharc.json
 
 
.npmignore
.npmignore
 
 
LICENSE.md
LICENSE.md
 
 
README.md
README.md
 
 
eslint.config.mjs
eslint.config.mjs
 
 
index.ts
index.ts
 
 
package.json
package.json
 
 
tsconfig.json
tsconfig.json
 
 
tsdown.config.ts
tsdown.config.ts
 
 
yarn.lock
yarn.lock
 
 

Repository files navigation

Npm package version CI Types

@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';
const data = {};

get(data, '/path/to/nested/item'); // undefined
set(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.

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

import pointer from '@sagold/json-pointer';
const 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

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

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

const titleOfChild = 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

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

import pointer from '@sagold/json-pointer';
const data = 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)

import pointer from '@sagold/json-pointer';
const data = 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

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)

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

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

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]

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

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

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

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:

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.

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

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'

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

failsafejson-pointermodifyretrieverfc-6901

Resources

Readme
MIT license
Activity

Stars

14 stars

Watchers

2 watching

Forks

3 forks
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.