From 9cc5aeea79ce27cc2041ed31284e11963ea05020 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 21 Apr 2017 09:57:18 +0100 Subject: [PATCH 1/2] Handle references to deep schema definitions --- src/utils.js | 17 ++++++++++++++--- test/Form_test.js | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/utils.js b/src/utils.js index cc67899c6b..06b1df9b8e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -314,10 +314,21 @@ export function optionsList(schema) { function findSchemaDefinition($ref, definitions = {}) { // Extract and use the referenced definition if we have it. - const match = /#\/definitions\/(.*)$/.exec($ref); - if (match && match[1] && definitions.hasOwnProperty(match[1])) { - return definitions[match[1]]; + const match = /^#\/definitions\/(.*)$/.exec($ref); + if (match && match[1]) { + const parts = match[1].split("/"); + let current = definitions; + for (const part of parts) { + if (current.hasOwnProperty(part)) { + current = current[part]; + } else { + // No matching definition found, that's an error (bogus schema?) + throw new Error(`Could not find a definition for ${$ref}.`); + } + } + return current; } + // No matching definition found, that's an error (bogus schema?) throw new Error(`Could not find a definition for ${$ref}.`); } diff --git a/test/Form_test.js b/test/Form_test.js index 177a0f1e44..6fcaea1a57 100644 --- a/test/Form_test.js +++ b/test/Form_test.js @@ -229,6 +229,27 @@ describe("Form", () => { expect(node.querySelectorAll("input[type=text]")).to.have.length.of(1); }); + it("should handle references to deep schema definitions", () => { + const schema = { + definitions: { + testdef: { + type: "object", + properties: { + bar: { type: "string" }, + }, + }, + }, + type: "object", + properties: { + foo: { $ref: "#/definitions/testdef/properties/bar" }, + }, + }; + + const { node } = createFormComponent({ schema }); + + expect(node.querySelectorAll("input[type=text]")).to.have.length.of(1); + }); + it("should handle referenced definitions for array items", () => { const schema = { definitions: { From 95bee418412810e67fb18c8d1a6c59c16d900ff6 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Wed, 26 Apr 2017 06:11:12 +0100 Subject: [PATCH 2/2] Handle JSON Pointer escaping --- src/utils.js | 3 ++- test/utils_test.js | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 06b1df9b8e..31c8b4ca37 100644 --- a/src/utils.js +++ b/src/utils.js @@ -318,7 +318,8 @@ function findSchemaDefinition($ref, definitions = {}) { if (match && match[1]) { const parts = match[1].split("/"); let current = definitions; - for (const part of parts) { + for (let part of parts) { + part = part.replace(/~1/g, "/").replace(/~0/g, "~"); if (current.hasOwnProperty(part)) { current = current[part]; } else { diff --git a/test/utils_test.js b/test/utils_test.js index 586f4594a3..ad42abd5df 100644 --- a/test/utils_test.js +++ b/test/utils_test.js @@ -365,6 +365,14 @@ describe("utils", () => { expect(retrieveSchema(schema, definitions)).eql(address); }); + it("should 'resolve' escaped JSON Pointers", () => { + const schema = { $ref: "#/definitions/a~0complex~1name" }; + const address = { type: "string" }; + const definitions = { "a~complex/name": address }; + + expect(retrieveSchema(schema, definitions)).eql(address); + }); + it("should priorize local definitions over foreign ones", () => { const schema = { $ref: "#/definitions/address",