Skip to content

Commit 0466383

Browse files
committed
feat: support async schema/fragment loading, closes #5
1 parent 6bc3853 commit 0466383

File tree

4 files changed

+77
-6
lines changed

4 files changed

+77
-6
lines changed

keywords/add_keyword.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ module.exports = function (ajv, keyword, jsonPatch, patchSchema) {
2020
: $ref;
2121
var validate = ajv.getSchema(id);
2222
if (validate) return validate.schema;
23-
throw new Error('can\'t resolve reference ' + $ref + ' from id ' + it.baseId);
23+
var err = new Error('can\'t resolve reference ' + $ref + ' from id ' + it.baseId);
24+
err.missingRef = it.resolve.url(it.baseId, $ref);
25+
err.missingSchema = it.resolve.normalizeId(it.resolve.fullPath(err.missingRef));
26+
throw err;
2427
}
2528
},
2629
metaSchema: {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ajv-merge-patch",
3-
"version": "2.0.2",
3+
"version": "2.1.0",
44
"description": "$merge and $patch keywords for Ajv JSON-Schema validator to extend schemas",
55
"main": "index.js",
66
"scripts": {

spec/async.spec.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
var Ajv = require('ajv');
4+
var addKeywords = require('..');
5+
var test = require('./test_validate');
6+
var assert = require('assert');
7+
8+
describe('async schema loading', function() {
9+
var ajv, loadCount;
10+
11+
beforeEach(function() {
12+
ajv = new Ajv({v5: true, loadSchema: loadSchema});
13+
addKeywords(ajv);
14+
loadCount = 0;
15+
});
16+
17+
describe('$merge', function() {
18+
it('should load missing schemas', function (done) {
19+
var schema = {
20+
"$merge": {
21+
"source": { "$ref": "obj.json#" },
22+
"with": {
23+
"properties": { "q": { "type": "number" } }
24+
}
25+
}
26+
};
27+
28+
testAsync(schema, '$merge', done);
29+
});
30+
});
31+
32+
describe('$patch', function() {
33+
it('should load missing schemas', function (done) {
34+
var schema = {
35+
"$patch": {
36+
"source": { "$ref": "obj.json#" },
37+
"with": [
38+
{ "op": "add", "path": "/properties/q", "value": { "type": "number" } }
39+
]
40+
}
41+
};
42+
43+
testAsync(schema, '$patch', done);
44+
});
45+
});
46+
47+
function testAsync(schema, keyword, done) {
48+
ajv.compileAsync(schema, function (err, validate) {
49+
if (err) done(err);
50+
assert.strictEqual(loadCount, 1);
51+
test(validate, keyword);
52+
done();
53+
});
54+
}
55+
56+
function loadSchema(ref, callback) {
57+
if (ref == 'obj.json') {
58+
loadCount++;
59+
return callback(null, {
60+
"id": "obj.json#",
61+
"type": "object",
62+
"properties": { "p": { "type": "string" } },
63+
"additionalProperties": false
64+
});
65+
}
66+
callback(new Error('404: ' + ref));
67+
}
68+
});

spec/patch.spec.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ describe('keyword $patch', function() {
3737
});
3838

3939
it('should extend schema defined in $ref', function() {
40-
ajvInstances.forEach(testMerge);
40+
ajvInstances.forEach(testPatch);
4141

42-
function testMerge(ajv) {
42+
function testPatch(ajv) {
4343
var sourceSchema = {
4444
"id": "obj.json#",
4545
"type": "object",
@@ -64,9 +64,9 @@ describe('keyword $patch', function() {
6464
});
6565

6666
it('should extend schema defined with relative $ref', function() {
67-
ajvInstances.forEach(testMerge);
67+
ajvInstances.forEach(testPatch);
6868

69-
function testMerge(ajv) {
69+
function testPatch(ajv) {
7070
var schema = {
7171
"id": "obj.json#",
7272
"definitions": {

0 commit comments

Comments
 (0)