Skip to content

Commit 37b47c9

Browse files
Change fast-deep-equal to fast-equals
1 parent a7b25e8 commit 37b47c9

13 files changed

+699
-275
lines changed

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,6 @@
7979
"packages/validator-ajv6",
8080
"packages/validator-ajv8",
8181
"packages/snapshot-tests"
82-
]
82+
],
83+
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
8384
}

packages/utils/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"react": "^16.14.0 || >=17"
3737
},
3838
"dependencies": {
39+
"fast-equals": "^5.0.1",
3940
"json-schema-merge-allof": "^0.8.1",
4041
"jsonpointer": "^5.0.1",
4142
"lodash": "^4.17.21",

packages/utils/src/createSchemaUtils.ts

Lines changed: 116 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import deepEquals from './deepEquals';
1+
import deepEquals from "./deepEquals";
22
import {
33
ErrorSchema,
44
Experimental_DefaultFormStateBehavior,
@@ -12,11 +12,11 @@ import {
1212
UiSchema,
1313
ValidationData,
1414
ValidatorType,
15-
} from './types';
15+
} from "./types";
1616
import {
17+
getClosestMatchingOption,
1718
getDefaultFormState,
1819
getDisplayLabel,
19-
getClosestMatchingOption,
2020
getFirstMatchingOption,
2121
getMatchingOption,
2222
isFilesArray,
@@ -27,16 +27,18 @@ import {
2727
sanitizeDataForNewSchema,
2828
toIdSchema,
2929
toPathSchema,
30-
} from './schema';
30+
} from "./schema";
3131

3232
/** The `SchemaUtils` class provides a wrapper around the publicly exported APIs in the `utils/schema` directory such
3333
* that one does not have to explicitly pass the `validator`, `rootSchema`, or `experimental_defaultFormStateBehavior` to each method.
3434
* Since these generally do not change across a `Form`, this allows for providing a simplified set of APIs to the
3535
* `@rjsf/core` components and the various themes as well. This class implements the `SchemaUtilsType` interface.
3636
*/
37-
class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
38-
implements SchemaUtilsType<T, S, F>
39-
{
37+
class SchemaUtils<
38+
T = any,
39+
S extends StrictRJSFSchema = RJSFSchema,
40+
F extends FormContextType = any,
41+
> implements SchemaUtilsType<T, S, F> {
4042
rootSchema: S;
4143
validator: ValidatorType<T, S, F>;
4244
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior;
@@ -50,11 +52,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
5052
constructor(
5153
validator: ValidatorType<T, S, F>,
5254
rootSchema: S,
53-
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior
55+
experimental_defaultFormStateBehavior:
56+
Experimental_DefaultFormStateBehavior,
5457
) {
5558
this.rootSchema = rootSchema;
5659
this.validator = validator;
57-
this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior;
60+
this.experimental_defaultFormStateBehavior =
61+
experimental_defaultFormStateBehavior;
5862
}
5963

6064
/** Returns the `ValidatorType` in the `SchemaUtilsType`
@@ -77,15 +81,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
7781
doesSchemaUtilsDiffer(
7882
validator: ValidatorType<T, S, F>,
7983
rootSchema: S,
80-
experimental_defaultFormStateBehavior = {}
84+
experimental_defaultFormStateBehavior = {},
8185
): boolean {
8286
if (!validator || !rootSchema) {
8387
return false;
8488
}
8589
return (
8690
this.validator !== validator ||
8791
!deepEquals(this.rootSchema, rootSchema) ||
88-
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior)
92+
!deepEquals(
93+
this.experimental_defaultFormStateBehavior,
94+
experimental_defaultFormStateBehavior,
95+
)
8996
);
9097
}
9198

@@ -102,15 +109,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
102109
getDefaultFormState(
103110
schema: S,
104111
formData?: T,
105-
includeUndefinedValues: boolean | 'excludeObjectChildren' = false
112+
includeUndefinedValues: boolean | "excludeObjectChildren" = false,
106113
): T | T[] | undefined {
107114
return getDefaultFormState<T, S, F>(
108115
this.validator,
109116
schema,
110117
formData,
111118
this.rootSchema,
112119
includeUndefinedValues,
113-
this.experimental_defaultFormStateBehavior
120+
this.experimental_defaultFormStateBehavior,
114121
);
115122
}
116123

@@ -122,8 +129,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
122129
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
123130
* @returns - True if the label should be displayed or false if it should not
124131
*/
125-
getDisplayLabel(schema: S, uiSchema?: UiSchema<T, S, F>, globalOptions?: GlobalUISchemaOptions) {
126-
return getDisplayLabel<T, S, F>(this.validator, schema, uiSchema, this.rootSchema, globalOptions);
132+
getDisplayLabel(
133+
schema: S,
134+
uiSchema?: UiSchema<T, S, F>,
135+
globalOptions?: GlobalUISchemaOptions,
136+
) {
137+
return getDisplayLabel<T, S, F>(
138+
this.validator,
139+
schema,
140+
uiSchema,
141+
this.rootSchema,
142+
globalOptions,
143+
);
127144
}
128145

129146
/** Determines which of the given `options` provided most closely matches the `formData`.
@@ -143,15 +160,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
143160
formData: T | undefined,
144161
options: S[],
145162
selectedOption?: number,
146-
discriminatorField?: string
163+
discriminatorField?: string,
147164
): number {
148165
return getClosestMatchingOption<T, S, F>(
149166
this.validator,
150167
this.rootSchema,
151168
formData,
152169
options,
153170
selectedOption,
154-
discriminatorField
171+
discriminatorField,
155172
);
156173
}
157174

@@ -164,8 +181,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
164181
* determine which option is selected
165182
* @returns - The firstindex of the matched option or 0 if none is available
166183
*/
167-
getFirstMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string): number {
168-
return getFirstMatchingOption<T, S, F>(this.validator, formData, options, this.rootSchema, discriminatorField);
184+
getFirstMatchingOption(
185+
formData: T | undefined,
186+
options: S[],
187+
discriminatorField?: string,
188+
): number {
189+
return getFirstMatchingOption<T, S, F>(
190+
this.validator,
191+
formData,
192+
options,
193+
this.rootSchema,
194+
discriminatorField,
195+
);
169196
}
170197

171198
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
@@ -178,8 +205,18 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
178205
* @returns - The index of the matched option or 0 if none is available
179206
* @deprecated
180207
*/
181-
getMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string) {
182-
return getMatchingOption<T, S, F>(this.validator, formData, options, this.rootSchema, discriminatorField);
208+
getMatchingOption(
209+
formData: T | undefined,
210+
options: S[],
211+
discriminatorField?: string,
212+
) {
213+
return getMatchingOption<T, S, F>(
214+
this.validator,
215+
formData,
216+
options,
217+
this.rootSchema,
218+
discriminatorField,
219+
);
183220
}
184221

185222
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
@@ -189,7 +226,12 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
189226
* @returns - True if schema/uiSchema contains an array of files, otherwise false
190227
*/
191228
isFilesArray(schema: S, uiSchema?: UiSchema<T, S, F>) {
192-
return isFilesArray<T, S, F>(this.validator, schema, uiSchema, this.rootSchema);
229+
return isFilesArray<T, S, F>(
230+
this.validator,
231+
schema,
232+
uiSchema,
233+
this.rootSchema,
234+
);
193235
}
194236

195237
/** Checks to see if the `schema` combination represents a multi-select
@@ -221,8 +263,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
221263
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
222264
* removed in the next major release.
223265
*/
224-
mergeValidationData(validationData: ValidationData<T>, additionalErrorSchema?: ErrorSchema<T>): ValidationData<T> {
225-
return mergeValidationData<T, S, F>(this.validator, validationData, additionalErrorSchema);
266+
mergeValidationData(
267+
validationData: ValidationData<T>,
268+
additionalErrorSchema?: ErrorSchema<T>,
269+
): ValidationData<T> {
270+
return mergeValidationData<T, S, F>(
271+
this.validator,
272+
validationData,
273+
additionalErrorSchema,
274+
);
226275
}
227276

228277
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
@@ -234,7 +283,12 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
234283
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
235284
*/
236285
retrieveSchema(schema: S, rawFormData?: T) {
237-
return retrieveSchema<T, S, F>(this.validator, schema, this.rootSchema, rawFormData);
286+
return retrieveSchema<T, S, F>(
287+
this.validator,
288+
schema,
289+
this.rootSchema,
290+
rawFormData,
291+
);
238292
}
239293

240294
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
@@ -249,7 +303,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
249303
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
250304
*/
251305
sanitizeDataForNewSchema(newSchema?: S, oldSchema?: S, data?: any): T {
252-
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
306+
return sanitizeDataForNewSchema(
307+
this.validator,
308+
this.rootSchema,
309+
newSchema,
310+
oldSchema,
311+
data,
312+
);
253313
}
254314

255315
/** Generates an `IdSchema` object for the `schema`, recursively
@@ -261,8 +321,22 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
261321
* @param [idSeparator='_'] - The separator to use for the path segments in the id
262322
* @returns - The `IdSchema` object for the `schema`
263323
*/
264-
toIdSchema(schema: S, id?: string | null, formData?: T, idPrefix = 'root', idSeparator = '_'): IdSchema<T> {
265-
return toIdSchema<T, S, F>(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
324+
toIdSchema(
325+
schema: S,
326+
id?: string | null,
327+
formData?: T,
328+
idPrefix = "root",
329+
idSeparator = "_",
330+
): IdSchema<T> {
331+
return toIdSchema<T, S, F>(
332+
this.validator,
333+
schema,
334+
id,
335+
this.rootSchema,
336+
formData,
337+
idPrefix,
338+
idSeparator,
339+
);
266340
}
267341

268342
/** Generates an `PathSchema` object for the `schema`, recursively
@@ -273,7 +347,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
273347
* @returns - The `PathSchema` object for the `schema`
274348
*/
275349
toPathSchema(schema: S, name?: string, formData?: T): PathSchema<T> {
276-
return toPathSchema<T, S, F>(this.validator, schema, name, this.rootSchema, formData);
350+
return toPathSchema<T, S, F>(
351+
this.validator,
352+
schema,
353+
name,
354+
this.rootSchema,
355+
formData,
356+
);
277357
}
278358
}
279359

@@ -288,11 +368,15 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
288368
export default function createSchemaUtils<
289369
T = any,
290370
S extends StrictRJSFSchema = RJSFSchema,
291-
F extends FormContextType = any
371+
F extends FormContextType = any,
292372
>(
293373
validator: ValidatorType<T, S, F>,
294374
rootSchema: S,
295-
experimental_defaultFormStateBehavior = {}
375+
experimental_defaultFormStateBehavior = {},
296376
): SchemaUtilsType<T, S, F> {
297-
return new SchemaUtils<T, S, F>(validator, rootSchema, experimental_defaultFormStateBehavior);
377+
return new SchemaUtils<T, S, F>(
378+
validator,
379+
rootSchema,
380+
experimental_defaultFormStateBehavior,
381+
);
298382
}

packages/utils/src/deepEquals.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
import isEqualWith from 'lodash/isEqualWith';
1+
import { createCustomEqual, State } from 'fast-equals';
2+
3+
function isFunctions(a: any, b: any) {
4+
return typeof a === 'function' && typeof b === 'function';
5+
}
6+
7+
const customDeepEqual = createCustomEqual({
8+
createInternalComparator: (comparator: (a: any, b: any, state: State<any>) => boolean) => {
9+
return (a: any, b: any, _idxA: any, _idxB: any, _parentA: any, _parentB: any, state: State<any>) => {
10+
if (isFunctions(a, b)) {
11+
// Assume all functions are equivalent
12+
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
13+
return true;
14+
}
15+
16+
return comparator(a, b, state);
17+
};
18+
},
19+
});
220

321
/** Implements a deep equals using the `lodash.isEqualWith` function, that provides a customized comparator that
422
* assumes all functions are equivalent.
@@ -8,12 +26,8 @@ import isEqualWith from 'lodash/isEqualWith';
826
* @returns - True if the `a` and `b` are deeply equal, false otherwise
927
*/
1028
export default function deepEquals(a: any, b: any): boolean {
11-
return isEqualWith(a, b, (obj: any, other: any) => {
12-
if (typeof obj === 'function' && typeof other === 'function') {
13-
// Assume all functions are equivalent
14-
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
15-
return true;
16-
}
17-
return undefined; // fallback to default isEquals behavior
18-
});
29+
if (isFunctions(a, b)) {
30+
return true;
31+
}
32+
return customDeepEqual(a, b);
1933
}

0 commit comments

Comments
 (0)