@limetech/lime-elements 39.20.0 → 39.22.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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/limel-chip_2.cjs.entry.js +2 -2
- package/dist/cjs/limel-form.cjs.entry.js +1111 -263
- package/dist/collection/components/chip-set/chip-set.js +3 -2
- package/dist/esm/{_baseEach-CL_-rBMy.js → _baseEach-C4UJIc96.js} +1 -1
- package/dist/esm/{_baseIsEqual-BfXMsuGh.js → _baseIsEqual-DCZXUzsZ.js} +1 -1
- package/dist/esm/{_baseIteratee-kS1-0_xD.js → _baseIteratee-CI-QZdpx.js} +1 -1
- package/dist/esm/{_getAllKeysIn-BKpeslPJ.js → _getAllKeysIn-v-KlW5r_.js} +1 -1
- package/dist/esm/{cloneDeep-BXAw5H-1.js → cloneDeep-V4fB8wfG.js} +2 -2
- package/dist/esm/{difference-DMAjHh-t.js → difference-CWrdq-hd.js} +1 -1
- package/dist/esm/{isEmpty-DrFXbHWO.js → isEmpty-BFxMjh_H.js} +1 -1
- package/dist/esm/{isEqual-CpaoJ_AF.js → isEqual-CsrptmTU.js} +1 -1
- package/dist/esm/limel-chip_2.entry.js +5 -5
- package/dist/esm/limel-dialog.entry.js +2 -2
- package/dist/esm/limel-file-dropzone_2.entry.js +3 -3
- package/dist/esm/limel-form.entry.js +1127 -279
- package/dist/esm/limel-prosemirror-adapter.entry.js +4 -4
- package/dist/esm/limel-tab-bar.entry.js +3 -3
- package/dist/esm/limel-table.entry.js +5 -5
- package/dist/esm/{pickBy-BEA90LIZ.js → pickBy-D8CUtxE4.js} +2 -2
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/p-29a59535.entry.js +13 -0
- package/dist/lime-elements/p-34d1d00a.entry.js +1 -0
- package/dist/lime-elements/{p-4ca67b17.entry.js → p-48db87d3.entry.js} +1 -1
- package/dist/lime-elements/{p-757896f5.entry.js → p-4e9baf08.entry.js} +1 -1
- package/dist/lime-elements/{p-BbU4FGNT.js → p-7uuv3HUP.js} +1 -1
- package/dist/lime-elements/{p-4ce682cf.entry.js → p-8139d26a.entry.js} +1 -1
- package/dist/lime-elements/{p-CMjGNANG.js → p-BTHqaZIi.js} +1 -1
- package/dist/lime-elements/p-Bj622DVt.js +1 -0
- package/dist/lime-elements/p-C3Myy3mA.js +1 -0
- package/dist/lime-elements/{p-xQsJdKrq.js → p-CXgJVvTe.js} +1 -1
- package/dist/lime-elements/p-CxfAgSVd.js +1 -0
- package/dist/lime-elements/{p-DFWcgJ_i.js → p-DNIqLXTL.js} +1 -1
- package/dist/lime-elements/p-DbC-smVQ.js +1 -0
- package/dist/lime-elements/p-SvuA3Boo.js +1 -0
- package/dist/lime-elements/{p-cffc137e.entry.js → p-e720f65c.entry.js} +3 -3
- package/dist/lime-elements/{p-8065425a.entry.js → p-fd4a4f87.entry.js} +1 -1
- package/dist/types/components/chip-set/chip-set.d.ts +1 -0
- package/dist/types/components/chip-set/chip.types.d.ts +4 -0
- package/dist/types/components.d.ts +4 -0
- package/package.json +4 -4
- package/dist/lime-elements/p-B3zCFNAw.js +0 -1
- package/dist/lime-elements/p-B6bNnxRu.js +0 -1
- package/dist/lime-elements/p-BCMRfUKp.js +0 -1
- package/dist/lime-elements/p-DTXIk0fN.js +0 -1
- package/dist/lime-elements/p-UGKt6Ywx.js +0 -1
- package/dist/lime-elements/p-cae35eb0.entry.js +0 -1
- package/dist/lime-elements/p-e60ffc0a.entry.js +0 -13
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var index$1 = require('./index-BjHIBY-I.js');
|
|
4
4
|
var _commonjsHelpers = require('./_commonjsHelpers-CFO10eej.js');
|
|
5
|
-
var _baseIsEqual = require('./_baseIsEqual-aOPReRWl.js');
|
|
6
5
|
var _baseIteratee = require('./_baseIteratee-DggA4e7a.js');
|
|
7
6
|
var pickBy = require('./pickBy-kLjYLoam.js');
|
|
8
|
-
var
|
|
7
|
+
var _baseIsEqual = require('./_baseIsEqual-aOPReRWl.js');
|
|
9
8
|
var identity$1 = require('./identity-Dz5mxHaJ.js');
|
|
10
9
|
var _isIterateeCall = require('./_isIterateeCall-CPWXFS_s.js');
|
|
11
10
|
var cloneDeep = require('./cloneDeep-CxFNKF1Y.js');
|
|
@@ -20,6 +19,7 @@ var isObjectLike = require('./isObjectLike-Dlpn-j-1.js');
|
|
|
20
19
|
var isEmpty = require('./isEmpty-EBCFxX1S.js');
|
|
21
20
|
var isSymbol = require('./isSymbol-DxAVNJfH.js');
|
|
22
21
|
var isArrayLike = require('./isArrayLike-_dR1U5-Y.js');
|
|
22
|
+
var isEqual = require('./isEqual-bXyw7kXo.js');
|
|
23
23
|
var moment = require('./moment-CqRdiK10.js');
|
|
24
24
|
var multiple = require('./multiple-DYfiga7l.js');
|
|
25
25
|
require('./_getNative-B4n5HX2B.js');
|
|
@@ -149,7 +149,7 @@ var funcProto = Function.prototype,
|
|
|
149
149
|
var funcToString = funcProto.toString;
|
|
150
150
|
|
|
151
151
|
/** Used to check objects for own properties. */
|
|
152
|
-
var hasOwnProperty$
|
|
152
|
+
var hasOwnProperty$2 = objectProto$1.hasOwnProperty;
|
|
153
153
|
|
|
154
154
|
/** Used to infer the `Object` constructor. */
|
|
155
155
|
var objectCtorString = funcToString.call(Object);
|
|
@@ -190,7 +190,7 @@ function isPlainObject(value) {
|
|
|
190
190
|
if (proto === null) {
|
|
191
191
|
return true;
|
|
192
192
|
}
|
|
193
|
-
var Ctor = hasOwnProperty$
|
|
193
|
+
var Ctor = hasOwnProperty$2.call(proto, 'constructor') && proto.constructor;
|
|
194
194
|
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
195
195
|
funcToString.call(Ctor) == objectCtorString;
|
|
196
196
|
}
|
|
@@ -906,44 +906,6 @@ function parent(object, path) {
|
|
|
906
906
|
return path.length < 2 ? object : _baseIteratee.baseGet(object, baseSlice(path, 0, -1));
|
|
907
907
|
}
|
|
908
908
|
|
|
909
|
-
/**
|
|
910
|
-
* This method is like `_.isEqual` except that it accepts `customizer` which
|
|
911
|
-
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
912
|
-
* are handled by the method instead. The `customizer` is invoked with up to
|
|
913
|
-
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
|
914
|
-
*
|
|
915
|
-
* @static
|
|
916
|
-
* @memberOf _
|
|
917
|
-
* @since 4.0.0
|
|
918
|
-
* @category Lang
|
|
919
|
-
* @param {*} value The value to compare.
|
|
920
|
-
* @param {*} other The other value to compare.
|
|
921
|
-
* @param {Function} [customizer] The function to customize comparisons.
|
|
922
|
-
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
923
|
-
* @example
|
|
924
|
-
*
|
|
925
|
-
* function isGreeting(value) {
|
|
926
|
-
* return /^h(?:i|ello)$/.test(value);
|
|
927
|
-
* }
|
|
928
|
-
*
|
|
929
|
-
* function customizer(objValue, othValue) {
|
|
930
|
-
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
|
931
|
-
* return true;
|
|
932
|
-
* }
|
|
933
|
-
* }
|
|
934
|
-
*
|
|
935
|
-
* var array = ['hello', 'goodbye'];
|
|
936
|
-
* var other = ['hi', 'goodbye'];
|
|
937
|
-
*
|
|
938
|
-
* _.isEqualWith(array, other, customizer);
|
|
939
|
-
* // => true
|
|
940
|
-
*/
|
|
941
|
-
function isEqualWith(value, other, customizer) {
|
|
942
|
-
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
943
|
-
var result = customizer ? customizer(value, other) : undefined;
|
|
944
|
-
return result === undefined ? _baseIsEqual.baseIsEqual(value, other, undefined, customizer) : !!result;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
909
|
/** `Object#toString` result references. */
|
|
948
910
|
var numberTag = '[object Number]';
|
|
949
911
|
|
|
@@ -1100,7 +1062,7 @@ var merge = createAssigner(function(object, source, srcIndex) {
|
|
|
1100
1062
|
var objectProto = Object.prototype;
|
|
1101
1063
|
|
|
1102
1064
|
/** Used to check objects for own properties. */
|
|
1103
|
-
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
1065
|
+
var hasOwnProperty$1 = objectProto.hasOwnProperty;
|
|
1104
1066
|
|
|
1105
1067
|
/**
|
|
1106
1068
|
* The base implementation of `_.unset`.
|
|
@@ -1127,7 +1089,7 @@ function baseUnset(object, path) {
|
|
|
1127
1089
|
var key = _baseIteratee.toKey(path[index]);
|
|
1128
1090
|
|
|
1129
1091
|
// Always block "__proto__" anywhere in the path if it's not expected
|
|
1130
|
-
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
|
|
1092
|
+
if (key === '__proto__' && !hasOwnProperty$1.call(object, '__proto__')) {
|
|
1131
1093
|
return false;
|
|
1132
1094
|
}
|
|
1133
1095
|
|
|
@@ -18535,24 +18497,634 @@ function createErrorHandler(formData) {
|
|
|
18535
18497
|
return handler;
|
|
18536
18498
|
}
|
|
18537
18499
|
|
|
18538
|
-
|
|
18539
|
-
|
|
18500
|
+
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
18501
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
18502
|
+
const { hasOwnProperty } = Object.prototype;
|
|
18503
|
+
/**
|
|
18504
|
+
* Combine two comparators into a single comparators.
|
|
18505
|
+
*/
|
|
18506
|
+
function combineComparators(comparatorA, comparatorB) {
|
|
18507
|
+
return function isEqual(a, b, state) {
|
|
18508
|
+
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
|
18509
|
+
};
|
|
18510
|
+
}
|
|
18511
|
+
/**
|
|
18512
|
+
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
|
18513
|
+
* for circular references to be safely included in the comparison without creating
|
|
18514
|
+
* stack overflows.
|
|
18515
|
+
*/
|
|
18516
|
+
function createIsCircular(areItemsEqual) {
|
|
18517
|
+
return function isCircular(a, b, state) {
|
|
18518
|
+
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
|
18519
|
+
return areItemsEqual(a, b, state);
|
|
18520
|
+
}
|
|
18521
|
+
const { cache } = state;
|
|
18522
|
+
const cachedA = cache.get(a);
|
|
18523
|
+
const cachedB = cache.get(b);
|
|
18524
|
+
if (cachedA && cachedB) {
|
|
18525
|
+
return cachedA === b && cachedB === a;
|
|
18526
|
+
}
|
|
18527
|
+
cache.set(a, b);
|
|
18528
|
+
cache.set(b, a);
|
|
18529
|
+
const result = areItemsEqual(a, b, state);
|
|
18530
|
+
cache.delete(a);
|
|
18531
|
+
cache.delete(b);
|
|
18532
|
+
return result;
|
|
18533
|
+
};
|
|
18534
|
+
}
|
|
18535
|
+
/**
|
|
18536
|
+
* Get the properties to strictly examine, which include both own properties that are
|
|
18537
|
+
* not enumerable and symbol properties.
|
|
18538
|
+
*/
|
|
18539
|
+
function getStrictProperties(object) {
|
|
18540
|
+
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
|
18541
|
+
}
|
|
18542
|
+
/**
|
|
18543
|
+
* Whether the object contains the property passed as an own property.
|
|
18544
|
+
*/
|
|
18545
|
+
const hasOwn =
|
|
18546
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18547
|
+
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
|
|
18548
|
+
|
|
18549
|
+
const PREACT_VNODE = '__v';
|
|
18550
|
+
const PREACT_OWNER = '__o';
|
|
18551
|
+
const REACT_OWNER = '_owner';
|
|
18552
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
18553
|
+
/**
|
|
18554
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
18555
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
18556
|
+
*
|
|
18557
|
+
* @note
|
|
18558
|
+
* When available in the environment, this is just a re-export of the global
|
|
18559
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
18560
|
+
*/
|
|
18561
|
+
const sameValueEqual =
|
|
18562
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18563
|
+
Object.is
|
|
18564
|
+
|| function sameValueEqual(a, b) {
|
|
18565
|
+
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
|
18566
|
+
};
|
|
18567
|
+
/**
|
|
18568
|
+
* Whether the values passed are equal based on a
|
|
18569
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
18570
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
18540
18571
|
*
|
|
18541
|
-
* @
|
|
18542
|
-
*
|
|
18543
|
-
*
|
|
18572
|
+
* @note
|
|
18573
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
18574
|
+
* two objects is used.
|
|
18544
18575
|
*/
|
|
18545
|
-
function
|
|
18546
|
-
return
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18576
|
+
function strictEqual(a, b) {
|
|
18577
|
+
return a === b;
|
|
18578
|
+
}
|
|
18579
|
+
/**
|
|
18580
|
+
* Whether the array buffers are equal in value.
|
|
18581
|
+
*/
|
|
18582
|
+
function areArrayBuffersEqual(a, b) {
|
|
18583
|
+
return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));
|
|
18584
|
+
}
|
|
18585
|
+
/**
|
|
18586
|
+
* Whether the arrays are equal in value.
|
|
18587
|
+
*/
|
|
18588
|
+
function areArraysEqual(a, b, state) {
|
|
18589
|
+
let index = a.length;
|
|
18590
|
+
if (b.length !== index) {
|
|
18591
|
+
return false;
|
|
18592
|
+
}
|
|
18593
|
+
while (index-- > 0) {
|
|
18594
|
+
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
|
18595
|
+
return false;
|
|
18596
|
+
}
|
|
18597
|
+
}
|
|
18598
|
+
return true;
|
|
18599
|
+
}
|
|
18600
|
+
/**
|
|
18601
|
+
* Whether the dataviews are equal in value.
|
|
18602
|
+
*/
|
|
18603
|
+
function areDataViewsEqual(a, b) {
|
|
18604
|
+
return (a.byteLength === b.byteLength
|
|
18605
|
+
&& areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength)));
|
|
18606
|
+
}
|
|
18607
|
+
/**
|
|
18608
|
+
* Whether the dates passed are equal in value.
|
|
18609
|
+
*/
|
|
18610
|
+
function areDatesEqual(a, b) {
|
|
18611
|
+
return sameValueEqual(a.getTime(), b.getTime());
|
|
18612
|
+
}
|
|
18613
|
+
/**
|
|
18614
|
+
* Whether the errors passed are equal in value.
|
|
18615
|
+
*/
|
|
18616
|
+
function areErrorsEqual(a, b) {
|
|
18617
|
+
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
18618
|
+
}
|
|
18619
|
+
/**
|
|
18620
|
+
* Whether the `Map`s are equal in value.
|
|
18621
|
+
*/
|
|
18622
|
+
function areMapsEqual(a, b, state) {
|
|
18623
|
+
const size = a.size;
|
|
18624
|
+
if (size !== b.size) {
|
|
18625
|
+
return false;
|
|
18626
|
+
}
|
|
18627
|
+
if (!size) {
|
|
18628
|
+
return true;
|
|
18629
|
+
}
|
|
18630
|
+
const matchedIndices = new Array(size);
|
|
18631
|
+
const aIterable = a.entries();
|
|
18632
|
+
let aResult;
|
|
18633
|
+
let bResult;
|
|
18634
|
+
let index = 0;
|
|
18635
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18636
|
+
while ((aResult = aIterable.next())) {
|
|
18637
|
+
if (aResult.done) {
|
|
18638
|
+
break;
|
|
18639
|
+
}
|
|
18640
|
+
const bIterable = b.entries();
|
|
18641
|
+
let hasMatch = false;
|
|
18642
|
+
let matchIndex = 0;
|
|
18643
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18644
|
+
while ((bResult = bIterable.next())) {
|
|
18645
|
+
if (bResult.done) {
|
|
18646
|
+
break;
|
|
18647
|
+
}
|
|
18648
|
+
if (matchedIndices[matchIndex]) {
|
|
18649
|
+
matchIndex++;
|
|
18650
|
+
continue;
|
|
18651
|
+
}
|
|
18652
|
+
const aEntry = aResult.value;
|
|
18653
|
+
const bEntry = bResult.value;
|
|
18654
|
+
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state)
|
|
18655
|
+
&& state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
|
18656
|
+
hasMatch = matchedIndices[matchIndex] = true;
|
|
18657
|
+
break;
|
|
18658
|
+
}
|
|
18659
|
+
matchIndex++;
|
|
18660
|
+
}
|
|
18661
|
+
if (!hasMatch) {
|
|
18662
|
+
return false;
|
|
18663
|
+
}
|
|
18664
|
+
index++;
|
|
18665
|
+
}
|
|
18666
|
+
return true;
|
|
18667
|
+
}
|
|
18668
|
+
/**
|
|
18669
|
+
* Whether the objects are equal in value.
|
|
18670
|
+
*/
|
|
18671
|
+
function areObjectsEqual(a, b, state) {
|
|
18672
|
+
const properties = keys(a);
|
|
18673
|
+
let index = properties.length;
|
|
18674
|
+
if (keys(b).length !== index) {
|
|
18675
|
+
return false;
|
|
18676
|
+
}
|
|
18677
|
+
// Decrementing `while` showed faster results than either incrementing or
|
|
18678
|
+
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
18679
|
+
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
18680
|
+
// cost of anonymous callbacks.
|
|
18681
|
+
while (index-- > 0) {
|
|
18682
|
+
if (!isPropertyEqual(a, b, state, properties[index])) {
|
|
18683
|
+
return false;
|
|
18684
|
+
}
|
|
18685
|
+
}
|
|
18686
|
+
return true;
|
|
18687
|
+
}
|
|
18688
|
+
/**
|
|
18689
|
+
* Whether the objects are equal in value with strict property checking.
|
|
18690
|
+
*/
|
|
18691
|
+
function areObjectsEqualStrict(a, b, state) {
|
|
18692
|
+
const properties = getStrictProperties(a);
|
|
18693
|
+
let index = properties.length;
|
|
18694
|
+
if (getStrictProperties(b).length !== index) {
|
|
18695
|
+
return false;
|
|
18696
|
+
}
|
|
18697
|
+
let property;
|
|
18698
|
+
let descriptorA;
|
|
18699
|
+
let descriptorB;
|
|
18700
|
+
// Decrementing `while` showed faster results than either incrementing or
|
|
18701
|
+
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
18702
|
+
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
18703
|
+
// cost of anonymous callbacks.
|
|
18704
|
+
while (index-- > 0) {
|
|
18705
|
+
property = properties[index];
|
|
18706
|
+
if (!isPropertyEqual(a, b, state, property)) {
|
|
18707
|
+
return false;
|
|
18708
|
+
}
|
|
18709
|
+
descriptorA = getOwnPropertyDescriptor(a, property);
|
|
18710
|
+
descriptorB = getOwnPropertyDescriptor(b, property);
|
|
18711
|
+
if ((descriptorA || descriptorB)
|
|
18712
|
+
&& (!descriptorA
|
|
18713
|
+
|| !descriptorB
|
|
18714
|
+
|| descriptorA.configurable !== descriptorB.configurable
|
|
18715
|
+
|| descriptorA.enumerable !== descriptorB.enumerable
|
|
18716
|
+
|| descriptorA.writable !== descriptorB.writable)) {
|
|
18717
|
+
return false;
|
|
18718
|
+
}
|
|
18719
|
+
}
|
|
18720
|
+
return true;
|
|
18721
|
+
}
|
|
18722
|
+
/**
|
|
18723
|
+
* Whether the primitive wrappers passed are equal in value.
|
|
18724
|
+
*/
|
|
18725
|
+
function arePrimitiveWrappersEqual(a, b) {
|
|
18726
|
+
return sameValueEqual(a.valueOf(), b.valueOf());
|
|
18727
|
+
}
|
|
18728
|
+
/**
|
|
18729
|
+
* Whether the regexps passed are equal in value.
|
|
18730
|
+
*/
|
|
18731
|
+
function areRegExpsEqual(a, b) {
|
|
18732
|
+
return a.source === b.source && a.flags === b.flags;
|
|
18733
|
+
}
|
|
18734
|
+
/**
|
|
18735
|
+
* Whether the `Set`s are equal in value.
|
|
18736
|
+
*/
|
|
18737
|
+
function areSetsEqual(a, b, state) {
|
|
18738
|
+
const size = a.size;
|
|
18739
|
+
if (size !== b.size) {
|
|
18740
|
+
return false;
|
|
18741
|
+
}
|
|
18742
|
+
if (!size) {
|
|
18743
|
+
return true;
|
|
18744
|
+
}
|
|
18745
|
+
const matchedIndices = new Array(size);
|
|
18746
|
+
const aIterable = a.values();
|
|
18747
|
+
let aResult;
|
|
18748
|
+
let bResult;
|
|
18749
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18750
|
+
while ((aResult = aIterable.next())) {
|
|
18751
|
+
if (aResult.done) {
|
|
18752
|
+
break;
|
|
18753
|
+
}
|
|
18754
|
+
const bIterable = b.values();
|
|
18755
|
+
let hasMatch = false;
|
|
18756
|
+
let matchIndex = 0;
|
|
18757
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18758
|
+
while ((bResult = bIterable.next())) {
|
|
18759
|
+
if (bResult.done) {
|
|
18760
|
+
break;
|
|
18761
|
+
}
|
|
18762
|
+
if (!matchedIndices[matchIndex]
|
|
18763
|
+
&& state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
|
18764
|
+
hasMatch = matchedIndices[matchIndex] = true;
|
|
18765
|
+
break;
|
|
18766
|
+
}
|
|
18767
|
+
matchIndex++;
|
|
18768
|
+
}
|
|
18769
|
+
if (!hasMatch) {
|
|
18770
|
+
return false;
|
|
18771
|
+
}
|
|
18772
|
+
}
|
|
18773
|
+
return true;
|
|
18774
|
+
}
|
|
18775
|
+
/**
|
|
18776
|
+
* Whether the TypedArray instances are equal in value.
|
|
18777
|
+
*/
|
|
18778
|
+
function areTypedArraysEqual(a, b) {
|
|
18779
|
+
let index = a.byteLength;
|
|
18780
|
+
if (b.byteLength !== index || a.byteOffset !== b.byteOffset) {
|
|
18781
|
+
return false;
|
|
18782
|
+
}
|
|
18783
|
+
while (index-- > 0) {
|
|
18784
|
+
if (a[index] !== b[index]) {
|
|
18785
|
+
return false;
|
|
18786
|
+
}
|
|
18787
|
+
}
|
|
18788
|
+
return true;
|
|
18789
|
+
}
|
|
18790
|
+
/**
|
|
18791
|
+
* Whether the URL instances are equal in value.
|
|
18792
|
+
*/
|
|
18793
|
+
function areUrlsEqual(a, b) {
|
|
18794
|
+
return (a.hostname === b.hostname
|
|
18795
|
+
&& a.pathname === b.pathname
|
|
18796
|
+
&& a.protocol === b.protocol
|
|
18797
|
+
&& a.port === b.port
|
|
18798
|
+
&& a.hash === b.hash
|
|
18799
|
+
&& a.username === b.username
|
|
18800
|
+
&& a.password === b.password);
|
|
18801
|
+
}
|
|
18802
|
+
function isPropertyEqual(a, b, state, property) {
|
|
18803
|
+
if ((property === REACT_OWNER || property === PREACT_OWNER || property === PREACT_VNODE)
|
|
18804
|
+
&& (a.$$typeof || b.$$typeof)) {
|
|
18805
|
+
return true;
|
|
18806
|
+
}
|
|
18807
|
+
return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);
|
|
18808
|
+
}
|
|
18809
|
+
|
|
18810
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
18811
|
+
const toString = Object.prototype.toString;
|
|
18812
|
+
/**
|
|
18813
|
+
* Create a comparator method based on the type-specific equality comparators passed.
|
|
18814
|
+
*/
|
|
18815
|
+
function createEqualityComparator(config) {
|
|
18816
|
+
const supportedComparatorMap = createSupportedComparatorMap(config);
|
|
18817
|
+
const { areArraysEqual, areDatesEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, areRegExpsEqual, areSetsEqual, getUnsupportedCustomComparator, } = config;
|
|
18818
|
+
/**
|
|
18819
|
+
* compare the value of the two objects and return true if they are equivalent in values
|
|
18820
|
+
*/
|
|
18821
|
+
return function comparator(a, b, state) {
|
|
18822
|
+
// If the items are strictly equal, no need to do a value comparison.
|
|
18823
|
+
if (a === b) {
|
|
18550
18824
|
return true;
|
|
18551
18825
|
}
|
|
18552
|
-
|
|
18553
|
-
|
|
18826
|
+
// If either of the items are nullish and fail the strictly equal check
|
|
18827
|
+
// above, then they must be unequal.
|
|
18828
|
+
if (a == null || b == null) {
|
|
18829
|
+
return false;
|
|
18830
|
+
}
|
|
18831
|
+
const type = typeof a;
|
|
18832
|
+
if (type !== typeof b) {
|
|
18833
|
+
return false;
|
|
18834
|
+
}
|
|
18835
|
+
if (type !== 'object') {
|
|
18836
|
+
if (type === 'number' || type === 'bigint') {
|
|
18837
|
+
return areNumbersEqual(a, b, state);
|
|
18838
|
+
}
|
|
18839
|
+
if (type === 'function') {
|
|
18840
|
+
return areFunctionsEqual(a, b, state);
|
|
18841
|
+
}
|
|
18842
|
+
// If a primitive value that is not strictly equal, it must be unequal.
|
|
18843
|
+
return false;
|
|
18844
|
+
}
|
|
18845
|
+
const constructor = a.constructor;
|
|
18846
|
+
// Checks are listed in order of commonality of use-case:
|
|
18847
|
+
// 1. Common complex object types (plain object, array)
|
|
18848
|
+
// 2. Common data values (date, regexp)
|
|
18849
|
+
// 3. Less-common complex object types (map, set)
|
|
18850
|
+
// 4. Less-common data values (promise, primitive wrappers)
|
|
18851
|
+
// Inherently this is both subjective and assumptive, however
|
|
18852
|
+
// when reviewing comparable libraries in the wild this order
|
|
18853
|
+
// appears to be generally consistent.
|
|
18854
|
+
// Constructors should match, otherwise there is potential for false positives
|
|
18855
|
+
// between class and subclass or custom object and POJO.
|
|
18856
|
+
if (constructor !== b.constructor) {
|
|
18857
|
+
return false;
|
|
18858
|
+
}
|
|
18859
|
+
// Try to fast-path equality checks for other complex object types in the
|
|
18860
|
+
// same realm to avoid capturing the string tag. Strict equality is used
|
|
18861
|
+
// instead of `instanceof` because it is more performant for the common
|
|
18862
|
+
// use-case. If someone is creating a subclass from a native class, it will be
|
|
18863
|
+
// handled with the string tag comparison.
|
|
18864
|
+
if (constructor === Object) {
|
|
18865
|
+
return areObjectsEqual(a, b, state);
|
|
18866
|
+
}
|
|
18867
|
+
if (constructor === Array) {
|
|
18868
|
+
return areArraysEqual(a, b, state);
|
|
18869
|
+
}
|
|
18870
|
+
if (constructor === Date) {
|
|
18871
|
+
return areDatesEqual(a, b, state);
|
|
18872
|
+
}
|
|
18873
|
+
if (constructor === RegExp) {
|
|
18874
|
+
return areRegExpsEqual(a, b, state);
|
|
18875
|
+
}
|
|
18876
|
+
if (constructor === Map) {
|
|
18877
|
+
return areMapsEqual(a, b, state);
|
|
18878
|
+
}
|
|
18879
|
+
if (constructor === Set) {
|
|
18880
|
+
return areSetsEqual(a, b, state);
|
|
18881
|
+
}
|
|
18882
|
+
if (constructor === Promise) {
|
|
18883
|
+
// Avoid tag checks for promise values, since we know if they are not referentially equal
|
|
18884
|
+
// then they are not equal.
|
|
18885
|
+
return false;
|
|
18886
|
+
}
|
|
18887
|
+
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
|
18888
|
+
// the string tag or doing an `instanceof` in edge cases.
|
|
18889
|
+
if (Array.isArray(a)) {
|
|
18890
|
+
return areArraysEqual(a, b, state);
|
|
18891
|
+
}
|
|
18892
|
+
// Since this is a custom object, capture the string tag to determining its type.
|
|
18893
|
+
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
|
18894
|
+
const tag = toString.call(a);
|
|
18895
|
+
const supportedComparator = supportedComparatorMap[tag];
|
|
18896
|
+
if (supportedComparator) {
|
|
18897
|
+
return supportedComparator(a, b, state);
|
|
18898
|
+
}
|
|
18899
|
+
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);
|
|
18900
|
+
if (unsupportedCustomComparator) {
|
|
18901
|
+
return unsupportedCustomComparator(a, b, state);
|
|
18902
|
+
}
|
|
18903
|
+
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
|
18904
|
+
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
|
18905
|
+
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
|
18906
|
+
// comparison that can be made.
|
|
18907
|
+
// - For types that can be introspected but do not have an objective definition of what
|
|
18908
|
+
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
|
18909
|
+
// In all cases, these decisions should be reevaluated based on changes to the language and
|
|
18910
|
+
// common development practices.
|
|
18911
|
+
return false;
|
|
18912
|
+
};
|
|
18913
|
+
}
|
|
18914
|
+
/**
|
|
18915
|
+
* Create the configuration object used for building comparators.
|
|
18916
|
+
*/
|
|
18917
|
+
function createEqualityComparatorConfig({ circular, createCustomConfig, strict, }) {
|
|
18918
|
+
let config = {
|
|
18919
|
+
areArrayBuffersEqual,
|
|
18920
|
+
areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
|
|
18921
|
+
areDataViewsEqual,
|
|
18922
|
+
areDatesEqual: areDatesEqual,
|
|
18923
|
+
areErrorsEqual: areErrorsEqual,
|
|
18924
|
+
areFunctionsEqual: strictEqual,
|
|
18925
|
+
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
18926
|
+
areNumbersEqual: sameValueEqual,
|
|
18927
|
+
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
18928
|
+
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
|
18929
|
+
areRegExpsEqual: areRegExpsEqual,
|
|
18930
|
+
areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
|
|
18931
|
+
areTypedArraysEqual: strict
|
|
18932
|
+
? combineComparators(areTypedArraysEqual, areObjectsEqualStrict)
|
|
18933
|
+
: areTypedArraysEqual,
|
|
18934
|
+
areUrlsEqual: areUrlsEqual,
|
|
18935
|
+
getUnsupportedCustomComparator: undefined,
|
|
18936
|
+
};
|
|
18937
|
+
if (createCustomConfig) {
|
|
18938
|
+
config = Object.assign({}, config, createCustomConfig(config));
|
|
18939
|
+
}
|
|
18940
|
+
if (circular) {
|
|
18941
|
+
const areArraysEqual = createIsCircular(config.areArraysEqual);
|
|
18942
|
+
const areMapsEqual = createIsCircular(config.areMapsEqual);
|
|
18943
|
+
const areObjectsEqual = createIsCircular(config.areObjectsEqual);
|
|
18944
|
+
const areSetsEqual = createIsCircular(config.areSetsEqual);
|
|
18945
|
+
config = Object.assign({}, config, {
|
|
18946
|
+
areArraysEqual,
|
|
18947
|
+
areMapsEqual,
|
|
18948
|
+
areObjectsEqual,
|
|
18949
|
+
areSetsEqual,
|
|
18950
|
+
});
|
|
18951
|
+
}
|
|
18952
|
+
return config;
|
|
18953
|
+
}
|
|
18954
|
+
/**
|
|
18955
|
+
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
|
18956
|
+
* use inside the built comparator.
|
|
18957
|
+
*/
|
|
18958
|
+
function createInternalEqualityComparator(compare) {
|
|
18959
|
+
return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
|
|
18960
|
+
return compare(a, b, state);
|
|
18961
|
+
};
|
|
18962
|
+
}
|
|
18963
|
+
/**
|
|
18964
|
+
* Create the `isEqual` function used by the consuming application.
|
|
18965
|
+
*/
|
|
18966
|
+
function createIsEqual({ circular, comparator, createState, equals, strict }) {
|
|
18967
|
+
if (createState) {
|
|
18968
|
+
return function isEqual(a, b) {
|
|
18969
|
+
const { cache = circular ? new WeakMap() : undefined, meta } = createState();
|
|
18970
|
+
return comparator(a, b, {
|
|
18971
|
+
cache,
|
|
18972
|
+
equals,
|
|
18973
|
+
meta,
|
|
18974
|
+
strict,
|
|
18975
|
+
});
|
|
18976
|
+
};
|
|
18977
|
+
}
|
|
18978
|
+
if (circular) {
|
|
18979
|
+
return function isEqual(a, b) {
|
|
18980
|
+
return comparator(a, b, {
|
|
18981
|
+
cache: new WeakMap(),
|
|
18982
|
+
equals,
|
|
18983
|
+
meta: undefined,
|
|
18984
|
+
strict,
|
|
18985
|
+
});
|
|
18986
|
+
};
|
|
18987
|
+
}
|
|
18988
|
+
const state = {
|
|
18989
|
+
cache: undefined,
|
|
18990
|
+
equals,
|
|
18991
|
+
meta: undefined,
|
|
18992
|
+
strict,
|
|
18993
|
+
};
|
|
18994
|
+
return function isEqual(a, b) {
|
|
18995
|
+
return comparator(a, b, state);
|
|
18996
|
+
};
|
|
18997
|
+
}
|
|
18998
|
+
/**
|
|
18999
|
+
* Create a map of `toString()` values to their respective handlers for `tag`-based lookups.
|
|
19000
|
+
*/
|
|
19001
|
+
function createSupportedComparatorMap({ areArrayBuffersEqual, areArraysEqual, areDataViewsEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, }) {
|
|
19002
|
+
return {
|
|
19003
|
+
'[object Arguments]': areObjectsEqual,
|
|
19004
|
+
'[object Array]': areArraysEqual,
|
|
19005
|
+
'[object ArrayBuffer]': areArrayBuffersEqual,
|
|
19006
|
+
'[object AsyncGeneratorFunction]': areFunctionsEqual,
|
|
19007
|
+
'[object BigInt]': areNumbersEqual,
|
|
19008
|
+
'[object BigInt64Array]': areTypedArraysEqual,
|
|
19009
|
+
'[object BigUint64Array]': areTypedArraysEqual,
|
|
19010
|
+
'[object Boolean]': arePrimitiveWrappersEqual,
|
|
19011
|
+
'[object DataView]': areDataViewsEqual,
|
|
19012
|
+
'[object Date]': areDatesEqual,
|
|
19013
|
+
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
|
19014
|
+
// enumerable, and therefore will give false positives if tested like a standard object.
|
|
19015
|
+
'[object Error]': areErrorsEqual,
|
|
19016
|
+
'[object Float16Array]': areTypedArraysEqual,
|
|
19017
|
+
'[object Float32Array]': areTypedArraysEqual,
|
|
19018
|
+
'[object Float64Array]': areTypedArraysEqual,
|
|
19019
|
+
'[object Function]': areFunctionsEqual,
|
|
19020
|
+
'[object GeneratorFunction]': areFunctionsEqual,
|
|
19021
|
+
'[object Int8Array]': areTypedArraysEqual,
|
|
19022
|
+
'[object Int16Array]': areTypedArraysEqual,
|
|
19023
|
+
'[object Int32Array]': areTypedArraysEqual,
|
|
19024
|
+
'[object Map]': areMapsEqual,
|
|
19025
|
+
'[object Number]': arePrimitiveWrappersEqual,
|
|
19026
|
+
'[object Object]': (a, b, state) =>
|
|
19027
|
+
// The exception for value comparison is custom `Promise`-like class instances. These should
|
|
19028
|
+
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
|
19029
|
+
// it reaches this point then that strict equality comparison has already failed.
|
|
19030
|
+
typeof a.then !== 'function' && typeof b.then !== 'function' && areObjectsEqual(a, b, state),
|
|
19031
|
+
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
|
19032
|
+
// tested like a standard object.
|
|
19033
|
+
'[object RegExp]': areRegExpsEqual,
|
|
19034
|
+
'[object Set]': areSetsEqual,
|
|
19035
|
+
'[object String]': arePrimitiveWrappersEqual,
|
|
19036
|
+
'[object URL]': areUrlsEqual,
|
|
19037
|
+
'[object Uint8Array]': areTypedArraysEqual,
|
|
19038
|
+
'[object Uint8ClampedArray]': areTypedArraysEqual,
|
|
19039
|
+
'[object Uint16Array]': areTypedArraysEqual,
|
|
19040
|
+
'[object Uint32Array]': areTypedArraysEqual,
|
|
19041
|
+
};
|
|
18554
19042
|
}
|
|
18555
19043
|
|
|
19044
|
+
/**
|
|
19045
|
+
* Whether the items passed are deeply-equal in value.
|
|
19046
|
+
*/
|
|
19047
|
+
createCustomEqual();
|
|
19048
|
+
/**
|
|
19049
|
+
* Whether the items passed are deeply-equal in value based on strict comparison.
|
|
19050
|
+
*/
|
|
19051
|
+
createCustomEqual({ strict: true });
|
|
19052
|
+
/**
|
|
19053
|
+
* Whether the items passed are deeply-equal in value, including circular references.
|
|
19054
|
+
*/
|
|
19055
|
+
createCustomEqual({ circular: true });
|
|
19056
|
+
/**
|
|
19057
|
+
* Whether the items passed are deeply-equal in value, including circular references,
|
|
19058
|
+
* based on strict comparison.
|
|
19059
|
+
*/
|
|
19060
|
+
createCustomEqual({
|
|
19061
|
+
circular: true,
|
|
19062
|
+
strict: true,
|
|
19063
|
+
});
|
|
19064
|
+
/**
|
|
19065
|
+
* Whether the items passed are shallowly-equal in value.
|
|
19066
|
+
*/
|
|
19067
|
+
createCustomEqual({
|
|
19068
|
+
createInternalComparator: () => sameValueEqual,
|
|
19069
|
+
});
|
|
19070
|
+
/**
|
|
19071
|
+
* Whether the items passed are shallowly-equal in value based on strict comparison
|
|
19072
|
+
*/
|
|
19073
|
+
createCustomEqual({
|
|
19074
|
+
strict: true,
|
|
19075
|
+
createInternalComparator: () => sameValueEqual,
|
|
19076
|
+
});
|
|
19077
|
+
/**
|
|
19078
|
+
* Whether the items passed are shallowly-equal in value, including circular references.
|
|
19079
|
+
*/
|
|
19080
|
+
createCustomEqual({
|
|
19081
|
+
circular: true,
|
|
19082
|
+
createInternalComparator: () => sameValueEqual,
|
|
19083
|
+
});
|
|
19084
|
+
/**
|
|
19085
|
+
* Whether the items passed are shallowly-equal in value, including circular references,
|
|
19086
|
+
* based on strict comparison.
|
|
19087
|
+
*/
|
|
19088
|
+
createCustomEqual({
|
|
19089
|
+
circular: true,
|
|
19090
|
+
createInternalComparator: () => sameValueEqual,
|
|
19091
|
+
strict: true,
|
|
19092
|
+
});
|
|
19093
|
+
/**
|
|
19094
|
+
* Create a custom equality comparison method.
|
|
19095
|
+
*
|
|
19096
|
+
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
|
19097
|
+
* where the standard methods are not performant enough, but can also be used to provide
|
|
19098
|
+
* support for legacy environments that do not support expected features like
|
|
19099
|
+
* `RegExp.prototype.flags` out of the box.
|
|
19100
|
+
*/
|
|
19101
|
+
function createCustomEqual(options = {}) {
|
|
19102
|
+
const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false, } = options;
|
|
19103
|
+
const config = createEqualityComparatorConfig(options);
|
|
19104
|
+
const comparator = createEqualityComparator(config);
|
|
19105
|
+
const equals = createCustomInternalComparator
|
|
19106
|
+
? createCustomInternalComparator(comparator)
|
|
19107
|
+
: createInternalEqualityComparator(comparator);
|
|
19108
|
+
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
19109
|
+
}
|
|
19110
|
+
|
|
19111
|
+
/** Implements a deep equals using `fast-equals.createCustomEqual`. Functions
|
|
19112
|
+
* are always considered equal, and circular references are tracked to avoid
|
|
19113
|
+
* infinite recursion on self-referential inputs.
|
|
19114
|
+
*
|
|
19115
|
+
* @param a - The first element to compare
|
|
19116
|
+
* @param b - The second element to compare
|
|
19117
|
+
* @returns - True if the `a` and `b` are deeply equal, false otherwise
|
|
19118
|
+
*/
|
|
19119
|
+
const deepEquals = createCustomEqual({
|
|
19120
|
+
circular: true,
|
|
19121
|
+
createCustomConfig: () => ({
|
|
19122
|
+
areFunctionsEqual(_a, b) {
|
|
19123
|
+
return typeof b === 'function';
|
|
19124
|
+
},
|
|
19125
|
+
}),
|
|
19126
|
+
});
|
|
19127
|
+
|
|
18556
19128
|
const objProto = Object.prototype;
|
|
18557
19129
|
function isRecordEmpty(rec) {
|
|
18558
19130
|
for (const key in rec) {
|
|
@@ -21614,7 +22186,7 @@ function findSelectedOptionInXxxOf(validator, rootSchema, schema, fallbackField,
|
|
|
21614
22186
|
const data = _baseIteratee.get(formData, selectorField);
|
|
21615
22187
|
if (data !== undefined) {
|
|
21616
22188
|
return xxxOfs.find((xxx) => {
|
|
21617
|
-
return
|
|
22189
|
+
return deepEquals(_baseIteratee.get(xxx, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], _baseIteratee.get(xxx, [PROPERTIES_KEY, selectorField, CONST_KEY])), data);
|
|
21618
22190
|
});
|
|
21619
22191
|
}
|
|
21620
22192
|
}
|
|
@@ -22498,11 +23070,6 @@ function getObjectDefaults(validator, rawSchema, { rawFormData, rootSchema = {},
|
|
|
22498
23070
|
? retrievedSchema.additionalProperties
|
|
22499
23071
|
: {};
|
|
22500
23072
|
const keys = new Set();
|
|
22501
|
-
if (isObject(defaults)) {
|
|
22502
|
-
Object.keys(defaults)
|
|
22503
|
-
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
22504
|
-
.forEach((key) => keys.add(key));
|
|
22505
|
-
}
|
|
22506
23073
|
const formDataRequired = [];
|
|
22507
23074
|
Object.keys(formData)
|
|
22508
23075
|
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
@@ -22510,6 +23077,14 @@ function getObjectDefaults(validator, rawSchema, { rawFormData, rootSchema = {},
|
|
|
22510
23077
|
keys.add(key);
|
|
22511
23078
|
formDataRequired.push(key);
|
|
22512
23079
|
});
|
|
23080
|
+
// Only seed keys from schema defaults when formData has no additionalProperties of its own.
|
|
23081
|
+
// If the user already has data (e.g. after a key rename), injecting default keys would
|
|
23082
|
+
// re-add stale entries that no longer exist in formData.
|
|
23083
|
+
if (isObject(defaults) && formDataRequired.length === 0) {
|
|
23084
|
+
Object.keys(defaults)
|
|
23085
|
+
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
23086
|
+
.forEach((key) => keys.add(key));
|
|
23087
|
+
}
|
|
22513
23088
|
keys.forEach((key) => {
|
|
22514
23089
|
var _a;
|
|
22515
23090
|
const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
|
|
@@ -23498,6 +24073,67 @@ function englishStringTranslator(stringToTranslate, params) {
|
|
|
23498
24073
|
return replaceStringParameters(stringToTranslate, params);
|
|
23499
24074
|
}
|
|
23500
24075
|
|
|
24076
|
+
/** Determines whether the given `value` is (one of) the `selected` value(s).
|
|
24077
|
+
*
|
|
24078
|
+
* @param value - The value being checked to see if it is selected
|
|
24079
|
+
* @param selected - The current selected value or list of values
|
|
24080
|
+
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
24081
|
+
*/
|
|
24082
|
+
function enumOptionsIsSelected(value, selected) {
|
|
24083
|
+
if (Array.isArray(selected)) {
|
|
24084
|
+
return selected.some((sel) => deepEquals(sel, value));
|
|
24085
|
+
}
|
|
24086
|
+
return deepEquals(selected, value);
|
|
24087
|
+
}
|
|
24088
|
+
|
|
24089
|
+
/** Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`. All the
|
|
24090
|
+
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
24091
|
+
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
24092
|
+
* returned.
|
|
24093
|
+
*
|
|
24094
|
+
* @param value - The single value or list of values for which indexes are desired
|
|
24095
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
24096
|
+
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
24097
|
+
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
24098
|
+
* of indexes for (each of) the value(s) in `value`.
|
|
24099
|
+
*/
|
|
24100
|
+
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
24101
|
+
const selectedIndexes = allEnumOptions
|
|
24102
|
+
.map((opt, index) => (enumOptionsIsSelected(opt.value, value) ? String(index) : undefined))
|
|
24103
|
+
.filter((opt) => typeof opt !== 'undefined');
|
|
24104
|
+
if (!multiple) {
|
|
24105
|
+
return selectedIndexes[0];
|
|
24106
|
+
}
|
|
24107
|
+
return selectedIndexes;
|
|
24108
|
+
}
|
|
24109
|
+
|
|
24110
|
+
/** Computes the value to pass to a select element's `value` attribute.
|
|
24111
|
+
*
|
|
24112
|
+
* When `format` is `'realValue'`, converts form data values to strings.
|
|
24113
|
+
* When `format` is `'indexed'` (the default), resolves to index-based values via
|
|
24114
|
+
* `enumOptionsIndexForValue`. Returns `emptyValue` when the current value is empty.
|
|
24115
|
+
*
|
|
24116
|
+
* @param value - The current form data value
|
|
24117
|
+
* @param enumOptions - The available enum options
|
|
24118
|
+
* @param multiple - Whether the select allows multiple selections
|
|
24119
|
+
* @param [format='indexed'] - How option values are encoded on the DOM
|
|
24120
|
+
* @param emptyValue - The value to return when the selection is empty
|
|
24121
|
+
* @returns The value to use for the select element's `value` attribute
|
|
24122
|
+
*/
|
|
24123
|
+
function enumOptionSelectedValue(value, enumOptions, multiple, format = 'indexed', emptyValue) {
|
|
24124
|
+
const isEmpty = typeof value === 'undefined' ||
|
|
24125
|
+
(multiple && Array.isArray(value) && value.length < 1) ||
|
|
24126
|
+
(!multiple && value === emptyValue);
|
|
24127
|
+
if (isEmpty) {
|
|
24128
|
+
return emptyValue;
|
|
24129
|
+
}
|
|
24130
|
+
if (format === 'realValue') {
|
|
24131
|
+
return multiple ? value.map(String) : String(value);
|
|
24132
|
+
}
|
|
24133
|
+
const indexes = enumOptionsIndexForValue(value, enumOptions, multiple);
|
|
24134
|
+
return typeof indexes === 'undefined' ? emptyValue : indexes;
|
|
24135
|
+
}
|
|
24136
|
+
|
|
23501
24137
|
/** Returns the value(s) from `allEnumOptions` at the index(es) provided by `valueIndex`. If `valueIndex` is not an
|
|
23502
24138
|
* array AND the index is not valid for `allEnumOptions`, `emptyValue` is returned. If `valueIndex` is an array, AND it
|
|
23503
24139
|
* contains an invalid index, the returned array will have the resulting undefined values filtered out, leaving only
|
|
@@ -23522,6 +24158,84 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
|
|
|
23522
24158
|
return option ? option.value : emptyValue;
|
|
23523
24159
|
}
|
|
23524
24160
|
|
|
24161
|
+
/** Resolves a single DOM value string back to its typed enum value in `'realValue'` mode.
|
|
24162
|
+
*
|
|
24163
|
+
* First attempts a reverse lookup by matching `String(opt.value)` against the input.
|
|
24164
|
+
* If no option matches and the input parses as a valid index, falls back to the
|
|
24165
|
+
* option at that index — this is how object/array enum values round-trip, since
|
|
24166
|
+
* they are encoded as indices by the encoder.
|
|
24167
|
+
*
|
|
24168
|
+
* @param value - A single string value from a DOM attribute
|
|
24169
|
+
* @param enumOptions - The available enum options
|
|
24170
|
+
* @param emptyValue - The value to return when the input is empty, options are missing, or no match is found
|
|
24171
|
+
* @returns The original typed enum value, or `emptyValue`
|
|
24172
|
+
*/
|
|
24173
|
+
function decodeSingle(value, enumOptions, emptyValue) {
|
|
24174
|
+
if (value === '' || !Array.isArray(enumOptions)) {
|
|
24175
|
+
return emptyValue;
|
|
24176
|
+
}
|
|
24177
|
+
const match = enumOptions.find((opt) => String(opt.value) === value);
|
|
24178
|
+
if (match) {
|
|
24179
|
+
return match.value;
|
|
24180
|
+
}
|
|
24181
|
+
// Fallback: value might be an index (for object/array enum values)
|
|
24182
|
+
const index = Number(value);
|
|
24183
|
+
if (!isNaN(index) && index >= 0 && index < enumOptions.length) {
|
|
24184
|
+
return enumOptions[index].value;
|
|
24185
|
+
}
|
|
24186
|
+
return emptyValue;
|
|
24187
|
+
}
|
|
24188
|
+
/** Decodes a string from a DOM value attribute back to a typed enum value.
|
|
24189
|
+
*
|
|
24190
|
+
* When `format` is `'realValue'`, does a reverse lookup: finds the enum option
|
|
24191
|
+
* whose `String(value)` matches the input string and returns the original typed value.
|
|
24192
|
+
* For object/array values that were encoded as indices, falls back to index resolution.
|
|
24193
|
+
*
|
|
24194
|
+
* When `format` is `'indexed'` (the default), uses index-based resolution via
|
|
24195
|
+
* `enumOptionsValueForIndex`.
|
|
24196
|
+
*
|
|
24197
|
+
* @param value - The string value(s) from the DOM
|
|
24198
|
+
* @param enumOptions - The available enum options
|
|
24199
|
+
* @param [format='indexed'] - How the values were encoded on the DOM
|
|
24200
|
+
* @param emptyValue - The value to return for empty/missing selections
|
|
24201
|
+
* @returns The original typed enum value(s)
|
|
24202
|
+
*/
|
|
24203
|
+
function enumOptionValueDecoder(value, enumOptions, format = 'indexed', emptyValue) {
|
|
24204
|
+
if (format !== 'realValue') {
|
|
24205
|
+
return enumOptionsValueForIndex(value, enumOptions, emptyValue);
|
|
24206
|
+
}
|
|
24207
|
+
if (Array.isArray(value)) {
|
|
24208
|
+
return value.map((v) => decodeSingle(v, enumOptions, emptyValue));
|
|
24209
|
+
}
|
|
24210
|
+
return decodeSingle(value, enumOptions, emptyValue);
|
|
24211
|
+
}
|
|
24212
|
+
|
|
24213
|
+
/** Encodes an enum option value into a string for a DOM value attribute.
|
|
24214
|
+
*
|
|
24215
|
+
* When `format` is `'realValue'`, primitive values are converted via `String()`.
|
|
24216
|
+
* Non-primitive values (objects, arrays) fall back to the index since
|
|
24217
|
+
* `String()` would produce `"[object Object]"`.
|
|
24218
|
+
*
|
|
24219
|
+
* When `format` is `'indexed'` (the default), returns the index as a string.
|
|
24220
|
+
*
|
|
24221
|
+
* @param value - The typed enum value
|
|
24222
|
+
* @param index - The option's position in the enumOptions array
|
|
24223
|
+
* @param [format='indexed'] - How to encode the value for the DOM attribute
|
|
24224
|
+
* @returns The string to use as the DOM value attribute
|
|
24225
|
+
*/
|
|
24226
|
+
function enumOptionValueEncoder(value, index, format = 'indexed') {
|
|
24227
|
+
if (format !== 'realValue') {
|
|
24228
|
+
return String(index);
|
|
24229
|
+
}
|
|
24230
|
+
if (isNil(value)) {
|
|
24231
|
+
return '';
|
|
24232
|
+
}
|
|
24233
|
+
if (typeof value === 'object') {
|
|
24234
|
+
return String(index);
|
|
24235
|
+
}
|
|
24236
|
+
return String(value);
|
|
24237
|
+
}
|
|
24238
|
+
|
|
23525
24239
|
/** Removes the enum option value at the `valueIndex` from the currently `selected` (list of) value(s). If `selected` is
|
|
23526
24240
|
* a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`. If it is
|
|
23527
24241
|
* a single value, then if the enum option value with the `valueIndex` in `allEnumOptions` matches `selected`, undefined
|
|
@@ -23542,40 +24256,6 @@ function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
|
|
|
23542
24256
|
return deepEquals(value, selected) ? undefined : selected;
|
|
23543
24257
|
}
|
|
23544
24258
|
|
|
23545
|
-
/** Determines whether the given `value` is (one of) the `selected` value(s).
|
|
23546
|
-
*
|
|
23547
|
-
* @param value - The value being checked to see if it is selected
|
|
23548
|
-
* @param selected - The current selected value or list of values
|
|
23549
|
-
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
23550
|
-
*/
|
|
23551
|
-
function enumOptionsIsSelected(value, selected) {
|
|
23552
|
-
if (Array.isArray(selected)) {
|
|
23553
|
-
return selected.some((sel) => deepEquals(sel, value));
|
|
23554
|
-
}
|
|
23555
|
-
return deepEquals(selected, value);
|
|
23556
|
-
}
|
|
23557
|
-
|
|
23558
|
-
/** Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`. All the
|
|
23559
|
-
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
23560
|
-
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
23561
|
-
* returned.
|
|
23562
|
-
*
|
|
23563
|
-
* @param value - The single value or list of values for which indexes are desired
|
|
23564
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
23565
|
-
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
23566
|
-
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
23567
|
-
* of indexes for (each of) the value(s) in `value`.
|
|
23568
|
-
*/
|
|
23569
|
-
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
23570
|
-
const selectedIndexes = allEnumOptions
|
|
23571
|
-
.map((opt, index) => (enumOptionsIsSelected(opt.value, value) ? String(index) : undefined))
|
|
23572
|
-
.filter((opt) => typeof opt !== 'undefined');
|
|
23573
|
-
if (!multiple) {
|
|
23574
|
-
return selectedIndexes[0];
|
|
23575
|
-
}
|
|
23576
|
-
return selectedIndexes;
|
|
23577
|
-
}
|
|
23578
|
-
|
|
23579
24259
|
/** Add the enum option value at the `valueIndex` to the list of `selected` values in the proper order as defined by
|
|
23580
24260
|
* `allEnumOptions`
|
|
23581
24261
|
*
|
|
@@ -23821,6 +24501,15 @@ function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = t
|
|
|
23821
24501
|
}
|
|
23822
24502
|
}
|
|
23823
24503
|
}
|
|
24504
|
+
// For date/time input types, propagate formatMinimum/formatMaximum to min/max
|
|
24505
|
+
if (['date', 'datetime-local', 'time', 'week', 'month'].includes(inputProps.type)) {
|
|
24506
|
+
if (schema.formatMinimum !== undefined) {
|
|
24507
|
+
inputProps.min = schema.formatMinimum;
|
|
24508
|
+
}
|
|
24509
|
+
if (schema.formatMaximum !== undefined) {
|
|
24510
|
+
inputProps.max = schema.formatMaximum;
|
|
24511
|
+
}
|
|
24512
|
+
}
|
|
23824
24513
|
if (options.autocomplete) {
|
|
23825
24514
|
inputProps.autoComplete = options.autocomplete;
|
|
23826
24515
|
}
|
|
@@ -23830,6 +24519,23 @@ function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = t
|
|
|
23830
24519
|
return inputProps;
|
|
23831
24520
|
}
|
|
23832
24521
|
|
|
24522
|
+
/** Resolves the effective `optionValueFormat` for enum-backed widgets.
|
|
24523
|
+
*
|
|
24524
|
+
* Provides a single source of truth for the default DOM encoding format
|
|
24525
|
+
* (`'indexed'`) used by `SelectWidget`, `RadioWidget`, and `CheckboxesWidget`.
|
|
24526
|
+
* Widgets should call this helper once and pass the result to
|
|
24527
|
+
* `enumOptionValueEncoder`, `enumOptionValueDecoder`, and `enumOptionSelectedValue`
|
|
24528
|
+
* rather than reading `options.optionValueFormat` directly.
|
|
24529
|
+
*
|
|
24530
|
+
* @param options - The widget options (typically from the `options` prop, already
|
|
24531
|
+
* resolved from `ui:options` and `ui:globalOptions`)
|
|
24532
|
+
* @returns The resolved `OptionValueFormat`, defaulting to `'indexed'` when not set
|
|
24533
|
+
*/
|
|
24534
|
+
function getOptionValueFormat(options) {
|
|
24535
|
+
var _a;
|
|
24536
|
+
return (_a = options === null || options === void 0 ? void 0 : options.optionValueFormat) !== null && _a !== void 0 ? _a : 'indexed';
|
|
24537
|
+
}
|
|
24538
|
+
|
|
23833
24539
|
/** The default submit button options, exported for testing purposes
|
|
23834
24540
|
*/
|
|
23835
24541
|
const DEFAULT_OPTIONS = {
|
|
@@ -24246,12 +24952,12 @@ function isFormDataAvailable(formData) {
|
|
|
24246
24952
|
*/
|
|
24247
24953
|
function isRootSchema(registry, schemaToCompare) {
|
|
24248
24954
|
const { rootSchema, schemaUtils } = registry;
|
|
24249
|
-
if (
|
|
24955
|
+
if (deepEquals(schemaToCompare, rootSchema)) {
|
|
24250
24956
|
return true;
|
|
24251
24957
|
}
|
|
24252
24958
|
if (REF_KEY in rootSchema) {
|
|
24253
24959
|
const resolvedSchema = schemaUtils.retrieveSchema(rootSchema);
|
|
24254
|
-
return
|
|
24960
|
+
return deepEquals(schemaToCompare, omit(resolvedSchema, RJSF_REF_KEY));
|
|
24255
24961
|
}
|
|
24256
24962
|
return false;
|
|
24257
24963
|
}
|
|
@@ -24286,6 +24992,111 @@ function lookupFromFormContext(regOrFc, toLookup, fallback) {
|
|
|
24286
24992
|
return _baseIteratee.get(regOrFc, [...lookupPath, toLookup], fallback);
|
|
24287
24993
|
}
|
|
24288
24994
|
|
|
24995
|
+
/** Determines whether a value is considered "empty" for the purposes of optional object pruning.
|
|
24996
|
+
* A value is empty if it is `undefined`, `null`, an empty string, or an object where all own
|
|
24997
|
+
* properties are themselves empty.
|
|
24998
|
+
*
|
|
24999
|
+
* @param value - The value to check
|
|
25000
|
+
* @returns True if the value is considered empty
|
|
25001
|
+
*/
|
|
25002
|
+
function isValueEmpty(value) {
|
|
25003
|
+
if (isNil(value) || value === '') {
|
|
25004
|
+
return true;
|
|
25005
|
+
}
|
|
25006
|
+
if (Array.isArray(value)) {
|
|
25007
|
+
// An empty array is considered empty; a non-empty array is not
|
|
25008
|
+
return value.length === 0;
|
|
25009
|
+
}
|
|
25010
|
+
if (isObject(value)) {
|
|
25011
|
+
const obj = value;
|
|
25012
|
+
const keys = Object.keys(obj);
|
|
25013
|
+
return keys.every((key) => isValueEmpty(obj[key]));
|
|
25014
|
+
}
|
|
25015
|
+
return false;
|
|
25016
|
+
}
|
|
25017
|
+
/** Recursively removes optional objects from the `formData` that are empty (i.e., all their fields
|
|
25018
|
+
* are undefined, null, empty strings, or themselves empty optional objects). This solves the problem
|
|
25019
|
+
* where interacting with fields inside an optional object "activates" it permanently, making the
|
|
25020
|
+
* form unsubmittable when the optional object has required inner fields.
|
|
25021
|
+
*
|
|
25022
|
+
* An object property is considered "optional" when it is NOT listed in its parent schema's `required`
|
|
25023
|
+
* array.
|
|
25024
|
+
*
|
|
25025
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
25026
|
+
* @param schema - The JSON schema describing the `formData`
|
|
25027
|
+
* @param [rootSchema] - The root schema, used primarily to look up `$ref`s
|
|
25028
|
+
* @param [formData] - The current form data to prune
|
|
25029
|
+
* @returns - A new copy of `formData` with empty optional objects removed, or `undefined` if the
|
|
25030
|
+
* entire formData was pruned
|
|
25031
|
+
*/
|
|
25032
|
+
function removeOptionalEmptyObjects(validator, schema, rootSchema, formData) {
|
|
25033
|
+
if (!isObject(schema)) {
|
|
25034
|
+
return formData;
|
|
25035
|
+
}
|
|
25036
|
+
const resolvedSchema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
25037
|
+
if (Array.isArray(formData)) {
|
|
25038
|
+
const itemsSchema = resolvedSchema.items;
|
|
25039
|
+
if (!itemsSchema) {
|
|
25040
|
+
return formData;
|
|
25041
|
+
}
|
|
25042
|
+
let hasChanges = false;
|
|
25043
|
+
const mapped = formData.map((item, index) => {
|
|
25044
|
+
let itemSchema = itemsSchema;
|
|
25045
|
+
if (Array.isArray(itemsSchema)) {
|
|
25046
|
+
itemSchema = itemsSchema[index] || resolvedSchema.additionalItems || {};
|
|
25047
|
+
}
|
|
25048
|
+
const cleaned = removeOptionalEmptyObjects(validator, itemSchema, rootSchema, item);
|
|
25049
|
+
if (cleaned !== item) {
|
|
25050
|
+
hasChanges = true;
|
|
25051
|
+
}
|
|
25052
|
+
return cleaned === undefined ? {} : cleaned;
|
|
25053
|
+
});
|
|
25054
|
+
// Although T is an array type here, we still need to cast it back to T since TS
|
|
25055
|
+
// doesn't narrow the generic T automatically
|
|
25056
|
+
return hasChanges ? mapped : formData;
|
|
25057
|
+
}
|
|
25058
|
+
const { properties, required: requiredFields = [] } = resolvedSchema;
|
|
25059
|
+
if (!isObject(formData) || !properties) {
|
|
25060
|
+
return formData;
|
|
25061
|
+
}
|
|
25062
|
+
const result = {};
|
|
25063
|
+
const data = formData;
|
|
25064
|
+
let hasAnyValue = false;
|
|
25065
|
+
for (const key of Object.keys(data)) {
|
|
25066
|
+
const value = data[key];
|
|
25067
|
+
const propertySchema = (properties[key] || {});
|
|
25068
|
+
const isRequired = requiredFields.includes(key);
|
|
25069
|
+
const isObj = isObject(value);
|
|
25070
|
+
const isArr = Array.isArray(value);
|
|
25071
|
+
if ((isObj || isArr) && properties[key]) {
|
|
25072
|
+
// Recursively process nested objects and arrays
|
|
25073
|
+
const cleaned = removeOptionalEmptyObjects(validator, propertySchema, rootSchema, value);
|
|
25074
|
+
if (!isRequired && isValueEmpty(cleaned)) {
|
|
25075
|
+
// This is an optional property and the cleaned result is empty — omit it
|
|
25076
|
+
continue;
|
|
25077
|
+
}
|
|
25078
|
+
result[key] = cleaned;
|
|
25079
|
+
hasAnyValue = true;
|
|
25080
|
+
}
|
|
25081
|
+
else if (!isRequired && isValueEmpty(value) && properties[key]) {
|
|
25082
|
+
// Optional scalar property that is empty — omit it
|
|
25083
|
+
continue;
|
|
25084
|
+
}
|
|
25085
|
+
else {
|
|
25086
|
+
result[key] = value;
|
|
25087
|
+
if (!isValueEmpty(value)) {
|
|
25088
|
+
hasAnyValue = true;
|
|
25089
|
+
}
|
|
25090
|
+
}
|
|
25091
|
+
}
|
|
25092
|
+
// If the entire object ended up empty after pruning, return undefined so that the
|
|
25093
|
+
// caller (which may itself be a recursive call) can decide whether to keep or drop it
|
|
25094
|
+
if (!hasAnyValue && Object.keys(result).length === 0) {
|
|
25095
|
+
return undefined;
|
|
25096
|
+
}
|
|
25097
|
+
return result;
|
|
25098
|
+
}
|
|
25099
|
+
|
|
24289
25100
|
/** Given a list of `properties` and an `order` list, returns a list that contains the `properties` ordered correctly.
|
|
24290
25101
|
* If `order` is not an array, then the untouched `properties` list is returned. Otherwise `properties` is ordered per
|
|
24291
25102
|
* the `order` list. If `order` contains a '*' then any `properties` that are not mentioned explicity in `order` will be
|
|
@@ -24356,104 +25167,18 @@ function parseDateString(dateString, includeTime = true) {
|
|
|
24356
25167
|
};
|
|
24357
25168
|
}
|
|
24358
25169
|
|
|
24359
|
-
// Keywords where child schemas map to uiSchema at the SAME key
|
|
24360
|
-
const SAME_KEY_KEYWORDS = [ITEMS_KEY, ADDITIONAL_PROPERTIES_KEY];
|
|
24361
|
-
// Keywords where child schemas are in an array, each mapping to uiSchema[keyword][i]
|
|
24362
|
-
const ARRAY_KEYWORDS = [ONE_OF_KEY, ANY_OF_KEY, ALL_OF_KEY];
|
|
24363
|
-
/** Expands `ui:definitions` into the uiSchema by walking the schema tree and finding all `$ref`s.
|
|
24364
|
-
* Called once at form initialization to pre-expand definitions into the uiSchema structure.
|
|
24365
|
-
*
|
|
24366
|
-
* For recursive schemas, expansion stops at recursion points to avoid infinite loops.
|
|
24367
|
-
* Runtime resolution via `resolveUiSchema` handles these cases using registry definitions.
|
|
24368
|
-
*
|
|
24369
|
-
* @param currentSchema - The current schema node being processed
|
|
24370
|
-
* @param uiSchema - The uiSchema at the current path
|
|
24371
|
-
* @param registry - The registry containing rootSchema and uiSchemaDefinitions
|
|
24372
|
-
* @param visited - Set of $refs already visited (to detect recursion)
|
|
24373
|
-
* @returns - The expanded uiSchema with definitions merged in
|
|
24374
|
-
*/
|
|
24375
|
-
function expandUiSchemaDefinitions(currentSchema, uiSchema, registry, visited = new Set()) {
|
|
24376
|
-
const { rootSchema, uiSchemaDefinitions: definitions } = registry;
|
|
24377
|
-
let result = { ...uiSchema };
|
|
24378
|
-
let resolvedSchema = currentSchema;
|
|
24379
|
-
const ref = currentSchema[REF_KEY];
|
|
24380
|
-
const isRecursive = ref && visited.has(ref);
|
|
24381
|
-
if (ref) {
|
|
24382
|
-
visited.add(ref);
|
|
24383
|
-
if (definitions && ref in definitions) {
|
|
24384
|
-
result = mergeObjects(definitions[ref], result);
|
|
24385
|
-
}
|
|
24386
|
-
if (isRecursive) {
|
|
24387
|
-
return result;
|
|
24388
|
-
}
|
|
24389
|
-
try {
|
|
24390
|
-
resolvedSchema = findSchemaDefinition(ref, rootSchema);
|
|
24391
|
-
}
|
|
24392
|
-
catch (_a) {
|
|
24393
|
-
resolvedSchema = currentSchema;
|
|
24394
|
-
}
|
|
24395
|
-
}
|
|
24396
|
-
// Process properties (each property maps to uiSchema[propName] - flattened)
|
|
24397
|
-
const properties = resolvedSchema[PROPERTIES_KEY];
|
|
24398
|
-
if (properties && isObject(properties)) {
|
|
24399
|
-
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
24400
|
-
const propUiSchema = (result[propName] || {});
|
|
24401
|
-
const expanded = expandUiSchemaDefinitions(propSchema, propUiSchema, registry, new Set(visited));
|
|
24402
|
-
if (Object.keys(expanded).length > 0) {
|
|
24403
|
-
result[propName] = expanded;
|
|
24404
|
-
}
|
|
24405
|
-
}
|
|
24406
|
-
}
|
|
24407
|
-
// Process keywords where child maps to same key in uiSchema (items, additionalProperties)
|
|
24408
|
-
for (const keyword of SAME_KEY_KEYWORDS) {
|
|
24409
|
-
const subSchema = resolvedSchema[keyword];
|
|
24410
|
-
if (subSchema && isObject(subSchema) && !Array.isArray(subSchema)) {
|
|
24411
|
-
const currentUiSchema = result[keyword];
|
|
24412
|
-
if (typeof currentUiSchema !== 'function') {
|
|
24413
|
-
const subUiSchema = (currentUiSchema || {});
|
|
24414
|
-
const expanded = expandUiSchemaDefinitions(subSchema, subUiSchema, registry, new Set(visited));
|
|
24415
|
-
if (Object.keys(expanded).length > 0) {
|
|
24416
|
-
result[keyword] = expanded;
|
|
24417
|
-
}
|
|
24418
|
-
}
|
|
24419
|
-
}
|
|
24420
|
-
}
|
|
24421
|
-
// Process array keywords (oneOf, anyOf, allOf) - each option maps to uiSchema[keyword][i]
|
|
24422
|
-
for (const keyword of ARRAY_KEYWORDS) {
|
|
24423
|
-
const schemaOptions = resolvedSchema[keyword];
|
|
24424
|
-
if (Array.isArray(schemaOptions) && schemaOptions.length > 0) {
|
|
24425
|
-
const currentUiSchemaArray = result[keyword];
|
|
24426
|
-
const uiSchemaArray = Array.isArray(currentUiSchemaArray) ? [...currentUiSchemaArray] : [];
|
|
24427
|
-
let hasExpanded = false;
|
|
24428
|
-
for (let i = 0; i < schemaOptions.length; i++) {
|
|
24429
|
-
const optionSchema = schemaOptions[i];
|
|
24430
|
-
const optionUiSchema = (uiSchemaArray[i] || {});
|
|
24431
|
-
const expanded = expandUiSchemaDefinitions(optionSchema, optionUiSchema, registry, new Set(visited));
|
|
24432
|
-
if (Object.keys(expanded).length > 0) {
|
|
24433
|
-
uiSchemaArray[i] = expanded;
|
|
24434
|
-
hasExpanded = true;
|
|
24435
|
-
}
|
|
24436
|
-
}
|
|
24437
|
-
if (hasExpanded) {
|
|
24438
|
-
result[keyword] = uiSchemaArray;
|
|
24439
|
-
}
|
|
24440
|
-
}
|
|
24441
|
-
}
|
|
24442
|
-
return result;
|
|
24443
|
-
}
|
|
24444
25170
|
/** Resolves the uiSchema for a given schema, considering `ui:definitions` stored in the registry.
|
|
24445
25171
|
*
|
|
24446
|
-
*
|
|
24447
|
-
*
|
|
24448
|
-
*
|
|
24449
|
-
*
|
|
24450
|
-
* from `registry.uiSchemaDefinitions` and merges it with any local uiSchema overrides.
|
|
25172
|
+
* Called at runtime for each field. When the schema contains a `$ref`, looks up the corresponding
|
|
25173
|
+
* uiSchema definition from `registry.uiSchemaDefinitions` and merges it with local overrides.
|
|
25174
|
+
* For schemas with `oneOf`/`anyOf` branches, also populates `uiSchema[keyword][i]` for branches
|
|
25175
|
+
* whose `$ref` matches a definition, so `MultiSchemaField` can read dropdown option titles.
|
|
24451
25176
|
*
|
|
24452
25177
|
* Resolution order (later sources override earlier):
|
|
24453
25178
|
* 1. `ui:definitions[$ref]` - base definition from registry
|
|
24454
25179
|
* 2. `localUiSchema` - local overrides at current path
|
|
24455
25180
|
*
|
|
24456
|
-
* @param schema - The JSON schema (may
|
|
25181
|
+
* @param schema - The JSON schema (may contain `$ref` or `RJSF_REF_KEY`)
|
|
24457
25182
|
* @param localUiSchema - The uiSchema at the current path (local overrides)
|
|
24458
25183
|
* @param registry - The registry containing `uiSchemaDefinitions`
|
|
24459
25184
|
* @returns - The resolved uiSchema with definitions merged in
|
|
@@ -24461,14 +25186,54 @@ function expandUiSchemaDefinitions(currentSchema, uiSchema, registry, visited =
|
|
|
24461
25186
|
function resolveUiSchema(schema, localUiSchema, registry) {
|
|
24462
25187
|
var _a, _b;
|
|
24463
25188
|
const ref = ((_a = schema[RJSF_REF_KEY]) !== null && _a !== void 0 ? _a : schema[REF_KEY]);
|
|
24464
|
-
const
|
|
25189
|
+
const definitions = registry.uiSchemaDefinitions;
|
|
25190
|
+
const definitionUiSchema = ref && definitions ? definitions[ref] : undefined;
|
|
25191
|
+
let result;
|
|
24465
25192
|
if (!definitionUiSchema) {
|
|
24466
|
-
|
|
25193
|
+
result = localUiSchema || {};
|
|
24467
25194
|
}
|
|
24468
|
-
if (!localUiSchema ||
|
|
24469
|
-
|
|
25195
|
+
else if (!localUiSchema || isEmpty.isEmpty(localUiSchema)) {
|
|
25196
|
+
result = { ...definitionUiSchema };
|
|
25197
|
+
}
|
|
25198
|
+
else {
|
|
25199
|
+
result = mergeObjects(definitionUiSchema, localUiSchema);
|
|
25200
|
+
}
|
|
25201
|
+
// Walk oneOf/anyOf branches to populate uiSchema[keyword][i] so MultiSchemaField
|
|
25202
|
+
// can read dropdown option titles at the parent level.
|
|
25203
|
+
if (definitions) {
|
|
25204
|
+
let resolvedSchema = schema;
|
|
25205
|
+
if (ref && schema[REF_KEY] && !schema[RJSF_REF_KEY]) {
|
|
25206
|
+
try {
|
|
25207
|
+
resolvedSchema = findSchemaDefinition(ref, registry.rootSchema);
|
|
25208
|
+
}
|
|
25209
|
+
catch (e) {
|
|
25210
|
+
console.warn('could not resolve $ref in resolveUiSchema:\n', e);
|
|
25211
|
+
return result;
|
|
25212
|
+
}
|
|
25213
|
+
}
|
|
25214
|
+
for (const keyword of [ONE_OF_KEY, ANY_OF_KEY]) {
|
|
25215
|
+
const schemaOptions = resolvedSchema[keyword];
|
|
25216
|
+
if (!Array.isArray(schemaOptions) || schemaOptions.length === 0) {
|
|
25217
|
+
continue;
|
|
25218
|
+
}
|
|
25219
|
+
const currentUiSchemaArray = result[keyword];
|
|
25220
|
+
const uiSchemaArray = Array.isArray(currentUiSchemaArray) ? [...currentUiSchemaArray] : [];
|
|
25221
|
+
let hasExpanded = false;
|
|
25222
|
+
for (let i = 0; i < schemaOptions.length; i++) {
|
|
25223
|
+
const option = schemaOptions[i];
|
|
25224
|
+
const optionRef = ((_b = option === null || option === void 0 ? void 0 : option[RJSF_REF_KEY]) !== null && _b !== void 0 ? _b : option === null || option === void 0 ? void 0 : option[REF_KEY]);
|
|
25225
|
+
if (optionRef && optionRef in definitions) {
|
|
25226
|
+
const optionUiSchema = (uiSchemaArray[i] || {});
|
|
25227
|
+
uiSchemaArray[i] = mergeObjects(definitions[optionRef], optionUiSchema);
|
|
25228
|
+
hasExpanded = true;
|
|
25229
|
+
}
|
|
25230
|
+
}
|
|
25231
|
+
if (hasExpanded) {
|
|
25232
|
+
result[keyword] = uiSchemaArray;
|
|
25233
|
+
}
|
|
25234
|
+
}
|
|
24470
25235
|
}
|
|
24471
|
-
return
|
|
25236
|
+
return result;
|
|
24472
25237
|
}
|
|
24473
25238
|
|
|
24474
25239
|
/** Check to see if a `schema` specifies that a value must be true. This happens when:
|
|
@@ -24779,7 +25544,7 @@ function useAltDateWidgetProps(props) {
|
|
|
24779
25544
|
*/
|
|
24780
25545
|
function useDeepCompareMemo(newValue) {
|
|
24781
25546
|
const valueRef = reactExports.useRef(newValue);
|
|
24782
|
-
if (!
|
|
25547
|
+
if (!deepEquals(newValue, valueRef.current)) {
|
|
24783
25548
|
valueRef.current = newValue;
|
|
24784
25549
|
}
|
|
24785
25550
|
return valueRef.current;
|
|
@@ -25704,10 +26469,12 @@ function ArrayField$1(props) {
|
|
|
25704
26469
|
* @param index - The index of the item being changed
|
|
25705
26470
|
*/
|
|
25706
26471
|
const handleChange = reactExports.useCallback((value, path, newErrorSchema, id) => {
|
|
26472
|
+
const lastPathIsItemIndex = typeof path.at(-1) === 'number';
|
|
25707
26473
|
onChange(
|
|
25708
26474
|
// We need to treat undefined items as nulls to have validation.
|
|
25709
26475
|
// See https://github.com/tdegrunt/jsonschema/issues/206
|
|
25710
|
-
|
|
26476
|
+
// Only set to null for array items, and not for object properties within array items
|
|
26477
|
+
lastPathIsItemIndex && value === undefined ? null : value, path, newErrorSchema, id);
|
|
25711
26478
|
}, [onChange]);
|
|
25712
26479
|
/** Callback handler used to change the value for a checkbox */
|
|
25713
26480
|
const onSelectChange = reactExports.useCallback((value) => {
|
|
@@ -27023,11 +27790,14 @@ function ObjectField$1(props) {
|
|
|
27023
27790
|
const { schema: rawSchema, uiSchema = {}, formData, errorSchema, fieldPathId, name, required = false, disabled, readonly, hideError, onBlur, onFocus, onChange, registry, title, } = props;
|
|
27024
27791
|
const { fields, schemaUtils, translateString, globalUiOptions } = registry;
|
|
27025
27792
|
const { OptionalDataControlsField } = fields;
|
|
27793
|
+
const formDataRef = reactExports.useRef(formData);
|
|
27794
|
+
formDataRef.current = formData;
|
|
27026
27795
|
const schema = schemaUtils.retrieveSchema(rawSchema, formData, true);
|
|
27027
27796
|
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
27028
27797
|
const { properties: schemaProperties = {} } = schema;
|
|
27029
27798
|
// All the children will use childFieldPathId if present in the props, falling back to the fieldPathId
|
|
27030
27799
|
const childFieldPathId = props.childFieldPathId ?? fieldPathId;
|
|
27800
|
+
const lastRenamedProperty = reactExports.useRef({ previousKey: '', currentKey: undefined });
|
|
27031
27801
|
const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
|
|
27032
27802
|
const description = uiOptions.description ?? schema.description;
|
|
27033
27803
|
const renderOptionalField = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
@@ -27087,6 +27857,10 @@ function ObjectField$1(props) {
|
|
|
27087
27857
|
// Cast this to make the `set` work properly
|
|
27088
27858
|
set(newFormData, newKey, newValue);
|
|
27089
27859
|
}
|
|
27860
|
+
if (lastRenamedProperty.current.previousKey === newKey) {
|
|
27861
|
+
lastRenamedProperty.current.currentKey = newKey;
|
|
27862
|
+
lastRenamedProperty.current.previousKey = getAvailableKey(newKey, newFormData);
|
|
27863
|
+
}
|
|
27090
27864
|
onChange(newFormData, childFieldPathId.path);
|
|
27091
27865
|
}, [formData, onChange, registry, childFieldPathId, getAvailableKey, schema]);
|
|
27092
27866
|
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
@@ -27098,9 +27872,10 @@ function ObjectField$1(props) {
|
|
|
27098
27872
|
*/
|
|
27099
27873
|
const handleKeyRename = reactExports.useCallback((oldKey, newKey) => {
|
|
27100
27874
|
if (oldKey !== newKey) {
|
|
27101
|
-
const
|
|
27875
|
+
const currentFormData = formDataRef.current;
|
|
27876
|
+
const actualNewKey = getAvailableKey(newKey, currentFormData);
|
|
27102
27877
|
const newFormData = {
|
|
27103
|
-
...
|
|
27878
|
+
...currentFormData,
|
|
27104
27879
|
};
|
|
27105
27880
|
const newKeys = { [oldKey]: actualNewKey };
|
|
27106
27881
|
const keyValues = Object.keys(newFormData).map((key) => {
|
|
@@ -27108,15 +27883,31 @@ function ObjectField$1(props) {
|
|
|
27108
27883
|
return { [newKey]: newFormData[key] };
|
|
27109
27884
|
});
|
|
27110
27885
|
const renamedObj = Object.assign({}, ...keyValues);
|
|
27886
|
+
formDataRef.current = renamedObj;
|
|
27887
|
+
if (oldKey !== lastRenamedProperty.current.currentKey) {
|
|
27888
|
+
lastRenamedProperty.current.previousKey = oldKey;
|
|
27889
|
+
}
|
|
27890
|
+
lastRenamedProperty.current.currentKey = actualNewKey;
|
|
27111
27891
|
onChange(renamedObj, childFieldPathId.path);
|
|
27112
27892
|
}
|
|
27113
|
-
}, [
|
|
27893
|
+
}, [onChange, childFieldPathId, getAvailableKey]);
|
|
27114
27894
|
/** Handles the remove click which calls the `onChange` callback with the special ADDITIONAL_PROPERTY_FIELD_REMOVE
|
|
27115
27895
|
* value for the path plus the key to be removed
|
|
27116
27896
|
*/
|
|
27117
27897
|
const handleRemoveProperty = reactExports.useCallback((key) => {
|
|
27118
27898
|
onChange(ADDITIONAL_PROPERTY_KEY_REMOVE, [...childFieldPathId.path, key]);
|
|
27119
27899
|
}, [onChange, childFieldPathId]);
|
|
27900
|
+
/** Returns the stable React key for a property. For the most recently renamed
|
|
27901
|
+
* additional property, returns the previous key so that React reuses the
|
|
27902
|
+
* existing component instance instead of unmounting/remounting it. This
|
|
27903
|
+
* preserves DOM focus naturally without manual focus management.
|
|
27904
|
+
*/
|
|
27905
|
+
const getStableKey = reactExports.useCallback((property) => {
|
|
27906
|
+
if (lastRenamedProperty.current.currentKey === property) {
|
|
27907
|
+
return lastRenamedProperty.current.previousKey;
|
|
27908
|
+
}
|
|
27909
|
+
return property;
|
|
27910
|
+
}, []);
|
|
27120
27911
|
if (!renderOptionalField || hasFormData) {
|
|
27121
27912
|
try {
|
|
27122
27913
|
const properties = Object.keys(schemaProperties);
|
|
@@ -27136,7 +27927,7 @@ function ObjectField$1(props) {
|
|
|
27136
27927
|
const addedByAdditionalProperties = pickBy.has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
|
|
27137
27928
|
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
|
|
27138
27929
|
const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
|
|
27139
|
-
const content = (jsxRuntimeExports.jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: _baseIteratee.get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: _baseIteratee.get(errorSchema, [name]), fieldPathId: childFieldPathId, formData: _baseIteratee.get(formData, [name]), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, name));
|
|
27930
|
+
const content = (jsxRuntimeExports.jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: _baseIteratee.get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: _baseIteratee.get(errorSchema, [name]), fieldPathId: childFieldPathId, formData: _baseIteratee.get(formData, [name]), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, getStableKey(name)));
|
|
27140
27931
|
return {
|
|
27141
27932
|
content,
|
|
27142
27933
|
name,
|
|
@@ -27881,7 +28672,7 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
27881
28672
|
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: children }));
|
|
27882
28673
|
}
|
|
27883
28674
|
const margin = hasDescription ? 46 : 26;
|
|
27884
|
-
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: jsxRuntimeExports.jsxs("div", { className: 'row', children: [jsxRuntimeExports.jsx("div", { className: 'col-xs-5 form-additional', children: jsxRuntimeExports.jsxs("div", { className: 'form-group', children: [displayLabel && jsxRuntimeExports.jsx(Label, { label: keyLabel, required: required, id: `${id}-key` }), displayLabel && rawDescription && jsxRuntimeExports.jsx("div", { children: "\u00A0" }), jsxRuntimeExports.jsx("input", { className: 'form-control', type: 'text', id: `${id}-key`, onBlur: onKeyRenameBlur, defaultValue: label })] }) }), jsxRuntimeExports.jsx("div", { className: 'form-additional form-group col-xs-5', children: children }), jsxRuntimeExports.jsx("div", { className: 'col-xs-2', style: { marginTop: displayLabel ? `${margin}px` : undefined }, children: jsxRuntimeExports.jsx(RemoveButton, { id: buttonId(id, 'remove'), className: 'rjsf-object-property-remove btn-block', style: { border: '0' }, disabled: disabled || readonly, onClick: onRemoveProperty, uiSchema: uiSchema, registry: registry }) })] }) }));
|
|
28675
|
+
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: jsxRuntimeExports.jsxs("div", { className: 'row', children: [jsxRuntimeExports.jsx("div", { className: 'col-xs-5 form-additional', children: jsxRuntimeExports.jsxs("div", { className: 'form-group', children: [displayLabel && jsxRuntimeExports.jsx(Label, { label: keyLabel, required: required, id: `${id}-key` }), displayLabel && rawDescription && jsxRuntimeExports.jsx("div", { children: "\u00A0" }), jsxRuntimeExports.jsx("input", { className: 'form-control', type: 'text', id: `${id}-key`, onBlur: onKeyRenameBlur, defaultValue: label }, label)] }) }), jsxRuntimeExports.jsx("div", { className: 'form-additional form-group col-xs-5', children: children }), jsxRuntimeExports.jsx("div", { className: 'col-xs-2', style: { marginTop: displayLabel ? `${margin}px` : undefined }, children: jsxRuntimeExports.jsx(RemoveButton, { id: buttonId(id, 'remove'), className: 'rjsf-object-property-remove btn-block', style: { border: '0' }, disabled: disabled || readonly, onClick: onRemoveProperty, uiSchema: uiSchema, registry: registry }) })] }) }));
|
|
27885
28676
|
}
|
|
27886
28677
|
|
|
27887
28678
|
function templates() {
|
|
@@ -27954,10 +28745,12 @@ function CheckboxWidget({ schema, uiSchema, options, id, value, disabled, readon
|
|
|
27954
28745
|
*
|
|
27955
28746
|
* @param props - The `WidgetProps` for this component
|
|
27956
28747
|
*/
|
|
27957
|
-
function CheckboxesWidget({ id, disabled, options
|
|
28748
|
+
function CheckboxesWidget({ id, disabled, options, value, autofocus = false, readonly, onChange, onBlur, onFocus, htmlName, }) {
|
|
28749
|
+
const { inline = false, enumOptions, enumDisabled, emptyValue } = options;
|
|
28750
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
27958
28751
|
const checkboxesValues = Array.isArray(value) ? value : [value];
|
|
27959
|
-
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id,
|
|
27960
|
-
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id,
|
|
28752
|
+
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onBlur, id, enumOptions, emptyValue, optionValueFormat]);
|
|
28753
|
+
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onFocus, id, enumOptions, emptyValue, optionValueFormat]);
|
|
27961
28754
|
return (jsxRuntimeExports.jsx("div", { className: 'checkboxes', id: id, children: Array.isArray(enumOptions) &&
|
|
27962
28755
|
enumOptions.map((option, index) => {
|
|
27963
28756
|
const checked = enumOptionsIsSelected(option.value, checkboxesValues);
|
|
@@ -27971,7 +28764,7 @@ function CheckboxesWidget({ id, disabled, options: { inline = false, enumOptions
|
|
|
27971
28764
|
onChange(enumOptionsDeselectValue(index, checkboxesValues, enumOptions));
|
|
27972
28765
|
}
|
|
27973
28766
|
};
|
|
27974
|
-
const checkbox = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'checkbox', id: optionId(id, index), name: htmlName || id, checked: checked, value:
|
|
28767
|
+
const checkbox = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'checkbox', id: optionId(id, index), name: htmlName || id, checked: checked, value: enumOptionValueEncoder(option.value, index, optionValueFormat), disabled: disabled || itemDisabled || readonly, autoFocus: autofocus && index === 0, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": ariaDescribedByIds(id) }), jsxRuntimeExports.jsx("span", { children: option.label })] }));
|
|
27975
28768
|
return inline ? (jsxRuntimeExports.jsx("label", { className: `checkbox-inline ${disabledCls}`, children: checkbox }, index)) : (jsxRuntimeExports.jsx("div", { className: `checkbox ${disabledCls}`, children: jsxRuntimeExports.jsx("label", { children: checkbox }) }, index));
|
|
27976
28769
|
}) }));
|
|
27977
28770
|
}
|
|
@@ -28089,15 +28882,16 @@ function PasswordWidget(props) {
|
|
|
28089
28882
|
*/
|
|
28090
28883
|
function RadioWidget({ options, value, required, disabled, readonly, autofocus = false, onBlur, onFocus, onChange, id, htmlName, }) {
|
|
28091
28884
|
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
28092
|
-
const
|
|
28093
|
-
const
|
|
28885
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
28886
|
+
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onBlur, enumOptions, emptyValue, id, optionValueFormat]);
|
|
28887
|
+
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onFocus, enumOptions, emptyValue, id, optionValueFormat]);
|
|
28094
28888
|
return (jsxRuntimeExports.jsx("div", { className: 'field-radio-group', id: id, role: 'radiogroup', children: Array.isArray(enumOptions) &&
|
|
28095
28889
|
enumOptions.map((option, i) => {
|
|
28096
28890
|
const checked = enumOptionsIsSelected(option.value, value);
|
|
28097
28891
|
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
|
|
28098
28892
|
const disabledCls = disabled || itemDisabled || readonly ? 'disabled' : '';
|
|
28099
28893
|
const handleChange = () => onChange(option.value);
|
|
28100
|
-
const radio = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'radio', id: optionId(id, i), checked: checked, name: htmlName || id, required: required, value:
|
|
28894
|
+
const radio = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'radio', id: optionId(id, i), checked: checked, name: htmlName || id, required: required, value: enumOptionValueEncoder(option.value, i, optionValueFormat), disabled: disabled || itemDisabled || readonly, autoFocus: autofocus && i === 0, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": ariaDescribedByIds(id) }), jsxRuntimeExports.jsx("span", { children: option.label })] }));
|
|
28101
28895
|
return inline ? (jsxRuntimeExports.jsx("label", { className: `radio-inline ${disabledCls}`, children: radio }, i)) : (jsxRuntimeExports.jsx("div", { className: `radio ${disabledCls}`, children: jsxRuntimeExports.jsx("label", { children: radio }) }, i));
|
|
28102
28896
|
}) }));
|
|
28103
28897
|
}
|
|
@@ -28191,24 +28985,25 @@ function getValue(event, multiple) {
|
|
|
28191
28985
|
function SelectWidget({ schema, id, options, value, required, disabled, readonly, multiple = false, autofocus = false, onChange, onBlur, onFocus, placeholder, htmlName, }) {
|
|
28192
28986
|
const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
|
|
28193
28987
|
const emptyValue = multiple ? [] : '';
|
|
28988
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
28194
28989
|
const handleFocus = reactExports.useCallback((event) => {
|
|
28195
28990
|
const newValue = getValue(event, multiple);
|
|
28196
|
-
return onFocus(id,
|
|
28197
|
-
}, [onFocus, id, multiple, enumOptions, optEmptyVal]);
|
|
28991
|
+
return onFocus(id, enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
28992
|
+
}, [onFocus, id, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
28198
28993
|
const handleBlur = reactExports.useCallback((event) => {
|
|
28199
28994
|
const newValue = getValue(event, multiple);
|
|
28200
|
-
return onBlur(id,
|
|
28201
|
-
}, [onBlur, id, multiple, enumOptions, optEmptyVal]);
|
|
28995
|
+
return onBlur(id, enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
28996
|
+
}, [onBlur, id, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
28202
28997
|
const handleChange = reactExports.useCallback((event) => {
|
|
28203
28998
|
const newValue = getValue(event, multiple);
|
|
28204
|
-
return onChange(
|
|
28205
|
-
}, [onChange, multiple, enumOptions, optEmptyVal]);
|
|
28206
|
-
const
|
|
28999
|
+
return onChange(enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
29000
|
+
}, [onChange, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
29001
|
+
const selectValue = enumOptionSelectedValue(value, enumOptions, multiple, optionValueFormat, emptyValue);
|
|
28207
29002
|
const showPlaceholderOption = !multiple && schema.default === undefined;
|
|
28208
|
-
return (jsxRuntimeExports.jsxs("select", { id: id, name: htmlName || id, multiple: multiple, role: 'combobox', className: 'form-control', value:
|
|
29003
|
+
return (jsxRuntimeExports.jsxs("select", { id: id, name: htmlName || id, multiple: multiple, role: 'combobox', className: 'form-control', value: selectValue, required: required, disabled: disabled || readonly, autoFocus: autofocus, onBlur: handleBlur, onFocus: handleFocus, onChange: handleChange, "aria-describedby": ariaDescribedByIds(id), children: [showPlaceholderOption && jsxRuntimeExports.jsx("option", { value: '', children: placeholder }), Array.isArray(enumOptions) &&
|
|
28209
29004
|
enumOptions.map(({ value, label }, i) => {
|
|
28210
29005
|
const disabled = enumDisabled && enumDisabled.indexOf(value) !== -1;
|
|
28211
|
-
return (jsxRuntimeExports.jsx("option", { value:
|
|
29006
|
+
return (jsxRuntimeExports.jsx("option", { value: enumOptionValueEncoder(value, i, optionValueFormat), disabled: disabled, children: label }, i));
|
|
28212
29007
|
})] }));
|
|
28213
29008
|
}
|
|
28214
29009
|
|
|
@@ -28546,10 +29341,6 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28546
29341
|
// Only store a new registry when the props cause a different one to be created
|
|
28547
29342
|
const newRegistry = this.getRegistry(props, rootSchema, schemaUtils);
|
|
28548
29343
|
const registry = deepEquals(state.registry, newRegistry) ? state.registry : newRegistry;
|
|
28549
|
-
// Pre-expand ui:definitions into the uiSchema structure (must happen after registry is created)
|
|
28550
|
-
const expandedUiSchema = registry.uiSchemaDefinitions
|
|
28551
|
-
? expandUiSchemaDefinitions(rootSchema, uiSchema, registry)
|
|
28552
|
-
: uiSchema;
|
|
28553
29344
|
// Only compute a new `fieldPathId` when the `idPrefix` is different than the existing fieldPathId's ID_KEY
|
|
28554
29345
|
const fieldPathId = state.fieldPathId && state.fieldPathId?.[ID_KEY] === registry.globalFormOptions.idPrefix
|
|
28555
29346
|
? state.fieldPathId
|
|
@@ -28557,7 +29348,7 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28557
29348
|
const nextState = {
|
|
28558
29349
|
schemaUtils,
|
|
28559
29350
|
schema: rootSchema,
|
|
28560
|
-
uiSchema
|
|
29351
|
+
uiSchema,
|
|
28561
29352
|
fieldPathId,
|
|
28562
29353
|
formData,
|
|
28563
29354
|
edit,
|
|
@@ -28731,9 +29522,13 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28731
29522
|
this._isProcessingUserChange = true;
|
|
28732
29523
|
const { newValue, path, id } = this.pendingChanges[0];
|
|
28733
29524
|
const { newErrorSchema } = this.pendingChanges[0];
|
|
28734
|
-
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
|
|
29525
|
+
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange, removeEmptyOptionalObjects } = this.props;
|
|
28735
29526
|
const { formData: oldFormData, schemaUtils, schema, fieldPathId, schemaValidationErrorSchema, errors } = this.state;
|
|
28736
|
-
let { customErrors
|
|
29527
|
+
let { customErrors } = this.state;
|
|
29528
|
+
// Use the un-merged AJV-only schema as the base for re-merging extraErrors. Mirrors the
|
|
29529
|
+
// pattern in getStateFromProps/getDerivedStateFromProps and avoids the duplication that
|
|
29530
|
+
// happened when state.errorSchema (already containing merged extraErrors) was passed in.
|
|
29531
|
+
let mergeBaseErrorSchema = schemaValidationErrorSchema;
|
|
28737
29532
|
const rootPathId = fieldPathId.path[0] || '';
|
|
28738
29533
|
const isRootPath = !path || path.length === 0 || (path.length === 1 && path[0] === rootPathId);
|
|
28739
29534
|
let retrievedSchema = this.state.retrievedSchema;
|
|
@@ -28770,18 +29565,27 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28770
29565
|
formData: newFormData,
|
|
28771
29566
|
};
|
|
28772
29567
|
}
|
|
29568
|
+
if (removeEmptyOptionalObjects) {
|
|
29569
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29570
|
+
state = {
|
|
29571
|
+
...state,
|
|
29572
|
+
formData: newFormData,
|
|
29573
|
+
};
|
|
29574
|
+
}
|
|
28773
29575
|
if (newErrorSchema) {
|
|
28774
29576
|
// First check to see if there is an existing validation error on this path...
|
|
28775
29577
|
// @ts-expect-error TS2590, because getting from the error schema is confusing TS
|
|
28776
29578
|
const oldValidationError = !isRootPath ? _baseIteratee.get(schemaValidationErrorSchema, path) : schemaValidationErrorSchema;
|
|
28777
29579
|
// If there is an old validation error for this path, assume we are updating it directly
|
|
28778
29580
|
if (!isEmpty.isEmpty(oldValidationError)) {
|
|
28779
|
-
//
|
|
29581
|
+
// Apply the user-supplied newErrorSchema onto a clone of the AJV-only base, so that
|
|
29582
|
+
// mergeErrors below sees the user's error at this path without mutating shared state.
|
|
28780
29583
|
if (!isRootPath) {
|
|
28781
|
-
|
|
29584
|
+
mergeBaseErrorSchema = cloneDeep.cloneDeep(schemaValidationErrorSchema);
|
|
29585
|
+
set(mergeBaseErrorSchema, path, newErrorSchema);
|
|
28782
29586
|
}
|
|
28783
29587
|
else {
|
|
28784
|
-
|
|
29588
|
+
mergeBaseErrorSchema = newErrorSchema;
|
|
28785
29589
|
}
|
|
28786
29590
|
}
|
|
28787
29591
|
else {
|
|
@@ -28806,12 +29610,12 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28806
29610
|
}
|
|
28807
29611
|
// If there are pending changes in the queue, skip live validation since it will happen with the last change
|
|
28808
29612
|
if (mustValidate && this.pendingChanges.length === 1) {
|
|
28809
|
-
const liveValidation = this.liveValidate(schema, schemaUtils,
|
|
29613
|
+
const liveValidation = this.liveValidate(schema, schemaUtils, mergeBaseErrorSchema, newFormData, extraErrors, customErrors, retrievedSchema);
|
|
28810
29614
|
state = { formData: newFormData, ...liveValidation, customErrors };
|
|
28811
29615
|
}
|
|
28812
29616
|
else if (!noValidate && newErrorSchema) {
|
|
28813
29617
|
// Merging 'newErrorSchema' into 'errorSchema' to display the custom raised errors.
|
|
28814
|
-
const mergedErrors = this.mergeErrors({ errorSchema:
|
|
29618
|
+
const mergedErrors = this.mergeErrors({ errorSchema: mergeBaseErrorSchema, errors }, extraErrors, customErrors);
|
|
28815
29619
|
state = {
|
|
28816
29620
|
formData: newFormData,
|
|
28817
29621
|
...mergedErrors,
|
|
@@ -28870,19 +29674,23 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28870
29674
|
* @param data - The data associated with the field that was blurred
|
|
28871
29675
|
*/
|
|
28872
29676
|
onBlur = (id, data) => {
|
|
28873
|
-
const { onBlur, omitExtraData, liveOmit, liveValidate } = this.props;
|
|
29677
|
+
const { onBlur, omitExtraData, liveOmit, liveValidate, removeEmptyOptionalObjects } = this.props;
|
|
28874
29678
|
if (onBlur) {
|
|
28875
29679
|
onBlur(id, data);
|
|
28876
29680
|
}
|
|
28877
29681
|
if ((omitExtraData === true && liveOmit === 'onBlur') || liveValidate === 'onBlur') {
|
|
28878
29682
|
const { onChange, extraErrors } = this.props;
|
|
28879
|
-
const { formData } = this.state;
|
|
29683
|
+
const { formData, schemaUtils, schema } = this.state;
|
|
28880
29684
|
let newFormData = formData;
|
|
28881
29685
|
let state = { formData: newFormData };
|
|
28882
29686
|
if (omitExtraData === true && liveOmit === 'onBlur') {
|
|
28883
29687
|
newFormData = this.omitExtraData(formData);
|
|
28884
29688
|
state = { formData: newFormData };
|
|
28885
29689
|
}
|
|
29690
|
+
if (removeEmptyOptionalObjects) {
|
|
29691
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29692
|
+
state = { ...state, formData: newFormData };
|
|
29693
|
+
}
|
|
28886
29694
|
if (liveValidate === 'onBlur') {
|
|
28887
29695
|
const { schema, schemaUtils, errorSchema, customErrors, retrievedSchema } = this.state;
|
|
28888
29696
|
const liveValidation = this.liveValidate(schema, schemaUtils, errorSchema, newFormData, extraErrors, customErrors, retrievedSchema);
|
|
@@ -28929,11 +29737,15 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28929
29737
|
return;
|
|
28930
29738
|
}
|
|
28931
29739
|
event.persist();
|
|
28932
|
-
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
29740
|
+
const { omitExtraData, extraErrors, noValidate, onSubmit, removeEmptyOptionalObjects } = this.props;
|
|
28933
29741
|
let { formData: newFormData } = this.state;
|
|
28934
29742
|
if (omitExtraData === true) {
|
|
28935
29743
|
newFormData = this.omitExtraData(newFormData);
|
|
28936
29744
|
}
|
|
29745
|
+
if (removeEmptyOptionalObjects) {
|
|
29746
|
+
const { schemaUtils, schema } = this.state;
|
|
29747
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29748
|
+
}
|
|
28937
29749
|
if (noValidate || this.validateFormWithFormData(newFormData)) {
|
|
28938
29750
|
// There are no errors generated through schema validation.
|
|
28939
29751
|
// Check for user provided errors and update state accordingly.
|
|
@@ -29026,8 +29838,9 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
29026
29838
|
const elementId = path.join(idSeparator);
|
|
29027
29839
|
let field = this.formElement.current.elements[elementId];
|
|
29028
29840
|
if (!field) {
|
|
29029
|
-
// if not an exact match, try finding
|
|
29030
|
-
|
|
29841
|
+
// if not an exact match, try finding a focusable element starting with the element id (like radio buttons or checkboxes)
|
|
29842
|
+
// some themes (e.g. shadcn) use button elements instead of native inputs for radio groups
|
|
29843
|
+
field = this.formElement.current.querySelector(`input[id^="${elementId}"], button[id^="${elementId}"]`);
|
|
29031
29844
|
}
|
|
29032
29845
|
if (field && field.length) {
|
|
29033
29846
|
// If we got a list with length > 0
|
|
@@ -29101,11 +29914,15 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
29101
29914
|
* @returns - True if the form is valid, false otherwise.
|
|
29102
29915
|
*/
|
|
29103
29916
|
validateForm() {
|
|
29104
|
-
const { omitExtraData } = this.props;
|
|
29917
|
+
const { omitExtraData, removeEmptyOptionalObjects } = this.props;
|
|
29105
29918
|
let { formData: newFormData } = this.state;
|
|
29106
29919
|
if (omitExtraData === true) {
|
|
29107
29920
|
newFormData = this.omitExtraData(newFormData);
|
|
29108
29921
|
}
|
|
29922
|
+
if (removeEmptyOptionalObjects) {
|
|
29923
|
+
const { schemaUtils, schema } = this.state;
|
|
29924
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29925
|
+
}
|
|
29109
29926
|
return this.validateFormWithFormData(newFormData);
|
|
29110
29927
|
}
|
|
29111
29928
|
/** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
|
|
@@ -35784,13 +36601,50 @@ function createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverr
|
|
|
35784
36601
|
return ajv;
|
|
35785
36602
|
}
|
|
35786
36603
|
|
|
36604
|
+
/** Filters duplicate errors from `anyOf`/`oneOf` schema paths according to the `suppressDuplicateFiltering` flag.
|
|
36605
|
+
*
|
|
36606
|
+
* @param errorList - The list of `RJSFValidationError`s to filter
|
|
36607
|
+
* @param [suppressDuplicateFiltering='none'] - Controls which duplicate filtering is suppressed:
|
|
36608
|
+
* - `'none'` (default): filters duplicates for both `anyOf` and `oneOf`
|
|
36609
|
+
* - `'all'`: returns `errorList` unmodified
|
|
36610
|
+
* - `'anyOf'`: suppresses filtering for `anyOf` errors; `oneOf` duplicates are still filtered
|
|
36611
|
+
* - `'oneOf'`: suppresses filtering for `oneOf` errors; `anyOf` duplicates are still filtered
|
|
36612
|
+
*/
|
|
36613
|
+
function filterDuplicateErrors(errorList, suppressDuplicateFiltering = 'none') {
|
|
36614
|
+
if (suppressDuplicateFiltering === 'all') {
|
|
36615
|
+
return errorList;
|
|
36616
|
+
}
|
|
36617
|
+
return errorList.reduce((acc, err) => {
|
|
36618
|
+
const { message, schemaPath } = err;
|
|
36619
|
+
// Compute the index only when filtering for that keyword is not suppressed.
|
|
36620
|
+
// 'all' is already handled above; within the reduce, only 'none', 'anyOf', and 'oneOf' are possible.
|
|
36621
|
+
const anyOfIndex = suppressDuplicateFiltering !== 'anyOf' ? schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ANY_OF_KEY}/`) : undefined;
|
|
36622
|
+
const oneOfIndex = suppressDuplicateFiltering !== 'oneOf' ? schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ONE_OF_KEY}/`) : undefined;
|
|
36623
|
+
let schemaPrefix;
|
|
36624
|
+
if (anyOfIndex && anyOfIndex >= 0) {
|
|
36625
|
+
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, anyOfIndex);
|
|
36626
|
+
}
|
|
36627
|
+
else if (oneOfIndex && oneOfIndex >= 0) {
|
|
36628
|
+
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, oneOfIndex);
|
|
36629
|
+
}
|
|
36630
|
+
// If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
|
|
36631
|
+
const dup = schemaPrefix
|
|
36632
|
+
? acc.find((e) => { var _a; return e.message === message && ((_a = e.schemaPath) === null || _a === void 0 ? void 0 : _a.startsWith(schemaPrefix)); })
|
|
36633
|
+
: undefined;
|
|
36634
|
+
if (!dup) {
|
|
36635
|
+
acc.push(err);
|
|
36636
|
+
}
|
|
36637
|
+
return acc;
|
|
36638
|
+
}, []);
|
|
36639
|
+
}
|
|
35787
36640
|
/** Transforming the error output from ajv to format used by @rjsf/utils.
|
|
35788
36641
|
* At some point, components should be updated to support ajv.
|
|
35789
36642
|
*
|
|
35790
36643
|
* @param errors - The list of AJV errors to convert to `RJSFValidationErrors`
|
|
35791
36644
|
* @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
|
|
36645
|
+
* @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
|
|
35792
36646
|
*/
|
|
35793
|
-
function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
36647
|
+
function transformRJSFValidationErrors(errors = [], uiSchema, suppressDuplicateFiltering) {
|
|
35794
36648
|
const errorList = errors.map((e) => {
|
|
35795
36649
|
var _a;
|
|
35796
36650
|
const { instancePath, keyword, params, schemaPath, parentSchema, ...rest } = e;
|
|
@@ -35860,29 +36714,7 @@ function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
|
35860
36714
|
title: uiTitle,
|
|
35861
36715
|
};
|
|
35862
36716
|
});
|
|
35863
|
-
|
|
35864
|
-
return errorList.reduce((acc, err) => {
|
|
35865
|
-
const { message, schemaPath } = err;
|
|
35866
|
-
const anyOfIndex = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ANY_OF_KEY}/`);
|
|
35867
|
-
const oneOfIndex = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ONE_OF_KEY}/`);
|
|
35868
|
-
let schemaPrefix;
|
|
35869
|
-
// Look specifically for `/anyOr/` or `/oneOf/` within the schemaPath information
|
|
35870
|
-
if (anyOfIndex && anyOfIndex >= 0) {
|
|
35871
|
-
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, anyOfIndex);
|
|
35872
|
-
}
|
|
35873
|
-
else if (oneOfIndex && oneOfIndex >= 0) {
|
|
35874
|
-
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, oneOfIndex);
|
|
35875
|
-
}
|
|
35876
|
-
// If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
|
|
35877
|
-
const dup = schemaPrefix
|
|
35878
|
-
? acc.find((e) => { var _a; return e.message === message && ((_a = e.schemaPath) === null || _a === void 0 ? void 0 : _a.startsWith(schemaPrefix)); })
|
|
35879
|
-
: undefined;
|
|
35880
|
-
if (!dup) {
|
|
35881
|
-
// Only push an error that is not a duplicate
|
|
35882
|
-
acc.push(err);
|
|
35883
|
-
}
|
|
35884
|
-
return acc;
|
|
35885
|
-
}, []);
|
|
36717
|
+
return filterDuplicateErrors(errorList, suppressDuplicateFiltering);
|
|
35886
36718
|
}
|
|
35887
36719
|
/** This function processes the `formData` with an optional user contributed `customValidate` function, which receives
|
|
35888
36720
|
* the form data and a `errorHandler` function that will be used to add custom validation errors for each field. Also
|
|
@@ -35896,10 +36728,11 @@ function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
|
35896
36728
|
* @param [customValidate] - An optional function that is used to perform custom validation
|
|
35897
36729
|
* @param [transformErrors] - An optional function that is used to transform errors after AJV validation
|
|
35898
36730
|
* @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
|
|
36731
|
+
* @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
|
|
35899
36732
|
*/
|
|
35900
|
-
function processRawValidationErrors(validator, rawErrors, formData, schema, customValidate, transformErrors, uiSchema) {
|
|
36733
|
+
function processRawValidationErrors(validator, rawErrors, formData, schema, customValidate, transformErrors, uiSchema, suppressDuplicateFiltering) {
|
|
35901
36734
|
const { validationError: invalidSchemaError } = rawErrors;
|
|
35902
|
-
let errors = transformRJSFValidationErrors(rawErrors.errors, uiSchema);
|
|
36735
|
+
let errors = transformRJSFValidationErrors(rawErrors.errors, uiSchema, suppressDuplicateFiltering);
|
|
35903
36736
|
if (invalidSchemaError) {
|
|
35904
36737
|
errors = [...errors, { stack: invalidSchemaError.message }];
|
|
35905
36738
|
}
|
|
@@ -35934,14 +36767,22 @@ class AJV8Validator {
|
|
|
35934
36767
|
* @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
|
|
35935
36768
|
*/
|
|
35936
36769
|
constructor(options, localizer) {
|
|
35937
|
-
|
|
36770
|
+
/** True once a `rootSchema` has been registered with Ajv in this lifecycle.
|
|
36771
|
+
*
|
|
36772
|
+
* @private
|
|
36773
|
+
*/
|
|
36774
|
+
this.hasRegisteredRootSchema = false;
|
|
36775
|
+
const { additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn, suppressDuplicateFiltering, } = options;
|
|
35938
36776
|
this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn);
|
|
35939
36777
|
this.localizer = localizer;
|
|
36778
|
+
this.suppressDuplicateFiltering = suppressDuplicateFiltering;
|
|
35940
36779
|
}
|
|
35941
36780
|
/** Resets the internal AJV validator to clear schemas from it. Can be helpful for resetting the validator for tests.
|
|
35942
36781
|
*/
|
|
35943
36782
|
reset() {
|
|
35944
36783
|
this.ajv.removeSchema();
|
|
36784
|
+
this.lastSeenRootSchema = undefined;
|
|
36785
|
+
this.hasRegisteredRootSchema = false;
|
|
35945
36786
|
}
|
|
35946
36787
|
/** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use
|
|
35947
36788
|
* by the playground. Returns the `errors` from the validation
|
|
@@ -36029,14 +36870,19 @@ class AJV8Validator {
|
|
|
36029
36870
|
*/
|
|
36030
36871
|
validateFormData(formData, schema, customValidate, transformErrors, uiSchema) {
|
|
36031
36872
|
const rawErrors = this.rawValidation(schema, formData);
|
|
36032
|
-
return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema);
|
|
36873
|
+
return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema, this.suppressDuplicateFiltering);
|
|
36033
36874
|
}
|
|
36034
36875
|
/**
|
|
36035
36876
|
* This function checks if a schema needs to be added and if the root schemas don't match it removes the old root schema from the ajv instance and adds the new one.
|
|
36877
|
+
* When called repeatedly with the same `rootSchema` reference the deep-equality check is skipped.
|
|
36878
|
+
*
|
|
36036
36879
|
* @param rootSchema - The root schema used to provide $ref resolutions
|
|
36037
36880
|
*/
|
|
36038
36881
|
handleSchemaUpdate(rootSchema) {
|
|
36039
36882
|
var _a, _b;
|
|
36883
|
+
if (this.lastSeenRootSchema === rootSchema && this.hasRegisteredRootSchema) {
|
|
36884
|
+
return;
|
|
36885
|
+
}
|
|
36040
36886
|
const rootSchemaId = (_a = rootSchema[ID_KEY]) !== null && _a !== void 0 ? _a : ROOT_SCHEMA_PREFIX;
|
|
36041
36887
|
// add the rootSchema ROOT_SCHEMA_PREFIX as id.
|
|
36042
36888
|
// if schema validator instance doesn't exist, add it.
|
|
@@ -36048,6 +36894,8 @@ class AJV8Validator {
|
|
|
36048
36894
|
this.ajv.removeSchema(rootSchemaId);
|
|
36049
36895
|
this.ajv.addSchema(rootSchema, rootSchemaId);
|
|
36050
36896
|
}
|
|
36897
|
+
this.lastSeenRootSchema = rootSchema;
|
|
36898
|
+
this.hasRegisteredRootSchema = true;
|
|
36051
36899
|
}
|
|
36052
36900
|
/** Validates data against a schema, returning true if the data is valid, or
|
|
36053
36901
|
* false otherwise. If the schema is invalid, then this function will return
|