Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

To improve performance, skip validating subschemas in oneOf / anyOf if formData is undefined #2676

Merged
merged 9 commits into from
Mar 1, 2022
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ should change the heading of the (upcoming) version to include a major version b

# v4.0.2 (upcoming)

## @rjsf/core

- To improve performance, skip validating subschemas in oneOf / anyOf 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`
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
49 changes: 49 additions & 0 deletions packages/core/test/utils_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4200,6 +4200,55 @@ 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 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: {
Expand Down