diff --git a/CHANGELOG.md b/CHANGELOG.md index 8571393011..c05bac325d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ should change the heading of the (upcoming) version to include a major version b --> +# 6.0.0-beta.8 + +## @rjsf/util + +- Fixed form data propagation with `patternProperties` [#4617](https://github.com/rjsf-team/react-jsonschema-form/pull/4617) + # 6.0.0-beta.7 ## @rjsf/core diff --git a/packages/utils/src/findSchemaDefinition.ts b/packages/utils/src/findSchemaDefinition.ts index 57178eee42..09abc7e215 100644 --- a/packages/utils/src/findSchemaDefinition.ts +++ b/packages/utils/src/findSchemaDefinition.ts @@ -6,6 +6,7 @@ import { GenericObjectType, RJSFSchema, StrictRJSFSchema } from './types'; import isObject from 'lodash/isObject'; import isEmpty from 'lodash/isEmpty'; import UriResolver from 'fast-uri'; +import get from 'lodash/get'; /** Looks for the `$id` pointed by `ref` in the schema definitions embedded in * a JSON Schema bundle @@ -51,7 +52,7 @@ export function splitKeyElementFromObject(key: string, object: GenericObjectType * @param $ref - The ref string for which the schema definition is desired * @param [rootSchema={}] - The root schema in which to search for the definition * @param recurseList - List of $refs already resolved to prevent recursion - * @param baseURI - The base URI to be used for resolving relative references + * @param [baseURI=rootSchema['$id']] - The base URI to be used for resolving relative references * @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists * @throws - Error indicating that no schema for that reference could be resolved */ @@ -59,7 +60,7 @@ export function findSchemaDefinitionRecursive( $ref?: string, rootSchema: S = {} as S, - baseURI: string | undefined = ID_KEY in rootSchema ? rootSchema[ID_KEY] : undefined, + baseURI: string | undefined = get(rootSchema, [ID_KEY]), ): S { const recurseList: string[] = []; return findSchemaDefinitionRecursive($ref, rootSchema, recurseList, baseURI); diff --git a/packages/utils/src/schema/retrieveSchema.ts b/packages/utils/src/schema/retrieveSchema.ts index 0b3a72d073..cb6d58d9d7 100644 --- a/packages/utils/src/schema/retrieveSchema.ts +++ b/packages/utils/src/schema/retrieveSchema.ts @@ -334,7 +334,7 @@ export function resolveReference( @@ -432,7 +432,7 @@ export function stubExistingAdditionalProperties< validator, { allOf: Object.values(matchingProperties) } as S, rootSchema, - formData as T, + get(formData, [key]) as T, experimental_customMergeAllOf, ); set(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true); @@ -578,7 +578,7 @@ export function retrieveSchemaInternal< validator, { allOf: [schema.properties[key], ...Object.values(matchingProperties)] } as S, rootSchema, - rawFormData as T, + get(rawFormData, [key]) as T, experimental_customMergeAllOf, ); } diff --git a/packages/utils/test/schema/retrieveSchemaTest.ts b/packages/utils/test/schema/retrieveSchemaTest.ts index ed2d9f34b9..d128453fa3 100644 --- a/packages/utils/test/schema/retrieveSchemaTest.ts +++ b/packages/utils/test/schema/retrieveSchemaTest.ts @@ -1338,6 +1338,95 @@ export default function retrieveSchemaTest(testValidator: TestValidatorType) { }); }); describe('withPatternProperties()', () => { + it('validates schemas with conditions inside patternProperties', () => { + const schema: RJSFSchema = { + type: 'object', + properties: { + foo: { + type: 'object', + }, + }, + patternProperties: { + '^[a-z]+$': { + type: 'object', + properties: { + isString: { type: 'boolean' }, + }, + allOf: [ + { + if: { + properties: { isString: { const: true } }, + }, + then: { + properties: { + value: { + type: 'string', + }, + }, + }, + }, + { + if: { + properties: { isString: { const: false } }, + }, + then: { + properties: { + value: { + type: 'number', + }, + }, + }, + }, + ], + }, + }, + }; + const rootSchema: RJSFSchema = { definitions: {} }; + testValidator.setReturnValues({ + isValid: [true, false, true, false], + }); + expect( + retrieveSchema(testValidator, schema, rootSchema, { + foo: { isString: true }, + bar: { isString: true }, + }), + ).toEqual({ + ...schema, + properties: { + foo: { + type: 'object', + properties: { isString: { type: 'boolean' }, value: { type: 'string' } }, + }, + bar: { + [ADDITIONAL_PROPERTY_FLAG]: true, + type: 'object', + properties: { isString: { type: 'boolean' }, value: { type: 'string' } }, + }, + }, + }); + testValidator.setReturnValues({ + isValid: [false, true, false, true], + }); + expect( + retrieveSchema(testValidator, schema, rootSchema, { + foo: { isString: false }, + bar: { isString: false }, + }), + ).toEqual({ + ...schema, + properties: { + foo: { + type: 'object', + properties: { isString: { type: 'boolean' }, value: { type: 'number' } }, + }, + bar: { + [ADDITIONAL_PROPERTY_FLAG]: true, + type: 'object', + properties: { isString: { type: 'boolean' }, value: { type: 'number' } }, + }, + }, + }); + }); it('merges all subschemas that match the patternProperties regex', () => { const schema: RJSFSchema = { type: 'object',