Skip to content

Commit

Permalink
semantic change; docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Phillip Clark committed May 14, 2021
1 parent 3103314 commit f48c5e7
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 34 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ npm install json-ptr
### [nodejs](https://nodejs.org/en/)

```javascript
import { JsonPointer, create } from 'json-ptr';
import { JsonPointer } from 'json-ptr';
```

## API Documentation
Expand Down Expand Up @@ -239,6 +239,8 @@ It is important to recognize in the performance results that _compiled_ options

## Releases

- 2021-05-14 — **2.2.0** _Added Handling for Relative JSON Pointers_
- [Example usage](https://github.com/flitbit/json-ptr/blob/master/examples/relative.ts)
- 2021-05-12 — **2.1.1** _Bug fix for [#36](https://github.com/flitbit/json-ptr/issues/36)_
- @CarolynWebster reported an unintentional behavior change starting at v1.3.0. An operation involving a pointer/path that crossed a null value in the object graph resulted in an exception. In versions prior to v1.3.0 it returned `undefined` as intended. The original behavior has been restored.
- 2021-05-12 — **2.1.0** _Bug fixes for [#28](https://github.com/flitbit/json-ptr/issues/28) and [#30](https://github.com/flitbit/json-ptr/issues/30); **Security Vulnerability Patched**_
Expand Down
48 changes: 24 additions & 24 deletions __tests__/pointer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,47 +487,47 @@ describe('JsonPointer', () => {

it('throws when relative pointer unspecified', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.relative(doc, undefined)).to.throw(
expect(() => p.rel(doc, undefined)).to.throw(
'Invalid type: Relative JSON Pointers are represented as strings.',
);
});
it('throws when relative pointer empty', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.relative(doc, '')).to.throw(
expect(() => p.rel(doc, '')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('throws when relative pointer invalid [0](NaN)', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.relative(doc, 'b/z')).to.throw(
expect(() => p.rel(doc, 'b/z')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('throws when relative pointer invalid 1#/z', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.relative(doc, '1#/z')).to.throw(
expect(() => p.rel(doc, '1#/z')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('Spec examples 1', () => {
const p = new JsonPointer('/foo/1');
expect(p.relative(doc, '0')).to.eql('baz');
expect(p.relative(doc, '1/0')).to.eql('bar');
expect(p.relative(doc, '2/highly/nested/objects')).to.eql(true);
expect(p.relative(doc, '0#')).to.eql(1);
expect(p.relative(doc, '1#')).to.eql('foo');
expect(p.rel(doc, '0')).to.eql('baz');
expect(p.rel(doc, '1/0')).to.eql('bar');
expect(p.rel(doc, '2/highly/nested/objects')).to.eql(true);
expect(p.rel(doc, '0#')).to.eql(1);
expect(p.rel(doc, '1#')).to.eql('foo');
});
it('Spec examples 2', () => {
const p = new JsonPointer('/highly/nested');
expect(p.relative(doc, '0/objects')).to.eql(true);
expect(p.relative(doc, '1/nested/objects')).to.eql(true);
expect(p.relative(doc, '2/foo/0')).to.eql('bar');
expect(p.relative(doc, '0#')).to.eql('nested');
expect(p.relative(doc, '1#')).to.eql('highly');
expect(p.rel(doc, '0/objects')).to.eql(true);
expect(p.rel(doc, '1/nested/objects')).to.eql(true);
expect(p.rel(doc, '2/foo/0')).to.eql('bar');
expect(p.rel(doc, '0#')).to.eql('nested');
expect(p.rel(doc, '1#')).to.eql('highly');
});
it('returns undefined when relative location cannot exist', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(p.relative(doc, '5/not-here')).to.be.undefined;
expect(p.rel(doc, '5/not-here')).to.be.undefined;
});
});

Expand All @@ -543,49 +543,49 @@ describe('JsonPointer', () => {

it('throws when relative pointer unspecified', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel(undefined)).to.throw(
expect(() => p.relative(undefined)).to.throw(
'Invalid type: Relative JSON Pointers are represented as strings.',
);
});
it('throws when relative pointer empty', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel('')).to.throw(
expect(() => p.relative('')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('throws when relative pointer invalid [0](NaN)', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel('b/z')).to.throw(
expect(() => p.relative('b/z')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('throws when relative pointer invalid 1#/z', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel('1#/z')).to.throw(
expect(() => p.relative('1#/z')).to.throw(
'Invalid Relative JSON Pointer syntax. Relative pointer must begin with a non-negative integer, followed by either the number sign (#), or a JSON Pointer.',
);
});
it('throws when relative pointer to name (#)', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel('1#')).to.throw(
"We won't compile a pointer that will always return 'nested'. Use JsonPointer.relative(target, ptr) instead.",
expect(() => p.relative('1#')).to.throw(
"We won't compile a pointer that will always return 'nested'. Use JsonPointer.rel(target, ptr) instead.",
);
});
it('throws when relative location cannot exist', () => {
const p = new JsonPointer('/highly/nested/objects');
expect(() => p.rel('5/not-here')).to.throw(
expect(() => p.relative('5/not-here')).to.throw(
'Relative location does not exist.',
);
});

it('Spec example from 1', () => {
const p = new JsonPointer('/foo/1');
const q = p.rel('2/highly/nested/objects');
const q = p.relative('2/highly/nested/objects');
expect(q.get(doc)).to.eql(true);
});
it('Spec example from 2', () => {
const p = new JsonPointer('/highly/nested');
const q = p.rel('2/foo/0');
const q = p.relative('2/foo/0');
expect(q.get(doc)).to.eql('bar');
});
});
Expand Down
7 changes: 6 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2738,7 +2738,7 @@ <h2>Use</h2>
<a href="#nodejs" id="nodejs" style="color: inherit; text-decoration: none;">
<h3><a href="https://nodejs.org/en/">nodejs</a></h3>
</a>
<pre><code class="language-javascript"><span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">JsonPointer</span><span style="color: #000000">, </span><span style="color: #001080">create</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">&#039;json-ptr&#039;</span><span style="color: #000000">;</span>
<pre><code class="language-javascript"><span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">JsonPointer</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">&#039;json-ptr&#039;</span><span style="color: #000000">;</span>
</code></pre>
<a href="#api-documentation" id="api-documentation" style="color: inherit; text-decoration: none;">
<h2>API Documentation</h2>
Expand Down Expand Up @@ -2991,6 +2991,11 @@ <h2>Performance</h2>
<h2>Releases</h2>
</a>
<ul>
<li><p>2021-05-14 — <strong>2.2.0</strong> <em>Added Handling for Relative JSON Pointers</em></p>
<ul>
<li><a href="https://github.com/flitbit/json-ptr/blob/master/examples/relative.ts">Example usage</a></li>
</ul>
</li>
<li><p>2021-05-12 — <strong>2.1.1</strong> <em>Bug fix for <a href="https://github.com/flitbit/json-ptr/issues/36">#36</a></em></p>
<ul>
<li>@CarolynWebster reported an unintentional behavior change starting at v1.3.0. An operation involving a pointer/path that crossed a null value in the object graph resulted in an exception. In versions prior to v1.3.0 it returned <code>undefined</code> as intended. The original behavior has been restored.</li>
Expand Down
7 changes: 6 additions & 1 deletion docs/modules.html
Original file line number Diff line number Diff line change
Expand Up @@ -2738,7 +2738,7 @@ <h2>Use</h2>
<a href="#nodejs" id="nodejs" style="color: inherit; text-decoration: none;">
<h3><a href="https://nodejs.org/en/">nodejs</a></h3>
</a>
<pre><code class="language-javascript"><span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">JsonPointer</span><span style="color: #000000">, </span><span style="color: #001080">create</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">&#039;json-ptr&#039;</span><span style="color: #000000">;</span>
<pre><code class="language-javascript"><span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">JsonPointer</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">&#039;json-ptr&#039;</span><span style="color: #000000">;</span>
</code></pre>
<a href="#api-documentation" id="api-documentation" style="color: inherit; text-decoration: none;">
<h2>API Documentation</h2>
Expand Down Expand Up @@ -2991,6 +2991,11 @@ <h2>Performance</h2>
<h2>Releases</h2>
</a>
<ul>
<li><p>2021-05-14 — <strong>2.2.0</strong> <em>Added Handling for Relative JSON Pointers</em></p>
<ul>
<li><a href="https://github.com/flitbit/json-ptr/blob/master/examples/relative.ts">Example usage</a></li>
</ul>
</li>
<li><p>2021-05-12 — <strong>2.1.1</strong> <em>Bug fix for <a href="https://github.com/flitbit/json-ptr/issues/36">#36</a></em></p>
<ul>
<li>@CarolynWebster reported an unintentional behavior change starting at v1.3.0. An operation involving a pointer/path that crossed a null value in the object graph resulted in an exception. In versions prior to v1.3.0 it returned <code>undefined</code> as intended. The original behavior has been restored.</li>
Expand Down
26 changes: 23 additions & 3 deletions examples/relative.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const assert = require('assert');
const { JsonPointer } = require('../dist');

// https://tools.ietf.org/id/draft-handrews-relative-json-pointer-00.html#rfc.section.5.1

const doc = {
foo: ['bar', 'baz'],
highly: {
Expand All @@ -11,6 +13,24 @@ const doc = {
};

const p = new JsonPointer('/foo/1');
assert(p.relative(doc, '0') == 'baz');
assert(p.relative(doc, '1/0') == 'bar');
assert(p.relative(doc, '2/highly/nested/objects') == true);
assert(p.rel(doc, '0') == 'baz');
assert(p.rel(doc, '1/0') == 'bar');
assert(p.rel(doc, '2/highly/nested/objects') == true);
assert(p.rel(doc, '0#') == 1);
assert(p.rel(doc, '1#') == 'foo');

const p2 = new JsonPointer('/highly/nested');
assert(p2.rel(doc, '0/objects') == true);
assert(p2.rel(doc, '1/nested/objects') == true);
assert(p2.rel(doc, '2/foo/0') == 'bar');
assert(p2.rel(doc, '0#') == 'nested');
assert(p2.rel(doc, '1#') == 'highly');

// Pre-compile relative pointers to dramatically improve performance in
// scenarios such as loops or when a piece of code will be frequently using
// the same relative location:
const compiled = p2.relative('1/nested/objects');
// ...once compiled, it is just another pointer...
assert(compiled.get(doc, '1/nested/objects') == true);


8 changes: 4 additions & 4 deletions src/pointer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,11 +549,11 @@ export class JsonPointer {
}

/**
* Creates a new JsonPointer instance to the specified relative location, based on this pointer's location in the object graph.
* Creates a new JsonPointer instance, pointing to the specified relative location in the object graph.
* @param ptr the relative pointer (relative to this)
* @returns A new instance that points to the relative location.
*/
rel(ptr: RelativeJsonPointer): JsonPointer {
relative(ptr: RelativeJsonPointer): JsonPointer {
const p = this.path;
const decoded = decodeRelativePointer(ptr) as string[];
const n = parseInt(decoded[0]);
Expand All @@ -563,7 +563,7 @@ export class JsonPointer {
// It references the path segment/name, not the value
const name = r[r.length - 1] as string;
throw new Error(
`We won't compile a pointer that will always return '${name}'. Use JsonPointer.relative(target, ptr) instead.`,
`We won't compile a pointer that will always return '${name}'. Use JsonPointer.rel(target, ptr) instead.`,
);
}
return new JsonPointer(r);
Expand All @@ -575,7 +575,7 @@ export class JsonPointer {
* @param ptr the relative pointer (relative to this)
* @returns the value at the relative pointer's resolved path; otherwise undefined.
*/
relative(target: unknown, ptr: RelativeJsonPointer): unknown {
rel(target: unknown, ptr: RelativeJsonPointer): unknown {
const p = this.path;
const decoded = decodeRelativePointer(ptr) as string[];
const n = parseInt(decoded[0]);
Expand Down

0 comments on commit f48c5e7

Please sign in to comment.