From 6af775359427f1541c54e974e5289e24cb25d102 Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Thu, 27 Jan 2022 16:39:01 +0000 Subject: [PATCH 1/9] Fixing getMatchingOption Fixing getMatchingOption in the case of oneOf/anyOf by validating schema only when formData is available --- packages/core/src/utils.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 3bc1bdbc29..468b4141a5 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -1288,10 +1288,11 @@ export function getMatchingOption(formData, options, rootSchema) { // been filled in yet, which will mean that the schema is not valid delete augmentedSchema.required; - if (isValid(augmentedSchema, formData, rootSchema)) { + if (formData && isValid(augmentedSchema, formData, rootSchema)) { return i; } - } else if (isValid(option, formData, rootSchema)) { + return i; + } else if (formData && isValid(option, formData, rootSchema)) { return i; } } From 75c49b9cddc46d8b47a2e9617453276dd6ba7b95 Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Tue, 1 Feb 2022 13:43:32 +0000 Subject: [PATCH 2/9] add proper return on formData check add proper return on formData check in getMatchingOption() --- packages/core/src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 468b4141a5..1564e3cc22 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -1291,7 +1291,7 @@ export function getMatchingOption(formData, options, rootSchema) { if (formData && isValid(augmentedSchema, formData, rootSchema)) { return i; } - return i; + } else if (formData && isValid(option, formData, rootSchema)) { return i; } From 2b7bd46ea40f0559e0ad1d3693127a829004c382 Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Tue, 1 Feb 2022 13:44:50 +0000 Subject: [PATCH 3/9] Test utils when formData is undefined Test utils when formData is undefined --- packages/core/test/utils_test.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/core/test/utils_test.js b/packages/core/test/utils_test.js index ba6c918045..364cfedb84 100644 --- a/packages/core/test/utils_test.js +++ b/packages/core/test/utils_test.js @@ -4200,6 +4200,33 @@ describe("utils", () => { })) ); }); + it("should infer correct anyOf schema based on data if passing undefined", () => { + const rootSchema = { + defs: { + a: { type: "object", properties: { id: { enum: ["a"] } } }, + nested: { + type: "object", + properties: { + id: { enum: ["nested"] }, + child: { $ref: "#/defs/any" }, + }, + }, + any: { anyOf: [{ $ref: "#/defs/a" }, { $ref: "#/defs/nested" }] }, + }, + $ref: "#/defs/any", + }; + const options = [ + { type: "object", properties: { id: { enum: ["a"] } } }, + { + type: "object", + properties: { + id: { enum: ["nested"] }, + child: { $ref: "#/defs/any" }, + }, + }, + ]; + expect(getMatchingOption(undefined, options, rootSchema)).eql(0); + }); it("should infer correct anyOf schema based on data", () => { const rootSchema = { defs: { From a79fb419a162f58643f87a0497abb1d023727802 Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Fri, 11 Feb 2022 14:24:18 +0000 Subject: [PATCH 4/9] moving formData check in getMatchingOption() For performance, skip validating subschemas if formData is undefined. We just want to get the first option in that case. moving formData check to beginning of getMatchingOption() --- packages/core/src/utils.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 1564e3cc22..1bdcd8390f 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -1244,6 +1244,11 @@ export function rangeSpec(schema) { } export function getMatchingOption(formData, options, rootSchema) { + // For performance, skip validating subschemas if formData is undefined. We just + // want to get the first option in that case. + if (formData === undefined) { + return 0; + } for (let i = 0; i < options.length; i++) { const option = options[i]; @@ -1288,11 +1293,11 @@ export function getMatchingOption(formData, options, rootSchema) { // been filled in yet, which will mean that the schema is not valid delete augmentedSchema.required; - if (formData && isValid(augmentedSchema, formData, rootSchema)) { + if (isValid(augmentedSchema, formData, rootSchema)) { return i; } - } else if (formData && isValid(option, formData, rootSchema)) { + } else if (isValid(option, formData, rootSchema)) { return i; } } From be4bf8b6510738b28660d9e1d418c0d957397559 Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Fri, 11 Feb 2022 14:26:26 +0000 Subject: [PATCH 5/9] Add a test for getMatchingOption when passing null Add a test for getMatchingOption where formData is null Where option 2 is {type: null} We expect getMatchingOption to be equal to 2 --- packages/core/test/utils_test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/core/test/utils_test.js b/packages/core/test/utils_test.js index 364cfedb84..86aa640ad4 100644 --- a/packages/core/test/utils_test.js +++ b/packages/core/test/utils_test.js @@ -4227,6 +4227,24 @@ describe("utils", () => { ]; expect(getMatchingOption(undefined, options, rootSchema)).eql(0); }); + it("should infer correct anyOf schema based on data if passing null and option 2 is {type: null}", () => { + const rootSchema = { + defs: { + a: { type: "object", properties: { id: { enum: ["a"] } } }, + nested: { + type: "object", + properties: { + id: { enum: ["nested"] }, + child: { $ref: "#/defs/any" }, + }, + }, + any: { anyOf: [{ $ref: "#/defs/a" }, { $ref: "#/defs/nested" }] }, + }, + $ref: "#/defs/any", + }; + const options = [{type: "string"}, {type: "string"}, {type: "null"}]; + expect(getMatchingOption(null, options, rootSchema)).eql(2); + }); it("should infer correct anyOf schema based on data", () => { const rootSchema = { defs: { From 37648c8f7fb56f83c5c03fdf7558f9690603000a Mon Sep 17 00:00:00 2001 From: Kitty Jose Date: Mon, 14 Feb 2022 18:12:44 +0000 Subject: [PATCH 6/9] after fixing lint errors after fixing lint errors --- packages/core/test/utils_test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/test/utils_test.js b/packages/core/test/utils_test.js index 86aa640ad4..e12b7808ab 100644 --- a/packages/core/test/utils_test.js +++ b/packages/core/test/utils_test.js @@ -4242,7 +4242,11 @@ describe("utils", () => { }, $ref: "#/defs/any", }; - const options = [{type: "string"}, {type: "string"}, {type: "null"}]; + const options = [ + { type: "string" }, + { type: "string" }, + { type: "null" }, + ]; expect(getMatchingOption(null, options, rootSchema)).eql(2); }); it("should infer correct anyOf schema based on data", () => { From a761b8a81322f8fba715c64e994bf94cbd82691e Mon Sep 17 00:00:00 2001 From: Robin de Rooij Date: Mon, 21 Feb 2022 10:59:26 +0100 Subject: [PATCH 7/9] utils: fix linter issue --- packages/core/src/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/utils.js b/packages/core/src/utils.js index 1bdcd8390f..14efe21bdf 100644 --- a/packages/core/src/utils.js +++ b/packages/core/src/utils.js @@ -1296,7 +1296,6 @@ export function getMatchingOption(formData, options, rootSchema) { if (isValid(augmentedSchema, formData, rootSchema)) { return i; } - } else if (isValid(option, formData, rootSchema)) { return i; } From 5ae170f2a41ce3df897f23a9cc1b931e17145b7e Mon Sep 17 00:00:00 2001 From: Robin de Rooij Date: Fri, 25 Feb 2022 16:43:06 +0100 Subject: [PATCH 8/9] CHANGELOG: add entry for performance PR --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c12ad5de..e1b944f846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ should change the heading of the (upcoming) version to include a major version b # v4.0.2 (upcoming) +## @rjsf/core + +- For performance, skip validating subschemas if formData is undefined (#2676) + # v4.0.1 - Bumped the peer dependencies of `@rjsf/core` to `^4.0.0` for all of themes in `package.json` From 9b38d3a96e0db6cabaa50d1920cea1d5cbfee2ed Mon Sep 17 00:00:00 2001 From: Robin de Rooij Date: Mon, 28 Feb 2022 09:52:24 +0100 Subject: [PATCH 9/9] CHANGELOG: rephrase change --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1b944f846..f060cb5040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ should change the heading of the (upcoming) version to include a major version b ## @rjsf/core -- For performance, skip validating subschemas if formData is undefined (#2676) +- To improve performance, skip validating subschemas in oneOf / anyOf if formData is undefined (#2676) # v4.0.1