@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.esm.js CHANGED
@@ -1,12 +1,15 @@
1
1
  // src/isObject.ts
2
2
  function isObject(thing) {
3
- if (typeof File !== "undefined" && thing instanceof File) {
3
+ if (typeof thing !== "object" || thing === null) {
4
4
  return false;
5
5
  }
6
- if (typeof Date !== "undefined" && thing instanceof Date) {
6
+ if (typeof thing.lastModified === "number" && typeof File !== "undefined" && thing instanceof File) {
7
7
  return false;
8
8
  }
9
- return typeof thing === "object" && thing !== null && !Array.isArray(thing);
9
+ if (typeof thing.getMonth === "function" && typeof Date !== "undefined" && thing instanceof Date) {
10
+ return false;
11
+ }
12
+ return !Array.isArray(thing);
10
13
  }
11
14
 
12
15
  // src/allowAdditionalItems.ts
@@ -279,7 +282,6 @@ function getFirstMatchingOption(validator, formData, options, rootSchema, discri
279
282
 
280
283
  // src/schema/retrieveSchema.ts
281
284
  import get4 from "lodash/get";
282
- import isEqual from "lodash/isEqual";
283
285
  import set from "lodash/set";
284
286
  import times from "lodash/times";
285
287
  import transform from "lodash/transform";
@@ -501,7 +503,10 @@ function resolveSchema(validator, schema, rootSchema, expandAllBranches, recurse
501
503
  )
502
504
  );
503
505
  const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
504
- return allPermutations.map((permutation) => ({ ...schema, allOf: permutation }));
506
+ return allPermutations.map((permutation) => ({
507
+ ...schema,
508
+ allOf: permutation
509
+ }));
505
510
  }
506
511
  return [schema];
507
512
  }
@@ -554,7 +559,7 @@ function resolveAllReferences(schema, rootSchema, recurseList) {
554
559
  items: resolveAllReferences(resolvedSchema.items, rootSchema, recurseList)
555
560
  };
556
561
  }
557
- return isEqual(schema, resolvedSchema) ? schema : resolvedSchema;
562
+ return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema;
558
563
  }
559
564
  function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData, experimental_customMergeAllOf) {
560
565
  const schema = {
@@ -957,38 +962,48 @@ function isFixedItems(schema) {
957
962
 
958
963
  // src/mergeDefaultsWithFormData.ts
959
964
  import get6 from "lodash/get";
960
- function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false) {
965
+ import isNil from "lodash/isNil";
966
+ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false, overrideFormDataWithDefaults = false) {
961
967
  if (Array.isArray(formData)) {
962
968
  const defaultsArray = Array.isArray(defaults) ? defaults : [];
963
- const mapped = formData.map((value, idx) => {
964
- if (defaultsArray[idx]) {
969
+ const overrideArray = overrideFormDataWithDefaults ? defaultsArray : formData;
970
+ const overrideOppositeArray = overrideFormDataWithDefaults ? formData : defaultsArray;
971
+ const mapped = overrideArray.map((value, idx) => {
972
+ if (overrideOppositeArray[idx]) {
965
973
  return mergeDefaultsWithFormData(
966
974
  defaultsArray[idx],
967
- value,
975
+ formData[idx],
968
976
  mergeExtraArrayDefaults,
969
- defaultSupercedesUndefined
977
+ defaultSupercedesUndefined,
978
+ overrideFormDataWithDefaults
970
979
  );
971
980
  }
972
981
  return value;
973
982
  });
974
- if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
975
- mapped.push(...defaultsArray.slice(mapped.length));
983
+ if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) {
984
+ mapped.push(...overrideOppositeArray.slice(mapped.length));
976
985
  }
977
986
  return mapped;
978
987
  }
979
988
  if (isObject(formData)) {
980
989
  const acc = Object.assign({}, defaults);
981
990
  return Object.keys(formData).reduce((acc2, key) => {
991
+ const keyValue = get6(formData, key);
992
+ const keyExistsInDefaults = isObject(defaults) && key in defaults;
993
+ const keyExistsInFormData = key in formData;
982
994
  acc2[key] = mergeDefaultsWithFormData(
983
995
  defaults ? get6(defaults, key) : {},
984
- get6(formData, key),
996
+ keyValue,
985
997
  mergeExtraArrayDefaults,
986
- defaultSupercedesUndefined
998
+ defaultSupercedesUndefined,
999
+ // overrideFormDataWithDefaults can be true only when the key value exists in defaults
1000
+ // Or if the key value doesn't exist in formData
1001
+ overrideFormDataWithDefaults && (keyExistsInDefaults || !keyExistsInFormData)
987
1002
  );
988
1003
  return acc2;
989
1004
  }, acc);
990
1005
  }
991
- if (defaultSupercedesUndefined && formData === void 0) {
1006
+ if (defaultSupercedesUndefined && (!isNil(defaults) && isNil(formData) || typeof formData === "number" && isNaN(formData)) || overrideFormDataWithDefaults && !isNil(formData)) {
992
1007
  return defaults;
993
1008
  }
994
1009
  return formData;
@@ -1044,6 +1059,69 @@ function isMultiSelect(validator, schema, rootSchema, experimental_customMergeAl
1044
1059
  return isSelect(validator, schema.items, rootSchema, experimental_customMergeAllOf);
1045
1060
  }
1046
1061
 
1062
+ // src/constIsAjvDataReference.ts
1063
+ import isString3 from "lodash/isString";
1064
+ function constIsAjvDataReference(schema) {
1065
+ const schemaConst = schema[CONST_KEY];
1066
+ const schemaType = getSchemaType(schema);
1067
+ return isObject(schemaConst) && isString3(schemaConst?.$data) && schemaType !== "object" && schemaType !== "array";
1068
+ }
1069
+
1070
+ // src/toConstant.ts
1071
+ function toConstant(schema) {
1072
+ if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
1073
+ return schema.enum[0];
1074
+ }
1075
+ if (CONST_KEY in schema) {
1076
+ return schema.const;
1077
+ }
1078
+ throw new Error("schema cannot be inferred as a constant");
1079
+ }
1080
+
1081
+ // src/optionsList.ts
1082
+ function optionsList(schema, uiSchema) {
1083
+ const schemaWithEnumNames = schema;
1084
+ if (schema.enum) {
1085
+ let enumNames;
1086
+ if (uiSchema) {
1087
+ const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
1088
+ enumNames = uiEnumNames;
1089
+ }
1090
+ if (!enumNames && schemaWithEnumNames.enumNames) {
1091
+ if (true) {
1092
+ console.warn(
1093
+ '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.'
1094
+ );
1095
+ }
1096
+ enumNames = schemaWithEnumNames.enumNames;
1097
+ }
1098
+ return schema.enum.map((value, i) => {
1099
+ const label = enumNames?.[i] || String(value);
1100
+ return { label, value };
1101
+ });
1102
+ }
1103
+ let altSchemas = void 0;
1104
+ let altUiSchemas = void 0;
1105
+ if (schema.anyOf) {
1106
+ altSchemas = schema.anyOf;
1107
+ altUiSchemas = uiSchema?.anyOf;
1108
+ } else if (schema.oneOf) {
1109
+ altSchemas = schema.oneOf;
1110
+ altUiSchemas = uiSchema?.oneOf;
1111
+ }
1112
+ return altSchemas && altSchemas.map((aSchemaDef, index) => {
1113
+ const { title } = getUiOptions(altUiSchemas?.[index]);
1114
+ const aSchema = aSchemaDef;
1115
+ const value = toConstant(aSchema);
1116
+ const label = title || aSchema.title || String(value);
1117
+ return {
1118
+ schema: aSchema,
1119
+ label,
1120
+ value
1121
+ };
1122
+ });
1123
+ }
1124
+
1047
1125
  // src/schema/getDefaultFormState.ts
1048
1126
  var PRIMITIVE_TYPES = ["string", "number", "integer", "boolean", "null"];
1049
1127
  function getInnerSchemaForArrayItem(schema, additionalItems = 0 /* Ignore */, idx = -1) {
@@ -1067,8 +1145,8 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1067
1145
  if (includeUndefinedValues || isConst) {
1068
1146
  obj[key] = computedDefault;
1069
1147
  } else if (emptyObjectFields !== "skipDefaults") {
1148
+ const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1070
1149
  if (isObject(computedDefault)) {
1071
- const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1072
1150
  if (emptyObjectFields === "skipEmptyDefaults") {
1073
1151
  if (!isEmpty(computedDefault)) {
1074
1152
  obj[key] = computedDefault;
@@ -1079,8 +1157,9 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1079
1157
  } else if (
1080
1158
  // Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
1081
1159
  // Condition 1: computedDefault is not undefined
1082
- // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults) or if the key is a required field
1083
- computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || requiredFields.includes(key))
1160
+ // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults)
1161
+ // Or if isSelfOrParentRequired is 'true' and the key is a required field
1162
+ computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || isSelfOrParentRequired && requiredFields.includes(key))
1084
1163
  ) {
1085
1164
  obj[key] = computedDefault;
1086
1165
  }
@@ -1095,7 +1174,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1095
1174
  _recurseList = [],
1096
1175
  experimental_defaultFormStateBehavior = void 0,
1097
1176
  experimental_customMergeAllOf = void 0,
1098
- required
1177
+ required,
1178
+ shouldMergeDefaultsIntoFormData = false
1099
1179
  } = computeDefaultsProps;
1100
1180
  const formData = isObject(rawFormData) ? rawFormData : {};
1101
1181
  const schema = isObject(rawSchema) ? rawSchema : {};
@@ -1103,8 +1183,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1103
1183
  let schemaToCompute = null;
1104
1184
  let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
1105
1185
  let updatedRecurseList = _recurseList;
1106
- if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never") {
1107
- defaults = schema.const;
1186
+ if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(schema)) {
1187
+ defaults = schema[CONST_KEY];
1108
1188
  } else if (isObject(defaults) && isObject(schema.default)) {
1109
1189
  defaults = mergeObjects(defaults, schema.default);
1110
1190
  } else if (DEFAULT_KEY in schema) {
@@ -1140,7 +1220,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1140
1220
  experimental_customMergeAllOf,
1141
1221
  parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : void 0,
1142
1222
  rawFormData: formData,
1143
- required
1223
+ required,
1224
+ shouldMergeDefaultsIntoFormData
1144
1225
  })
1145
1226
  );
1146
1227
  } else if (ONE_OF_KEY in schema) {
@@ -1151,12 +1232,15 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1151
1232
  const discriminator = getDiscriminatorFieldFromSchema(schema);
1152
1233
  const { type = "null" } = remaining;
1153
1234
  if (!Array.isArray(type) && PRIMITIVE_TYPES.includes(type) && experimental_dfsb_to_compute?.constAsDefaults === "skipOneOf") {
1154
- experimental_dfsb_to_compute = { ...experimental_dfsb_to_compute, constAsDefaults: "never" };
1235
+ experimental_dfsb_to_compute = {
1236
+ ...experimental_dfsb_to_compute,
1237
+ constAsDefaults: "never"
1238
+ };
1155
1239
  }
1156
1240
  schemaToCompute = oneOf[getClosestMatchingOption(
1157
1241
  validator,
1158
1242
  rootSchema,
1159
- isEmpty(formData) ? void 0 : formData,
1243
+ rawFormData,
1160
1244
  oneOf,
1161
1245
  0,
1162
1246
  discriminator,
@@ -1172,7 +1256,7 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1172
1256
  schemaToCompute = anyOf[getClosestMatchingOption(
1173
1257
  validator,
1174
1258
  rootSchema,
1175
- isEmpty(formData) ? void 0 : formData,
1259
+ rawFormData,
1176
1260
  anyOf,
1177
1261
  0,
1178
1262
  discriminator,
@@ -1189,14 +1273,49 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1189
1273
  experimental_customMergeAllOf,
1190
1274
  parentDefaults: defaults,
1191
1275
  rawFormData: formData,
1192
- required
1276
+ required,
1277
+ shouldMergeDefaultsIntoFormData
1193
1278
  });
1194
1279
  }
1195
1280
  if (defaults === void 0) {
1196
1281
  defaults = schema.default;
1197
1282
  }
1198
1283
  const defaultBasedOnSchemaType = getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults);
1199
- return defaultBasedOnSchemaType ?? defaults;
1284
+ let defaultsWithFormData = defaultBasedOnSchemaType ?? defaults;
1285
+ if (shouldMergeDefaultsIntoFormData) {
1286
+ const { arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1287
+ const { mergeExtraDefaults } = arrayMinItems;
1288
+ const matchingFormData = ensureFormDataMatchingSchema(
1289
+ validator,
1290
+ schema,
1291
+ rootSchema,
1292
+ rawFormData,
1293
+ experimental_defaultFormStateBehavior
1294
+ );
1295
+ if (!isObject(rawFormData)) {
1296
+ defaultsWithFormData = mergeDefaultsWithFormData(
1297
+ defaultsWithFormData,
1298
+ matchingFormData,
1299
+ mergeExtraDefaults,
1300
+ true
1301
+ );
1302
+ }
1303
+ }
1304
+ return defaultsWithFormData;
1305
+ }
1306
+ function ensureFormDataMatchingSchema(validator, schema, rootSchema, formData, experimental_defaultFormStateBehavior) {
1307
+ const isSelectField = !isConstant(schema) && isSelect(validator, schema, rootSchema);
1308
+ let validFormData = formData;
1309
+ if (isSelectField) {
1310
+ const getOptionsList = optionsList(schema);
1311
+ const isValid = getOptionsList?.some((option) => deepEquals(option.value, formData));
1312
+ validFormData = isValid ? formData : void 0;
1313
+ }
1314
+ const constTakesPrecedence = schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults === "always";
1315
+ if (constTakesPrecedence) {
1316
+ validFormData = schema.const;
1317
+ }
1318
+ return validFormData;
1200
1319
  }
1201
1320
  function getObjectDefaults(validator, rawSchema, {
1202
1321
  rawFormData,
@@ -1205,7 +1324,8 @@ function getObjectDefaults(validator, rawSchema, {
1205
1324
  _recurseList = [],
1206
1325
  experimental_defaultFormStateBehavior = void 0,
1207
1326
  experimental_customMergeAllOf = void 0,
1208
- required
1327
+ required,
1328
+ shouldMergeDefaultsIntoFormData
1209
1329
  } = {}, defaults) {
1210
1330
  {
1211
1331
  const formData = isObject(rawFormData) ? rawFormData : {};
@@ -1216,7 +1336,7 @@ function getObjectDefaults(validator, rawSchema, {
1216
1336
  (acc, key) => {
1217
1337
  const propertySchema = get7(retrievedSchema, [PROPERTIES_KEY, key]);
1218
1338
  const hasParentConst = isObject(parentConst) && parentConst[key] !== void 0;
1219
- const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never";
1339
+ const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(propertySchema);
1220
1340
  const computedDefault = computeDefaults(validator, propertySchema, {
1221
1341
  rootSchema,
1222
1342
  _recurseList,
@@ -1225,7 +1345,8 @@ function getObjectDefaults(validator, rawSchema, {
1225
1345
  includeUndefinedValues: includeUndefinedValues === true,
1226
1346
  parentDefaults: get7(defaults, [key]),
1227
1347
  rawFormData: get7(formData, [key]),
1228
- required: retrievedSchema.required?.includes(key)
1348
+ required: retrievedSchema.required?.includes(key),
1349
+ shouldMergeDefaultsIntoFormData
1229
1350
  });
1230
1351
  maybeAddDefaultToObject(
1231
1352
  acc,
@@ -1243,16 +1364,16 @@ function getObjectDefaults(validator, rawSchema, {
1243
1364
  );
1244
1365
  if (retrievedSchema.additionalProperties) {
1245
1366
  const additionalPropertiesSchema = isObject(retrievedSchema.additionalProperties) ? retrievedSchema.additionalProperties : {};
1246
- const keys = /* @__PURE__ */ new Set();
1367
+ const keys2 = /* @__PURE__ */ new Set();
1247
1368
  if (isObject(defaults)) {
1248
- Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys.add(key));
1369
+ Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys2.add(key));
1249
1370
  }
1250
1371
  const formDataRequired = [];
1251
1372
  Object.keys(formData).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => {
1252
- keys.add(key);
1373
+ keys2.add(key);
1253
1374
  formDataRequired.push(key);
1254
1375
  });
1255
- keys.forEach((key) => {
1376
+ keys2.forEach((key) => {
1256
1377
  const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
1257
1378
  rootSchema,
1258
1379
  _recurseList,
@@ -1261,7 +1382,8 @@ function getObjectDefaults(validator, rawSchema, {
1261
1382
  includeUndefinedValues: includeUndefinedValues === true,
1262
1383
  parentDefaults: get7(defaults, [key]),
1263
1384
  rawFormData: get7(formData, [key]),
1264
- required: retrievedSchema.required?.includes(key)
1385
+ required: retrievedSchema.required?.includes(key),
1386
+ shouldMergeDefaultsIntoFormData
1265
1387
  });
1266
1388
  maybeAddDefaultToObject(
1267
1389
  objectDefaults,
@@ -1282,7 +1404,8 @@ function getArrayDefaults(validator, rawSchema, {
1282
1404
  _recurseList = [],
1283
1405
  experimental_defaultFormStateBehavior = void 0,
1284
1406
  experimental_customMergeAllOf = void 0,
1285
- required
1407
+ required,
1408
+ shouldMergeDefaultsIntoFormData
1286
1409
  } = {}, defaults) {
1287
1410
  const schema = rawSchema;
1288
1411
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -1302,7 +1425,8 @@ function getArrayDefaults(validator, rawSchema, {
1302
1425
  experimental_defaultFormStateBehavior,
1303
1426
  experimental_customMergeAllOf,
1304
1427
  parentDefaults: item,
1305
- required
1428
+ required,
1429
+ shouldMergeDefaultsIntoFormData
1306
1430
  });
1307
1431
  });
1308
1432
  }
@@ -1319,7 +1443,8 @@ function getArrayDefaults(validator, rawSchema, {
1319
1443
  experimental_customMergeAllOf,
1320
1444
  rawFormData: item,
1321
1445
  parentDefaults: get7(defaults, [idx]),
1322
- required
1446
+ required,
1447
+ shouldMergeDefaultsIntoFormData
1323
1448
  });
1324
1449
  });
1325
1450
  const mergeExtraDefaults = (ignoreMinItemsFlagSet && required || isPopulateAll) && arrayMergeExtraDefaults;
@@ -1349,7 +1474,8 @@ function getArrayDefaults(validator, rawSchema, {
1349
1474
  _recurseList,
1350
1475
  experimental_defaultFormStateBehavior,
1351
1476
  experimental_customMergeAllOf,
1352
- required
1477
+ required,
1478
+ shouldMergeDefaultsIntoFormData
1353
1479
  })
1354
1480
  );
1355
1481
  return defaultEntries.concat(fillerEntries);
@@ -1374,21 +1500,24 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
1374
1500
  includeUndefinedValues,
1375
1501
  experimental_defaultFormStateBehavior,
1376
1502
  experimental_customMergeAllOf,
1377
- rawFormData: formData
1503
+ rawFormData: formData,
1504
+ shouldMergeDefaultsIntoFormData: true
1378
1505
  });
1379
- if (formData === void 0 || formData === null || typeof formData === "number" && isNaN(formData)) {
1380
- return defaults;
1381
- }
1382
- const { mergeDefaultsIntoFormData, arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1383
- const { mergeExtraDefaults } = arrayMinItems;
1384
- const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1385
- if (isObject(formData)) {
1386
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1387
- }
1388
- if (Array.isArray(formData)) {
1389
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1506
+ if (isObject(formData) || Array.isArray(formData)) {
1507
+ const { mergeDefaultsIntoFormData } = experimental_defaultFormStateBehavior || {};
1508
+ const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1509
+ const result = mergeDefaultsWithFormData(
1510
+ defaults,
1511
+ formData,
1512
+ true,
1513
+ // set to true to add any additional default array entries.
1514
+ defaultSupercedesUndefined,
1515
+ true
1516
+ // set to true to override formData with defaults if they exist.
1517
+ );
1518
+ return result;
1390
1519
  }
1391
- return formData;
1520
+ return defaults;
1392
1521
  }
1393
1522
 
1394
1523
  // src/isCustomWidget.ts
@@ -1471,9 +1600,9 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1471
1600
  }
1472
1601
  });
1473
1602
  }
1474
- const keys = Object.keys(get8(newSchema, PROPERTIES_KEY, {}));
1603
+ const keys2 = Object.keys(get8(newSchema, PROPERTIES_KEY, {}));
1475
1604
  const nestedData = {};
1476
- keys.forEach((key) => {
1605
+ keys2.forEach((key) => {
1477
1606
  const formValue = get8(data, key);
1478
1607
  let oldKeyedSchema = get8(oldSchema, [PROPERTIES_KEY, key], {});
1479
1608
  let newKeyedSchema = get8(newSchema, [PROPERTIES_KEY, key], {});
@@ -1590,11 +1719,10 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1590
1719
 
1591
1720
  // src/schema/toIdSchema.ts
1592
1721
  import get9 from "lodash/get";
1593
- import isEqual2 from "lodash/isEqual";
1594
1722
  function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1595
1723
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1596
1724
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1597
- const sameSchemaIndex = _recurseList.findIndex((item) => isEqual2(item, _schema));
1725
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1598
1726
  if (sameSchemaIndex === -1) {
1599
1727
  return toIdSchemaInternal(
1600
1728
  validator,
@@ -1661,12 +1789,11 @@ function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = "roo
1661
1789
 
1662
1790
  // src/schema/toPathSchema.ts
1663
1791
  import get10 from "lodash/get";
1664
- import isEqual3 from "lodash/isEqual";
1665
1792
  import set2 from "lodash/set";
1666
1793
  function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1667
1794
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1668
1795
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1669
- const sameSchemaIndex = _recurseList.findIndex((item) => isEqual3(item, _schema));
1796
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1670
1797
  if (sameSchemaIndex === -1) {
1671
1798
  return toPathSchemaInternal(
1672
1799
  validator,
@@ -2104,9 +2231,6 @@ function englishStringTranslator(stringToTranslate, params) {
2104
2231
  return replaceStringParameters(stringToTranslate, params);
2105
2232
  }
2106
2233
 
2107
- // src/enumOptionsDeselectValue.ts
2108
- import isEqual4 from "lodash/isEqual";
2109
-
2110
2234
  // src/enumOptionsValueForIndex.ts
2111
2235
  function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2112
2236
  if (Array.isArray(valueIndex)) {
@@ -2121,18 +2245,17 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2121
2245
  function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
2122
2246
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2123
2247
  if (Array.isArray(selected)) {
2124
- return selected.filter((v) => !isEqual4(v, value));
2248
+ return selected.filter((v) => !deepEquals(v, value));
2125
2249
  }
2126
- return isEqual4(value, selected) ? void 0 : selected;
2250
+ return deepEquals(value, selected) ? void 0 : selected;
2127
2251
  }
2128
2252
 
2129
2253
  // src/enumOptionsIsSelected.ts
2130
- import isEqual5 from "lodash/isEqual";
2131
2254
  function enumOptionsIsSelected(value, selected) {
2132
2255
  if (Array.isArray(selected)) {
2133
- return selected.some((sel) => isEqual5(sel, value));
2256
+ return selected.some((sel) => deepEquals(sel, value));
2134
2257
  }
2135
- return isEqual5(selected, value);
2258
+ return deepEquals(selected, value);
2136
2259
  }
2137
2260
 
2138
2261
  // src/enumOptionsIndexForValue.ts
@@ -2145,10 +2268,10 @@ function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false)
2145
2268
  }
2146
2269
 
2147
2270
  // src/enumOptionsSelectValue.ts
2148
- import isNil from "lodash/isNil";
2271
+ import isNil2 from "lodash/isNil";
2149
2272
  function enumOptionsSelectValue(valueIndex, selected, allEnumOptions = []) {
2150
2273
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2151
- if (!isNil(value)) {
2274
+ if (!isNil2(value)) {
2152
2275
  const index = allEnumOptions.findIndex((opt) => value === opt.value);
2153
2276
  const all = allEnumOptions.map(({ value: val }) => val);
2154
2277
  const updated = selected.slice(0, index).concat(value, selected.slice(index));
@@ -2478,9 +2601,9 @@ function hasWidget(schema, widget, registeredWidgets = {}) {
2478
2601
  }
2479
2602
 
2480
2603
  // src/idGenerators.ts
2481
- import isString3 from "lodash/isString";
2604
+ import isString4 from "lodash/isString";
2482
2605
  function idGenerator(id, suffix) {
2483
- const theId = isString3(id) ? id : id[ID_KEY];
2606
+ const theId = isString4(id) ? id : id[ID_KEY];
2484
2607
  return `${theId}__${suffix}`;
2485
2608
  }
2486
2609
  function descriptionId(id) {
@@ -2516,61 +2639,6 @@ function localToUTC(dateString) {
2516
2639
  return dateString ? new Date(dateString).toJSON() : void 0;
2517
2640
  }
2518
2641
 
2519
- // src/toConstant.ts
2520
- function toConstant(schema) {
2521
- if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
2522
- return schema.enum[0];
2523
- }
2524
- if (CONST_KEY in schema) {
2525
- return schema.const;
2526
- }
2527
- throw new Error("schema cannot be inferred as a constant");
2528
- }
2529
-
2530
- // src/optionsList.ts
2531
- function optionsList(schema, uiSchema) {
2532
- const schemaWithEnumNames = schema;
2533
- if (schema.enum) {
2534
- let enumNames;
2535
- if (uiSchema) {
2536
- const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
2537
- enumNames = uiEnumNames;
2538
- }
2539
- if (!enumNames && schemaWithEnumNames.enumNames) {
2540
- if (true) {
2541
- console.warn(
2542
- '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.'
2543
- );
2544
- }
2545
- enumNames = schemaWithEnumNames.enumNames;
2546
- }
2547
- return schema.enum.map((value, i) => {
2548
- const label = enumNames?.[i] || String(value);
2549
- return { label, value };
2550
- });
2551
- }
2552
- let altSchemas = void 0;
2553
- let altUiSchemas = void 0;
2554
- if (schema.anyOf) {
2555
- altSchemas = schema.anyOf;
2556
- altUiSchemas = uiSchema?.anyOf;
2557
- } else if (schema.oneOf) {
2558
- altSchemas = schema.oneOf;
2559
- altUiSchemas = uiSchema?.oneOf;
2560
- }
2561
- return altSchemas && altSchemas.map((aSchemaDef, index) => {
2562
- const { title } = getUiOptions(altUiSchemas?.[index]);
2563
- const aSchema = aSchemaDef;
2564
- const value = toConstant(aSchema);
2565
- const label = title || aSchema.title || String(value);
2566
- return {
2567
- schema: aSchema,
2568
- label,
2569
- value
2570
- };
2571
- });
2572
- }
2573
-
2574
2642
  // src/orderProperties.ts
2575
2643
  function orderProperties(properties, order) {
2576
2644
  if (!Array.isArray(order)) {
@@ -2792,6 +2860,29 @@ function withIdRefPrefix(schemaNode) {
2792
2860
  return schemaNode;
2793
2861
  }
2794
2862
 
2863
+ // src/getChangedFields.ts
2864
+ import keys from "lodash/keys";
2865
+ import pickBy from "lodash/pickBy";
2866
+ import isPlainObject4 from "lodash/isPlainObject";
2867
+ import get13 from "lodash/get";
2868
+ import difference from "lodash/difference";
2869
+ function getChangedFields(a, b) {
2870
+ const aIsPlainObject = isPlainObject4(a);
2871
+ const bIsPlainObject = isPlainObject4(b);
2872
+ if (a === b || !aIsPlainObject && !bIsPlainObject) {
2873
+ return [];
2874
+ }
2875
+ if (aIsPlainObject && !bIsPlainObject) {
2876
+ return keys(a);
2877
+ } else if (!aIsPlainObject && bIsPlainObject) {
2878
+ return keys(b);
2879
+ } else {
2880
+ const unequalFields = keys(pickBy(a, (value, key) => !deepEquals(value, get13(b, key))));
2881
+ const diffFields = difference(keys(b), keys(a));
2882
+ return [...unequalFields, ...diffFields];
2883
+ }
2884
+ }
2885
+
2795
2886
  // src/enums.ts
2796
2887
  var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2797
2888
  TranslatableString2["ArrayItemTitle"] = "Item";
@@ -2828,11 +2919,9 @@ var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2828
2919
 
2829
2920
  // src/parser/schemaParser.ts
2830
2921
  import forEach from "lodash/forEach";
2831
- import isEqual7 from "lodash/isEqual";
2832
2922
 
2833
2923
  // src/parser/ParserValidator.ts
2834
- import get13 from "lodash/get";
2835
- import isEqual6 from "lodash/isEqual";
2924
+ import get14 from "lodash/get";
2836
2925
  var ParserValidator = class {
2837
2926
  /** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
2838
2927
  * first.
@@ -2858,12 +2947,12 @@ var ParserValidator = class {
2858
2947
  * @param hash - The hash value at which to map the schema
2859
2948
  */
2860
2949
  addSchema(schema, hash) {
2861
- const key = get13(schema, ID_KEY, hash);
2950
+ const key = get14(schema, ID_KEY, hash);
2862
2951
  const identifiedSchema = { ...schema, [ID_KEY]: key };
2863
2952
  const existing = this.schemaMap[key];
2864
2953
  if (!existing) {
2865
2954
  this.schemaMap[key] = identifiedSchema;
2866
- } else if (!isEqual6(existing, identifiedSchema)) {
2955
+ } else if (!deepEquals(existing, identifiedSchema)) {
2867
2956
  console.error("existing schema:", JSON.stringify(existing, null, 2));
2868
2957
  console.error("new schema:", JSON.stringify(identifiedSchema, null, 2));
2869
2958
  throw new Error(
@@ -2885,7 +2974,7 @@ var ParserValidator = class {
2885
2974
  * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
2886
2975
  */
2887
2976
  isValid(schema, _formData, rootSchema) {
2888
- if (!isEqual6(rootSchema, this.rootSchema)) {
2977
+ if (!deepEquals(rootSchema, this.rootSchema)) {
2889
2978
  throw new Error("Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema");
2890
2979
  }
2891
2980
  this.addSchema(schema, hashForSchema(schema));
@@ -2925,7 +3014,7 @@ var ParserValidator = class {
2925
3014
  function parseSchema(validator, recurseList, rootSchema, schema) {
2926
3015
  const schemas = retrieveSchemaInternal(validator, schema, rootSchema, void 0, true);
2927
3016
  schemas.forEach((schema2) => {
2928
- const sameSchemaIndex = recurseList.findIndex((item) => isEqual7(item, schema2));
3017
+ const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema2));
2929
3018
  if (sameSchemaIndex === -1) {
2930
3019
  recurseList.push(schema2);
2931
3020
  const allOptions = resolveAnyOrOneOfSchemas(validator, schema2, rootSchema, true);
@@ -2997,6 +3086,7 @@ export {
2997
3086
  errorId,
2998
3087
  examplesId,
2999
3088
  findSchemaDefinition,
3089
+ getChangedFields,
3000
3090
  getClosestMatchingOption,
3001
3091
  getDateElementProps,
3002
3092
  getDefaultFormState,