MCPcopy
hub / github.com/Starcounter-Jack/JSON-Patch

github.com/Starcounter-Jack/JSON-Patch @3.1.1 sqlite

repository ↗ · DeepWiki ↗ · release 3.1.1 ↗
172 symbols 336 edges 34 files 14 documented · 8%
README

JSON-Patch

A leaner and meaner implementation of JSON-Patch. Small footprint. High performance.

Build Status

With JSON-Patch, you can: - apply patches (arrays) and single operations on JS object - validate a sequence of patches - observe for changes and generate patches when a change is detected - compare two objects to obtain the difference

Tested in Firefox, Chrome, Edge, Safari, IE11, Deno and Node.js

Why you should use JSON-Patch

JSON-Patch (RFC6902) is a standard format that allows you to update a JSON document by sending the changes rather than the whole document. JSON Patch plays well with the HTTP PATCH verb (method) and REST style programming.

Mark Nottingham has a nice blog about it.

Install

Download as ZIP or install the current version using a package manager (and save it as a dependency):

# NPM
npm install fast-json-patch --save

Adding to your project

In a web browser

Load the bundled distribution script:

<script src="https://github.com/Starcounter-Jack/JSON-Patch/raw/3.1.1/dist/fast-json-patch.min.js"></script>

In browsers that support ECMAScript modules, the below code uses this library as a module:

<script type="module">
  import * as jsonpatch from 'fast-json-patch/index.mjs';
  import { applyOperation } from 'fast-json-patch/index.mjs';
</script>

In Node.js

In Node 12+ with --experimental-modules flag, the below code uses this library as an ECMAScript module:

import * as jsonpatch from 'fast-json-patch/index.mjs';
import { applyOperation } from 'fast-json-patch/index.mjs';

In Webpack (and most surely other bundlers based on Babel), the below code uses this library as an ECMAScript module:

import * as jsonpatch from 'fast-json-patch';
import { applyOperation } from 'fast-json-patch';

In standard Node, the below code uses this library as a CommonJS module:

const { applyOperation } = require('fast-json-patch');
const applyOperation = require('fast-json-patch').applyOperation;

Directories

Directories used in this package:

  • dist/ - contains ES5 files for a Web browser
  • commonjs/ - contains CommonJS module and typings
  • module/ - contains ECMAScript module and typings
  • src/ - contains TypeScript source files

API

function applyPatch<T>(document: T, patch: Operation[], validateOperation?: boolean | Validator<T>, mutateDocument: boolean = true, banPrototypeModifications: boolean = true): PatchResult<T>

Applies patch array on obj.

  • document The document to patch
  • patch a JSON-Patch array of operations to apply
  • validateOperation Boolean for whether to validate each operation with our default validator, or to pass a validator callback
  • mutateDocument Whether to mutate the original document or clone it before applying
  • banPrototypeModifications Whether to ban modifications to __proto__, defaults to true.

An invalid patch results in throwing an error (see jsonpatch.validate for more information about the error object).

It modifies the document object and patch - it gets the values by reference. If you would like to avoid touching your patch array values, clone them: jsonpatch.applyPatch(document, jsonpatch.deepClone(patch)).

Returns an array of OperationResult objects - one item for each item in patches, each item is an object {newDocument: any, test?: boolean, removed?: any}.

  • test - boolean result of the test
  • remove, replace and move - original object that has been removed
  • add (only when adding to an array) - index at which item has been inserted (useful when using - alias)

  • ** Note: It throws TEST_OPERATION_FAILED error if test operation fails. **

  • ** Note II: the returned array has newDocument property that you can use as the final state of the patched document **.
  • ** Note III: By default, when banPrototypeModifications is true, this method throws a TypeError when you attempt to modify an object's prototype.

  • See Validation notes.

Example:

var document = { firstName: "Albert", contactDetails: { phoneNumbers: [] } };
var patch = [
  { op: "replace", path: "/firstName", value: "Joachim" },
  { op: "add", path: "/lastName", value: "Wester" },
  { op: "add", path: "/contactDetails/phoneNumbers/0", value: { number: "555-123" }  }
];
document = jsonpatch.applyPatch(document, patch).newDocument;
// document == { firstName: "Joachim", lastName: "Wester", contactDetails: { phoneNumbers: [{number:"555-123"}] } };

function applyOperation<T>(document: T, operation: Operation, validateOperation: boolean | Validator<T> = false, mutateDocument: boolean = true, banPrototypeModifications: boolean = true, index: number = 0): OperationResult<T>

Applies single operation object operation on document.

  • document The document to patch
  • operation The operation to apply
  • validateOperation Whether to validate the operation, or to pass a validator callback
  • mutateDocument Whether to mutate the original document or clone it before applying
  • banPrototypeModifications Whether to ban modifications to __proto__, defaults to true.
  • index The index of the operation in your patch array. Useful for better error reporting when that operation fails to apply.

It modifies the document object and operation - it gets the values by reference. If you would like to avoid touching your values, clone them: jsonpatch.applyOperation(document, jsonpatch.deepClone(operation)).

Returns an OperationResult object {newDocument: any, test?: boolean, removed?: any}.

  • ** Note: It throws TEST_OPERATION_FAILED error if test operation fails. **
  • ** Note II: By default, when banPrototypeModifications is true, this method throws a TypeError when you attempt to modify an object's prototype.

  • See Validation notes.

Example:

var document = { firstName: "Albert", contactDetails: { phoneNumbers: [] } };
var operation = { op: "replace", path: "/firstName", value: "Joachim" };
document = jsonpatch.applyOperation(document, operation).newDocument;
// document == { firstName: "Joachim", contactDetails: { phoneNumbers: [] }}

jsonpatch.applyReducer<T>(document: T, operation: Operation, index: number): T

Ideal for patch.reduce(jsonpatch.applyReducer, document).

Applies single operation object operation on document.

Returns the a modified document.

Note: It throws TEST_OPERATION_FAILED error if test operation fails.

Example:

var document = { firstName: "Albert", contactDetails: { phoneNumbers: [ ] } };
var patch = [
  { op:"replace", path: "/firstName", value: "Joachim" },
  { op:"add", path: "/lastName", value: "Wester" },
  { op:"add", path: "/contactDetails/phoneNumbers/0", value: { number: "555-123" } }
];
var updatedDocument = patch.reduce(applyReducer, document);
// updatedDocument == { firstName:"Joachim", lastName:"Wester", contactDetails:{ phoneNumbers[ {number:"555-123"} ] } };

jsonpatch.deepClone(value: any): any

Returns deeply cloned value.

jsonpatch.escapePathComponent(path: string): string

Returns the escaped path.

jsonpatch.unescapePathComponent(path: string): string

Returns the unescaped path.

jsonpatch.getValueByPointer(document: object, pointer: string)

Retrieves a value from a JSON document by a JSON pointer.

Returns the value.

jsonpatch.observe(document: any, callback?: Function): Observer

Sets up an deep observer on document that listens for changes in object tree. When changes are detected, the optional callback is called with the generated patches array as the parameter.

Returns observer.

jsonpatch.generate(document: any, observer: Observer, invertible = false): Operation[]

If there are pending changes in obj, returns them synchronously. If a callback was defined in observe method, it will be triggered synchronously as well. If invertible is true, then each change will be preceded by a test operation of the value before the change.

If there are no pending changes in obj, returns an empty array (length 0).

Example:

var document = { firstName: "Joachim", lastName: "Wester", contactDetails: { phoneNumbers: [ { number:"555-123" }] } };
var observer = jsonpatch.observe(document);
document.firstName = "Albert";
document.contactDetails.phoneNumbers[0].number = "123";
document.contactDetails.phoneNumbers.push({ number:"456" });
var patch = jsonpatch.generate(observer);
// patch  == [
//   { op: "replace", path: "/firstName", value: "Albert"},
//   { op: "replace", path: "/contactDetails/phoneNumbers/0/number", value: "123" },
//   { op: "add", path: "/contactDetails/phoneNumbers/1", value: {number:"456"}}
// ];

Example of generating patches with test operations for values in the first object:

var document = { firstName: "Joachim", lastName: "Wester", contactDetails: { phoneNumbers: [ { number:"555-123" }] } };
var observer = jsonpatch.observe(document);
document.firstName = "Albert";
document.contactDetails.phoneNumbers[0].number = "123";
document.contactDetails.phoneNumbers.push({ number:"456" });
var patch = jsonpatch.generate(observer, true);
// patch  == [
//   { op: "test", path: "/firstName", value: "Joachim"},
//   { op: "replace", path: "/firstName", value: "Albert"},
//   { op: "test", path: "/contactDetails/phoneNumbers/0/number", value: "555-123" },
//   { op: "replace", path: "/contactDetails/phoneNumbers/0/number", value: "123" },
//   { op: "add", path: "/contactDetails/phoneNumbers/1", value: {number:"456"}}
// ];

jsonpatch.unobserve(document, observer)

jsonpatch.unobserve(document: any, observer: Observer): void

type JsonableObj = { [key:string]: Jsonable };
type JsonableArr = Jsonable[];
type Jsonable = JsonableArr | JsonableObj | string | number | boolean | null;

Destroys the observer set up on document.

Any remaining changes are delivered synchronously (as in jsonpatch.generate). Note: this is different that ES6/7 Object.unobserve, which delivers remaining changes asynchronously.

jsonpatch.compare(document1, document2, invertible)

jsonpatch.compare(document1: Jsonable, document2: Jsonable, invertible = false): Operation[]

type JsonableObj = { [key:string]: Jsonable };
type JsonableArr = Jsonable[];
type Jsonable = JsonableArr | JsonableObj | string | number | boolean | null;

Compares object trees document1 and document2 and returns the difference relative to document1 as a patches array. If invertible is true, then each change will be preceded by a test operation of the value in document1.

If there are no differences, returns an empty array (length 0).

Example:

var documentA = {user: {firstName: "Albert", lastName: "Einstein"}};
var documentB = {user: {firstName: "Albert", lastName: "Collins"}};
var diff = jsonpatch.compare(documentA, documentB);
//diff == [{op: "replace", path: "/user/lastName", value: "Collins"}]

Example of comparing two object trees with test operations for values in the first object:

var documentA = {user: {firstName: "Albert", lastName: "Einstein"}};
var documentB = {user: {firstName: "Albert", lastName: "Collins"}};
var diff = jsonpatch.compare(documentA, documentB, true);
//diff == [
//   {op: "test", path: "/user/lastName", value: "Einstein"},
//   {op: "replace", path: "/user/lastName", value: "Collins"}
// ];

jsonpatch.validate(patch: Operation[], document?: any, validator?: Function): JsonPatchError

See Validation notes

Validates a sequence of operations. If document parameter is provided, the sequence is additionally validated against the object tree.

If there are no errors, returns undefined. If there is an errors, returns a JsonPatchError object with the following properties:

  • name String - short error code
  • message String - long human readable error message
  • index Number - index of the operation in the sequence
  • operation Object - reference to the operation
  • tree Object - reference to the tree

Possible errors:

Error name Error message
SEQUENCE_NOT_AN_ARRAY Patch sequence must be an array
OPERATION_NOT_AN_OBJECT Operation is not an object
OPERATION_OP_INVALID Operation op property is not one of operations defined in RFC-6902
OPERATION_PATH_INVALID Operation path property is not a valid string
OPERATION_FROM_REQUIRED Operation from property is not present (applicable in move and copy operations)
OPERATION_VALUE_REQUIRED Operation value property is not present, or undefined (applicable in add, replace and test operations)
OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED Operation value property object has at least one undefined value (applicable in add, replace and test operations)
OPERATION_PATH_CANNOT_ADD Cannot perform an add operation at the desired path
OPERATION_PATH_UNRESOLVABLE Cannot perform the operation at a path that does not exist
OPERATION_FROM_UNRESOLVABLE Cannot perform the operation from a path that does not exist
OPERATION_PATH_ILLEGAL_ARRAY_INDEX Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index
OPERATION_VALUE_OUT_OF_BOUNDS The specified index MUST NOT be greater than the number of elements in the array
TEST_OPERATION_FAILED When operation is test and the test fails, applies to applyReducer.

Example:

```js var obj = {

Extension points exported contracts — how you extend this code

Validator (Interface)
(no doc)
module/core.d.ts
Observer (Interface)
(no doc)
module/duplex.d.ts
Validator (Interface)
(no doc)
src/core.ts
Observer (Interface)
(no doc)
src/duplex.ts
OperationResult (Interface)
(no doc)
module/core.d.ts
OperationResult (Interface)
(no doc)
src/core.ts
BaseOperation (Interface)
(no doc)
module/core.d.ts
BaseOperation (Interface)
(no doc)
src/core.ts

Core symbols most depended-on inside this repo

trigger
called by 29
test/spec/duplexSpec.mjs
_deepClone
called by 22
module/helpers.mjs
insertIf
called by 16
test/spec/duplexSpec.mjs
escapePathComponent
called by 14
module/helpers.mjs
variantIt
called by 14
test/spec/duplexSpec.mjs
s
called by 11
test/spec/webpack/importSpec.build.js
hasOwnProperty
called by 6
module/helpers.mjs
isInteger
called by 6
module/helpers.mjs

Shape

Function 137
Interface 24
Class 8
Method 3

Languages

TypeScript100%

Modules by API surface

test/spec/webpack/importSpec.build.js26 symbols
src/core.ts18 symbols
src/duplex.ts17 symbols
src/helpers.ts13 symbols
module/helpers.mjs13 symbols
commonjs/helpers.js13 symbols
module/duplex.mjs12 symbols
commonjs/duplex.js12 symbols
module/core.d.ts11 symbols
test/spec/duplexSpec.mjs9 symbols
module/core.mjs7 symbols
commonjs/core.js7 symbols

Used by 2 indexed graphs manifest dependencies, hub-wide

Dependencies from manifests, versioned

benchmark2.1.4 · 1×
bluebird3.5.5 · 1×
bluebird-retry0.11.0 · 1×
chalk2.4.2 · 1×
event-target-shim5.0.1 · 1×
fast-deep-equal2.0.1 · 1×
http-server0.12.3 · 1×
jasmine3.4.0 · 1×
request2.88.0 · 1×
sauce-connect-launcher1.2.7 · 1×
saucelabs2.1.9 · 1×
selenium-webdriver4.0.0-alpha.4 · 1×

For agents

$ claude mcp add JSON-Patch \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact