@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/index.js CHANGED
@@ -78,6 +78,7 @@ __export(src_exports, {
78
78
  errorId: () => errorId,
79
79
  examplesId: () => examplesId,
80
80
  findSchemaDefinition: () => findSchemaDefinition,
81
+ getChangedFields: () => getChangedFields,
81
82
  getClosestMatchingOption: () => getClosestMatchingOption,
82
83
  getDateElementProps: () => getDateElementProps,
83
84
  getDefaultFormState: () => getDefaultFormState,
@@ -137,13 +138,16 @@ module.exports = __toCommonJS(src_exports);
137
138
 
138
139
  // src/isObject.ts
139
140
  function isObject(thing) {
140
- if (typeof File !== "undefined" && thing instanceof File) {
141
+ if (typeof thing !== "object" || thing === null) {
141
142
  return false;
142
143
  }
143
- if (typeof Date !== "undefined" && thing instanceof Date) {
144
+ if (typeof thing.lastModified === "number" && typeof File !== "undefined" && thing instanceof File) {
144
145
  return false;
145
146
  }
146
- return typeof thing === "object" && thing !== null && !Array.isArray(thing);
147
+ if (typeof thing.getMonth === "function" && typeof Date !== "undefined" && thing instanceof Date) {
148
+ return false;
149
+ }
150
+ return !Array.isArray(thing);
147
151
  }
148
152
 
149
153
  // src/allowAdditionalItems.ts
@@ -416,7 +420,6 @@ function getFirstMatchingOption(validator, formData, options, rootSchema, discri
416
420
 
417
421
  // src/schema/retrieveSchema.ts
418
422
  var import_get4 = __toESM(require("lodash/get"));
419
- var import_isEqual = __toESM(require("lodash/isEqual"));
420
423
  var import_set = __toESM(require("lodash/set"));
421
424
  var import_times = __toESM(require("lodash/times"));
422
425
  var import_transform = __toESM(require("lodash/transform"));
@@ -638,7 +641,10 @@ function resolveSchema(validator, schema, rootSchema, expandAllBranches, recurse
638
641
  )
639
642
  );
640
643
  const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
641
- return allPermutations.map((permutation) => ({ ...schema, allOf: permutation }));
644
+ return allPermutations.map((permutation) => ({
645
+ ...schema,
646
+ allOf: permutation
647
+ }));
642
648
  }
643
649
  return [schema];
644
650
  }
@@ -691,7 +697,7 @@ function resolveAllReferences(schema, rootSchema, recurseList) {
691
697
  items: resolveAllReferences(resolvedSchema.items, rootSchema, recurseList)
692
698
  };
693
699
  }
694
- return (0, import_isEqual.default)(schema, resolvedSchema) ? schema : resolvedSchema;
700
+ return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema;
695
701
  }
696
702
  function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData, experimental_customMergeAllOf) {
697
703
  const schema = {
@@ -1094,38 +1100,48 @@ function isFixedItems(schema) {
1094
1100
 
1095
1101
  // src/mergeDefaultsWithFormData.ts
1096
1102
  var import_get6 = __toESM(require("lodash/get"));
1097
- function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false) {
1103
+ var import_isNil = __toESM(require("lodash/isNil"));
1104
+ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false, overrideFormDataWithDefaults = false) {
1098
1105
  if (Array.isArray(formData)) {
1099
1106
  const defaultsArray = Array.isArray(defaults) ? defaults : [];
1100
- const mapped = formData.map((value, idx) => {
1101
- if (defaultsArray[idx]) {
1107
+ const overrideArray = overrideFormDataWithDefaults ? defaultsArray : formData;
1108
+ const overrideOppositeArray = overrideFormDataWithDefaults ? formData : defaultsArray;
1109
+ const mapped = overrideArray.map((value, idx) => {
1110
+ if (overrideOppositeArray[idx]) {
1102
1111
  return mergeDefaultsWithFormData(
1103
1112
  defaultsArray[idx],
1104
- value,
1113
+ formData[idx],
1105
1114
  mergeExtraArrayDefaults,
1106
- defaultSupercedesUndefined
1115
+ defaultSupercedesUndefined,
1116
+ overrideFormDataWithDefaults
1107
1117
  );
1108
1118
  }
1109
1119
  return value;
1110
1120
  });
1111
- if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
1112
- mapped.push(...defaultsArray.slice(mapped.length));
1121
+ if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) {
1122
+ mapped.push(...overrideOppositeArray.slice(mapped.length));
1113
1123
  }
1114
1124
  return mapped;
1115
1125
  }
1116
1126
  if (isObject(formData)) {
1117
1127
  const acc = Object.assign({}, defaults);
1118
1128
  return Object.keys(formData).reduce((acc2, key) => {
1129
+ const keyValue = (0, import_get6.default)(formData, key);
1130
+ const keyExistsInDefaults = isObject(defaults) && key in defaults;
1131
+ const keyExistsInFormData = key in formData;
1119
1132
  acc2[key] = mergeDefaultsWithFormData(
1120
1133
  defaults ? (0, import_get6.default)(defaults, key) : {},
1121
- (0, import_get6.default)(formData, key),
1134
+ keyValue,
1122
1135
  mergeExtraArrayDefaults,
1123
- defaultSupercedesUndefined
1136
+ defaultSupercedesUndefined,
1137
+ // overrideFormDataWithDefaults can be true only when the key value exists in defaults
1138
+ // Or if the key value doesn't exist in formData
1139
+ overrideFormDataWithDefaults && (keyExistsInDefaults || !keyExistsInFormData)
1124
1140
  );
1125
1141
  return acc2;
1126
1142
  }, acc);
1127
1143
  }
1128
- if (defaultSupercedesUndefined && formData === void 0) {
1144
+ if (defaultSupercedesUndefined && (!(0, import_isNil.default)(defaults) && (0, import_isNil.default)(formData) || typeof formData === "number" && isNaN(formData)) || overrideFormDataWithDefaults && !(0, import_isNil.default)(formData)) {
1129
1145
  return defaults;
1130
1146
  }
1131
1147
  return formData;
@@ -1181,6 +1197,69 @@ function isMultiSelect(validator, schema, rootSchema, experimental_customMergeAl
1181
1197
  return isSelect(validator, schema.items, rootSchema, experimental_customMergeAllOf);
1182
1198
  }
1183
1199
 
1200
+ // src/constIsAjvDataReference.ts
1201
+ var import_isString3 = __toESM(require("lodash/isString"));
1202
+ function constIsAjvDataReference(schema) {
1203
+ const schemaConst = schema[CONST_KEY];
1204
+ const schemaType = getSchemaType(schema);
1205
+ return isObject(schemaConst) && (0, import_isString3.default)(schemaConst?.$data) && schemaType !== "object" && schemaType !== "array";
1206
+ }
1207
+
1208
+ // src/toConstant.ts
1209
+ function toConstant(schema) {
1210
+ if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
1211
+ return schema.enum[0];
1212
+ }
1213
+ if (CONST_KEY in schema) {
1214
+ return schema.const;
1215
+ }
1216
+ throw new Error("schema cannot be inferred as a constant");
1217
+ }
1218
+
1219
+ // src/optionsList.ts
1220
+ function optionsList(schema, uiSchema) {
1221
+ const schemaWithEnumNames = schema;
1222
+ if (schema.enum) {
1223
+ let enumNames;
1224
+ if (uiSchema) {
1225
+ const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
1226
+ enumNames = uiEnumNames;
1227
+ }
1228
+ if (!enumNames && schemaWithEnumNames.enumNames) {
1229
+ if (true) {
1230
+ console.warn(
1231
+ '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.'
1232
+ );
1233
+ }
1234
+ enumNames = schemaWithEnumNames.enumNames;
1235
+ }
1236
+ return schema.enum.map((value, i) => {
1237
+ const label = enumNames?.[i] || String(value);
1238
+ return { label, value };
1239
+ });
1240
+ }
1241
+ let altSchemas = void 0;
1242
+ let altUiSchemas = void 0;
1243
+ if (schema.anyOf) {
1244
+ altSchemas = schema.anyOf;
1245
+ altUiSchemas = uiSchema?.anyOf;
1246
+ } else if (schema.oneOf) {
1247
+ altSchemas = schema.oneOf;
1248
+ altUiSchemas = uiSchema?.oneOf;
1249
+ }
1250
+ return altSchemas && altSchemas.map((aSchemaDef, index) => {
1251
+ const { title } = getUiOptions(altUiSchemas?.[index]);
1252
+ const aSchema = aSchemaDef;
1253
+ const value = toConstant(aSchema);
1254
+ const label = title || aSchema.title || String(value);
1255
+ return {
1256
+ schema: aSchema,
1257
+ label,
1258
+ value
1259
+ };
1260
+ });
1261
+ }
1262
+
1184
1263
  // src/schema/getDefaultFormState.ts
1185
1264
  var PRIMITIVE_TYPES = ["string", "number", "integer", "boolean", "null"];
1186
1265
  function getInnerSchemaForArrayItem(schema, additionalItems = 0 /* Ignore */, idx = -1) {
@@ -1204,8 +1283,8 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1204
1283
  if (includeUndefinedValues || isConst) {
1205
1284
  obj[key] = computedDefault;
1206
1285
  } else if (emptyObjectFields !== "skipDefaults") {
1286
+ const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1207
1287
  if (isObject(computedDefault)) {
1208
- const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1209
1288
  if (emptyObjectFields === "skipEmptyDefaults") {
1210
1289
  if (!(0, import_isEmpty.default)(computedDefault)) {
1211
1290
  obj[key] = computedDefault;
@@ -1216,8 +1295,9 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1216
1295
  } else if (
1217
1296
  // Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
1218
1297
  // Condition 1: computedDefault is not undefined
1219
- // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults) or if the key is a required field
1220
- computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || requiredFields.includes(key))
1298
+ // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults)
1299
+ // Or if isSelfOrParentRequired is 'true' and the key is a required field
1300
+ computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || emptyObjectFields === "skipEmptyDefaults" || isSelfOrParentRequired && requiredFields.includes(key))
1221
1301
  ) {
1222
1302
  obj[key] = computedDefault;
1223
1303
  }
@@ -1232,7 +1312,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1232
1312
  _recurseList = [],
1233
1313
  experimental_defaultFormStateBehavior = void 0,
1234
1314
  experimental_customMergeAllOf = void 0,
1235
- required
1315
+ required,
1316
+ shouldMergeDefaultsIntoFormData = false
1236
1317
  } = computeDefaultsProps;
1237
1318
  const formData = isObject(rawFormData) ? rawFormData : {};
1238
1319
  const schema = isObject(rawSchema) ? rawSchema : {};
@@ -1240,8 +1321,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1240
1321
  let schemaToCompute = null;
1241
1322
  let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
1242
1323
  let updatedRecurseList = _recurseList;
1243
- if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never") {
1244
- defaults = schema.const;
1324
+ if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(schema)) {
1325
+ defaults = schema[CONST_KEY];
1245
1326
  } else if (isObject(defaults) && isObject(schema.default)) {
1246
1327
  defaults = mergeObjects(defaults, schema.default);
1247
1328
  } else if (DEFAULT_KEY in schema) {
@@ -1277,7 +1358,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1277
1358
  experimental_customMergeAllOf,
1278
1359
  parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : void 0,
1279
1360
  rawFormData: formData,
1280
- required
1361
+ required,
1362
+ shouldMergeDefaultsIntoFormData
1281
1363
  })
1282
1364
  );
1283
1365
  } else if (ONE_OF_KEY in schema) {
@@ -1288,12 +1370,15 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1288
1370
  const discriminator = getDiscriminatorFieldFromSchema(schema);
1289
1371
  const { type = "null" } = remaining;
1290
1372
  if (!Array.isArray(type) && PRIMITIVE_TYPES.includes(type) && experimental_dfsb_to_compute?.constAsDefaults === "skipOneOf") {
1291
- experimental_dfsb_to_compute = { ...experimental_dfsb_to_compute, constAsDefaults: "never" };
1373
+ experimental_dfsb_to_compute = {
1374
+ ...experimental_dfsb_to_compute,
1375
+ constAsDefaults: "never"
1376
+ };
1292
1377
  }
1293
1378
  schemaToCompute = oneOf[getClosestMatchingOption(
1294
1379
  validator,
1295
1380
  rootSchema,
1296
- (0, import_isEmpty.default)(formData) ? void 0 : formData,
1381
+ rawFormData,
1297
1382
  oneOf,
1298
1383
  0,
1299
1384
  discriminator,
@@ -1309,7 +1394,7 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1309
1394
  schemaToCompute = anyOf[getClosestMatchingOption(
1310
1395
  validator,
1311
1396
  rootSchema,
1312
- (0, import_isEmpty.default)(formData) ? void 0 : formData,
1397
+ rawFormData,
1313
1398
  anyOf,
1314
1399
  0,
1315
1400
  discriminator,
@@ -1326,14 +1411,49 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1326
1411
  experimental_customMergeAllOf,
1327
1412
  parentDefaults: defaults,
1328
1413
  rawFormData: formData,
1329
- required
1414
+ required,
1415
+ shouldMergeDefaultsIntoFormData
1330
1416
  });
1331
1417
  }
1332
1418
  if (defaults === void 0) {
1333
1419
  defaults = schema.default;
1334
1420
  }
1335
1421
  const defaultBasedOnSchemaType = getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults);
1336
- return defaultBasedOnSchemaType ?? defaults;
1422
+ let defaultsWithFormData = defaultBasedOnSchemaType ?? defaults;
1423
+ if (shouldMergeDefaultsIntoFormData) {
1424
+ const { arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1425
+ const { mergeExtraDefaults } = arrayMinItems;
1426
+ const matchingFormData = ensureFormDataMatchingSchema(
1427
+ validator,
1428
+ schema,
1429
+ rootSchema,
1430
+ rawFormData,
1431
+ experimental_defaultFormStateBehavior
1432
+ );
1433
+ if (!isObject(rawFormData)) {
1434
+ defaultsWithFormData = mergeDefaultsWithFormData(
1435
+ defaultsWithFormData,
1436
+ matchingFormData,
1437
+ mergeExtraDefaults,
1438
+ true
1439
+ );
1440
+ }
1441
+ }
1442
+ return defaultsWithFormData;
1443
+ }
1444
+ function ensureFormDataMatchingSchema(validator, schema, rootSchema, formData, experimental_defaultFormStateBehavior) {
1445
+ const isSelectField = !isConstant(schema) && isSelect(validator, schema, rootSchema);
1446
+ let validFormData = formData;
1447
+ if (isSelectField) {
1448
+ const getOptionsList = optionsList(schema);
1449
+ const isValid = getOptionsList?.some((option) => deepEquals(option.value, formData));
1450
+ validFormData = isValid ? formData : void 0;
1451
+ }
1452
+ const constTakesPrecedence = schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults === "always";
1453
+ if (constTakesPrecedence) {
1454
+ validFormData = schema.const;
1455
+ }
1456
+ return validFormData;
1337
1457
  }
1338
1458
  function getObjectDefaults(validator, rawSchema, {
1339
1459
  rawFormData,
@@ -1342,7 +1462,8 @@ function getObjectDefaults(validator, rawSchema, {
1342
1462
  _recurseList = [],
1343
1463
  experimental_defaultFormStateBehavior = void 0,
1344
1464
  experimental_customMergeAllOf = void 0,
1345
- required
1465
+ required,
1466
+ shouldMergeDefaultsIntoFormData
1346
1467
  } = {}, defaults) {
1347
1468
  {
1348
1469
  const formData = isObject(rawFormData) ? rawFormData : {};
@@ -1353,7 +1474,7 @@ function getObjectDefaults(validator, rawSchema, {
1353
1474
  (acc, key) => {
1354
1475
  const propertySchema = (0, import_get7.default)(retrievedSchema, [PROPERTIES_KEY, key]);
1355
1476
  const hasParentConst = isObject(parentConst) && parentConst[key] !== void 0;
1356
- const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never";
1477
+ const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema || hasParentConst) && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(propertySchema);
1357
1478
  const computedDefault = computeDefaults(validator, propertySchema, {
1358
1479
  rootSchema,
1359
1480
  _recurseList,
@@ -1362,7 +1483,8 @@ function getObjectDefaults(validator, rawSchema, {
1362
1483
  includeUndefinedValues: includeUndefinedValues === true,
1363
1484
  parentDefaults: (0, import_get7.default)(defaults, [key]),
1364
1485
  rawFormData: (0, import_get7.default)(formData, [key]),
1365
- required: retrievedSchema.required?.includes(key)
1486
+ required: retrievedSchema.required?.includes(key),
1487
+ shouldMergeDefaultsIntoFormData
1366
1488
  });
1367
1489
  maybeAddDefaultToObject(
1368
1490
  acc,
@@ -1380,16 +1502,16 @@ function getObjectDefaults(validator, rawSchema, {
1380
1502
  );
1381
1503
  if (retrievedSchema.additionalProperties) {
1382
1504
  const additionalPropertiesSchema = isObject(retrievedSchema.additionalProperties) ? retrievedSchema.additionalProperties : {};
1383
- const keys = /* @__PURE__ */ new Set();
1505
+ const keys2 = /* @__PURE__ */ new Set();
1384
1506
  if (isObject(defaults)) {
1385
- Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys.add(key));
1507
+ Object.keys(defaults).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => keys2.add(key));
1386
1508
  }
1387
1509
  const formDataRequired = [];
1388
1510
  Object.keys(formData).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => {
1389
- keys.add(key);
1511
+ keys2.add(key);
1390
1512
  formDataRequired.push(key);
1391
1513
  });
1392
- keys.forEach((key) => {
1514
+ keys2.forEach((key) => {
1393
1515
  const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
1394
1516
  rootSchema,
1395
1517
  _recurseList,
@@ -1398,7 +1520,8 @@ function getObjectDefaults(validator, rawSchema, {
1398
1520
  includeUndefinedValues: includeUndefinedValues === true,
1399
1521
  parentDefaults: (0, import_get7.default)(defaults, [key]),
1400
1522
  rawFormData: (0, import_get7.default)(formData, [key]),
1401
- required: retrievedSchema.required?.includes(key)
1523
+ required: retrievedSchema.required?.includes(key),
1524
+ shouldMergeDefaultsIntoFormData
1402
1525
  });
1403
1526
  maybeAddDefaultToObject(
1404
1527
  objectDefaults,
@@ -1419,7 +1542,8 @@ function getArrayDefaults(validator, rawSchema, {
1419
1542
  _recurseList = [],
1420
1543
  experimental_defaultFormStateBehavior = void 0,
1421
1544
  experimental_customMergeAllOf = void 0,
1422
- required
1545
+ required,
1546
+ shouldMergeDefaultsIntoFormData
1423
1547
  } = {}, defaults) {
1424
1548
  const schema = rawSchema;
1425
1549
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -1439,7 +1563,8 @@ function getArrayDefaults(validator, rawSchema, {
1439
1563
  experimental_defaultFormStateBehavior,
1440
1564
  experimental_customMergeAllOf,
1441
1565
  parentDefaults: item,
1442
- required
1566
+ required,
1567
+ shouldMergeDefaultsIntoFormData
1443
1568
  });
1444
1569
  });
1445
1570
  }
@@ -1456,7 +1581,8 @@ function getArrayDefaults(validator, rawSchema, {
1456
1581
  experimental_customMergeAllOf,
1457
1582
  rawFormData: item,
1458
1583
  parentDefaults: (0, import_get7.default)(defaults, [idx]),
1459
- required
1584
+ required,
1585
+ shouldMergeDefaultsIntoFormData
1460
1586
  });
1461
1587
  });
1462
1588
  const mergeExtraDefaults = (ignoreMinItemsFlagSet && required || isPopulateAll) && arrayMergeExtraDefaults;
@@ -1486,7 +1612,8 @@ function getArrayDefaults(validator, rawSchema, {
1486
1612
  _recurseList,
1487
1613
  experimental_defaultFormStateBehavior,
1488
1614
  experimental_customMergeAllOf,
1489
- required
1615
+ required,
1616
+ shouldMergeDefaultsIntoFormData
1490
1617
  })
1491
1618
  );
1492
1619
  return defaultEntries.concat(fillerEntries);
@@ -1511,21 +1638,24 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
1511
1638
  includeUndefinedValues,
1512
1639
  experimental_defaultFormStateBehavior,
1513
1640
  experimental_customMergeAllOf,
1514
- rawFormData: formData
1641
+ rawFormData: formData,
1642
+ shouldMergeDefaultsIntoFormData: true
1515
1643
  });
1516
- if (formData === void 0 || formData === null || typeof formData === "number" && isNaN(formData)) {
1517
- return defaults;
1518
- }
1519
- const { mergeDefaultsIntoFormData, arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1520
- const { mergeExtraDefaults } = arrayMinItems;
1521
- const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1522
- if (isObject(formData)) {
1523
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1524
- }
1525
- if (Array.isArray(formData)) {
1526
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1644
+ if (isObject(formData) || Array.isArray(formData)) {
1645
+ const { mergeDefaultsIntoFormData } = experimental_defaultFormStateBehavior || {};
1646
+ const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1647
+ const result = mergeDefaultsWithFormData(
1648
+ defaults,
1649
+ formData,
1650
+ true,
1651
+ // set to true to add any additional default array entries.
1652
+ defaultSupercedesUndefined,
1653
+ true
1654
+ // set to true to override formData with defaults if they exist.
1655
+ );
1656
+ return result;
1527
1657
  }
1528
- return formData;
1658
+ return defaults;
1529
1659
  }
1530
1660
 
1531
1661
  // src/isCustomWidget.ts
@@ -1608,9 +1738,9 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1608
1738
  }
1609
1739
  });
1610
1740
  }
1611
- const keys = Object.keys((0, import_get8.default)(newSchema, PROPERTIES_KEY, {}));
1741
+ const keys2 = Object.keys((0, import_get8.default)(newSchema, PROPERTIES_KEY, {}));
1612
1742
  const nestedData = {};
1613
- keys.forEach((key) => {
1743
+ keys2.forEach((key) => {
1614
1744
  const formValue = (0, import_get8.default)(data, key);
1615
1745
  let oldKeyedSchema = (0, import_get8.default)(oldSchema, [PROPERTIES_KEY, key], {});
1616
1746
  let newKeyedSchema = (0, import_get8.default)(newSchema, [PROPERTIES_KEY, key], {});
@@ -1727,11 +1857,10 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1727
1857
 
1728
1858
  // src/schema/toIdSchema.ts
1729
1859
  var import_get9 = __toESM(require("lodash/get"));
1730
- var import_isEqual2 = __toESM(require("lodash/isEqual"));
1731
1860
  function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1732
1861
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1733
1862
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1734
- const sameSchemaIndex = _recurseList.findIndex((item) => (0, import_isEqual2.default)(item, _schema));
1863
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1735
1864
  if (sameSchemaIndex === -1) {
1736
1865
  return toIdSchemaInternal(
1737
1866
  validator,
@@ -1798,12 +1927,11 @@ function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = "roo
1798
1927
 
1799
1928
  // src/schema/toPathSchema.ts
1800
1929
  var import_get10 = __toESM(require("lodash/get"));
1801
- var import_isEqual3 = __toESM(require("lodash/isEqual"));
1802
1930
  var import_set2 = __toESM(require("lodash/set"));
1803
1931
  function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1804
1932
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1805
1933
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1806
- const sameSchemaIndex = _recurseList.findIndex((item) => (0, import_isEqual3.default)(item, _schema));
1934
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1807
1935
  if (sameSchemaIndex === -1) {
1808
1936
  return toPathSchemaInternal(
1809
1937
  validator,
@@ -2241,9 +2369,6 @@ function englishStringTranslator(stringToTranslate, params) {
2241
2369
  return replaceStringParameters(stringToTranslate, params);
2242
2370
  }
2243
2371
 
2244
- // src/enumOptionsDeselectValue.ts
2245
- var import_isEqual4 = __toESM(require("lodash/isEqual"));
2246
-
2247
2372
  // src/enumOptionsValueForIndex.ts
2248
2373
  function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2249
2374
  if (Array.isArray(valueIndex)) {
@@ -2258,18 +2383,17 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2258
2383
  function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
2259
2384
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2260
2385
  if (Array.isArray(selected)) {
2261
- return selected.filter((v) => !(0, import_isEqual4.default)(v, value));
2386
+ return selected.filter((v) => !deepEquals(v, value));
2262
2387
  }
2263
- return (0, import_isEqual4.default)(value, selected) ? void 0 : selected;
2388
+ return deepEquals(value, selected) ? void 0 : selected;
2264
2389
  }
2265
2390
 
2266
2391
  // src/enumOptionsIsSelected.ts
2267
- var import_isEqual5 = __toESM(require("lodash/isEqual"));
2268
2392
  function enumOptionsIsSelected(value, selected) {
2269
2393
  if (Array.isArray(selected)) {
2270
- return selected.some((sel) => (0, import_isEqual5.default)(sel, value));
2394
+ return selected.some((sel) => deepEquals(sel, value));
2271
2395
  }
2272
- return (0, import_isEqual5.default)(selected, value);
2396
+ return deepEquals(selected, value);
2273
2397
  }
2274
2398
 
2275
2399
  // src/enumOptionsIndexForValue.ts
@@ -2282,10 +2406,10 @@ function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false)
2282
2406
  }
2283
2407
 
2284
2408
  // src/enumOptionsSelectValue.ts
2285
- var import_isNil = __toESM(require("lodash/isNil"));
2409
+ var import_isNil2 = __toESM(require("lodash/isNil"));
2286
2410
  function enumOptionsSelectValue(valueIndex, selected, allEnumOptions = []) {
2287
2411
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2288
- if (!(0, import_isNil.default)(value)) {
2412
+ if (!(0, import_isNil2.default)(value)) {
2289
2413
  const index = allEnumOptions.findIndex((opt) => value === opt.value);
2290
2414
  const all = allEnumOptions.map(({ value: val }) => val);
2291
2415
  const updated = selected.slice(0, index).concat(value, selected.slice(index));
@@ -2615,9 +2739,9 @@ function hasWidget(schema, widget, registeredWidgets = {}) {
2615
2739
  }
2616
2740
 
2617
2741
  // src/idGenerators.ts
2618
- var import_isString3 = __toESM(require("lodash/isString"));
2742
+ var import_isString4 = __toESM(require("lodash/isString"));
2619
2743
  function idGenerator(id, suffix) {
2620
- const theId = (0, import_isString3.default)(id) ? id : id[ID_KEY];
2744
+ const theId = (0, import_isString4.default)(id) ? id : id[ID_KEY];
2621
2745
  return `${theId}__${suffix}`;
2622
2746
  }
2623
2747
  function descriptionId(id) {
@@ -2653,61 +2777,6 @@ function localToUTC(dateString) {
2653
2777
  return dateString ? new Date(dateString).toJSON() : void 0;
2654
2778
  }
2655
2779
 
2656
- // src/toConstant.ts
2657
- function toConstant(schema) {
2658
- if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
2659
- return schema.enum[0];
2660
- }
2661
- if (CONST_KEY in schema) {
2662
- return schema.const;
2663
- }
2664
- throw new Error("schema cannot be inferred as a constant");
2665
- }
2666
-
2667
- // src/optionsList.ts
2668
- function optionsList(schema, uiSchema) {
2669
- const schemaWithEnumNames = schema;
2670
- if (schema.enum) {
2671
- let enumNames;
2672
- if (uiSchema) {
2673
- const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
2674
- enumNames = uiEnumNames;
2675
- }
2676
- if (!enumNames && schemaWithEnumNames.enumNames) {
2677
- if (true) {
2678
- console.warn(
2679
- '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.'
2680
- );
2681
- }
2682
- enumNames = schemaWithEnumNames.enumNames;
2683
- }
2684
- return schema.enum.map((value, i) => {
2685
- const label = enumNames?.[i] || String(value);
2686
- return { label, value };
2687
- });
2688
- }
2689
- let altSchemas = void 0;
2690
- let altUiSchemas = void 0;
2691
- if (schema.anyOf) {
2692
- altSchemas = schema.anyOf;
2693
- altUiSchemas = uiSchema?.anyOf;
2694
- } else if (schema.oneOf) {
2695
- altSchemas = schema.oneOf;
2696
- altUiSchemas = uiSchema?.oneOf;
2697
- }
2698
- return altSchemas && altSchemas.map((aSchemaDef, index) => {
2699
- const { title } = getUiOptions(altUiSchemas?.[index]);
2700
- const aSchema = aSchemaDef;
2701
- const value = toConstant(aSchema);
2702
- const label = title || aSchema.title || String(value);
2703
- return {
2704
- schema: aSchema,
2705
- label,
2706
- value
2707
- };
2708
- });
2709
- }
2710
-
2711
2780
  // src/orderProperties.ts
2712
2781
  function orderProperties(properties, order) {
2713
2782
  if (!Array.isArray(order)) {
@@ -2929,6 +2998,29 @@ function withIdRefPrefix(schemaNode) {
2929
2998
  return schemaNode;
2930
2999
  }
2931
3000
 
3001
+ // src/getChangedFields.ts
3002
+ var import_keys = __toESM(require("lodash/keys"));
3003
+ var import_pickBy = __toESM(require("lodash/pickBy"));
3004
+ var import_isPlainObject4 = __toESM(require("lodash/isPlainObject"));
3005
+ var import_get13 = __toESM(require("lodash/get"));
3006
+ var import_difference = __toESM(require("lodash/difference"));
3007
+ function getChangedFields(a, b) {
3008
+ const aIsPlainObject = (0, import_isPlainObject4.default)(a);
3009
+ const bIsPlainObject = (0, import_isPlainObject4.default)(b);
3010
+ if (a === b || !aIsPlainObject && !bIsPlainObject) {
3011
+ return [];
3012
+ }
3013
+ if (aIsPlainObject && !bIsPlainObject) {
3014
+ return (0, import_keys.default)(a);
3015
+ } else if (!aIsPlainObject && bIsPlainObject) {
3016
+ return (0, import_keys.default)(b);
3017
+ } else {
3018
+ const unequalFields = (0, import_keys.default)((0, import_pickBy.default)(a, (value, key) => !deepEquals(value, (0, import_get13.default)(b, key))));
3019
+ const diffFields = (0, import_difference.default)((0, import_keys.default)(b), (0, import_keys.default)(a));
3020
+ return [...unequalFields, ...diffFields];
3021
+ }
3022
+ }
3023
+
2932
3024
  // src/enums.ts
2933
3025
  var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2934
3026
  TranslatableString2["ArrayItemTitle"] = "Item";
@@ -2965,11 +3057,9 @@ var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2965
3057
 
2966
3058
  // src/parser/schemaParser.ts
2967
3059
  var import_forEach = __toESM(require("lodash/forEach"));
2968
- var import_isEqual7 = __toESM(require("lodash/isEqual"));
2969
3060
 
2970
3061
  // src/parser/ParserValidator.ts
2971
- var import_get13 = __toESM(require("lodash/get"));
2972
- var import_isEqual6 = __toESM(require("lodash/isEqual"));
3062
+ var import_get14 = __toESM(require("lodash/get"));
2973
3063
  var ParserValidator = class {
2974
3064
  /** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
2975
3065
  * first.
@@ -2995,12 +3085,12 @@ var ParserValidator = class {
2995
3085
  * @param hash - The hash value at which to map the schema
2996
3086
  */
2997
3087
  addSchema(schema, hash) {
2998
- const key = (0, import_get13.default)(schema, ID_KEY, hash);
3088
+ const key = (0, import_get14.default)(schema, ID_KEY, hash);
2999
3089
  const identifiedSchema = { ...schema, [ID_KEY]: key };
3000
3090
  const existing = this.schemaMap[key];
3001
3091
  if (!existing) {
3002
3092
  this.schemaMap[key] = identifiedSchema;
3003
- } else if (!(0, import_isEqual6.default)(existing, identifiedSchema)) {
3093
+ } else if (!deepEquals(existing, identifiedSchema)) {
3004
3094
  console.error("existing schema:", JSON.stringify(existing, null, 2));
3005
3095
  console.error("new schema:", JSON.stringify(identifiedSchema, null, 2));
3006
3096
  throw new Error(
@@ -3022,7 +3112,7 @@ var ParserValidator = class {
3022
3112
  * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
3023
3113
  */
3024
3114
  isValid(schema, _formData, rootSchema) {
3025
- if (!(0, import_isEqual6.default)(rootSchema, this.rootSchema)) {
3115
+ if (!deepEquals(rootSchema, this.rootSchema)) {
3026
3116
  throw new Error("Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema");
3027
3117
  }
3028
3118
  this.addSchema(schema, hashForSchema(schema));
@@ -3062,7 +3152,7 @@ var ParserValidator = class {
3062
3152
  function parseSchema(validator, recurseList, rootSchema, schema) {
3063
3153
  const schemas = retrieveSchemaInternal(validator, schema, rootSchema, void 0, true);
3064
3154
  schemas.forEach((schema2) => {
3065
- const sameSchemaIndex = recurseList.findIndex((item) => (0, import_isEqual7.default)(item, schema2));
3155
+ const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema2));
3066
3156
  if (sameSchemaIndex === -1) {
3067
3157
  recurseList.push(schema2);
3068
3158
  const allOptions = resolveAnyOrOneOfSchemas(validator, schema2, rootSchema, true);