@regle/core 1.11.0-beta.1 → 1.11.0-beta.3
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/dist/regle-core.d.ts +1215 -3958
- package/dist/regle-core.js +1278 -1286
- package/dist/regle-core.min.js +1 -1
- package/package.json +13 -17
package/dist/regle-core.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { computed, effectScope, getCurrentInstance, getCurrentScope, isRef, markRaw, nextTick, onMounted, onScopeDispose, reactive, ref, shallowRef, toRef, toValue, triggerRef, unref, version, watch, watchEffect } from "vue";
|
|
2
2
|
import { setupDevtoolsPlugin } from "@vue/devtools-api";
|
|
3
3
|
|
|
4
|
-
//#region ../shared/utils/isFile.ts
|
|
5
4
|
/**
|
|
6
5
|
* Server side friendly way of checking for a File
|
|
7
6
|
*/
|
|
@@ -9,8 +8,6 @@ function isFile(value) {
|
|
|
9
8
|
return value?.constructor?.name == "File" || value?.constructor?.name == "FileList";
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
//#endregion
|
|
13
|
-
//#region ../shared/utils/isEmpty.ts
|
|
14
11
|
/**
|
|
15
12
|
* This is the inverse of isFilled. It will check if the value is in any way empty (including arrays and objects)
|
|
16
13
|
*
|
|
@@ -30,12 +27,8 @@ function isEmpty(value, considerEmptyArrayInvalid = true) {
|
|
|
30
27
|
return !String(value).length;
|
|
31
28
|
}
|
|
32
29
|
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region ../shared/utils/symbol.ts
|
|
35
30
|
const RegleRuleSymbol = Symbol("regle-rule");
|
|
36
31
|
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region ../shared/utils/cloneDeep.ts
|
|
39
32
|
function getRegExpFlags(regExp) {
|
|
40
33
|
if (typeof regExp.source.flags == "string") return regExp.source.flags;
|
|
41
34
|
else {
|
|
@@ -62,8 +55,6 @@ function cloneDeep(obj) {
|
|
|
62
55
|
return result;
|
|
63
56
|
}
|
|
64
57
|
|
|
65
|
-
//#endregion
|
|
66
|
-
//#region ../shared/utils/object.utils.ts
|
|
67
58
|
function isObject(obj) {
|
|
68
59
|
if (obj && (obj instanceof Date || obj.constructor.name == "File" || obj.constructor.name == "FileList")) return false;
|
|
69
60
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
@@ -146,8 +137,6 @@ function dotPathObjectToNested(obj) {
|
|
|
146
137
|
return result;
|
|
147
138
|
}
|
|
148
139
|
|
|
149
|
-
//#endregion
|
|
150
|
-
//#region ../shared/utils/toDate.ts
|
|
151
140
|
/**
|
|
152
141
|
* This utility will coerce any string, number or Date value into a Date using the Date constructor.
|
|
153
142
|
*/
|
|
@@ -160,8 +149,6 @@ function toDate(argument) {
|
|
|
160
149
|
else return /* @__PURE__ */ new Date(NaN);
|
|
161
150
|
}
|
|
162
151
|
|
|
163
|
-
//#endregion
|
|
164
|
-
//#region ../shared/utils/debounce.ts
|
|
165
152
|
function debounce(func, wait, { immediate = false, trackDebounceRef } = {}) {
|
|
166
153
|
let timeout;
|
|
167
154
|
const debouncedFn = (...args) => {
|
|
@@ -202,8 +189,6 @@ function debounce(func, wait, { immediate = false, trackDebounceRef } = {}) {
|
|
|
202
189
|
return debouncedFn;
|
|
203
190
|
}
|
|
204
191
|
|
|
205
|
-
//#endregion
|
|
206
|
-
//#region ../shared/utils/isEqual.ts
|
|
207
192
|
function isEqual(a, b, deep = false, firstDeep = true) {
|
|
208
193
|
if (a === b) return true;
|
|
209
194
|
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
@@ -236,8 +221,6 @@ function isEqual(a, b, deep = false, firstDeep = true) {
|
|
|
236
221
|
return a !== a && b !== b;
|
|
237
222
|
}
|
|
238
223
|
|
|
239
|
-
//#endregion
|
|
240
|
-
//#region ../shared/utils/abortablePromise.ts
|
|
241
224
|
var AbortError = class extends Error {
|
|
242
225
|
constructor(message = "Promise was aborted") {
|
|
243
226
|
super(message);
|
|
@@ -279,15 +262,11 @@ function abortablePromise(input) {
|
|
|
279
262
|
};
|
|
280
263
|
}
|
|
281
264
|
|
|
282
|
-
//#endregion
|
|
283
|
-
//#region src/types/rules/rule.internal.types.ts
|
|
284
265
|
const InternalRuleType = {
|
|
285
266
|
Inline: "__inline",
|
|
286
267
|
Async: "__async"
|
|
287
268
|
};
|
|
288
269
|
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region src/types/utils/groups.ts
|
|
291
270
|
function mergeBooleanGroupProperties(entries, property) {
|
|
292
271
|
return entries.some((entry) => {
|
|
293
272
|
if (!property) return false;
|
|
@@ -302,8 +281,6 @@ function mergeArrayGroupProperties(entries, property) {
|
|
|
302
281
|
}, []);
|
|
303
282
|
}
|
|
304
283
|
|
|
305
|
-
//#endregion
|
|
306
|
-
//#region src/core/createRule/unwrapRuleParameters.ts
|
|
307
284
|
/**
|
|
308
285
|
* Returns a clean list of parameters
|
|
309
286
|
* Removing Ref and executing function to return the unwrapped value
|
|
@@ -335,8 +312,6 @@ function getFunctionParametersLength(func) {
|
|
|
335
312
|
return (paramsMatch[0] || paramsMatch[1] || paramsMatch[2] || paramsMatch[3] || paramsMatch[4] || "").split(",").map((p) => p.trim()).filter((p) => p.length > 0).length;
|
|
336
313
|
}
|
|
337
314
|
|
|
338
|
-
//#endregion
|
|
339
|
-
//#region src/core/createRule/defineRuleProcessors.ts
|
|
340
315
|
function defineRuleProcessors(definition, ...params) {
|
|
341
316
|
const { validator, type, async } = definition;
|
|
342
317
|
const isAsync = async || type === InternalRuleType.Async || validator.constructor.name === "AsyncFunction";
|
|
@@ -393,8 +368,6 @@ function defineRuleProcessors(definition, ...params) {
|
|
|
393
368
|
});
|
|
394
369
|
}
|
|
395
370
|
|
|
396
|
-
//#endregion
|
|
397
|
-
//#region src/core/createRule/createRule.ts
|
|
398
371
|
/**
|
|
399
372
|
* Create a typed custom rule that can be used like default rules.
|
|
400
373
|
* It can also be declared in the global options
|
|
@@ -458,8 +431,98 @@ function createRule(definition) {
|
|
|
458
431
|
throw new Error("[createRule] validator must be a function");
|
|
459
432
|
}
|
|
460
433
|
|
|
461
|
-
|
|
462
|
-
|
|
434
|
+
/**
|
|
435
|
+
* Checks if a Vue Ref is an object.
|
|
436
|
+
*
|
|
437
|
+
* @param obj - The Ref to check
|
|
438
|
+
* @returns True if the Ref is an object, false otherwise
|
|
439
|
+
*/
|
|
440
|
+
function isRefObject(obj) {
|
|
441
|
+
return isObject(obj.value);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Unwraps a collection ($each) getter function or returns the getter directly if it's not a function.
|
|
445
|
+
*
|
|
446
|
+
* @template T - The type of the getter function or the getter value
|
|
447
|
+
* @param getter - The getter function or value to unwrap
|
|
448
|
+
* @param value - The value to pass to the getter
|
|
449
|
+
* @param index - The index to pass to the getter
|
|
450
|
+
* @returns An object containing the scope and the unwrapped value
|
|
451
|
+
*/
|
|
452
|
+
function unwrapGetter(getter, value, index) {
|
|
453
|
+
const scope = effectScope();
|
|
454
|
+
let unwrapped;
|
|
455
|
+
if (getter instanceof Function) unwrapped = scope.run(() => getter(value, index ?? 0));
|
|
456
|
+
else unwrapped = getter;
|
|
457
|
+
return {
|
|
458
|
+
scope,
|
|
459
|
+
unwrapped
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const VersionIs = {
|
|
464
|
+
LessThan: -1,
|
|
465
|
+
EqualTo: 0,
|
|
466
|
+
GreaterThan: 1
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* Compare two versions quickly.
|
|
470
|
+
* @param current Is this version greater, equal to, or less than the other?
|
|
471
|
+
* @param other The version to compare against the current version
|
|
472
|
+
* @return 1 if current is greater than other, 0 if they are equal or equivalent, and -1 if current is less than other
|
|
473
|
+
*/
|
|
474
|
+
function versionCompare(current, other) {
|
|
475
|
+
const cp = String(current).split(".");
|
|
476
|
+
const op = String(other).split(".");
|
|
477
|
+
for (let depth = 0; depth < Math.min(cp.length, op.length); depth++) {
|
|
478
|
+
const cn = Number(cp[depth]);
|
|
479
|
+
const on = Number(op[depth]);
|
|
480
|
+
if (cn > on) return VersionIs.GreaterThan;
|
|
481
|
+
if (on > cn) return VersionIs.LessThan;
|
|
482
|
+
if (!isNaN(cn) && isNaN(on)) return VersionIs.GreaterThan;
|
|
483
|
+
if (isNaN(cn) && !isNaN(on)) return VersionIs.LessThan;
|
|
484
|
+
}
|
|
485
|
+
return VersionIs.EqualTo;
|
|
486
|
+
}
|
|
487
|
+
const isVueSuperiorOrEqualTo3dotFive = versionCompare(version, "3.5.0") === -1 ? false : true;
|
|
488
|
+
|
|
489
|
+
function uniqueIDNuxt() {
|
|
490
|
+
return Math.floor(Math.random() * Date.now()).toString();
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Generates a random SSR compatible ID.
|
|
494
|
+
*/
|
|
495
|
+
function randomId() {
|
|
496
|
+
if (typeof window === "undefined") return uniqueIDNuxt();
|
|
497
|
+
else return window.crypto.getRandomValues(new Uint32Array(1))[0].toString(10);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function tryOnScopeDispose(fn) {
|
|
501
|
+
if (getCurrentScope()) {
|
|
502
|
+
onScopeDispose(fn);
|
|
503
|
+
return true;
|
|
504
|
+
}
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Creates a global state that is shared for scoped validation.
|
|
509
|
+
*
|
|
510
|
+
* @param stateFactory - The function that creates the state
|
|
511
|
+
* @returns The state factory function
|
|
512
|
+
*/
|
|
513
|
+
function createGlobalState(stateFactory) {
|
|
514
|
+
let initialized = false;
|
|
515
|
+
let state;
|
|
516
|
+
const scope = effectScope(true);
|
|
517
|
+
return ((...args) => {
|
|
518
|
+
if (!initialized) {
|
|
519
|
+
state = scope.run(() => stateFactory(...args));
|
|
520
|
+
initialized = true;
|
|
521
|
+
}
|
|
522
|
+
return state;
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
|
|
463
526
|
/**
|
|
464
527
|
* Inspired by Vuelidate storage
|
|
465
528
|
*/
|
|
@@ -580,108 +643,6 @@ function useStorage() {
|
|
|
580
643
|
};
|
|
581
644
|
}
|
|
582
645
|
|
|
583
|
-
//#endregion
|
|
584
|
-
//#region src/utils/object.utils.ts
|
|
585
|
-
/**
|
|
586
|
-
* Checks if a Vue Ref is an object.
|
|
587
|
-
*
|
|
588
|
-
* @param obj - The Ref to check
|
|
589
|
-
* @returns True if the Ref is an object, false otherwise
|
|
590
|
-
*/
|
|
591
|
-
function isRefObject(obj) {
|
|
592
|
-
return isObject(obj.value);
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Unwraps a collection ($each) getter function or returns the getter directly if it's not a function.
|
|
596
|
-
*
|
|
597
|
-
* @template T - The type of the getter function or the getter value
|
|
598
|
-
* @param getter - The getter function or value to unwrap
|
|
599
|
-
* @param value - The value to pass to the getter
|
|
600
|
-
* @param index - The index to pass to the getter
|
|
601
|
-
* @returns An object containing the scope and the unwrapped value
|
|
602
|
-
*/
|
|
603
|
-
function unwrapGetter(getter, value, index) {
|
|
604
|
-
const scope = effectScope();
|
|
605
|
-
let unwrapped;
|
|
606
|
-
if (getter instanceof Function) unwrapped = scope.run(() => getter(value, index ?? 0));
|
|
607
|
-
else unwrapped = getter;
|
|
608
|
-
return {
|
|
609
|
-
scope,
|
|
610
|
-
unwrapped
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
//#endregion
|
|
615
|
-
//#region src/utils/version-compare.ts
|
|
616
|
-
const VersionIs = {
|
|
617
|
-
LessThan: -1,
|
|
618
|
-
EqualTo: 0,
|
|
619
|
-
GreaterThan: 1
|
|
620
|
-
};
|
|
621
|
-
/**
|
|
622
|
-
* Compare two versions quickly.
|
|
623
|
-
* @param current Is this version greater, equal to, or less than the other?
|
|
624
|
-
* @param other The version to compare against the current version
|
|
625
|
-
* @return 1 if current is greater than other, 0 if they are equal or equivalent, and -1 if current is less than other
|
|
626
|
-
*/
|
|
627
|
-
function versionCompare(current, other) {
|
|
628
|
-
const cp = String(current).split(".");
|
|
629
|
-
const op = String(other).split(".");
|
|
630
|
-
for (let depth = 0; depth < Math.min(cp.length, op.length); depth++) {
|
|
631
|
-
const cn = Number(cp[depth]);
|
|
632
|
-
const on = Number(op[depth]);
|
|
633
|
-
if (cn > on) return VersionIs.GreaterThan;
|
|
634
|
-
if (on > cn) return VersionIs.LessThan;
|
|
635
|
-
if (!isNaN(cn) && isNaN(on)) return VersionIs.GreaterThan;
|
|
636
|
-
if (isNaN(cn) && !isNaN(on)) return VersionIs.LessThan;
|
|
637
|
-
}
|
|
638
|
-
return VersionIs.EqualTo;
|
|
639
|
-
}
|
|
640
|
-
const isVueSuperiorOrEqualTo3dotFive = versionCompare(version, "3.5.0") === -1 ? false : true;
|
|
641
|
-
|
|
642
|
-
//#endregion
|
|
643
|
-
//#region src/utils/randomId.ts
|
|
644
|
-
function uniqueIDNuxt() {
|
|
645
|
-
return Math.floor(Math.random() * Date.now()).toString();
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* Generates a random SSR compatible ID.
|
|
649
|
-
*/
|
|
650
|
-
function randomId() {
|
|
651
|
-
if (typeof window === "undefined") return uniqueIDNuxt();
|
|
652
|
-
else return window.crypto.getRandomValues(new Uint32Array(1))[0].toString(10);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
//#endregion
|
|
656
|
-
//#region src/utils/state.utils.ts
|
|
657
|
-
function tryOnScopeDispose(fn) {
|
|
658
|
-
if (getCurrentScope()) {
|
|
659
|
-
onScopeDispose(fn);
|
|
660
|
-
return true;
|
|
661
|
-
}
|
|
662
|
-
return false;
|
|
663
|
-
}
|
|
664
|
-
/**
|
|
665
|
-
* Creates a global state that is shared for scoped validation.
|
|
666
|
-
*
|
|
667
|
-
* @param stateFactory - The function that creates the state
|
|
668
|
-
* @returns The state factory function
|
|
669
|
-
*/
|
|
670
|
-
function createGlobalState(stateFactory) {
|
|
671
|
-
let initialized = false;
|
|
672
|
-
let state;
|
|
673
|
-
const scope = effectScope(true);
|
|
674
|
-
return ((...args) => {
|
|
675
|
-
if (!initialized) {
|
|
676
|
-
state = scope.run(() => stateFactory(...args));
|
|
677
|
-
initialized = true;
|
|
678
|
-
}
|
|
679
|
-
return state;
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
//#endregion
|
|
684
|
-
//#region src/core/useRegle/guards/ruleDef.guards.ts
|
|
685
646
|
function isNestedRulesDef(state, rules) {
|
|
686
647
|
return isRefObject(state) || isObject(rules.value) && !isEmpty(rules.value) && !Object.entries(rules.value).some(([_, rule]) => isRuleDef(rule) || typeof rule === "function");
|
|
687
648
|
}
|
|
@@ -702,8 +663,6 @@ function isFormRuleDefinition(rule) {
|
|
|
702
663
|
return true;
|
|
703
664
|
}
|
|
704
665
|
|
|
705
|
-
//#endregion
|
|
706
|
-
//#region src/core/useRegle/guards/rule.status.guards.ts
|
|
707
666
|
function isNestedRulesStatus(rule) {
|
|
708
667
|
return isObject(rule) && "$fields" in rule;
|
|
709
668
|
}
|
|
@@ -714,8 +673,6 @@ function isFieldStatus(rule) {
|
|
|
714
673
|
return !!rule && "$rules" in rule;
|
|
715
674
|
}
|
|
716
675
|
|
|
717
|
-
//#endregion
|
|
718
|
-
//#region src/core/useRegle/useErrors.ts
|
|
719
676
|
function extractRulesIssues({ field, silent = false }) {
|
|
720
677
|
const ruleIssues = Object.entries(field.$rules ?? {}).map(([key, rule]) => {
|
|
721
678
|
let message = "";
|
|
@@ -794,8 +751,6 @@ function iterateErrors(errors, includePath = false, _path) {
|
|
|
794
751
|
} else return Object.entries(errors).map(([key, value]) => iterateErrors(value, includePath, path?.concat(key))).flat();
|
|
795
752
|
}
|
|
796
753
|
|
|
797
|
-
//#endregion
|
|
798
|
-
//#region src/core/useRegle/root/createReactiveRuleStatus.ts
|
|
799
754
|
function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path, cachePath, storage, modifiers }) {
|
|
800
755
|
let scope = effectScope();
|
|
801
756
|
let scopeState = {};
|
|
@@ -829,21 +784,31 @@ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path,
|
|
|
829
784
|
...$metadata.value
|
|
830
785
|
}));
|
|
831
786
|
const $active = computed(() => {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
787
|
+
try {
|
|
788
|
+
if (isFormRuleDefinition(rule)) if (typeof rule.value.active === "function") return rule.value.active($defaultMetadata.value);
|
|
789
|
+
else return !!rule.value.active;
|
|
790
|
+
else return true;
|
|
791
|
+
} catch (e) {
|
|
792
|
+
console.error(`Error in "active" function for "${path}.${ruleKey}" rule`, { cause: e });
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
835
795
|
});
|
|
836
796
|
function computeRuleProcessor(key) {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
797
|
+
try {
|
|
798
|
+
let result = "";
|
|
799
|
+
const customProcessor = customMessages ? customMessages[ruleKey]?.[key] : void 0;
|
|
800
|
+
if (customProcessor) if (typeof customProcessor === "function") result = customProcessor($defaultMetadata.value);
|
|
801
|
+
else result = customProcessor;
|
|
802
|
+
if (isFormRuleDefinition(rule)) {
|
|
803
|
+
const patchedKey = `_${key}_patched`;
|
|
804
|
+
if (!(customProcessor && !rule.value[patchedKey])) if (typeof rule.value[key] === "function") result = rule.value[key]($defaultMetadata.value);
|
|
805
|
+
else result = rule.value[key] ?? "";
|
|
806
|
+
}
|
|
807
|
+
return result;
|
|
808
|
+
} catch (e) {
|
|
809
|
+
console.error(`Error in "${key}" function for "${path}.${ruleKey}" rule`, { cause: e });
|
|
810
|
+
return "";
|
|
845
811
|
}
|
|
846
|
-
return result;
|
|
847
812
|
}
|
|
848
813
|
const $message = computed(() => {
|
|
849
814
|
let message = computeRuleProcessor("message");
|
|
@@ -906,7 +871,7 @@ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path,
|
|
|
906
871
|
if (state.value !== cachedValue) return true;
|
|
907
872
|
if (typeof validatorResult === "boolean") ruleResult = validatorResult;
|
|
908
873
|
else {
|
|
909
|
-
const { $valid: $valid$1
|
|
874
|
+
const { $valid: $valid$1, ...rest } = validatorResult;
|
|
910
875
|
ruleResult = $valid$1;
|
|
911
876
|
$metadata.value = rest;
|
|
912
877
|
}
|
|
@@ -929,7 +894,7 @@ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path,
|
|
|
929
894
|
if (resultOrPromise instanceof Promise) console.warn("You used a async validator function on a non-async rule, please use \"async await\" or the \"withAsync\" helper");
|
|
930
895
|
else if (resultOrPromise != null) if (typeof resultOrPromise === "boolean") ruleResult = resultOrPromise;
|
|
931
896
|
else {
|
|
932
|
-
const { $valid: $valid$1
|
|
897
|
+
const { $valid: $valid$1, ...rest } = resultOrPromise;
|
|
933
898
|
ruleResult = $valid$1;
|
|
934
899
|
$metadata.value = rest;
|
|
935
900
|
}
|
|
@@ -970,8 +935,6 @@ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path,
|
|
|
970
935
|
});
|
|
971
936
|
}
|
|
972
937
|
|
|
973
|
-
//#endregion
|
|
974
|
-
//#region src/core/useRegle/root/standard-schemas.ts
|
|
975
938
|
function createStandardSchema(validateFn) {
|
|
976
939
|
return { "~standard": {
|
|
977
940
|
version: 1,
|
|
@@ -987,8 +950,7 @@ function createStandardSchema(validateFn) {
|
|
|
987
950
|
} };
|
|
988
951
|
}
|
|
989
952
|
|
|
990
|
-
|
|
991
|
-
//#region src/core/useRegle/root/createReactiveFieldStatus.ts
|
|
953
|
+
const DEFAULT_DEBOUNCE_TIME = 200;
|
|
992
954
|
function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cachePath, fieldName, storage, options, externalErrors, schemaErrors, schemaMode, onUnwatch, $isArray, initialState, originalState, shortcuts, onValidate }) {
|
|
993
955
|
let scope = effectScope();
|
|
994
956
|
let scopeState;
|
|
@@ -1039,7 +1001,7 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1039
1001
|
storage.addRuleDeclEntry(cachePath, declaredRules);
|
|
1040
1002
|
}
|
|
1041
1003
|
function define$commit() {
|
|
1042
|
-
if (scopeState.$debounce.value
|
|
1004
|
+
if (scopeState.$debounce.value > 0) $commit = debounce($commitHandler, scopeState.$debounce.value, { trackDebounceRef: $isDebouncing });
|
|
1043
1005
|
else $commit = $commitHandler;
|
|
1044
1006
|
}
|
|
1045
1007
|
function $unwatch() {
|
|
@@ -1062,7 +1024,9 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1062
1024
|
const triggerPunishment = ref(false);
|
|
1063
1025
|
const $anyDirty = computed(() => $dirty.value);
|
|
1064
1026
|
const $debounce$1 = computed(() => {
|
|
1065
|
-
return $localOptions.value.$debounce;
|
|
1027
|
+
if ($localOptions.value.$debounce != null) return $localOptions.value.$debounce;
|
|
1028
|
+
if (scopeState.$haveAnyAsyncRule.value) return DEFAULT_DEBOUNCE_TIME;
|
|
1029
|
+
return 0;
|
|
1066
1030
|
});
|
|
1067
1031
|
const $deepCompare = computed(() => {
|
|
1068
1032
|
if ($localOptions.value.$deepCompare != null) return $localOptions.value.$deepCompare;
|
|
@@ -1188,6 +1152,16 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1188
1152
|
const $haveAnyAsyncRule$1 = computed(() => {
|
|
1189
1153
|
return Object.values($rules.value).some((rule) => rule.$haveAsync);
|
|
1190
1154
|
});
|
|
1155
|
+
const $modifiers = computed(() => {
|
|
1156
|
+
return {
|
|
1157
|
+
$debounce: $debounce$1.value,
|
|
1158
|
+
$lazy: $lazy$1.value,
|
|
1159
|
+
$rewardEarly: $rewardEarly$1.value,
|
|
1160
|
+
$autoDirty: $autoDirty$1.value,
|
|
1161
|
+
$silent: $silent.value,
|
|
1162
|
+
$clearExternalErrorsOnChange: $clearExternalErrorsOnChange$1.value
|
|
1163
|
+
};
|
|
1164
|
+
});
|
|
1191
1165
|
function processShortcuts() {
|
|
1192
1166
|
if (shortcuts?.fields) Object.entries(shortcuts.fields).forEach(([key, value]) => {
|
|
1193
1167
|
const scope$1 = effectScope();
|
|
@@ -1249,7 +1223,8 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1249
1223
|
$dirty,
|
|
1250
1224
|
processShortcuts,
|
|
1251
1225
|
$silentValue,
|
|
1252
|
-
$inactive
|
|
1226
|
+
$inactive,
|
|
1227
|
+
$modifiers
|
|
1253
1228
|
};
|
|
1254
1229
|
});
|
|
1255
1230
|
define$watchState();
|
|
@@ -1395,7 +1370,7 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1395
1370
|
if (externalErrors?.value?.length) externalErrors.value = [];
|
|
1396
1371
|
}
|
|
1397
1372
|
if (!scopeState.$lazy.value && !scopeState.$dirty.value && !scopeState.$silent.value) $commitHandler();
|
|
1398
|
-
const { $shortcuts, $validating, $autoDirty, $rewardEarly, $clearExternalErrorsOnChange, $haveAnyAsyncRule, $debounce, $lazy
|
|
1373
|
+
const { $shortcuts, $validating, $autoDirty, $rewardEarly, $clearExternalErrorsOnChange, $haveAnyAsyncRule, $debounce, $lazy, ...restScope } = scopeState;
|
|
1399
1374
|
return reactive({
|
|
1400
1375
|
...restScope,
|
|
1401
1376
|
$externalErrors: externalErrors,
|
|
@@ -1414,12 +1389,11 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cach
|
|
|
1414
1389
|
$extractDirtyFields,
|
|
1415
1390
|
$clearExternalErrors,
|
|
1416
1391
|
$abort,
|
|
1392
|
+
"~modifiers": scopeState.$modifiers,
|
|
1417
1393
|
...createStandardSchema($validate)
|
|
1418
1394
|
});
|
|
1419
1395
|
}
|
|
1420
1396
|
|
|
1421
|
-
//#endregion
|
|
1422
|
-
//#region src/core/useRegle/root/collections/createReactiveCollectionElement.ts
|
|
1423
1397
|
function createCollectionElement({ $id, path, cachePath, index, options, storage, stateValue, customMessages, rules, externalErrors, schemaErrors, initialState, originalState, shortcuts, fieldName, schemaMode }) {
|
|
1424
1398
|
const $fieldId = stateValue.value?.$id ?? rules.$key ?? randomId();
|
|
1425
1399
|
let $cachePath = `${cachePath}.${String($fieldId)}`;
|
|
@@ -1458,8 +1432,6 @@ function createCollectionElement({ $id, path, cachePath, index, options, storage
|
|
|
1458
1432
|
return $status;
|
|
1459
1433
|
}
|
|
1460
1434
|
|
|
1461
|
-
//#endregion
|
|
1462
|
-
//#region src/core/useRegle/root/collections/createReactiveCollectionRoot.ts
|
|
1463
1435
|
function createReactiveCollectionStatus({ state, rulesDef, customMessages, path, storage, options, externalErrors, schemaErrors, schemaMode, initialState, originalState, shortcuts, fieldName }) {
|
|
1464
1436
|
let scope = effectScope();
|
|
1465
1437
|
let scopeState;
|
|
@@ -1696,6 +1668,16 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
|
|
|
1696
1668
|
return true;
|
|
1697
1669
|
});
|
|
1698
1670
|
const $name = computed(() => fieldName);
|
|
1671
|
+
const $modifiers = computed(() => {
|
|
1672
|
+
return {
|
|
1673
|
+
$deepCompare: $localOptions.value.$deepCompare ?? false,
|
|
1674
|
+
$lazy: $localOptions.value.$lazy ?? false,
|
|
1675
|
+
$rewardEarly: $rewardEarly.value,
|
|
1676
|
+
$autoDirty: $autoDirty.value,
|
|
1677
|
+
$silent: $silent.value,
|
|
1678
|
+
$clearExternalErrorsOnChange: $localOptions.value.$clearExternalErrorsOnChange ?? false
|
|
1679
|
+
};
|
|
1680
|
+
});
|
|
1699
1681
|
function processShortcuts() {
|
|
1700
1682
|
if (shortcuts?.collections) Object.entries(shortcuts?.collections).forEach(([key, value]) => {
|
|
1701
1683
|
const scope$1 = effectScope();
|
|
@@ -1750,7 +1732,8 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
|
|
|
1750
1732
|
$rewardEarly,
|
|
1751
1733
|
$silent,
|
|
1752
1734
|
$autoDirty,
|
|
1753
|
-
$issues
|
|
1735
|
+
$issues,
|
|
1736
|
+
$modifiers
|
|
1754
1737
|
};
|
|
1755
1738
|
});
|
|
1756
1739
|
if (immediateScopeState.isPrimitiveArray.value && rulesDef.value.$each) console.warn(`${path} is a Array of primitives. Tracking can be lost when reassigning the Array. We advise to use an Array of objects instead`);
|
|
@@ -1844,7 +1827,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
|
|
|
1844
1827
|
}
|
|
1845
1828
|
return dirtyFields;
|
|
1846
1829
|
}
|
|
1847
|
-
const { $shortcuts
|
|
1830
|
+
const { $shortcuts, ...restScopeState } = scopeState;
|
|
1848
1831
|
return reactive({
|
|
1849
1832
|
$self: $selfStatus,
|
|
1850
1833
|
...restScopeState,
|
|
@@ -1862,13 +1845,12 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
|
|
|
1862
1845
|
$abort,
|
|
1863
1846
|
$extractDirtyFields,
|
|
1864
1847
|
$clearExternalErrors,
|
|
1848
|
+
"~modifiers": scopeState.$modifiers,
|
|
1865
1849
|
...createStandardSchema($validate)
|
|
1866
1850
|
});
|
|
1867
1851
|
}
|
|
1868
1852
|
|
|
1869
|
-
|
|
1870
|
-
//#region src/core/useRegle/root/createReactiveNestedStatus.ts
|
|
1871
|
-
function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, rootRules, externalErrors, schemaErrors, rootSchemaErrors, validationGroups, initialState, originalState, fieldName,...commonArgs }) {
|
|
1853
|
+
function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, rootRules, externalErrors, schemaErrors, rootSchemaErrors, validationGroups, initialState, originalState, fieldName, ...commonArgs }) {
|
|
1872
1854
|
let scope = effectScope();
|
|
1873
1855
|
let scopeState;
|
|
1874
1856
|
let nestedScopes = [];
|
|
@@ -2110,6 +2092,16 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2110
2092
|
return false;
|
|
2111
2093
|
});
|
|
2112
2094
|
const $name = computed(() => fieldName);
|
|
2095
|
+
const $modifiers = computed(() => {
|
|
2096
|
+
return {
|
|
2097
|
+
autoDirty: $autoDirty.value,
|
|
2098
|
+
lazy: unref(commonArgs.options.lazy) ?? false,
|
|
2099
|
+
rewardEarly: $rewardEarly.value,
|
|
2100
|
+
silent: $silent.value,
|
|
2101
|
+
clearExternalErrorsOnChange: unref(commonArgs.options.clearExternalErrorsOnChange) ?? false,
|
|
2102
|
+
id: unref(commonArgs.options.id)
|
|
2103
|
+
};
|
|
2104
|
+
});
|
|
2113
2105
|
function processShortcuts() {
|
|
2114
2106
|
if (commonArgs.shortcuts?.nested) Object.entries(commonArgs.shortcuts.nested).forEach(([key, value]) => {
|
|
2115
2107
|
const scope$1 = effectScope();
|
|
@@ -2135,7 +2127,8 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2135
2127
|
$fields,
|
|
2136
2128
|
$edited,
|
|
2137
2129
|
$anyEdited,
|
|
2138
|
-
$issues
|
|
2130
|
+
$issues,
|
|
2131
|
+
"~modifiers": unref(commonArgs.options)
|
|
2139
2132
|
}));
|
|
2140
2133
|
});
|
|
2141
2134
|
return result;
|
|
@@ -2184,7 +2177,8 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2184
2177
|
$localPending,
|
|
2185
2178
|
$autoDirty,
|
|
2186
2179
|
$silent,
|
|
2187
|
-
$value
|
|
2180
|
+
$value,
|
|
2181
|
+
$modifiers
|
|
2188
2182
|
};
|
|
2189
2183
|
});
|
|
2190
2184
|
}
|
|
@@ -2275,7 +2269,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2275
2269
|
scopeState.$localPending.value = false;
|
|
2276
2270
|
}
|
|
2277
2271
|
}
|
|
2278
|
-
const { $shortcuts, $localPending: _$localPending
|
|
2272
|
+
const { $shortcuts, $localPending: _$localPending, ...restScopeState } = scopeState;
|
|
2279
2273
|
const fullStatus = reactive({
|
|
2280
2274
|
...restScopeState,
|
|
2281
2275
|
...$shortcuts,
|
|
@@ -2291,6 +2285,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2291
2285
|
$clearExternalErrors,
|
|
2292
2286
|
$extractDirtyFields,
|
|
2293
2287
|
$abort,
|
|
2288
|
+
...!!rootRules ? { "~modifiers": scopeState.$modifiers } : {},
|
|
2294
2289
|
...createStandardSchema($validate)
|
|
2295
2290
|
});
|
|
2296
2291
|
watchEffect(() => {
|
|
@@ -2302,7 +2297,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, roo
|
|
|
2302
2297
|
/**
|
|
2303
2298
|
* Main resolver divider, will distribute the logic depending on the type of the current value (primitive, object, array)
|
|
2304
2299
|
*/
|
|
2305
|
-
function createReactiveChildrenStatus({ rulesDef
|
|
2300
|
+
function createReactiveChildrenStatus({ rulesDef, ...properties }) {
|
|
2306
2301
|
if (isCollectionRulesDef(rulesDef, properties.state, properties.schemaMode)) return createReactiveCollectionStatus({
|
|
2307
2302
|
rulesDef,
|
|
2308
2303
|
...properties
|
|
@@ -2322,7 +2317,7 @@ function createReactiveChildrenStatus({ rulesDef,...properties }) {
|
|
|
2322
2317
|
}, { deep: true });
|
|
2323
2318
|
return { fakeState };
|
|
2324
2319
|
});
|
|
2325
|
-
const { state: _state
|
|
2320
|
+
const { state: _state, ...restProperties } = properties;
|
|
2326
2321
|
return createReactiveNestedStatus({
|
|
2327
2322
|
rulesDef,
|
|
2328
2323
|
...restProperties,
|
|
@@ -2335,1248 +2330,1245 @@ function createReactiveChildrenStatus({ rulesDef,...properties }) {
|
|
|
2335
2330
|
});
|
|
2336
2331
|
}
|
|
2337
2332
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2333
|
+
const COLORS = {
|
|
2334
|
+
ERROR: {
|
|
2335
|
+
text: 16777215,
|
|
2336
|
+
bg: 15680580
|
|
2337
|
+
},
|
|
2338
|
+
INVALID: {
|
|
2339
|
+
text: 16777215,
|
|
2340
|
+
bg: 16747520
|
|
2341
|
+
},
|
|
2342
|
+
VALID: {
|
|
2343
|
+
text: 16777215,
|
|
2344
|
+
bg: 1096065
|
|
2345
|
+
},
|
|
2346
|
+
PENDING: {
|
|
2347
|
+
text: 16777215,
|
|
2348
|
+
bg: 16096779
|
|
2349
|
+
},
|
|
2350
|
+
DIRTY: {
|
|
2351
|
+
text: 2042167,
|
|
2352
|
+
bg: 16708551
|
|
2353
|
+
},
|
|
2354
|
+
COMPONENT: {
|
|
2355
|
+
text: 16777215,
|
|
2356
|
+
bg: 6514417
|
|
2357
|
+
},
|
|
2358
|
+
PRISTINE: {
|
|
2359
|
+
text: 1120295,
|
|
2360
|
+
bg: 16777215
|
|
2361
|
+
},
|
|
2362
|
+
INACTIVE: {
|
|
2363
|
+
text: 0,
|
|
2364
|
+
bg: 11581118
|
|
2363
2365
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
customMessages: customRules?.(),
|
|
2389
|
-
storage,
|
|
2390
|
-
options,
|
|
2391
|
-
externalErrors: computedExternalErrors,
|
|
2392
|
-
initialState,
|
|
2393
|
-
originalState,
|
|
2394
|
-
shortcuts,
|
|
2395
|
-
fieldName: "root",
|
|
2396
|
-
path: "",
|
|
2397
|
-
cachePath: "",
|
|
2398
|
-
schemaMode,
|
|
2399
|
-
schemaErrors,
|
|
2400
|
-
onValidate
|
|
2401
|
-
});
|
|
2402
|
-
if (getCurrentScope()) onScopeDispose(() => {
|
|
2403
|
-
regle.value?.$unwatch();
|
|
2404
|
-
$unwatchComputedExternalErrors?.();
|
|
2405
|
-
$unwatchExternalErrors?.();
|
|
2406
|
-
});
|
|
2407
|
-
return reactive({ regle });
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
//#endregion
|
|
2411
|
-
//#region src/core/useRegle/shared.rootRegle.ts
|
|
2412
|
-
function createRootRegleLogic({ state, rulesFactory, options, globalOptions, customRules, shortcuts }) {
|
|
2413
|
-
const definedRules = isRef(rulesFactory) ? rulesFactory : typeof rulesFactory === "function" ? void 0 : computed(() => rulesFactory);
|
|
2414
|
-
const resolvedOptions = {
|
|
2415
|
-
...globalOptions,
|
|
2416
|
-
...options
|
|
2417
|
-
};
|
|
2418
|
-
let unwatchRules;
|
|
2419
|
-
const watchableRulesGetters = shallowRef(definedRules ?? {});
|
|
2420
|
-
if (typeof rulesFactory === "function") unwatchRules = watchEffect(() => {
|
|
2421
|
-
watchableRulesGetters.value = rulesFactory(state);
|
|
2422
|
-
triggerRef(watchableRulesGetters);
|
|
2423
|
-
});
|
|
2424
|
-
const initialState = ref(isObject(state.value) ? { ...cloneDeep(state.value) } : cloneDeep(state.value));
|
|
2425
|
-
const originalState = isObject(state.value) ? { ...cloneDeep(state.value) } : cloneDeep(state.value);
|
|
2426
|
-
tryOnScopeDispose(() => {
|
|
2427
|
-
unwatchRules?.();
|
|
2428
|
-
});
|
|
2429
|
-
const regle = useRootStorage({
|
|
2430
|
-
scopeRules: watchableRulesGetters,
|
|
2431
|
-
state,
|
|
2432
|
-
options: resolvedOptions,
|
|
2433
|
-
initialState,
|
|
2434
|
-
originalState,
|
|
2435
|
-
customRules,
|
|
2436
|
-
shortcuts
|
|
2437
|
-
});
|
|
2438
|
-
if (process.env.NODE_ENV === "development" && regle.regle) registerRegleInstance(regle.regle, { name: toValue(resolvedOptions.id) });
|
|
2439
|
-
return regle;
|
|
2440
|
-
}
|
|
2366
|
+
};
|
|
2367
|
+
const PRIORITY_KEYS = {
|
|
2368
|
+
ROOT: [
|
|
2369
|
+
"$invalid",
|
|
2370
|
+
"$dirty",
|
|
2371
|
+
"$error",
|
|
2372
|
+
"$pending",
|
|
2373
|
+
"$valid",
|
|
2374
|
+
"$ready"
|
|
2375
|
+
],
|
|
2376
|
+
FIELD: [
|
|
2377
|
+
"$value",
|
|
2378
|
+
"$invalid",
|
|
2379
|
+
"$dirty",
|
|
2380
|
+
"$error",
|
|
2381
|
+
"$pending",
|
|
2382
|
+
"$errors"
|
|
2383
|
+
]
|
|
2384
|
+
};
|
|
2385
|
+
const INSPECTOR_IDS = {
|
|
2386
|
+
INSPECTOR: "regle-inspector",
|
|
2387
|
+
COMPONENTS: "components",
|
|
2388
|
+
TIMELINE: "regle-timeline"
|
|
2389
|
+
};
|
|
2441
2390
|
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
const
|
|
2452
|
-
|
|
2391
|
+
function useRegleDevtoolsRegistry() {
|
|
2392
|
+
const devtoolsApi = shallowRef();
|
|
2393
|
+
const instances = shallowRef(/* @__PURE__ */ new Map());
|
|
2394
|
+
const watchers = shallowRef(/* @__PURE__ */ new Map());
|
|
2395
|
+
let idCounter = 0;
|
|
2396
|
+
function setApi(api) {
|
|
2397
|
+
devtoolsApi.value = api;
|
|
2398
|
+
}
|
|
2399
|
+
function register(r$, options) {
|
|
2400
|
+
const id = `${options?.uid?.toString() ?? "regle"}#${++idCounter}`;
|
|
2401
|
+
const name = options?.name || `Regle #${idCounter}`;
|
|
2402
|
+
instances.value.set(id, {
|
|
2453
2403
|
id,
|
|
2454
2404
|
name,
|
|
2455
2405
|
r$,
|
|
2456
2406
|
componentName: options?.componentName ? `<${options.componentName}>` : void 0
|
|
2457
2407
|
});
|
|
2458
|
-
|
|
2408
|
+
const stopHandle = watch(() => r$, () => notifyDevtools(), {
|
|
2409
|
+
deep: true,
|
|
2410
|
+
flush: "post"
|
|
2411
|
+
});
|
|
2412
|
+
regleDevtoolsRegistry.addWatcher(id, stopHandle);
|
|
2413
|
+
notifyDevtools();
|
|
2459
2414
|
return id;
|
|
2460
2415
|
}
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2416
|
+
function notifyDevtools() {
|
|
2417
|
+
if (devtoolsApi.value) emitInspectorState(devtoolsApi.value);
|
|
2418
|
+
}
|
|
2419
|
+
function unregister(id) {
|
|
2420
|
+
instances.value.delete(id);
|
|
2421
|
+
const watcher = watchers.value.get(id);
|
|
2464
2422
|
if (watcher) {
|
|
2465
2423
|
watcher();
|
|
2466
|
-
|
|
2424
|
+
watchers.value.delete(id);
|
|
2467
2425
|
}
|
|
2468
|
-
|
|
2469
|
-
}
|
|
2470
|
-
getAll() {
|
|
2471
|
-
return Array.from(this.instances.values());
|
|
2426
|
+
notifyDevtools();
|
|
2472
2427
|
}
|
|
2473
|
-
|
|
2474
|
-
return
|
|
2428
|
+
function getAll() {
|
|
2429
|
+
return Array.from(instances.value.values());
|
|
2475
2430
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
this.watchers.clear();
|
|
2479
|
-
this.instances.clear();
|
|
2480
|
-
this.notifyDevtools();
|
|
2431
|
+
function get(id) {
|
|
2432
|
+
return instances.value.get(id);
|
|
2481
2433
|
}
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
}
|
|
2488
|
-
addWatcher(id, stopHandle) {
|
|
2489
|
-
this.watchers.set(id, stopHandle);
|
|
2434
|
+
function clear() {
|
|
2435
|
+
watchers.value.forEach((stop) => stop());
|
|
2436
|
+
watchers.value.clear();
|
|
2437
|
+
instances.value.clear();
|
|
2438
|
+
notifyDevtools();
|
|
2490
2439
|
}
|
|
2491
|
-
|
|
2492
|
-
|
|
2440
|
+
function addWatcher(id, stopHandle) {
|
|
2441
|
+
watchers.value.set(id, stopHandle);
|
|
2493
2442
|
}
|
|
2494
|
-
|
|
2495
|
-
|
|
2443
|
+
return {
|
|
2444
|
+
register,
|
|
2445
|
+
unregister,
|
|
2446
|
+
getAll,
|
|
2447
|
+
get,
|
|
2448
|
+
clear,
|
|
2449
|
+
addWatcher,
|
|
2450
|
+
setApi,
|
|
2451
|
+
notifyDevtools
|
|
2452
|
+
};
|
|
2453
|
+
}
|
|
2454
|
+
const regleDevtoolsRegistry = useRegleDevtoolsRegistry();
|
|
2455
|
+
/**
|
|
2456
|
+
* To be used by `useRegle` composable.
|
|
2457
|
+
*/
|
|
2496
2458
|
function registerRegleInstance(r$, options) {
|
|
2497
2459
|
if (typeof window === "undefined") return;
|
|
2498
2460
|
const instance = getCurrentInstance();
|
|
2499
2461
|
const componentName = instance?.type?.name || instance?.type?.__name;
|
|
2500
2462
|
const id = regleDevtoolsRegistry.register(r$, {
|
|
2501
2463
|
name: options?.name,
|
|
2502
|
-
componentName
|
|
2464
|
+
componentName,
|
|
2465
|
+
uid: instance?.uid
|
|
2503
2466
|
});
|
|
2504
2467
|
tryOnScopeDispose(() => {
|
|
2505
2468
|
regleDevtoolsRegistry.unregister(id);
|
|
2506
2469
|
});
|
|
2507
2470
|
}
|
|
2508
|
-
function watchRegleInstance(id, r$, onChange) {
|
|
2509
|
-
const stopHandle = watch(() => r$, onChange, {
|
|
2510
|
-
deep: true,
|
|
2511
|
-
flush: "post"
|
|
2512
|
-
});
|
|
2513
|
-
regleDevtoolsRegistry.addWatcher(id, stopHandle);
|
|
2514
|
-
return stopHandle;
|
|
2515
|
-
}
|
|
2516
2471
|
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
function createUseRegleComposable(customRules, options, shortcuts) {
|
|
2520
|
-
const globalOptions = {
|
|
2521
|
-
autoDirty: options?.autoDirty,
|
|
2522
|
-
lazy: options?.lazy,
|
|
2523
|
-
rewardEarly: options?.rewardEarly,
|
|
2524
|
-
silent: options?.silent,
|
|
2525
|
-
clearExternalErrorsOnChange: options?.clearExternalErrorsOnChange
|
|
2526
|
-
};
|
|
2527
|
-
function useRegle$1(state, rulesFactory, options$1) {
|
|
2528
|
-
return { r$: createRootRegleLogic({
|
|
2529
|
-
state: isRef(state) ? state : ref(state),
|
|
2530
|
-
rulesFactory,
|
|
2531
|
-
options: options$1,
|
|
2532
|
-
globalOptions,
|
|
2533
|
-
customRules,
|
|
2534
|
-
shortcuts
|
|
2535
|
-
}).regle };
|
|
2536
|
-
}
|
|
2537
|
-
return useRegle$1;
|
|
2472
|
+
function isMethod(value) {
|
|
2473
|
+
return typeof value === "function";
|
|
2538
2474
|
}
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
* import { useRegle } from '@regle/core';
|
|
2550
|
-
import { required } from '@regle/rules';
|
|
2551
|
-
|
|
2552
|
-
const { r$ } = useRegle({ email: '' }, {
|
|
2553
|
-
email: { required }
|
|
2554
|
-
})
|
|
2555
|
-
* ```
|
|
2556
|
-
* Docs: {@link https://reglejs.dev/core-concepts/}
|
|
2557
|
-
*/
|
|
2558
|
-
const useRegle = createUseRegleComposable();
|
|
2559
|
-
|
|
2560
|
-
//#endregion
|
|
2561
|
-
//#region src/core/useRegle/inferRules.ts
|
|
2562
|
-
function createInferRuleHelper() {
|
|
2563
|
-
function inferRules$1(state, rulesFactory) {
|
|
2564
|
-
return rulesFactory;
|
|
2565
|
-
}
|
|
2566
|
-
return inferRules$1;
|
|
2475
|
+
function getPriorityProperties(obj, keys) {
|
|
2476
|
+
return keys.filter((key) => key in obj && !isMethod(obj[key])).map((key) => {
|
|
2477
|
+
let editable = false;
|
|
2478
|
+
if (key === "$value") editable = true;
|
|
2479
|
+
return {
|
|
2480
|
+
key,
|
|
2481
|
+
value: obj[key],
|
|
2482
|
+
editable
|
|
2483
|
+
};
|
|
2484
|
+
});
|
|
2567
2485
|
}
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
*/
|
|
2575
|
-
const inferRules = createInferRuleHelper();
|
|
2576
|
-
|
|
2577
|
-
//#endregion
|
|
2578
|
-
//#region src/core/useRegle/useRules.ts
|
|
2579
|
-
function registerRegleWithDevtools(regle, options) {
|
|
2580
|
-
try {
|
|
2581
|
-
registerRegleInstance(regle, { name: options?.devtoolsName });
|
|
2582
|
-
} catch (e) {}
|
|
2486
|
+
function getRemainingProperties(obj, excludeKeys) {
|
|
2487
|
+
return Object.entries(obj).filter(([key]) => !excludeKeys.includes(key) && key.startsWith("$") && !isMethod(obj[key])).map(([key, value]) => ({
|
|
2488
|
+
key,
|
|
2489
|
+
value,
|
|
2490
|
+
editable: false
|
|
2491
|
+
}));
|
|
2583
2492
|
}
|
|
2584
|
-
function
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
else result[key] = null;
|
|
2592
|
-
}
|
|
2593
|
-
return result;
|
|
2493
|
+
function parseFieldNodeId(nodeId) {
|
|
2494
|
+
if (!nodeId.includes(":field:")) return null;
|
|
2495
|
+
const [instanceId, , fieldName] = nodeId.split(":");
|
|
2496
|
+
return {
|
|
2497
|
+
instanceId,
|
|
2498
|
+
fieldName
|
|
2499
|
+
};
|
|
2594
2500
|
}
|
|
2595
|
-
function
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2501
|
+
function createFieldNodeId(instanceId, fieldName) {
|
|
2502
|
+
return `${instanceId}:field:${fieldName}`;
|
|
2503
|
+
}
|
|
2504
|
+
function parseRuleNodeId(nodeId) {
|
|
2505
|
+
if (!nodeId.includes(":rule:")) return null;
|
|
2506
|
+
const parts = nodeId.split(":rule:");
|
|
2507
|
+
if (parts.length !== 2) return null;
|
|
2508
|
+
const fieldPart = parts[0];
|
|
2509
|
+
const ruleName = parts[1];
|
|
2510
|
+
const fieldInfo = parseFieldNodeId(fieldPart);
|
|
2511
|
+
if (!fieldInfo) return null;
|
|
2512
|
+
return {
|
|
2513
|
+
...fieldInfo,
|
|
2514
|
+
ruleName
|
|
2602
2515
|
};
|
|
2603
|
-
function useRules$1(rulesFactory, options$1) {
|
|
2604
|
-
const definedRules = isRef(rulesFactory) ? rulesFactory : typeof rulesFactory === "function" ? void 0 : computed(() => rulesFactory);
|
|
2605
|
-
const regle = createRootRegleLogic({
|
|
2606
|
-
state: ref(createEmptyRuleState(definedRules?.value)),
|
|
2607
|
-
rulesFactory: definedRules,
|
|
2608
|
-
options: options$1,
|
|
2609
|
-
globalOptions,
|
|
2610
|
-
customRules,
|
|
2611
|
-
shortcuts
|
|
2612
|
-
});
|
|
2613
|
-
registerRegleWithDevtools(regle.regle, options$1);
|
|
2614
|
-
return regle.regle;
|
|
2615
|
-
}
|
|
2616
|
-
return useRules$1;
|
|
2617
2516
|
}
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
* It accepts the following inputs:
|
|
2622
|
-
*
|
|
2623
|
-
* @param rules - Your rules object
|
|
2624
|
-
* @param modifiers - Customize regle behaviour
|
|
2625
|
-
*
|
|
2626
|
-
* ```ts
|
|
2627
|
-
* import { useRules } from '@regle/core';
|
|
2628
|
-
import { required } from '@regle/rules';
|
|
2629
|
-
|
|
2630
|
-
const { r$ } = useRules({
|
|
2631
|
-
email: { required }
|
|
2632
|
-
})
|
|
2633
|
-
* ```
|
|
2634
|
-
*/
|
|
2635
|
-
const useRules = createUseRulesComposable();
|
|
2517
|
+
function createRuleNodeId(instanceId, fieldName, ruleName) {
|
|
2518
|
+
return `${createFieldNodeId(instanceId, fieldName)}:rule:${ruleName}`;
|
|
2519
|
+
}
|
|
2636
2520
|
|
|
2637
|
-
//#endregion
|
|
2638
|
-
//#region src/core/defineRegleConfig.ts
|
|
2639
2521
|
/**
|
|
2640
|
-
*
|
|
2641
|
-
* - Customize built-in rules messages
|
|
2642
|
-
* - Add your custom rules
|
|
2643
|
-
* - Define global modifiers
|
|
2644
|
-
* - Define shortcuts
|
|
2645
|
-
*
|
|
2646
|
-
* It will return:
|
|
2647
|
-
*
|
|
2648
|
-
* - a `useRegle` composable that can typecheck your custom rules
|
|
2649
|
-
* - an `inferRules` helper that can typecheck your custom rules
|
|
2522
|
+
* Build state for a field node
|
|
2650
2523
|
*/
|
|
2651
|
-
function
|
|
2652
|
-
const
|
|
2653
|
-
const
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
useRules: useRules$1
|
|
2668
|
-
};
|
|
2524
|
+
function buildFieldState(fieldStatus) {
|
|
2525
|
+
const state = {};
|
|
2526
|
+
const priorityProperties = getPriorityProperties(fieldStatus, PRIORITY_KEYS.FIELD);
|
|
2527
|
+
if (priorityProperties.length > 0) state["State"] = priorityProperties;
|
|
2528
|
+
const remainingProperties = getRemainingProperties(fieldStatus, [
|
|
2529
|
+
...PRIORITY_KEYS.FIELD,
|
|
2530
|
+
"$rules",
|
|
2531
|
+
"$fields"
|
|
2532
|
+
]);
|
|
2533
|
+
if (remainingProperties.length > 0) state["Other Properties"] = remainingProperties;
|
|
2534
|
+
if (fieldStatus["~modifiers"]) state["Modifiers"] = Object.entries(fieldStatus["~modifiers"]).map(([key, value]) => ({
|
|
2535
|
+
key,
|
|
2536
|
+
value,
|
|
2537
|
+
editable: false
|
|
2538
|
+
}));
|
|
2539
|
+
return state;
|
|
2669
2540
|
}
|
|
2670
2541
|
/**
|
|
2671
|
-
*
|
|
2672
|
-
*
|
|
2673
|
-
* It will return:
|
|
2674
|
-
*
|
|
2675
|
-
* - a `useRegle` composable that can typecheck your custom rules
|
|
2676
|
-
* - an `inferRules` helper that can typecheck your custom rules
|
|
2542
|
+
* Build state for a rule node
|
|
2677
2543
|
*/
|
|
2678
|
-
function
|
|
2679
|
-
const
|
|
2680
|
-
const
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2544
|
+
function buildRuleState(ruleStatus) {
|
|
2545
|
+
const state = {};
|
|
2546
|
+
const ruleKeys = [
|
|
2547
|
+
"$type",
|
|
2548
|
+
"$valid",
|
|
2549
|
+
"$active",
|
|
2550
|
+
"$pending",
|
|
2551
|
+
"$message",
|
|
2552
|
+
"$tooltip"
|
|
2553
|
+
];
|
|
2554
|
+
const priorityProperties = getPriorityProperties(ruleStatus, ruleKeys);
|
|
2555
|
+
if (priorityProperties.length > 0) state["Rule State"] = priorityProperties;
|
|
2556
|
+
if (ruleStatus.$params && Array.isArray(ruleStatus.$params) && ruleStatus.$params.length > 0) state["Parameters"] = [{
|
|
2557
|
+
key: "$params",
|
|
2558
|
+
value: ruleStatus.$params,
|
|
2559
|
+
editable: false
|
|
2560
|
+
}];
|
|
2561
|
+
if (ruleStatus.$metadata !== void 0 && ruleStatus.$metadata !== true && ruleStatus.$metadata !== false) state["Metadata"] = [{
|
|
2562
|
+
key: "$metadata",
|
|
2563
|
+
value: ruleStatus.$metadata,
|
|
2564
|
+
objectType: "reactive",
|
|
2565
|
+
editable: false
|
|
2566
|
+
}];
|
|
2567
|
+
const remainingProperties = getRemainingProperties(ruleStatus, [
|
|
2568
|
+
...ruleKeys,
|
|
2569
|
+
"$params",
|
|
2570
|
+
"$metadata",
|
|
2571
|
+
"$haveAsync",
|
|
2572
|
+
"$validating",
|
|
2573
|
+
"$fieldDirty",
|
|
2574
|
+
"$fieldInvalid",
|
|
2575
|
+
"$fieldPending",
|
|
2576
|
+
"$fieldCorrect",
|
|
2577
|
+
"$fieldError",
|
|
2578
|
+
"$maybePending",
|
|
2579
|
+
"$externalErrors"
|
|
2580
|
+
]);
|
|
2581
|
+
if (remainingProperties.length > 0) state["Other Properties"] = remainingProperties;
|
|
2582
|
+
return state;
|
|
2583
|
+
}
|
|
2584
|
+
function buildRootState(r$) {
|
|
2585
|
+
const state = {};
|
|
2586
|
+
const priorityProperties = getPriorityProperties(r$, PRIORITY_KEYS.ROOT);
|
|
2587
|
+
if (priorityProperties.length > 0) state["State"] = priorityProperties;
|
|
2588
|
+
const remainingProperties = getRemainingProperties(r$, [...PRIORITY_KEYS.ROOT, "$fields"]);
|
|
2589
|
+
if (remainingProperties.length > 0) state["Other Properties"] = remainingProperties;
|
|
2590
|
+
if (r$["~modifiers"]) state["Modifiers"] = Object.entries(r$["~modifiers"]).map(([key, value]) => ({
|
|
2591
|
+
key,
|
|
2592
|
+
value,
|
|
2593
|
+
editable: false
|
|
2594
|
+
}));
|
|
2595
|
+
return state;
|
|
2596
|
+
}
|
|
2597
|
+
function resolveFieldByPath(fields, path) {
|
|
2598
|
+
if (!fields || !path) return null;
|
|
2599
|
+
const segments = path.match(/[^.\[\]]+/g);
|
|
2600
|
+
if (!segments) return null;
|
|
2601
|
+
let current = fields;
|
|
2602
|
+
for (const segment of segments) {
|
|
2603
|
+
if (!current) return null;
|
|
2604
|
+
const index = parseInt(segment);
|
|
2605
|
+
if (!isNaN(index)) if (isCollectionRulesStatus(current) && Array.isArray(current.$each)) current = current.$each[index];
|
|
2606
|
+
else return null;
|
|
2607
|
+
else if (isCollectionRulesStatus(current) && current.$self && current.$self) current = current.$self;
|
|
2608
|
+
else if (isNestedRulesStatus(current) && current.$fields && current.$fields[segment]) current = current.$fields[segment];
|
|
2609
|
+
else if (current[segment]) current = current[segment];
|
|
2610
|
+
else return null;
|
|
2611
|
+
}
|
|
2612
|
+
return current;
|
|
2613
|
+
}
|
|
2614
|
+
function buildInspectorState(nodeId, getInstance) {
|
|
2615
|
+
const ruleInfo = parseRuleNodeId(nodeId);
|
|
2616
|
+
if (ruleInfo) {
|
|
2617
|
+
const { instanceId, fieldName, ruleName } = ruleInfo;
|
|
2618
|
+
const instance$1 = getInstance(instanceId);
|
|
2619
|
+
if (!instance$1 || !instance$1.r$.$fields) return null;
|
|
2620
|
+
const fieldStatus = resolveFieldByPath(instance$1.r$.$fields, fieldName);
|
|
2621
|
+
if (!fieldStatus || !("$rules" in fieldStatus)) return null;
|
|
2622
|
+
const ruleStatus = fieldStatus.$rules[ruleName];
|
|
2623
|
+
if (!ruleStatus) return null;
|
|
2624
|
+
return buildRuleState(ruleStatus);
|
|
2625
|
+
}
|
|
2626
|
+
const fieldInfo = parseFieldNodeId(nodeId);
|
|
2627
|
+
if (fieldInfo) {
|
|
2628
|
+
const { instanceId, fieldName } = fieldInfo;
|
|
2629
|
+
const instance$1 = getInstance(instanceId);
|
|
2630
|
+
if (!instance$1 || !instance$1.r$.$fields) return null;
|
|
2631
|
+
const fieldStatus = resolveFieldByPath(instance$1.r$.$fields, fieldName);
|
|
2632
|
+
if (!fieldStatus) return null;
|
|
2633
|
+
return buildFieldState(fieldStatus);
|
|
2634
|
+
}
|
|
2635
|
+
const instance = getInstance(nodeId);
|
|
2636
|
+
if (!instance) return null;
|
|
2637
|
+
return buildRootState(instance.r$);
|
|
2696
2638
|
}
|
|
2697
2639
|
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
get
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
set: (value) => {
|
|
2708
|
-
if (!scoped) {
|
|
2709
|
-
if (typeof value === "object") Object.entries(value).forEach(([key, newValue]) => regles[key].$value = newValue);
|
|
2710
|
-
}
|
|
2640
|
+
function handleValidateAction(nodeId, api) {
|
|
2641
|
+
if (nodeId.includes(":rule:")) return;
|
|
2642
|
+
const fieldInfo = parseFieldNodeId(nodeId);
|
|
2643
|
+
if (fieldInfo) {
|
|
2644
|
+
const { instanceId, fieldName } = fieldInfo;
|
|
2645
|
+
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
2646
|
+
if (instance && instance.r$.$fields) {
|
|
2647
|
+
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldName);
|
|
2648
|
+
if (fieldStatus && typeof fieldStatus.$validate === "function") fieldStatus.$validate();
|
|
2711
2649
|
}
|
|
2712
|
-
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2650
|
+
} else {
|
|
2651
|
+
const instance = regleDevtoolsRegistry.get(nodeId);
|
|
2652
|
+
if (instance && typeof instance.r$.$validate === "function") instance.r$.$validate();
|
|
2653
|
+
}
|
|
2654
|
+
emitInspectorState(api);
|
|
2655
|
+
}
|
|
2656
|
+
async function handleResetAction(nodeId, api, resetState = false) {
|
|
2657
|
+
const fieldInfo = parseFieldNodeId(nodeId);
|
|
2658
|
+
if (fieldInfo) {
|
|
2659
|
+
const { instanceId, fieldName } = fieldInfo;
|
|
2660
|
+
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
2661
|
+
if (instance && instance.r$.$fields) {
|
|
2662
|
+
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldName);
|
|
2663
|
+
if (fieldStatus && typeof fieldStatus.$reset === "function") fieldStatus.$reset({ toOriginalState: resetState });
|
|
2717
2664
|
}
|
|
2665
|
+
} else {
|
|
2666
|
+
const instance = regleDevtoolsRegistry.get(nodeId);
|
|
2667
|
+
if (instance && typeof instance.r$.$reset === "function") instance.r$.$reset({ toOriginalState: resetState });
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
function handleEditInspectorState(payload) {
|
|
2671
|
+
const { nodeId, path, state } = payload;
|
|
2672
|
+
if (!path.includes("$value")) return;
|
|
2673
|
+
if (!parseFieldNodeId(nodeId)) return;
|
|
2674
|
+
const [instanceId, _, fieldPath] = nodeId.split(":");
|
|
2675
|
+
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
2676
|
+
if (instance && instance.r$.$fields) {
|
|
2677
|
+
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldPath);
|
|
2678
|
+
if (fieldStatus && "$value" in fieldStatus) fieldStatus.$value = state.value;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
async function emitInspectorState(api) {
|
|
2682
|
+
api.sendInspectorState(INSPECTOR_IDS.INSPECTOR);
|
|
2683
|
+
api.sendInspectorTree(INSPECTOR_IDS.INSPECTOR);
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
function buildNodeTags(fieldOrR$, componentName) {
|
|
2687
|
+
const tags = [];
|
|
2688
|
+
if (fieldOrR$.$error) tags.push({
|
|
2689
|
+
label: "error",
|
|
2690
|
+
textColor: COLORS.ERROR.text,
|
|
2691
|
+
backgroundColor: COLORS.ERROR.bg
|
|
2718
2692
|
});
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
});
|
|
2724
|
-
});
|
|
2725
|
-
const $anyDirty = computed(() => {
|
|
2726
|
-
return Object.entries(regles).some(([_, regle]) => {
|
|
2727
|
-
return regle?.$anyDirty;
|
|
2728
|
-
});
|
|
2693
|
+
else if (fieldOrR$.$correct) tags.push({
|
|
2694
|
+
label: "correct",
|
|
2695
|
+
textColor: COLORS.VALID.text,
|
|
2696
|
+
backgroundColor: COLORS.VALID.bg
|
|
2729
2697
|
});
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2698
|
+
if (fieldOrR$.$pending) tags.push({
|
|
2699
|
+
label: "pending",
|
|
2700
|
+
textColor: COLORS.PENDING.text,
|
|
2701
|
+
backgroundColor: COLORS.PENDING.bg
|
|
2734
2702
|
});
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
});
|
|
2703
|
+
if (fieldOrR$.$dirty) tags.push({
|
|
2704
|
+
label: "dirty",
|
|
2705
|
+
textColor: COLORS.DIRTY.text,
|
|
2706
|
+
backgroundColor: COLORS.DIRTY.bg
|
|
2740
2707
|
});
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2708
|
+
else if ("$rules" in fieldOrR$) tags.push({
|
|
2709
|
+
label: "pristine",
|
|
2710
|
+
textColor: COLORS.PRISTINE.text,
|
|
2711
|
+
backgroundColor: COLORS.PRISTINE.bg
|
|
2745
2712
|
});
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
});
|
|
2713
|
+
if (componentName) tags.push({
|
|
2714
|
+
label: componentName,
|
|
2715
|
+
textColor: COLORS.COMPONENT.text,
|
|
2716
|
+
backgroundColor: COLORS.COMPONENT.bg
|
|
2751
2717
|
});
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
});
|
|
2761
|
-
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
2762
|
-
return [key, regle.$issues];
|
|
2763
|
-
}));
|
|
2764
|
-
});
|
|
2765
|
-
const $silentIssues = computed(() => {
|
|
2766
|
-
if (scoped) return Object.entries(regles).map(([_, regle]) => {
|
|
2767
|
-
return regle.$silentIssues;
|
|
2768
|
-
});
|
|
2769
|
-
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
2770
|
-
return [key, regle.$silentIssues];
|
|
2771
|
-
}));
|
|
2718
|
+
return tags;
|
|
2719
|
+
}
|
|
2720
|
+
function buildRuleTags(rule) {
|
|
2721
|
+
const tags = [];
|
|
2722
|
+
if (!rule.$active) tags.push({
|
|
2723
|
+
label: "inactive",
|
|
2724
|
+
textColor: COLORS.INACTIVE.text,
|
|
2725
|
+
backgroundColor: COLORS.INACTIVE.bg
|
|
2772
2726
|
});
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
2778
|
-
return [key, regle.$errors];
|
|
2779
|
-
}));
|
|
2727
|
+
else if (!rule.$valid) tags.push({
|
|
2728
|
+
label: "invalid",
|
|
2729
|
+
textColor: COLORS.INVALID.text,
|
|
2730
|
+
backgroundColor: COLORS.INVALID.bg
|
|
2780
2731
|
});
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
2786
|
-
return [key, regle.$silentErrors];
|
|
2787
|
-
}));
|
|
2732
|
+
else if (rule.$valid) tags.push({
|
|
2733
|
+
label: "valid",
|
|
2734
|
+
textColor: COLORS.VALID.text,
|
|
2735
|
+
backgroundColor: COLORS.VALID.bg
|
|
2788
2736
|
});
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
});
|
|
2737
|
+
if (rule.$pending) tags.push({
|
|
2738
|
+
label: "pending",
|
|
2739
|
+
textColor: COLORS.PENDING.text,
|
|
2740
|
+
backgroundColor: COLORS.PENDING.bg
|
|
2794
2741
|
});
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2742
|
+
return tags;
|
|
2743
|
+
}
|
|
2744
|
+
function buildRuleNodes(fieldStatus, instanceId, fieldPath) {
|
|
2745
|
+
const children = [];
|
|
2746
|
+
if (!fieldStatus.$rules || typeof fieldStatus.$rules !== "object") return children;
|
|
2747
|
+
Object.entries(fieldStatus.$rules).forEach(([ruleName, ruleStatus]) => {
|
|
2748
|
+
if (ruleStatus && typeof ruleStatus === "object") {
|
|
2749
|
+
const ruleTags = buildRuleTags(ruleStatus);
|
|
2750
|
+
children.push({
|
|
2751
|
+
id: createRuleNodeId(instanceId, fieldPath, ruleName),
|
|
2752
|
+
label: `⚙️ ${ruleName}`,
|
|
2753
|
+
tags: ruleTags,
|
|
2754
|
+
children: []
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2799
2757
|
});
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2758
|
+
return children;
|
|
2759
|
+
}
|
|
2760
|
+
function buildCollectionItemNodes(fieldStatus, instanceId, fieldPath) {
|
|
2761
|
+
const children = [];
|
|
2762
|
+
if (!fieldStatus.$each || !Array.isArray(fieldStatus.$each)) return children;
|
|
2763
|
+
fieldStatus.$each.forEach((item, index) => {
|
|
2764
|
+
if (item && typeof item === "object") {
|
|
2765
|
+
const itemTags = buildNodeTags(item);
|
|
2766
|
+
const itemPath = `${fieldPath}[${index}]`;
|
|
2767
|
+
let itemChildren = [];
|
|
2768
|
+
if (isNestedRulesStatus(item)) itemChildren = buildNestedFieldNodes(item.$fields, instanceId, itemPath);
|
|
2769
|
+
else if (isFieldStatus(item)) itemChildren = buildRuleNodes(item, instanceId, itemPath);
|
|
2770
|
+
children.push({
|
|
2771
|
+
id: createFieldNodeId(instanceId, itemPath),
|
|
2772
|
+
label: `[${index}]`,
|
|
2773
|
+
tags: itemTags,
|
|
2774
|
+
children: itemChildren
|
|
2775
|
+
});
|
|
2776
|
+
}
|
|
2803
2777
|
});
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2778
|
+
if (fieldStatus.$self && typeof fieldStatus.$self === "object" && !isEmpty(fieldStatus.$self.$rules)) {
|
|
2779
|
+
const itemTags = buildNodeTags(fieldStatus.$self);
|
|
2780
|
+
const itemPath = `${fieldPath}[$self]`;
|
|
2781
|
+
children.unshift({
|
|
2782
|
+
id: createFieldNodeId(instanceId, itemPath),
|
|
2783
|
+
label: "$self",
|
|
2784
|
+
tags: itemTags,
|
|
2785
|
+
children: buildRuleNodes(fieldStatus.$self, instanceId, itemPath)
|
|
2807
2786
|
});
|
|
2808
2787
|
}
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
if (
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
}),
|
|
2833
|
-
data,
|
|
2834
|
-
errors: $errors.value,
|
|
2835
|
-
issues: $issues.value
|
|
2836
|
-
};
|
|
2837
|
-
} catch {
|
|
2838
|
-
return {
|
|
2839
|
-
valid: false,
|
|
2840
|
-
data: $value.value,
|
|
2841
|
-
errors: $errors.value,
|
|
2842
|
-
issues: $issues.value
|
|
2843
|
-
};
|
|
2788
|
+
return children;
|
|
2789
|
+
}
|
|
2790
|
+
function buildNestedFieldNodes(fields, instanceId, parentPath) {
|
|
2791
|
+
const children = [];
|
|
2792
|
+
Object.entries(fields).forEach(([fieldName, fieldStatus]) => {
|
|
2793
|
+
if (fieldStatus && typeof fieldStatus === "object") {
|
|
2794
|
+
const fieldPath = parentPath ? `${parentPath}.${fieldName}` : fieldName;
|
|
2795
|
+
const fieldTags = buildNodeTags(fieldStatus);
|
|
2796
|
+
let isCollection = false;
|
|
2797
|
+
let isEmptyCollection = false;
|
|
2798
|
+
let fieldChildren = [];
|
|
2799
|
+
if (isCollectionRulesStatus(fieldStatus)) {
|
|
2800
|
+
fieldChildren = buildCollectionItemNodes(fieldStatus, instanceId, fieldPath);
|
|
2801
|
+
isCollection = true;
|
|
2802
|
+
if (fieldChildren.length === 0) isEmptyCollection = true;
|
|
2803
|
+
} else if (isNestedRulesStatus(fieldStatus)) fieldChildren = buildNestedFieldNodes(fieldStatus.$fields, instanceId, fieldPath);
|
|
2804
|
+
else if (isFieldStatus(fieldStatus)) fieldChildren = buildRuleNodes(fieldStatus, instanceId, fieldPath);
|
|
2805
|
+
children.push({
|
|
2806
|
+
id: createFieldNodeId(instanceId, fieldPath),
|
|
2807
|
+
label: `${isCollection ? `${fieldName}[${fieldChildren.length}]` : fieldName}${isEmptyCollection ? " (empty)" : ""}`,
|
|
2808
|
+
tags: fieldTags,
|
|
2809
|
+
children: fieldChildren
|
|
2810
|
+
});
|
|
2844
2811
|
}
|
|
2845
|
-
}
|
|
2846
|
-
return reactive({
|
|
2847
|
-
...!scoped && { $silentValue },
|
|
2848
|
-
$errors,
|
|
2849
|
-
$issues,
|
|
2850
|
-
$silentIssues,
|
|
2851
|
-
$silentErrors,
|
|
2852
|
-
$instances,
|
|
2853
|
-
$value,
|
|
2854
|
-
$dirty,
|
|
2855
|
-
$anyDirty,
|
|
2856
|
-
$invalid,
|
|
2857
|
-
$correct,
|
|
2858
|
-
$error,
|
|
2859
|
-
$pending,
|
|
2860
|
-
$ready,
|
|
2861
|
-
$edited,
|
|
2862
|
-
$anyEdited,
|
|
2863
|
-
$reset,
|
|
2864
|
-
$touch,
|
|
2865
|
-
$validate,
|
|
2866
|
-
$extractDirtyFields,
|
|
2867
|
-
$clearExternalErrors
|
|
2868
2812
|
});
|
|
2813
|
+
return children;
|
|
2869
2814
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2815
|
+
function buildRootChildrenNodes(r$, instanceId) {
|
|
2816
|
+
const children = [];
|
|
2817
|
+
if (isFieldStatus(r$)) return buildRuleNodes(r$, instanceId, "root");
|
|
2818
|
+
if (!r$.$fields || typeof r$.$fields !== "object") return children;
|
|
2819
|
+
Object.entries(r$.$fields).forEach(([fieldName, fieldStatus]) => {
|
|
2820
|
+
if (fieldStatus && typeof fieldStatus === "object") {
|
|
2821
|
+
const fieldTags = buildNodeTags(fieldStatus);
|
|
2822
|
+
let fieldChildren = [];
|
|
2823
|
+
let isCollection = false;
|
|
2824
|
+
if (isCollectionRulesStatus(fieldStatus)) {
|
|
2825
|
+
fieldChildren = buildCollectionItemNodes(fieldStatus, instanceId, fieldName);
|
|
2826
|
+
isCollection = true;
|
|
2827
|
+
} else if (isNestedRulesStatus(fieldStatus)) fieldChildren = buildNestedFieldNodes(fieldStatus.$fields, instanceId, fieldName);
|
|
2828
|
+
else if (isFieldStatus(fieldStatus)) fieldChildren = buildRuleNodes(fieldStatus, instanceId, fieldName);
|
|
2829
|
+
children.push({
|
|
2830
|
+
id: createFieldNodeId(instanceId, fieldName),
|
|
2831
|
+
label: `${isCollection ? `${fieldName}[${fieldChildren.length}]` : fieldName}`,
|
|
2832
|
+
tags: fieldTags,
|
|
2833
|
+
children: fieldChildren
|
|
2834
|
+
});
|
|
2889
2835
|
}
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
return { useCollectScope: useCollectScope$1 };
|
|
2836
|
+
});
|
|
2837
|
+
return children;
|
|
2893
2838
|
}
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
function createUseScopedRegleComposable(instances, customUseRegle) {
|
|
2898
|
-
const scopedUseRegle = customUseRegle ?? useRegle;
|
|
2899
|
-
const useScopedRegle$1 = ((state, rulesFactory, options) => {
|
|
2900
|
-
const { namespace, scopeKey: _scopeKey,...restOptions } = options ?? {};
|
|
2901
|
-
scopedUseRegle.__config ??= {};
|
|
2902
|
-
const computedNamespace = computed(() => toValue(namespace));
|
|
2903
|
-
const $id = ref(`${Object.keys(instances.value).length + 1}-${randomId()}`);
|
|
2904
|
-
const instanceName = computed(() => {
|
|
2905
|
-
return options?.scopeKey ?? `instance-${$id.value}`;
|
|
2906
|
-
});
|
|
2907
|
-
const { r$ } = scopedUseRegle(state, rulesFactory, restOptions);
|
|
2908
|
-
register();
|
|
2909
|
-
tryOnScopeDispose(dispose);
|
|
2910
|
-
watch(computedNamespace, (newName, oldName) => {
|
|
2911
|
-
dispose(oldName);
|
|
2912
|
-
register();
|
|
2913
|
-
});
|
|
2914
|
-
if (getCurrentInstance()) onMounted(() => {
|
|
2915
|
-
const currentInstance = getCurrentInstance();
|
|
2916
|
-
if (typeof window !== "undefined" && currentInstance?.proxy?.$el?.parentElement) {
|
|
2917
|
-
if (document.documentElement && !document.documentElement.contains(currentInstance?.proxy?.$el?.parentElement)) dispose();
|
|
2918
|
-
}
|
|
2919
|
-
});
|
|
2920
|
-
function dispose(oldName) {
|
|
2921
|
-
const nameToClean = oldName ?? computedNamespace.value;
|
|
2922
|
-
if (nameToClean) {
|
|
2923
|
-
if (instances.value[nameToClean]) delete instances.value[nameToClean][instanceName.value];
|
|
2924
|
-
} else if (instances.value["~~global"][instanceName.value]) delete instances.value["~~global"][instanceName.value];
|
|
2925
|
-
}
|
|
2926
|
-
function register() {
|
|
2927
|
-
if (computedNamespace.value) {
|
|
2928
|
-
if (!instances.value[computedNamespace.value]) instances.value[computedNamespace.value] = {};
|
|
2929
|
-
instances.value[computedNamespace.value][instanceName.value] = r$;
|
|
2930
|
-
} else {
|
|
2931
|
-
if (!instances.value["~~global"]) instances.value["~~global"] = {};
|
|
2932
|
-
instances.value["~~global"][instanceName.value] = r$;
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2839
|
+
function buildInspectorTree(instances, filter) {
|
|
2840
|
+
const nodes = instances.map((instance) => {
|
|
2841
|
+
const { r$, id, name, componentName } = instance;
|
|
2935
2842
|
return {
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2843
|
+
id,
|
|
2844
|
+
label: name,
|
|
2845
|
+
tags: buildNodeTags(r$, componentName),
|
|
2846
|
+
children: buildRootChildrenNodes(r$, id)
|
|
2939
2847
|
};
|
|
2940
2848
|
});
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
const
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
}
|
|
2956
|
-
|
|
2957
|
-
const { useCollectScope: useCollectScope$1 } = createUseCollectScope(instances, { asRecord: options?.asRecord });
|
|
2958
|
-
return {
|
|
2959
|
-
useScopedRegle: useScopedRegle$1,
|
|
2960
|
-
useCollectScope: useCollectScope$1
|
|
2961
|
-
};
|
|
2849
|
+
if (!filter || filter.trim() === "") return nodes;
|
|
2850
|
+
return filterInspectorTree(nodes, filter);
|
|
2851
|
+
}
|
|
2852
|
+
function filterInspectorTree(nodes, filter) {
|
|
2853
|
+
const lowerFilter = filter.toLowerCase();
|
|
2854
|
+
const filtered = [];
|
|
2855
|
+
for (const node of nodes) {
|
|
2856
|
+
const labelMatches = node.label.toLowerCase().includes(lowerFilter);
|
|
2857
|
+
const tagMatches = node.tags?.some((tag) => tag.label.toLowerCase().includes(lowerFilter)) ?? false;
|
|
2858
|
+
const filteredChildren = node.children ? filterInspectorTree(node.children, filter) : [];
|
|
2859
|
+
if (labelMatches || tagMatches || filteredChildren.length > 0) filtered.push({
|
|
2860
|
+
...node,
|
|
2861
|
+
children: filteredChildren.length > 0 ? filteredChildren : node.children
|
|
2862
|
+
});
|
|
2863
|
+
}
|
|
2864
|
+
return filtered;
|
|
2962
2865
|
}
|
|
2963
|
-
const { useCollectScope, useScopedRegle } = createScopedUseRegle();
|
|
2964
2866
|
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2867
|
+
function createDevtools(app) {
|
|
2868
|
+
setupDevtoolsPlugin({
|
|
2869
|
+
id: "regle-devtools",
|
|
2870
|
+
label: "Regle",
|
|
2871
|
+
logo: "https://reglejs.dev/logo_main.png",
|
|
2872
|
+
packageName: "@regle/core",
|
|
2873
|
+
homepage: "https://reglejs.dev",
|
|
2874
|
+
componentStateTypes: ["Regles"],
|
|
2875
|
+
app
|
|
2876
|
+
}, (api) => {
|
|
2877
|
+
regleDevtoolsRegistry.setApi(api);
|
|
2878
|
+
api.addInspector({
|
|
2879
|
+
id: INSPECTOR_IDS.INSPECTOR,
|
|
2880
|
+
label: "Regle",
|
|
2881
|
+
noSelectionText: "No instance selected",
|
|
2882
|
+
icon: "rule",
|
|
2883
|
+
treeFilterPlaceholder: "Filter",
|
|
2884
|
+
stateFilterPlaceholder: "Filter validation status",
|
|
2885
|
+
nodeActions: [
|
|
2886
|
+
{
|
|
2887
|
+
icon: "check_circle",
|
|
2888
|
+
tooltip: "Validate",
|
|
2889
|
+
action: (nodeId) => {
|
|
2890
|
+
handleValidateAction(nodeId, api);
|
|
2891
|
+
}
|
|
2892
|
+
},
|
|
2893
|
+
{
|
|
2894
|
+
icon: "refresh",
|
|
2895
|
+
tooltip: "Reset validation state",
|
|
2896
|
+
action: (nodeId) => {
|
|
2897
|
+
handleResetAction(nodeId, api);
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2900
|
+
{
|
|
2901
|
+
icon: "restore",
|
|
2902
|
+
tooltip: "Restore to original state",
|
|
2903
|
+
action: (nodeId) => {
|
|
2904
|
+
handleResetAction(nodeId, api, true);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
]
|
|
2908
|
+
});
|
|
2909
|
+
regleDevtoolsRegistry.notifyDevtools();
|
|
2910
|
+
let componentInstances = [];
|
|
2911
|
+
let selectedNodeId = null;
|
|
2912
|
+
api.on.getInspectorTree(async (payload) => {
|
|
2913
|
+
api.unhighlightElement();
|
|
2914
|
+
if (payload.inspectorId === INSPECTOR_IDS.INSPECTOR) {
|
|
2915
|
+
const nodes = buildInspectorTree(regleDevtoolsRegistry.getAll(), payload.filter);
|
|
2916
|
+
if (nodes.length > 0) payload.rootNodes = nodes;
|
|
2917
|
+
else payload.rootNodes = [{
|
|
2918
|
+
id: "empty-regles",
|
|
2919
|
+
label: "No Regles instances found",
|
|
2920
|
+
children: []
|
|
2921
|
+
}];
|
|
2922
|
+
componentInstances = await api.getComponentInstances(app);
|
|
2994
2923
|
}
|
|
2995
2924
|
});
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
2925
|
+
api.on.getInspectorState((payload) => {
|
|
2926
|
+
api.unhighlightElement();
|
|
2927
|
+
if (payload.inspectorId === INSPECTOR_IDS.INSPECTOR) {
|
|
2928
|
+
const state = buildInspectorState(payload.nodeId, (id) => regleDevtoolsRegistry.get(id));
|
|
2929
|
+
const instance = componentInstances.find((instance$1) => {
|
|
2930
|
+
const [componentName] = payload.nodeId.split("#");
|
|
2931
|
+
return instance$1.uid.toString() === componentName;
|
|
2932
|
+
});
|
|
2933
|
+
if (instance?.uid && selectedNodeId !== payload.nodeId) {
|
|
2934
|
+
selectedNodeId = payload.nodeId;
|
|
2935
|
+
if (!parseFieldNodeId(payload.nodeId)) api.highlightElement(instance);
|
|
2936
|
+
}
|
|
2937
|
+
if (state) payload.state = state;
|
|
2938
|
+
else payload.state = {};
|
|
2939
|
+
}
|
|
2940
|
+
});
|
|
2941
|
+
api.on.editInspectorState((payload) => {
|
|
2942
|
+
if (payload.inspectorId === INSPECTOR_IDS.INSPECTOR) handleEditInspectorState(payload);
|
|
2943
|
+
});
|
|
3002
2944
|
});
|
|
3003
2945
|
}
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
2946
|
+
|
|
2947
|
+
function useRootStorage({ initialState, originalState, options, scopeRules, state, customRules, shortcuts, schemaErrors, schemaMode = false, onValidate }) {
|
|
2948
|
+
const storage = useStorage();
|
|
2949
|
+
const regle = ref();
|
|
2950
|
+
const computedExternalErrors = ref();
|
|
2951
|
+
let $unwatchExternalErrors;
|
|
2952
|
+
let $unwatchComputedExternalErrors;
|
|
2953
|
+
function defineExternalErrorsWatchSource() {
|
|
2954
|
+
$unwatchExternalErrors = watch(() => options.externalErrors?.value, () => {
|
|
2955
|
+
$unwatchComputedExternalErrors?.();
|
|
2956
|
+
if (options.externalErrors?.value && Object.keys(options.externalErrors.value).some((key) => key.includes("."))) computedExternalErrors.value = dotPathObjectToNested(options.externalErrors.value);
|
|
2957
|
+
else computedExternalErrors.value = options.externalErrors?.value;
|
|
2958
|
+
defineComputedExternalErrorsWatchSource();
|
|
2959
|
+
}, {
|
|
2960
|
+
immediate: true,
|
|
2961
|
+
deep: true
|
|
2962
|
+
});
|
|
2963
|
+
}
|
|
2964
|
+
function defineComputedExternalErrorsWatchSource() {
|
|
2965
|
+
$unwatchComputedExternalErrors = watch(() => computedExternalErrors.value, () => {
|
|
2966
|
+
$unwatchExternalErrors?.();
|
|
2967
|
+
if (options.externalErrors?.value) options.externalErrors.value = computedExternalErrors.value;
|
|
2968
|
+
defineExternalErrorsWatchSource();
|
|
2969
|
+
}, { deep: true });
|
|
2970
|
+
}
|
|
2971
|
+
defineExternalErrorsWatchSource();
|
|
2972
|
+
if (isNestedRulesDef(state, scopeRules)) regle.value = createReactiveNestedStatus({
|
|
2973
|
+
rootRules: scopeRules,
|
|
2974
|
+
rulesDef: scopeRules,
|
|
2975
|
+
state,
|
|
2976
|
+
customMessages: customRules?.(),
|
|
2977
|
+
storage,
|
|
2978
|
+
options,
|
|
2979
|
+
externalErrors: computedExternalErrors,
|
|
2980
|
+
validationGroups: options.validationGroups,
|
|
2981
|
+
initialState,
|
|
2982
|
+
originalState,
|
|
2983
|
+
shortcuts,
|
|
2984
|
+
fieldName: "root",
|
|
2985
|
+
path: "",
|
|
2986
|
+
cachePath: "",
|
|
2987
|
+
schemaErrors,
|
|
2988
|
+
rootSchemaErrors: schemaErrors,
|
|
2989
|
+
schemaMode,
|
|
2990
|
+
onValidate
|
|
2991
|
+
});
|
|
2992
|
+
else if (isValidatorRulesDef(scopeRules)) regle.value = createReactiveFieldStatus({
|
|
2993
|
+
rulesDef: scopeRules,
|
|
2994
|
+
state,
|
|
2995
|
+
customMessages: customRules?.(),
|
|
2996
|
+
storage,
|
|
2997
|
+
options,
|
|
2998
|
+
externalErrors: computedExternalErrors,
|
|
2999
|
+
initialState,
|
|
3000
|
+
originalState,
|
|
3001
|
+
shortcuts,
|
|
3002
|
+
fieldName: "root",
|
|
3003
|
+
path: "",
|
|
3004
|
+
cachePath: "",
|
|
3005
|
+
schemaMode,
|
|
3006
|
+
schemaErrors,
|
|
3007
|
+
onValidate
|
|
3008
|
+
});
|
|
3009
|
+
if (getCurrentScope()) onScopeDispose(() => {
|
|
3010
|
+
regle.value?.$unwatch();
|
|
3011
|
+
$unwatchComputedExternalErrors?.();
|
|
3012
|
+
$unwatchExternalErrors?.();
|
|
3013
|
+
});
|
|
3014
|
+
if (typeof window !== "undefined" && regle.value) registerRegleInstance(regle.value, { name: toValue(options.id) });
|
|
3015
|
+
return reactive({ regle });
|
|
3015
3016
|
}
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
const
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3017
|
+
|
|
3018
|
+
function createRootRegleLogic({ state, rulesFactory, options, globalOptions, customRules, shortcuts }) {
|
|
3019
|
+
const definedRules = isRef(rulesFactory) ? rulesFactory : typeof rulesFactory === "function" ? void 0 : computed(() => rulesFactory);
|
|
3020
|
+
const resolvedOptions = {
|
|
3021
|
+
...globalOptions,
|
|
3022
|
+
...options
|
|
3023
|
+
};
|
|
3024
|
+
let unwatchRules;
|
|
3025
|
+
const watchableRulesGetters = shallowRef(definedRules ?? {});
|
|
3026
|
+
if (typeof rulesFactory === "function") unwatchRules = watchEffect(() => {
|
|
3027
|
+
watchableRulesGetters.value = rulesFactory(state);
|
|
3028
|
+
triggerRef(watchableRulesGetters);
|
|
3029
|
+
});
|
|
3030
|
+
const initialState = ref(isObject(state.value) ? { ...cloneDeep(state.value) } : cloneDeep(state.value));
|
|
3031
|
+
const originalState = isObject(state.value) ? { ...cloneDeep(state.value) } : cloneDeep(state.value);
|
|
3032
|
+
tryOnScopeDispose(() => {
|
|
3033
|
+
unwatchRules?.();
|
|
3034
|
+
});
|
|
3035
|
+
return useRootStorage({
|
|
3036
|
+
scopeRules: watchableRulesGetters,
|
|
3037
|
+
state,
|
|
3038
|
+
options: resolvedOptions,
|
|
3039
|
+
initialState,
|
|
3040
|
+
originalState,
|
|
3041
|
+
customRules,
|
|
3042
|
+
shortcuts
|
|
3026
3043
|
});
|
|
3027
|
-
return returnedRef;
|
|
3028
3044
|
}
|
|
3029
3045
|
|
|
3030
|
-
|
|
3031
|
-
|
|
3046
|
+
function createUseRegleComposable(customRules, options, shortcuts) {
|
|
3047
|
+
const globalOptions = {
|
|
3048
|
+
autoDirty: options?.autoDirty,
|
|
3049
|
+
lazy: options?.lazy,
|
|
3050
|
+
rewardEarly: options?.rewardEarly,
|
|
3051
|
+
silent: options?.silent,
|
|
3052
|
+
clearExternalErrorsOnChange: options?.clearExternalErrorsOnChange
|
|
3053
|
+
};
|
|
3054
|
+
function useRegle$1(state, rulesFactory, options$1) {
|
|
3055
|
+
return { r$: createRootRegleLogic({
|
|
3056
|
+
state: isRef(state) ? state : ref(state),
|
|
3057
|
+
rulesFactory,
|
|
3058
|
+
options: options$1,
|
|
3059
|
+
globalOptions,
|
|
3060
|
+
customRules,
|
|
3061
|
+
shortcuts
|
|
3062
|
+
}).regle };
|
|
3063
|
+
}
|
|
3064
|
+
return useRegle$1;
|
|
3065
|
+
}
|
|
3032
3066
|
/**
|
|
3033
|
-
*
|
|
3067
|
+
* useRegle serves as the foundation for validation logic.
|
|
3034
3068
|
*
|
|
3035
|
-
*
|
|
3069
|
+
* It accepts the following inputs:
|
|
3036
3070
|
*
|
|
3037
|
-
*
|
|
3038
|
-
*
|
|
3071
|
+
* @param state - This can be a plain object, a ref, a reactive object, or a structure containing nested refs.
|
|
3072
|
+
* @param rules - These should align with the structure of your state.
|
|
3073
|
+
* @param modifiers - Customize regle behaviour
|
|
3074
|
+
*
|
|
3075
|
+
* ```ts
|
|
3076
|
+
* import { useRegle } from '@regle/core';
|
|
3077
|
+
import { required } from '@regle/rules';
|
|
3078
|
+
|
|
3079
|
+
const { r$ } = useRegle({ email: '' }, {
|
|
3080
|
+
email: { required }
|
|
3081
|
+
})
|
|
3039
3082
|
* ```
|
|
3083
|
+
* Docs: {@link https://reglejs.dev/core-concepts/}
|
|
3040
3084
|
*/
|
|
3041
|
-
|
|
3042
|
-
|
|
3085
|
+
const useRegle = createUseRegleComposable();
|
|
3086
|
+
|
|
3087
|
+
function createInferRuleHelper() {
|
|
3088
|
+
function inferRules$1(state, rulesFactory) {
|
|
3089
|
+
return rulesFactory;
|
|
3090
|
+
}
|
|
3091
|
+
return inferRules$1;
|
|
3043
3092
|
}
|
|
3044
3093
|
/**
|
|
3045
|
-
*
|
|
3046
|
-
*
|
|
3047
|
-
* @example
|
|
3094
|
+
* Rule type helper to provide autocomplete and typecheck to your form rules or part of your form rules
|
|
3095
|
+
* It will just return the rules without any processing.
|
|
3048
3096
|
*
|
|
3049
|
-
*
|
|
3050
|
-
*
|
|
3051
|
-
* password: { required, type: type<string>() },
|
|
3052
|
-
* }, (state) => {
|
|
3053
|
-
* return {
|
|
3054
|
-
* confirmPassword: { required, sameAs: sameAs(() => state.value.password)}
|
|
3055
|
-
* }
|
|
3056
|
-
* })
|
|
3057
|
-
* ```
|
|
3097
|
+
* @param state - The state reference
|
|
3098
|
+
* @param rules - Your rule tree
|
|
3058
3099
|
*/
|
|
3059
|
-
|
|
3060
|
-
return (state) => merge({ ...rules }, refinement(state));
|
|
3061
|
-
}
|
|
3100
|
+
const inferRules = createInferRuleHelper();
|
|
3062
3101
|
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
text: 16777215,
|
|
3072
|
-
bg: 16281969
|
|
3073
|
-
},
|
|
3074
|
-
VALID: {
|
|
3075
|
-
text: 16777215,
|
|
3076
|
-
bg: 1096065
|
|
3077
|
-
},
|
|
3078
|
-
PENDING: {
|
|
3079
|
-
text: 16777215,
|
|
3080
|
-
bg: 16096779
|
|
3081
|
-
},
|
|
3082
|
-
DIRTY: {
|
|
3083
|
-
text: 2042167,
|
|
3084
|
-
bg: 16708551
|
|
3085
|
-
},
|
|
3086
|
-
COMPONENT: {
|
|
3087
|
-
text: 16777215,
|
|
3088
|
-
bg: 6514417
|
|
3102
|
+
function createEmptyRuleState(rules) {
|
|
3103
|
+
const result = {};
|
|
3104
|
+
if (Object.entries(rules).some(([_, rule]) => isRuleDef(rule) || typeof rule === "function")) return null;
|
|
3105
|
+
for (const key in rules) {
|
|
3106
|
+
const item = rules[key];
|
|
3107
|
+
if (!!item && isObject(item) && "$each" in item && item["$each"] && isObject(item["$each"])) result[key] = [createEmptyRuleState(item["$each"])];
|
|
3108
|
+
else if (isObject(item) && !isEmpty(item) && !Object.entries(item).some(([_, rule]) => isRuleDef(rule) || typeof rule === "function")) result[key] = createEmptyRuleState(item);
|
|
3109
|
+
else result[key] = null;
|
|
3089
3110
|
}
|
|
3090
|
-
|
|
3091
|
-
const PRIORITY_KEYS = {
|
|
3092
|
-
ROOT: [
|
|
3093
|
-
"$invalid",
|
|
3094
|
-
"$dirty",
|
|
3095
|
-
"$error",
|
|
3096
|
-
"$pending",
|
|
3097
|
-
"$valid",
|
|
3098
|
-
"$ready"
|
|
3099
|
-
],
|
|
3100
|
-
FIELD: [
|
|
3101
|
-
"$value",
|
|
3102
|
-
"$invalid",
|
|
3103
|
-
"$dirty",
|
|
3104
|
-
"$error",
|
|
3105
|
-
"$pending",
|
|
3106
|
-
"$errors"
|
|
3107
|
-
]
|
|
3108
|
-
};
|
|
3109
|
-
const INSPECTOR_IDS = {
|
|
3110
|
-
INSPECTOR: "regle-inspector",
|
|
3111
|
-
TIMELINE: "regle-timeline"
|
|
3112
|
-
};
|
|
3113
|
-
|
|
3114
|
-
//#endregion
|
|
3115
|
-
//#region src/devtools/utils.ts
|
|
3116
|
-
function isMethod(value) {
|
|
3117
|
-
return typeof value === "function";
|
|
3118
|
-
}
|
|
3119
|
-
function getPriorityProperties(obj, keys) {
|
|
3120
|
-
return keys.filter((key) => key in obj && !isMethod(obj[key])).map((key) => {
|
|
3121
|
-
let editable = false;
|
|
3122
|
-
if (key === "$value") editable = true;
|
|
3123
|
-
return {
|
|
3124
|
-
key,
|
|
3125
|
-
value: obj[key],
|
|
3126
|
-
editable
|
|
3127
|
-
};
|
|
3128
|
-
});
|
|
3129
|
-
}
|
|
3130
|
-
function getRemainingProperties(obj, excludeKeys) {
|
|
3131
|
-
return Object.entries(obj).filter(([key]) => !excludeKeys.includes(key) && key.startsWith("$") && !isMethod(obj[key])).map(([key, value]) => ({
|
|
3132
|
-
key,
|
|
3133
|
-
value,
|
|
3134
|
-
editable: false
|
|
3135
|
-
}));
|
|
3136
|
-
}
|
|
3137
|
-
function parseFieldNodeId(nodeId) {
|
|
3138
|
-
if (!nodeId.includes(":field:")) return null;
|
|
3139
|
-
const [instanceId, , fieldName] = nodeId.split(":");
|
|
3140
|
-
return {
|
|
3141
|
-
instanceId,
|
|
3142
|
-
fieldName
|
|
3143
|
-
};
|
|
3144
|
-
}
|
|
3145
|
-
function createFieldNodeId(instanceId, fieldName) {
|
|
3146
|
-
return `${instanceId}:field:${fieldName}`;
|
|
3111
|
+
return result;
|
|
3147
3112
|
}
|
|
3148
|
-
function
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
if (!fieldInfo) return null;
|
|
3156
|
-
return {
|
|
3157
|
-
...fieldInfo,
|
|
3158
|
-
ruleName
|
|
3113
|
+
function createUseRulesComposable(customRules, options, shortcuts) {
|
|
3114
|
+
const globalOptions = {
|
|
3115
|
+
autoDirty: options?.autoDirty,
|
|
3116
|
+
lazy: options?.lazy,
|
|
3117
|
+
rewardEarly: options?.rewardEarly,
|
|
3118
|
+
silent: options?.silent,
|
|
3119
|
+
clearExternalErrorsOnChange: options?.clearExternalErrorsOnChange
|
|
3159
3120
|
};
|
|
3121
|
+
function useRules$1(rulesFactory, options$1) {
|
|
3122
|
+
const definedRules = isRef(rulesFactory) ? rulesFactory : typeof rulesFactory === "function" ? void 0 : computed(() => rulesFactory);
|
|
3123
|
+
return createRootRegleLogic({
|
|
3124
|
+
state: ref(createEmptyRuleState(definedRules?.value)),
|
|
3125
|
+
rulesFactory: definedRules,
|
|
3126
|
+
options: options$1,
|
|
3127
|
+
globalOptions,
|
|
3128
|
+
customRules,
|
|
3129
|
+
shortcuts
|
|
3130
|
+
}).regle;
|
|
3131
|
+
}
|
|
3132
|
+
return useRules$1;
|
|
3160
3133
|
}
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3134
|
+
/**
|
|
3135
|
+
* useRules is a clone of useRegle, without the need to provide a state.
|
|
3136
|
+
*
|
|
3137
|
+
* It accepts the following inputs:
|
|
3138
|
+
*
|
|
3139
|
+
* @param rules - Your rules object
|
|
3140
|
+
* @param modifiers - Customize regle behaviour
|
|
3141
|
+
*
|
|
3142
|
+
* ```ts
|
|
3143
|
+
* import { useRules } from '@regle/core';
|
|
3144
|
+
import { required } from '@regle/rules';
|
|
3145
|
+
|
|
3146
|
+
const { r$ } = useRules({
|
|
3147
|
+
email: { required }
|
|
3148
|
+
})
|
|
3149
|
+
* ```
|
|
3150
|
+
*/
|
|
3151
|
+
const useRules = createUseRulesComposable();
|
|
3164
3152
|
|
|
3165
|
-
//#endregion
|
|
3166
|
-
//#region src/devtools/state-builder.ts
|
|
3167
3153
|
/**
|
|
3168
|
-
*
|
|
3154
|
+
* Define a global regle configuration, where you can:
|
|
3155
|
+
* - Customize built-in rules messages
|
|
3156
|
+
* - Add your custom rules
|
|
3157
|
+
* - Define global modifiers
|
|
3158
|
+
* - Define shortcuts
|
|
3159
|
+
*
|
|
3160
|
+
* It will return:
|
|
3161
|
+
*
|
|
3162
|
+
* - a `useRegle` composable that can typecheck your custom rules
|
|
3163
|
+
* - an `inferRules` helper that can typecheck your custom rules
|
|
3169
3164
|
*/
|
|
3170
|
-
function
|
|
3171
|
-
const
|
|
3172
|
-
const
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3165
|
+
function defineRegleConfig({ rules, modifiers, shortcuts }) {
|
|
3166
|
+
const useRegle$1 = createUseRegleComposable(rules, modifiers, shortcuts);
|
|
3167
|
+
const useRules$1 = createUseRulesComposable(rules, modifiers, shortcuts);
|
|
3168
|
+
useRegle$1.__config = {
|
|
3169
|
+
rules,
|
|
3170
|
+
modifiers,
|
|
3171
|
+
shortcuts
|
|
3172
|
+
};
|
|
3173
|
+
useRules$1.__config = {
|
|
3174
|
+
rules,
|
|
3175
|
+
modifiers,
|
|
3176
|
+
shortcuts
|
|
3177
|
+
};
|
|
3178
|
+
return {
|
|
3179
|
+
useRegle: useRegle$1,
|
|
3180
|
+
inferRules: createInferRuleHelper(),
|
|
3181
|
+
useRules: useRules$1
|
|
3182
|
+
};
|
|
3181
3183
|
}
|
|
3182
3184
|
/**
|
|
3183
|
-
*
|
|
3185
|
+
* Extend an already created custom `useRegle` (as the first parameter)
|
|
3186
|
+
*
|
|
3187
|
+
* It will return:
|
|
3188
|
+
*
|
|
3189
|
+
* - a `useRegle` composable that can typecheck your custom rules
|
|
3190
|
+
* - an `inferRules` helper that can typecheck your custom rules
|
|
3184
3191
|
*/
|
|
3185
|
-
function
|
|
3186
|
-
const
|
|
3187
|
-
const
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
key: "$metadata",
|
|
3204
|
-
value: ruleStatus.$metadata,
|
|
3205
|
-
editable: false
|
|
3206
|
-
}];
|
|
3207
|
-
const remainingProperties = getRemainingProperties(ruleStatus, [
|
|
3208
|
-
...ruleKeys,
|
|
3209
|
-
"$params",
|
|
3210
|
-
"$metadata",
|
|
3211
|
-
"$validator",
|
|
3212
|
-
"$parse",
|
|
3213
|
-
"$reset",
|
|
3214
|
-
"$unwatch",
|
|
3215
|
-
"$watch",
|
|
3216
|
-
"$haveAsync",
|
|
3217
|
-
"$validating",
|
|
3218
|
-
"$fieldDirty",
|
|
3219
|
-
"$fieldInvalid",
|
|
3220
|
-
"$fieldPending",
|
|
3221
|
-
"$fieldCorrect",
|
|
3222
|
-
"$fieldError",
|
|
3223
|
-
"$maybePending",
|
|
3224
|
-
"$externalErrors"
|
|
3225
|
-
]);
|
|
3226
|
-
if (remainingProperties.length > 0) state["Other Properties"] = remainingProperties;
|
|
3227
|
-
return state;
|
|
3228
|
-
}
|
|
3229
|
-
function buildRootState(r$) {
|
|
3230
|
-
const state = {};
|
|
3231
|
-
const priorityProperties = getPriorityProperties(r$, PRIORITY_KEYS.ROOT);
|
|
3232
|
-
if (priorityProperties.length > 0) state["State"] = priorityProperties;
|
|
3233
|
-
const remainingProperties = getRemainingProperties(r$, [...PRIORITY_KEYS.ROOT, "$fields"]);
|
|
3234
|
-
if (remainingProperties.length > 0) state["Other Properties"] = remainingProperties;
|
|
3235
|
-
return state;
|
|
3236
|
-
}
|
|
3237
|
-
function resolveFieldByPath(fields, path) {
|
|
3238
|
-
if (!fields || !path) return null;
|
|
3239
|
-
const segments = path.match(/[^.\[\]]+/g);
|
|
3240
|
-
if (!segments) return null;
|
|
3241
|
-
let current = fields;
|
|
3242
|
-
for (const segment of segments) {
|
|
3243
|
-
if (!current) return null;
|
|
3244
|
-
const index = parseInt(segment);
|
|
3245
|
-
if (!isNaN(index)) if (isCollectionRulesStatus(current) && Array.isArray(current.$each)) current = current.$each[index];
|
|
3246
|
-
else return null;
|
|
3247
|
-
else if (isNestedRulesStatus(current) && current.$fields && current.$fields[segment]) current = current.$fields[segment];
|
|
3248
|
-
else if (current[segment]) current = current[segment];
|
|
3249
|
-
else return null;
|
|
3250
|
-
}
|
|
3251
|
-
return current;
|
|
3252
|
-
}
|
|
3253
|
-
function buildInspectorState(nodeId, getInstance) {
|
|
3254
|
-
const ruleInfo = parseRuleNodeId(nodeId);
|
|
3255
|
-
if (ruleInfo) {
|
|
3256
|
-
const { instanceId, fieldName, ruleName } = ruleInfo;
|
|
3257
|
-
const instance$1 = getInstance(instanceId);
|
|
3258
|
-
if (!instance$1 || !instance$1.r$.$fields) return null;
|
|
3259
|
-
const fieldStatus = resolveFieldByPath(instance$1.r$.$fields, fieldName);
|
|
3260
|
-
if (!fieldStatus || !("$rules" in fieldStatus)) return null;
|
|
3261
|
-
const ruleStatus = fieldStatus.$rules[ruleName];
|
|
3262
|
-
if (!ruleStatus) return null;
|
|
3263
|
-
return buildRuleState(ruleStatus);
|
|
3264
|
-
}
|
|
3265
|
-
const fieldInfo = parseFieldNodeId(nodeId);
|
|
3266
|
-
if (fieldInfo) {
|
|
3267
|
-
const { instanceId, fieldName } = fieldInfo;
|
|
3268
|
-
const instance$1 = getInstance(instanceId);
|
|
3269
|
-
if (!instance$1 || !instance$1.r$.$fields) return null;
|
|
3270
|
-
const fieldStatus = resolveFieldByPath(instance$1.r$.$fields, fieldName);
|
|
3271
|
-
if (!fieldStatus) return null;
|
|
3272
|
-
return buildFieldState(fieldStatus);
|
|
3273
|
-
}
|
|
3274
|
-
const instance = getInstance(nodeId);
|
|
3275
|
-
if (!instance) return null;
|
|
3276
|
-
return buildRootState(instance.r$);
|
|
3277
|
-
}
|
|
3278
|
-
|
|
3279
|
-
//#endregion
|
|
3280
|
-
//#region src/devtools/actions.ts
|
|
3281
|
-
function handleValidateAction(nodeId, api) {
|
|
3282
|
-
if (nodeId.includes(":rule:")) return;
|
|
3283
|
-
const fieldInfo = parseFieldNodeId(nodeId);
|
|
3284
|
-
if (fieldInfo) {
|
|
3285
|
-
const { instanceId, fieldName } = fieldInfo;
|
|
3286
|
-
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
3287
|
-
if (instance && instance.r$.$fields) {
|
|
3288
|
-
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldName);
|
|
3289
|
-
if (fieldStatus && typeof fieldStatus.$validate === "function") fieldStatus.$validate();
|
|
3290
|
-
}
|
|
3291
|
-
} else {
|
|
3292
|
-
const instance = regleDevtoolsRegistry.get(nodeId);
|
|
3293
|
-
if (instance && typeof instance.r$.$validate === "function") instance.r$.$validate();
|
|
3294
|
-
}
|
|
3295
|
-
emitInspectorState(api);
|
|
3296
|
-
}
|
|
3297
|
-
function handleResetAction(nodeId, api, resetState = false) {
|
|
3298
|
-
const fieldInfo = parseFieldNodeId(nodeId);
|
|
3299
|
-
if (fieldInfo) {
|
|
3300
|
-
const { instanceId, fieldName } = fieldInfo;
|
|
3301
|
-
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
3302
|
-
if (instance && instance.r$.$fields) {
|
|
3303
|
-
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldName);
|
|
3304
|
-
if (fieldStatus && typeof fieldStatus.$reset === "function") fieldStatus.$reset({ toInitialState: resetState });
|
|
3305
|
-
}
|
|
3306
|
-
} else {
|
|
3307
|
-
const instance = regleDevtoolsRegistry.get(nodeId);
|
|
3308
|
-
if (instance && typeof instance.r$.$reset === "function") instance.r$.$reset({ toInitialState: resetState });
|
|
3309
|
-
}
|
|
3310
|
-
emitInspectorState(api);
|
|
3311
|
-
}
|
|
3312
|
-
function handleEditInspectorState(payload, api) {
|
|
3313
|
-
const { nodeId, path, state } = payload;
|
|
3314
|
-
if (!path.includes("$value")) return;
|
|
3315
|
-
if (!parseFieldNodeId(nodeId)) return;
|
|
3316
|
-
const [instanceId, _, fieldPath] = nodeId.split(":");
|
|
3317
|
-
const instance = regleDevtoolsRegistry.get(instanceId);
|
|
3318
|
-
if (instance && instance.r$.$fields) {
|
|
3319
|
-
const fieldStatus = resolveFieldByPath(instance.r$.$fields, fieldPath);
|
|
3320
|
-
if (fieldStatus && "$value" in fieldStatus) fieldStatus.$value = state.value;
|
|
3321
|
-
}
|
|
3322
|
-
emitInspectorState(api);
|
|
3323
|
-
}
|
|
3324
|
-
function emitInspectorState(api) {
|
|
3325
|
-
setTimeout(() => {
|
|
3326
|
-
api.sendInspectorState(INSPECTOR_IDS.INSPECTOR);
|
|
3327
|
-
api.sendInspectorTree(INSPECTOR_IDS.INSPECTOR);
|
|
3328
|
-
}, 100);
|
|
3192
|
+
function extendRegleConfig(regle, { rules, modifiers, shortcuts }) {
|
|
3193
|
+
const rootConfig = regle.__config ?? {};
|
|
3194
|
+
const newRules = () => ({
|
|
3195
|
+
...rootConfig.rules?.(),
|
|
3196
|
+
...rules?.()
|
|
3197
|
+
});
|
|
3198
|
+
const newModifiers = rootConfig.modifiers && modifiers ? merge(rootConfig.modifiers, modifiers) : rootConfig.modifiers ?? modifiers;
|
|
3199
|
+
const newShortcuts = rootConfig.shortcuts && shortcuts ? merge(rootConfig.shortcuts, shortcuts) : rootConfig.shortcuts ?? shortcuts;
|
|
3200
|
+
const useRegle$1 = createUseRegleComposable(newRules, newModifiers, newShortcuts);
|
|
3201
|
+
useRegle$1.__config = {
|
|
3202
|
+
rules: newRules,
|
|
3203
|
+
modifiers: newModifiers,
|
|
3204
|
+
shortcuts: newShortcuts
|
|
3205
|
+
};
|
|
3206
|
+
return {
|
|
3207
|
+
useRegle: useRegle$1,
|
|
3208
|
+
inferRules: createInferRuleHelper()
|
|
3209
|
+
};
|
|
3329
3210
|
}
|
|
3330
3211
|
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3212
|
+
function mergeRegles(regles, _scoped) {
|
|
3213
|
+
const scoped = _scoped == null ? false : _scoped;
|
|
3214
|
+
const $value = computed({
|
|
3215
|
+
get: () => {
|
|
3216
|
+
if (scoped) return Object.values(regles).map((r) => r.$value);
|
|
3217
|
+
else return Object.fromEntries(Object.entries(regles).map(([key, r]) => [key, r.$value]));
|
|
3218
|
+
},
|
|
3219
|
+
set: (value) => {
|
|
3220
|
+
if (!scoped) {
|
|
3221
|
+
if (typeof value === "object") Object.entries(value).forEach(([key, newValue]) => regles[key].$value = newValue);
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3339
3224
|
});
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3225
|
+
const $silentValue = computed({
|
|
3226
|
+
get: () => Object.fromEntries(Object.entries(regles).map(([key, r]) => [key, r.$silentValue])),
|
|
3227
|
+
set: (value) => {
|
|
3228
|
+
if (typeof value === "object") Object.entries(value).forEach(([key, newValue]) => regles[key].$silentValue = newValue);
|
|
3229
|
+
}
|
|
3344
3230
|
});
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3231
|
+
const $dirty = computed(() => {
|
|
3232
|
+
const entries = Object.entries(regles);
|
|
3233
|
+
return !!entries.length && entries.every(([_, regle]) => {
|
|
3234
|
+
return regle?.$dirty;
|
|
3235
|
+
});
|
|
3349
3236
|
});
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3237
|
+
const $anyDirty = computed(() => {
|
|
3238
|
+
return Object.entries(regles).some(([_, regle]) => {
|
|
3239
|
+
return regle?.$anyDirty;
|
|
3240
|
+
});
|
|
3354
3241
|
});
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3242
|
+
const $invalid = computed(() => {
|
|
3243
|
+
return Object.entries(regles).some(([_, regle]) => {
|
|
3244
|
+
return regle?.$invalid;
|
|
3245
|
+
});
|
|
3359
3246
|
});
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
label: "inactive",
|
|
3366
|
-
textColor: 10265519,
|
|
3367
|
-
backgroundColor: 15987958
|
|
3247
|
+
const $correct = computed(() => {
|
|
3248
|
+
const entries = Object.entries(regles);
|
|
3249
|
+
return !!entries.length && entries.every(([_, regle]) => {
|
|
3250
|
+
return regle?.$correct || regle.$anyDirty && !regle.$invalid;
|
|
3251
|
+
});
|
|
3368
3252
|
});
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3253
|
+
const $error = computed(() => {
|
|
3254
|
+
return Object.entries(regles).some(([_, regle]) => {
|
|
3255
|
+
return regle?.$error;
|
|
3256
|
+
});
|
|
3373
3257
|
});
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3258
|
+
const $ready = computed(() => {
|
|
3259
|
+
const entries = Object.entries(regles);
|
|
3260
|
+
return !!entries.length && entries.every(([_, regle]) => {
|
|
3261
|
+
return regle?.$ready;
|
|
3262
|
+
});
|
|
3378
3263
|
});
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3264
|
+
const $pending = computed(() => {
|
|
3265
|
+
return Object.entries(regles).some(([_, regle]) => {
|
|
3266
|
+
return regle?.$pending;
|
|
3267
|
+
});
|
|
3383
3268
|
});
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
const ruleTags = buildRuleTags(ruleStatus);
|
|
3392
|
-
children.push({
|
|
3393
|
-
id: createRuleNodeId(instanceId, fieldPath, ruleName),
|
|
3394
|
-
label: ruleName,
|
|
3395
|
-
tags: ruleTags,
|
|
3396
|
-
children: []
|
|
3397
|
-
});
|
|
3398
|
-
}
|
|
3269
|
+
const $issues = computed(() => {
|
|
3270
|
+
if (scoped) return Object.entries(regles).map(([_, regle]) => {
|
|
3271
|
+
return regle.$issues;
|
|
3272
|
+
});
|
|
3273
|
+
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
3274
|
+
return [key, regle.$issues];
|
|
3275
|
+
}));
|
|
3399
3276
|
});
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
const itemTags = buildNodeTags(item);
|
|
3408
|
-
const itemPath = `${fieldPath}[${index}]`;
|
|
3409
|
-
let itemChildren = [];
|
|
3410
|
-
if (isNestedRulesStatus(item)) itemChildren = buildNestedFieldNodes(item.$fields, instanceId, itemPath);
|
|
3411
|
-
else if (isFieldStatus(item)) itemChildren = buildRuleNodes(item, instanceId, itemPath);
|
|
3412
|
-
children.push({
|
|
3413
|
-
id: createFieldNodeId(instanceId, itemPath),
|
|
3414
|
-
label: `[${index}]`,
|
|
3415
|
-
tags: itemTags,
|
|
3416
|
-
children: itemChildren
|
|
3417
|
-
});
|
|
3418
|
-
}
|
|
3277
|
+
const $silentIssues = computed(() => {
|
|
3278
|
+
if (scoped) return Object.entries(regles).map(([_, regle]) => {
|
|
3279
|
+
return regle.$silentIssues;
|
|
3280
|
+
});
|
|
3281
|
+
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
3282
|
+
return [key, regle.$silentIssues];
|
|
3283
|
+
}));
|
|
3419
3284
|
});
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3285
|
+
const $errors = computed(() => {
|
|
3286
|
+
if (scoped) return Object.entries(regles).map(([_, regle]) => {
|
|
3287
|
+
return regle.$errors;
|
|
3288
|
+
});
|
|
3289
|
+
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
3290
|
+
return [key, regle.$errors];
|
|
3291
|
+
}));
|
|
3292
|
+
});
|
|
3293
|
+
const $silentErrors = computed(() => {
|
|
3294
|
+
if (scoped) return Object.entries(regles).map(([_, regle]) => {
|
|
3295
|
+
return regle.$silentErrors;
|
|
3296
|
+
});
|
|
3297
|
+
else return Object.fromEntries(Object.entries(regles).map(([key, regle]) => {
|
|
3298
|
+
return [key, regle.$silentErrors];
|
|
3299
|
+
}));
|
|
3300
|
+
});
|
|
3301
|
+
const $edited = computed(() => {
|
|
3302
|
+
const entries = Object.entries(regles);
|
|
3303
|
+
return !!entries.length && entries.every(([_, regle]) => {
|
|
3304
|
+
return regle?.$edited;
|
|
3305
|
+
});
|
|
3306
|
+
});
|
|
3307
|
+
const $anyEdited = computed(() => {
|
|
3308
|
+
return Object.entries(regles).some(([_, regle]) => {
|
|
3309
|
+
return regle?.$anyEdited;
|
|
3310
|
+
});
|
|
3311
|
+
});
|
|
3312
|
+
const $instances = computed(() => {
|
|
3313
|
+
if (scoped) return Object.values(regles);
|
|
3314
|
+
else return regles;
|
|
3315
|
+
});
|
|
3316
|
+
function $reset(options) {
|
|
3317
|
+
Object.values(regles).forEach((regle) => {
|
|
3318
|
+
regle.$reset(options);
|
|
3319
|
+
});
|
|
3320
|
+
}
|
|
3321
|
+
function $touch() {
|
|
3322
|
+
Object.values(regles).forEach((regle) => {
|
|
3323
|
+
regle.$touch();
|
|
3324
|
+
});
|
|
3325
|
+
}
|
|
3326
|
+
function $extractDirtyFields(filterNullishValues = true) {
|
|
3327
|
+
return Object.values(regles).map((regle) => regle.$extractDirtyFields(filterNullishValues));
|
|
3328
|
+
}
|
|
3329
|
+
function $clearExternalErrors() {
|
|
3330
|
+
Object.values(regles).forEach((regle) => {
|
|
3331
|
+
regle.$clearExternalErrors();
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
async function $validate(forceValues) {
|
|
3335
|
+
try {
|
|
3336
|
+
if (forceValues) $value.value = forceValues;
|
|
3337
|
+
const data = $value.value;
|
|
3338
|
+
return {
|
|
3339
|
+
valid: (await Promise.allSettled(Object.values(regles).map((regle) => {
|
|
3340
|
+
return regle.$validate();
|
|
3341
|
+
}))).every((value) => {
|
|
3342
|
+
if (value.status === "fulfilled") return value.value.valid === true;
|
|
3343
|
+
else return false;
|
|
3344
|
+
}),
|
|
3345
|
+
data,
|
|
3346
|
+
errors: $errors.value,
|
|
3347
|
+
issues: $issues.value
|
|
3348
|
+
};
|
|
3349
|
+
} catch {
|
|
3350
|
+
return {
|
|
3351
|
+
valid: false,
|
|
3352
|
+
data: $value.value,
|
|
3353
|
+
errors: $errors.value,
|
|
3354
|
+
issues: $issues.value
|
|
3355
|
+
};
|
|
3438
3356
|
}
|
|
3357
|
+
}
|
|
3358
|
+
return reactive({
|
|
3359
|
+
...!scoped && { $silentValue },
|
|
3360
|
+
$errors,
|
|
3361
|
+
$issues,
|
|
3362
|
+
$silentIssues,
|
|
3363
|
+
$silentErrors,
|
|
3364
|
+
$instances,
|
|
3365
|
+
$value,
|
|
3366
|
+
$dirty,
|
|
3367
|
+
$anyDirty,
|
|
3368
|
+
$invalid,
|
|
3369
|
+
$correct,
|
|
3370
|
+
$error,
|
|
3371
|
+
$pending,
|
|
3372
|
+
$ready,
|
|
3373
|
+
$edited,
|
|
3374
|
+
$anyEdited,
|
|
3375
|
+
$reset,
|
|
3376
|
+
$touch,
|
|
3377
|
+
$validate,
|
|
3378
|
+
$extractDirtyFields,
|
|
3379
|
+
$clearExternalErrors
|
|
3439
3380
|
});
|
|
3440
|
-
return children;
|
|
3441
3381
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
if (
|
|
3451
|
-
else if (isNestedRulesStatus(fieldStatus)) fieldChildren = buildNestedFieldNodes(fieldStatus.$fields, instanceId, fieldName);
|
|
3452
|
-
else if (isFieldStatus(fieldStatus)) fieldChildren = buildRuleNodes(fieldStatus, instanceId, fieldName);
|
|
3453
|
-
children.push({
|
|
3454
|
-
id: createFieldNodeId(instanceId, fieldName),
|
|
3455
|
-
label: fieldName,
|
|
3456
|
-
tags: fieldTags,
|
|
3457
|
-
children: fieldChildren
|
|
3458
|
-
});
|
|
3382
|
+
|
|
3383
|
+
function createUseCollectScope(instances, options) {
|
|
3384
|
+
function useCollectScope$1(namespace) {
|
|
3385
|
+
const computedNamespace = computed(() => toValue(namespace));
|
|
3386
|
+
setEmptyNamespace();
|
|
3387
|
+
const r$ = ref(collectRegles(instances.value));
|
|
3388
|
+
const regle = reactive({ r$ });
|
|
3389
|
+
function setEmptyNamespace() {
|
|
3390
|
+
if (computedNamespace.value && !instances.value[computedNamespace.value]) instances.value[computedNamespace.value] = {};
|
|
3459
3391
|
}
|
|
3460
|
-
|
|
3461
|
-
|
|
3392
|
+
watch(computedNamespace, setEmptyNamespace);
|
|
3393
|
+
watch(instances, (newInstances) => {
|
|
3394
|
+
r$.value = collectRegles(newInstances);
|
|
3395
|
+
}, { deep: true });
|
|
3396
|
+
function collectRegles(r$Instances) {
|
|
3397
|
+
if (computedNamespace.value) return mergeRegles(r$Instances[computedNamespace.value] ?? {}, !options.asRecord);
|
|
3398
|
+
else return mergeRegles(r$Instances["~~global"] ?? {}, !options.asRecord);
|
|
3399
|
+
}
|
|
3400
|
+
return { r$: regle.r$ };
|
|
3401
|
+
}
|
|
3402
|
+
return { useCollectScope: useCollectScope$1 };
|
|
3462
3403
|
}
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3404
|
+
|
|
3405
|
+
function createUseScopedRegleComposable(instances, customUseRegle) {
|
|
3406
|
+
const scopedUseRegle = customUseRegle ?? useRegle;
|
|
3407
|
+
const useScopedRegle$1 = ((state, rulesFactory, options) => {
|
|
3408
|
+
const { namespace, scopeKey: _scopeKey, ...restOptions } = options ?? {};
|
|
3409
|
+
scopedUseRegle.__config ??= {};
|
|
3410
|
+
const computedNamespace = computed(() => toValue(namespace));
|
|
3411
|
+
const $id = ref(`${Object.keys(instances.value).length + 1}-${randomId()}`);
|
|
3412
|
+
const instanceName = computed(() => {
|
|
3413
|
+
return options?.scopeKey ?? `instance-${$id.value}`;
|
|
3414
|
+
});
|
|
3415
|
+
const { r$ } = scopedUseRegle(state, rulesFactory, restOptions);
|
|
3416
|
+
register();
|
|
3417
|
+
tryOnScopeDispose(dispose);
|
|
3418
|
+
watch(computedNamespace, (newName, oldName) => {
|
|
3419
|
+
dispose(oldName);
|
|
3420
|
+
register();
|
|
3421
|
+
});
|
|
3422
|
+
if (getCurrentInstance()) onMounted(() => {
|
|
3423
|
+
const currentInstance = getCurrentInstance();
|
|
3424
|
+
if (typeof window !== "undefined" && currentInstance?.proxy?.$el?.parentElement) {
|
|
3425
|
+
if (document.documentElement && !document.documentElement.contains(currentInstance?.proxy?.$el?.parentElement)) dispose();
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
function dispose(oldName) {
|
|
3429
|
+
const nameToClean = oldName ?? computedNamespace.value;
|
|
3430
|
+
if (nameToClean) {
|
|
3431
|
+
if (instances.value[nameToClean]) delete instances.value[nameToClean][instanceName.value];
|
|
3432
|
+
} else if (instances.value["~~global"][instanceName.value]) delete instances.value["~~global"][instanceName.value];
|
|
3433
|
+
}
|
|
3434
|
+
function register() {
|
|
3435
|
+
if (computedNamespace.value) {
|
|
3436
|
+
if (!instances.value[computedNamespace.value]) instances.value[computedNamespace.value] = {};
|
|
3437
|
+
instances.value[computedNamespace.value][instanceName.value] = r$;
|
|
3438
|
+
} else {
|
|
3439
|
+
if (!instances.value["~~global"]) instances.value["~~global"] = {};
|
|
3440
|
+
instances.value["~~global"][instanceName.value] = r$;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3466
3443
|
return {
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
children: buildRootChildrenNodes(r$, id)
|
|
3444
|
+
r$,
|
|
3445
|
+
dispose,
|
|
3446
|
+
register
|
|
3471
3447
|
};
|
|
3472
3448
|
});
|
|
3473
|
-
|
|
3474
|
-
return filterInspectorTree(nodes, filter);
|
|
3449
|
+
return { useScopedRegle: useScopedRegle$1 };
|
|
3475
3450
|
}
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
const
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
}
|
|
3488
|
-
|
|
3451
|
+
|
|
3452
|
+
function createScopedUseRegle(options) {
|
|
3453
|
+
const instances = (options?.customStore ? () => {
|
|
3454
|
+
if (options.customStore) {
|
|
3455
|
+
if (!options.customStore?.value["~~global"]) options.customStore.value["~~global"] = {};
|
|
3456
|
+
else if (options.customStore?.value) options.customStore.value = { "~~global": {} };
|
|
3457
|
+
}
|
|
3458
|
+
return options.customStore;
|
|
3459
|
+
} : createGlobalState(() => {
|
|
3460
|
+
return ref({ "~~global": {} });
|
|
3461
|
+
}))();
|
|
3462
|
+
const { useScopedRegle: useScopedRegle$1 } = createUseScopedRegleComposable(instances, options?.customUseRegle);
|
|
3463
|
+
const { useCollectScope: useCollectScope$1 } = createUseCollectScope(instances, { asRecord: options?.asRecord });
|
|
3464
|
+
return {
|
|
3465
|
+
useScopedRegle: useScopedRegle$1,
|
|
3466
|
+
useCollectScope: useCollectScope$1
|
|
3467
|
+
};
|
|
3489
3468
|
}
|
|
3469
|
+
const { useCollectScope, useScopedRegle } = createScopedUseRegle();
|
|
3490
3470
|
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
{
|
|
3519
|
-
icon: "refresh",
|
|
3520
|
-
tooltip: "Reset validation state (with `$reset`)",
|
|
3521
|
-
action: (nodeId) => {
|
|
3522
|
-
handleResetAction(nodeId, api);
|
|
3523
|
-
}
|
|
3524
|
-
},
|
|
3525
|
-
{
|
|
3526
|
-
icon: "restore",
|
|
3527
|
-
tooltip: "Restore to initial state (with `$reset`)",
|
|
3528
|
-
action: (nodeId) => {
|
|
3529
|
-
handleResetAction(nodeId, api, true);
|
|
3530
|
-
}
|
|
3531
|
-
}
|
|
3532
|
-
]
|
|
3533
|
-
});
|
|
3534
|
-
setupInstanceWatchers(api);
|
|
3535
|
-
api.on.getInspectorTree((payload) => {
|
|
3536
|
-
if (payload.inspectorId === INSPECTOR_IDS.INSPECTOR) payload.rootNodes = buildInspectorTree(regleDevtoolsRegistry.getAll(), payload.filter);
|
|
3537
|
-
});
|
|
3538
|
-
api.on.getInspectorState((payload) => {
|
|
3539
|
-
if (payload.inspectorId === INSPECTOR_IDS.INSPECTOR) {
|
|
3540
|
-
const state = buildInspectorState(payload.nodeId, (id) => regleDevtoolsRegistry.get(id));
|
|
3541
|
-
if (state) payload.state = state;
|
|
3471
|
+
/**
|
|
3472
|
+
* Declare variations of state that depends on one value
|
|
3473
|
+
*
|
|
3474
|
+
* Autocomplete may not work here because of https://github.com/microsoft/TypeScript/issues/49547
|
|
3475
|
+
*
|
|
3476
|
+
* ```ts
|
|
3477
|
+
* // ⚠️ Use getter syntax for your rules () => {} or a computed one
|
|
3478
|
+
* const {r$} = useRegle(state, () => {
|
|
3479
|
+
* const variant = createVariant(state, 'type', [
|
|
3480
|
+
* {type: { literal: literal('EMAIL')}, email: { required, email }},
|
|
3481
|
+
* {type: { literal: literal('GITHUB')}, username: { required }},
|
|
3482
|
+
* {type: { required }},
|
|
3483
|
+
* ]);
|
|
3484
|
+
*
|
|
3485
|
+
* return {
|
|
3486
|
+
* ...variant.value,
|
|
3487
|
+
* };
|
|
3488
|
+
* })
|
|
3489
|
+
* ```
|
|
3490
|
+
*/
|
|
3491
|
+
function createVariant(root, discriminantKey, variants) {
|
|
3492
|
+
const watchableRoot = computed(() => toValue(root)[discriminantKey]);
|
|
3493
|
+
return computed(() => {
|
|
3494
|
+
const selectedVariant = variants.find((variant) => {
|
|
3495
|
+
if (variant[discriminantKey] && "literal" in variant[discriminantKey]) {
|
|
3496
|
+
const literalRule = variant[discriminantKey]["literal"];
|
|
3497
|
+
if (isRuleDef(literalRule)) return unref(literalRule._params?.[0]) === watchableRoot.value;
|
|
3542
3498
|
}
|
|
3543
3499
|
});
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3500
|
+
if (selectedVariant) return selectedVariant;
|
|
3501
|
+
else {
|
|
3502
|
+
const anyDiscriminantRules = variants.find((variant) => isObject(variant[discriminantKey]) && !Object.keys(variant[discriminantKey]).some((key) => key === "literal"));
|
|
3503
|
+
if (anyDiscriminantRules) return anyDiscriminantRules;
|
|
3504
|
+
else return {};
|
|
3505
|
+
}
|
|
3547
3506
|
});
|
|
3548
3507
|
}
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3508
|
+
/**
|
|
3509
|
+
* Narrow a nested variant field to a discriminated value
|
|
3510
|
+
*
|
|
3511
|
+
* ```ts
|
|
3512
|
+
* if (narrowVariant(r$, 'type', 'EMAIL')) {
|
|
3513
|
+
* r$.email.$value = 'foo';
|
|
3514
|
+
* }
|
|
3515
|
+
* ```
|
|
3516
|
+
*/
|
|
3517
|
+
function narrowVariant(root, discriminantKey, discriminantValue) {
|
|
3518
|
+
return isObject(root[discriminantKey]) && "$value" in root[discriminantKey] && root[discriminantKey]?.$value === discriminantValue;
|
|
3519
|
+
}
|
|
3520
|
+
function variantToRef(root, discriminantKey, discriminantValue, _options) {
|
|
3521
|
+
const fromRoot = isRef(root) ? toRef(root.value, "$fields") : toRef(root, "$fields");
|
|
3522
|
+
const returnedRef = ref();
|
|
3523
|
+
watch(fromRoot, async () => {
|
|
3524
|
+
await nextTick();
|
|
3525
|
+
if (narrowVariant(fromRoot.value, discriminantKey, discriminantValue)) returnedRef.value = toRef(root).value;
|
|
3526
|
+
else returnedRef.value = void 0;
|
|
3527
|
+
}, {
|
|
3528
|
+
immediate: true,
|
|
3529
|
+
flush: "pre"
|
|
3569
3530
|
});
|
|
3531
|
+
return returnedRef;
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
/**
|
|
3535
|
+
* Helper method to wrap an raw rules object
|
|
3536
|
+
*
|
|
3537
|
+
* Similar to:
|
|
3538
|
+
*
|
|
3539
|
+
* ```ts
|
|
3540
|
+
* const rules = {...} satisfies RegleUnknownRulesTree
|
|
3541
|
+
* ```
|
|
3542
|
+
*/
|
|
3543
|
+
function defineRules(rules) {
|
|
3544
|
+
return rules;
|
|
3545
|
+
}
|
|
3546
|
+
/**
|
|
3547
|
+
* Refine a raw rules object to set rules that depends on the state values.
|
|
3548
|
+
*
|
|
3549
|
+
* @example
|
|
3550
|
+
*
|
|
3551
|
+
* ```ts
|
|
3552
|
+
* const rules = refineRules({
|
|
3553
|
+
* password: { required, type: type<string>() },
|
|
3554
|
+
* }, (state) => {
|
|
3555
|
+
* return {
|
|
3556
|
+
* confirmPassword: { required, sameAs: sameAs(() => state.value.password)}
|
|
3557
|
+
* }
|
|
3558
|
+
* })
|
|
3559
|
+
* ```
|
|
3560
|
+
*/
|
|
3561
|
+
function refineRules(rules, refinement) {
|
|
3562
|
+
return (state) => merge({ ...rules }, refinement(state));
|
|
3570
3563
|
}
|
|
3571
3564
|
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
const __USE_DEVTOOLS__ = process.env.NODE_ENV === "development";
|
|
3565
|
+
var version$1 = "1.11.0-beta.3";
|
|
3566
|
+
|
|
3575
3567
|
const regleSymbol = Symbol("regle");
|
|
3568
|
+
|
|
3576
3569
|
const RegleVuePlugin = { install(app) {
|
|
3577
|
-
app.provide(regleSymbol,
|
|
3578
|
-
if (typeof window !== "undefined" &&
|
|
3570
|
+
app.provide(regleSymbol, version$1);
|
|
3571
|
+
if (typeof window !== "undefined" && true) createDevtools(app);
|
|
3579
3572
|
} };
|
|
3580
3573
|
|
|
3581
|
-
|
|
3582
|
-
export { InternalRuleType, RegleVuePlugin, createRule, createScopedUseRegle, createVariant, defineRegleConfig, defineRules, extendRegleConfig, flatErrors, inferRules, mergeRegles, narrowVariant, refineRules, registerRegleInstance, unwrapRuleParameters, useCollectScope, useRegle, useRootStorage, useRules, useScopedRegle, variantToRef };
|
|
3574
|
+
export { InternalRuleType, RegleVuePlugin, createRule, createScopedUseRegle, createVariant, defineRegleConfig, defineRules, extendRegleConfig, flatErrors, inferRules, mergeRegles, narrowVariant, refineRules, unwrapRuleParameters, useCollectScope, useRegle, useRootStorage, useRules, useScopedRegle, variantToRef };
|