@regle/core 0.0.4-beta.0 → 0.0.5-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ function createReactiveParams(params) {
22
22
  // src/core/createRule/defineRuleProcessors.ts
23
23
  function defineRuleProcessors(definition, ...params) {
24
24
  const { message, validator, active, ...properties } = definition;
25
+ const isAsync = validator.constructor.name === "AsyncFunction";
25
26
  const processors = {
26
27
  message(value, ...args) {
27
28
  if (typeof definition.message === "function") {
@@ -47,6 +48,7 @@ function defineRuleProcessors(definition, ...params) {
47
48
  _active: definition.active,
48
49
  _type: definition.type,
49
50
  _patched: false,
51
+ _async: isAsync,
50
52
  _params: createReactiveParams(params)
51
53
  }
52
54
  };
@@ -58,6 +60,7 @@ function createRule(definition) {
58
60
  if (typeof definition.validator === "function") {
59
61
  let fakeParams = [];
60
62
  const staticProcessors = defineRuleProcessors(definition, ...fakeParams);
63
+ const isAsync = definition.validator.constructor.name === "AsyncFunction";
61
64
  if (definition.validator.length > 1) {
62
65
  const ruleFactory = function(...params) {
63
66
  return defineRuleProcessors(definition, ...params);
@@ -71,6 +74,7 @@ function createRule(definition) {
71
74
  ruleFactory._active = definition.active;
72
75
  ruleFactory._type = definition.type;
73
76
  ruleFactory._patched = false;
77
+ ruleFactory._async = isAsync;
74
78
  return ruleFactory;
75
79
  } else {
76
80
  return staticProcessors;
@@ -203,16 +207,21 @@ function useErrors($regle) {
203
207
  }
204
208
 
205
209
  // src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
206
- import {
207
- computed as computed4,
208
- effectScope as effectScope4,
209
- reactive as reactive4,
210
- toRef as toRef4,
211
- watch as watch4
212
- } from "vue";
210
+ import { computed as computed4, effectScope as effectScope4, reactive as reactive4, toRef as toRef4, watch as watch4 } from "vue";
211
+
212
+ // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
213
+ import { reactive as reactive3, ref as ref3, toRef as toRef3, toRefs, watch as watch3 } from "vue";
213
214
 
214
215
  // src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
215
- import { computed as computed3, effectScope as effectScope3, reactive as reactive2, ref as ref2, toRef as toRef2, watch as watch2 } from "vue";
216
+ import {
217
+ computed as computed3,
218
+ effectScope as effectScope3,
219
+ reactive as reactive2,
220
+ ref as ref2,
221
+ toRef as toRef2,
222
+ unref as unref2,
223
+ watch as watch2
224
+ } from "vue";
216
225
 
217
226
  // src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts
218
227
  import { computed as computed2, effectScope as effectScope2, reactive, watch } from "vue";
@@ -232,7 +241,8 @@ function createReactiveRuleStatus({
232
241
  ruleKey,
233
242
  state,
234
243
  path,
235
- storage
244
+ storage,
245
+ options
236
246
  }) {
237
247
  let scope = effectScope2();
238
248
  let scopeState;
@@ -252,7 +262,7 @@ function createReactiveRuleStatus({
252
262
  });
253
263
  const $message = computed2(() => {
254
264
  let message = "";
255
- const customMessageRule = customMessages[ruleKey]?.message;
265
+ const customMessageRule = customMessages ? customMessages[ruleKey]?.message : void 0;
256
266
  if (customMessageRule) {
257
267
  if (typeof customMessageRule === "function") {
258
268
  message = customMessageRule(state.value, ...$params.value);
@@ -305,7 +315,6 @@ function createReactiveRuleStatus({
305
315
  $path
306
316
  };
307
317
  });
308
- $validate();
309
318
  }
310
319
  $watch();
311
320
  const $unwatchState = watch(scopeState.$params, $validate, {
@@ -338,7 +347,6 @@ function createReactiveRuleStatus({
338
347
  $unwatchState();
339
348
  scope.stop();
340
349
  scope = effectScope2();
341
- scopeState = null;
342
350
  }
343
351
  return reactive({
344
352
  ...scopeState,
@@ -356,12 +364,14 @@ function createReactiveFieldStatus({
356
364
  rulesDef,
357
365
  customMessages,
358
366
  path,
359
- storage
367
+ storage,
368
+ options
360
369
  }) {
361
370
  let scope = effectScope3();
362
371
  let scopeState;
363
372
  const $dirty = ref2(false);
364
373
  const $anyDirty = computed3(() => $dirty.value);
374
+ const triggerPunishment = ref2(false);
365
375
  function createReactiveRulesResult() {
366
376
  const declaredRules = rulesDef.value;
367
377
  const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
@@ -378,7 +388,8 @@ function createReactiveFieldStatus({
378
388
  ruleKey,
379
389
  state,
380
390
  path,
381
- storage
391
+ storage,
392
+ options
382
393
  })
383
394
  ];
384
395
  }
@@ -395,10 +406,14 @@ function createReactiveFieldStatus({
395
406
  storage.setDirtyEntry(path, $dirty.value);
396
407
  });
397
408
  const $unwatchState = watch2(state, () => {
398
- if (!$dirty.value) {
399
- $dirty.value = true;
409
+ if (unref2(options.autoDirty)) {
410
+ if (!$dirty.value) {
411
+ $dirty.value = true;
412
+ }
413
+ }
414
+ if (!unref2(options.lazy)) {
415
+ $commit();
400
416
  }
401
- $validate();
402
417
  });
403
418
  function $unwatch() {
404
419
  if ($rules.value) {
@@ -411,9 +426,9 @@ function createReactiveFieldStatus({
411
426
  storage.setDirtyEntry(path, $dirty.value);
412
427
  }
413
428
  $unwatchState();
429
+ $unwatchValid();
414
430
  scope.stop();
415
431
  scope = effectScope3();
416
- scopeState = null;
417
432
  }
418
433
  function $watch() {
419
434
  scopeState = scope.run(() => {
@@ -421,16 +436,30 @@ function createReactiveFieldStatus({
421
436
  return $invalid.value && !$pending.value && $dirty.value;
422
437
  });
423
438
  const $pending = computed3(() => {
424
- return Object.entries($rules.value).some(([key, rule]) => {
425
- return rule.$pending;
426
- });
439
+ if (triggerPunishment.value || !unref2(options.rewardEarly)) {
440
+ return Object.entries($rules.value).some(([key, ruleResult]) => {
441
+ return ruleResult.$pending;
442
+ });
443
+ }
444
+ return false;
427
445
  });
428
446
  const $invalid = computed3(() => {
429
- return Object.entries($rules.value).some(([key, ruleResult]) => {
430
- return !ruleResult.$valid;
431
- });
447
+ if (triggerPunishment.value || !unref2(options.rewardEarly)) {
448
+ return Object.entries($rules.value).some(([key, ruleResult]) => {
449
+ return !ruleResult.$valid;
450
+ });
451
+ }
452
+ return false;
453
+ });
454
+ const $valid = computed3(() => {
455
+ if (unref2(options.rewardEarly)) {
456
+ return Object.entries($rules.value).every(([key, ruleResult]) => {
457
+ return ruleResult.$valid;
458
+ });
459
+ } else {
460
+ return !$invalid.value;
461
+ }
432
462
  });
433
- const $valid = computed3(() => !$invalid.value);
434
463
  return {
435
464
  $error,
436
465
  $pending,
@@ -441,15 +470,25 @@ function createReactiveFieldStatus({
441
470
  }
442
471
  const $rules = ref2();
443
472
  createReactiveRulesResult();
473
+ const $unwatchValid = watch2(scopeState.$valid, (valid) => {
474
+ if (unref2(options.rewardEarly) && valid) {
475
+ triggerPunishment.value = false;
476
+ }
477
+ });
444
478
  function $reset() {
445
479
  $dirty.value = false;
446
480
  }
447
481
  function $touch() {
448
482
  $dirty.value = true;
449
- $validate();
483
+ }
484
+ function $commit() {
485
+ Object.entries($rules.value).map(([key, rule]) => {
486
+ return rule.$validate();
487
+ });
450
488
  }
451
489
  async function $validate() {
452
490
  try {
491
+ triggerPunishment.value = true;
453
492
  const results = await Promise.all(
454
493
  Object.entries($rules.value).map(([key, rule]) => {
455
494
  return rule.$validate();
@@ -477,14 +516,53 @@ function createReactiveFieldStatus({
477
516
  });
478
517
  }
479
518
 
519
+ // src/utils/randomId.ts
520
+ function randomId() {
521
+ const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0];
522
+ return uint32.toString(8);
523
+ }
524
+
480
525
  // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
481
- import { reactive as reactive3, ref as ref3, toRef as toRef3, watch as watch3 } from "vue";
526
+ function createCollectionElement({
527
+ path,
528
+ index,
529
+ options,
530
+ storage,
531
+ value,
532
+ customMessages,
533
+ rules
534
+ }) {
535
+ const $path = `${path}.${index}`;
536
+ const $id = randomId();
537
+ if (!value[index].$id) {
538
+ Object.defineProperties(value[index], {
539
+ $id: {
540
+ value: $id
541
+ }
542
+ });
543
+ }
544
+ const $state = toRefs(value);
545
+ const $status = createReactiveChildrenStatus({
546
+ state: $state[index],
547
+ rulesDef: toRef3(() => rules),
548
+ customMessages,
549
+ path: $path,
550
+ storage,
551
+ options
552
+ });
553
+ if ($status) {
554
+ $status.$id = value[index].$id ?? $id;
555
+ storage.addArrayStatus($status.$id, $status);
556
+ }
557
+ return $status;
558
+ }
482
559
  function createReactiveCollectionStatus({
483
560
  state,
484
561
  rulesDef,
485
562
  customMessages,
486
563
  path,
487
- storage
564
+ storage,
565
+ options
488
566
  }) {
489
567
  if (Array.isArray(state.value) && !rulesDef.value.$each) {
490
568
  return null;
@@ -501,16 +579,17 @@ function createReactiveCollectionStatus({
501
579
  rulesDef: toRef3(() => otherFields),
502
580
  customMessages,
503
581
  path,
504
- storage
582
+ storage,
583
+ options
505
584
  });
506
585
  if (Array.isArray(state.value) && $each) {
507
586
  $eachStatus.value = state.value.map((value, index) => {
508
- const $path = `${path}.${index}`;
509
- return createReactiveChildrenStatus({
510
- state: toRef3(() => value),
511
- rulesDef: toRef3(() => $each),
512
- customMessages,
513
- path: $path,
587
+ return createCollectionElement({
588
+ path,
589
+ rules: $each,
590
+ value: state.value,
591
+ index,
592
+ options,
514
593
  storage
515
594
  });
516
595
  }).filter((f) => !!f);
@@ -518,6 +597,38 @@ function createReactiveCollectionStatus({
518
597
  $eachStatus.value = [];
519
598
  }
520
599
  }
600
+ function updateChildrenStatus() {
601
+ const { $each } = rulesDef.value;
602
+ if (Array.isArray(state.value) && $eachStatus.value && $each) {
603
+ state.value.forEach((value, index) => {
604
+ if (value.$id) {
605
+ const previousStatus = storage.getArrayStatus(value.$id);
606
+ if (previousStatus) {
607
+ $eachStatus.value[index] = previousStatus;
608
+ }
609
+ } else {
610
+ const newElement = createCollectionElement({
611
+ value: state.value,
612
+ rules: $each,
613
+ customMessages,
614
+ path,
615
+ storage,
616
+ options,
617
+ index
618
+ });
619
+ if (newElement) {
620
+ $eachStatus.value[index] = newElement;
621
+ }
622
+ }
623
+ });
624
+ }
625
+ if ($eachStatus.value) {
626
+ const deletedItems = $eachStatus.value.filter(($each2) => {
627
+ return Array.isArray(state.value) && !state.value.find((val) => val.$id === $each2.$id);
628
+ });
629
+ deletedItems.forEach((item) => item.$unwatch());
630
+ }
631
+ }
521
632
  function $unwatch() {
522
633
  if ($unwatchState) {
523
634
  $unwatchState();
@@ -535,16 +646,43 @@ function createReactiveCollectionStatus({
535
646
  $unwatchState = watch3(
536
647
  state,
537
648
  () => {
538
- createStatus();
649
+ updateChildrenStatus();
539
650
  },
540
651
  { deep: true, flush: "sync" }
541
652
  );
542
653
  }
654
+ function $touch() {
655
+ $fieldStatus.value.$touch();
656
+ $eachStatus.value.forEach(($each) => {
657
+ $each.$touch();
658
+ });
659
+ }
660
+ function $reset() {
661
+ $fieldStatus.value.$reset();
662
+ $eachStatus.value.forEach(($each) => {
663
+ $each.$reset();
664
+ });
665
+ }
666
+ async function $validate() {
667
+ try {
668
+ const results = await Promise.all(
669
+ $eachStatus.value.map((rule) => {
670
+ return rule.$validate();
671
+ })
672
+ );
673
+ return results.every((value) => !!value);
674
+ } catch (e) {
675
+ return false;
676
+ }
677
+ }
543
678
  return reactive3({
544
679
  ...$fieldStatus.value,
545
680
  $each: $eachStatus,
681
+ $validate,
546
682
  $unwatch,
547
- $watch
683
+ $watch,
684
+ $touch,
685
+ $reset
548
686
  });
549
687
  }
550
688
 
@@ -555,7 +693,8 @@ function createReactiveNestedStatus({
555
693
  customMessages,
556
694
  path = "",
557
695
  rootRules,
558
- storage
696
+ storage,
697
+ options
559
698
  }) {
560
699
  let scope = effectScope4();
561
700
  let scopeState;
@@ -573,7 +712,8 @@ function createReactiveNestedStatus({
573
712
  rulesDef: statePropRulesRef,
574
713
  customMessages,
575
714
  path: path ? `${path}.${statePropKey}` : statePropKey,
576
- storage
715
+ storage,
716
+ options
577
717
  })
578
718
  ];
579
719
  }
@@ -667,11 +807,11 @@ function createReactiveNestedStatus({
667
807
  }
668
808
  scope.stop();
669
809
  scope = effectScope4();
670
- scopeState = null;
671
810
  }
672
811
  return reactive4({
673
812
  ...scopeState,
674
813
  $fields,
814
+ $value: state,
675
815
  $reset,
676
816
  $touch,
677
817
  $validate,
@@ -684,7 +824,8 @@ function createReactiveChildrenStatus({
684
824
  rulesDef,
685
825
  customMessages,
686
826
  path,
687
- storage
827
+ storage,
828
+ options
688
829
  }) {
689
830
  if (isCollectionRulesDef(rulesDef)) {
690
831
  return createReactiveCollectionStatus({
@@ -692,7 +833,8 @@ function createReactiveChildrenStatus({
692
833
  rulesDef,
693
834
  customMessages,
694
835
  path,
695
- storage
836
+ storage,
837
+ options
696
838
  });
697
839
  } else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) {
698
840
  return createReactiveNestedStatus({
@@ -700,7 +842,8 @@ function createReactiveChildrenStatus({
700
842
  state,
701
843
  customMessages,
702
844
  path,
703
- storage
845
+ storage,
846
+ options
704
847
  });
705
848
  } else if (isValidatorRulesDef(rulesDef)) {
706
849
  return createReactiveFieldStatus({
@@ -708,14 +851,15 @@ function createReactiveChildrenStatus({
708
851
  rulesDef,
709
852
  customMessages,
710
853
  path,
711
- storage
854
+ storage,
855
+ options
712
856
  });
713
857
  }
714
858
  return null;
715
859
  }
716
860
 
717
861
  // src/core/useStorage/useStorage.ts
718
- import { ref as ref5, shallowRef } from "vue";
862
+ import { ref as ref4, shallowRef } from "vue";
719
863
  function useStorage() {
720
864
  const ruleDeclStorage = shallowRef(/* @__PURE__ */ new Map());
721
865
  const fieldsStorage = shallowRef(
@@ -724,12 +868,13 @@ function useStorage() {
724
868
  const collectionsStorage = shallowRef(/* @__PURE__ */ new Map());
725
869
  const dirtyStorage = shallowRef(/* @__PURE__ */ new Map());
726
870
  const ruleStatusStorage = shallowRef(/* @__PURE__ */ new Map());
871
+ const arrayStatusStorage = shallowRef(/* @__PURE__ */ new Map());
727
872
  function getFieldsEntry($path) {
728
873
  const existingFields = fieldsStorage.value.get($path);
729
874
  if (existingFields) {
730
875
  return existingFields;
731
876
  } else {
732
- const $fields = ref5({});
877
+ const $fields = ref4({});
733
878
  fieldsStorage.value.set($path, $fields);
734
879
  return $fields;
735
880
  }
@@ -739,11 +884,17 @@ function useStorage() {
739
884
  if (existingEach) {
740
885
  return existingEach;
741
886
  } else {
742
- const $each = ref5([]);
887
+ const $each = ref4([]);
743
888
  collectionsStorage.value.set($path, $each);
744
889
  return $each;
745
890
  }
746
891
  }
892
+ function addArrayStatus($id, value) {
893
+ arrayStatusStorage.value.set($id, value);
894
+ }
895
+ function getArrayStatus($id) {
896
+ return arrayStatusStorage.value.get($id);
897
+ }
747
898
  function setDirtyEntry($path, dirty) {
748
899
  dirtyStorage.value.set($path, dirty);
749
900
  }
@@ -790,8 +941,8 @@ function useStorage() {
790
941
  if (ruleStatus) {
791
942
  return ruleStatus;
792
943
  } else {
793
- const $pending = ref5(false);
794
- const $valid = ref5(true);
944
+ const $pending = ref4(false);
945
+ const $valid = ref4(true);
795
946
  ruleStatusStorage.value.set(path, { $pending, $valid });
796
947
  return { $pending, $valid };
797
948
  }
@@ -803,20 +954,23 @@ function useStorage() {
803
954
  getDirtyState,
804
955
  trySetRuleStatusRef,
805
956
  getFieldsEntry,
806
- getCollectionsEntry
957
+ getCollectionsEntry,
958
+ getArrayStatus,
959
+ addArrayStatus
807
960
  };
808
961
  }
809
962
 
810
963
  // src/core/useRegle/useStateProperties/useStateProperties.ts
811
- function useStateProperties(scopeRules, state, customRules) {
964
+ function useStateProperties(scopeRules, state, options, customRules) {
812
965
  const storage = useStorage();
813
966
  const $regle = reactive5(
814
967
  createReactiveNestedStatus({
815
968
  rootRules: scopeRules,
816
969
  scopeRules,
817
970
  state,
818
- customMessages: customRules(),
819
- storage
971
+ customMessages: customRules?.(),
972
+ storage,
973
+ options
820
974
  })
821
975
  );
822
976
  const errors = useErrors($regle);
@@ -824,13 +978,23 @@ function useStateProperties(scopeRules, state, customRules) {
824
978
  }
825
979
 
826
980
  // src/core/useRegle/useRegle.ts
827
- function createUseRegleComposable(customRules) {
828
- function useRegle(state, rulesFactory) {
981
+ function createUseRegleComposable(customRules, options) {
982
+ const globalOptions = {
983
+ autoDirty: options?.autoDirty ?? true,
984
+ lazy: options?.lazy ?? false,
985
+ rewardEarly: options?.rewardEarly ?? false
986
+ };
987
+ function useRegle2(state, rulesFactory, options2) {
829
988
  const scopeRules = isRef2(rulesFactory) ? rulesFactory : computed5(rulesFactory);
989
+ const resolvedOptions = {
990
+ ...globalOptions,
991
+ ...options2
992
+ };
830
993
  const initialState = shallowRef2(structuredClone(toRaw(state.value)));
831
994
  const { $regle, errors } = useStateProperties(
832
995
  scopeRules,
833
996
  state,
997
+ resolvedOptions,
834
998
  customRules
835
999
  );
836
1000
  function resetForm() {
@@ -839,7 +1003,11 @@ function createUseRegleComposable(customRules) {
839
1003
  }
840
1004
  async function validateForm() {
841
1005
  $regle.$touch();
842
- return await $regle.$validate();
1006
+ const result = await $regle.$validate();
1007
+ if (result) {
1008
+ return state.value;
1009
+ }
1010
+ return false;
843
1011
  }
844
1012
  return {
845
1013
  state,
@@ -849,18 +1017,21 @@ function createUseRegleComposable(customRules) {
849
1017
  validateForm
850
1018
  };
851
1019
  }
852
- return useRegle;
1020
+ return useRegle2;
853
1021
  }
1022
+ var useRegle = createUseRegleComposable();
854
1023
 
855
- // src/core/defineCustomValidators.ts
856
- function defineCustomValidators(customRules) {
857
- const useRegle = createUseRegleComposable(customRules);
858
- return {
859
- useRegle
860
- };
1024
+ // src/core/defineRegleOptions.ts
1025
+ function defineRegleOptions({
1026
+ rules,
1027
+ options
1028
+ }) {
1029
+ const useRegle2 = createUseRegleComposable(rules, options);
1030
+ return useRegle2;
861
1031
  }
862
1032
  export {
863
1033
  InternalRuleType,
864
1034
  createRule,
865
- defineCustomValidators
1035
+ defineRegleOptions,
1036
+ unwrapRuleParameters
866
1037
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@regle/core",
3
- "version": "0.0.4-beta.0",
3
+ "version": "0.0.5-beta.0",
4
4
  "description": "Vue form validator",
5
5
  "scripts": {
6
6
  "lint": "eslint --ext .ts --ext .vue .",
7
- "typecheck": "vue-tsc --noEmit",
7
+ "typecheck": "tsc --noEmit",
8
8
  "release": "npm publish",
9
9
  "build": "tsup",
10
10
  "dev": "tsup --config=tsup.dev.ts --watch"
@@ -27,7 +27,8 @@
27
27
  "vue-eslint-parser": "9.3.1",
28
28
  "vue-tsc": "1.8.15",
29
29
  "tsup": "7.2.0",
30
- "@total-typescript/ts-reset": "0.5.1"
30
+ "@total-typescript/ts-reset": "0.5.1",
31
+ "type-fest": "4.4.0"
31
32
  },
32
33
  "type": "module",
33
34
  "exports": {