Skip to content

Commit

Permalink
Change fast-deep-equal to fast-equals
Browse files Browse the repository at this point in the history
  • Loading branch information
igorbrasileiro committed Sep 9, 2024
1 parent a7b25e8 commit 37b47c9
Show file tree
Hide file tree
Showing 13 changed files with 699 additions and 275 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@
"packages/validator-ajv6",
"packages/validator-ajv8",
"packages/snapshot-tests"
]
],
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
1 change: 1 addition & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"react": "^16.14.0 || >=17"
},
"dependencies": {
"fast-equals": "^5.0.1",
"json-schema-merge-allof": "^0.8.1",
"jsonpointer": "^5.0.1",
"lodash": "^4.17.21",
Expand Down
148 changes: 116 additions & 32 deletions packages/utils/src/createSchemaUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import deepEquals from './deepEquals';
import deepEquals from "./deepEquals";

Check failure on line 1 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `"./deepEquals"` with `'./deepEquals'`

Check failure on line 1 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `"./deepEquals"` with `'./deepEquals'`

Check failure on line 1 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `"./deepEquals"` with `'./deepEquals'`
import {
ErrorSchema,
Experimental_DefaultFormStateBehavior,
Expand All @@ -12,11 +12,11 @@ import {
UiSchema,
ValidationData,
ValidatorType,
} from './types';
} from "./types";

Check failure on line 15 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `"./types"` with `'./types'`

Check failure on line 15 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `"./types"` with `'./types'`

Check failure on line 15 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `"./types"` with `'./types'`
import {
getClosestMatchingOption,
getDefaultFormState,
getDisplayLabel,
getClosestMatchingOption,
getFirstMatchingOption,
getMatchingOption,
isFilesArray,
Expand All @@ -27,16 +27,18 @@ import {
sanitizeDataForNewSchema,
toIdSchema,
toPathSchema,
} from './schema';
} from "./schema";

Check failure on line 30 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `"./schema"` with `'./schema'`

Check failure on line 30 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `"./schema"` with `'./schema'`

Check failure on line 30 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `"./schema"` with `'./schema'`

/** The `SchemaUtils` class provides a wrapper around the publicly exported APIs in the `utils/schema` directory such
* that one does not have to explicitly pass the `validator`, `rootSchema`, or `experimental_defaultFormStateBehavior` to each method.
* Since these generally do not change across a `Form`, this allows for providing a simplified set of APIs to the
* `@rjsf/core` components and the various themes as well. This class implements the `SchemaUtilsType` interface.
*/
class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
implements SchemaUtilsType<T, S, F>
{
class SchemaUtils<

Check failure on line 37 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `⏎··T·=·any,⏎··S·extends·StrictRJSFSchema·=·RJSFSchema,⏎··F·extends·FormContextType·=·any,` with `T·=·any,·S·extends·StrictRJSFSchema·=·RJSFSchema,·F·extends·FormContextType·=·any>`

Check failure on line 37 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `⏎··T·=·any,⏎··S·extends·StrictRJSFSchema·=·RJSFSchema,⏎··F·extends·FormContextType·=·any,` with `T·=·any,·S·extends·StrictRJSFSchema·=·RJSFSchema,·F·extends·FormContextType·=·any>`

Check failure on line 37 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `⏎··T·=·any,⏎··S·extends·StrictRJSFSchema·=·RJSFSchema,⏎··F·extends·FormContextType·=·any,` with `T·=·any,·S·extends·StrictRJSFSchema·=·RJSFSchema,·F·extends·FormContextType·=·any>`
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
> implements SchemaUtilsType<T, S, F> {

Check failure on line 41 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `>·implements·SchemaUtilsType<T,·S,·F>·` with `··implements·SchemaUtilsType<T,·S,·F>⏎`

Check failure on line 41 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `>·implements·SchemaUtilsType<T,·S,·F>·` with `··implements·SchemaUtilsType<T,·S,·F>⏎`

Check failure on line 41 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `>·implements·SchemaUtilsType<T,·S,·F>·` with `··implements·SchemaUtilsType<T,·S,·F>⏎`
rootSchema: S;
validator: ValidatorType<T, S, F>;
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior;
Expand All @@ -50,11 +52,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
constructor(
validator: ValidatorType<T, S, F>,
rootSchema: S,
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior
experimental_defaultFormStateBehavior:

Check failure on line 55 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `⏎······Experimental_DefaultFormStateBehavior,` with `·Experimental_DefaultFormStateBehavior`

Check failure on line 55 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `⏎······Experimental_DefaultFormStateBehavior,` with `·Experimental_DefaultFormStateBehavior`

Check failure on line 55 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `⏎······Experimental_DefaultFormStateBehavior,` with `·Experimental_DefaultFormStateBehavior`
Experimental_DefaultFormStateBehavior,
) {
this.rootSchema = rootSchema;
this.validator = validator;
this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior;
this.experimental_defaultFormStateBehavior =

Check failure on line 60 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Delete `⏎·····`

Check failure on line 60 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Delete `⏎·····`

Check failure on line 60 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Delete `⏎·····`
experimental_defaultFormStateBehavior;
}

/** Returns the `ValidatorType` in the `SchemaUtilsType`
Expand All @@ -77,15 +81,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
doesSchemaUtilsDiffer(
validator: ValidatorType<T, S, F>,
rootSchema: S,
experimental_defaultFormStateBehavior = {}
experimental_defaultFormStateBehavior = {},

Check failure on line 84 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Delete `,`

Check failure on line 84 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Delete `,`

Check failure on line 84 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Delete `,`
): boolean {
if (!validator || !rootSchema) {
return false;
}
return (
this.validator !== validator ||
!deepEquals(this.rootSchema, rootSchema) ||
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior)
!deepEquals(

Check failure on line 92 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `⏎········this.experimental_defaultFormStateBehavior,⏎········experimental_defaultFormStateBehavior,⏎······` with `this.experimental_defaultFormStateBehavior,·experimental_defaultFormStateBehavior`

Check failure on line 92 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `⏎········this.experimental_defaultFormStateBehavior,⏎········experimental_defaultFormStateBehavior,⏎······` with `this.experimental_defaultFormStateBehavior,·experimental_defaultFormStateBehavior`

Check failure on line 92 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `⏎········this.experimental_defaultFormStateBehavior,⏎········experimental_defaultFormStateBehavior,⏎······` with `this.experimental_defaultFormStateBehavior,·experimental_defaultFormStateBehavior`
this.experimental_defaultFormStateBehavior,
experimental_defaultFormStateBehavior,
)
);
}

Expand All @@ -102,15 +109,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
getDefaultFormState(
schema: S,
formData?: T,
includeUndefinedValues: boolean | 'excludeObjectChildren' = false
includeUndefinedValues: boolean | "excludeObjectChildren" = false,

Check failure on line 112 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (14.x)

Replace `"excludeObjectChildren"·=·false,` with `'excludeObjectChildren'·=·false`

Check failure on line 112 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Replace `"excludeObjectChildren"·=·false,` with `'excludeObjectChildren'·=·false`

Check failure on line 112 in packages/utils/src/createSchemaUtils.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `"excludeObjectChildren"·=·false,` with `'excludeObjectChildren'·=·false`
): T | T[] | undefined {
return getDefaultFormState<T, S, F>(
this.validator,
schema,
formData,
this.rootSchema,
includeUndefinedValues,
this.experimental_defaultFormStateBehavior
this.experimental_defaultFormStateBehavior,
);
}

Expand All @@ -122,8 +129,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
* @returns - True if the label should be displayed or false if it should not
*/
getDisplayLabel(schema: S, uiSchema?: UiSchema<T, S, F>, globalOptions?: GlobalUISchemaOptions) {
return getDisplayLabel<T, S, F>(this.validator, schema, uiSchema, this.rootSchema, globalOptions);
getDisplayLabel(
schema: S,
uiSchema?: UiSchema<T, S, F>,
globalOptions?: GlobalUISchemaOptions,
) {
return getDisplayLabel<T, S, F>(
this.validator,
schema,
uiSchema,
this.rootSchema,
globalOptions,
);
}

/** Determines which of the given `options` provided most closely matches the `formData`.
Expand All @@ -143,15 +160,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
formData: T | undefined,
options: S[],
selectedOption?: number,
discriminatorField?: string
discriminatorField?: string,
): number {
return getClosestMatchingOption<T, S, F>(
this.validator,
this.rootSchema,
formData,
options,
selectedOption,
discriminatorField
discriminatorField,
);
}

Expand All @@ -164,8 +181,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* determine which option is selected
* @returns - The firstindex of the matched option or 0 if none is available
*/
getFirstMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string): number {
return getFirstMatchingOption<T, S, F>(this.validator, formData, options, this.rootSchema, discriminatorField);
getFirstMatchingOption(
formData: T | undefined,
options: S[],
discriminatorField?: string,
): number {
return getFirstMatchingOption<T, S, F>(
this.validator,
formData,
options,
this.rootSchema,
discriminatorField,
);
}

/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
Expand All @@ -178,8 +205,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @returns - The index of the matched option or 0 if none is available
* @deprecated
*/
getMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string) {
return getMatchingOption<T, S, F>(this.validator, formData, options, this.rootSchema, discriminatorField);
getMatchingOption(
formData: T | undefined,
options: S[],
discriminatorField?: string,
) {
return getMatchingOption<T, S, F>(
this.validator,
formData,
options,
this.rootSchema,
discriminatorField,
);
}

/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
Expand All @@ -189,7 +226,12 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @returns - True if schema/uiSchema contains an array of files, otherwise false
*/
isFilesArray(schema: S, uiSchema?: UiSchema<T, S, F>) {
return isFilesArray<T, S, F>(this.validator, schema, uiSchema, this.rootSchema);
return isFilesArray<T, S, F>(
this.validator,
schema,
uiSchema,
this.rootSchema,
);
}

/** Checks to see if the `schema` combination represents a multi-select
Expand Down Expand Up @@ -221,8 +263,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
* removed in the next major release.
*/
mergeValidationData(validationData: ValidationData<T>, additionalErrorSchema?: ErrorSchema<T>): ValidationData<T> {
return mergeValidationData<T, S, F>(this.validator, validationData, additionalErrorSchema);
mergeValidationData(
validationData: ValidationData<T>,
additionalErrorSchema?: ErrorSchema<T>,
): ValidationData<T> {
return mergeValidationData<T, S, F>(
this.validator,
validationData,
additionalErrorSchema,
);
}

/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
Expand All @@ -234,7 +283,12 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
*/
retrieveSchema(schema: S, rawFormData?: T) {
return retrieveSchema<T, S, F>(this.validator, schema, this.rootSchema, rawFormData);
return retrieveSchema<T, S, F>(
this.validator,
schema,
this.rootSchema,
rawFormData,
);
}

/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
Expand All @@ -249,7 +303,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
*/
sanitizeDataForNewSchema(newSchema?: S, oldSchema?: S, data?: any): T {
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
return sanitizeDataForNewSchema(
this.validator,
this.rootSchema,
newSchema,
oldSchema,
data,
);
}

/** Generates an `IdSchema` object for the `schema`, recursively
Expand All @@ -261,8 +321,22 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @param [idSeparator='_'] - The separator to use for the path segments in the id
* @returns - The `IdSchema` object for the `schema`
*/
toIdSchema(schema: S, id?: string | null, formData?: T, idPrefix = 'root', idSeparator = '_'): IdSchema<T> {
return toIdSchema<T, S, F>(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
toIdSchema(
schema: S,
id?: string | null,
formData?: T,
idPrefix = "root",
idSeparator = "_",
): IdSchema<T> {
return toIdSchema<T, S, F>(
this.validator,
schema,
id,
this.rootSchema,
formData,
idPrefix,
idSeparator,
);
}

/** Generates an `PathSchema` object for the `schema`, recursively
Expand All @@ -273,7 +347,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
* @returns - The `PathSchema` object for the `schema`
*/
toPathSchema(schema: S, name?: string, formData?: T): PathSchema<T> {
return toPathSchema<T, S, F>(this.validator, schema, name, this.rootSchema, formData);
return toPathSchema<T, S, F>(
this.validator,
schema,
name,
this.rootSchema,
formData,
);
}
}

Expand All @@ -288,11 +368,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
export default function createSchemaUtils<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
F extends FormContextType = any,
>(
validator: ValidatorType<T, S, F>,
rootSchema: S,
experimental_defaultFormStateBehavior = {}
experimental_defaultFormStateBehavior = {},
): SchemaUtilsType<T, S, F> {
return new SchemaUtils<T, S, F>(validator, rootSchema, experimental_defaultFormStateBehavior);
return new SchemaUtils<T, S, F>(
validator,
rootSchema,
experimental_defaultFormStateBehavior,
);
}
32 changes: 23 additions & 9 deletions packages/utils/src/deepEquals.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
import isEqualWith from 'lodash/isEqualWith';
import { createCustomEqual, State } from 'fast-equals';

function isFunctions(a: any, b: any) {
return typeof a === 'function' && typeof b === 'function';
}

const customDeepEqual = createCustomEqual({
createInternalComparator: (comparator: (a: any, b: any, state: State<any>) => boolean) => {
return (a: any, b: any, _idxA: any, _idxB: any, _parentA: any, _parentB: any, state: State<any>) => {
if (isFunctions(a, b)) {
// Assume all functions are equivalent
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
return true;
}

return comparator(a, b, state);
};
},
});

/** Implements a deep equals using the `lodash.isEqualWith` function, that provides a customized comparator that
* assumes all functions are equivalent.
Expand All @@ -8,12 +26,8 @@ import isEqualWith from 'lodash/isEqualWith';
* @returns - True if the `a` and `b` are deeply equal, false otherwise
*/
export default function deepEquals(a: any, b: any): boolean {
return isEqualWith(a, b, (obj: any, other: any) => {
if (typeof obj === 'function' && typeof other === 'function') {
// Assume all functions are equivalent
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
return true;
}
return undefined; // fallback to default isEquals behavior
});
if (isFunctions(a, b)) {
return true;
}
return customDeepEqual(a, b);
}
Loading

0 comments on commit 37b47c9

Please sign in to comment.