@rjsf/utils 5.23.1 → 5.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/index.js +223 -133
  2. package/dist/index.js.map +4 -4
  3. package/dist/utils.esm.js +223 -133
  4. package/dist/utils.esm.js.map +4 -4
  5. package/dist/utils.umd.js +215 -125
  6. package/lib/constIsAjvDataReference.d.ts +9 -0
  7. package/lib/constIsAjvDataReference.js +15 -0
  8. package/lib/constIsAjvDataReference.js.map +1 -0
  9. package/lib/enumOptionsDeselectValue.js +3 -3
  10. package/lib/enumOptionsDeselectValue.js.map +1 -1
  11. package/lib/enumOptionsIsSelected.js +3 -3
  12. package/lib/enumOptionsIsSelected.js.map +1 -1
  13. package/lib/getChangedFields.d.ts +17 -0
  14. package/lib/getChangedFields.js +42 -0
  15. package/lib/getChangedFields.js.map +1 -0
  16. package/lib/index.d.ts +2 -1
  17. package/lib/index.js +2 -1
  18. package/lib/index.js.map +1 -1
  19. package/lib/isObject.d.ts +1 -1
  20. package/lib/isObject.js +11 -4
  21. package/lib/isObject.js.map +1 -1
  22. package/lib/mergeDefaultsWithFormData.d.ts +5 -1
  23. package/lib/mergeDefaultsWithFormData.js +31 -8
  24. package/lib/mergeDefaultsWithFormData.js.map +1 -1
  25. package/lib/parser/ParserValidator.js +3 -3
  26. package/lib/parser/ParserValidator.js.map +1 -1
  27. package/lib/parser/schemaParser.js +4 -4
  28. package/lib/parser/schemaParser.js.map +1 -1
  29. package/lib/schema/getDefaultFormState.d.ts +17 -2
  30. package/lib/schema/getDefaultFormState.js +85 -31
  31. package/lib/schema/getDefaultFormState.js.map +1 -1
  32. package/lib/schema/retrieveSchema.js +7 -4
  33. package/lib/schema/retrieveSchema.js.map +1 -1
  34. package/lib/schema/toIdSchema.js +2 -2
  35. package/lib/schema/toIdSchema.js.map +1 -1
  36. package/lib/schema/toPathSchema.js +3 -3
  37. package/lib/schema/toPathSchema.js.map +1 -1
  38. package/lib/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +2 -2
  40. package/src/constIsAjvDataReference.ts +17 -0
  41. package/src/enumOptionsDeselectValue.ts +3 -4
  42. package/src/enumOptionsIsSelected.ts +3 -4
  43. package/src/getChangedFields.ts +40 -0
  44. package/src/index.ts +2 -0
  45. package/src/isObject.ts +11 -4
  46. package/src/mergeDefaultsWithFormData.ts +42 -10
  47. package/src/parser/ParserValidator.ts +3 -3
  48. package/src/parser/schemaParser.ts +4 -4
  49. package/src/schema/getDefaultFormState.ts +126 -31
  50. package/src/schema/retrieveSchema.ts +8 -5
  51. package/src/schema/toIdSchema.ts +2 -2
  52. package/src/schema/toPathSchema.ts +3 -3
package/dist/utils.umd.js CHANGED
@@ -1,18 +1,21 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('lodash/isPlainObject'), require('lodash/isEqualWith'), require('lodash/get'), require('lodash/isEmpty'), require('jsonpointer'), require('lodash/omit'), require('lodash/has'), require('lodash/isNumber'), require('lodash/isObject'), require('lodash/isString'), require('lodash/reduce'), require('lodash/times'), require('lodash/isEqual'), require('lodash/set'), require('lodash/transform'), require('lodash/merge'), require('lodash/flattenDeep'), require('lodash/uniq'), require('json-schema-merge-allof'), require('lodash/union'), require('lodash/isNil'), require('lodash/cloneDeep'), require('lodash/setWith'), require('react'), require('react-is'), require('react/jsx-runtime'), require('lodash/toPath'), require('lodash/forEach')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'lodash/isPlainObject', 'lodash/isEqualWith', 'lodash/get', 'lodash/isEmpty', 'jsonpointer', 'lodash/omit', 'lodash/has', 'lodash/isNumber', 'lodash/isObject', 'lodash/isString', 'lodash/reduce', 'lodash/times', 'lodash/isEqual', 'lodash/set', 'lodash/transform', 'lodash/merge', 'lodash/flattenDeep', 'lodash/uniq', 'json-schema-merge-allof', 'lodash/union', 'lodash/isNil', 'lodash/cloneDeep', 'lodash/setWith', 'react', 'react-is', 'react/jsx-runtime', 'lodash/toPath', 'lodash/forEach'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@rjsf/utils"] = {}, global.isPlainObject, global.isEqualWith, global.get8, global.isEmpty, global.jsonpointer, global.omit, global.has3, global.isNumber, global.isObject2, global.isString, global.reduce, global.times, global.isEqual4, global.set3, global.transform, global.merge, global.flattenDeep, global.uniq, global.mergeAllOf, global.union, global.isNil, global.cloneDeep, global.setWith, global.react, global.ReactIs, global.jsxRuntime, global.toPath, global.forEach));
5
- })(this, (function (exports, isPlainObject, isEqualWith, get8, isEmpty, jsonpointer, omit, has3, isNumber, isObject2, isString, reduce, times, isEqual4, set3, transform, merge, flattenDeep, uniq, mergeAllOf, union, isNil, cloneDeep, setWith, react, ReactIs, jsxRuntime, toPath, forEach) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('lodash/isPlainObject'), require('lodash/isEqualWith'), require('lodash/get'), require('lodash/isEmpty'), require('jsonpointer'), require('lodash/omit'), require('lodash/has'), require('lodash/isNumber'), require('lodash/isObject'), require('lodash/isString'), require('lodash/reduce'), require('lodash/times'), require('lodash/set'), require('lodash/transform'), require('lodash/merge'), require('lodash/flattenDeep'), require('lodash/uniq'), require('json-schema-merge-allof'), require('lodash/union'), require('lodash/isNil'), require('lodash/cloneDeep'), require('lodash/setWith'), require('react'), require('react-is'), require('react/jsx-runtime'), require('lodash/toPath'), require('lodash/keys'), require('lodash/pickBy'), require('lodash/difference'), require('lodash/forEach')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'lodash/isPlainObject', 'lodash/isEqualWith', 'lodash/get', 'lodash/isEmpty', 'jsonpointer', 'lodash/omit', 'lodash/has', 'lodash/isNumber', 'lodash/isObject', 'lodash/isString', 'lodash/reduce', 'lodash/times', 'lodash/set', 'lodash/transform', 'lodash/merge', 'lodash/flattenDeep', 'lodash/uniq', 'json-schema-merge-allof', 'lodash/union', 'lodash/isNil', 'lodash/cloneDeep', 'lodash/setWith', 'react', 'react-is', 'react/jsx-runtime', 'lodash/toPath', 'lodash/keys', 'lodash/pickBy', 'lodash/difference', 'lodash/forEach'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@rjsf/utils"] = {}, global.isPlainObject4, global.isEqualWith, global.get8, global.isEmpty, global.jsonpointer, global.omit, global.has3, global.isNumber, global.isObject2, global.isString, global.reduce, global.times, global.set3, global.transform, global.merge, global.flattenDeep, global.uniq, global.mergeAllOf, global.union, global.isNil, global.cloneDeep, global.setWith, global.react, global.ReactIs, global.jsxRuntime, global.toPath, global.keys, global.pickBy, global.difference, global.forEach));
5
+ })(this, (function (exports, isPlainObject4, isEqualWith, get8, isEmpty, jsonpointer, omit, has3, isNumber, isObject2, isString, reduce, times, set3, transform, merge, flattenDeep, uniq, mergeAllOf, union, isNil, cloneDeep, setWith, react, ReactIs, jsxRuntime, toPath, keys, pickBy, difference, forEach) { 'use strict';
6
6
 
7
7
  // src/isObject.ts
8
8
  function isObject(thing) {
9
- if (typeof File !== "undefined" && thing instanceof File) {
9
+ if (typeof thing !== "object" || thing === null) {
10
10
  return false;
11
11
  }
12
- if (typeof Date !== "undefined" && thing instanceof Date) {
12
+ if (typeof thing.lastModified === "number" && typeof File !== "undefined" && thing instanceof File) {
13
13
  return false;
14
14
  }
15
- return typeof thing === "object" && thing !== null && !Array.isArray(thing);
15
+ if (typeof thing.getMonth === "function" && typeof Date !== "undefined" && thing instanceof Date) {
16
+ return false;
17
+ }
18
+ return !Array.isArray(thing);
16
19
  }
17
20
 
18
21
  // src/allowAdditionalItems.ts
@@ -121,7 +124,7 @@
121
124
  return { ...acc, [key]: createErrorHandler(value) };
122
125
  }, handler);
123
126
  }
124
- if (isPlainObject(formData)) {
127
+ if (isPlainObject4(formData)) {
125
128
  const formObject = formData;
126
129
  return Object.keys(formObject).reduce((acc, key) => {
127
130
  return { ...acc, [key]: createErrorHandler(formObject[key]) };
@@ -458,7 +461,10 @@
458
461
  )
459
462
  );
460
463
  const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
461
- return allPermutations.map((permutation) => ({ ...schema, allOf: permutation }));
464
+ return allPermutations.map((permutation) => ({
465
+ ...schema,
466
+ allOf: permutation
467
+ }));
462
468
  }
463
469
  return [schema];
464
470
  }
@@ -511,7 +517,7 @@
511
517
  items: resolveAllReferences(resolvedSchema.items, rootSchema, recurseList)
512
518
  };
513
519
  }
514
- return isEqual4(schema, resolvedSchema) ? schema : resolvedSchema;
520
+ return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema;
515
521
  }
516
522
  function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData, experimental_customMergeAllOf) {
517
523
  const schema = {
@@ -911,38 +917,47 @@
911
917
  function isFixedItems(schema) {
912
918
  return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every((item) => isObject(item));
913
919
  }
914
- function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false) {
920
+ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false, overrideFormDataWithDefaults = false) {
915
921
  if (Array.isArray(formData)) {
916
922
  const defaultsArray = Array.isArray(defaults) ? defaults : [];
917
- const mapped = formData.map((value, idx) => {
918
- if (defaultsArray[idx]) {
923
+ const overrideArray = overrideFormDataWithDefaults ? defaultsArray : formData;
924
+ const overrideOppositeArray = overrideFormDataWithDefaults ? formData : defaultsArray;
925
+ const mapped = overrideArray.map((value, idx) => {
926
+ if (overrideOppositeArray[idx]) {
919
927
  return mergeDefaultsWithFormData(
920
928
  defaultsArray[idx],
921
- value,
929
+ formData[idx],
922
930
  mergeExtraArrayDefaults,
923
- defaultSupercedesUndefined
931
+ defaultSupercedesUndefined,
932
+ overrideFormDataWithDefaults
924
933
  );
925
934
  }
926
935
  return value;
927
936
  });
928
- if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
929
- mapped.push(...defaultsArray.slice(mapped.length));
937
+ if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) {
938
+ mapped.push(...overrideOppositeArray.slice(mapped.length));
930
939
  }
931
940
  return mapped;
932
941
  }
933
942
  if (isObject(formData)) {
934
943
  const acc = Object.assign({}, defaults);
935
944
  return Object.keys(formData).reduce((acc2, key) => {
945
+ const keyValue = get8(formData, key);
946
+ const keyExistsInDefaults = isObject(defaults) && key in defaults;
947
+ const keyExistsInFormData = key in formData;
936
948
  acc2[key] = mergeDefaultsWithFormData(
937
949
  defaults ? get8(defaults, key) : {},
938
- get8(formData, key),
950
+ keyValue,
939
951
  mergeExtraArrayDefaults,
940
- defaultSupercedesUndefined
952
+ defaultSupercedesUndefined,
953
+ // overrideFormDataWithDefaults can be true only when the key value exists in defaults
954
+ // Or if the key value doesn't exist in formData
955
+ overrideFormDataWithDefaults && (keyExistsInDefaults || !keyExistsInFormData)
941
956
  );
942
957
  return acc2;
943
958
  }, acc);
944
959
  }
945
- if (defaultSupercedesUndefined && formData === void 0) {
960
+ if (defaultSupercedesUndefined && (!isNil(defaults) && isNil(formData) || typeof formData === "number" && isNaN(formData)) || overrideFormDataWithDefaults && !isNil(formData)) {
946
961
  return defaults;
947
962
  }
948
963
  return formData;
@@ -997,6 +1012,66 @@
997
1012
  }
998
1013
  return isSelect(validator, schema.items, rootSchema, experimental_customMergeAllOf);
999
1014
  }
1015
+ function constIsAjvDataReference(schema) {
1016
+ const schemaConst = schema[CONST_KEY];
1017
+ const schemaType = getSchemaType(schema);
1018
+ return isObject(schemaConst) && isString(schemaConst?.$data) && schemaType !== "object" && schemaType !== "array";
1019
+ }
1020
+
1021
+ // src/toConstant.ts
1022
+ function toConstant(schema) {
1023
+ if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
1024
+ return schema.enum[0];
1025
+ }
1026
+ if (CONST_KEY in schema) {
1027
+ return schema.const;
1028
+ }
1029
+ throw new Error("schema cannot be inferred as a constant");
1030
+ }
1031
+
1032
+ // src/optionsList.ts
1033
+ function optionsList(schema, uiSchema) {
1034
+ const schemaWithEnumNames = schema;
1035
+ if (schema.enum) {
1036
+ let enumNames;
1037
+ if (uiSchema) {
1038
+ const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
1039
+ enumNames = uiEnumNames;
1040
+ }
1041
+ if (!enumNames && schemaWithEnumNames.enumNames) {
1042
+ {
1043
+ console.warn(
1044
+ 'The "enumNames" property in the schema is deprecated and will be removed in a future major release. Use the "ui:enumNames" property in the uiSchema instead.'
1045
+ );
1046
+ }
1047
+ enumNames = schemaWithEnumNames.enumNames;
1048
+ }
1049
+ return schema.enum.map((value, i) => {
1050
+ const label = enumNames?.[i] || String(value);
1051
+ return { label, value };
1052
+ });
1053
+ }
1054
+ let altSchemas = void 0;
1055
+ let altUiSchemas = void 0;
1056
+ if (schema.anyOf) {
1057
+ altSchemas = schema.anyOf;
1058
+ altUiSchemas = uiSchema?.anyOf;
1059
+ } else if (schema.oneOf) {
1060
+ altSchemas = schema.oneOf;
1061
+ altUiSchemas = uiSchema?.oneOf;
1062
+ }
1063
+ return altSchemas && altSchemas.map((aSchemaDef, index) => {
1064
+ const { title } = getUiOptions(altUiSchemas?.[index]);
1065
+ const aSchema = aSchemaDef;
1066
+ const value = toConstant(aSchema);
1067
+ const label = title || aSchema.title || String(value);
1068
+ return {
1069
+ schema: aSchema,
1070
+ label,
1071
+ value
1072
+ };
1073
+ });
1074
+ }
1000
1075
 
1001
1076
  // src/schema/getDefaultFormState.ts
1002
1077
  var PRIMITIVE_TYPES = ["string", "number", "integer", "boolean", "null"];
@@ -1021,8 +1096,8 @@
1021
1096
  if (includeUndefinedValues || isConst) {
1022
1097
  obj[key] = computedDefault;
1023
1098
  } else if (emptyObjectFields !== "skipDefaults") {
1099
+ const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1024
1100
  if (isObject(computedDefault)) {
1025
- const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1026
1101
  if (emptyObjectFields === "skipEmptyDefaults") {
1027
1102
  if (!isEmpty(computedDefault)) {
1028
1103
  obj[key] = computedDefault;
@@ -1033,8 +1108,9 @@
1033
1108
  } else if (
1034
1109
  // Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
1035
1110
  // Condition 1: computedDefault is not undefined
1036
- // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults) or if the key is a required field
1037
- computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || requiredFields.includes(key))
1111
+ // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults)
1112
+ // Or if isSelfOrParentRequired is 'true' and the key is a required field
1113
+ computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || isSelfOrParentRequired && requiredFields.includes(key))
1038
1114
  ) {
1039
1115
  obj[key] = computedDefault;
1040
1116
  }
@@ -1049,7 +1125,8 @@
1049
1125
  _recurseList = [],
1050
1126
  experimental_defaultFormStateBehavior = void 0,
1051
1127
  experimental_customMergeAllOf = void 0,
1052
- required
1128
+ required,
1129
+ shouldMergeDefaultsIntoFormData = false
1053
1130
  } = computeDefaultsProps;
1054
1131
  const formData = isObject(rawFormData) ? rawFormData : {};
1055
1132
  const schema = isObject(rawSchema) ? rawSchema : {};
@@ -1057,8 +1134,8 @@
1057
1134
  let schemaToCompute = null;
1058
1135
  let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
1059
1136
  let updatedRecurseList = _recurseList;
1060
- if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never") {
1061
- defaults = schema.const;
1137
+ if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(schema)) {
1138
+ defaults = schema[CONST_KEY];
1062
1139
  } else if (isObject(defaults) && isObject(schema.default)) {
1063
1140
  defaults = mergeObjects(defaults, schema.default);
1064
1141
  } else if (DEFAULT_KEY in schema) {
@@ -1094,7 +1171,8 @@
1094
1171
  experimental_customMergeAllOf,
1095
1172
  parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : void 0,
1096
1173
  rawFormData: formData,
1097
- required
1174
+ required,
1175
+ shouldMergeDefaultsIntoFormData
1098
1176
  })
1099
1177
  );
1100
1178
  } else if (ONE_OF_KEY in schema) {
@@ -1105,12 +1183,15 @@
1105
1183
  const discriminator = getDiscriminatorFieldFromSchema(schema);
1106
1184
  const { type = "null" } = remaining;
1107
1185
  if (!Array.isArray(type) && PRIMITIVE_TYPES.includes(type) && experimental_dfsb_to_compute?.constAsDefaults === "skipOneOf") {
1108
- experimental_dfsb_to_compute = { ...experimental_dfsb_to_compute, constAsDefaults: "never" };
1186
+ experimental_dfsb_to_compute = {
1187
+ ...experimental_dfsb_to_compute,
1188
+ constAsDefaults: "never"
1189
+ };
1109
1190
  }
1110
1191
  schemaToCompute = oneOf[getClosestMatchingOption(
1111
1192
  validator,
1112
1193
  rootSchema,
1113
- isEmpty(formData) ? void 0 : formData,
1194
+ rawFormData,
1114
1195
  oneOf,
1115
1196
  0,
1116
1197
  discriminator,
@@ -1126,7 +1207,7 @@
1126
1207
  schemaToCompute = anyOf[getClosestMatchingOption(
1127
1208
  validator,
1128
1209
  rootSchema,
1129
- isEmpty(formData) ? void 0 : formData,
1210
+ rawFormData,
1130
1211
  anyOf,
1131
1212
  0,
1132
1213
  discriminator,
@@ -1143,14 +1224,49 @@
1143
1224
  experimental_customMergeAllOf,
1144
1225
  parentDefaults: defaults,
1145
1226
  rawFormData: formData,
1146
- required
1227
+ required,
1228
+ shouldMergeDefaultsIntoFormData
1147
1229
  });
1148
1230
  }
1149
1231
  if (defaults === void 0) {
1150
1232
  defaults = schema.default;
1151
1233
  }
1152
1234
  const defaultBasedOnSchemaType = getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults);
1153
- return defaultBasedOnSchemaType ?? defaults;
1235
+ let defaultsWithFormData = defaultBasedOnSchemaType ?? defaults;
1236
+ if (shouldMergeDefaultsIntoFormData) {
1237
+ const { arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1238
+ const { mergeExtraDefaults } = arrayMinItems;
1239
+ const matchingFormData = ensureFormDataMatchingSchema(
1240
+ validator,
1241
+ schema,
1242
+ rootSchema,
1243
+ rawFormData,
1244
+ experimental_defaultFormStateBehavior
1245
+ );
1246
+ if (!isObject(rawFormData)) {
1247
+ defaultsWithFormData = mergeDefaultsWithFormData(
1248
+ defaultsWithFormData,
1249
+ matchingFormData,
1250
+ mergeExtraDefaults,
1251
+ true
1252
+ );
1253
+ }
1254
+ }
1255
+ return defaultsWithFormData;
1256
+ }
1257
+ function ensureFormDataMatchingSchema(validator, schema, rootSchema, formData, experimental_defaultFormStateBehavior) {
1258
+ const isSelectField = !isConstant(schema) && isSelect(validator, schema, rootSchema);
1259
+ let validFormData = formData;
1260
+ if (isSelectField) {
1261
+ const getOptionsList = optionsList(schema);
1262
+ const isValid = getOptionsList?.some((option) => deepEquals(option.value, formData));
1263
+ validFormData = isValid ? formData : void 0;
1264
+ }
1265
+ const constTakesPrecedence = schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults === "always";
1266
+ if (constTakesPrecedence) {
1267
+ validFormData = schema.const;
1268
+ }
1269
+ return validFormData;
1154
1270
  }
1155
1271
  function getObjectDefaults(validator, rawSchema, {
1156
1272
  rawFormData,
@@ -1159,7 +1275,8 @@
1159
1275
  _recurseList = [],
1160
1276
  experimental_defaultFormStateBehavior = void 0,
1161
1277
  experimental_customMergeAllOf = void 0,
1162
- required
1278
+ required,
1279
+ shouldMergeDefaultsIntoFormData
1163
1280
  } = {}, defaults) {
1164
1281
  {
1165
1282
  const formData = isObject(rawFormData) ? rawFormData : {};
@@ -1170,7 +1287,7 @@
1170
1287
  (acc, key) => {
1171
1288
  const propertySchema = get8(retrievedSchema, [PROPERTIES_KEY, key]);
1172
1289
  const hasParentConst = isObject(parentConst) && parentConst[key] !== void 0;
1173
- const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never";
1290
+ const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(propertySchema);
1174
1291
  const computedDefault = computeDefaults(validator, propertySchema, {
1175
1292
  rootSchema,
1176
1293
  _recurseList,
@@ -1179,7 +1296,8 @@
1179
1296
  includeUndefinedValues: includeUndefinedValues === true,
1180
1297
  parentDefaults: get8(defaults, [key]),
1181
1298
  rawFormData: get8(formData, [key]),
1182
- required: retrievedSchema.required?.includes(key)
1299
+ required: retrievedSchema.required?.includes(key),
1300
+ shouldMergeDefaultsIntoFormData
1183
1301
  });
1184
1302
  maybeAddDefaultToObject(
1185
1303
  acc,
@@ -1197,16 +1315,16 @@
1197
1315
  );
1198
1316
  if (retrievedSchema.additionalProperties) {
1199
1317
  const additionalPropertiesSchema = isObject(retrievedSchema.additionalProperties) ? retrievedSchema.additionalProperties : {};
1200
- const keys = /* @__PURE__ */ new Set();
1318
+ const keys2 = /* @__PURE__ */ new Set();
1201
1319
  if (isObject(defaults)) {
1202
- Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys.add(key));
1320
+ Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys2.add(key));
1203
1321
  }
1204
1322
  const formDataRequired = [];
1205
1323
  Object.keys(formData).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => {
1206
- keys.add(key);
1324
+ keys2.add(key);
1207
1325
  formDataRequired.push(key);
1208
1326
  });
1209
- keys.forEach((key) => {
1327
+ keys2.forEach((key) => {
1210
1328
  const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
1211
1329
  rootSchema,
1212
1330
  _recurseList,
@@ -1215,7 +1333,8 @@
1215
1333
  includeUndefinedValues: includeUndefinedValues === true,
1216
1334
  parentDefaults: get8(defaults, [key]),
1217
1335
  rawFormData: get8(formData, [key]),
1218
- required: retrievedSchema.required?.includes(key)
1336
+ required: retrievedSchema.required?.includes(key),
1337
+ shouldMergeDefaultsIntoFormData
1219
1338
  });
1220
1339
  maybeAddDefaultToObject(
1221
1340
  objectDefaults,
@@ -1236,7 +1355,8 @@
1236
1355
  _recurseList = [],
1237
1356
  experimental_defaultFormStateBehavior = void 0,
1238
1357
  experimental_customMergeAllOf = void 0,
1239
- required
1358
+ required,
1359
+ shouldMergeDefaultsIntoFormData
1240
1360
  } = {}, defaults) {
1241
1361
  const schema = rawSchema;
1242
1362
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -1256,7 +1376,8 @@
1256
1376
  experimental_defaultFormStateBehavior,
1257
1377
  experimental_customMergeAllOf,
1258
1378
  parentDefaults: item,
1259
- required
1379
+ required,
1380
+ shouldMergeDefaultsIntoFormData
1260
1381
  });
1261
1382
  });
1262
1383
  }
@@ -1273,7 +1394,8 @@
1273
1394
  experimental_customMergeAllOf,
1274
1395
  rawFormData: item,
1275
1396
  parentDefaults: get8(defaults, [idx]),
1276
- required
1397
+ required,
1398
+ shouldMergeDefaultsIntoFormData
1277
1399
  });
1278
1400
  });
1279
1401
  const mergeExtraDefaults = (ignoreMinItemsFlagSet && required || isPopulateAll) && arrayMergeExtraDefaults;
@@ -1303,7 +1425,8 @@
1303
1425
  _recurseList,
1304
1426
  experimental_defaultFormStateBehavior,
1305
1427
  experimental_customMergeAllOf,
1306
- required
1428
+ required,
1429
+ shouldMergeDefaultsIntoFormData
1307
1430
  })
1308
1431
  );
1309
1432
  return defaultEntries.concat(fillerEntries);
@@ -1328,21 +1451,24 @@
1328
1451
  includeUndefinedValues,
1329
1452
  experimental_defaultFormStateBehavior,
1330
1453
  experimental_customMergeAllOf,
1331
- rawFormData: formData
1454
+ rawFormData: formData,
1455
+ shouldMergeDefaultsIntoFormData: true
1332
1456
  });
1333
- if (formData === void 0 || formData === null || typeof formData === "number" && isNaN(formData)) {
1334
- return defaults;
1335
- }
1336
- const { mergeDefaultsIntoFormData, arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1337
- const { mergeExtraDefaults } = arrayMinItems;
1338
- const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1339
- if (isObject(formData)) {
1340
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1341
- }
1342
- if (Array.isArray(formData)) {
1343
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1457
+ if (isObject(formData) || Array.isArray(formData)) {
1458
+ const { mergeDefaultsIntoFormData } = experimental_defaultFormStateBehavior || {};
1459
+ const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1460
+ const result = mergeDefaultsWithFormData(
1461
+ defaults,
1462
+ formData,
1463
+ true,
1464
+ // set to true to add any additional default array entries.
1465
+ defaultSupercedesUndefined,
1466
+ true
1467
+ // set to true to override formData with defaults if they exist.
1468
+ );
1469
+ return result;
1344
1470
  }
1345
- return formData;
1471
+ return defaults;
1346
1472
  }
1347
1473
 
1348
1474
  // src/isCustomWidget.ts
@@ -1418,9 +1544,9 @@
1418
1544
  }
1419
1545
  });
1420
1546
  }
1421
- const keys = Object.keys(get8(newSchema, PROPERTIES_KEY, {}));
1547
+ const keys2 = Object.keys(get8(newSchema, PROPERTIES_KEY, {}));
1422
1548
  const nestedData = {};
1423
- keys.forEach((key) => {
1549
+ keys2.forEach((key) => {
1424
1550
  const formValue = get8(data, key);
1425
1551
  let oldKeyedSchema = get8(oldSchema, [PROPERTIES_KEY, key], {});
1426
1552
  let newKeyedSchema = get8(newSchema, [PROPERTIES_KEY, key], {});
@@ -1537,7 +1663,7 @@
1537
1663
  function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1538
1664
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1539
1665
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1540
- const sameSchemaIndex = _recurseList.findIndex((item) => isEqual4(item, _schema));
1666
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1541
1667
  if (sameSchemaIndex === -1) {
1542
1668
  return toIdSchemaInternal(
1543
1669
  validator,
@@ -1604,7 +1730,7 @@
1604
1730
  function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1605
1731
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1606
1732
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1607
- const sameSchemaIndex = _recurseList.findIndex((item) => isEqual4(item, _schema));
1733
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1608
1734
  if (sameSchemaIndex === -1) {
1609
1735
  return toPathSchemaInternal(
1610
1736
  validator,
@@ -2056,15 +2182,17 @@
2056
2182
  function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
2057
2183
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2058
2184
  if (Array.isArray(selected)) {
2059
- return selected.filter((v) => !isEqual4(v, value));
2185
+ return selected.filter((v) => !deepEquals(v, value));
2060
2186
  }
2061
- return isEqual4(value, selected) ? void 0 : selected;
2187
+ return deepEquals(value, selected) ? void 0 : selected;
2062
2188
  }
2189
+
2190
+ // src/enumOptionsIsSelected.ts
2063
2191
  function enumOptionsIsSelected(value, selected) {
2064
2192
  if (Array.isArray(selected)) {
2065
- return selected.some((sel) => isEqual4(sel, value));
2193
+ return selected.some((sel) => deepEquals(sel, value));
2066
2194
  }
2067
- return isEqual4(selected, value);
2195
+ return deepEquals(selected, value);
2068
2196
  }
2069
2197
 
2070
2198
  // src/enumOptionsIndexForValue.ts
@@ -2429,61 +2557,6 @@
2429
2557
  return dateString ? new Date(dateString).toJSON() : void 0;
2430
2558
  }
2431
2559
 
2432
- // src/toConstant.ts
2433
- function toConstant(schema) {
2434
- if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
2435
- return schema.enum[0];
2436
- }
2437
- if (CONST_KEY in schema) {
2438
- return schema.const;
2439
- }
2440
- throw new Error("schema cannot be inferred as a constant");
2441
- }
2442
-
2443
- // src/optionsList.ts
2444
- function optionsList(schema, uiSchema) {
2445
- const schemaWithEnumNames = schema;
2446
- if (schema.enum) {
2447
- let enumNames;
2448
- if (uiSchema) {
2449
- const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
2450
- enumNames = uiEnumNames;
2451
- }
2452
- if (!enumNames && schemaWithEnumNames.enumNames) {
2453
- {
2454
- console.warn(
2455
- 'The "enumNames" property in the schema is deprecated and will be removed in a future major release. Use the "ui:enumNames" property in the uiSchema instead.'
2456
- );
2457
- }
2458
- enumNames = schemaWithEnumNames.enumNames;
2459
- }
2460
- return schema.enum.map((value, i) => {
2461
- const label = enumNames?.[i] || String(value);
2462
- return { label, value };
2463
- });
2464
- }
2465
- let altSchemas = void 0;
2466
- let altUiSchemas = void 0;
2467
- if (schema.anyOf) {
2468
- altSchemas = schema.anyOf;
2469
- altUiSchemas = uiSchema?.anyOf;
2470
- } else if (schema.oneOf) {
2471
- altSchemas = schema.oneOf;
2472
- altUiSchemas = uiSchema?.oneOf;
2473
- }
2474
- return altSchemas && altSchemas.map((aSchemaDef, index) => {
2475
- const { title } = getUiOptions(altUiSchemas?.[index]);
2476
- const aSchema = aSchemaDef;
2477
- const value = toConstant(aSchema);
2478
- const label = title || aSchema.title || String(value);
2479
- return {
2480
- schema: aSchema,
2481
- label,
2482
- value
2483
- };
2484
- });
2485
- }
2486
-
2487
2560
  // src/orderProperties.ts
2488
2561
  function orderProperties(properties, order) {
2489
2562
  if (!Array.isArray(order)) {
@@ -2594,7 +2667,7 @@
2594
2667
  return Object.keys(errorSchema).reduce((acc, key) => {
2595
2668
  if (key !== ERRORS_KEY) {
2596
2669
  const childSchema = errorSchema[key];
2597
- if (isPlainObject(childSchema)) {
2670
+ if (isPlainObject4(childSchema)) {
2598
2671
  acc = acc.concat(toErrorList(childSchema, [...fieldPath, key]));
2599
2672
  }
2600
2673
  }
@@ -2623,7 +2696,7 @@
2623
2696
  return acc;
2624
2697
  } else {
2625
2698
  const childSchema = errorHandler[key];
2626
- if (isPlainObject(childSchema)) {
2699
+ if (isPlainObject4(childSchema)) {
2627
2700
  return {
2628
2701
  ...acc,
2629
2702
  [key]: unwrapErrorHandler(childSchema)
@@ -2689,6 +2762,22 @@
2689
2762
  }
2690
2763
  return schemaNode;
2691
2764
  }
2765
+ function getChangedFields(a, b) {
2766
+ const aIsPlainObject = isPlainObject4(a);
2767
+ const bIsPlainObject = isPlainObject4(b);
2768
+ if (a === b || !aIsPlainObject && !bIsPlainObject) {
2769
+ return [];
2770
+ }
2771
+ if (aIsPlainObject && !bIsPlainObject) {
2772
+ return keys(a);
2773
+ } else if (!aIsPlainObject && bIsPlainObject) {
2774
+ return keys(b);
2775
+ } else {
2776
+ const unequalFields = keys(pickBy(a, (value, key) => !deepEquals(value, get8(b, key))));
2777
+ const diffFields = difference(keys(b), keys(a));
2778
+ return [...unequalFields, ...diffFields];
2779
+ }
2780
+ }
2692
2781
 
2693
2782
  // src/enums.ts
2694
2783
  var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
@@ -2753,7 +2842,7 @@
2753
2842
  const existing = this.schemaMap[key];
2754
2843
  if (!existing) {
2755
2844
  this.schemaMap[key] = identifiedSchema;
2756
- } else if (!isEqual4(existing, identifiedSchema)) {
2845
+ } else if (!deepEquals(existing, identifiedSchema)) {
2757
2846
  console.error("existing schema:", JSON.stringify(existing, null, 2));
2758
2847
  console.error("new schema:", JSON.stringify(identifiedSchema, null, 2));
2759
2848
  throw new Error(
@@ -2775,7 +2864,7 @@
2775
2864
  * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
2776
2865
  */
2777
2866
  isValid(schema, _formData, rootSchema) {
2778
- if (!isEqual4(rootSchema, this.rootSchema)) {
2867
+ if (!deepEquals(rootSchema, this.rootSchema)) {
2779
2868
  throw new Error("Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema");
2780
2869
  }
2781
2870
  this.addSchema(schema, hashForSchema(schema));
@@ -2815,7 +2904,7 @@
2815
2904
  function parseSchema(validator, recurseList, rootSchema, schema) {
2816
2905
  const schemas = retrieveSchemaInternal(validator, schema, rootSchema, void 0, true);
2817
2906
  schemas.forEach((schema2) => {
2818
- const sameSchemaIndex = recurseList.findIndex((item) => isEqual4(item, schema2));
2907
+ const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema2));
2819
2908
  if (sameSchemaIndex === -1) {
2820
2909
  recurseList.push(schema2);
2821
2910
  const allOptions = resolveAnyOrOneOfSchemas(validator, schema2, rootSchema, true);
@@ -2887,6 +2976,7 @@
2887
2976
  exports.errorId = errorId;
2888
2977
  exports.examplesId = examplesId;
2889
2978
  exports.findSchemaDefinition = findSchemaDefinition;
2979
+ exports.getChangedFields = getChangedFields;
2890
2980
  exports.getClosestMatchingOption = getClosestMatchingOption;
2891
2981
  exports.getDateElementProps = getDateElementProps;
2892
2982
  exports.getDefaultFormState = getDefaultFormState;
@@ -0,0 +1,9 @@
1
+ import { RJSFSchema, StrictRJSFSchema } from './types';
2
+ /**
3
+ * Checks if the schema const property value is an AJV $data reference
4
+ * and the current schema is not an object or array
5
+ *
6
+ * @param schema - The schema to check if the const is an AJV $data reference
7
+ * @returns - true if the schema const property value is an AJV $data reference otherwise false.
8
+ */
9
+ export default function constIsAjvDataReference<S extends StrictRJSFSchema = RJSFSchema>(schema: S): boolean;
@@ -0,0 +1,15 @@
1
+ import { CONST_KEY, getSchemaType, isObject } from './';
2
+ import isString from 'lodash/isString';
3
+ /**
4
+ * Checks if the schema const property value is an AJV $data reference
5
+ * and the current schema is not an object or array
6
+ *
7
+ * @param schema - The schema to check if the const is an AJV $data reference
8
+ * @returns - true if the schema const property value is an AJV $data reference otherwise false.
9
+ */
10
+ export default function constIsAjvDataReference(schema) {
11
+ const schemaConst = schema[CONST_KEY];
12
+ const schemaType = getSchemaType(schema);
13
+ return isObject(schemaConst) && isString(schemaConst === null || schemaConst === void 0 ? void 0 : schemaConst.$data) && schemaType !== 'object' && schemaType !== 'array';
14
+ }
15
+ //# sourceMappingURL=constIsAjvDataReference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constIsAjvDataReference.js","sourceRoot":"","sources":["../src/constIsAjvDataReference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAGxD,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAA0C,MAAS;IAChG,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAwC,CAAC;IAC7E,MAAM,UAAU,GAAG,aAAa,CAAI,MAAM,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,CAAC,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,CAAC;AACpH,CAAC"}