diff --git a/package.json b/package.json index 0639401064..5852ea996c 100644 --- a/package.json +++ b/package.json @@ -79,5 +79,6 @@ "packages/validator-ajv6", "packages/validator-ajv8", "packages/snapshot-tests" - ] + ], + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/core/src/components/Form.tsx b/packages/core/src/components/Form.tsx index 48851cfcf3..a83a629d8f 100644 --- a/packages/core/src/components/Form.tsx +++ b/packages/core/src/components/Form.tsx @@ -1,10 +1,11 @@ -import { Component, ElementType, FormEvent, ReactNode, Ref, RefObject, createRef } from 'react'; +import { Component, createRef, ElementType, FormEvent, ReactNode, Ref, RefObject } from 'react'; import { createSchemaUtils, CustomValidator, deepEquals, ErrorSchema, ErrorTransformer, + Experimental_DefaultFormStateBehavior, FormContextType, GenericObjectType, getTemplate, @@ -14,31 +15,31 @@ import { mergeObjects, NAME_KEY, PathSchema, - StrictRJSFSchema, Registry, RegistryFieldsType, RegistryWidgetsType, + RJSF_ADDITIONAL_PROPERTIES_FLAG, RJSFSchema, RJSFValidationError, - RJSF_ADDITIONAL_PROPERTIES_FLAG, SchemaUtilsType, shouldRender, + StrictRJSFSchema, SUBMIT_BTN_OPTIONS_KEY, TemplatesType, toErrorList, - UiSchema, UI_GLOBAL_OPTIONS_KEY, UI_OPTIONS_KEY, + UiSchema, ValidationData, validationDataMerge, ValidatorType, - Experimental_DefaultFormStateBehavior, } from '@rjsf/utils'; import _forEach from 'lodash/forEach'; import _get from 'lodash/get'; import _isEmpty from 'lodash/isEmpty'; import _pick from 'lodash/pick'; import _toPath from 'lodash/toPath'; +import fastDeepEqual from 'fast-deep-equal'; import getDefaultRegistry from '../getDefaultRegistry'; @@ -282,7 +283,7 @@ export default class Form< } this.state = this.getStateFromProps(props, props.formData); - if (this.props.onChange && !deepEquals(this.state.formData, this.props.formData)) { + if (this.props.onChange && !fastDeepEqual(this.state.formData, this.props.formData)) { this.props.onChange(this.state); } this.formElement = createRef(); @@ -309,10 +310,14 @@ export default class Form< getSnapshotBeforeUpdate( prevProps: FormProps, prevState: FormState - ): { nextState: FormState; shouldUpdate: true } | { shouldUpdate: false } { + ): + | { nextState: FormState; shouldUpdate: true } + | { + shouldUpdate: false; + } { if (!deepEquals(this.props, prevProps)) { - const isSchemaChanged = !deepEquals(prevProps.schema, this.props.schema); - const isFormDataChanged = !deepEquals(prevProps.formData, this.props.formData); + const isSchemaChanged = !fastDeepEqual(prevProps.schema, this.props.schema); + const isFormDataChanged = !fastDeepEqual(prevProps.formData, this.props.formData); const nextState = this.getStateFromProps( this.props, this.props.formData, @@ -346,14 +351,18 @@ export default class Form< componentDidUpdate( _: FormProps, prevState: FormState, - snapshot: { nextState: FormState; shouldUpdate: true } | { shouldUpdate: false } + snapshot: + | { nextState: FormState; shouldUpdate: true } + | { + shouldUpdate: false; + } ) { if (snapshot.shouldUpdate) { const { nextState } = snapshot; if ( - !deepEquals(nextState.formData, this.props.formData) && - !deepEquals(nextState.formData, prevState.formData) && + !fastDeepEqual(nextState.formData, this.props.formData) && + !fastDeepEqual(nextState.formData, prevState.formData) && this.props.onChange ) { this.props.onChange(nextState); @@ -692,7 +701,6 @@ export default class Form< * Callback function to handle reset form data. * - Reset all fields with default values. * - Reset validations and errors - * */ reset = () => { const { onChange } = this.props; @@ -772,7 +780,14 @@ export default class Form< }, () => { if (onSubmit) { - onSubmit({ ...this.state, formData: newFormData, status: 'submitted' }, event); + onSubmit( + { + ...this.state, + formData: newFormData, + status: 'submitted', + }, + event + ); } } ); @@ -956,9 +971,14 @@ export default class Form< let { [SUBMIT_BTN_OPTIONS_KEY]: submitOptions = {} } = getUiOptions(uiSchema); if (disabled) { - submitOptions = { ...submitOptions, props: { ...submitOptions.props, disabled: true } }; + submitOptions = { + ...submitOptions, + props: { ...submitOptions.props, disabled: true }, + }; } - const submitUiSchema = { [UI_OPTIONS_KEY]: { [SUBMIT_BTN_OPTIONS_KEY]: submitOptions } }; + const submitUiSchema = { + [UI_OPTIONS_KEY]: { [SUBMIT_BTN_OPTIONS_KEY]: submitOptions }, + }; return ( = { @@ -67,7 +67,7 @@ class AnyOfField schemaUtils.retrieveSchema(opt, formData)); newState = { selectedOption, retrievedOptions }; } - if (!deepEquals(formData, prevProps.formData) && idSchema.$id === prevProps.idSchema.$id) { + if (!fastDeepEqual(formData, prevProps.formData) && idSchema.$id === prevProps.idSchema.$id) { const { retrievedOptions } = newState; const matchingOption = this.getMatchingOption(selectedOption, formData, retrievedOptions); diff --git a/packages/utils/src/enumOptionsDeselectValue.ts b/packages/utils/src/enumOptionsDeselectValue.ts index 1dde198c32..1cabb53ccc 100644 --- a/packages/utils/src/enumOptionsDeselectValue.ts +++ b/packages/utils/src/enumOptionsDeselectValue.ts @@ -1,4 +1,4 @@ -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from './types'; import enumOptionsValueForIndex from './enumOptionsValueForIndex'; @@ -22,7 +22,7 @@ export default function enumOptionsDeselectValue['value'] | EnumOptionsType['value'][] | undefined { const value = enumOptionsValueForIndex(valueIndex, allEnumOptions); if (Array.isArray(selected)) { - return selected.filter((v) => !isEqual(v, value)); + return selected.filter((v) => !fastDeepEqual(v, value)); } - return isEqual(value, selected) ? undefined : selected; + return fastDeepEqual(value, selected) ? undefined : selected; } diff --git a/packages/utils/src/enumOptionsIsSelected.ts b/packages/utils/src/enumOptionsIsSelected.ts index a1c9fed1dd..c5d33ade12 100644 --- a/packages/utils/src/enumOptionsIsSelected.ts +++ b/packages/utils/src/enumOptionsIsSelected.ts @@ -1,4 +1,4 @@ -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from './types'; @@ -13,7 +13,7 @@ export default function enumOptionsIsSelected['value'] | EnumOptionsType['value'][] ) { if (Array.isArray(selected)) { - return selected.some((sel) => isEqual(sel, value)); + return selected.some((sel) => fastDeepEqual(sel, value)); } - return isEqual(selected, value); + return fastDeepEqual(selected, value); } diff --git a/packages/utils/src/parser/ParserValidator.ts b/packages/utils/src/parser/ParserValidator.ts index f1b771fc39..fd3b513d40 100644 --- a/packages/utils/src/parser/ParserValidator.ts +++ b/packages/utils/src/parser/ParserValidator.ts @@ -1,5 +1,5 @@ import get from 'lodash/get'; -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { ID_KEY } from '../constants'; import hashForSchema from '../hashForSchema'; @@ -67,7 +67,7 @@ export default class ParserValidator(schema)); diff --git a/packages/utils/src/parser/schemaParser.ts b/packages/utils/src/parser/schemaParser.ts index 70151f06a0..2514a482f3 100644 --- a/packages/utils/src/parser/schemaParser.ts +++ b/packages/utils/src/parser/schemaParser.ts @@ -1,10 +1,10 @@ import forEach from 'lodash/forEach'; -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { FormContextType, RJSFSchema, StrictRJSFSchema } from '../types'; -import { PROPERTIES_KEY, ITEMS_KEY } from '../constants'; +import { ITEMS_KEY, PROPERTIES_KEY } from '../constants'; import ParserValidator, { SchemaMap } from './ParserValidator'; -import { retrieveSchemaInternal, resolveAnyOrOneOfSchemas } from '../schema/retrieveSchema'; +import { resolveAnyOrOneOfSchemas, retrieveSchemaInternal } from '../schema/retrieveSchema'; /** Recursive function used to parse the given `schema` belonging to the `rootSchema`. The `validator` is used to * capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the @@ -24,7 +24,7 @@ function parseSchema(validator, schema, rootSchema, undefined, true); schemas.forEach((schema) => { - const sameSchemaIndex = recurseList.findIndex((item) => isEqual(item, schema)); + const sameSchemaIndex = recurseList.findIndex((item) => fastDeepEqual(item, schema)); if (sameSchemaIndex === -1) { recurseList.push(schema); const allOptions = resolveAnyOrOneOfSchemas(validator, schema, rootSchema, true); diff --git a/packages/utils/src/schema/retrieveSchema.ts b/packages/utils/src/schema/retrieveSchema.ts index 0f46632f1c..c74690b25c 100644 --- a/packages/utils/src/schema/retrieveSchema.ts +++ b/packages/utils/src/schema/retrieveSchema.ts @@ -1,5 +1,5 @@ import get from 'lodash/get'; -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import set from 'lodash/set'; import times from 'lodash/times'; import transform from 'lodash/transform'; @@ -15,10 +15,10 @@ import { ANY_OF_KEY, DEPENDENCIES_KEY, IF_KEY, + ITEMS_KEY, ONE_OF_KEY, - REF_KEY, PROPERTIES_KEY, - ITEMS_KEY, + REF_KEY, } from '../constants'; import findSchemaDefinition, { splitKeyElementFromObject } from '../findSchemaDefinition'; import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema'; @@ -196,7 +196,10 @@ export function resolveSchema(allOfSchemaElements); - return allPermutations.map((permutation) => ({ ...schema, allOf: permutation })); + return allPermutations.map((permutation) => ({ + ...schema, + allOf: permutation, + })); } // No $ref or dependencies or allOf attribute was found, returning the original schema. return [schema]; @@ -293,7 +296,7 @@ export function resolveAllReferences( }; } - return isEqual(schema, resolvedSchema) ? schema : resolvedSchema; + return fastDeepEqual(schema, resolvedSchema) ? schema : resolvedSchema; } /** Creates new 'properties' items for each key in the `formData` diff --git a/packages/utils/src/schema/toIdSchema.ts b/packages/utils/src/schema/toIdSchema.ts index 3ea196d2c6..5369062223 100644 --- a/packages/utils/src/schema/toIdSchema.ts +++ b/packages/utils/src/schema/toIdSchema.ts @@ -1,5 +1,5 @@ import get from 'lodash/get'; -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { ALL_OF_KEY, DEPENDENCIES_KEY, ID_KEY, ITEMS_KEY, PROPERTIES_KEY, REF_KEY } from '../constants'; import isObject from '../isObject'; @@ -46,7 +46,7 @@ function toIdSchemaInternal(validator, schema, rootSchema, formData); - const sameSchemaIndex = _recurseList.findIndex((item) => isEqual(item, _schema)); + const sameSchemaIndex = _recurseList.findIndex((item) => fastDeepEqual(item, _schema)); if (sameSchemaIndex === -1) { stack.push({ validator, @@ -112,7 +112,7 @@ function toIdSchemaInternal - // isEqual(item, _schema) + // fastDeepEqual(item, _schema) // ); // if (sameSchemaIndex === -1) { // return toIdSchemaInternal( diff --git a/packages/utils/src/schema/toPathSchema.ts b/packages/utils/src/schema/toPathSchema.ts index bce2da0f0e..d21f7a9655 100644 --- a/packages/utils/src/schema/toPathSchema.ts +++ b/packages/utils/src/schema/toPathSchema.ts @@ -1,5 +1,5 @@ import get from 'lodash/get'; -import isEqual from 'fast-deep-equal'; +import fastDeepEqual from 'fast-deep-equal'; import set from 'lodash/set'; import { @@ -52,7 +52,7 @@ function toPathSchemaInternal(validator, schema, rootSchema, formData); - const sameSchemaIndex = _recurseList.findIndex((item) => isEqual(item, _schema)); + const sameSchemaIndex = _recurseList.findIndex((item) => fastDeepEqual(item, _schema)); if (sameSchemaIndex === -1) { stack.push({ schema: _schema, diff --git a/packages/validator-ajv8/src/precompiledValidator.ts b/packages/validator-ajv8/src/precompiledValidator.ts index 3b201b9a90..53f4299ded 100644 --- a/packages/validator-ajv8/src/precompiledValidator.ts +++ b/packages/validator-ajv8/src/precompiledValidator.ts @@ -1,6 +1,6 @@ import { ErrorObject } from 'ajv'; import get from 'lodash/get'; -import isEqual from 'lodash/isEqual'; +import fastDeepEqual from 'fast-deep-equal'; import { CustomValidator, ErrorSchema, @@ -9,13 +9,13 @@ import { hashForSchema, ID_KEY, JUNK_OPTION_ID, + retrieveSchema, RJSFSchema, StrictRJSFSchema, toErrorList, UiSchema, ValidationData, ValidatorType, - retrieveSchema, } from '@rjsf/utils'; import { CompiledValidateFunction, Localizer, ValidatorFunctions } from './types'; @@ -92,10 +92,10 @@ export default class AJV8PrecompiledValidator< * @param [formData] - The form data to validate if any */ ensureSameRootSchema(schema: S, formData?: T) { - if (!isEqual(schema, this.rootSchema)) { + if (!fastDeepEqual(schema, this.rootSchema)) { // Resolve the root schema with the passed in form data since that may affect the resolution const resolvedRootSchema = retrieveSchema(this, this.rootSchema, this.rootSchema, formData); - if (!isEqual(schema, resolvedRootSchema)) { + if (!fastDeepEqual(schema, resolvedRootSchema)) { throw new Error( 'The schema associated with the precompiled validator differs from the rootSchema provided for validation' );