@rjsf/utils 5.23.2 → 5.24.1

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 (48) hide show
  1. package/dist/index.js +217 -130
  2. package/dist/index.js.map +4 -4
  3. package/dist/utils.esm.js +217 -130
  4. package/dist/utils.esm.js.map +4 -4
  5. package/dist/utils.umd.js +209 -122
  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/mergeDefaultsWithFormData.d.ts +5 -1
  20. package/lib/mergeDefaultsWithFormData.js +31 -8
  21. package/lib/mergeDefaultsWithFormData.js.map +1 -1
  22. package/lib/parser/ParserValidator.js +3 -3
  23. package/lib/parser/ParserValidator.js.map +1 -1
  24. package/lib/parser/schemaParser.js +4 -4
  25. package/lib/parser/schemaParser.js.map +1 -1
  26. package/lib/schema/getDefaultFormState.d.ts +17 -2
  27. package/lib/schema/getDefaultFormState.js +85 -31
  28. package/lib/schema/getDefaultFormState.js.map +1 -1
  29. package/lib/schema/retrieveSchema.js +7 -4
  30. package/lib/schema/retrieveSchema.js.map +1 -1
  31. package/lib/schema/toIdSchema.js +2 -2
  32. package/lib/schema/toIdSchema.js.map +1 -1
  33. package/lib/schema/toPathSchema.js +3 -3
  34. package/lib/schema/toPathSchema.js.map +1 -1
  35. package/lib/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +2 -2
  37. package/src/constIsAjvDataReference.ts +17 -0
  38. package/src/enumOptionsDeselectValue.ts +3 -4
  39. package/src/enumOptionsIsSelected.ts +3 -4
  40. package/src/getChangedFields.ts +40 -0
  41. package/src/index.ts +2 -0
  42. package/src/mergeDefaultsWithFormData.ts +42 -10
  43. package/src/parser/ParserValidator.ts +3 -3
  44. package/src/parser/schemaParser.ts +4 -4
  45. package/src/schema/getDefaultFormState.ts +126 -31
  46. package/src/schema/retrieveSchema.ts +8 -5
  47. package/src/schema/toIdSchema.ts +2 -2
  48. 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,
@@ -419,7 +420,6 @@ function getFirstMatchingOption(validator, formData, options, rootSchema, discri
419
420
 
420
421
  // src/schema/retrieveSchema.ts
421
422
  var import_get4 = __toESM(require("lodash/get"));
422
- var import_isEqual = __toESM(require("lodash/isEqual"));
423
423
  var import_set = __toESM(require("lodash/set"));
424
424
  var import_times = __toESM(require("lodash/times"));
425
425
  var import_transform = __toESM(require("lodash/transform"));
@@ -641,7 +641,10 @@ function resolveSchema(validator, schema, rootSchema, expandAllBranches, recurse
641
641
  )
642
642
  );
643
643
  const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
644
- return allPermutations.map((permutation) => ({ ...schema, allOf: permutation }));
644
+ return allPermutations.map((permutation) => ({
645
+ ...schema,
646
+ allOf: permutation
647
+ }));
645
648
  }
646
649
  return [schema];
647
650
  }
@@ -694,7 +697,7 @@ function resolveAllReferences(schema, rootSchema, recurseList) {
694
697
  items: resolveAllReferences(resolvedSchema.items, rootSchema, recurseList)
695
698
  };
696
699
  }
697
- return (0, import_isEqual.default)(schema, resolvedSchema) ? schema : resolvedSchema;
700
+ return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema;
698
701
  }
699
702
  function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData, experimental_customMergeAllOf) {
700
703
  const schema = {
@@ -1097,38 +1100,48 @@ function isFixedItems(schema) {
1097
1100
 
1098
1101
  // src/mergeDefaultsWithFormData.ts
1099
1102
  var import_get6 = __toESM(require("lodash/get"));
1100
- 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) {
1101
1105
  if (Array.isArray(formData)) {
1102
1106
  const defaultsArray = Array.isArray(defaults) ? defaults : [];
1103
- const mapped = formData.map((value, idx) => {
1104
- 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]) {
1105
1111
  return mergeDefaultsWithFormData(
1106
1112
  defaultsArray[idx],
1107
- value,
1113
+ formData[idx],
1108
1114
  mergeExtraArrayDefaults,
1109
- defaultSupercedesUndefined
1115
+ defaultSupercedesUndefined,
1116
+ overrideFormDataWithDefaults
1110
1117
  );
1111
1118
  }
1112
1119
  return value;
1113
1120
  });
1114
- if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
1115
- mapped.push(...defaultsArray.slice(mapped.length));
1121
+ if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) {
1122
+ mapped.push(...overrideOppositeArray.slice(mapped.length));
1116
1123
  }
1117
1124
  return mapped;
1118
1125
  }
1119
1126
  if (isObject(formData)) {
1120
1127
  const acc = Object.assign({}, defaults);
1121
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;
1122
1132
  acc2[key] = mergeDefaultsWithFormData(
1123
1133
  defaults ? (0, import_get6.default)(defaults, key) : {},
1124
- (0, import_get6.default)(formData, key),
1134
+ keyValue,
1125
1135
  mergeExtraArrayDefaults,
1126
- 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)
1127
1140
  );
1128
1141
  return acc2;
1129
1142
  }, acc);
1130
1143
  }
1131
- 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)) {
1132
1145
  return defaults;
1133
1146
  }
1134
1147
  return formData;
@@ -1184,6 +1197,69 @@ function isMultiSelect(validator, schema, rootSchema, experimental_customMergeAl
1184
1197
  return isSelect(validator, schema.items, rootSchema, experimental_customMergeAllOf);
1185
1198
  }
1186
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
+
1187
1263
  // src/schema/getDefaultFormState.ts
1188
1264
  var PRIMITIVE_TYPES = ["string", "number", "integer", "boolean", "null"];
1189
1265
  function getInnerSchemaForArrayItem(schema, additionalItems = 0 /* Ignore */, idx = -1) {
@@ -1207,8 +1283,8 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1207
1283
  if (includeUndefinedValues || isConst) {
1208
1284
  obj[key] = computedDefault;
1209
1285
  } else if (emptyObjectFields !== "skipDefaults") {
1286
+ const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1210
1287
  if (isObject(computedDefault)) {
1211
- const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
1212
1288
  if (emptyObjectFields === "skipEmptyDefaults") {
1213
1289
  if (!(0, import_isEmpty.default)(computedDefault)) {
1214
1290
  obj[key] = computedDefault;
@@ -1219,8 +1295,9 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
1219
1295
  } else if (
1220
1296
  // Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
1221
1297
  // Condition 1: computedDefault is not undefined
1222
- // Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults) or if the key is a required field
1223
- 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))
1224
1301
  ) {
1225
1302
  obj[key] = computedDefault;
1226
1303
  }
@@ -1235,7 +1312,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1235
1312
  _recurseList = [],
1236
1313
  experimental_defaultFormStateBehavior = void 0,
1237
1314
  experimental_customMergeAllOf = void 0,
1238
- required
1315
+ required,
1316
+ shouldMergeDefaultsIntoFormData = false
1239
1317
  } = computeDefaultsProps;
1240
1318
  const formData = isObject(rawFormData) ? rawFormData : {};
1241
1319
  const schema = isObject(rawSchema) ? rawSchema : {};
@@ -1243,8 +1321,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1243
1321
  let schemaToCompute = null;
1244
1322
  let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
1245
1323
  let updatedRecurseList = _recurseList;
1246
- if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never") {
1247
- defaults = schema.const;
1324
+ if (schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults !== "never" && !constIsAjvDataReference(schema)) {
1325
+ defaults = schema[CONST_KEY];
1248
1326
  } else if (isObject(defaults) && isObject(schema.default)) {
1249
1327
  defaults = mergeObjects(defaults, schema.default);
1250
1328
  } else if (DEFAULT_KEY in schema) {
@@ -1280,7 +1358,8 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1280
1358
  experimental_customMergeAllOf,
1281
1359
  parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : void 0,
1282
1360
  rawFormData: formData,
1283
- required
1361
+ required,
1362
+ shouldMergeDefaultsIntoFormData
1284
1363
  })
1285
1364
  );
1286
1365
  } else if (ONE_OF_KEY in schema) {
@@ -1291,12 +1370,15 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1291
1370
  const discriminator = getDiscriminatorFieldFromSchema(schema);
1292
1371
  const { type = "null" } = remaining;
1293
1372
  if (!Array.isArray(type) && PRIMITIVE_TYPES.includes(type) && experimental_dfsb_to_compute?.constAsDefaults === "skipOneOf") {
1294
- experimental_dfsb_to_compute = { ...experimental_dfsb_to_compute, constAsDefaults: "never" };
1373
+ experimental_dfsb_to_compute = {
1374
+ ...experimental_dfsb_to_compute,
1375
+ constAsDefaults: "never"
1376
+ };
1295
1377
  }
1296
1378
  schemaToCompute = oneOf[getClosestMatchingOption(
1297
1379
  validator,
1298
1380
  rootSchema,
1299
- (0, import_isEmpty.default)(formData) ? void 0 : formData,
1381
+ rawFormData,
1300
1382
  oneOf,
1301
1383
  0,
1302
1384
  discriminator,
@@ -1312,7 +1394,7 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1312
1394
  schemaToCompute = anyOf[getClosestMatchingOption(
1313
1395
  validator,
1314
1396
  rootSchema,
1315
- (0, import_isEmpty.default)(formData) ? void 0 : formData,
1397
+ rawFormData,
1316
1398
  anyOf,
1317
1399
  0,
1318
1400
  discriminator,
@@ -1329,14 +1411,49 @@ function computeDefaults(validator, rawSchema, computeDefaultsProps = {}) {
1329
1411
  experimental_customMergeAllOf,
1330
1412
  parentDefaults: defaults,
1331
1413
  rawFormData: formData,
1332
- required
1414
+ required,
1415
+ shouldMergeDefaultsIntoFormData
1333
1416
  });
1334
1417
  }
1335
1418
  if (defaults === void 0) {
1336
1419
  defaults = schema.default;
1337
1420
  }
1338
1421
  const defaultBasedOnSchemaType = getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults);
1339
- 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;
1340
1457
  }
1341
1458
  function getObjectDefaults(validator, rawSchema, {
1342
1459
  rawFormData,
@@ -1345,7 +1462,8 @@ function getObjectDefaults(validator, rawSchema, {
1345
1462
  _recurseList = [],
1346
1463
  experimental_defaultFormStateBehavior = void 0,
1347
1464
  experimental_customMergeAllOf = void 0,
1348
- required
1465
+ required,
1466
+ shouldMergeDefaultsIntoFormData
1349
1467
  } = {}, defaults) {
1350
1468
  {
1351
1469
  const formData = isObject(rawFormData) ? rawFormData : {};
@@ -1356,7 +1474,7 @@ function getObjectDefaults(validator, rawSchema, {
1356
1474
  (acc, key) => {
1357
1475
  const propertySchema = (0, import_get7.default)(retrievedSchema, [PROPERTIES_KEY, key]);
1358
1476
  const hasParentConst = isObject(parentConst) && parentConst[key] !== void 0;
1359
- 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);
1360
1478
  const computedDefault = computeDefaults(validator, propertySchema, {
1361
1479
  rootSchema,
1362
1480
  _recurseList,
@@ -1365,7 +1483,8 @@ function getObjectDefaults(validator, rawSchema, {
1365
1483
  includeUndefinedValues: includeUndefinedValues === true,
1366
1484
  parentDefaults: (0, import_get7.default)(defaults, [key]),
1367
1485
  rawFormData: (0, import_get7.default)(formData, [key]),
1368
- required: retrievedSchema.required?.includes(key)
1486
+ required: retrievedSchema.required?.includes(key),
1487
+ shouldMergeDefaultsIntoFormData
1369
1488
  });
1370
1489
  maybeAddDefaultToObject(
1371
1490
  acc,
@@ -1383,16 +1502,16 @@ function getObjectDefaults(validator, rawSchema, {
1383
1502
  );
1384
1503
  if (retrievedSchema.additionalProperties) {
1385
1504
  const additionalPropertiesSchema = isObject(retrievedSchema.additionalProperties) ? retrievedSchema.additionalProperties : {};
1386
- const keys = /* @__PURE__ */ new Set();
1505
+ const keys2 = /* @__PURE__ */ new Set();
1387
1506
  if (isObject(defaults)) {
1388
- 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));
1389
1508
  }
1390
1509
  const formDataRequired = [];
1391
1510
  Object.keys(formData).filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key]).forEach((key) => {
1392
- keys.add(key);
1511
+ keys2.add(key);
1393
1512
  formDataRequired.push(key);
1394
1513
  });
1395
- keys.forEach((key) => {
1514
+ keys2.forEach((key) => {
1396
1515
  const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
1397
1516
  rootSchema,
1398
1517
  _recurseList,
@@ -1401,7 +1520,8 @@ function getObjectDefaults(validator, rawSchema, {
1401
1520
  includeUndefinedValues: includeUndefinedValues === true,
1402
1521
  parentDefaults: (0, import_get7.default)(defaults, [key]),
1403
1522
  rawFormData: (0, import_get7.default)(formData, [key]),
1404
- required: retrievedSchema.required?.includes(key)
1523
+ required: retrievedSchema.required?.includes(key),
1524
+ shouldMergeDefaultsIntoFormData
1405
1525
  });
1406
1526
  maybeAddDefaultToObject(
1407
1527
  objectDefaults,
@@ -1422,7 +1542,8 @@ function getArrayDefaults(validator, rawSchema, {
1422
1542
  _recurseList = [],
1423
1543
  experimental_defaultFormStateBehavior = void 0,
1424
1544
  experimental_customMergeAllOf = void 0,
1425
- required
1545
+ required,
1546
+ shouldMergeDefaultsIntoFormData
1426
1547
  } = {}, defaults) {
1427
1548
  const schema = rawSchema;
1428
1549
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -1442,7 +1563,8 @@ function getArrayDefaults(validator, rawSchema, {
1442
1563
  experimental_defaultFormStateBehavior,
1443
1564
  experimental_customMergeAllOf,
1444
1565
  parentDefaults: item,
1445
- required
1566
+ required,
1567
+ shouldMergeDefaultsIntoFormData
1446
1568
  });
1447
1569
  });
1448
1570
  }
@@ -1459,7 +1581,8 @@ function getArrayDefaults(validator, rawSchema, {
1459
1581
  experimental_customMergeAllOf,
1460
1582
  rawFormData: item,
1461
1583
  parentDefaults: (0, import_get7.default)(defaults, [idx]),
1462
- required
1584
+ required,
1585
+ shouldMergeDefaultsIntoFormData
1463
1586
  });
1464
1587
  });
1465
1588
  const mergeExtraDefaults = (ignoreMinItemsFlagSet && required || isPopulateAll) && arrayMergeExtraDefaults;
@@ -1489,7 +1612,8 @@ function getArrayDefaults(validator, rawSchema, {
1489
1612
  _recurseList,
1490
1613
  experimental_defaultFormStateBehavior,
1491
1614
  experimental_customMergeAllOf,
1492
- required
1615
+ required,
1616
+ shouldMergeDefaultsIntoFormData
1493
1617
  })
1494
1618
  );
1495
1619
  return defaultEntries.concat(fillerEntries);
@@ -1514,21 +1638,24 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
1514
1638
  includeUndefinedValues,
1515
1639
  experimental_defaultFormStateBehavior,
1516
1640
  experimental_customMergeAllOf,
1517
- rawFormData: formData
1641
+ rawFormData: formData,
1642
+ shouldMergeDefaultsIntoFormData: true
1518
1643
  });
1519
- if (formData === void 0 || formData === null || typeof formData === "number" && isNaN(formData)) {
1520
- return defaults;
1521
- }
1522
- const { mergeDefaultsIntoFormData, arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
1523
- const { mergeExtraDefaults } = arrayMinItems;
1524
- const defaultSupercedesUndefined = mergeDefaultsIntoFormData === "useDefaultIfFormDataUndefined";
1525
- if (isObject(formData)) {
1526
- return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults, defaultSupercedesUndefined);
1527
- }
1528
- if (Array.isArray(formData)) {
1529
- 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;
1530
1657
  }
1531
- return formData;
1658
+ return defaults;
1532
1659
  }
1533
1660
 
1534
1661
  // src/isCustomWidget.ts
@@ -1611,9 +1738,9 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1611
1738
  }
1612
1739
  });
1613
1740
  }
1614
- const keys = Object.keys((0, import_get8.default)(newSchema, PROPERTIES_KEY, {}));
1741
+ const keys2 = Object.keys((0, import_get8.default)(newSchema, PROPERTIES_KEY, {}));
1615
1742
  const nestedData = {};
1616
- keys.forEach((key) => {
1743
+ keys2.forEach((key) => {
1617
1744
  const formValue = (0, import_get8.default)(data, key);
1618
1745
  let oldKeyedSchema = (0, import_get8.default)(oldSchema, [PROPERTIES_KEY, key], {});
1619
1746
  let newKeyedSchema = (0, import_get8.default)(newSchema, [PROPERTIES_KEY, key], {});
@@ -1730,11 +1857,10 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
1730
1857
 
1731
1858
  // src/schema/toIdSchema.ts
1732
1859
  var import_get9 = __toESM(require("lodash/get"));
1733
- var import_isEqual2 = __toESM(require("lodash/isEqual"));
1734
1860
  function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1735
1861
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1736
1862
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1737
- const sameSchemaIndex = _recurseList.findIndex((item) => (0, import_isEqual2.default)(item, _schema));
1863
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1738
1864
  if (sameSchemaIndex === -1) {
1739
1865
  return toIdSchemaInternal(
1740
1866
  validator,
@@ -1801,12 +1927,11 @@ function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = "roo
1801
1927
 
1802
1928
  // src/schema/toPathSchema.ts
1803
1929
  var import_get10 = __toESM(require("lodash/get"));
1804
- var import_isEqual3 = __toESM(require("lodash/isEqual"));
1805
1930
  var import_set2 = __toESM(require("lodash/set"));
1806
1931
  function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
1807
1932
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
1808
1933
  const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
1809
- const sameSchemaIndex = _recurseList.findIndex((item) => (0, import_isEqual3.default)(item, _schema));
1934
+ const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
1810
1935
  if (sameSchemaIndex === -1) {
1811
1936
  return toPathSchemaInternal(
1812
1937
  validator,
@@ -2244,9 +2369,6 @@ function englishStringTranslator(stringToTranslate, params) {
2244
2369
  return replaceStringParameters(stringToTranslate, params);
2245
2370
  }
2246
2371
 
2247
- // src/enumOptionsDeselectValue.ts
2248
- var import_isEqual4 = __toESM(require("lodash/isEqual"));
2249
-
2250
2372
  // src/enumOptionsValueForIndex.ts
2251
2373
  function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2252
2374
  if (Array.isArray(valueIndex)) {
@@ -2261,18 +2383,17 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
2261
2383
  function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
2262
2384
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2263
2385
  if (Array.isArray(selected)) {
2264
- return selected.filter((v) => !(0, import_isEqual4.default)(v, value));
2386
+ return selected.filter((v) => !deepEquals(v, value));
2265
2387
  }
2266
- return (0, import_isEqual4.default)(value, selected) ? void 0 : selected;
2388
+ return deepEquals(value, selected) ? void 0 : selected;
2267
2389
  }
2268
2390
 
2269
2391
  // src/enumOptionsIsSelected.ts
2270
- var import_isEqual5 = __toESM(require("lodash/isEqual"));
2271
2392
  function enumOptionsIsSelected(value, selected) {
2272
2393
  if (Array.isArray(selected)) {
2273
- return selected.some((sel) => (0, import_isEqual5.default)(sel, value));
2394
+ return selected.some((sel) => deepEquals(sel, value));
2274
2395
  }
2275
- return (0, import_isEqual5.default)(selected, value);
2396
+ return deepEquals(selected, value);
2276
2397
  }
2277
2398
 
2278
2399
  // src/enumOptionsIndexForValue.ts
@@ -2285,10 +2406,10 @@ function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false)
2285
2406
  }
2286
2407
 
2287
2408
  // src/enumOptionsSelectValue.ts
2288
- var import_isNil = __toESM(require("lodash/isNil"));
2409
+ var import_isNil2 = __toESM(require("lodash/isNil"));
2289
2410
  function enumOptionsSelectValue(valueIndex, selected, allEnumOptions = []) {
2290
2411
  const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
2291
- if (!(0, import_isNil.default)(value)) {
2412
+ if (!(0, import_isNil2.default)(value)) {
2292
2413
  const index = allEnumOptions.findIndex((opt) => value === opt.value);
2293
2414
  const all = allEnumOptions.map(({ value: val }) => val);
2294
2415
  const updated = selected.slice(0, index).concat(value, selected.slice(index));
@@ -2618,9 +2739,9 @@ function hasWidget(schema, widget, registeredWidgets = {}) {
2618
2739
  }
2619
2740
 
2620
2741
  // src/idGenerators.ts
2621
- var import_isString3 = __toESM(require("lodash/isString"));
2742
+ var import_isString4 = __toESM(require("lodash/isString"));
2622
2743
  function idGenerator(id, suffix) {
2623
- const theId = (0, import_isString3.default)(id) ? id : id[ID_KEY];
2744
+ const theId = (0, import_isString4.default)(id) ? id : id[ID_KEY];
2624
2745
  return `${theId}__${suffix}`;
2625
2746
  }
2626
2747
  function descriptionId(id) {
@@ -2656,61 +2777,6 @@ function localToUTC(dateString) {
2656
2777
  return dateString ? new Date(dateString).toJSON() : void 0;
2657
2778
  }
2658
2779
 
2659
- // src/toConstant.ts
2660
- function toConstant(schema) {
2661
- if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
2662
- return schema.enum[0];
2663
- }
2664
- if (CONST_KEY in schema) {
2665
- return schema.const;
2666
- }
2667
- throw new Error("schema cannot be inferred as a constant");
2668
- }
2669
-
2670
- // src/optionsList.ts
2671
- function optionsList(schema, uiSchema) {
2672
- const schemaWithEnumNames = schema;
2673
- if (schema.enum) {
2674
- let enumNames;
2675
- if (uiSchema) {
2676
- const { enumNames: uiEnumNames } = getUiOptions(uiSchema);
2677
- enumNames = uiEnumNames;
2678
- }
2679
- if (!enumNames && schemaWithEnumNames.enumNames) {
2680
- if (true) {
2681
- console.warn(
2682
- '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.'
2683
- );
2684
- }
2685
- enumNames = schemaWithEnumNames.enumNames;
2686
- }
2687
- return schema.enum.map((value, i) => {
2688
- const label = enumNames?.[i] || String(value);
2689
- return { label, value };
2690
- });
2691
- }
2692
- let altSchemas = void 0;
2693
- let altUiSchemas = void 0;
2694
- if (schema.anyOf) {
2695
- altSchemas = schema.anyOf;
2696
- altUiSchemas = uiSchema?.anyOf;
2697
- } else if (schema.oneOf) {
2698
- altSchemas = schema.oneOf;
2699
- altUiSchemas = uiSchema?.oneOf;
2700
- }
2701
- return altSchemas && altSchemas.map((aSchemaDef, index) => {
2702
- const { title } = getUiOptions(altUiSchemas?.[index]);
2703
- const aSchema = aSchemaDef;
2704
- const value = toConstant(aSchema);
2705
- const label = title || aSchema.title || String(value);
2706
- return {
2707
- schema: aSchema,
2708
- label,
2709
- value
2710
- };
2711
- });
2712
- }
2713
-
2714
2780
  // src/orderProperties.ts
2715
2781
  function orderProperties(properties, order) {
2716
2782
  if (!Array.isArray(order)) {
@@ -2932,6 +2998,29 @@ function withIdRefPrefix(schemaNode) {
2932
2998
  return schemaNode;
2933
2999
  }
2934
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
+
2935
3024
  // src/enums.ts
2936
3025
  var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2937
3026
  TranslatableString2["ArrayItemTitle"] = "Item";
@@ -2968,11 +3057,9 @@ var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
2968
3057
 
2969
3058
  // src/parser/schemaParser.ts
2970
3059
  var import_forEach = __toESM(require("lodash/forEach"));
2971
- var import_isEqual7 = __toESM(require("lodash/isEqual"));
2972
3060
 
2973
3061
  // src/parser/ParserValidator.ts
2974
- var import_get13 = __toESM(require("lodash/get"));
2975
- var import_isEqual6 = __toESM(require("lodash/isEqual"));
3062
+ var import_get14 = __toESM(require("lodash/get"));
2976
3063
  var ParserValidator = class {
2977
3064
  /** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
2978
3065
  * first.
@@ -2998,12 +3085,12 @@ var ParserValidator = class {
2998
3085
  * @param hash - The hash value at which to map the schema
2999
3086
  */
3000
3087
  addSchema(schema, hash) {
3001
- const key = (0, import_get13.default)(schema, ID_KEY, hash);
3088
+ const key = (0, import_get14.default)(schema, ID_KEY, hash);
3002
3089
  const identifiedSchema = { ...schema, [ID_KEY]: key };
3003
3090
  const existing = this.schemaMap[key];
3004
3091
  if (!existing) {
3005
3092
  this.schemaMap[key] = identifiedSchema;
3006
- } else if (!(0, import_isEqual6.default)(existing, identifiedSchema)) {
3093
+ } else if (!deepEquals(existing, identifiedSchema)) {
3007
3094
  console.error("existing schema:", JSON.stringify(existing, null, 2));
3008
3095
  console.error("new schema:", JSON.stringify(identifiedSchema, null, 2));
3009
3096
  throw new Error(
@@ -3025,7 +3112,7 @@ var ParserValidator = class {
3025
3112
  * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
3026
3113
  */
3027
3114
  isValid(schema, _formData, rootSchema) {
3028
- if (!(0, import_isEqual6.default)(rootSchema, this.rootSchema)) {
3115
+ if (!deepEquals(rootSchema, this.rootSchema)) {
3029
3116
  throw new Error("Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema");
3030
3117
  }
3031
3118
  this.addSchema(schema, hashForSchema(schema));
@@ -3065,7 +3152,7 @@ var ParserValidator = class {
3065
3152
  function parseSchema(validator, recurseList, rootSchema, schema) {
3066
3153
  const schemas = retrieveSchemaInternal(validator, schema, rootSchema, void 0, true);
3067
3154
  schemas.forEach((schema2) => {
3068
- const sameSchemaIndex = recurseList.findIndex((item) => (0, import_isEqual7.default)(item, schema2));
3155
+ const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema2));
3069
3156
  if (sameSchemaIndex === -1) {
3070
3157
  recurseList.push(schema2);
3071
3158
  const allOptions = resolveAnyOrOneOfSchemas(validator, schema2, rootSchema, true);