Skip to content

Commit

Permalink
docs: add JSON Pointer quick start
Browse files Browse the repository at this point in the history
  • Loading branch information
jg-rp committed Sep 18, 2023
1 parent ea7606a commit 30b0ccb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
6 changes: 3 additions & 3 deletions docs/docs/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import TabItem from "@theme/TabItem";

JSON P3 implements JSONPath following the [IETF JSONPath draft](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20) specification, JSON Pointer described by [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901), and JSON Patch described by [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902).

JSONPath is a mini language for selecting values from JSON-like data. A JSONPath query has the potential to return multiple values from a data structure, along with their locations. This implementation is non-evaluating and read-only. We strictly follow the [IETF JSONPath draft](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20).
**JSONPath** is a mini language for selecting values from JSON-like data. A JSONPath query has the potential to return multiple values from a data structure, along with their locations. This implementation is non-evaluating and read-only. We strictly follow the [IETF JSONPath draft](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20).

JSON Pointer is a syntax for targeting a single value in JSON-like data. JSON Pointers can be _resolved_ against data to retrieve the value, or used as part of a JSON Patch operation.
**JSON Pointer** is a syntax for targeting a single value in JSON-like data. JSON Pointers can be _resolved_ against data to retrieve the value, or used as part of a JSON Patch operation.

JSON Patch is a standard for describing update operations to perform on JSON-like data. You can _apply_ a patch to _add_, _remove_, _replace_, _move_, _copy_ and _move_ values within a JSON document.
**JSON Patch** is a standard for describing update operations to perform on JSON-like data. You can _apply_ a patch to _add_, _remove_, _replace_, _copy_ and _move_ values within a JSON document.

We use the term _JSON-like data_ to describe arbitrary, possibly nested, JavaScript arrays and objects, plus primitive strings, numbers, booleans and `null`, as you might expect from `JSON.parse()`. When traversing JSON-like data, we only resolve an object's direct properties, and the `length` property of arrays and strings is ignored.

Expand Down
69 changes: 66 additions & 3 deletions docs/docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,78 @@ console.log(nodes.values()); // [ 'John', 'Sally', 'Jane' ]

## JSON Pointer

TODO:
Resolve a JSON Pointer ([RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)) against some data using `jsonpointer.resolve()`.

```javascript
import { jsonpointer } from "json-p3";

const data = {
users: [
{ name: "Sue", score: 100 },
{ name: "John", score: 86 },
{ name: "Sally", score: 84 },
{ name: "Jane", score: 55 },
],
};

const rv = jsonpointer.resolve("/users/1", data);
console.log(rv); // { name: 'John', score: 86 }
```

`resolve()` is a convenience function equivalent to `new JSONPointer(pointer).resolve(data)`. Use the [`JSONPointer`](./api/classes/jsonpointer.JSONPointer.md) constructor when you need to resolve the same pointer repeatedly against different data.

```javascript
import { JSONPointer } from "json-p3";

const someData = {
users: [
{ name: "Sue", score: 100 },
{ name: "John", score: 86 },
{ name: "Sally", score: 84 },
],
};

const otherData = {
users: [{ name: "Brian" }, { name: "Roy" }],
};

const pointer = new JSONPointer("/users/1");
console.log(pointer.resolve(someData)); // { name: 'John', score: 86 }
console.log(pointer.resolve(otherData)); // { name: 'Roy' }
```

### Errors and fallbacks

TODO:
If the pointer can't be resolved against the argument JSON value, one of [`JSONPointerIndexError`](./api/classes/jsonpointer.JSONPointerIndexError.md), [`JSONPointerKeyError`](./api/classes/jsonpointer.JSONPointerKeyError.md) or [`JSONPointerTypeError`](./api/classes/jsonpointer.JSONPointerTypeError.md) is thrown. All three exceptions inherit from [`JSONPointerResolutionError`](./api/classes/jsonpointer.JSONPointerResolutionError.md).

```javascript
// .. continued from above
const rv = pointer.resolve("/users/1/age", data);
// JSONPointerKeyError: no such property ("/users/1/age")
```

A fallback value can be given as a third argument, which will be returned in the event of a `JSONPointerResolutionError`.

```javascript
// .. continued from above
const rv = pointer.resolve("/users/1/age", data, -1);
console.log(rv); // -1
```

### Relative JSON Pointers

TODO:
We support [Relative JSON Pointers](https://www.ietf.org/id/draft-hha-relative-json-pointer-00.html) via the [`to(rel)`](./api/classes/jsonpointer.JSONPointer.md#to) method of `JSONPointer`, where `rel` is a relative JSON pointer string, and a new `JSONPointer` is returned.

```javascript
import { JSONPointer } from "json-p3";

const data = { foo: { bar: [1, 2, 3], baz: [4, 5, 6] } };
const pointer = new JSONPointer("/foo/bar/2");

console.log(pointer.resolve(data)); // 3
console.log(pointer.to("0-1").resolve(data)); // 2
console.log(pointer.to("2/baz/2").resolve(data)); // 6
```

## JSON Patch

Expand Down
2 changes: 2 additions & 0 deletions src/path/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ export class JSONPathEnvironment {
return this.compile(path).query(value);
}

// TODO: match(path, value): boolean

protected setupFilterFunctions(): void {
this.functionRegister.set("count", new CountFilterFunction());
this.functionRegister.set("length", new LengthFilterFunction());
Expand Down
15 changes: 15 additions & 0 deletions src/pointer/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export class JSONPointerError extends Error {
}
}

/**
* Base class for JSON Pointer resolution errors.
*/
export class JSONPointerResolutionError extends JSONPointerError {
constructor(readonly message: string) {
super(message);
Expand All @@ -17,6 +20,9 @@ export class JSONPointerResolutionError extends JSONPointerError {
}
}

/**
* Error thrown due to an out of range index when resolving a JSON Pointer.
*/
export class JSONPointerIndexError extends JSONPointerResolutionError {
constructor(readonly message: string) {
super(message);
Expand All @@ -25,6 +31,9 @@ export class JSONPointerIndexError extends JSONPointerResolutionError {
}
}

/**
* Error thrown due to a missing property when resolving a JSON Pointer.
*/
export class JSONPointerKeyError extends JSONPointerResolutionError {
constructor(readonly message: string) {
super(message);
Expand All @@ -33,6 +42,9 @@ export class JSONPointerKeyError extends JSONPointerResolutionError {
}
}

/**
* Error thrown due to invalid JSON Pointer syntax.
*/
export class JSONPointerSyntaxError extends JSONPointerError {
constructor(readonly message: string) {
super(message);
Expand All @@ -41,6 +53,9 @@ export class JSONPointerSyntaxError extends JSONPointerError {
}
}

/**
* Error thrown when trying to resolve a property or index against a primitive value.
*/
export class JSONPointerTypeError extends JSONPointerResolutionError {
constructor(readonly message: string) {
super(message);
Expand Down

0 comments on commit 30b0ccb

Please sign in to comment.