From 21741bd11572d1c79dd19c10e3b6a60bafc2023d Mon Sep 17 00:00:00 2001 From: Simon Meusel Date: Sat, 14 Jul 2018 15:53:13 +0200 Subject: [PATCH 1/2] feat: allow arrays in merge --- keywords/merge.js | 29 +++++++++++++++++++++++++++-- spec/merge.spec.js | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/keywords/merge.js b/keywords/merge.js index 4106577..f283864 100644 --- a/keywords/merge.js +++ b/keywords/merge.js @@ -3,6 +3,31 @@ var addKeyword = require('./add_keyword'); var jsonMergePatch = require('json-merge-patch'); -module.exports = function(ajv) { - addKeyword(ajv, '$merge', jsonMergePatch.apply, { "type": "object" }); +function merge(source, other, _, index) { + if (!index) + index = 0; + + if (!Array.isArray(other)) + return jsonMergePatch.apply(source, other); + + if (other.length - index == 1) + return jsonMergePatch.apply(source, other[index]); + + return merge(jsonMergePatch.apply(source, other[index]), other, null, index + 1); +} + +module.exports = function (ajv) { + addKeyword(ajv, '$merge', merge, { + "oneOf": [ + { + "type": "object" + }, + { + "type": "array", + "items": { + "type": "object" + } + } + ] + }); }; diff --git a/spec/merge.spec.js b/spec/merge.spec.js index 0b770f2..443db22 100644 --- a/spec/merge.spec.js +++ b/spec/merge.spec.js @@ -157,4 +157,31 @@ describe('keyword $merge', function() { test(validate, '$merge'); } }); + + it('should extend schema defined in $merge', function() { + ajvInstances.forEach(testMerge); + + function testMerge(ajv) { + var schema = { + "$merge": { + "source": { + "type": "object", + "properties": { "p": { "type": "string" } }, + "additionalProperties": false + }, + "with": [ + { + "required": [ "q" ] + }, + { + "properties": { "q": { "type": "number" } } + } + ] + } + }; + + var validate = ajv.compile(schema); + test(validate, '$merge'); + } + }); }); From 3fd591812634f7876a1e3693c9bdcda79a42e5f0 Mon Sep 17 00:00:00 2001 From: Simon Meusel Date: Sat, 14 Jul 2018 16:02:48 +0200 Subject: [PATCH 2/2] feat: update array merge to iterative approach --- keywords/merge.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/keywords/merge.js b/keywords/merge.js index f283864..1ba89e5 100644 --- a/keywords/merge.js +++ b/keywords/merge.js @@ -3,17 +3,17 @@ var addKeyword = require('./add_keyword'); var jsonMergePatch = require('json-merge-patch'); -function merge(source, other, _, index) { - if (!index) - index = 0; +function merge(source, merges) { + if (!Array.isArray(merges)) + return jsonMergePatch.apply(source, merges); - if (!Array.isArray(other)) - return jsonMergePatch.apply(source, other); + var merged = source; - if (other.length - index == 1) - return jsonMergePatch.apply(source, other[index]); + merges.forEach(function (m) { + merged = jsonMergePatch.apply(source, m); + }); - return merge(jsonMergePatch.apply(source, other[index]), other, null, index + 1); + return merged; } module.exports = function (ajv) {