Skip to content

Commit

Permalink
fix: Fixes #3805 by copying schema props rather than directly updatin…
Browse files Browse the repository at this point in the history
…g them (#3806)

* fix: Fixes #3805 by copying schema props rather than directly updating them

Fixes #3805 by using object spread of schema changes rather than direct updating of schema properties

- In `@rjsf/utils`, updated `resolveAllReferences()` to copy updated schema properties rather than directly changing them to avoid issues with frozen schemas
- In `@rjsf/material-ui`, removed the unnecessary import of the `@types/material-ui` which was causing typescript issues in some situations

* - Added deep freeze of schema used for testing to verify #3805
  • Loading branch information
heath-freenome authored Aug 2, 2023
1 parent 58c0ffa commit 23056cb
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 54 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ it according to semantic versioning. For example, if your PR adds a breaking cha
should change the heading of the (upcoming) version to include a major version bump.
-->
# 5.11.2

## @rjsf/material-ui

- Removed unnecessary import of old `@types/material-ui` which can cause typescript issues in some situations

## @rjsf/utils

- Updated the `resolveAllReferences()` function to use object spreading to update properties and items in a schema rather than directly modifying the schema to avoid issues with frozen object, fixing [#3805](https://github.com/rjsf-team/react-jsonschema-form/issues/3805)

# 5.11.1

## @rjsf/core
Expand Down
25 changes: 7 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/material-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"@rjsf/core": "^5.11.1",
"@rjsf/utils": "^5.11.1",
"@rjsf/validator-ajv8": "^5.11.1",
"@types/material-ui": "^0.21.12",
"@types/react": "^17.0.62",
"@types/react-dom": "^17.0.20",
"@types/react-test-renderer": "^17.0.2",
Expand Down
1 change: 1 addition & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@types/react-is": "^17.0.4",
"@types/react-test-renderer": "^17.0.2",
"babel-jest": "^29.6.1",
"deep-freeze-es6": "^1.4.1",
"dts-cli": "^1.6.3",
"eslint": "^8.44.0",
"jest": "^29.6.1",
Expand Down
15 changes: 10 additions & 5 deletions packages/utils/src/schema/retrieveSchema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import get from 'lodash/get';
import set from 'lodash/set';
import times from 'lodash/times';
import forEach from 'lodash/forEach';
import transform from 'lodash/transform';
import mergeAllOf, { Options } from 'json-schema-merge-allof';

import {
Expand Down Expand Up @@ -212,17 +212,22 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(sc
}

if (PROPERTIES_KEY in resolvedSchema) {
forEach(resolvedSchema[PROPERTIES_KEY], (value, key) => {
resolvedSchema[PROPERTIES_KEY]![key] = resolveAllReferences(value as S, rootSchema);
});
const updatedProps = transform(
resolvedSchema[PROPERTIES_KEY]!,
(result, value, key: string) => {
result[key] = resolveAllReferences(value as S, rootSchema);
},
{} as RJSFSchema
);
resolvedSchema = { ...resolvedSchema, [PROPERTIES_KEY]: updatedProps };
}

if (
ITEMS_KEY in resolvedSchema &&
!Array.isArray(resolvedSchema.items) &&
typeof resolvedSchema.items !== 'boolean'
) {
resolvedSchema.items = resolveAllReferences(resolvedSchema.items as S, rootSchema);
resolvedSchema = { ...resolvedSchema, items: resolveAllReferences(resolvedSchema.items as S, rootSchema) };
}

return resolvedSchema;
Expand Down
61 changes: 31 additions & 30 deletions packages/utils/test/testUtils/testData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import reduce from 'lodash/reduce';
import deepFreeze from 'deep-freeze-es6';

import {
EnumOptionsType,
Expand All @@ -21,7 +22,7 @@ export const oneOfData = {
},
},
};
export const oneOfSchema: RJSFSchema = {
export const oneOfSchema: RJSFSchema = deepFreeze({
type: 'object',
title: 'Testing OneOfs',
definitions: {
Expand Down Expand Up @@ -201,11 +202,11 @@ export const oneOfSchema: RJSFSchema = {
title: 'second option',
},
],
};
});
export const ONE_OF_SCHEMA_OPTIONS = oneOfSchema[ONE_OF_KEY]! as RJSFSchema[];
export const FIRST_ONE_OF: RJSFSchema = ONE_OF_SCHEMA_OPTIONS[0];
export const SECOND_ONE_OF: RJSFSchema = ONE_OF_SCHEMA_OPTIONS[1];
export const OPTIONAL_ONE_OF_SCHEMA: RJSFSchema = {
export const OPTIONAL_ONE_OF_SCHEMA: RJSFSchema = deepFreeze({
oneOf: [
{
type: 'object',
Expand Down Expand Up @@ -257,7 +258,7 @@ export const OPTIONAL_ONE_OF_SCHEMA: RJSFSchema = {
additionalProperties: false,
},
],
};
});
export const OPTIONAL_ONE_OF_SCHEMA_ONEOF = OPTIONAL_ONE_OF_SCHEMA[ONE_OF_KEY] as RJSFSchema[];
export const OPTIONAL_ONE_OF_DATA = { flag: true, inner_obj: { foo: 'bar' } };
export const SIMPLE_ONE_OF_SCHEMA = {
Expand Down Expand Up @@ -290,7 +291,7 @@ export const FALSY_OPTIONS: EnumOptionsType[] = [
{ value: 0, label: 'Zero' },
];

export const RECURSIVE_REF_ALLOF: RJSFSchema = {
export const RECURSIVE_REF_ALLOF: RJSFSchema = deepFreeze({
definitions: {
'@enum': {
type: 'object',
Expand Down Expand Up @@ -332,9 +333,9 @@ export const RECURSIVE_REF_ALLOF: RJSFSchema = {
minItems: 1,
},
},
};
});

export const RECURSIVE_REF: RJSFSchema = {
export const RECURSIVE_REF: RJSFSchema = deepFreeze({
definitions: {
'@enum': {
type: 'object',
Expand All @@ -351,7 +352,7 @@ export const RECURSIVE_REF: RJSFSchema = {
},
},
$ref: '#/definitions/@enum',
};
});

export const ERROR_MAPPER = {
'': 'root error',
Expand Down Expand Up @@ -390,7 +391,7 @@ export const TEST_ERROR_LIST: RJSFValidationError[] = reduce(
[]
);

export const SUPER_SCHEMA: RJSFSchema = {
export const SUPER_SCHEMA: RJSFSchema = deepFreeze({
[ID_KEY]: 'super-schema',
definitions: {
foo: {
Expand Down Expand Up @@ -465,9 +466,9 @@ export const SUPER_SCHEMA: RJSFSchema = {
},
},
},
};
});

export const PROPERTY_DEPENDENCIES: RJSFSchema = {
export const PROPERTY_DEPENDENCIES: RJSFSchema = deepFreeze({
type: 'object',
properties: {
a: { type: 'string' },
Expand All @@ -477,9 +478,9 @@ export const PROPERTY_DEPENDENCIES: RJSFSchema = {
dependencies: {
a: ['b'],
},
};
});

export const SCHEMA_DEPENDENCIES: RJSFSchema = {
export const SCHEMA_DEPENDENCIES: RJSFSchema = deepFreeze({
type: 'object',
properties: {
a: { type: 'string' },
Expand All @@ -491,9 +492,9 @@ export const SCHEMA_DEPENDENCIES: RJSFSchema = {
},
},
},
};
});

export const SCHEMA_AND_ONEOF_REF_DEPENDENCIES: RJSFSchema = {
export const SCHEMA_AND_ONEOF_REF_DEPENDENCIES: RJSFSchema = deepFreeze({
type: 'object',
definitions: {
needsA: {
Expand All @@ -517,9 +518,9 @@ export const SCHEMA_AND_ONEOF_REF_DEPENDENCIES: RJSFSchema = {
oneOf: [{ $ref: '#/definitions/needsA' }, { $ref: '#/definitions/needsB' }],
},
},
};
});

export const SCHEMA_AND_REQUIRED_DEPENDENCIES: RJSFSchema = {
export const SCHEMA_AND_REQUIRED_DEPENDENCIES: RJSFSchema = deepFreeze({
type: 'object',
properties: {
a: { type: 'string' },
Expand All @@ -534,9 +535,9 @@ export const SCHEMA_AND_REQUIRED_DEPENDENCIES: RJSFSchema = {
required: ['b'],
},
},
};
});

export const SCHEMA_WITH_ONEOF_NESTED_DEPENDENCIES: RJSFSchema = {
export const SCHEMA_WITH_ONEOF_NESTED_DEPENDENCIES: RJSFSchema = deepFreeze({
type: 'object',
dependencies: {
employee_accounts: {
Expand Down Expand Up @@ -604,9 +605,9 @@ export const SCHEMA_WITH_ONEOF_NESTED_DEPENDENCIES: RJSFSchema = {
title: 'Employee Accounts',
},
},
};
});

export const SCHEMA_WITH_SINGLE_CONDITION: RJSFSchema = {
export const SCHEMA_WITH_SINGLE_CONDITION: RJSFSchema = deepFreeze({
type: 'object',
properties: {
country: {
Expand All @@ -625,9 +626,9 @@ export const SCHEMA_WITH_SINGLE_CONDITION: RJSFSchema = {
postal_code: { pattern: '[A-Z][0-9][A-Z] [0-9][A-Z][0-9]' },
},
},
};
});

export const SCHEMA_WITH_MULTIPLE_CONDITIONS: RJSFSchema = {
export const SCHEMA_WITH_MULTIPLE_CONDITIONS: RJSFSchema = deepFreeze({
type: 'object',
properties: {
Animal: {
Expand Down Expand Up @@ -731,9 +732,9 @@ export const SCHEMA_WITH_MULTIPLE_CONDITIONS: RJSFSchema = {
},
],
required: ['Animal'],
};
});

export const SCHEMA_WITH_NESTED_CONDITIONS: RJSFSchema = {
export const SCHEMA_WITH_NESTED_CONDITIONS: RJSFSchema = deepFreeze({
type: 'object',
properties: {
country: {
Expand Down Expand Up @@ -792,19 +793,19 @@ export const SCHEMA_WITH_NESTED_CONDITIONS: RJSFSchema = {
},
},
},
};
});

export const SCHEMA_WITH_ARRAY_CONDITION: RJSFSchema = {
export const SCHEMA_WITH_ARRAY_CONDITION: RJSFSchema = deepFreeze({
type: 'object',
properties: {
list: {
type: 'array',
items: SCHEMA_WITH_SINGLE_CONDITION,
},
},
};
});

export const SCHEMA_WITH_ALLOF_CANNOT_MERGE: RJSFSchema = {
export const SCHEMA_WITH_ALLOF_CANNOT_MERGE: RJSFSchema = deepFreeze({
type: 'object',
properties: {
animal: {
Expand Down Expand Up @@ -856,4 +857,4 @@ export const SCHEMA_WITH_ALLOF_CANNOT_MERGE: RJSFSchema = {
required: ['animal'],
},
],
};
});

0 comments on commit 23056cb

Please sign in to comment.