@regle/rules 1.13.0 → 1.14.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.
@@ -106,19 +106,27 @@ function withParams(rule, depsArray) {
106
106
  }
107
107
 
108
108
  /**
109
- * The applyIf operator is similar to requiredIf, but it can be used with any rule.
109
+ * The `applyIf` operator is similar to `requiredIf`, but it can be used with **any rule**.
110
110
  * It simplifies conditional rule declarations.
111
111
  *
112
+ * @param _condition - The condition to check (ref, getter, or value)
113
+ * @param rule - The rule to apply conditionally
114
+ * @returns A rule that only applies when the condition is truthy
115
+ *
112
116
  * @example
113
117
  * ```ts
118
+ * import { minLength, applyIf } from '@regle/rules';
119
+ *
114
120
  * const condition = ref(false);
115
- * const { r$ } = useRegle({name: ''}, {
121
+ *
122
+ * const { r$ } = useRegle({ name: '' }, {
116
123
  * name: {
117
124
  * minLength: applyIf(condition, minLength(6))
118
125
  * },
119
126
  * });
120
- *
121
127
  * ```
128
+ *
129
+ * @see {@link https://reglejs.dev/core-concepts/rules/rules-operators#applyif Documentation}
122
130
  */
123
131
  function applyIf(_condition, rule) {
124
132
  let _type;
@@ -162,12 +170,34 @@ function isFile(value) {
162
170
  }
163
171
 
164
172
  /**
165
- * This is the inverse of isFilled. It will check if the value is in any way empty (including arrays and objects)
173
+ * Checks if a value is empty in any way (including arrays and objects).
174
+ * This is the inverse of `isFilled`.
175
+ *
176
+ * `isEmpty` also acts as a type guard.
177
+ *
178
+ * By default, it considers an empty array as `true`. You can override this behavior with `considerEmptyArrayInvalid`.
166
179
  *
167
- * isEmpty also acts as a type guard.
180
+ * @param value - The target value to check
181
+ * @param considerEmptyArrayInvalid - When `false`, empty arrays are not considered empty (default: `true`)
182
+ * @returns `true` if the value is empty, `false` otherwise
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * import { createRule, type Maybe } from '@regle/core';
187
+ * import { isEmpty } from '@regle/rules';
188
+ *
189
+ * const rule = createRule({
190
+ * validator(value: Maybe<string>) {
191
+ * if (isEmpty(value)) {
192
+ * return true;
193
+ * }
194
+ * return check(value);
195
+ * },
196
+ * message: 'Error'
197
+ * })
198
+ * ```
168
199
  *
169
- * @param value - the target value
170
- * @param [considerEmptyArrayInvalid=true] - will return false if set to `false`. (default: `true`)
200
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isempty Documentation}
171
201
  */
172
202
  function isEmpty(value, considerEmptyArrayInvalid = true) {
173
203
  if (value === void 0 || value === null) return true;
@@ -186,7 +216,29 @@ function isObject(obj) {
186
216
  }
187
217
 
188
218
  /**
189
- * This is a useful helper that can check if the provided value is a Date, it is used internally for date rules. This can also check strings.
219
+ * Checks if the provided value is a valid Date. Used internally for date rules.
220
+ * Can also validate date strings.
221
+ *
222
+ * @param value - The value to check
223
+ * @returns `true` if the value is a valid Date or date string, `false` otherwise
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * import { createRule, type Maybe } from '@regle/core';
228
+ * import { isFilled, isDate } from '@regle/rules';
229
+ *
230
+ * const rule = createRule({
231
+ * validator(value: Maybe<string | Date>) {
232
+ * if (isFilled(value) && isDate(value)) {
233
+ * return checkDate(value);
234
+ * }
235
+ * return true;
236
+ * },
237
+ * message: 'Error'
238
+ * })
239
+ * ```
240
+ *
241
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isdate Documentation}
190
242
  */
191
243
  function isDate(value) {
192
244
  if (isEmpty(value)) return false;
@@ -205,7 +257,21 @@ function isDate(value) {
205
257
  }
206
258
 
207
259
  /**
208
- * This utility will coerce any string, number or Date value into a Date using the Date constructor.
260
+ * Coerces any string, number, or Date value into a `Date` using the `Date` constructor.
261
+ *
262
+ * @param argument - The value to convert to a Date
263
+ * @returns A new Date object (may be invalid if input cannot be parsed)
264
+ *
265
+ * @example
266
+ * ```ts
267
+ * import { toDate } from '@regle/rules';
268
+ *
269
+ * const date1 = toDate('2024-01-15'); // Date object
270
+ * const date2 = toDate(1705276800000); // Date from timestamp
271
+ * const date3 = toDate(new Date()); // Clone of Date
272
+ * ```
273
+ *
274
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#todate Documentation}
209
275
  */
210
276
  function toDate(argument) {
211
277
  const argStr = Object.prototype.toString.call(argument);
@@ -217,19 +283,63 @@ function toDate(argument) {
217
283
  }
218
284
 
219
285
  /**
220
- * This is almost a must have for optional fields. It checks if any value you provided is defined (including arrays and objects). You can base your validator result on this.
286
+ * Checks if any value you provide is defined (including arrays and objects).
287
+ * This is almost a must-have for optional fields when writing custom rules.
288
+ *
289
+ * `isFilled` also acts as a type guard.
290
+ *
291
+ * By default, it considers an empty array as `false`. You can override this behavior with `considerEmptyArrayInvalid`.
292
+ *
293
+ * @param value - The target value to check
294
+ * @param considerEmptyArrayInvalid - When `false`, empty arrays are considered filled (default: `true`)
295
+ * @returns `true` if the value is filled, `false` otherwise
221
296
  *
222
- * isFilled also acts as a type guard.
297
+ * @example
298
+ * ```ts
299
+ * import { createRule } from '@regle/core';
300
+ * import { isFilled } from '@regle/rules';
301
+ *
302
+ * const rule = createRule({
303
+ * validator(value: unknown) {
304
+ * if (isFilled(value)) {
305
+ * return check(value);
306
+ * }
307
+ * return true;
308
+ * },
309
+ * message: 'Error'
310
+ * })
311
+ * ```
223
312
  *
224
- * @param value - the target value
225
- * @param [considerEmptyArrayInvalid=true] - will return true if set to `false`. (default: `true`)
313
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isfilled Documentation}
226
314
  */
227
315
  function isFilled(value, considerEmptyArrayInvalid = true) {
228
316
  return !isEmpty(typeof value === "string" ? value.trim() : value, considerEmptyArrayInvalid);
229
317
  }
230
318
 
231
319
  /**
232
- * This is a type guard that will check if the passed value is a real Number. This also returns false for NaN, so this is better than typeof value === "number".
320
+ * Type guard that checks if the passed value is a real `Number`.
321
+ * Returns `false` for `NaN`, making it safer than `typeof value === "number"`.
322
+ *
323
+ * @param value - The value to check
324
+ * @returns `true` if value is a valid number (not `NaN`), `false` otherwise
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * import { createRule, type Maybe } from '@regle/core';
329
+ * import { isFilled, isNumber } from '@regle/rules';
330
+ *
331
+ * const rule = createRule({
332
+ * validator(value: Maybe<number | string>) {
333
+ * if (isFilled(value) && isNumber(value)) {
334
+ * return checkNumber(value);
335
+ * }
336
+ * return true;
337
+ * },
338
+ * message: 'Error'
339
+ * })
340
+ * ```
341
+ *
342
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isnumber Documentation}
233
343
  */
234
344
  function isNumber(value) {
235
345
  if (value == null) return false;
@@ -239,7 +349,30 @@ function isNumber(value) {
239
349
  }
240
350
 
241
351
  /**
242
- * This utility can take multiple regular expressions as arguments. It checks the input's validity and tests it against the provided regex patterns.
352
+ * Tests a value against one or more regular expressions.
353
+ * Returns `true` if the value is empty or matches **all** provided patterns.
354
+ *
355
+ * @param _value - The value to test
356
+ * @param expr - One or more RegExp patterns to match against
357
+ * @returns `true` if empty or all patterns match, `false` otherwise
358
+ *
359
+ * @example
360
+ * ```ts
361
+ * import { createRule, type Maybe } from '@regle/core';
362
+ * import { isFilled, matchRegex } from '@regle/rules';
363
+ *
364
+ * const regex = createRule({
365
+ * validator(value: Maybe<string>, regexps: RegExp[]) {
366
+ * if (isFilled(value)) {
367
+ * return matchRegex(value, ...regexps);
368
+ * }
369
+ * return true;
370
+ * },
371
+ * message: 'Error'
372
+ * })
373
+ * ```
374
+ *
375
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#matchregex Documentation}
243
376
  */
244
377
  function matchRegex(_value, ...expr) {
245
378
  if (isEmpty(_value)) return true;
@@ -251,7 +384,28 @@ function matchRegex(_value, ...expr) {
251
384
  }
252
385
 
253
386
  /**
254
- * This helper will return the length of any data type you pass. It works with strings, arrays, objects and numbers.
387
+ * Returns the length/size of any data type. Works with strings, arrays, objects and numbers.
388
+ *
389
+ * @param value - The value to get the size of
390
+ * @returns The length of strings/arrays, number of keys for objects, or the number itself
391
+ *
392
+ * @example
393
+ * ```ts
394
+ * import { createRule, type Maybe } from '@regle/core';
395
+ * import { isFilled, getSize } from '@regle/rules';
396
+ *
397
+ * const rule = createRule({
398
+ * validator(value: Maybe<string | Array<number>>) {
399
+ * if (isFilled(value)) {
400
+ * return getSize(value) > 6;
401
+ * }
402
+ * return true;
403
+ * },
404
+ * message: 'Error'
405
+ * })
406
+ * ```
407
+ *
408
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#getsize Documentation}
255
409
  */
256
410
  function getSize(value) {
257
411
  const _value = unref(value);
@@ -265,9 +419,25 @@ function getSize(value) {
265
419
  }
266
420
 
267
421
  /**
268
- * This utility converts any string (or number) into a number using the Number constructor.
422
+ * Converts any string (or number) into a number using the `Number` constructor.
423
+ *
424
+ * @param argument - The value to convert
425
+ * @returns The converted number (⚠️ Warning: returned value can be `NaN`)
269
426
  *
270
- * @returns ⚠️ Warning, returned value can be NaN
427
+ * @example
428
+ * ```ts
429
+ * import { toNumber, isNumber } from '@regle/rules';
430
+ *
431
+ * const num = toNumber('42'); // 42
432
+ * const invalid = toNumber('abc'); // NaN
433
+ *
434
+ * // Always check for NaN when using toNumber
435
+ * if (!isNaN(toNumber(value))) {
436
+ * // Safe to use as number
437
+ * }
438
+ * ```
439
+ *
440
+ * @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#tonumber Documentation}
271
441
  */
272
442
  function toNumber(argument) {
273
443
  if (typeof argument === "number") return argument;
@@ -282,7 +452,31 @@ function toNumber(argument) {
282
452
  }
283
453
 
284
454
  /**
285
- * The and operator combines multiple rules and validates successfully only if all provided rules are valid.
455
+ * The `and` operator combines multiple rules and validates successfully only if **all** provided rules are valid.
456
+ *
457
+ * @param rules - Two or more rules to combine
458
+ * @returns A combined rule that passes when all provided rules pass
459
+ *
460
+ * @example
461
+ * ```ts
462
+ * import { useRegle } from '@regle/core';
463
+ * import { and, startsWith, endsWith, withMessage } from '@regle/rules';
464
+ *
465
+ * const { r$ } = useRegle(
466
+ * { regex: '' },
467
+ * {
468
+ * regex: {
469
+ * myError: withMessage(
470
+ * and(startsWith('^'), endsWith('$')),
471
+ * ({ $params: [start, end] }) =>
472
+ * `Regex should start with "${start}" and end with "${end}"`
473
+ * ),
474
+ * },
475
+ * }
476
+ * );
477
+ * ```
478
+ *
479
+ * @see {@link https://reglejs.dev/core-concepts/rules/rules-operators#and Documentation}
286
480
  */
287
481
  function and(...rules) {
288
482
  const isAnyRuleAsync = rules.some((rule) => {
@@ -348,7 +542,31 @@ function and(...rules) {
348
542
  }
349
543
 
350
544
  /**
351
- * The or operator validates successfully if at least one of the provided rules is valid.
545
+ * The `or` operator validates successfully if **at least one** of the provided rules is valid.
546
+ *
547
+ * @param rules - Two or more rules to combine
548
+ * @returns A combined rule that passes when any of the provided rules pass
549
+ *
550
+ * @example
551
+ * ```ts
552
+ * import { useRegle } from '@regle/core';
553
+ * import { or, startsWith, endsWith, withMessage } from '@regle/rules';
554
+ *
555
+ * const { r$ } = useRegle(
556
+ * { regex: '' },
557
+ * {
558
+ * regex: {
559
+ * myError: withMessage(
560
+ * or(startsWith('^'), endsWith('$')),
561
+ * ({ $params: [start, end] }) =>
562
+ * `Field should start with "${start}" or end with "${end}"`
563
+ * ),
564
+ * },
565
+ * }
566
+ * );
567
+ * ```
568
+ *
569
+ * @see {@link https://reglejs.dev/core-concepts/rules/rules-operators#or Documentation}
352
570
  */
353
571
  function or(...rules) {
354
572
  const isAnyRuleAsync = rules.some((rule) => {
@@ -405,7 +623,33 @@ function or(...rules) {
405
623
  }
406
624
 
407
625
  /**
408
- * The not operator passes when the provided rule fails and fails when the rule passes. It can be combined with other rules.
626
+ * The `not` operator passes when the provided rule **fails** and fails when the rule **passes**.
627
+ * It can be combined with other rules.
628
+ *
629
+ * @param rule - The rule to negate
630
+ * @param message - Optional custom error message
631
+ * @returns A negated rule
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * import { useRegle } from '@regle/core';
636
+ * import { not, required, sameAs, withMessage } from '@regle/rules';
637
+ * import { ref } from 'vue';
638
+ *
639
+ * const form = ref({ oldPassword: '', newPassword: '' });
640
+ *
641
+ * const { r$ } = useRegle(form, {
642
+ * oldPassword: { required },
643
+ * newPassword: {
644
+ * notEqual: withMessage(
645
+ * not(sameAs(() => form.value.oldPassword)),
646
+ * 'Your new password must not be the same as your old password'
647
+ * ),
648
+ * },
649
+ * });
650
+ * ```
651
+ *
652
+ * @see {@link https://reglejs.dev/core-concepts/rules/rules-operators#not Documentation}
409
653
  */
410
654
  function not(rule, message) {
411
655
  let _type;
@@ -439,26 +683,39 @@ function not(rule, message) {
439
683
  else return newRule;
440
684
  }
441
685
 
686
+ function mapRulesWithCondition(condition, rules, trueCheck) {
687
+ return Object.entries(toValue(rules)).map(([key, rule]) => {
688
+ if (typeof rule === "function" || isObject(rule) && "_validator" in rule) return [key, applyIf(trueCheck ? condition : () => !toValue(condition), rule)];
689
+ return [key, rule];
690
+ });
691
+ }
442
692
  /**
443
- * The assignIf is a shorthand for conditional destructuring assignment.
444
- * It allows to apply multiple rules to a field conditionally.
693
+ * The `assignIf` is a shorthand for conditional destructuring assignment.
694
+ * It allows applying **multiple rules** to a field conditionally.
695
+ *
696
+ * @param _condition - The condition to check (ref, getter, or value)
697
+ * @param rules - An object of rules to apply conditionally
698
+ * @returns A computed ref containing the rules that only apply when the condition is truthy
445
699
  *
446
700
  * @example
447
701
  * ```ts
702
+ * import { required, email, minLength, assignIf } from '@regle/rules';
703
+ *
448
704
  * const condition = ref(false);
449
705
  *
450
706
  * const { r$ } = useRegle(ref({ name: '', email: '' }), {
451
707
  * name: assignIf(condition, { required, minLength: minLength(4) }),
452
708
  * email: { email },
453
- * })
709
+ * });
454
710
  * ```
711
+ *
712
+ * @see {@link https://reglejs.dev/core-concepts/rules/rules-operators#assignif Documentation}
455
713
  */
456
- function assignIf(_condition, rules) {
714
+ function assignIf(_condition, rules, otherwiseRules) {
457
715
  return computed(() => {
458
- return Object.fromEntries(Object.entries(toValue(rules)).map(([key, rule]) => {
459
- if (typeof rule === "function" || isObject(rule) && "_validator" in rule) return [key, applyIf(_condition, rule)];
460
- return [key, rule];
461
- }));
716
+ let trueRules = mapRulesWithCondition(_condition, rules, true);
717
+ let falseRules = otherwiseRules ? mapRulesWithCondition(_condition, otherwiseRules, false) : [];
718
+ return Object.fromEntries([...trueRules, ...falseRules]);
462
719
  });
463
720
  }
464
721
 
@@ -467,8 +724,23 @@ const alphaSymbolRegex = /^[\w.]+$/;
467
724
  /**
468
725
  * Allows only alphabetic characters.
469
726
  *
470
- * @param [options] - Alpha rules options
471
- * */
727
+ * @param options - Optional configuration for alpha validation
728
+ *
729
+ * @example
730
+ * ```ts
731
+ * import { alpha } from '@regle/rules';
732
+ *
733
+ * const { r$ } = useRegle({ name: '' }, {
734
+ * name: {
735
+ * alpha,
736
+ * // or with symbols allowed
737
+ * alpha: alpha({ allowSymbols: true }),
738
+ * },
739
+ * })
740
+ * ```
741
+ *
742
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#alpha Documentation}
743
+ */
472
744
  const alpha = createRule({
473
745
  type: "alpha",
474
746
  validator(value, options) {
@@ -484,7 +756,22 @@ const alphaNumSymbolRegex = /^[a-zA-Z0-9_]*$/;
484
756
  /**
485
757
  * Allows only alphanumeric characters.
486
758
  *
487
- * @param [options] - Alpha rules options
759
+ * @param options - Optional configuration for alphanumeric validation
760
+ *
761
+ * @example
762
+ * ```ts
763
+ * import { alphaNum } from '@regle/rules';
764
+ *
765
+ * const { r$ } = useRegle({ name: '' }, {
766
+ * name: {
767
+ * alphaNum,
768
+ * // or with symbols allowed
769
+ * alphaNum: alphaNum({ allowSymbols: true }),
770
+ * },
771
+ * })
772
+ * ```
773
+ *
774
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#alphanum Documentation}
488
775
  */
489
776
  const alphaNum = createRule({
490
777
  type: "alphaNum",
@@ -497,10 +784,30 @@ const alphaNum = createRule({
497
784
  });
498
785
 
499
786
  /**
500
- * Checks if a number is in specified bounds. min and max are both inclusive.
787
+ * Checks if a number is in specified bounds. `min` and `max` are both inclusive by default.
788
+ *
789
+ * @param min - The minimum limit
790
+ * @param max - The maximum limit
791
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }` for exclusive bounds)
792
+ *
793
+ * @example
794
+ * ```ts
795
+ * import { between } from '@regle/rules';
796
+ *
797
+ * const maxCount = ref(6);
798
+ *
799
+ * const { r$ } = useRegle({ count: 0 }, {
800
+ * count: {
801
+ * between: between(1, 6),
802
+ * // or with reactive max
803
+ * between: between(1, maxCount, { allowEqual: false }),
804
+ * // or with getter
805
+ * between: between(() => maxCount.value, 10)
806
+ * },
807
+ * })
808
+ * ```
501
809
  *
502
- * @param min - the minimum limit
503
- * @param max - the maximum limit
810
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#between Documentation}
504
811
  */
505
812
  const between = createRule({
506
813
  type: "between",
@@ -523,9 +830,23 @@ const between = createRule({
523
830
  });
524
831
 
525
832
  /**
526
- * Requires a value to be a native boolean type
833
+ * Requires a value to be a native boolean type.
834
+ *
835
+ * Mainly used for typing with `InferInput`.
836
+ *
837
+ * @example
838
+ * ```ts
839
+ * import { type InferInput } from '@regle/core';
840
+ * import { boolean } from '@regle/rules';
841
+ *
842
+ * const rules = {
843
+ * checkbox: { boolean },
844
+ * }
527
845
  *
528
- * Mainly used for typing
846
+ * const state = ref<InferInput<typeof rules>>({});
847
+ * ```
848
+ *
849
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#boolean Documentation}
529
850
  */
530
851
  const boolean = createRule({
531
852
  type: "boolean",
@@ -537,7 +858,18 @@ const boolean = createRule({
537
858
  });
538
859
 
539
860
  /**
540
- * Requires a boolean value to be true. This is useful for checkbox inputs.
861
+ * Requires a boolean value to be `true`. This is useful for checkbox inputs like "accept terms".
862
+ *
863
+ * @example
864
+ * ```ts
865
+ * import { checked } from '@regle/rules';
866
+ *
867
+ * const { r$ } = useRegle({ confirm: false }, {
868
+ * confirm: { checked },
869
+ * })
870
+ * ```
871
+ *
872
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#checked Documentation}
541
873
  */
542
874
  const checked = createRule({
543
875
  type: "checked",
@@ -551,7 +883,20 @@ const checked = createRule({
551
883
  /**
552
884
  * Checks if the string contains the specified substring.
553
885
  *
554
- * @param part - the part the value needs to contain
886
+ * @param part - The substring the value must contain
887
+ *
888
+ * @example
889
+ * ```ts
890
+ * import { contains } from '@regle/rules';
891
+ *
892
+ * const { r$ } = useRegle({ bestLib: '' }, {
893
+ * bestLib: {
894
+ * contains: contains('regle')
895
+ * },
896
+ * })
897
+ * ```
898
+ *
899
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#contains Documentation}
555
900
  */
556
901
  const contains = createRule({
557
902
  type: "contains",
@@ -565,9 +910,23 @@ const contains = createRule({
565
910
  });
566
911
 
567
912
  /**
568
- * Requires a value to be a native Date constructor
913
+ * Requires a value to be a native `Date` constructor.
914
+ *
915
+ * Mainly used for typing with `InferInput`.
916
+ *
917
+ * @example
918
+ * ```ts
919
+ * import { type InferInput } from '@regle/core';
920
+ * import { date } from '@regle/rules';
569
921
  *
570
- * Mainly used for typing
922
+ * const rules = {
923
+ * birthday: { date },
924
+ * }
925
+ *
926
+ * const state = ref<InferInput<typeof rules>>({});
927
+ * ```
928
+ *
929
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#date Documentation}
571
930
  */
572
931
  const date = createRule({
573
932
  type: "date",
@@ -590,8 +949,23 @@ function formatLocaleDate(date$1) {
590
949
  /**
591
950
  * Checks if the date is after the given parameter.
592
951
  *
593
- * @param after - the date to compare to
594
- * @param options - comparison options
952
+ * @param after - The date to compare to (can be a `Date`, string, ref, or getter)
953
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
954
+ *
955
+ * @example
956
+ * ```ts
957
+ * import { dateAfter } from '@regle/rules';
958
+ *
959
+ * const { r$ } = useRegle({ birthday: null as Date | null }, {
960
+ * birthday: {
961
+ * dateAfter: dateAfter(new Date()),
962
+ * // or with options
963
+ * dateAfter: dateAfter(new Date(), { allowEqual: false }),
964
+ * },
965
+ * })
966
+ * ```
967
+ *
968
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#dateafter Documentation}
595
969
  */
596
970
  const dateAfter = createRule({
597
971
  type: "dateAfter",
@@ -621,8 +995,23 @@ const dateAfter = createRule({
621
995
  /**
622
996
  * Checks if the date is before the given parameter.
623
997
  *
624
- * @param before - the date to compare to
625
- * @param options - comparison options
998
+ * @param before - The date to compare to (can be a `Date`, string, ref, or getter)
999
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1000
+ *
1001
+ * @example
1002
+ * ```ts
1003
+ * import { dateBefore } from '@regle/rules';
1004
+ *
1005
+ * const { r$ } = useRegle({ birthday: null as Date | null }, {
1006
+ * birthday: {
1007
+ * dateBefore: dateBefore(new Date()),
1008
+ * // or with options
1009
+ * dateBefore: dateBefore(new Date(), { allowEqual: false }),
1010
+ * },
1011
+ * })
1012
+ * ```
1013
+ *
1014
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#datebefore Documentation}
626
1015
  */
627
1016
  const dateBefore = createRule({
628
1017
  type: "dateBefore",
@@ -652,9 +1041,24 @@ const dateBefore = createRule({
652
1041
  /**
653
1042
  * Checks if the date falls between the specified bounds.
654
1043
  *
655
- * @param before - the minimum limit
656
- * @param after - the maximum limit
657
- * @param options - comparison options
1044
+ * @param before - The minimum date limit
1045
+ * @param after - The maximum date limit
1046
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1047
+ *
1048
+ * @example
1049
+ * ```ts
1050
+ * import { dateBetween } from '@regle/rules';
1051
+ *
1052
+ * const { r$ } = useRegle({ birthday: null as Date | null }, {
1053
+ * birthday: {
1054
+ * dateBetween: dateBetween(new Date(), new Date(2030, 3, 1)),
1055
+ * // or with options
1056
+ * dateBetween: dateBetween(new Date(), new Date(2030, 3, 1), { allowEqual: false }),
1057
+ * },
1058
+ * })
1059
+ * ```
1060
+ *
1061
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#datebetweeen Documentation}
658
1062
  */
659
1063
  const dateBetween = createRule({
660
1064
  type: "dateBetween",
@@ -672,6 +1076,17 @@ const dateBetween = createRule({
672
1076
  const decimalRegex = /^[-]?\d*(\.\d+)?$/;
673
1077
  /**
674
1078
  * Allows positive and negative decimal numbers.
1079
+ *
1080
+ * @example
1081
+ * ```ts
1082
+ * import { decimal } from '@regle/rules';
1083
+ *
1084
+ * const { r$ } = useRegle({ price: 0 }, {
1085
+ * price: { decimal },
1086
+ * })
1087
+ * ```
1088
+ *
1089
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#decimal Documentation}
675
1090
  */
676
1091
  const decimal = createRule({
677
1092
  type: "decimal",
@@ -685,6 +1100,17 @@ const decimal = createRule({
685
1100
  const emailRegex = /^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
686
1101
  /**
687
1102
  * Validates email addresses. Always verify on the server to ensure the address is real and not already in use.
1103
+ *
1104
+ * @example
1105
+ * ```ts
1106
+ * import { email } from '@regle/rules';
1107
+ *
1108
+ * const { r$ } = useRegle({ email: '' }, {
1109
+ * email: { email },
1110
+ * })
1111
+ * ```
1112
+ *
1113
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#email Documentation}
688
1114
  */
689
1115
  const email = createRule({
690
1116
  type: "email",
@@ -698,7 +1124,18 @@ const email = createRule({
698
1124
  /**
699
1125
  * Checks if the string ends with the specified substring.
700
1126
  *
701
- * @param part - the value the field must end with
1127
+ * @param part - The substring the value must end with
1128
+ *
1129
+ * @example
1130
+ * ```ts
1131
+ * import { endsWith } from '@regle/rules';
1132
+ *
1133
+ * const { r$ } = useRegle({ firstName: '' }, {
1134
+ * firstName: { endsWith: endsWith('foo') },
1135
+ * })
1136
+ * ```
1137
+ *
1138
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#endswith Documentation}
702
1139
  */
703
1140
  const endsWith = createRule({
704
1141
  type: "endsWith",
@@ -712,9 +1149,28 @@ const endsWith = createRule({
712
1149
  });
713
1150
 
714
1151
  /**
715
- * Requires the input value to have a strict specified length, inclusive. Works with arrays, objects and strings.
1152
+ * Requires the input value to have a strict specified length. Works with arrays, objects and strings.
1153
+ *
1154
+ * @param count - The exact required length
716
1155
  *
717
- * @param count - the required length
1156
+ * @example
1157
+ * ```ts
1158
+ * import { exactLength } from '@regle/rules';
1159
+ *
1160
+ * const exactValue = ref(6);
1161
+ *
1162
+ * const { r$ } = useRegle({ name: '' }, {
1163
+ * name: {
1164
+ * exactLength: exactLength(6),
1165
+ * // or with reactive value
1166
+ * exactLength: exactLength(exactValue),
1167
+ * // or with getter
1168
+ * exactLength: exactLength(() => exactValue.value)
1169
+ * },
1170
+ * })
1171
+ * ```
1172
+ *
1173
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#exactlength Documentation}
718
1174
  */
719
1175
  const exactLength = createRule({
720
1176
  type: "exactLength",
@@ -733,6 +1189,27 @@ const exactLength = createRule({
733
1189
 
734
1190
  /**
735
1191
  * Requires a field to have a strict numeric value.
1192
+ *
1193
+ * @param count - The exact required numeric value
1194
+ *
1195
+ * @example
1196
+ * ```ts
1197
+ * import { exactValue } from '@regle/rules';
1198
+ *
1199
+ * const exactCount = ref(6);
1200
+ *
1201
+ * const { r$ } = useRegle({ count: 0 }, {
1202
+ * count: {
1203
+ * exactValue: exactValue(6),
1204
+ * // or with reactive value
1205
+ * exactValue: exactValue(exactCount),
1206
+ * // or with getter
1207
+ * exactValue: exactValue(() => exactCount.value)
1208
+ * },
1209
+ * })
1210
+ * ```
1211
+ *
1212
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#exactvalue Documentation}
736
1213
  */
737
1214
  const exactValue = createRule({
738
1215
  type: "exactValue",
@@ -751,7 +1228,18 @@ const exactValue = createRule({
751
1228
 
752
1229
  const hexadecimalRegex = /^[a-fA-F0-9]*$/;
753
1230
  /**
754
- * Allows only hexadecimal values.
1231
+ * Validates hexadecimal values.
1232
+ *
1233
+ * @example
1234
+ * ```ts
1235
+ * import { hexadecimal } from '@regle/rules';
1236
+ *
1237
+ * const { r$ } = useRegle({ hexadecimal: '' }, {
1238
+ * hexadecimal: { hexadecimal },
1239
+ * })
1240
+ * ```
1241
+ *
1242
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#hexadecimal Documentation}
755
1243
  */
756
1244
  const hexadecimal = createRule({
757
1245
  type: "hexadecimal",
@@ -765,6 +1253,17 @@ const hexadecimal = createRule({
765
1253
  const integerRegex = /(^[0-9]*$)|(^-[0-9]+$)/;
766
1254
  /**
767
1255
  * Allows only integers (positive and negative).
1256
+ *
1257
+ * @example
1258
+ * ```ts
1259
+ * import { integer } from '@regle/rules';
1260
+ *
1261
+ * const { r$ } = useRegle({ count: 0 }, {
1262
+ * count: { integer },
1263
+ * })
1264
+ * ```
1265
+ *
1266
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#integer Documentation}
768
1267
  */
769
1268
  const integer = createRule({
770
1269
  type: "integer",
@@ -783,7 +1282,18 @@ function nibbleValid(nibble) {
783
1282
  return numeric$1 >= 0 && numeric$1 <= 255;
784
1283
  }
785
1284
  /**
786
- * Validates IPv4 addresses in dotted decimal notation 127.0.0.1.
1285
+ * Validates IPv4 addresses in dotted decimal notation (e.g., `127.0.0.1`).
1286
+ *
1287
+ * @example
1288
+ * ```ts
1289
+ * import { ipv4Address } from '@regle/rules';
1290
+ *
1291
+ * const { r$ } = useRegle({ address: '' }, {
1292
+ * address: { ipv4Address },
1293
+ * })
1294
+ * ```
1295
+ *
1296
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#ipv4address Documentation}
787
1297
  */
788
1298
  const ipv4Address = createRule({
789
1299
  type: "ipv4Address",
@@ -797,7 +1307,20 @@ const ipv4Address = createRule({
797
1307
  });
798
1308
 
799
1309
  /**
800
- * Allow only one possible literal value
1310
+ * Allow only one possible literal value.
1311
+ *
1312
+ * @param literal - The literal value to match
1313
+ *
1314
+ * @example
1315
+ * ```ts
1316
+ * import { literal } from '@regle/rules';
1317
+ *
1318
+ * const { r$ } = useRegle({ status: '' }, {
1319
+ * status: { literal: literal('active') },
1320
+ * })
1321
+ * ```
1322
+ *
1323
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#literal Documentation}
801
1324
  */
802
1325
  function literal(literal$1) {
803
1326
  return withMessage(withParams((value, literal$2) => {
@@ -807,9 +1330,24 @@ function literal(literal$1) {
807
1330
  }
808
1331
 
809
1332
  /**
810
- * Validates MAC addresses. Call as a function to specify a custom separator (e.g., ':' or an empty string for 00ff1122334455).
1333
+ * Validates MAC addresses. Call as a function to specify a custom separator (e.g., `':'` or an empty string for `00ff1122334455`).
1334
+ *
1335
+ * @param separator - The custom separator (default: `':'`)
1336
+ *
1337
+ * @example
1338
+ * ```ts
1339
+ * import { macAddress } from '@regle/rules';
811
1340
  *
812
- * @param separator - the custom separator
1341
+ * const { r$ } = useRegle({ address: '' }, {
1342
+ * address: {
1343
+ * macAddress,
1344
+ * // or with custom separator
1345
+ * macAddress: macAddress('-')
1346
+ * },
1347
+ * })
1348
+ * ```
1349
+ *
1350
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#macaddress Documentation}
813
1351
  */
814
1352
  const macAddress = createRule({
815
1353
  type: "macAddress",
@@ -826,17 +1364,36 @@ const hexValid = (hex) => hex.toLowerCase().match(/^[0-9a-f]{2}$/);
826
1364
  /**
827
1365
  * Requires the input value to have a maximum specified length, inclusive. Works with arrays, objects and strings.
828
1366
  *
829
- * @param max - the maximum length
830
- * @param options - comparison options
1367
+ * @param max - The maximum length
1368
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1369
+ *
1370
+ * @example
1371
+ * ```ts
1372
+ * import { maxLength } from '@regle/rules';
1373
+ *
1374
+ * const maxValue = ref(6);
1375
+ *
1376
+ * const { r$ } = useRegle({ name: '' }, {
1377
+ * name: {
1378
+ * maxLength: maxLength(6),
1379
+ * // or with reactive value
1380
+ * maxLength: maxLength(maxValue),
1381
+ * // or with getter
1382
+ * maxLength: maxLength(() => maxValue.value)
1383
+ * },
1384
+ * })
1385
+ * ```
1386
+ *
1387
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#maxlength Documentation}
831
1388
  */
832
1389
  const maxLength = createRule({
833
1390
  type: "maxLength",
834
- validator: (value, count, options) => {
1391
+ validator: (value, max, options) => {
835
1392
  const { allowEqual = true } = options ?? {};
836
- if (isFilled(value, false) && isFilled(count)) {
837
- if (isNumber(count)) if (allowEqual) return getSize(value) <= count;
838
- else return getSize(value) < count;
839
- console.warn(`[maxLength] Value or parameter isn't a number, got value: ${value}, parameter: ${count}`);
1393
+ if (isFilled(value, false) && isFilled(max)) {
1394
+ if (isNumber(max)) if (allowEqual) return getSize(value) <= max;
1395
+ else return getSize(value) < max;
1396
+ console.warn(`[maxLength] Value or parameter isn't a number, got value: ${value}, parameter: ${max}`);
840
1397
  return false;
841
1398
  }
842
1399
  return true;
@@ -850,74 +1407,131 @@ const maxLength = createRule({
850
1407
  /**
851
1408
  * Requires a field to have a specified maximum numeric value.
852
1409
  *
853
- * @param max - the maximum value
854
- * @param options - comparison options
1410
+ * @param max - The maximum value
1411
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1412
+ *
1413
+ * @example
1414
+ * ```ts
1415
+ * import { maxValue } from '@regle/rules';
1416
+ *
1417
+ * const maxCount = ref(6);
1418
+ *
1419
+ * const { r$ } = useRegle({ count: 0 }, {
1420
+ * count: {
1421
+ * maxValue: maxValue(6),
1422
+ * // or with options
1423
+ * maxValue: maxValue(maxCount, { allowEqual: false }),
1424
+ * // or with getter
1425
+ * maxValue: maxValue(() => maxCount.value)
1426
+ * },
1427
+ * })
1428
+ * ```
1429
+ *
1430
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#maxvalue Documentation}
855
1431
  */
856
1432
  const maxValue = createRule({
857
1433
  type: "maxValue",
858
- validator: (value, count, options) => {
1434
+ validator: (value, max, options) => {
859
1435
  const { allowEqual = true } = options ?? {};
860
- if (isFilled(value) && isFilled(count)) {
861
- if (!isNaN(toNumber(value)) && !isNaN(toNumber(count))) if (allowEqual) return toNumber(value) <= toNumber(count);
862
- else return toNumber(value) < toNumber(count);
863
- console.warn(`[maxValue] Value or parameter isn't a number, got value: ${value}, parameter: ${count}`);
1436
+ if (isFilled(value) && isFilled(max)) {
1437
+ if (!isNaN(toNumber(value)) && !isNaN(toNumber(max))) if (allowEqual) return toNumber(value) <= toNumber(max);
1438
+ else return toNumber(value) < toNumber(max);
1439
+ console.warn(`[maxValue] Value or parameter isn't a number, got value: ${value}, parameter: ${max}`);
864
1440
  return false;
865
1441
  }
866
1442
  return true;
867
1443
  },
868
- message: ({ $params: [count, options] }) => {
1444
+ message: ({ $params: [max, options] }) => {
869
1445
  const { allowEqual = true } = options ?? {};
870
- if (allowEqual) return `The value must be less than or equal to ${count}`;
871
- else return `The value must be less than ${count}`;
1446
+ if (allowEqual) return `The value must be less than or equal to ${max}`;
1447
+ else return `The value must be less than ${max}`;
872
1448
  }
873
1449
  });
874
1450
 
875
1451
  /**
876
1452
  * Requires the input value to have a minimum specified length, inclusive. Works with arrays, objects and strings.
877
1453
  *
878
- * @param min - the minimum value
879
- * @param options - comparison options
1454
+ * @param min - The minimum length
1455
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1456
+ *
1457
+ * @example
1458
+ * ```ts
1459
+ * import { minLength } from '@regle/rules';
1460
+ *
1461
+ * const minValue = ref(6);
1462
+ *
1463
+ * const { r$ } = useRegle({ name: '' }, {
1464
+ * name: {
1465
+ * minLength: minLength(6),
1466
+ * // or with reactive value
1467
+ * minLength: minLength(minValue),
1468
+ * // or with getter
1469
+ * minLength: minLength(() => minValue.value)
1470
+ * },
1471
+ * })
1472
+ * ```
1473
+ *
1474
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#minlength Documentation}
880
1475
  */
881
1476
  const minLength = createRule({
882
1477
  type: "minLength",
883
- validator: (value, count, options) => {
1478
+ validator: (value, min, options) => {
884
1479
  const { allowEqual = true } = options ?? {};
885
- if (isFilled(value, false) && isFilled(count)) {
886
- if (isNumber(count)) if (allowEqual) return getSize(value) >= count;
887
- else return getSize(value) > count;
888
- console.warn(`[minLength] Parameter isn't a number, got parameter: ${count}`);
1480
+ if (isFilled(value, false) && isFilled(min)) {
1481
+ if (isNumber(min)) if (allowEqual) return getSize(value) >= min;
1482
+ else return getSize(value) > min;
1483
+ console.warn(`[minLength] Parameter isn't a number, got parameter: ${min}`);
889
1484
  return false;
890
1485
  }
891
1486
  return true;
892
1487
  },
893
- message: ({ $value, $params: [count] }) => {
894
- if (Array.isArray($value)) return `The list should have at least ${count} items`;
895
- return `The value length should be at least ${count}`;
1488
+ message: ({ $value, $params: [min] }) => {
1489
+ if (Array.isArray($value)) return `The list should have at least ${min} items`;
1490
+ return `The value length should be at least ${min}`;
896
1491
  }
897
1492
  });
898
1493
 
899
1494
  /**
900
1495
  * Requires a field to have a specified minimum numeric value.
901
1496
  *
902
- * @param count - the minimum count
903
- * @param options - comparison options
1497
+ * @param min - The minimum value
1498
+ * @param options - Optional configuration (e.g., `{ allowEqual: false }`)
1499
+ *
1500
+ * @example
1501
+ * ```ts
1502
+ * import { minValue } from '@regle/rules';
1503
+ *
1504
+ * const minCount = ref(6);
1505
+ *
1506
+ * const { r$ } = useRegle({ count: 0 }, {
1507
+ * count: {
1508
+ * minValue: minValue(6),
1509
+ * // or with options
1510
+ * minValue: minValue(minCount, { allowEqual: false }),
1511
+ * // or with getter
1512
+ * minValue: minValue(() => minCount.value)
1513
+ * },
1514
+ * })
1515
+ * ```
1516
+ *
1517
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#minvalue Documentation}
904
1518
  */
905
1519
  const minValue = createRule({
906
1520
  type: "minValue",
907
- validator: (value, count, options) => {
1521
+ validator: (value, min, options) => {
908
1522
  const { allowEqual = true } = options ?? {};
909
- if (isFilled(value) && isFilled(count)) {
910
- if (!isNaN(toNumber(value)) && !isNaN(toNumber(count))) if (allowEqual) return toNumber(value) >= toNumber(count);
911
- else return toNumber(value) > toNumber(count);
912
- console.warn(`[minValue] Value or parameter isn't a number, got value: ${value}, parameter: ${count}`);
1523
+ if (isFilled(value) && isFilled(min)) {
1524
+ if (!isNaN(toNumber(value)) && !isNaN(toNumber(min))) if (allowEqual) return toNumber(value) >= toNumber(min);
1525
+ else return toNumber(value) > toNumber(min);
1526
+ console.warn(`[minValue] Value or parameter isn't a number, got value: ${value}, parameter: ${min}`);
913
1527
  return false;
914
1528
  }
915
1529
  return true;
916
1530
  },
917
- message: ({ $params: [count, options] }) => {
1531
+ message: ({ $params: [min, options] }) => {
918
1532
  const { allowEqual = true } = options ?? {};
919
- if (allowEqual) return `The value must be greater than or equal to ${count}`;
920
- else return `The value must be greater than ${count}`;
1533
+ if (allowEqual) return `The value must be greater than or equal to ${min}`;
1534
+ else return `The value must be greater than ${min}`;
921
1535
  }
922
1536
  });
923
1537
 
@@ -928,7 +1542,24 @@ function getValidEnumValues(obj) {
928
1542
  return Object.values(filtered);
929
1543
  }
930
1544
  /**
931
- * Validate against a native Typescript enum value.
1545
+ * Validate against a native TypeScript enum value. Similar to Zod's `nativeEnum`.
1546
+ *
1547
+ * @param enumLike - The TypeScript enum to validate against
1548
+ *
1549
+ * @example
1550
+ * ```ts
1551
+ * import { nativeEnum } from '@regle/rules';
1552
+ *
1553
+ * enum Foo {
1554
+ * Bar, Baz
1555
+ * }
1556
+ *
1557
+ * const { r$ } = useRegle({ type: '' }, {
1558
+ * type: { nativeEnum: nativeEnum(Foo) },
1559
+ * })
1560
+ * ```
1561
+ *
1562
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#nativeenum Documentation}
932
1563
  */
933
1564
  function nativeEnum(enumLike) {
934
1565
  return withMessage(withParams((value, enumLike$1) => {
@@ -938,9 +1569,23 @@ function nativeEnum(enumLike) {
938
1569
  }
939
1570
 
940
1571
  /**
941
- * Requires a value to be a native number type
1572
+ * Requires a value to be a native number type.
1573
+ *
1574
+ * Mainly used for typing with `InferInput`.
942
1575
  *
943
- * Mainly used for typing
1576
+ * @example
1577
+ * ```ts
1578
+ * import { type InferInput } from '@regle/core';
1579
+ * import { number } from '@regle/rules';
1580
+ *
1581
+ * const rules = {
1582
+ * count: { number },
1583
+ * }
1584
+ *
1585
+ * const state = ref<InferInput<typeof rules>>({});
1586
+ * ```
1587
+ *
1588
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#number Documentation}
944
1589
  */
945
1590
  const number = createRule({
946
1591
  type: "number",
@@ -954,6 +1599,17 @@ const number = createRule({
954
1599
  const numericRegex = /^\d*(\.\d+)?$/;
955
1600
  /**
956
1601
  * Allows only numeric values (including numeric strings).
1602
+ *
1603
+ * @example
1604
+ * ```ts
1605
+ * import { numeric } from '@regle/rules';
1606
+ *
1607
+ * const { r$ } = useRegle({ count: 0 }, {
1608
+ * count: { numeric },
1609
+ * })
1610
+ * ```
1611
+ *
1612
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#numeric Documentation}
957
1613
  */
958
1614
  const numeric = createRule({
959
1615
  type: "numeric",
@@ -966,6 +1622,21 @@ const numeric = createRule({
966
1622
 
967
1623
  /**
968
1624
  * Allow only one of the values from a fixed Array of possible entries.
1625
+ *
1626
+ * @param options - Array of allowed values
1627
+ *
1628
+ * @example
1629
+ * ```ts
1630
+ * import { oneOf } from '@regle/rules';
1631
+ *
1632
+ * const { r$ } = useRegle({ aliment: 'Fish' }, {
1633
+ * aliment: {
1634
+ * oneOf: oneOf(['Fish', 'Meat', 'Bone'])
1635
+ * },
1636
+ * })
1637
+ * ```
1638
+ *
1639
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#oneof Documentation}
969
1640
  */
970
1641
  const oneOf = createRule({
971
1642
  type: "oneOf",
@@ -978,6 +1649,23 @@ const oneOf = createRule({
978
1649
 
979
1650
  /**
980
1651
  * Checks if the value matches one or more regular expressions.
1652
+ *
1653
+ * @param regexp - A single RegExp or an array of RegExp patterns
1654
+ *
1655
+ * @example
1656
+ * ```ts
1657
+ * import { regex } from '@regle/rules';
1658
+ *
1659
+ * const { r$ } = useRegle({ name: '' }, {
1660
+ * name: {
1661
+ * regex: regex(/^foo/),
1662
+ * // or with multiple patterns
1663
+ * regex: regex([/^bar/, /baz$/]),
1664
+ * },
1665
+ * })
1666
+ * ```
1667
+ *
1668
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#regex Documentation}
981
1669
  */
982
1670
  const regex = createRule({
983
1671
  type: "regex",
@@ -990,6 +1678,17 @@ const regex = createRule({
990
1678
 
991
1679
  /**
992
1680
  * Requires non-empty data. Checks for empty arrays and strings containing only whitespaces.
1681
+ *
1682
+ * @example
1683
+ * ```ts
1684
+ * import { required } from '@regle/rules';
1685
+ *
1686
+ * const { r$ } = useRegle({ name: '' }, {
1687
+ * name: { required },
1688
+ * })
1689
+ * ```
1690
+ *
1691
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#required Documentation}
993
1692
  */
994
1693
  const required = createRule({
995
1694
  type: "required",
@@ -1000,9 +1699,27 @@ const required = createRule({
1000
1699
  });
1001
1700
 
1002
1701
  /**
1003
- * Requires non-empty data, only if provided data property, ref, or a function resolves to true.
1702
+ * Requires non-empty data, only if provided data property, ref, or a function resolves to `true`.
1703
+ *
1704
+ * @param condition - The condition to enable the required rule (can be a ref, getter, or value)
1705
+ *
1706
+ * @example
1707
+ * ```ts
1708
+ * import { requiredIf } from '@regle/rules';
1709
+ *
1710
+ * const form = ref({ name: '', condition: false });
1711
+ * const conditionRef = ref(false);
1712
+ *
1713
+ * const { r$ } = useRegle(form, {
1714
+ * name: {
1715
+ * required: requiredIf(() => form.value.condition),
1716
+ * // or with a ref
1717
+ * required: requiredIf(conditionRef),
1718
+ * },
1719
+ * })
1720
+ * ```
1004
1721
  *
1005
- * @param condition - the condition to enable the required rule
1722
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#requiredif Documentation}
1006
1723
  */
1007
1724
  const requiredIf = createRule({
1008
1725
  type: "required",
@@ -1017,9 +1734,27 @@ const requiredIf = createRule({
1017
1734
  });
1018
1735
 
1019
1736
  /**
1020
- * Requires non-empty data, only if provided data property, ref, or a function resolves to false.
1737
+ * Requires non-empty data, only if provided data property, ref, or a function resolves to `false`.
1738
+ *
1739
+ * @param condition - The condition to disable the required rule (can be a ref, getter, or value)
1740
+ *
1741
+ * @example
1742
+ * ```ts
1743
+ * import { requiredUnless } from '@regle/rules';
1744
+ *
1745
+ * const form = ref({ name: '', condition: false });
1746
+ * const conditionRef = ref(false);
1747
+ *
1748
+ * const { r$ } = useRegle(form, {
1749
+ * name: {
1750
+ * required: requiredUnless(() => form.value.condition),
1751
+ * // or with a ref
1752
+ * required: requiredUnless(conditionRef)
1753
+ * },
1754
+ * })
1755
+ * ```
1021
1756
  *
1022
- * @param condition - the condition to disable the required rule
1757
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#requiredunless Documentation}
1023
1758
  */
1024
1759
  const requiredUnless = createRule({
1025
1760
  type: "required",
@@ -1034,7 +1769,28 @@ const requiredUnless = createRule({
1034
1769
  });
1035
1770
 
1036
1771
  /**
1037
- * Checks if the value matches the specified property or ref.
1772
+ * Checks if the value matches the specified property or ref. Useful for password confirmation fields.
1773
+ *
1774
+ * @param target - The target value to compare against (can be a ref or getter)
1775
+ * @param otherName - Optional name for the other field (used in error message)
1776
+ *
1777
+ * @example
1778
+ * ```ts
1779
+ * import { sameAs } from '@regle/rules';
1780
+ *
1781
+ * const form = ref({
1782
+ * password: '',
1783
+ * confirmPassword: '',
1784
+ * });
1785
+ *
1786
+ * const { r$ } = useRegle(form, {
1787
+ * confirmPassword: {
1788
+ * sameAs: sameAs(() => form.value.password),
1789
+ * }
1790
+ * })
1791
+ * ```
1792
+ *
1793
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#sameas Documentation}
1038
1794
  */
1039
1795
  const sameAs = createRule({
1040
1796
  type: "sameAs",
@@ -1050,7 +1806,20 @@ const sameAs = createRule({
1050
1806
  /**
1051
1807
  * Checks if the string starts with the specified substring.
1052
1808
  *
1053
- * @private part - the value the field must start with
1809
+ * @param part - The substring the value must start with
1810
+ *
1811
+ * @example
1812
+ * ```ts
1813
+ * import { startsWith } from '@regle/rules';
1814
+ *
1815
+ * const { r$ } = useRegle({ bestLib: '' }, {
1816
+ * bestLib: {
1817
+ * startsWith: startsWith('regle')
1818
+ * },
1819
+ * })
1820
+ * ```
1821
+ *
1822
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#startswith Documentation}
1054
1823
  */
1055
1824
  const startsWith = createRule({
1056
1825
  type: "startsWith",
@@ -1064,9 +1833,23 @@ const startsWith = createRule({
1064
1833
  });
1065
1834
 
1066
1835
  /**
1067
- * Requires a value to be a native string type
1836
+ * Requires a value to be a native string type.
1837
+ *
1838
+ * Mainly used for typing with `InferInput`.
1068
1839
  *
1069
- * Mainly used for typing
1840
+ * @example
1841
+ * ```ts
1842
+ * import { type InferInput } from '@regle/core';
1843
+ * import { string } from '@regle/rules';
1844
+ *
1845
+ * const rules = {
1846
+ * firstName: { string },
1847
+ * }
1848
+ *
1849
+ * const state = ref<InferInput<typeof rules>>({});
1850
+ * ```
1851
+ *
1852
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#string Documentation}
1070
1853
  */
1071
1854
  const string = createRule({
1072
1855
  type: "string",
@@ -1081,6 +1864,21 @@ const string = createRule({
1081
1864
  * Define the input type of a rule. No runtime validation.
1082
1865
  *
1083
1866
  * Override any input type set by other rules.
1867
+ *
1868
+ * @example
1869
+ * ```ts
1870
+ * import { type InferInput } from '@regle/core';
1871
+ * import { type } from '@regle/rules';
1872
+ *
1873
+ * const rules = {
1874
+ * firstName: { type: type<string>() },
1875
+ * status: { type: type<'active' | 'inactive'>() },
1876
+ * }
1877
+ *
1878
+ * const state = ref<InferInput<typeof rules>>({});
1879
+ * ```
1880
+ *
1881
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#type Documentation}
1084
1882
  */
1085
1883
  function type() {
1086
1884
  return (() => true);
@@ -1092,6 +1890,17 @@ function type() {
1092
1890
  const urlRegex = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i;
1093
1891
  /**
1094
1892
  * Validates URLs.
1893
+ *
1894
+ * @example
1895
+ * ```ts
1896
+ * import { url } from '@regle/rules';
1897
+ *
1898
+ * const { r$ } = useRegle({ bestUrl: '' }, {
1899
+ * bestUrl: { url },
1900
+ * })
1901
+ * ```
1902
+ *
1903
+ * @see {@link https://reglejs.dev/core-concepts/rules/built-in-rules#url Documentation}
1095
1904
  */
1096
1905
  const url = createRule({
1097
1906
  type: "url",