@regle/core 0.0.3 → 0.0.4-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.cjs CHANGED
@@ -36,6 +36,16 @@ function unwrapRuleParameters(params) {
36
36
  return (0, import_vue.unref)(param);
37
37
  });
38
38
  }
39
+ function createReactiveParams(params) {
40
+ return params.map((param) => {
41
+ if (param instanceof Function) {
42
+ return param;
43
+ } else if ((0, import_vue.isRef)(param)) {
44
+ return param;
45
+ }
46
+ return (0, import_vue.toRef)(() => param);
47
+ });
48
+ }
39
49
 
40
50
  // src/core/createRule/defineRuleProcessors.ts
41
51
  function defineRuleProcessors(definition, ...params) {
@@ -43,26 +53,17 @@ function defineRuleProcessors(definition, ...params) {
43
53
  const processors = {
44
54
  message(value, ...args) {
45
55
  if (typeof definition.message === "function") {
46
- return definition.message(
47
- value,
48
- ...unwrapRuleParameters(args.length ? args : params)
49
- );
56
+ return definition.message(value, ...args.length ? args : params);
50
57
  } else {
51
58
  return definition.message;
52
59
  }
53
60
  },
54
61
  validator(value, ...args) {
55
- return definition.validator(
56
- value,
57
- ...unwrapRuleParameters(args.length ? args : params)
58
- );
62
+ return definition.validator(value, ...args.length ? args : params);
59
63
  },
60
64
  active(value, ...args) {
61
65
  if (typeof definition.active === "function") {
62
- return definition.active(
63
- value,
64
- ...unwrapRuleParameters(args.length ? args : params)
65
- );
66
+ return definition.active(value, ...args.length ? args : params);
66
67
  } else {
67
68
  return definition.active ?? true;
68
69
  }
@@ -74,7 +75,7 @@ function defineRuleProcessors(definition, ...params) {
74
75
  _active: definition.active,
75
76
  _type: definition.type,
76
77
  _patched: false,
77
- _params: params
78
+ _params: createReactiveParams(params)
78
79
  }
79
80
  };
80
81
  return processors;
@@ -107,18 +108,21 @@ function createRule(definition) {
107
108
  }
108
109
 
109
110
  // src/core/useRegle/useRegle.ts
110
- var import_vue6 = require("vue");
111
+ var import_vue10 = require("vue");
111
112
 
112
113
  // src/core/useRegle/useStateProperties/useStateProperties.ts
113
- var import_vue5 = require("vue");
114
+ var import_vue9 = require("vue");
114
115
 
115
- // src/core/useRegle/useStateProperties/createReactiveStatus.ts
116
+ // src/core/useRegle/useErrors.ts
116
117
  var import_vue3 = require("vue");
117
118
 
118
119
  // src/utils/object.utils.ts
119
120
  function isObject(obj) {
120
121
  return typeof obj === "object" && obj !== null && !Array.isArray(obj);
121
122
  }
123
+ function isRefObject(obj) {
124
+ return isObject(obj.value);
125
+ }
122
126
 
123
127
  // src/utils/isEmpty.ts
124
128
  function isEmpty(value) {
@@ -143,6 +147,9 @@ function isEmpty(value) {
143
147
  return !String(value).trim().length;
144
148
  }
145
149
 
150
+ // src/utils/composables.ts
151
+ var import_vue2 = require("vue");
152
+
146
153
  // src/core/useRegle/guards/ruleDef.guards.ts
147
154
  function isNestedRulesDef(state, rule) {
148
155
  return isObject(state.value) && isObject(rule.value) && !Object.entries(rule.value).some((rule2) => isRuleDef(rule2));
@@ -159,9 +166,6 @@ function isRuleDef(rule) {
159
166
  function isFormRuleDefinition(rule) {
160
167
  return !(typeof rule.value === "function");
161
168
  }
162
- function isFormInline(rule) {
163
- return typeof rule.value === "function";
164
- }
165
169
 
166
170
  // src/core/useRegle/guards/rule.status.guards.ts
167
171
  function isNestedRulesStatus(rule) {
@@ -174,8 +178,66 @@ function isFieldStatus(rule) {
174
178
  return !!rule && "$rules" in rule;
175
179
  }
176
180
 
181
+ // src/core/useRegle/useErrors.ts
182
+ function extractRulesErrors(rules) {
183
+ return Object.entries(rules).map(([ruleKey, rule]) => {
184
+ if (!rule.$valid) {
185
+ return rule.$message;
186
+ }
187
+ return null;
188
+ }).filter((msg) => !!msg);
189
+ }
190
+ function processFieldErrors(fieldStatus) {
191
+ if (isNestedRulesStatus(fieldStatus)) {
192
+ return extractNestedErrors(fieldStatus.$fields);
193
+ } else if (isCollectionRulesStatus(fieldStatus)) {
194
+ return {
195
+ $errors: fieldStatus.$rules ? extractRulesErrors(fieldStatus.$rules) : [],
196
+ $each: fieldStatus.$each.map(processFieldErrors)
197
+ };
198
+ } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
199
+ return extractRulesErrors(fieldStatus.$rules);
200
+ }
201
+ return [];
202
+ }
203
+ function extractCollectionError(field) {
204
+ return field.$each.map(processFieldErrors);
205
+ }
206
+ function extractNestedErrors(fields) {
207
+ return Object.fromEntries(
208
+ Object.entries(fields).map(([fieldKey, fieldStatus]) => {
209
+ if (isNestedRulesStatus(fieldStatus)) {
210
+ return [fieldKey, extractNestedErrors(fieldStatus.$fields)];
211
+ } else if (isCollectionRulesStatus(fieldStatus)) {
212
+ return [
213
+ fieldKey,
214
+ {
215
+ ...fieldStatus.$rules && { $errors: extractRulesErrors(fieldStatus.$rules) },
216
+ $each: extractCollectionError(fieldStatus)
217
+ }
218
+ ];
219
+ } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
220
+ return [fieldKey, extractRulesErrors(fieldStatus.$rules)];
221
+ }
222
+ return [fieldKey, []];
223
+ })
224
+ );
225
+ }
226
+ function useErrors($regle) {
227
+ const errors = (0, import_vue3.computed)(() => {
228
+ return extractNestedErrors($regle.$fields);
229
+ });
230
+ return errors;
231
+ }
232
+
233
+ // src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
234
+ var import_vue7 = require("vue");
235
+
236
+ // src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
237
+ var import_vue5 = require("vue");
238
+
177
239
  // src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts
178
- var import_vue2 = require("vue");
240
+ var import_vue4 = require("vue");
179
241
 
180
242
  // src/types/rules/rule.internal.types.ts
181
243
  var InternalRuleType = /* @__PURE__ */ ((InternalRuleType2) => {
@@ -190,311 +252,595 @@ function createReactiveRuleStatus({
190
252
  customMessages,
191
253
  rule,
192
254
  ruleKey,
193
- state
255
+ state,
256
+ path,
257
+ storage
194
258
  }) {
195
- const $pending = (0, import_vue2.ref)(false);
196
- const $valid = (0, import_vue2.ref)(true);
197
- const $active = (0, import_vue2.computed)(() => {
198
- if (isFormInline(rule)) {
199
- return true;
200
- } else {
201
- if (typeof rule.value.active === "function") {
202
- return rule.value.active(state.value, ...$params.value);
203
- } else {
204
- return rule.value.active;
205
- }
206
- }
207
- });
208
- const $message = (0, import_vue2.computed)(() => {
209
- let message = "";
210
- const customMessageRule = customMessages[ruleKey]?.message;
211
- if (customMessageRule) {
212
- if (typeof customMessageRule === "function") {
213
- message = customMessageRule(state.value, ...$params.value);
214
- } else {
215
- message = customMessageRule;
216
- }
217
- }
218
- if (isFormRuleDefinition(rule)) {
219
- if (!(customMessageRule && !rule.value._patched)) {
220
- if (typeof rule.value.message === "function") {
221
- message = rule.value.message(state.value, ...$params.value);
259
+ let scope = (0, import_vue4.effectScope)();
260
+ let scopeState;
261
+ const { $pending, $valid } = storage.trySetRuleStatusRef(`${path}.${ruleKey}`);
262
+ function $watch() {
263
+ scopeState = scope.run(() => {
264
+ const $active = (0, import_vue4.computed)(() => {
265
+ if (isFormRuleDefinition(rule)) {
266
+ if (typeof rule.value.active === "function") {
267
+ return rule.value.active(state.value, ...$params.value);
268
+ } else {
269
+ return rule.value.active;
270
+ }
222
271
  } else {
223
- message = rule.value.message;
272
+ return true;
273
+ }
274
+ });
275
+ const $message = (0, import_vue4.computed)(() => {
276
+ let message = "";
277
+ const customMessageRule = customMessages[ruleKey]?.message;
278
+ if (customMessageRule) {
279
+ if (typeof customMessageRule === "function") {
280
+ message = customMessageRule(state.value, ...$params.value);
281
+ } else {
282
+ message = customMessageRule;
283
+ }
284
+ }
285
+ if (isFormRuleDefinition(rule)) {
286
+ if (!(customMessageRule && !rule.value._patched)) {
287
+ if (typeof rule.value.message === "function") {
288
+ message = rule.value.message(state.value, ...$params.value);
289
+ } else {
290
+ message = rule.value.message;
291
+ }
292
+ }
293
+ }
294
+ if (isEmpty(message)) {
295
+ message = "Error";
296
+ console.warn(`No error message defined for ${ruleKey}`);
297
+ }
298
+ return message;
299
+ });
300
+ const $type = (0, import_vue4.computed)(() => {
301
+ if (isFormRuleDefinition(rule)) {
302
+ return Object.values(InternalRuleType).includes(rule.value.type) ? ruleKey : rule.value.type;
303
+ } else {
304
+ return ruleKey;
305
+ }
306
+ });
307
+ const $validator = (0, import_vue4.computed)(() => {
308
+ if (isFormRuleDefinition(rule)) {
309
+ return rule.value.validator;
310
+ } else {
311
+ return rule.value;
312
+ }
313
+ });
314
+ const $params = (0, import_vue4.computed)(() => {
315
+ if (typeof rule.value === "function") {
316
+ return [];
317
+ }
318
+ return unwrapRuleParameters(rule.value._params ?? []);
319
+ });
320
+ const $path = (0, import_vue4.computed)(() => `${path}.${$type.value}`);
321
+ return {
322
+ $active,
323
+ $message,
324
+ $type,
325
+ $validator,
326
+ $params,
327
+ $path
328
+ };
329
+ });
330
+ $validate();
331
+ }
332
+ $watch();
333
+ const $unwatchState = (0, import_vue4.watch)(scopeState.$params, $validate, {
334
+ deep: true
335
+ });
336
+ async function $validate() {
337
+ const validator = scopeState.$validator.value;
338
+ let ruleResult = false;
339
+ const resultOrPromise = validator(state.value, ...scopeState.$params.value);
340
+ if (resultOrPromise instanceof Promise) {
341
+ if ($dirty.value && !$pending.value) {
342
+ try {
343
+ $valid.value = true;
344
+ $pending.value = true;
345
+ const promiseResult = await resultOrPromise;
346
+ ruleResult = promiseResult;
347
+ } catch (e) {
348
+ ruleResult = false;
349
+ } finally {
350
+ $pending.value = false;
224
351
  }
225
352
  }
353
+ } else {
354
+ ruleResult = resultOrPromise;
226
355
  }
227
- if (isEmpty(message)) {
228
- message = "Error";
229
- console.warn(`No error message defined for ${ruleKey}`);
356
+ $valid.value = ruleResult;
357
+ return ruleResult;
358
+ }
359
+ function $unwatch() {
360
+ $unwatchState();
361
+ scope.stop();
362
+ scope = (0, import_vue4.effectScope)();
363
+ scopeState = null;
364
+ }
365
+ return (0, import_vue4.reactive)({
366
+ ...scopeState,
367
+ $pending,
368
+ $valid,
369
+ $validate,
370
+ $unwatch,
371
+ $watch
372
+ });
373
+ }
374
+
375
+ // src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
376
+ function createReactiveFieldStatus({
377
+ state,
378
+ rulesDef,
379
+ customMessages,
380
+ path,
381
+ storage
382
+ }) {
383
+ let scope = (0, import_vue5.effectScope)();
384
+ let scopeState;
385
+ const $dirty = (0, import_vue5.ref)(false);
386
+ const $anyDirty = (0, import_vue5.computed)(() => $dirty.value);
387
+ function createReactiveRulesResult() {
388
+ const declaredRules = rulesDef.value;
389
+ const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
390
+ $rules.value = Object.fromEntries(
391
+ Object.entries(declaredRules).map(([ruleKey, rule]) => {
392
+ if (rule) {
393
+ const ruleRef = (0, import_vue5.toRef)(() => rule);
394
+ return [
395
+ ruleKey,
396
+ createReactiveRuleStatus({
397
+ $dirty,
398
+ customMessages,
399
+ rule: ruleRef,
400
+ ruleKey,
401
+ state,
402
+ path,
403
+ storage
404
+ })
405
+ ];
406
+ }
407
+ return [];
408
+ }).filter((ruleDef) => !!ruleDef.length)
409
+ );
410
+ $watch();
411
+ if (storeResult?.valid != null) {
412
+ $dirty.value = storage.getDirtyState(path);
230
413
  }
231
- return message;
414
+ storage.addRuleDeclEntry(path, declaredRules);
415
+ }
416
+ const $unwatchDirty = (0, import_vue5.watch)($dirty, () => {
417
+ storage.setDirtyEntry(path, $dirty.value);
232
418
  });
233
- const $type = (0, import_vue2.computed)(() => {
234
- if (isFormInline(rule)) {
235
- return ruleKey;
236
- } else {
237
- return Object.values(InternalRuleType).includes(rule.value.type) ? ruleKey : rule.value.type;
419
+ const $unwatchState = (0, import_vue5.watch)(state, () => {
420
+ if (!$dirty.value) {
421
+ $dirty.value = true;
238
422
  }
423
+ $validate();
239
424
  });
240
- const $validator = (0, import_vue2.computed)(
241
- () => {
242
- if (isFormInline(rule)) {
243
- return rule.value;
244
- } else {
245
- return rule.value.validator;
246
- }
425
+ function $unwatch() {
426
+ if ($rules.value) {
427
+ Object.entries($rules.value).forEach(([_, rule]) => {
428
+ rule.$unwatch();
429
+ });
247
430
  }
248
- );
249
- const $params = (0, import_vue2.computed)(() => {
250
- if (typeof rule.value === "function") {
251
- return [];
431
+ $unwatchDirty();
432
+ if ($dirty.value) {
433
+ storage.setDirtyEntry(path, $dirty.value);
434
+ }
435
+ $unwatchState();
436
+ scope.stop();
437
+ scope = (0, import_vue5.effectScope)();
438
+ scopeState = null;
439
+ }
440
+ function $watch() {
441
+ scopeState = scope.run(() => {
442
+ const $error = (0, import_vue5.computed)(() => {
443
+ return $invalid.value && !$pending.value && $dirty.value;
444
+ });
445
+ const $pending = (0, import_vue5.computed)(() => {
446
+ return Object.entries($rules.value).some(([key, rule]) => {
447
+ return rule.$pending;
448
+ });
449
+ });
450
+ const $invalid = (0, import_vue5.computed)(() => {
451
+ return Object.entries($rules.value).some(([key, ruleResult]) => {
452
+ return !ruleResult.$valid;
453
+ });
454
+ });
455
+ const $valid = (0, import_vue5.computed)(() => !$invalid.value);
456
+ return {
457
+ $error,
458
+ $pending,
459
+ $invalid,
460
+ $valid
461
+ };
462
+ });
463
+ }
464
+ const $rules = (0, import_vue5.ref)();
465
+ createReactiveRulesResult();
466
+ function $reset() {
467
+ $dirty.value = false;
468
+ }
469
+ function $touch() {
470
+ $dirty.value = true;
471
+ $validate();
472
+ }
473
+ async function $validate() {
474
+ try {
475
+ const results = await Promise.all(
476
+ Object.entries($rules.value).map(([key, rule]) => {
477
+ return rule.$validate();
478
+ })
479
+ );
480
+ return results.every((value) => !!value);
481
+ } catch (e) {
482
+ return false;
252
483
  }
253
- return unwrapRuleParameters(rule.value._params ?? []);
484
+ }
485
+ return (0, import_vue5.reactive)({
486
+ $dirty,
487
+ $anyDirty,
488
+ $invalid: scopeState.$invalid,
489
+ $error: scopeState.$error,
490
+ $pending: scopeState.$pending,
491
+ $valid: scopeState.$valid,
492
+ $value: state,
493
+ $rules,
494
+ $reset,
495
+ $touch,
496
+ $validate,
497
+ $unwatch,
498
+ $watch
254
499
  });
255
- (0, import_vue2.watch)(
256
- [state, $dirty, $params],
257
- async () => {
258
- const validator = $validator.value;
259
- let ruleResult = false;
260
- const resultOrPromise = validator(state.value, ...$params.value);
261
- if (resultOrPromise instanceof Promise) {
262
- if ($dirty.value) {
263
- try {
264
- $valid.value = true;
265
- $pending.value = true;
266
- const promiseResult = await resultOrPromise;
267
- ruleResult = promiseResult;
268
- } catch (e) {
269
- ruleResult = false;
270
- } finally {
271
- $pending.value = false;
272
- }
273
- }
274
- } else {
275
- ruleResult = resultOrPromise;
276
- }
277
- $valid.value = ruleResult;
278
- },
279
- { immediate: true, deep: true }
280
- );
281
- return (0, import_vue2.reactive)({
282
- $message,
283
- $active,
284
- $pending,
285
- $type,
286
- $valid,
287
- $validator,
288
- ...$params.value.length && { $params }
500
+ }
501
+
502
+ // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
503
+ var import_vue6 = require("vue");
504
+ function createReactiveCollectionStatus({
505
+ state,
506
+ rulesDef,
507
+ customMessages,
508
+ path,
509
+ storage
510
+ }) {
511
+ if (Array.isArray(state.value) && !rulesDef.value.$each) {
512
+ return null;
513
+ }
514
+ let $unwatchState = null;
515
+ const $fieldStatus = (0, import_vue6.ref)({});
516
+ const $eachStatus = storage.getCollectionsEntry(path);
517
+ createStatus();
518
+ $watch();
519
+ function createStatus() {
520
+ const { $each, ...otherFields } = rulesDef.value;
521
+ $fieldStatus.value = createReactiveFieldStatus({
522
+ state,
523
+ rulesDef: (0, import_vue6.toRef)(() => otherFields),
524
+ customMessages,
525
+ path,
526
+ storage
527
+ });
528
+ if (Array.isArray(state.value) && $each) {
529
+ $eachStatus.value = state.value.map((value, index) => {
530
+ const $path = `${path}.${index}`;
531
+ return createReactiveChildrenStatus({
532
+ state: (0, import_vue6.toRef)(() => value),
533
+ rulesDef: (0, import_vue6.toRef)(() => $each),
534
+ customMessages,
535
+ path: $path,
536
+ storage
537
+ });
538
+ }).filter((f) => !!f);
539
+ } else {
540
+ $eachStatus.value = [];
541
+ }
542
+ }
543
+ function $unwatch() {
544
+ if ($unwatchState) {
545
+ $unwatchState();
546
+ }
547
+ if ($fieldStatus.value) {
548
+ $fieldStatus.value.$unwatch();
549
+ }
550
+ if ($eachStatus.value) {
551
+ $eachStatus.value.forEach((element) => {
552
+ element.$unwatch();
553
+ });
554
+ }
555
+ }
556
+ function $watch() {
557
+ $unwatchState = (0, import_vue6.watch)(
558
+ state,
559
+ () => {
560
+ createStatus();
561
+ },
562
+ { deep: true, flush: "sync" }
563
+ );
564
+ }
565
+ return (0, import_vue6.reactive)({
566
+ ...$fieldStatus.value,
567
+ $each: $eachStatus,
568
+ $unwatch,
569
+ $watch
289
570
  });
290
571
  }
291
572
 
292
- // src/core/useRegle/useStateProperties/createReactiveStatus.ts
293
- function createReactiveNestedStatus(scopeRules, state, customRules) {
294
- const $fields = (0, import_vue3.reactive)(
295
- Object.fromEntries(
573
+ // src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
574
+ function createReactiveNestedStatus({
575
+ scopeRules,
576
+ state,
577
+ customMessages,
578
+ path = "",
579
+ rootRules,
580
+ storage
581
+ }) {
582
+ let scope = (0, import_vue7.effectScope)();
583
+ let scopeState;
584
+ let $unwatchFields;
585
+ function createReactiveFieldsStatus() {
586
+ $fields.value = Object.fromEntries(
296
587
  Object.entries(scopeRules.value).map(([statePropKey, statePropRules]) => {
297
588
  if (statePropRules) {
298
- const stateRef = (0, import_vue3.toRef)(state.value, statePropKey);
299
- const statePropRulesRef = (0, import_vue3.toRef)(() => statePropRules);
589
+ const stateRef = (0, import_vue7.toRef)(state.value, statePropKey);
590
+ const statePropRulesRef = (0, import_vue7.toRef)(() => statePropRules);
300
591
  return [
301
592
  statePropKey,
302
- createReactiveFieldStatus(stateRef, statePropRulesRef, customRules)
593
+ createReactiveChildrenStatus({
594
+ state: stateRef,
595
+ rulesDef: statePropRulesRef,
596
+ customMessages,
597
+ path: path ? `${path}.${statePropKey}` : statePropKey,
598
+ storage
599
+ })
303
600
  ];
304
601
  }
305
602
  return [];
306
603
  }).filter(
307
604
  (rule) => !!rule.length && rule[1] != null
308
605
  )
309
- )
310
- );
311
- const $dirty = (0, import_vue3.computed)(() => {
312
- return Object.entries($fields).every(([key, statusOrField]) => {
313
- return statusOrField.$dirty;
314
- });
315
- });
316
- const $anyDirty = (0, import_vue3.computed)(() => {
317
- return Object.entries($fields).some(([key, statusOrField]) => {
318
- return statusOrField.$dirty;
319
- });
320
- });
321
- const $invalid = (0, import_vue3.computed)(() => {
322
- return Object.entries($fields).some(([key, statusOrField]) => {
323
- return statusOrField.$invalid;
324
- });
325
- });
326
- const $error = (0, import_vue3.computed)(() => {
327
- return Object.entries($fields).some(([key, statusOrField]) => {
328
- return statusOrField.$error;
329
- });
330
- });
331
- const $pending = (0, import_vue3.computed)(() => {
332
- return Object.entries($fields).some(([key, statusOrField]) => {
333
- return statusOrField.$pending;
334
- });
335
- });
606
+ );
607
+ $watch();
608
+ }
609
+ const $fields = storage.getFieldsEntry(path);
610
+ createReactiveFieldsStatus();
336
611
  function $reset() {
337
- Object.entries($fields).forEach(([key, statusOrField]) => {
612
+ Object.entries($fields.value).forEach(([_, statusOrField]) => {
338
613
  statusOrField.$reset();
339
614
  });
340
615
  }
341
616
  function $touch() {
342
- Object.entries($fields).forEach(([key, statusOrField]) => {
617
+ Object.entries($fields.value).forEach(([_, statusOrField]) => {
343
618
  statusOrField.$touch();
344
619
  });
345
620
  }
346
- const $valid = (0, import_vue3.computed)(() => !$invalid.value);
347
- return (0, import_vue3.reactive)({
348
- $dirty,
349
- $anyDirty,
350
- $invalid,
351
- $valid,
352
- $error,
353
- $pending,
354
- $value: state,
621
+ async function $validate() {
622
+ try {
623
+ const results = await Promise.all(
624
+ Object.entries($fields.value).map(([_, statusOrField]) => {
625
+ return statusOrField.$validate();
626
+ })
627
+ );
628
+ return results.every((value) => !!value);
629
+ } catch (e) {
630
+ return false;
631
+ }
632
+ }
633
+ function $watch() {
634
+ if (rootRules) {
635
+ $unwatchFields = (0, import_vue7.watch)(
636
+ rootRules,
637
+ () => {
638
+ $unwatch();
639
+ createReactiveFieldsStatus();
640
+ },
641
+ { deep: true, flush: "post" }
642
+ );
643
+ }
644
+ scopeState = scope.run(() => {
645
+ const $dirty = (0, import_vue7.computed)(() => {
646
+ return Object.entries($fields.value).every(([key, statusOrField]) => {
647
+ return statusOrField.$dirty;
648
+ });
649
+ });
650
+ const $anyDirty = (0, import_vue7.computed)(() => {
651
+ return Object.entries($fields.value).some(([key, statusOrField]) => {
652
+ return statusOrField.$dirty;
653
+ });
654
+ });
655
+ const $invalid = (0, import_vue7.computed)(() => {
656
+ return Object.entries($fields.value).some(([key, statusOrField]) => {
657
+ return statusOrField.$invalid;
658
+ });
659
+ });
660
+ const $valid = (0, import_vue7.computed)(() => !$invalid.value);
661
+ const $error = (0, import_vue7.computed)(() => {
662
+ return Object.entries($fields.value).some(([key, statusOrField]) => {
663
+ return statusOrField.$error;
664
+ });
665
+ });
666
+ const $pending = (0, import_vue7.computed)(() => {
667
+ return Object.entries($fields.value).some(([key, statusOrField]) => {
668
+ return statusOrField.$pending;
669
+ });
670
+ });
671
+ return {
672
+ $dirty,
673
+ $anyDirty,
674
+ $invalid,
675
+ $valid,
676
+ $error,
677
+ $pending
678
+ };
679
+ });
680
+ }
681
+ function $unwatch() {
682
+ if ($fields.value) {
683
+ Object.entries($fields.value).forEach(([_, field]) => {
684
+ field.$unwatch();
685
+ });
686
+ }
687
+ if ($unwatchFields) {
688
+ $unwatchFields();
689
+ }
690
+ scope.stop();
691
+ scope = (0, import_vue7.effectScope)();
692
+ scopeState = null;
693
+ }
694
+ return (0, import_vue7.reactive)({
695
+ ...scopeState,
355
696
  $fields,
356
697
  $reset,
357
- $touch
698
+ $touch,
699
+ $validate,
700
+ $unwatch,
701
+ $watch
358
702
  });
359
703
  }
360
- function createReactiveFieldStatus(state, rulesDef, customRules) {
704
+ function createReactiveChildrenStatus({
705
+ state,
706
+ rulesDef,
707
+ customMessages,
708
+ path,
709
+ storage
710
+ }) {
361
711
  if (isCollectionRulesDef(rulesDef)) {
362
- const { $each, ...otherFields } = (0, import_vue3.toRefs)((0, import_vue3.reactive)(rulesDef.value));
363
- if (Array.isArray(state.value) && $each?.value) {
364
- const values = (0, import_vue3.toRefs)(state.value);
365
- return (0, import_vue3.reactive)({
366
- ...!isEmpty(otherFields) && createReactiveFieldStatus(state, (0, import_vue3.toRef)((0, import_vue3.reactive)(otherFields)), customRules),
367
- $each: values.map((value) => {
368
- return createReactiveFieldStatus(value, $each, customRules);
369
- }).filter((f) => !!f)
370
- });
371
- }
372
- return null;
373
- } else if (isNestedRulesDef(state, rulesDef)) {
374
- return createReactiveNestedStatus(rulesDef, state, customRules);
375
- } else if (isValidatorRulesDef(rulesDef)) {
376
- let $reset2 = function() {
377
- $dirty.value = false;
378
- }, $touch2 = function() {
379
- $dirty.value = true;
380
- };
381
- var $reset = $reset2, $touch = $touch2;
382
- const customMessages = customRules();
383
- const $dirty = (0, import_vue3.ref)(false);
384
- const $anyDirty = (0, import_vue3.computed)(() => $dirty.value);
385
- const $rules = (0, import_vue3.reactive)(
386
- Object.fromEntries(
387
- Object.entries(rulesDef.value).map(([ruleKey, rule]) => {
388
- if (rule) {
389
- const ruleRef = (0, import_vue3.toRef)(() => rule);
390
- return [
391
- ruleKey,
392
- createReactiveRuleStatus({
393
- $dirty,
394
- customMessages,
395
- rule: ruleRef,
396
- ruleKey,
397
- state
398
- })
399
- ];
400
- }
401
- return [];
402
- }).filter((ruleDef) => !!ruleDef.length)
403
- )
404
- );
405
- const $error = (0, import_vue3.computed)(() => {
406
- return $invalid.value && !$pending.value && $dirty.value;
407
- });
408
- const $pending = (0, import_vue3.computed)(() => {
409
- return Object.entries($rules).some(([key, rule]) => {
410
- return rule.$pending;
411
- });
412
- });
413
- const $invalid = (0, import_vue3.computed)(() => {
414
- return Object.entries($rules).some(([key, ruleResult]) => {
415
- return !ruleResult.$valid;
416
- });
712
+ return createReactiveCollectionStatus({
713
+ state,
714
+ rulesDef,
715
+ customMessages,
716
+ path,
717
+ storage
417
718
  });
418
- const $valid = (0, import_vue3.computed)(() => !$invalid.value);
419
- (0, import_vue3.watch)(state, () => {
420
- console.log(state);
421
- if (!$dirty.value) {
422
- $dirty.value = true;
423
- }
719
+ } else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) {
720
+ return createReactiveNestedStatus({
721
+ scopeRules: rulesDef,
722
+ state,
723
+ customMessages,
724
+ path,
725
+ storage
424
726
  });
425
- console.log(state);
426
- return (0, import_vue3.reactive)({
427
- $dirty,
428
- $anyDirty,
429
- $invalid,
430
- $error,
431
- $pending,
432
- $valid,
433
- $reset: $reset2,
434
- $touch: $touch2,
435
- $value: state,
436
- $rules
727
+ } else if (isValidatorRulesDef(rulesDef)) {
728
+ return createReactiveFieldStatus({
729
+ state,
730
+ rulesDef,
731
+ customMessages,
732
+ path,
733
+ storage
437
734
  });
438
735
  }
439
736
  return null;
440
737
  }
441
738
 
442
- // src/core/useRegle/useErrors.ts
443
- var import_vue4 = require("vue");
444
- function extractRulesErrors(rules) {
445
- return Object.entries(rules).map(([ruleKey, rule]) => {
446
- if (!rule.$valid) {
447
- return rule.$message;
739
+ // src/core/useStorage/useStorage.ts
740
+ var import_vue8 = require("vue");
741
+ function useStorage() {
742
+ const ruleDeclStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
743
+ const fieldsStorage = (0, import_vue8.shallowRef)(
744
+ /* @__PURE__ */ new Map()
745
+ );
746
+ const collectionsStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
747
+ const dirtyStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
748
+ const ruleStatusStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
749
+ function getFieldsEntry($path) {
750
+ const existingFields = fieldsStorage.value.get($path);
751
+ if (existingFields) {
752
+ return existingFields;
753
+ } else {
754
+ const $fields = (0, import_vue8.ref)({});
755
+ fieldsStorage.value.set($path, $fields);
756
+ return $fields;
448
757
  }
449
- return null;
450
- }).filter((msg) => !!msg);
451
- }
452
- function processFieldErrors(fieldStatus) {
453
- if (isNestedRulesStatus(fieldStatus)) {
454
- return extractNestedErrors(fieldStatus.$fields);
455
- } else if (isCollectionRulesStatus(fieldStatus)) {
456
- return {
457
- $errors: fieldStatus.$error ? extractRulesErrors(fieldStatus.$rules) : [],
458
- $each: fieldStatus.$each.map(processFieldErrors)
459
- };
460
- } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
461
- return extractRulesErrors(fieldStatus.$rules);
462
758
  }
463
- return [];
464
- }
465
- function extractCollectionError(field) {
466
- return field.$each.map(processFieldErrors);
467
- }
468
- function extractNestedErrors(fields) {
469
- return Object.fromEntries(
470
- Object.entries(fields).map(([fieldKey, fieldStatus]) => {
471
- if (isNestedRulesStatus(fieldStatus)) {
472
- return [fieldKey, extractNestedErrors(fieldStatus.$fields)];
473
- } else if (isCollectionRulesStatus(fieldStatus)) {
474
- return [
475
- fieldKey,
476
- {
477
- ...fieldStatus.$rules && { $errors: extractRulesErrors(fieldStatus.$rules) },
478
- $each: extractCollectionError(fieldStatus)
479
- }
480
- ];
481
- } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
482
- return [fieldKey, extractRulesErrors(fieldStatus.$rules)];
483
- }
484
- return [fieldKey, []];
485
- })
486
- );
487
- }
488
- function useErrors($regle) {
489
- const errors = (0, import_vue4.computed)(() => {
490
- return extractNestedErrors($regle.value.$fields);
491
- });
492
- return errors;
759
+ function getCollectionsEntry($path) {
760
+ const existingEach = collectionsStorage.value.get($path);
761
+ if (existingEach) {
762
+ return existingEach;
763
+ } else {
764
+ const $each = (0, import_vue8.ref)([]);
765
+ collectionsStorage.value.set($path, $each);
766
+ return $each;
767
+ }
768
+ }
769
+ function setDirtyEntry($path, dirty) {
770
+ dirtyStorage.value.set($path, dirty);
771
+ }
772
+ function getDirtyState(path) {
773
+ return dirtyStorage.value.get(path) ?? false;
774
+ }
775
+ function addRuleDeclEntry($path, options) {
776
+ ruleDeclStorage.value.set($path, options);
777
+ }
778
+ function checkRuleDeclEntry($path, newRules) {
779
+ const storedRulesDefs = ruleDeclStorage.value.get($path);
780
+ if (!storedRulesDefs)
781
+ return void 0;
782
+ const storedRules = storedRulesDefs;
783
+ const isValidCache = areRulesChanged(newRules, storedRules);
784
+ if (!isValidCache)
785
+ return { valid: false };
786
+ return { valid: true };
787
+ }
788
+ function areRulesChanged(newRules, storedRules) {
789
+ const storedRulesKeys = Object.keys(storedRules);
790
+ const newRulesKeys = Object.keys(newRules);
791
+ if (newRulesKeys.length !== storedRulesKeys.length)
792
+ return false;
793
+ const hasAllValidators = newRulesKeys.every((ruleKey) => storedRulesKeys.includes(ruleKey));
794
+ if (!hasAllValidators)
795
+ return false;
796
+ return newRulesKeys.every((ruleKey) => {
797
+ const newRuleElement = newRules[ruleKey];
798
+ const storedRuleElement = storedRules[ruleKey];
799
+ if (!storedRuleElement || !newRuleElement || typeof newRuleElement === "function" || typeof storedRuleElement === "function")
800
+ return false;
801
+ if (!newRuleElement._params)
802
+ return true;
803
+ return newRuleElement._params?.every((paramKey, index) => {
804
+ const storedParams = unwrapRuleParameters(storedRuleElement._params);
805
+ const newParams = unwrapRuleParameters(newRuleElement._params);
806
+ return storedParams?.[index] === newParams?.[index];
807
+ });
808
+ });
809
+ }
810
+ function trySetRuleStatusRef(path) {
811
+ const ruleStatus = ruleStatusStorage.value.get(path);
812
+ if (ruleStatus) {
813
+ return ruleStatus;
814
+ } else {
815
+ const $pending = (0, import_vue8.ref)(false);
816
+ const $valid = (0, import_vue8.ref)(true);
817
+ ruleStatusStorage.value.set(path, { $pending, $valid });
818
+ return { $pending, $valid };
819
+ }
820
+ }
821
+ return {
822
+ addRuleDeclEntry,
823
+ setDirtyEntry,
824
+ checkRuleDeclEntry,
825
+ getDirtyState,
826
+ trySetRuleStatusRef,
827
+ getFieldsEntry,
828
+ getCollectionsEntry
829
+ };
493
830
  }
494
831
 
495
832
  // src/core/useRegle/useStateProperties/useStateProperties.ts
496
833
  function useStateProperties(scopeRules, state, customRules) {
497
- const $regle = (0, import_vue5.ref)(createReactiveNestedStatus(scopeRules, state, customRules));
834
+ const storage = useStorage();
835
+ const $regle = (0, import_vue9.reactive)(
836
+ createReactiveNestedStatus({
837
+ rootRules: scopeRules,
838
+ scopeRules,
839
+ state,
840
+ customMessages: customRules(),
841
+ storage
842
+ })
843
+ );
498
844
  const errors = useErrors($regle);
499
845
  return { $regle, errors };
500
846
  }
@@ -502,17 +848,27 @@ function useStateProperties(scopeRules, state, customRules) {
502
848
  // src/core/useRegle/useRegle.ts
503
849
  function createUseRegleComposable(customRules) {
504
850
  function useRegle(state, rulesFactory) {
505
- const scopeRules = (0, import_vue6.isRef)(rulesFactory) ? rulesFactory : (0, import_vue6.computed)(rulesFactory);
506
- const initialState = (0, import_vue6.shallowRef)(structuredClone((0, import_vue6.toRaw)(state.value)));
851
+ const scopeRules = (0, import_vue10.isRef)(rulesFactory) ? rulesFactory : (0, import_vue10.computed)(rulesFactory);
852
+ const initialState = (0, import_vue10.shallowRef)(structuredClone((0, import_vue10.toRaw)(state.value)));
507
853
  const { $regle, errors } = useStateProperties(
508
854
  scopeRules,
509
855
  state,
510
856
  customRules
511
857
  );
858
+ function resetForm() {
859
+ state.value = (0, import_vue10.toRaw)(initialState.value);
860
+ $regle.$reset();
861
+ }
862
+ async function validateForm() {
863
+ $regle.$touch();
864
+ return await $regle.$validate();
865
+ }
512
866
  return {
513
867
  state,
514
868
  $regle,
515
- errors
869
+ errors,
870
+ resetForm,
871
+ validateForm
516
872
  };
517
873
  }
518
874
  return useRegle;