Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

json-ptr

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-ptr - npm Package Compare versions

Comparing version 1.2.1-ts.c739a2e.0 to 1.2.1-ts.d9366c0

dist.browser/json-ptr-with-browser-tests.js

9

dist/index.js
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./util"));
__export(require("./pointer"));
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./types"), exports);
tslib_1.__exportStar(require("./util"), exports);
tslib_1.__exportStar(require("./pointer"), exports);
//# sourceMappingURL=index.js.map
import { JsonStringPointer, UriFragmentIdentifierPointer, Pointer, PathSegments, JsonStringPointerListItem, UriFragmentIdentifierPointerListItem } from './types';
/**
* Signature of visitor functions, used with [[JsonPointer.visit]] method. Visitors are callbacks invoked for every segment/branch of a target's object graph.
*/
export declare type Visitor = (ptr: JsonStringPointer, val: unknown) => void;

@@ -9,9 +6,2 @@ declare const $ptr: unique symbol;

declare const $get: unique symbol;
/**
* Represents a JSON Pointer, capable of getting and setting values on object graphs at the pointer's dereferenced location.
*
* While there are static variants for most operations, our recommendation is to use the instance level methods, which enables you avoid repeated compiling/emitting transient accessors. Take a look at the speed comparisons for our justification.
*
* In most cases, create and reuse instances of JsonPointer within a scope that makes sense for your app. We often use a cache of frequently used pointers, but your use case may support constants, static members, or other long-lived scenarios.
*/
export declare class JsonPointer {

@@ -21,115 +11,34 @@ private [$ptr];

private [$get];
/**
* Creates a JsonPointer instance.
* @param ptr the string representation of a pointer, or it's decoded path.
*/
static create(ptr: Pointer | PathSegments): JsonPointer;
/**
* Determines if the `target` object has a value at the pointer's location in the object graph.
* @param target the target of the operation
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the where in the object graph to make the determination.
*/
static has(target: unknown, ptr: Pointer | PathSegments | JsonPointer): boolean;
/**
* Gets the value at the specified pointer's location in the object graph. If there is no value, then the result is `undefined`.
* @param target the target of the operation
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the where in the object graph to get the value.
*/
static get(target: unknown, ptr: Pointer | PathSegments | JsonPointer): unknown;
/**
* Set the value at the specified pointer's location in the object graph.
* @param target the target of the operation
* @param ptr the string representation
* @param val a value to wite into the object graph at the specified pointer location
* @param force indications whether the operation should force the pointer's location into existence in the object graph.
*/
static set(target: unknown, ptr: Pointer | PathSegments | JsonPointer, val: unknown, force?: boolean): unknown;
/**
* Decodes the specified pointer into path segments.
* @param ptr a string representation of a JSON Pointer
*/
static decode(ptr: Pointer): PathSegments;
/**
* Evaluates the target's object graph, calling the specified visitor for every unique pointer location discovered while walking the graph.
* @param target the target of the operation
* @param visitor a callback function invoked for each unique pointer location in the object graph
* @param fragmentId indicates whether the visitor should receive fragment identifiers or regular pointers
*/
static create(pointer: Pointer | PathSegments): JsonPointer;
static has(target: unknown, pointer: Pointer | PathSegments | JsonPointer): boolean;
static get(target: unknown, pointer: Pointer | PathSegments | JsonPointer): unknown;
static set(target: unknown, pointer: Pointer | PathSegments | JsonPointer, val: unknown, force?: boolean): unknown;
static unset(target: unknown, pointer: Pointer | PathSegments | JsonPointer): unknown;
static decode(pointer: Pointer): PathSegments;
static visit(target: unknown, visitor: Visitor, fragmentId?: boolean): void;
/**
* Evaluates the target's object graph, returning a [[JsonStringPointerListItem]] for each location in the graph.
* @param target the target of the operation
*/
static listPointers(target: unknown): JsonStringPointerListItem[];
/**
* Evaluates the target's object graph, returning a [[UriFragmentIdentifierPointerListItem]] for each location in the graph.
* @param target the target of the operation
*/
static listFragmentIds(target: unknown): UriFragmentIdentifierPointerListItem[];
/**
* Evaluates the target's object graph, returning a Record<Pointer, unknown> populated with pointers and the corresponding values from the graph.
* @param target the target of the operation
* @param fragmentId indicates whether the results are populated with fragment identifiers rather than regular pointers
*/
static flatten(target: unknown, fragmentId?: boolean): Record<Pointer, unknown>;
/**
* Evaluates the target's object graph, returning a Map&lt;Pointer,unknown> populated with pointers and the corresponding values form the graph.
* @param target the target of the operation
* @param fragmentId indicates whether the results are populated with fragment identifiers rather than regular pointers
*/
static map(target: unknown, fragmentId?: boolean): Map<Pointer, unknown>;
/**
* The pointer's decoded path through the object graph.
*/
readonly path: PathSegments;
/**
* Creates a new instance.
* @param ptr a string representation of a JSON Pointer, or a decoded array of path segments.
*/
constructor(ptr: Pointer | PathSegments);
/**
* Gets the value the specified target's object graph at this pointer's location.
* @param target the target of the operation
*/
get(target: unknown): unknown;
/**
* Set's the specified value in the specified target's object graph at this pointer's location.
*
* If any part of the pointer's path does not exist, the operation returns unless the caller indicates that pointer's location should be created.
* @param target the target of the operation
* @param value the value to set
* @param force indicates whether the pointer's location should be created if it doesn't already exist.
*/
set(target: unknown, value: unknown, force?: boolean): unknown;
/**
* Determines if the specified target's object graph has a value at the pointer's location.
* @param target the target of the operation
*/
unset(target: unknown): unknown;
has(target: unknown): boolean;
/**
* Creates a new instance by concatenating the specified pointer's path with this pointer's path.
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the additional path to concatenate onto the existing pointer.
*/
concat(ptr: JsonPointer | Pointer | PathSegments): JsonPointer;
/**
* This pointer's JSON Pointer encoded string representation.
*/
get pointer(): JsonStringPointer;
/**
* This pointer's URI fragment identifier encoded string representation.
*/
get uriFragmentIdentifier(): UriFragmentIdentifierPointer;
/**
* Produces this pointer's JSON Pointer encoded string representation.
*/
toString(): string;
}
declare const $pointer: unique symbol;
export declare class JsonReference {
static isReference(candidate: unknown): candidate is JsonReference;
pointer: JsonPointer;
$ref: UriFragmentIdentifierPointer;
constructor(ptr: JsonPointer | Pointer | PathSegments);
private readonly [$pointer];
readonly $ref: UriFragmentIdentifierPointer;
constructor(pointer: JsonPointer | Pointer | PathSegments);
resolve(target: unknown): unknown;
pointer(): JsonPointer;
toString(): string;
}
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonReference = exports.JsonPointer = void 0;
const util_1 = require("./util");

@@ -7,61 +8,50 @@ function isObject(value) {

}
function descendingVisit(target, visitor, encoder, cycle = false) {
function shouldDescend(obj) {
return isObject(obj) && !JsonReference.isReference(obj);
}
function descendingVisit(target, visitor, encoder) {
const distinctObjects = new Map();
const q = [];
let cursor2 = 0;
q.push({
obj: target,
path: [],
});
visitor(encoder([]), target);
while (cursor2 < q.length) {
const cursor = q[cursor2++];
if (isObject(cursor.obj)) {
if (Array.isArray(cursor.obj)) {
let j = -1;
const len2 = cursor.obj.length;
while (++j < len2) {
const it = cursor.obj[j];
const path = cursor.path.concat([j + '']);
if (isObject(it)) {
if (cycle && distinctObjects.has(it)) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define,@typescript-eslint/no-non-null-assertion
visitor(encoder(path), new JsonReference(distinctObjects.get(it)));
continue;
}
const q = [{ obj: target, path: [] }];
while (q.length) {
const { obj, path } = q.shift();
visitor(encoder(path), obj);
if (shouldDescend(obj)) {
distinctObjects.set(obj, new JsonPointer(util_1.encodeUriFragmentIdentifier(path)));
if (!Array.isArray(obj)) {
const keys = Object.keys(obj);
const len = keys.length;
let i = -1;
while (++i < len) {
const it = obj[keys[i]];
if (isObject(it) && distinctObjects.has(it)) {
q.push({
obj: new JsonReference(distinctObjects.get(it)),
path: path.concat(keys[i])
});
}
else {
q.push({
obj: it,
path: path,
path: path.concat(keys[i])
});
if (cycle) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
distinctObjects.set(it, new JsonPointer(util_1.encodeUriFragmentIdentifier(path)));
}
}
visitor(encoder(path), it);
}
}
else {
const keys = Object.keys(cursor.obj);
const len3 = keys.length;
let i = -1;
while (++i < len3) {
const it = cursor.obj[keys[i]];
const path = cursor.path.concat(keys[i]);
if (isObject(it)) {
if (cycle && distinctObjects.has(it)) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define,@typescript-eslint/no-non-null-assertion
visitor(encoder(path), new JsonReference(distinctObjects.get(it)));
continue;
}
let j = -1;
const len = obj.length;
while (++j < len) {
const it = obj[j];
if (isObject(it) && distinctObjects.has(it)) {
q.push({
obj: new JsonReference(distinctObjects.get(it)),
path: path.concat([j + ''])
});
}
else {
q.push({
obj: it,
path: path,
path: path.concat([j + ''])
});
if (cycle) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
distinctObjects.set(it, new JsonPointer(util_1.encodeUriFragmentIdentifier(path)));
}
}
visitor(encoder(path), it);
}

@@ -75,79 +65,39 @@ }

const $get = Symbol('getter');
/**
* Represents a JSON Pointer, capable of getting and setting values on object graphs at the pointer's dereferenced location.
*
* While there are static variants for most operations, our recommendation is to use the instance level methods, which enables you avoid repeated compiling/emitting transient accessors. Take a look at the speed comparisons for our justification.
*
* In most cases, create and reuse instances of JsonPointer within a scope that makes sense for your app. We often use a cache of frequently used pointers, but your use case may support constants, static members, or other long-lived scenarios.
*/
class JsonPointer {
/**
* Creates a new instance.
* @param ptr a string representation of a JSON Pointer, or a decoded array of path segments.
*/
constructor(ptr) {
this.path = util_1.decodePtrInit(ptr);
}
/**
* Creates a JsonPointer instance.
* @param ptr the string representation of a pointer, or it's decoded path.
*/
static create(ptr) {
return new JsonPointer(ptr);
static create(pointer) {
return new JsonPointer(pointer);
}
/**
* Determines if the `target` object has a value at the pointer's location in the object graph.
* @param target the target of the operation
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the where in the object graph to make the determination.
*/
static has(target, ptr) {
if (typeof ptr === 'string' || Array.isArray(ptr)) {
ptr = new JsonPointer(ptr);
static has(target, pointer) {
if (typeof pointer === 'string' || Array.isArray(pointer)) {
pointer = new JsonPointer(pointer);
}
return ptr.has(target);
return pointer.has(target);
}
/**
* Gets the value at the specified pointer's location in the object graph. If there is no value, then the result is `undefined`.
* @param target the target of the operation
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the where in the object graph to get the value.
*/
static get(target, ptr) {
if (typeof ptr === 'string' || Array.isArray(ptr)) {
ptr = new JsonPointer(ptr);
static get(target, pointer) {
if (typeof pointer === 'string' || Array.isArray(pointer)) {
pointer = new JsonPointer(pointer);
}
return ptr.get(target);
return pointer.get(target);
}
/**
* Set the value at the specified pointer's location in the object graph.
* @param target the target of the operation
* @param ptr the string representation
* @param val a value to wite into the object graph at the specified pointer location
* @param force indications whether the operation should force the pointer's location into existence in the object graph.
*/
static set(target, ptr, val, force = false) {
if (typeof ptr === 'string' || Array.isArray(ptr)) {
ptr = new JsonPointer(ptr);
static set(target, pointer, val, force = false) {
if (typeof pointer === 'string' || Array.isArray(pointer)) {
pointer = new JsonPointer(pointer);
}
return ptr.set(target, val, force);
return pointer.set(target, val, force);
}
/**
* Decodes the specified pointer into path segments.
* @param ptr a string representation of a JSON Pointer
*/
static decode(ptr) {
return util_1.pickDecoder(ptr)(ptr);
static unset(target, pointer) {
if (typeof pointer === 'string' || Array.isArray(pointer)) {
pointer = new JsonPointer(pointer);
}
return pointer.unset(target);
}
/**
* Evaluates the target's object graph, calling the specified visitor for every unique pointer location discovered while walking the graph.
* @param target the target of the operation
* @param visitor a callback function invoked for each unique pointer location in the object graph
* @param fragmentId indicates whether the visitor should receive fragment identifiers or regular pointers
*/
static decode(pointer) {
return util_1.pickDecoder(pointer)(pointer);
}
static visit(target, visitor, fragmentId = false) {
descendingVisit(target, visitor, fragmentId ? util_1.encodeUriFragmentIdentifier : util_1.encodePointer);
}
/**
* Evaluates the target's object graph, returning a [[JsonStringPointerListItem]] for each location in the graph.
* @param target the target of the operation
*/
static listPointers(target) {

@@ -160,6 +110,2 @@ const res = [];

}
/**
* Evaluates the target's object graph, returning a [[UriFragmentIdentifierPointerListItem]] for each location in the graph.
* @param target the target of the operation
*/
static listFragmentIds(target) {

@@ -172,7 +118,2 @@ const res = [];

}
/**
* Evaluates the target's object graph, returning a Record&lt;Pointer, unknown> populated with pointers and the corresponding values from the graph.
* @param target the target of the operation
* @param fragmentId indicates whether the results are populated with fragment identifiers rather than regular pointers
*/
static flatten(target, fragmentId = false) {

@@ -185,7 +126,2 @@ const res = {};

}
/**
* Evaluates the target's object graph, returning a Map&lt;Pointer,unknown> populated with pointers and the corresponding values form the graph.
* @param target the target of the operation
* @param fragmentId indicates whether the results are populated with fragment identifiers rather than regular pointers
*/
static map(target, fragmentId = false) {

@@ -196,6 +132,2 @@ const res = new Map();

}
/**
* Gets the value the specified target's object graph at this pointer's location.
* @param target the target of the operation
*/
get(target) {

@@ -207,32 +139,16 @@ if (!this[$get]) {

}
/**
* Set's the specified value in the specified target's object graph at this pointer's location.
*
* If any part of the pointer's path does not exist, the operation returns unless the caller indicates that pointer's location should be created.
* @param target the target of the operation
* @param value the value to set
* @param force indicates whether the pointer's location should be created if it doesn't already exist.
*/
set(target, value, force = false) {
return util_1.setValueAtPath(target, value, this.path, force);
}
/**
* Determines if the specified target's object graph has a value at the pointer's location.
* @param target the target of the operation
*/
unset(target) {
return util_1.unsetValueAtPath(target, this.path);
}
has(target) {
return typeof this.get(target) !== 'undefined';
}
/**
* Creates a new instance by concatenating the specified pointer's path with this pointer's path.
* @param ptr the string representation of a pointer, it's decoded path, or an instance of JsonPointer indicating the additional path to concatenate onto the existing pointer.
*/
concat(ptr) {
return new JsonPointer(this.path.concat(ptr instanceof JsonPointer ? ptr.path : util_1.decodePtrInit(ptr)));
}
/**
* This pointer's JSON Pointer encoded string representation.
*/
get pointer() {
if (!this[$ptr]) {
if (this[$ptr] === undefined) {
this[$ptr] = util_1.encodePointer(this.path);

@@ -242,5 +158,2 @@ }

}
/**
* This pointer's URI fragment identifier encoded string representation.
*/
get uriFragmentIdentifier() {

@@ -252,5 +165,2 @@ if (!this[$frg]) {

}
/**
* Produces this pointer's JSON Pointer encoded string representation.
*/
toString() {

@@ -261,6 +171,7 @@ return this.pointer;

exports.JsonPointer = JsonPointer;
const $pointer = Symbol('pointer');
class JsonReference {
constructor(ptr) {
this.pointer = ptr instanceof JsonPointer ? ptr : new JsonPointer(ptr);
this.$ref = this.pointer.uriFragmentIdentifier;
constructor(pointer) {
this[$pointer] = pointer instanceof JsonPointer ? pointer : new JsonPointer(pointer);
this.$ref = this[$pointer].uriFragmentIdentifier;
}

@@ -274,4 +185,5 @@ static isReference(candidate) {

resolve(target) {
return this.pointer.get(target);
return this[$pointer].get(target);
}
pointer() { return this[$pointer]; }
toString() {

@@ -278,0 +190,0 @@ return this.$ref;

@@ -1,2 +0,2 @@

export declare type PathSegment = string;
export declare type PathSegment = string | number;
export declare type PathSegments = readonly PathSegment[];

@@ -6,26 +6,8 @@ export declare type JsonStringPointer = string;

export declare type Pointer = JsonStringPointer | UriFragmentIdentifierPointer;
/**
* List item used when listing pointers and their values in an object graph.
*/
export interface JsonStringPointerListItem {
/**
* Contains the location of the value in the evaluated object graph.
*/
readonly pointer: JsonStringPointer;
/**
* The value at the pointer's location in the object graph.
*/
readonly value: unknown;
}
/**
* List item used when listing fragment identifiers and their values in an object graph.
*/
export interface UriFragmentIdentifierPointerListItem {
/**
* Contains the location (as a fragmentId) of the value in the evaluated object graph.
*/
readonly fragmentId: UriFragmentIdentifierPointer;
/**
* The value at the pointer's location in the object graph.
*/
readonly value: unknown;

@@ -32,0 +14,0 @@ }

@@ -1,2 +0,2 @@

import { JsonStringPointer, UriFragmentIdentifierPointer, Pointer, PathSegments, Decoder } from './types';
import { JsonStringPointer, UriFragmentIdentifierPointer, Pointer, PathSegment, PathSegments, Decoder } from './types';
export declare function replace(source: string, find: string, repl: string): string;

@@ -11,10 +11,9 @@ export declare function decodeFragmentSegments(segments: PathSegments): PathSegments;

export declare function encodeUriFragmentIdentifier(path: PathSegments): UriFragmentIdentifierPointer;
export declare function toArrayIndexReference(arr: readonly unknown[], idx: string): number;
export declare function hasValueAtPath(target: unknown, path: PathSegments): boolean;
export declare function getValueAtPath(target: unknown, path: PathSegments): unknown;
export declare function toArrayIndexReference(arr: readonly unknown[], idx: PathSegment): number;
export declare type Dereference = (it: unknown) => unknown;
export declare function compilePointerDereference(path: PathSegments): Dereference;
export declare function setValueAtPath(target: unknown, val: unknown, path: PathSegments, force?: boolean): unknown;
export declare function unsetValueAtPath(target: unknown, path: PathSegments): unknown;
export declare function looksLikeFragment(ptr: Pointer): boolean;
export declare function pickDecoder(ptr: Pointer): Decoder;
export declare function decodePtrInit(ptr: Pointer | PathSegments): PathSegments;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodePtrInit = exports.pickDecoder = exports.looksLikeFragment = exports.unsetValueAtPath = exports.setValueAtPath = exports.compilePointerDereference = exports.toArrayIndexReference = exports.encodeUriFragmentIdentifier = exports.decodeUriFragmentIdentifier = exports.encodePointer = exports.decodePointer = exports.encodePointerSegments = exports.decodePointerSegments = exports.encodeFragmentSegments = exports.decodeFragmentSegments = exports.replace = void 0;
function replace(source, find, repl) {

@@ -24,3 +25,8 @@ let res = '';

while (++i < len) {
res[i] = replace(replace(decodeURIComponent('' + segments[i]), '~1', '/'), '~0', '~');
if (typeof segments[i] === 'string') {
res[i] = replace(replace(decodeURIComponent(segments[i]), '~1', '/'), '~0', '~');
}
else {
res[i] = segments[i];
}
}

@@ -50,3 +56,8 @@ return res;

while (++i < len) {
res[i] = replace(replace(segments[i], '~1', '/'), '~0', '~');
if (typeof segments[i] === 'string') {
res[i] = replace(replace(segments[i], '~1', '/'), '~0', '~');
}
else {
res[i] = segments[i];
}
}

@@ -85,3 +96,3 @@ return res;

function encodePointer(path) {
if (path && !Array.isArray(path)) {
if (!path || (path && !Array.isArray(path))) {
throw new TypeError('Invalid type: path must be an array of segments.');

@@ -112,3 +123,3 @@ }

function encodeUriFragmentIdentifier(path) {
if (path && !Array.isArray(path)) {
if (!path || (path && !Array.isArray(path))) {
throw new TypeError('Invalid type: path must be an array of segments.');

@@ -123,3 +134,7 @@ }

function toArrayIndexReference(arr, idx) {
if (typeof idx === 'number')
return idx;
const len = idx.length;
if (!len)
return -1;
let cursor = 0;

@@ -132,5 +147,2 @@ if (len === 1 && idx[0] === '-') {

}
if (len === 0 || (len > 1 && idx[0] === '0') || !isFinite(Number(idx))) {
return -1;
}
while (++cursor < len) {

@@ -144,80 +156,2 @@ if (idx[cursor] < '0' || idx[cursor] > '9') {

exports.toArrayIndexReference = toArrayIndexReference;
function hasValueAtPath(target, path) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let it;
let len;
let cursor;
let step;
let p;
if (typeof target !== 'undefined') {
it = target;
len = path.length;
cursor = -1;
if (len) {
while (++cursor < len && it) {
step = path[cursor];
if (Array.isArray(it)) {
const n = Number(step);
if (isNaN(n) || !isFinite(n)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
it = it[step];
continue;
}
p = toArrayIndexReference(it, step);
if (it.length > p) {
it = it[p];
}
else {
break;
}
}
else {
it = it[step];
}
}
}
return cursor === len && typeof it !== 'undefined';
}
return false;
}
exports.hasValueAtPath = hasValueAtPath;
function getValueAtPath(target, path) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let it;
let len;
let cursor;
let step;
let p;
if (typeof target !== 'undefined') {
it = target;
len = path.length;
cursor = -1;
if (len) {
while (++cursor < len && it) {
step = path[cursor];
if (Array.isArray(it)) {
const n = Number(step);
if (isNaN(n) || !isFinite(n)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
it = it[step];
continue;
}
p = toArrayIndexReference(it, step);
if (it.length > p) {
it = it[p];
}
else {
return undefined;
}
}
else {
it = it[step];
}
}
}
return it;
}
return undefined;
}
exports.getValueAtPath = getValueAtPath;
function compilePointerDereference(path) {

@@ -229,6 +163,5 @@ let body = "if (typeof(it) !== 'undefined'";

body = path.reduce((body, _, i) => {
return body + " && \n\ttypeof((it = it['" + replace(path[i], '\\', '\\\\') + "'])) !== 'undefined'";
return body + " && \n\ttypeof((it = it['" + replace(path[i] + '', '\\', '\\\\') + "'])) !== 'undefined'";
}, "if (typeof(it) !== 'undefined'");
body = body + ') {\n\treturn it;\n }';
// eslint-disable-next-line no-new-func
return new Function('it', body);

@@ -244,3 +177,2 @@ }

}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let it = target;

@@ -253,54 +185,97 @@ const len = path.length;

let p;
if (len) {
while (++cursor < len) {
step = path[cursor];
if (Array.isArray(it)) {
p = toArrayIndexReference(it, step);
if (it.length > p) {
if (cursor === end) {
rem = it[p];
it[p] = val;
return rem;
}
it = it[p];
while (++cursor < len) {
step = path[cursor];
if (Array.isArray(it)) {
if (step === '-' && cursor === end) {
it.push(val);
return undefined;
}
p = toArrayIndexReference(it, step);
if (it.length > p) {
if (cursor === end) {
rem = it[p];
it[p] = val;
break;
}
else if (it.length === p) {
it = it[p];
}
else if (cursor === end && p === it.length) {
if (force) {
it.push(val);
return undefined;
}
}
else if (force) {
it = it[p] = cursor === end ? val : {};
}
}
else {
if (typeof it[step] === 'undefined') {
if (force) {
if (cursor === end) {
it.push(val);
it[step] = val;
return undefined;
}
else if (force) {
it = it[p] = {};
}
}
}
else {
if (typeof it[step] === 'undefined') {
if (force) {
if (cursor === end) {
it[step] = val;
return undefined;
}
// if the next step is an array index, this step should be an array.
if (toArrayIndexReference(it[step], path[cursor + 1]) !== -1) {
it = it[step] = [];
continue;
}
it = it[step] = {};
if (toArrayIndexReference(it[step], path[cursor + 1]) !== -1) {
it = it[step] = [];
continue;
}
return undefined;
it = it[step] = {};
continue;
}
if (cursor === end) {
rem = it[step];
it[step] = val;
return rem;
}
it = it[step];
return undefined;
}
if (cursor === end) {
rem = it[step];
it[step] = val;
break;
}
it = it[step];
}
}
return it;
return rem;
}
exports.setValueAtPath = setValueAtPath;
function unsetValueAtPath(target, path) {
if (path.length === 0) {
throw new Error('Cannot unset the root object; assign it directly.');
}
if (typeof target === 'undefined') {
throw new TypeError('Cannot unset values on undefined');
}
let it = target;
const len = path.length;
const end = path.length - 1;
let step;
let cursor = -1;
let rem;
let p;
while (++cursor < len) {
step = path[cursor];
if (Array.isArray(it)) {
p = toArrayIndexReference(it, step);
if (p >= it.length)
return undefined;
if (cursor === end) {
rem = it[p];
delete it[p];
break;
}
it = it[p];
}
else {
if (typeof it[step] === 'undefined') {
return undefined;
}
if (cursor === end) {
rem = it[step];
delete it[step];
break;
}
it = it[step];
}
}
return rem;
}
exports.unsetValueAtPath = unsetValueAtPath;
function looksLikeFragment(ptr) {

@@ -307,0 +282,0 @@ return (ptr === null || ptr === void 0 ? void 0 : ptr.length) > 0 && ptr[0] === '#';

{
"name": "json-ptr",
"version": "1.2.1-ts.c739a2e.0",
"version": "1.2.1-ts.d9366c0",
"author": "Phillip Clark <phillip@flitbit.com>",

@@ -14,2 +14,6 @@ "description": "A complete implementation of JSON Pointer (RFC 6901) for nodejs and modern browsers.",

"types": "dist/index.d.ts",
"files": [
"dist",
"dist.browser"
],
"license": "MIT",

@@ -21,10 +25,18 @@ "repository": {

"scripts": {
"build": "tsc --build tsconfig.json",
"clean": "rimraf dist .nyc_output coverage",
"lint": "eslint src --ext .js,.ts,.json",
"preversion": "npm run build",
"clean": "rimraf coverage dist dist.browser tmp docs",
"prebuild": "npm run lint",
"pretest": "npm run build",
"test": "nyc mocha src/**/*.spec.ts",
"ci": "npm run test",
"build:browser": "webpack",
"build:browser-tests": "webpack --config webpack.tests.config.js",
"buildall": "tsc -p tsconfig.release.json && npm run build:browser && npm run build:browser-tests && npm run docs",
"build": "npm run buildall",
"build:watch": "tsc -w -p tsconfig.release.json",
"lint": "eslint . --ext .ts,.tsx",
"pretest": "npm run lint",
"test": "nyc mocha __tests__/**/*.spec.ts",
"test:watch": "chokidar \"*.js\" \"*.json\" \"src/**/*.ts\" \"__tests__/**/*.ts\" --command \"npm run test\" --initial",
"cilint": "eslint . --ext .ts,.tsx --format junit --output-file ./reports/eslint/eslint.xml",
"precibuild": "npm run cilint",
"cibuild": "npm run buildall",
"preci": "npm run cibuild",
"ci": "nyc mocha __tests__/**/*.spec.ts --timeout=10000 --exit --reporter mocha-junit-reporter --reporter-options mochaFile=reports/mocha/test-results.xml",
"docs": "typedoc"

@@ -34,24 +46,26 @@ },

"@types/assert-plus": "^1.0.4",
"@types/bent": "^7.0.1",
"@types/bent": "^7.0.2",
"@types/chai": "^4.2.11",
"@types/debug": "^4.1.5",
"@types/mocha": "^7.0.2",
"@typescript-eslint/eslint-plugin": "^2.25.0",
"@typescript-eslint/parser": "^2.25.0",
"bent": "^7.1.2",
"@types/node": "~14.0.19",
"@typescript-eslint/eslint-plugin": "~3.6.0",
"@typescript-eslint/parser": "~3.6.0",
"bent": "^7.3.7",
"chai": "^4.2.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-json": "^2.1.1",
"eslint-plugin-mocha": "^6.3.0",
"eslint-plugin-prettier": "^3.1.2",
"lodash": "^4.17.15",
"mocha": "^7.1.1",
"nyc": "^15.0.0",
"prettier": "^2.0.2",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.16",
"ts-node": "^8.8.1",
"typedoc": "^0.17.3",
"typescript": "^3.8.3"
"chokidar-cli": "^2.1.0",
"eslint": "^7.4.0",
"eslint-config-prettier": "~6.11.0",
"eslint-plugin-mocha": "^7.0.1",
"mocha": "^8.0.1",
"mocha-junit-reporter": "^2.0.0",
"nyc": "^15.1.0",
"prettier": "~2.0.5",
"rimraf": "~3.0.2",
"ts-loader": "^7.0.5",
"ts-node": "^8.10.2",
"typedoc": "^0.17.8",
"typescript": "~3.9.6",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12"
},

@@ -58,0 +72,0 @@ "nyc": {

@@ -9,3 +9,3 @@ # json-ptr

I wrote this module a couple of years ago when I was unable to find what I considered a _complete implementation_ of [RFC 6901](https://tools.ietf.org/html/rfc6901). It turns out that I now use the hell out of it.
I wrote this a few years back when I was unable to find a _complete implementation_ of [RFC 6901](https://tools.ietf.org/html/rfc6901). It turns out that I now use the hell out of it.

@@ -28,439 +28,110 @@ Since there are a few npm modules for you to choose from, see [the section on performance later in this _readme_](#user-content-performance); you can use your own judgement as to which package you should employ.

### Module API
### Example
#### Classes
There are many uses for JSON Pointers, here's one we encountered when we updated a public API and suddenly had clients sending two different message bodies to our APIs. This example is contrived to illustrate how we supported both new and old incoming messages:
* [`JsonPointer`](#user-content-jsonpointer-class) : _class_ &ndash; a convenience class for working with JSON pointers.
* [`JsonReference`](#user-content-jsonreference-class) : _class_ &ndash; a convenience class for working with JSON references.
#### Functions
* [`.create(pointer)`](#user-content-createpointer)
* [`.has(target,pointer)`](#user-content-hastargetpointer)
* [`.get(target,pointer)`](#user-content-gettargetpointer)
* [`.set(target,pointer,value,force)`](#user-content-settarget-pointer-value-force)
* [`.flatten(target,fragmentId)`](#user-content-flattentarget-fragmentid)
* [`.list(target,fragmentId)`](#user-content-listtarget-fragmentid)
* [`.map(target,fragmentId)`](#user-content-maptarget-fragmentid)
All example code assumes data has this structure:
```javascript
const data = {
legumes: [{
name: 'pinto beans',
unit: 'lbs',
instock: 4
}, {
name: 'lima beans',
unit: 'lbs',
instock: 21
}, {
name: 'black eyed peas',
unit: 'lbs',
instock: 13
}, {
name: 'plit peas',
unit: 'lbs',
instock: 8
}]
}
```
#### .create(pointer: string | string[]): JsonPointer
Creates an instance of the `JsonPointer` class.
_arguments:_
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5) or [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6)
_returns:_
* a new [`JsonPointer` instance](#user-content-jsonpointer-class)
_example:_
```ts
const pointer = JsonPointer.create('/legumes/0');
// fragmentId: #/legumes/0
```
// examples/versions.ts
import { JsonPointer } from 'json-ptr';
#### .has&lt;T>(target: T, pointer: string | string[] | JsonPointer): boolean
export type SupportedVersion = '1.0' | '1.1';
Determins whether the specified `target` has a value at the `pointer`'s path.
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5) or [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6)
_returns:_
* the dereferenced value or _undefined_ if nonexistent
#### .get(target,pointer)
Gets a value from the specified `target` object at the `pointer`'s path
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5) or [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6)
_returns:_
* the dereferenced value or _undefined_ if nonexistent
_example:_
```javascript
let value = JsonPointer.get(data, '/legumes/1');
// fragmentId: #/legumes/1
```
#### .set(target, pointer, value, force)
Sets the `value` at the specified `pointer` on the `target`. The default behavior is to do nothing if `pointer` is nonexistent.
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5) or [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6)
* `value` : _any_ &ndash; the value to be set at the specified `pointer`'s path
* `force` : _boolean, optional_ &ndash; indicates [whether nonexistent paths are created during the call](https://tools.ietf.org/html/rfc6901#section-7)
_returns:_
* The prior value at the pointer's path &mdash; therefore, _undefined_ means the pointer's path was nonexistent.
_example:_
```javascript
let prior = JsonPointer.set(data, '#/legumes/1/instock', 50);
```
example force:
```javascript
let data = {};
JsonPointer.set(data, '#/peter/piper', 'man', true);
JsonPointer.set(data, '#/peter/pan', 'boy', true);
JsonPointer.set(data, '#/peter/pickle', 'dunno', true);
console.log(JSON.stringify(data, null, ' '));
```
```json
{
"peter": {
"piper": "man",
"pan": "boy",
"pickle": "dunno"
}
interface PrimaryGuestNamePointers {
name: JsonPointer;
surname: JsonPointer;
honorific: JsonPointer;
}
```
#### .list(target, fragmentId)
Lists all of the pointers available on the specified `target`.
> See [a discussion about cycles in the object graph later in this document](#user-content-object-graph-cycles-and-recursion) if you have interest in how such is dealt with.
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `fragmentId` : _boolean, optional_ &ndash; indicates whether fragment identifiers should be listed instead of pointers
_returns:_
* an array of `pointer-value` pairs
_example:_
```javascript
let list = JsonPointer.list(data);
```
```json
[ ...
{
"pointer": "/legumes/2/unit",
"value": "ea"
const versions: Record<SupportedVersion, PrimaryGuestNamePointers> = {
'1.0': {
name: JsonPointer.create('/guests/0/name'),
surname: JsonPointer.create('/guests/0/surname'),
honorific: JsonPointer.create('/guests/0/honorific'),
},
{
"pointer": "/legumes/2/instock",
"value": 9340
},
{
"pointer": "/legumes/3/name",
"value": "plit peas"
},
{
"pointer": "/legumes/3/unit",
"value": "lbs"
},
{
"pointer": "/legumes/3/instock",
"value": 8
'1.1': {
name: JsonPointer.create('/primary/primaryGuest/name'),
surname: JsonPointer.create('/primary/primaryGuest/surname'),
honorific: JsonPointer.create('/primary/primaryGuest/honorific'),
}
]
```
};
_`fragmentId` example:_
interface Reservation extends Record<string, unknown> {
version?: SupportedVersion;
}
```javascript
let list = JsonPointer.list(data, true);
```
```json
[ ...
{
"fragmentId": "#/legumes/2/unit",
"value": "ea"
},
{
"fragmentId": "#/legumes/2/instock",
"value": 9340
},
{
"fragmentId": "#/legumes/3/name",
"value": "plit peas"
},
{
"fragmentId": "#/legumes/3/unit",
"value": "lbs"
},
{
"fragmentId": "#/legumes/3/instock",
"value": 8
/**
* Gets the primary guest's name from the specified reservation.
* @param reservation a reservation, either version 1.0 or bearing a `version`
* property indicating the version.
*/
function primaryGuestName(reservation: Reservation): string {
const pointers = versions[reservation.version || '1.0'];
if (!pointers) {
throw new Error(`Unsupported reservation version: ${reservation.version}`);
}
]
```
#### .flatten(target, fragmentId)
Flattens an object graph (the `target`) into a single-level object of `pointer-value` pairs.
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `fragmentId` : _boolean, optional_ &ndash; indicates whether fragment identifiers should be listed instead of pointers
_returns:_
* a flattened object of `property-value` pairs as properties.
_example:_
```javascript
let obj = JsonPointer.flatten(data, true);
```
```json
{ ...
"#/legumes/1/name": "lima beans",
"#/legumes/1/unit": "lbs",
"#/legumes/1/instock": 21,
"#/legumes/2/name": "black eyed peas",
"#/legumes/2/unit": "ea",
"#/legumes/2/instock": 9340,
"#/legumes/3/name": "plit peas",
"#/legumes/3/unit": "lbs",
"#/legumes/3/instock": 8
const name = pointers.name.get(reservation) as string;
const surname = pointers.surname.get(reservation) as string;
const honorific = pointers.honorific.get(reservation) as string;
const names: string[] = [];
if (honorific) names.push(honorific);
if (name) names.push(name);
if (surname) names.push(surname);
return names.join(' ');
}
```
#### .map(target, fragmentId)
// The original layout of a reservation (only the parts relevant to our example)
const reservationV1: Reservation = {
guests: [{
name: 'Wilbur',
surname: 'Finkle',
honorific: 'Mr.'
}, {
name: 'Wanda',
surname: 'Finkle',
honorific: 'Mrs.'
}, {
name: 'Wilma',
surname: 'Finkle',
honorific: 'Miss',
child: true,
age: 12
}]
// ...
};
Flattens an object graph (the `target`) into a [Map object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).
// The new layout of a reservation (only the parts relevant to our example)
const reservationV1_1: Reservation = {
version: '1.1',
primary: {
primaryGuest: {
name: 'Wilbur',
surname: 'Finkle',
honorific: 'Mr.'
},
additionalGuests: [{
name: 'Wanda',
surname: 'Finkle',
honorific: 'Mrs.'
}, {
name: 'Wilma',
surname: 'Finkle',
honorific: 'Miss',
child: true,
age: 12
}]
// ...
}
// ...
};
_arguments:_
console.log(primaryGuestName(reservationV1));
console.log(primaryGuestName(reservationV1_1));
* `target` : _object, required_ &ndash; the target object
* `fragmentId` : _boolean, optional_ &ndash; indicates whether fragment identifiers should be listed instead of pointers
_returns:_
* a Map object containing key-value pairs where keys are pointers.
_example:_
```javascript
let map = JsonPointer.map(data, true);
for (let it of map) {
console.log(JSON.stringify(it, null, ' '));
}
```
```json
...
["#/legumes/0/name", "pinto beans"]
["#/legumes/0/unit", "lbs"]
["#/legumes/0/instock", 4 ]
["#/legumes/1/name", "lima beans"]
["#/legumes/1/unit", "lbs"]
["#/legumes/1/instock", 21 ]
["#/legumes/2/name", "black eyed peas"]
["#/legumes/2/unit", "ea"]
["#/legumes/2/instock", 9340 ]
["#/legumes/3/name", "plit peas"]
["#/legumes/3/unit", "lbs"]
["#/legumes/3/instock", 8 ]
```
## API Documentation
#### .decode(pointer)
The API documentation is generated from code comments by typedoc and [hosted here](<>).
Decodes the specified `pointer`.
We welcome new issues if you have questions or need additional documentation.
_arguments:_
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5) or [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6).
_returns:_
* An array of path segments used as indexers to descend from a root/`target` object to a referenced value.
_example:_
```javascript
let path = JsonPointer.decode('#/legumes/1/instock');
```
```json
[ "legumes", "1", "instock" ]
```
#### decodePointer(pointer)
Decodes the specified `pointer`.
_arguments:_
* `pointer` : _string, required_ &ndash; a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5).
_returns:_
* An array of path segments used as indexers to descend from a root/`target` object to a referenced value.
_example:_
```javascript
let path = decodePointer('/people/wilbur dongleworth/age');
```
```json
[ "people", "wilbur dongleworth", "age" ]
```
#### encodePointer(path)
Encodes the specified `path` as a JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5).
_arguments:_
* `path` : _Array, required_ &ndash; an array of path segments
_returns:_
* A JSON pointer in [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5).
_example:_
```javascript
let path = encodePointer(['people', 'wilbur dongleworth', 'age']);
```
```json
"/people/wilbur dongleworth/age"
```
#### decodeUriFragmentIdentifier(pointer)
Decodes the specified `pointer`.
_arguments:_
* `pointer` : _string, required_ &ndash; a JSON pointer in [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6).
_returns:_
* An array of path segments used as indexers to descend from a root/`target` object to a referenced value.
_example:_
```javascript
let path = decodePointer('#/people/wilbur%20dongleworth/age');
```
```json
[ "people", "wilbur dongleworth", "age" ]
```
#### encodeUriFragmentIdentifier(path)
Encodes the specified `path` as a JSON pointer in [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6).
_arguments:_
* `path` : _Array, required_ - an array of path segments
_returns:_
* A JSON pointer in [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6).
_example:_
```javascript
let path = ptr.encodePointer(['people', 'wilbur dongleworth', 'age']);
```
```json
"#/people/wilbur%20dongleworth/age"
```
### `JsonPointer` Class
Encapsulates pointer related operations for a specified `pointer`.
_properties:_
* `.path` : _array_ &ndash; contains the pointer's path segements.
* `.pointer` : _string_ &ndash; the pointer's [JSON string representation](https://tools.ietf.org/html/rfc6901#section-5)
* `.uriFragmentIdentifier` : _string_ &ndash; the pointer's [URI fragment identifier representation](https://tools.ietf.org/html/rfc6901#section-6)
_methods:_
#### .has(target)
Determins whether the specified `target` has a value at the pointer's path.
#### .get(target)
Looks up the specified `target`'s value at the pointer's path if such exists; otherwise _undefined_.
#### .set(target, value, force)
Sets the specified `target`'s value at the pointer's path, if such exists.If `force` is specified (_truthy_), missing path segments are created and the value is always set at the pointer's path.
_arguments:_
* `target` : _object, required_ &ndash; the target object
* `value` : _any_ &ndash; the value to be set at the specified `pointer`'s path
* `force` : _boolean, optional_ &ndash; indicates [whether nonexistent paths are created during the call](https://tools.ietf.org/html/rfc6901#section-7)
_result:_
* The prior value at the pointer's path &mdash; therefore, _undefined_ means the pointer's path was nonexistent.
#### .concat(target)
Creates new pointer appending target to the current pointer's path
_arguments:_
* `target` : _JsonPointer, array or string, required_ &ndash; the path to be appended to the current path
## Performance

@@ -588,24 +259,24 @@

* 2019-09-14 &mdash; __1.2.0__
* Merged new `.concat` function contributed by @vuwuv, updated dependencies.
- 2019-09-14 — **1.2.0**
- Merged new `.concat` function contributed by @vuwuv, updated dependencies.
* 2019-03-10 &mdash; __1.1.2__
* Updated packages to remove critical security concern among dev dependencies'
- 2019-03-10 — **1.1.2**
- Updated packages to remove critical security concern among dev dependencies'
* 2016-07-26 &mdash; __1.0.1__
* Fixed a problem with the Babel configuration
- 2016-07-26 — **1.0.1**
- Fixed a problem with the Babel configuration
* 2016-01-12 &mdash; __1.0.0__
* Rolled major version to 1 to reflect breaking change in `.list(obj, fragmentId)`.
- 2016-01-12 — **1.0.0**
- Rolled major version to 1 to reflect breaking change in `.list(obj, fragmentId)`.
* 2016-01-02 &mdash; __0.3.0__
* Retooled for node 4+
* Better compiled pointers
* Unrolled recursive `.list` function
* Added `.map` function
* Fully linted
* Lots more tests and examples.
* Documented many previously undocumented features.
- 2016-01-02 — **0.3.0**
- Retooled for node 4+
- Better compiled pointers
- Unrolled recursive `.list` function
- Added `.map` function
- Fully linted
- Lots more tests and examples.
- Documented many previously undocumented features.
* 2014-10-21 &mdash; __0.2.0__ Added #list function to enumerate all properties in a graph, producing fragmentId/value pairs.
- 2014-10-21 — **0.2.0** Added #list function to enumerate all properties in a graph, producing fragmentId/value pairs.

@@ -612,0 +283,0 @@ ## License

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc