vuelidify 2.1.2 → 2.2.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/README.md +39 -23
- package/dist/index.d.ts +143 -41
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -377,28 +377,37 @@ Note, your properties may show up in the intellisense for `state`, but they are
|
|
|
377
377
|
Here are the validators that Vuelidify provides by default:
|
|
378
378
|
|
|
379
379
|
- ```ts
|
|
380
|
-
required()
|
|
380
|
+
required(message?: string)
|
|
381
|
+
```
|
|
382
|
+
- ```ts
|
|
383
|
+
notEmpty(message?: string)
|
|
381
384
|
```
|
|
382
385
|
- ```ts
|
|
383
|
-
minLength(min: number)
|
|
386
|
+
minLength(min: number, message?: string)
|
|
384
387
|
```
|
|
385
388
|
- ```ts
|
|
386
|
-
maxLength(max: number)
|
|
389
|
+
maxLength(max: number, message?: string)
|
|
390
|
+
```
|
|
391
|
+
- ```ts
|
|
392
|
+
minNumber(min: number, message?: string)
|
|
393
|
+
```
|
|
394
|
+
- ```ts
|
|
395
|
+
exclusiveMinNumber(min: number, message?: string)
|
|
387
396
|
```
|
|
388
397
|
- ```ts
|
|
389
|
-
|
|
398
|
+
maxNumber(max: number, message?: string)
|
|
390
399
|
```
|
|
391
400
|
- ```ts
|
|
392
|
-
|
|
401
|
+
exclusiveMaxNumber(max: number, message?: string)
|
|
393
402
|
```
|
|
394
403
|
- ```ts
|
|
395
|
-
must(fn: (params) => boolean,
|
|
404
|
+
must(fn: (params) => boolean, message: string)
|
|
396
405
|
```
|
|
397
406
|
- ```ts
|
|
398
407
|
validateIf(predicate: (params) => boolean | Promise<boolean>, validators: Validator[])
|
|
399
408
|
```
|
|
400
409
|
- ```ts
|
|
401
|
-
isEmailSync()
|
|
410
|
+
isEmailSync(message?: string)
|
|
402
411
|
```
|
|
403
412
|
|
|
404
413
|
There aren't many validators provided by this library on purpose. If you feel a validator would be useful for everyone to have, give us feedback on our GitHub repository. However, we highly encourage you to understand how to make your own!
|
|
@@ -412,6 +421,7 @@ Here is a breakdown of one of the provided validators (expanded to make comments
|
|
|
412
421
|
// always provide a header comment to explain what the validator does!
|
|
413
422
|
/**
|
|
414
423
|
* Checks if the string value is a valid looking email using RegEx.
|
|
424
|
+
* @param message sets the error message returned.
|
|
415
425
|
*/
|
|
416
426
|
export function isEmailSync<
|
|
417
427
|
// The type of the property you want to support validation for.
|
|
@@ -430,7 +440,8 @@ export function isEmailSync<
|
|
|
430
440
|
// Generally you don't put constraints on this.
|
|
431
441
|
A
|
|
432
442
|
>(
|
|
433
|
-
// Specify any parameters
|
|
443
|
+
// Specify any parameters here.
|
|
444
|
+
message?: string
|
|
434
445
|
): SyncValidator<T, K, V, R, A> // Explicitly type the validator you'll be returning
|
|
435
446
|
{
|
|
436
447
|
// Return a validator function
|
|
@@ -438,12 +449,14 @@ export function isEmailSync<
|
|
|
438
449
|
// Strongly type the expected params object to have intellisense
|
|
439
450
|
params: ValidatorParams<T, K, V, A>
|
|
440
451
|
) => {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
452
|
+
/**
|
|
453
|
+
* You can do whatever here, but you must return undefined,
|
|
454
|
+
* an array of validators, or a validation result.
|
|
455
|
+
* In this case, we're checking the value against an email regex.
|
|
456
|
+
*/
|
|
444
457
|
return {
|
|
445
458
|
isValid: params.value ? RegExp(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/).test(params.value) : false,
|
|
446
|
-
message: "Invalid email format"
|
|
459
|
+
message: message ?? "Invalid email format"
|
|
447
460
|
}
|
|
448
461
|
};
|
|
449
462
|
}
|
|
@@ -454,11 +467,14 @@ Because every generic has a default value in `SyncValidator`, we can greatly sim
|
|
|
454
467
|
```ts
|
|
455
468
|
/**
|
|
456
469
|
* Validates a string is a valid looking email using RegEx.
|
|
470
|
+
* @param message sets the error message returned.
|
|
457
471
|
*/
|
|
458
|
-
export function isEmailSync<T extends string | undefined | null>(
|
|
472
|
+
export function isEmailSync<T extends string | undefined | null>(
|
|
473
|
+
message?: string
|
|
474
|
+
): SyncValidator<T> {
|
|
459
475
|
return (params: ValidatorParams<T>) => ({
|
|
460
476
|
isValid: params.value ? RegExp(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/).test(params.value) : false,
|
|
461
|
-
message: "Invalid email format"
|
|
477
|
+
message: message ?? "Invalid email format"
|
|
462
478
|
});
|
|
463
479
|
}
|
|
464
480
|
```
|
|
@@ -471,17 +487,17 @@ Vuelidify provides several throttling functions for limiting how often a functio
|
|
|
471
487
|
- ```ts
|
|
472
488
|
bufferAsync<F extends (...args: any[]) => any>(
|
|
473
489
|
func: F,
|
|
474
|
-
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof
|
|
490
|
+
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>
|
|
475
491
|
```
|
|
476
|
-
`bufferAsync` ensures that the provided function has only one instance executing at a time. Calls to the buffered function will return a promise to execute when the current instance returns. Only the latest promise will execute the function next, all other promises will resolve to `
|
|
492
|
+
`bufferAsync` ensures that the provided function has only one instance executing at a time. Calls to the buffered function will return a promise to execute when the current instance returns. Only the latest promise will execute the function next, all other promises will resolve to `V$_IGNORE` once the current instance returns. This function is very useful for only invoking resource-heavy functions while guaranteeing each execution uses the most up-to-date parameters.
|
|
477
493
|
|
|
478
494
|
- ```ts
|
|
479
495
|
throttleBufferAsync<F extends (...args: any[]) => any>(
|
|
480
496
|
func: F,
|
|
481
497
|
delayMs: number,
|
|
482
|
-
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof
|
|
498
|
+
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>
|
|
483
499
|
```
|
|
484
|
-
`throttleBufferAsync` behaves very similarly to `bufferAsync`, but instead of waiting for the current instance to return, it waits for a throttle duration to expire. Once the throttle expires the latest buffered promise will execute the function and all others will resolve to `
|
|
500
|
+
`throttleBufferAsync` behaves very similarly to `bufferAsync`, but instead of waiting for the current instance to return, it waits for a throttle duration to expire. Once the throttle expires the latest buffered promise will execute the function and all others will resolve to `V$_IGNORE`. This means multiple instances of the function could be running at the same time, depending on the throttle and how long the function takes to return.
|
|
485
501
|
|
|
486
502
|
- ```ts
|
|
487
503
|
throttleAsync<F extends (...args: any) => any>(
|
|
@@ -489,20 +505,20 @@ Vuelidify provides several throttling functions for limiting how often a functio
|
|
|
489
505
|
delayMs: number,
|
|
490
506
|
): {
|
|
491
507
|
isThrottled: Ref<boolean>;
|
|
492
|
-
throttledFunc: (...params: Parameters<F>) => ReturnType<F> | typeof
|
|
508
|
+
throttledFunc: (...params: Parameters<F>) => ReturnType<F> | typeof V$_IGNORE;
|
|
493
509
|
}
|
|
494
510
|
```
|
|
495
|
-
`throttleAsync` ensures a function can only be invoked once every throttle period. Does not use buffering. Returns two objects, a ref indicating if the function is in its throttle period and the throttled function. Useful for hard limiting invocation of a function (e.g. forgot password form submission). Calls during the throttle period return `
|
|
511
|
+
`throttleAsync` ensures a function can only be invoked once every throttle period. Does not use buffering. Returns two objects, a ref indicating if the function is in its throttle period and the throttled function. Useful for hard limiting invocation of a function (e.g. forgot password form submission). Calls during the throttle period return `V$_IGNORE`.
|
|
496
512
|
|
|
497
513
|
- ```ts
|
|
498
514
|
trailingDebounceAsync<F extends (...args: any) => any>(
|
|
499
515
|
func: F,
|
|
500
516
|
delayMs: number,
|
|
501
|
-
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof
|
|
517
|
+
): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>
|
|
502
518
|
```
|
|
503
|
-
`trailingDebounceAsync` ensures a function will only be invoked after a delay has passed since the last call. Guarantees the latest parameters will be executed. All calls prior to the latest will return `
|
|
519
|
+
`trailingDebounceAsync` ensures a function will only be invoked after a delay has passed since the last call. Guarantees the latest parameters will be executed. All calls prior to the latest will return `V$_IGNORE`.
|
|
504
520
|
|
|
505
|
-
`
|
|
521
|
+
`V$_IGNORE` is a constant unique symbol exported by Vuelidify that helps you to identify when invocations are ignored by a throttle function. This was done to make sure this unique state doesn't conflict with possible returns from your own functions.
|
|
506
522
|
|
|
507
523
|
## Utility Functions
|
|
508
524
|
Vuelidify provides a utility function you are free to use as well.
|
package/dist/index.d.ts
CHANGED
|
@@ -76,6 +76,10 @@ type ArrayValidation<U, T = U[], KModel = unknown, Args = unknown, Return = any,
|
|
|
76
76
|
[key in NLevel]: ArrayAncestor<U, T>;
|
|
77
77
|
}, Increment<NLevel>>;
|
|
78
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Represents an element in {@link ValidatorParams.arrayAncestors | arrayAncestors} which
|
|
81
|
+
* holds context about the ancestor along with the ancestor itself.
|
|
82
|
+
*/
|
|
79
83
|
type ArrayAncestor<U = unknown, // the type of T's elements
|
|
80
84
|
T = unknown> = Readonly<{
|
|
81
85
|
/** The index this ancestor is at in `array` */
|
|
@@ -88,11 +92,11 @@ T = unknown> = Readonly<{
|
|
|
88
92
|
/** A synchronous or asynchronous validator. */
|
|
89
93
|
type Validator<T = unknown, KModel = unknown, Args = unknown, Return = any, Ancestors = unknown> = SyncValidator<T, KModel, Args, Return, Ancestors> | AsyncValidator<T, KModel, Args, Return, Ancestors>;
|
|
90
94
|
/** Defines a validator function */
|
|
91
|
-
type BaseValidator<T,
|
|
95
|
+
type BaseValidator<T, KModel, Args, Return, Ancestors> = (input: ValidatorParams<T, KModel, Args, Ancestors>) => Return;
|
|
92
96
|
/** Defines a validator which always runs synchronously */
|
|
93
|
-
type SyncValidator<T = unknown,
|
|
97
|
+
type SyncValidator<T = unknown, KModel = unknown, Args = unknown, Return = any, Ancestors = unknown> = BaseValidator<T, KModel, Args, BaseValidationReturn<Return> | Array<Validator<T, KModel, Args, Return, Ancestors>> | undefined, Ancestors>;
|
|
94
98
|
/** Defines a validator which returns a promise */
|
|
95
|
-
type AsyncValidator<T = unknown,
|
|
99
|
+
type AsyncValidator<T = unknown, KModel = unknown, Args = unknown, Return = any, Ancestors = unknown> = BaseValidator<T, KModel, Args, Promise<BaseValidationReturn<Return> | Array<Validator<T, KModel, Args, Return, Ancestors>> | undefined>, Ancestors>;
|
|
96
100
|
/** Defines the return value of validators */
|
|
97
101
|
type BaseValidationReturn<F = unknown> = {
|
|
98
102
|
/**
|
|
@@ -191,76 +195,170 @@ type Increment<N extends number> = [
|
|
|
191
195
|
...number[]
|
|
192
196
|
][N];
|
|
193
197
|
|
|
198
|
+
/** Vuelidify's constant Symbol used for identifying when a throttle function returned early. */
|
|
199
|
+
declare const V$_IGNORE: unique symbol;
|
|
194
200
|
/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
201
|
+
* Buffers a function such that only one instance of the function executes at a time.
|
|
202
|
+
*
|
|
203
|
+
* Calls during execution return a promise to execute the function after current execution finishes.
|
|
204
|
+
* Only the latest buffered call will execute the function; the rest resolve to {@link V$_IGNORE}.
|
|
205
|
+
*
|
|
206
|
+
* @param func The function to apply a buffer to.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* const buffered = bufferAsync(someAsyncFn);
|
|
210
|
+
* buffered('a'); // executes
|
|
211
|
+
* buffered('b'); // queued but will resolve to undefined
|
|
212
|
+
* buffered('c'); // queued and will executed after first completes
|
|
213
|
+
*/
|
|
214
|
+
declare function bufferAsync<F extends (...args: any[]) => any>(func: F): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>;
|
|
215
|
+
/**
|
|
216
|
+
* Throttles and buffers a function such that it is only called once per delay period.
|
|
217
|
+
*
|
|
218
|
+
* Calls during the throttle return a promise to execute the function after the throttle.
|
|
219
|
+
* Only the latest buffered call will execute; the rest resolve to {@link V$_IGNORE}.
|
|
220
|
+
*
|
|
221
|
+
* Useful when you want to avoid spamming a resource and using the latest parameters is important.
|
|
222
|
+
*
|
|
223
|
+
* @param func - The function to throttle.
|
|
224
|
+
* @param delayMs - Time between invocations.
|
|
225
|
+
* @returns A throttled version of the function.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* async function saveInput(input: string) { ... }
|
|
229
|
+
* const throttledSave = throttleBufferAsync(saveInput, 1000);
|
|
230
|
+
*
|
|
231
|
+
* throttledSave("a"); // Executes immediately
|
|
232
|
+
* throttledSave("b"); // Queued but will resolve to IGNORE_RESULT
|
|
233
|
+
* throttledSave("c"); // Replaces "b", starts after 1s
|
|
234
|
+
*
|
|
235
|
+
* // Only "a" and "c" will be processed
|
|
236
|
+
*/
|
|
237
|
+
declare function throttleBufferAsync<F extends (...args: any[]) => any>(func: F, delayMs: number): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>;
|
|
238
|
+
/**
|
|
239
|
+
* Adds trailing debounce behavior to a function.
|
|
240
|
+
*
|
|
241
|
+
* Waits for the specified delay after the last call before executing.
|
|
242
|
+
* All previous calls during the delay resolve to {@link V$_IGNORE}. Guarantees the call will have the latest parameters.
|
|
243
|
+
*
|
|
244
|
+
* @param func - The async function to debounce.
|
|
245
|
+
* @param delay - Delay in milliseconds after the last call before execution.
|
|
246
|
+
* @returns A debounced version of the function.
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* async function fetchResults(query: string) { ... }
|
|
250
|
+
* const debouncedFetch = trailingDebounceAsync(fetchResults, 500);
|
|
251
|
+
*
|
|
252
|
+
* debouncedFetch("a"); // resolves to IGNORE_RESULT
|
|
253
|
+
* debouncedFetch("ab"); // resolves to IGNORE_RESULT
|
|
254
|
+
* debouncedFetch("abc"); // Only this call will be executed after 500ms
|
|
205
255
|
*/
|
|
206
|
-
declare function
|
|
256
|
+
declare function trailingDebounceAsync<F extends (...args: any) => any>(func: F, delayMs: number): (...params: Parameters<F>) => Promise<Awaited<ReturnType<F>> | typeof V$_IGNORE>;
|
|
207
257
|
/**
|
|
208
|
-
*
|
|
258
|
+
* Throttles a function, ensuring it's called once per delay period.
|
|
209
259
|
*
|
|
210
|
-
*
|
|
260
|
+
* Calls during the delay are ignored, and the first call after the delay executes immediately.
|
|
211
261
|
*
|
|
212
|
-
*
|
|
262
|
+
* Useful for hard limiting actions (e.g. form submissions or API calls).
|
|
263
|
+
*
|
|
264
|
+
* @param func - The function to throttle.
|
|
265
|
+
* @param delayMs - The minimum time (in milliseconds) between calls.
|
|
266
|
+
* @returns A ref indicating throttle state and the throttled function.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* async function fetchResults(query: string) { ... }
|
|
270
|
+
* const { throttledFunc } = throttleAsync(fetchResults, 500);
|
|
271
|
+
*
|
|
272
|
+
* throttledFunc("a"); // executes immediately
|
|
273
|
+
* throttledFunc("ab"); // ignored
|
|
274
|
+
* // ... 500 ms later ...
|
|
275
|
+
* throttledFunc("abc"); // executes immediately
|
|
276
|
+
*/
|
|
277
|
+
declare function throttleAsync<F extends (...args: any) => any>(func: F, delayMs: number): {
|
|
278
|
+
isThrottled: Ref<boolean>;
|
|
279
|
+
throttledFunc: (...params: Parameters<F>) => ReturnType<F> | typeof V$_IGNORE;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Accepts an array and uses the provided getter to get any value from each element
|
|
284
|
+
* and ignoring any undefined or null values returned.
|
|
213
285
|
*
|
|
214
|
-
* Once the interval has passed, all queued promises are executed, but only the latest promise will execute the function. The others will return undefined.
|
|
215
286
|
* ```ts
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* const throttledTest = throttleQueueAsync<
|
|
219
|
-
* typeof test, // this type makes the return the same signature as test()
|
|
220
|
-
* Awaited<ReturnType<typeof test>> // this type makes the returned function have the same return type
|
|
221
|
-
* >(test);
|
|
287
|
+
* const array = [{ id: 123, name: "Foo"}, { id: 456, name: undefined }]
|
|
288
|
+
* const validNames = reduceUndefined(array, v => v.name) // ["Foo"]
|
|
222
289
|
* ```
|
|
223
|
-
* @param
|
|
224
|
-
* @param
|
|
290
|
+
* @param array the array to map values from
|
|
291
|
+
* @param getter a function executed with each element which can perform any kind of custom mapping.
|
|
292
|
+
* @returns an array of the getter's return value invoked with each source element, with undefined values omitted.
|
|
225
293
|
*/
|
|
226
|
-
declare function
|
|
294
|
+
declare function reduceUndefined<T, K = NonNullable<T>>(array: T[], getter?: (value: T) => K | undefined | null): K[];
|
|
227
295
|
|
|
228
296
|
/**
|
|
229
297
|
* Validates the object is not loosely undefined.
|
|
298
|
+
* This does allow for empty strings. If you need a non-empty value, use {@link notEmpty()}.
|
|
299
|
+
* @param message sets the error message returned.
|
|
230
300
|
*/
|
|
231
|
-
declare function required(): SyncValidator;
|
|
301
|
+
declare function required(message?: string): SyncValidator;
|
|
302
|
+
/**
|
|
303
|
+
* Validates the object is not loosely undefined and is not an empty string.
|
|
304
|
+
* @param message sets the error message returned.
|
|
305
|
+
*/
|
|
306
|
+
declare function notEmpty(message?: string): SyncValidator;
|
|
232
307
|
/**
|
|
233
308
|
* Validates a string or number has a length >= to the provided length. Undefined and null are 0 length.
|
|
234
|
-
* @param
|
|
309
|
+
* @param min the minimum length of the string or number.
|
|
310
|
+
* @param message sets the error message returned.
|
|
235
311
|
*/
|
|
236
|
-
declare function minLength<T extends string | number | undefined | null>(
|
|
312
|
+
declare function minLength<T extends string | number | undefined | null>(min: number, message?: string): SyncValidator<T>;
|
|
237
313
|
/**
|
|
238
314
|
* Validates a string or number's length. Undefined and null are 0 length.
|
|
239
|
-
* @param
|
|
315
|
+
* @param max the maximum length of the string or number.
|
|
316
|
+
* @param message sets the error message returned.
|
|
317
|
+
*/
|
|
318
|
+
declare function maxLength<T extends string | number | undefined | null>(max: number, message?: string): SyncValidator<T>;
|
|
319
|
+
/**
|
|
320
|
+
* Validates a number is defined and is at least some value.
|
|
321
|
+
* @param min the minimum number the value can be.
|
|
322
|
+
* @param message sets the error message returned.
|
|
240
323
|
*/
|
|
241
|
-
declare function
|
|
324
|
+
declare function minNumber<T extends number | undefined | null>(min: number, message?: string): SyncValidator<T>;
|
|
242
325
|
/**
|
|
243
326
|
* Validates a number is defined and is at least some value.
|
|
244
|
-
* @param
|
|
327
|
+
* @param min the minimum number the value can be.
|
|
328
|
+
* @param message sets the error message returned.
|
|
329
|
+
*/
|
|
330
|
+
declare function exclusiveMinNumber<T extends number | undefined | null>(min: number, message?: string): SyncValidator<T>;
|
|
331
|
+
/**
|
|
332
|
+
* Validates a number is defined and is at most some value.
|
|
333
|
+
* @param max the maximum number the value can be.
|
|
334
|
+
* @param message sets the error message returned.
|
|
245
335
|
*/
|
|
246
|
-
declare function
|
|
336
|
+
declare function maxNumber<T extends number | undefined | null>(max: number, message?: string): SyncValidator<T>;
|
|
247
337
|
/**
|
|
248
338
|
* Validates a number is defined and is at most some value.
|
|
249
|
-
* @param
|
|
339
|
+
* @param max the maximum number the value can be.
|
|
340
|
+
* @param message sets the error message returned.
|
|
250
341
|
*/
|
|
251
|
-
declare function
|
|
342
|
+
declare function exclusiveMaxNumber<T extends number | undefined | null>(max: number, message?: string): SyncValidator<T>;
|
|
252
343
|
/**
|
|
253
344
|
* Validate the provided predicate function.
|
|
254
345
|
* @param fn predicate that returns true if the value is valid.
|
|
255
|
-
* @param
|
|
346
|
+
* @param message sets the error message returned.
|
|
256
347
|
*/
|
|
257
|
-
declare function must<T, K, V, R, A>(fn: (params: ValidatorParams<T, K, V, A>) => boolean,
|
|
348
|
+
declare function must<T, K, V, R, A>(fn: (params: ValidatorParams<T, K, V, A>) => boolean, message: string): SyncValidator<T, K, V, R, A>;
|
|
349
|
+
/**
|
|
350
|
+
* Execute a set of validators only if the provided predicate is true.
|
|
351
|
+
* @param predicate determines if the set of validators should be returned.
|
|
352
|
+
* @param validators The set of validators to execute if the predicate returns true.
|
|
353
|
+
*/
|
|
354
|
+
declare function validateIf<T, K, V, R, A, Validators extends Validator<T, K, V, R, A>[]>(predicate: (params: ValidatorParams<T, K, V, A>) => boolean | Promise<boolean>, validators: Validators): AsyncValidator<T, K, V, R, A>;
|
|
258
355
|
/**
|
|
259
356
|
* Validates a string is a valid looking email using RegEx.
|
|
260
357
|
*
|
|
261
358
|
* The RegEx was taken from https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript, and may be updated in the future.
|
|
262
|
-
|
|
263
|
-
|
|
359
|
+
* @param message sets the error message returned.
|
|
360
|
+
*/
|
|
361
|
+
declare function isEmailSync<T extends string | undefined | null>(message?: string): SyncValidator<T>;
|
|
264
362
|
|
|
265
363
|
type UseValidationReturn<T = unknown, Return = any> = {
|
|
266
364
|
hasValidated: Ref<boolean>;
|
|
@@ -280,6 +378,10 @@ type UseValidationReturn<T = unknown, Return = any> = {
|
|
|
280
378
|
* The reference state can be changed using {@link setReference()}.
|
|
281
379
|
*/
|
|
282
380
|
isDirty: ComputedRef<boolean>;
|
|
381
|
+
/**
|
|
382
|
+
* Resets the internal state of the composable back to its starting state.
|
|
383
|
+
*/
|
|
384
|
+
reset: () => void;
|
|
283
385
|
};
|
|
284
386
|
/**
|
|
285
387
|
* The starting point for validation with Vuelidify.
|
|
@@ -288,4 +390,4 @@ type UseValidationReturn<T = unknown, Return = any> = {
|
|
|
288
390
|
*/
|
|
289
391
|
declare function useValidation<T, Args = unknown, Return = any>(validationConfig: ValidationConfig<T, Args, Return>): Reactive<UseValidationReturn<T, Return>>;
|
|
290
392
|
|
|
291
|
-
export { ArrayAncestor, ArrayValidation, ArrayValidationState, AsyncValidator, BaseValidation, BaseValidationReturn, BaseValidationState, BaseValidator, ObjectValidationTypes, Primitive, PrimitiveValidationState, RecursiveValidation, RecursiveValidationState, SyncValidator, Validation, ValidationConfig, ValidationState, Validator, ValidatorParams, bufferAsync, isEmailSync, maxLength, maxNumber, minLength, minNumber, must, required,
|
|
393
|
+
export { ArrayAncestor, ArrayValidation, ArrayValidationState, AsyncValidator, BaseValidation, BaseValidationReturn, BaseValidationState, BaseValidator, ObjectValidationTypes, Primitive, PrimitiveValidationState, RecursiveValidation, RecursiveValidationState, SyncValidator, V$_IGNORE, Validation, ValidationConfig, ValidationState, Validator, ValidatorParams, bufferAsync, exclusiveMaxNumber, exclusiveMinNumber, isEmailSync, maxLength, maxNumber, minLength, minNumber, must, notEmpty, reduceUndefined, required, throttleAsync, throttleBufferAsync, trailingDebounceAsync, useValidation, validateIf };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{ref as K}from"vue";var x=Symbol("Throttled function call was ignored");function H(e){let a=0,t;return(...n)=>{let r=++a;return(t??Promise.resolve()).then(()=>r!==a?x:e(...n)).finally(()=>{r===a&&(t=void 0)})}}function Q(e,a){let t=0,n=0;return async(...r)=>{let s=++t,f=Date.now()-n;return f<a&&(await new Promise(u=>setTimeout(u,a-f)),s!==t)?x:(n=Date.now(),await e(...r))}}function X(e,a){let t=0;return(...n)=>new Promise(r=>{let s=++t;setTimeout(async()=>{s==t?r(await e(...n)):r(x)},a)})}function Y(e,a){let t=K(!1);return{isThrottled:t,throttledFunc:(...r)=>t.value?x:(t.value=!0,setTimeout(()=>t.value=!1,a),e(...r))}}function O(e,a=t=>t){return e.reduce((t,n)=>{let r=a(n);return r!=null&&t.push(r),t},[])}function ae(e){return a=>({isValid:a.value!=null,message:e??"This field is required"})}function te(e){return a=>({isValid:a.value!=null&&a.value!==""&&String(a.value).trim().length>0,message:e??"Must not be empty"})}function ie(e,a){return t=>{let n=String(t.value??"");return{isValid:n.length>=e,message:a??`Too short (${n.length} / ${e})`}}}function ne(e,a){return t=>{let n=String(t.value??"");return{isValid:n.length<=e,message:a??`Too long (${n.length} / ${e})`}}}function re(e,a){return t=>({isValid:t.value!=null&&t.value>=e&&String(t.value)!=="",message:a??`The minimum value is ${e}`})}function oe(e,a){return t=>({isValid:t.value!=null&&t.value>e&&String(t.value)!=="",message:a??`The minimum value is ${e}`})}function se(e,a){return t=>({isValid:t.value!=null&&t.value<=e&&String(t.value)!=="",message:a??`The maximum value is ${e}`})}function le(e,a){return t=>({isValid:t.value!=null&&t.value<e&&String(t.value)!=="",message:a??`The maximum value is ${e}`})}function de(e,a){return t=>({isValid:e(t),message:a})}function ue(e,a){return async t=>{if(await e(t))return a}}function ce(e){return a=>({isValid:a.value?RegExp(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/).test(a.value):!1,message:e??"Invalid email format"})}import{computed as h,reactive as U,ref as E,watch as q}from"vue";import{computed as D,toValue as G}from"vue";import{computed as b,reactive as k,ref as T,toValue as F}from"vue";function L(){return`${Date.now()}-${Math.floor(Math.random()*1e3)}`}function z(e,a){return C(e,a)}function w(e,a,t){let n=[],r=()=>`${a?"reactive":"lazy"}-${L()}`;t!=null&&(r=s=>`${t}-${s}`);for(let[s,d]of e.entries())n.push({validatorId:r(s),validator:d,optimized:!1,isReactive:a,previouslyReturnedValidators:!1,previouslySpawnedValidators:{},spawnedValidators:{}});return n}function M(e,a,t=[]){let n=k({$state:{isValid:b(()=>{let l=u.isLazyValid.value??!1,g=u.isReactiveValid.value??!1;return l&&g}),isValidating:b(()=>u.isValidatingReactive.value||u.isValidatingLazy.value),isErrored:b(()=>n.$state?.resultsArray.some(l=>l.isValid===!1)??!1),errorMessages:b(()=>O(n.$state?.resultsArray??[],l=>l.isValid?void 0:l.message)),results:b(()=>u.namedValidationResults.value),resultsArray:b(()=>u.validationResults.value)},$arrayState:b(()=>{if(Array.isArray(e.value)===!1||u.elementValidation===void 0)return[];let l=e.value,g=u.elementValidation,m=u.arrayConfigMap,i=[],V={},o,p=[];for(let c=0;c<l.length;c++){let v=l[c]!==void 0&&typeof l[c]=="object";if(v?(l[c].$ffId===void 0&&Object.defineProperty(l[c],"$ffId",{value:`${u.id}-${u.elementId++}`,writable:!1,configurable:!1,enumerable:!1}),o=l[c].$ffId):l[c]!==void 0&&(o=c),p.push(o),m[o]){i.push(m[o].validationState),V[o]=m[o];continue}let y=b(()=>l[c]),R=[...u.arrayAncestors];v&&R.push({ancestor:y,array:l,index:c});let P=C(y,g,R);m[o]={validationConfigs:P.validationConfigs,validationState:P.state},i.push(m[o].validationState),V[o]=m[o]}return u.arrayConfigMap=V,i})}),r=!0,s=!0,d=[],f=[];a.$reactive&&a.$reactive.length>0&&(s=!1,d=w(a.$reactive,!0)),a.$lazy&&a.$lazy?.length>0&&(r=!1,f=w(a.$lazy,!1));let u={id:L(),reactiveIterationId:0,lazyIterationId:0,isReactiveValid:T(s),isValidatingReactive:T(!1),reactiveProcessedValidators:d,isLazyValid:T(r),isValidatingLazy:T(!1),lazyProcessedValidators:f,target:e,validation:a,validationState:n,validationResults:T([]),namedValidationResults:T({}),arrayConfigMap:{},elementId:0,elementValidation:a.$each,arrayAncestors:k(t)};return u}function C(e,a,t=[]){let n=[],r={};if(N(a)){let d=b(()=>F(e)),f=M(d,a,t);n.push(f),r=f.validationState}a!=null&&s(e,a,r);function s(d,f,u){if(I(f)!==!1)for(let l in f){if(l==="$reactive"||l==="$lazy"||l==="$each")continue;let g=b(()=>{let i=F(d);return I(i)?i[l]:(console.error(`Vuelidify Error: validation could not be setup correctly on ${i} because ${d} is not enumerable.`),null)}),m=f[l];if(N(m)){let i=M(g,m,t);n.push(i),u[l]=i.validationState}if(I(m)){let i=u[l]??{};u[l]=i,s(g,m,i)}}}return{validationConfigs:n,state:r}}function N(e){return Array.isArray(e?.$reactive)||Array.isArray(e?.$lazy)||e?.$each!==void 0}function I(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function j(e,a,t,n,r,s){let d=!0,f=(i,V,o)=>{if(n!==G(r))return;o.isValid===!1&&(d=!1),o.id=V.validatorId;let p=i.validationResults.value.find(c=>c.id===o.id);p!==void 0?(Object.assign(p,o),o.name!==void 0&&i.namedValidationResults.value[o.name]!==void 0&&Object.assign(i.namedValidationResults.value[o.name],o)):(i.validationResults.value.push(o),o.name!==void 0&&(i.namedValidationResults.value[o.name]=o))},u=[];for(let i of s){let V=(i.activeValidation??Promise.resolve()).then(async()=>n!==G(r)?[]:await g(i,!0));i.activeValidation=V,u.push(V)}return await Promise.all(u),d;function l(i,V){let o=[];for(let p of i)o.push(g(p,!1,V));return o}async function g(i,V,o=i){let p=[],c=i.previouslyReturnedValidators;c&&(i.previouslySpawnedValidators=i.spawnedValidators,i.spawnedValidators={}),i.previouslyReturnedValidators=!1;let v={value:e.target.value,model:a,args:t,arrayAncestors:e.arrayAncestors},y=i.validator(v);if(y instanceof Promise){let R=await y;if(Array.isArray(R)){let P=m(i,R,o),$=await Promise.all(P);p.push(...$.flat()),c&&S(e,i)}else c&&S(e,i),R!=null&&(p.push(R),f(e,i,R))}else if(Array.isArray(y)){let R=m(i,y,o),P=await Promise.all(R);p.push(...P.flat()),c&&S(e,i)}else if(c&&S(e,i),y!=null){if(V&&i.optimized===!1){let R=i.validator,P=D(()=>{let $={value:e.target.value,model:a,args:t,arrayAncestors:e.arrayAncestors};return R($)});i.optimized=!0,i.validator=()=>P.value}p.push(y),f(e,i,y)}return p}function m(i,V,o){let p=w(V,i.isReactive,i.validatorId),c=l(p,o),v=o.spawnedValidators;for(let y of p)v[y.validatorId]!=null&&console.error(`Unable to keep track of nested validators. Validator ID: ${y.validatorId} was not unique.`),v[y.validatorId]=y;return i.spawnedValidators=v,i.previouslyReturnedValidators=!0,c}}function S(e,a){for(let t in a.previouslySpawnedValidators){if(a.spawnedValidators[t]!=null)continue;let n=e.validationResults.value.findIndex(r=>r.id===t);n!==-1&&e.validationResults.value.splice(n,1)}}async function B(e,a,t,n,r){e.isValidatingReactive.value=!0;let s=await j(e,a,t,n,r,e.reactiveProcessedValidators);return n===G(r)&&(e.isReactiveValid.value=s,e.isValidatingReactive.value=!1),e.isReactiveValid.value??!1}async function _(e,a,t,n,r){e.isValidatingLazy.value=!0;let s=await j(e,a,t,n,r,e.lazyProcessedValidators);return n===G(r)&&(e.isLazyValid.value=s,e.isValidatingLazy.value=!1),e.isLazyValid.value??!1}function A(e,a,t,n,r){let s=[];for(let d of e)if(n&&d.reactiveProcessedValidators.length>0&&s.push(B(d,a.value,t,++d.reactiveIterationId,()=>d.reactiveIterationId)),r&&d.lazyProcessedValidators.length>0&&s.push(_(d,a.value,t,++d.lazyIterationId,()=>d.lazyIterationId)),Array.isArray(d.validationState.$arrayState)){let f=[];for(let u in d.arrayConfigMap)f.push(...d.arrayConfigMap[u].validationConfigs);s.push(A(f,a,t,n,r))}return Promise.all(s).then(d=>d.every(f=>f===!0))}function J(e){e.delayReactiveValidation??=!0;let{model:a,validation:t,delayReactiveValidation:n,args:r}=e,s=E(!1),d=h(()=>V.some(v=>v.isValidatingLazy.value||v.isValidatingReactive.value)),f=h(()=>V.some(v=>v.validationResults.value.some(y=>y.isValid===!1))),u=h(()=>V.every(y=>y.isReactiveValid.value&&y.isLazyValid.value)),l=E(JSON.stringify(e.model.value)),g=h(()=>l.value!==JSON.stringify(e.model.value)),m=z(a,t),i=m.state,V=m.validationConfigs;q(e.model,()=>{n?s.value===!0&&A(V,a,r,!0,!1):A(V,a,r,!0,!1)},{deep:!0});async function o(){let v=await A(V,a,r,!0,!0);return s.value=!0,v}function p(v){l.value=JSON.stringify(v)}function c(){s.value=!1,m=z(a,t),V=m.validationConfigs,i=m.state}return U({hasValidated:s,validate:o,isValidating:d,state:h(()=>i),isValid:u,isErrored:f,setReference:p,isDirty:g,reset:c})}export{x as V$_IGNORE,H as bufferAsync,le as exclusiveMaxNumber,oe as exclusiveMinNumber,ce as isEmailSync,ne as maxLength,se as maxNumber,ie as minLength,re as minNumber,de as must,te as notEmpty,O as reduceUndefined,ae as required,Y as throttleAsync,Q as throttleBufferAsync,X as trailingDebounceAsync,J as useValidation,ue as validateIf};
|