Skip to content

Commit

Permalink
Merge pull request #23 from donaldjarmstrong/master
Browse files Browse the repository at this point in the history
Update to latest fast-json-patch
  • Loading branch information
epoberezkin authored Jun 25, 2018
2 parents 4094556 + 5708ba9 commit f1e8831
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ The same schema extension using `$patch` keyword:
`$patch` is implemented as a [custom macro keyword](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md#define-keyword-with-macro-function) using [fast-json-patch](https://github.com/Starcounter-Jack/JSON-Patch) package.


In the majority of cases `$merge` format is easier to understand and to maintain. `$patch` can be used for extensions and changes that cannot be expressed using `$merge`.
In the majority of cases `$merge` format is easier to understand and to maintain. `$patch` can be used for extensions and changes that cannot be expressed using `$merge`, e.g. [Adding an array value](https://tools.ietf.org/html/rfc6902#page-18).

`with` property in keywords can also be a reference to a part of some schema, in which case the resolved value will be used rather than the actual object with property `$ref`.

Expand Down
2 changes: 1 addition & 1 deletion keywords/add_keyword.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = function (ajv, keyword, jsonPatch, patchSchema) {
var patch = schema.with;
if (source.$ref) source = JSON.parse(JSON.stringify(getSchema(source.$ref)));
if (patch.$ref) patch = getSchema(patch.$ref);
jsonPatch.apply(source, patch, true);
jsonPatch.call(null, source, patch, true);
return source;

function getSchema($ref) {
Expand Down
2 changes: 1 addition & 1 deletion keywords/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ var addKeyword = require('./add_keyword');
var jsonMergePatch = require('json-merge-patch');

module.exports = function(ajv) {
addKeyword(ajv, '$merge', jsonMergePatch, { "type": "object" });
addKeyword(ajv, '$merge', jsonMergePatch.apply, { "type": "object" });
};
4 changes: 2 additions & 2 deletions keywords/patch.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';

var addKeyword = require('./add_keyword');
var jsonPatch = require('fast-json-patch/src/json-patch');
var jsonPatch = require('fast-json-patch');

module.exports = function(ajv) {
addKeyword(ajv, '$patch', jsonPatch, {
addKeyword(ajv, '$patch', jsonPatch.applyPatch, {
"type": "array",
"items": {
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"homepage": "https://github.com/epoberezkin/ajv-merge-patch#readme",
"dependencies": {
"fast-json-patch": "^1.0.0",
"fast-json-patch": "^2.0.6",
"json-merge-patch": "^0.2.3"
},
"devDependencies": {
Expand Down
9 changes: 6 additions & 3 deletions spec/async.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ describe('async schema loading', function() {
"$merge": {
"source": { "$ref": "obj.json#" },
"with": {
"properties": { "q": { "type": "number" } }
"properties": { "q": { "type": "number" } },
"required": [ "q" ]
}
}
};
Expand All @@ -35,7 +36,8 @@ describe('async schema loading', function() {
"$patch": {
"source": { "$ref": "obj.json#" },
"with": [
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } },
{ "op": "add", "path": "/required/-", "value": "q" }
]
}
};
Expand All @@ -59,7 +61,8 @@ describe('async schema loading', function() {
"id": "obj.json#",
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "p" ]
};
return Promise.resolve(schema);
}
Expand Down
18 changes: 12 additions & 6 deletions spec/merge.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ describe('keyword $merge', function() {
"additionalProperties": false
},
"with": {
"properties": { "q": { "type": "number" } }
"properties": { "q": { "type": "number" } },
"required": [ "q" ]
}
}
};
Expand All @@ -53,7 +54,8 @@ describe('keyword $merge', function() {
"$merge": {
"source": { "$ref": "obj.json#" },
"with": {
"properties": { "q": { "type": "number" } }
"properties": { "q": { "type": "number" } },
"required": [ "q" ]
}
}
};
Expand All @@ -79,7 +81,8 @@ describe('keyword $merge', function() {
"$merge": {
"source": { "$ref": "#/definitions/source" },
"with": {
"properties": { "q": { "type": "number" } }
"properties": { "q": { "type": "number" } },
"required": [ "q" ]
}
}
};
Expand All @@ -96,13 +99,15 @@ describe('keyword $merge', function() {
var sourceSchema = {
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "p" ]
};

var patchSchema = {
"type": "object",
"properties": { "q": { "type": "number" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "q" ]
};

ajv.addSchema(sourceSchema, "obj1.json#");
Expand Down Expand Up @@ -138,7 +143,8 @@ describe('keyword $merge', function() {
"patch":{
"type": "object",
"properties": { "q": { "type": "number" } },
"additionalProperties": false
"additionalProperties": false,
"required" : [ "q" ]
}
},
"$merge": {
Expand Down
18 changes: 12 additions & 6 deletions spec/patch.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ describe('keyword $patch', function() {
"source": {
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "p" ]
},
"with": [
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } },
{ "op": "add", "path": "/required/-", "value": "q" }
]
}
};
Expand All @@ -44,7 +46,8 @@ describe('keyword $patch', function() {
"$id": "obj.json#",
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "p" ]
};

ajv.addSchema(sourceSchema);
Expand All @@ -53,7 +56,8 @@ describe('keyword $patch', function() {
"$patch": {
"source": { "$ref": "obj.json#" },
"with": [
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } },
{ "op": "add", "path": "/required/-", "value": "q" }
]
}
};
Expand All @@ -73,13 +77,15 @@ describe('keyword $patch', function() {
"source": {
"type": "object",
"properties": { "p": { "type": "string" } },
"additionalProperties": false
"additionalProperties": false,
"required": [ "p" ]
}
},
"$patch": {
"source": { "$ref": "#/definitions/source" },
"with": [
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } },
{ "op": "add", "path": "/required/-", "value": "q" }
]
}
};
Expand Down
14 changes: 14 additions & 0 deletions spec/test_validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var assert = require('assert');

module.exports = function (validate, keyword) {
assert.strictEqual(validate({ p: 'abc', q: 1 }), true);

// property q should be a number
assert.strictEqual(validate({ p: 'foo', q: 'bar' }), false);
var errs = validate.errors;
assert.equal(errs.length, 2);
Expand All @@ -13,4 +15,16 @@ module.exports = function (validate, keyword) {
assert.equal(errs[1].keyword, keyword);
assert.equal(errs[1].dataPath, '');
assert.equal(errs[1].schemaPath, '#/' + keyword);

// an object without q should fail
assert.strictEqual(validate({ p: 'foo' }), false);
errs = validate.errors;
assert.equal(errs.length, 2);
assert.equal(errs[0].keyword, 'required');
assert.equal(errs[0].dataPath, '');
assert.equal(errs[0].schemaPath, '#/required');
assert.deepEqual(errs[0].params, { missingProperty: 'q' });
assert.equal(errs[1].keyword, keyword);
assert.equal(errs[1].dataPath, '');
assert.equal(errs[1].schemaPath, '#/' + keyword);
};

0 comments on commit f1e8831

Please sign in to comment.