@satoshibits/functional 1.0.2

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.
Files changed (46) hide show
  1. package/README.md +242 -0
  2. package/dist/array-utils.d.mts +317 -0
  3. package/dist/array-utils.d.mts.map +1 -0
  4. package/dist/array-utils.mjs +370 -0
  5. package/dist/array-utils.mjs.map +1 -0
  6. package/dist/composition.d.mts +603 -0
  7. package/dist/composition.d.mts.map +1 -0
  8. package/dist/composition.mjs +516 -0
  9. package/dist/composition.mjs.map +1 -0
  10. package/dist/object-utils.d.mts +267 -0
  11. package/dist/object-utils.d.mts.map +1 -0
  12. package/dist/object-utils.mjs +258 -0
  13. package/dist/object-utils.mjs.map +1 -0
  14. package/dist/option.d.mts +622 -0
  15. package/dist/option.d.mts.map +1 -0
  16. package/dist/option.mjs +637 -0
  17. package/dist/option.mjs.map +1 -0
  18. package/dist/performance.d.mts +265 -0
  19. package/dist/performance.d.mts.map +1 -0
  20. package/dist/performance.mjs +453 -0
  21. package/dist/performance.mjs.map +1 -0
  22. package/dist/pipeline.d.mts +431 -0
  23. package/dist/pipeline.d.mts.map +1 -0
  24. package/dist/pipeline.mjs +460 -0
  25. package/dist/pipeline.mjs.map +1 -0
  26. package/dist/predicates.d.mts +722 -0
  27. package/dist/predicates.d.mts.map +1 -0
  28. package/dist/predicates.mjs +802 -0
  29. package/dist/predicates.mjs.map +1 -0
  30. package/dist/reader-result.d.mts +422 -0
  31. package/dist/reader-result.d.mts.map +1 -0
  32. package/dist/reader-result.mjs +758 -0
  33. package/dist/reader-result.mjs.map +1 -0
  34. package/dist/result.d.mts +684 -0
  35. package/dist/result.d.mts.map +1 -0
  36. package/dist/result.mjs +814 -0
  37. package/dist/result.mjs.map +1 -0
  38. package/dist/types.d.mts +439 -0
  39. package/dist/types.d.mts.map +1 -0
  40. package/dist/types.mjs +191 -0
  41. package/dist/types.mjs.map +1 -0
  42. package/dist/validation.d.mts +622 -0
  43. package/dist/validation.d.mts.map +1 -0
  44. package/dist/validation.mjs +852 -0
  45. package/dist/validation.mjs.map +1 -0
  46. package/package.json +46 -0
@@ -0,0 +1,622 @@
1
+ /**
2
+ * @module validation
3
+ * @description Functional validation utilities using Result types for composable,
4
+ * type-safe data validation. This module provides a rich set of validators and
5
+ * combinators for building complex validation schemas. Unlike traditional validation
6
+ * libraries that throw exceptions, all validators return Result types, making
7
+ * error handling explicit and composable. Validators can be combined, transformed,
8
+ * and reused to build sophisticated validation logic.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { Validation, validators, schema, ValidationError } from './validation.mts';
13
+ *
14
+ * // simple validators
15
+ * const validateAge = validators.number.between(0, 150);
16
+ * const validateEmail = validators.string.email();
17
+ *
18
+ * // combining validators
19
+ * const validatePassword = Validation.all(
20
+ * validators.string.minLength(8),
21
+ * validators.string.matches(/[A-Z]/, 'Must contain uppercase'),
22
+ * validators.string.matches(/[0-9]/, 'Must contain number')
23
+ * );
24
+ *
25
+ * // object validation schema
26
+ * const userSchema = schema({
27
+ * name: validators.string.nonEmpty(),
28
+ * email: validateEmail,
29
+ * age: Validation.optional(validateAge),
30
+ * password: validatePassword
31
+ * });
32
+ *
33
+ * // using the validator
34
+ * const result = userSchema({
35
+ * name: 'John Doe',
36
+ * email: 'john@example.com',
37
+ * age: 30,
38
+ * password: 'SecurePass123'
39
+ * });
40
+ *
41
+ * if (result.success) {
42
+ * console.log('Valid user:', result.data);
43
+ * } else {
44
+ * console.error('Validation errors:', result.error.errors);
45
+ * }
46
+ * ```
47
+ *
48
+ * @category Core
49
+ * @since 2025-07-03
50
+ */
51
+ import { Result } from "./result.mjs";
52
+ /**
53
+ * Custom validation error that can hold multiple error messages.
54
+ * @description Extends the standard Error class to accumulate multiple validation
55
+ * errors. This allows validators to collect all errors rather than failing on
56
+ * the first error, providing better user experience for form validation.
57
+ *
58
+ * @category Errors
59
+ * @example
60
+ * // Creating validation errors
61
+ * const error = new ValidationError(['Name is required', 'Email is invalid']);
62
+ * console.log(error.message); // "Validation failed: Name is required, Email is invalid"
63
+ *
64
+ * @example
65
+ * // Working with errors
66
+ * if (!result.success) {
67
+ * const validationError = result.error;
68
+ * console.log('First error:', validationError.firstError());
69
+ * console.log('All errors:', validationError.errors);
70
+ *
71
+ * if (validationError.hasError('Email is invalid')) {
72
+ * // Handle email error specifically
73
+ * }
74
+ * }
75
+ *
76
+ * @since 2025-07-03
77
+ */
78
+ export declare class ValidationError extends Error {
79
+ readonly errors: string[];
80
+ /**
81
+ * Creates a new ValidationError with the given error messages.
82
+ *
83
+ * @param {string[]} errors - Array of error messages
84
+ */
85
+ constructor(errors: string[]);
86
+ /**
87
+ * Adds additional errors to this validation error.
88
+ * @description Creates a new ValidationError with the combined errors.
89
+ * The original error remains unchanged (immutable).
90
+ *
91
+ * @param {string[]} newErrors - Additional error messages to add
92
+ * @returns {ValidationError} A new ValidationError with all errors
93
+ *
94
+ * @example
95
+ * const error1 = new ValidationError(['Name required']);
96
+ * const error2 = error1.addErrors(['Email invalid']);
97
+ * // error2.errors => ['Name required', 'Email invalid']
98
+ * // error1.errors => ['Name required'] (unchanged)
99
+ */
100
+ addErrors(newErrors: string[]): ValidationError;
101
+ /**
102
+ * Checks if this error contains a specific error message.
103
+ * @description Useful for conditional error handling based on specific
104
+ * validation failures.
105
+ *
106
+ * @param {string} error - The error message to check for
107
+ * @returns {boolean} True if the error message is present
108
+ *
109
+ * @example
110
+ * if (!result.success && result.error.hasError('Email is invalid')) {
111
+ * showEmailHelp();
112
+ * }
113
+ */
114
+ hasError(error: string): boolean;
115
+ /**
116
+ * Gets the first error message.
117
+ * @description Returns the first error in the list, useful when you only
118
+ * want to display one error at a time.
119
+ *
120
+ * @returns {string | undefined} The first error message or undefined if no errors
121
+ *
122
+ * @example
123
+ * const firstError = validationError.firstError();
124
+ * if (firstError) {
125
+ * showToast(firstError);
126
+ * }
127
+ */
128
+ firstError(): string | undefined;
129
+ }
130
+ /**
131
+ * A validator is a function that takes a value and returns a Result.
132
+ * @description The core type of the validation system. Validators are pure functions
133
+ * that take a value and return either a successful Result with the (possibly transformed)
134
+ * value, or a failed Result with a ValidationError.
135
+ *
136
+ * @template T - The type of value being validated
137
+ *
138
+ * @category Types
139
+ * @example
140
+ * // Simple validator
141
+ * const isPositive: Validator<number> = (n) =>
142
+ * n > 0 ? Result.ok(n) : Result.err(new ValidationError(['Must be positive']));
143
+ *
144
+ * @example
145
+ * // Transforming validator
146
+ * const trimString: Validator<string> = (s) =>
147
+ * Result.ok(s.trim());
148
+ *
149
+ * @since 2025-07-03
150
+ */
151
+ export type Validator<T> = (value: T) => Result<T, ValidationError>;
152
+ /**
153
+ * Validation utilities for creating and composing validators.
154
+ * @description The main namespace for validation combinators and utilities.
155
+ * Provides methods for creating, combining, and transforming validators
156
+ * in a functional style.
157
+ *
158
+ * @category Utilities
159
+ * @since 2025-07-03
160
+ */
161
+ export declare const Validation: {
162
+ /**
163
+ * Creates a validator that always succeeds.
164
+ * @description Useful as a default validator or when conditionally applying
165
+ * validation. The value passes through unchanged.
166
+ *
167
+ * @template T - The type of value
168
+ * @returns {Validator<T>} A validator that always returns success
169
+ *
170
+ * @category Constructors
171
+ * @example
172
+ * // Conditional validation
173
+ * const validator = shouldValidate
174
+ * ? validators.string.email()
175
+ * : Validation.success();
176
+ *
177
+ * @since 2025-07-03
178
+ */
179
+ success: <T>() => Validator<T>;
180
+ /**
181
+ * Creates a validator that always fails with the given error.
182
+ * @description Useful for custom validation logic or placeholder validators
183
+ * during development.
184
+ *
185
+ * @template T - The type of value
186
+ * @param {string} error - The error message
187
+ * @returns {Validator<T>} A validator that always returns failure
188
+ *
189
+ * @category Constructors
190
+ * @example
191
+ * // Feature flag validation
192
+ * const validator = featureEnabled
193
+ * ? actualValidator
194
+ * : Validation.failure('Feature not available');
195
+ *
196
+ * @since 2025-07-03
197
+ */
198
+ failure: <T>(error: string) => Validator<T>;
199
+ /**
200
+ * Creates a validator from a predicate function.
201
+ * @description The fundamental building block for custom validators. Converts
202
+ * a boolean-returning function into a validator.
203
+ *
204
+ * @template T - The type of value to validate
205
+ * @param {function(T): boolean} predicate - Function that returns true if valid
206
+ * @param {string} error - Error message if validation fails
207
+ * @returns {Validator<T>} A validator based on the predicate
208
+ *
209
+ * @category Constructors
210
+ * @example
211
+ * // Custom age validator
212
+ * const isAdult = Validation.fromPredicate(
213
+ * (age: number) => age >= 18,
214
+ * 'Must be 18 or older'
215
+ * );
216
+ *
217
+ * @example
218
+ * // Complex validation
219
+ * const isValidUsername = Validation.fromPredicate(
220
+ * (username: string) => /^[a-zA-Z0-9_]{3,20}$/.test(username),
221
+ * 'Username must be 3-20 characters, alphanumeric or underscore'
222
+ * );
223
+ *
224
+ * @since 2025-07-03
225
+ */
226
+ fromPredicate: <T>(predicate: (value: T) => boolean, error: string) => Validator<T>;
227
+ /**
228
+ * Combines multiple validators using AND logic.
229
+ * @description All validators must pass for the validation to succeed.
230
+ * Collects all errors from all validators before returning, providing
231
+ * comprehensive feedback.
232
+ *
233
+ * @template T - The type of value to validate
234
+ * @param {Validator<T>[]} validators - Validators to combine
235
+ * @returns {Validator<T>} A validator that requires all validations to pass
236
+ *
237
+ * @category Combinators
238
+ * @example
239
+ * // Password validation
240
+ * const validatePassword = Validation.all(
241
+ * validators.string.minLength(8),
242
+ * validators.string.matches(/[A-Z]/, 'Must contain uppercase'),
243
+ * validators.string.matches(/[0-9]/, 'Must contain number'),
244
+ * validators.string.matches(/[!@#$%]/, 'Must contain special character')
245
+ * );
246
+ *
247
+ * @example
248
+ * // Numeric range validation
249
+ * const validatePercentage = Validation.all(
250
+ * validators.number.min(0),
251
+ * validators.number.max(100),
252
+ * validators.number.integer()
253
+ * );
254
+ *
255
+ * @since 2025-07-03
256
+ */
257
+ all: <T>(...validators: Validator<T>[]) => Validator<T>;
258
+ /**
259
+ * Combines multiple validators using OR logic.
260
+ * @description At least one validator must pass for the validation to succeed.
261
+ * Returns the result of the first successful validator, or all errors if
262
+ * none succeed.
263
+ *
264
+ * @template T - The type of value to validate
265
+ * @param {Validator<T>[]} validators - Validators to try
266
+ * @returns {Validator<T>} A validator that requires at least one validation to pass
267
+ *
268
+ * @category Combinators
269
+ * @example
270
+ * // Multiple format support
271
+ * const validateDate = Validation.any(
272
+ * validators.string.matches(/^\d{4}-\d{2}-\d{2}$/, 'Invalid ISO date'),
273
+ * validators.string.matches(/^\d{2}\/\d{2}\/\d{4}$/, 'Invalid US date')
274
+ * );
275
+ *
276
+ * @example
277
+ * // Flexible identifier
278
+ * const validateIdentifier = Validation.any(
279
+ * validators.string.matches(/^\d+$/, 'Not a numeric ID'),
280
+ * validators.string.email(),
281
+ * validators.string.matches(/^[A-Z]{2,}$/, 'Not a code')
282
+ * );
283
+ *
284
+ * @since 2025-07-03
285
+ */
286
+ any: <T>(...validators: Validator<T>[]) => Validator<T>;
287
+ /**
288
+ * Transforms the validated value if validation passes.
289
+ * @description Note: The returned validator still takes an input of type T.
290
+ * This is the functor map operation for validators, allowing value transformation
291
+ * after successful validation.
292
+ *
293
+ * @template T - The input type
294
+ * @template U - The output type
295
+ * @param {function(T): U} fn - Function to transform the validated value
296
+ * @returns {function(Validator<T>): function(T): Result<U, ValidationError>} A function that transforms validators
297
+ *
298
+ * @category Transformations
299
+ * @example
300
+ * // Normalize email
301
+ * const normalizeEmail = Validation.map((email: string) => email.toLowerCase());
302
+ * const validateEmail = normalizeEmail(validators.string.email());
303
+ *
304
+ * @example
305
+ * // Parse and validate
306
+ * const parseNumber = Validation.map((s: string) => parseInt(s, 10));
307
+ * const validateNumericString = parseNumber(
308
+ * validators.string.matches(/^\d+$/, 'Must be numeric')
309
+ * );
310
+ *
311
+ * @since 2025-07-03
312
+ */
313
+ map: <T, U>(fn: (value: T) => U) => (validator: Validator<T>) => ((value: T) => Result<U, ValidationError>);
314
+ /**
315
+ * Chains validators together.
316
+ * @description The choice of the second validator depends on the successful
317
+ * result of the first. This is the monadic bind operation for validators,
318
+ * enabling dynamic validation based on previous results.
319
+ *
320
+ * @template T - The type being validated
321
+ * @param {function(T): Validator<T>} fn - Function that returns the next validator
322
+ * @returns {function(Validator<T>): Validator<T>} A function that chains validators
323
+ *
324
+ * @category Combinators
325
+ * @example
326
+ * // Conditional validation based on value
327
+ * const validateScore = Validation.flatMap((score: number) => {
328
+ * if (score < 0) return Validation.failure('Negative scores not allowed');
329
+ * if (score > 100) return validators.number.max(200); // Allow bonus points
330
+ * return Validation.success();
331
+ * });
332
+ *
333
+ * @example
334
+ * // Dynamic validation
335
+ * const validateField = Validation.flatMap((field: { type: string; value: any }) => {
336
+ * switch (field.type) {
337
+ * case 'email': return validators.string.email();
338
+ * case 'number': return validators.number.positive();
339
+ * default: return Validation.success();
340
+ * }
341
+ * });
342
+ *
343
+ * @since 2025-07-03
344
+ */
345
+ flatMap: <T>(fn: (value: T) => Validator<T>) => (validator: Validator<T>) => Validator<T>;
346
+ /**
347
+ * Validates an optional value.
348
+ * @description If the value is null or undefined, validation passes.
349
+ * Otherwise, applies the validator. Useful for optional form fields
350
+ * or nullable database columns.
351
+ *
352
+ * @template T - The type being validated
353
+ * @param {Validator<T>} validator - Validator to apply if value is present
354
+ * @returns {Validator<T | null | undefined>} A validator that handles optional values
355
+ *
356
+ * @category Modifiers
357
+ * @example
358
+ * // Optional email field
359
+ * const validateOptionalEmail = Validation.optional(
360
+ * validators.string.email()
361
+ * );
362
+ *
363
+ * validateOptionalEmail(null); // => { success: true, data: null }
364
+ * validateOptionalEmail('user@example.com'); // => validates as email
365
+ *
366
+ * @example
367
+ * // In object schema
368
+ * const userSchema = schema({
369
+ * name: validators.string.nonEmpty(),
370
+ * email: validators.string.email(),
371
+ * phone: Validation.optional(validators.string.matches(/^\d{10}$/))
372
+ * });
373
+ *
374
+ * @since 2025-07-03
375
+ */
376
+ optional: <T>(validator: Validator<T>) => Validator<T | null | undefined>;
377
+ /**
378
+ * Makes a validator required.
379
+ * @description Fails if value is null or undefined. This is a type guard
380
+ * that narrows T | null | undefined to T.
381
+ *
382
+ * @template T - The required type
383
+ * @param {string} error - Error message if value is missing
384
+ * @returns {Validator<T | null | undefined>} A validator that requires presence
385
+ *
386
+ * @category Modifiers
387
+ * @example
388
+ * // Basic usage
389
+ * const required = Validation.required<string>();
390
+ * required(null); // => { success: false, error: 'Value is required' }
391
+ * required('hello'); // => { success: true, data: 'hello' }
392
+ *
393
+ * @example
394
+ * // Combining with other validators
395
+ * const validateName = Validation.all(
396
+ * Validation.required<string>('Name is required'),
397
+ * validators.string.minLength(2)
398
+ * );
399
+ *
400
+ * @since 2025-07-03
401
+ */
402
+ required: <T>(error?: string) => Validator<T | null | undefined>;
403
+ /**
404
+ * Validates each item in an array.
405
+ * @description Applies the same validator to each element of an array,
406
+ * collecting all errors with their indices. Returns a new array with
407
+ * validated (and possibly transformed) items.
408
+ *
409
+ * @template T - The type of array elements
410
+ * @param {Validator<T>} itemValidator - Validator to apply to each item
411
+ * @returns {Validator<T[]>} A validator for arrays
412
+ *
413
+ * @category Collections
414
+ * @example
415
+ * // Validate array of emails
416
+ * const validateEmails = Validation.array(
417
+ * validators.string.email()
418
+ * );
419
+ *
420
+ * const result = validateEmails([
421
+ * 'user@example.com',
422
+ * 'invalid-email',
423
+ * 'admin@example.com'
424
+ * ]);
425
+ * // Error: "[1]: Invalid email format"
426
+ *
427
+ * @example
428
+ * // Complex item validation
429
+ * const validateUsers = Validation.array(
430
+ * schema({
431
+ * name: validators.string.nonEmpty(),
432
+ * age: validators.number.positive()
433
+ * })
434
+ * );
435
+ *
436
+ * @since 2025-07-03
437
+ */
438
+ array: <T>(itemValidator: Validator<T>) => Validator<T[]>;
439
+ /**
440
+ * Validates properties of an object.
441
+ * @description Validates specified properties of an object using individual
442
+ * validators. Unspecified properties are passed through unchanged. Errors
443
+ * are prefixed with the property name for clarity.
444
+ *
445
+ * @template T - The object type
446
+ * @param {object} validators - Map of property names to validators
447
+ * @returns {Validator<T>} A validator for the object
448
+ *
449
+ * @category Objects
450
+ * @example
451
+ * // Partial object validation
452
+ * const validatePerson = Validation.object({
453
+ * name: validators.string.nonEmpty(),
454
+ * age: validators.number.positive()
455
+ * });
456
+ *
457
+ * const result = validatePerson({
458
+ * name: 'John',
459
+ * age: -5,
460
+ * extra: 'ignored'
461
+ * });
462
+ * // Error: "age: Number must be positive"
463
+ *
464
+ * @see schema - Type-safe alternative for complete object validation
465
+ * @since 2025-07-03
466
+ */
467
+ object: <T extends Record<string, any>>(validators: { [K in keyof T]?: Validator<T[K]>; }) => Validator<T>;
468
+ };
469
+ /**
470
+ * Common validators for primitive types.
471
+ * @description Pre-built validators for common validation scenarios.
472
+ * These validators can be used directly or combined with the Validation
473
+ * combinators to create more complex validation logic.
474
+ *
475
+ * @category Validators
476
+ * @example
477
+ * // Using validators directly
478
+ * const emailValidator = validators.string.email();
479
+ * const ageValidator = validators.number.between(0, 150);
480
+ *
481
+ * @example
482
+ * // Combining validators
483
+ * const strongPassword = Validation.all(
484
+ * validators.string.minLength(12),
485
+ * validators.string.matches(/[A-Z]/, 'Need uppercase'),
486
+ * validators.string.matches(/[a-z]/, 'Need lowercase'),
487
+ * validators.string.matches(/[0-9]/, 'Need number')
488
+ * );
489
+ *
490
+ * @since 2025-07-03
491
+ */
492
+ export declare const validators: {
493
+ /**
494
+ * String validators.
495
+ * @description Validators for string values including length checks,
496
+ * format validation, and pattern matching.
497
+ *
498
+ * @category String Validators
499
+ * @since 2025-07-03
500
+ */
501
+ string: {
502
+ minLength: (min: number) => Validator<string>;
503
+ maxLength: (max: number) => Validator<string>;
504
+ nonEmpty: () => Validator<string>;
505
+ email: () => Validator<string>;
506
+ url: () => Validator<string>;
507
+ matches: (pattern: RegExp, error?: string) => Validator<string>;
508
+ oneOf: (options: string[]) => Validator<string>;
509
+ };
510
+ /**
511
+ * Number validators.
512
+ */
513
+ number: {
514
+ min: (min: number) => Validator<number>;
515
+ max: (max: number) => Validator<number>;
516
+ positive: () => Validator<number>;
517
+ nonNegative: () => Validator<number>;
518
+ integer: () => Validator<number>;
519
+ between: (min: number, max: number) => Validator<number>;
520
+ };
521
+ /**
522
+ * Array validators.
523
+ */
524
+ array: {
525
+ minLength: <T>(min: number) => Validator<T[]>;
526
+ maxLength: <T>(max: number) => Validator<T[]>;
527
+ nonEmpty: <T>() => Validator<T[]>;
528
+ unique: <T>() => Validator<T[]>;
529
+ };
530
+ /**
531
+ * Date validators.
532
+ */
533
+ date: {
534
+ after: (date: Date) => Validator<Date>;
535
+ before: (date: Date) => Validator<Date>;
536
+ future: () => Validator<Date>;
537
+ past: () => Validator<Date>;
538
+ };
539
+ /**
540
+ * Object validators.
541
+ */
542
+ object: {
543
+ hasProperty: <T extends object>(prop: keyof T) => Validator<T>;
544
+ notEmpty: () => Validator<Record<string, any>>;
545
+ };
546
+ };
547
+ /**
548
+ * Utility for creating complex validation schemas.
549
+ * @description Type-safe wrapper around Validation.object that requires
550
+ * validators for all properties of the type. This ensures complete
551
+ * validation coverage for object types.
552
+ *
553
+ * @template T - The object type to validate
554
+ * @param {object} validators - Validators for each property of T
555
+ * @returns {Validator<T>} A validator for objects of type T
556
+ *
557
+ * @category Schema
558
+ * @example
559
+ * // Type-safe user validation
560
+ * interface User {
561
+ * name: string;
562
+ * email: string;
563
+ * age: number;
564
+ * }
565
+ *
566
+ * const userValidator = schema<User>({
567
+ * name: validators.string.nonEmpty(),
568
+ * email: validators.string.email(),
569
+ * age: validators.number.between(0, 150)
570
+ * });
571
+ *
572
+ * @example
573
+ * // Nested schemas
574
+ * const addressValidator = schema({
575
+ * street: validators.string.nonEmpty(),
576
+ * city: validators.string.nonEmpty(),
577
+ * zipCode: validators.string.matches(/^\d{5}$/)
578
+ * });
579
+ *
580
+ * const personValidator = schema({
581
+ * name: validators.string.nonEmpty(),
582
+ * address: addressValidator
583
+ * });
584
+ *
585
+ * @since 2025-07-03
586
+ */
587
+ export declare const schema: <T extends Record<string, any>>(validators: { [K in keyof T]: Validator<T[K]>; }) => Validator<T>;
588
+ /**
589
+ * Validates a value and returns either the validated value or throws the error.
590
+ * @description Use sparingly, only when you're certain validation should pass.
591
+ * This bridges the Result-based validation system with exception-based code.
592
+ *
593
+ * @template T - The type being validated
594
+ * @param {Validator<T>} validator - The validator to apply
595
+ * @returns {function(T): T} A function that validates or throws
596
+ * @throws {ValidationError} If validation fails
597
+ *
598
+ * @category Utilities
599
+ * @example
600
+ * // Configuration validation at startup
601
+ * const validateConfig = validateOrThrow(
602
+ * schema({
603
+ * port: validators.number.between(1, 65535),
604
+ * host: validators.string.nonEmpty()
605
+ * })
606
+ * );
607
+ *
608
+ * // Throws if invalid, otherwise returns validated config
609
+ * const config = validateConfig(loadConfig());
610
+ *
611
+ * @example
612
+ * // Input sanitization
613
+ * const sanitizeEmail = validateOrThrow(
614
+ * Validation.map((s: string) => s.toLowerCase())(
615
+ * validators.string.email()
616
+ * )
617
+ * );
618
+ *
619
+ * @since 2025-07-03
620
+ */
621
+ export declare const validateOrThrow: <T>(validator: Validator<T>) => (value: T) => T;
622
+ //# sourceMappingURL=validation.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.mts","sourceRoot":"","sources":["../src/validation.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAMZ,MAAM,EAAE,MAAM,EAAE;IAL5C;;;;OAIG;gBACyB,MAAM,EAAE,MAAM,EAAE;IAK5C;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,eAAe;IAI/C;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC;;;;;;;;;;;;OAYG;IACH,UAAU,IAAI,MAAM,GAAG,SAAS;CAGjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU;IACrB;;;;;;;;;;;;;;;;OAgBG;cAEA,CAAC,OAAM,SAAS,CAAC,CAAC,CAAC;IAItB;;;;;;;;;;;;;;;;;OAiBG;cAEA,CAAC,SAAU,MAAM,KAAG,SAAS,CAAC,CAAC,CAAC;IAInC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;oBAEA,CAAC,aAAc,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,SAAS,MAAM,KAAG,SAAS,CAAC,CAAC,CAAC;IAMrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;UAEA,CAAC,iBAAkB,SAAS,CAAC,CAAC,CAAC,EAAE,KAAG,SAAS,CAAC,CAAC,CAAC;IAgBnD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;UAEA,CAAC,iBAAkB,SAAS,CAAC,CAAC,CAAC,EAAE,KAAG,SAAS,CAAC,CAAC,CAAC;IAgBnD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;UAEA,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,iBACd,SAAS,CAAC,CAAC,CAAC,KAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IAOvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;cAEA,CAAC,MAAO,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,iBACvB,SAAS,CAAC,CAAC,CAAC,KAAG,SAAS,CAAC,CAAC,CAAC;IAczC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;eAEA,CAAC,aAAc,SAAS,CAAC,CAAC,CAAC,KAAG,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAQhE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;eAEA,CAAC,qBAEC,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAQpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;YAEA,CAAC,iBAAkB,SAAS,CAAC,CAAC,CAAC,KAAG,SAAS,CAAC,CAAC,EAAE,CAAC;IAqBnD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;aAGA,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,GACzC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjC,KAAG,SAAS,CAAC,CAAC,CAAC;CAuBnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,UAAU;IACrB;;;;;;;OAOG;;yBAEgB,MAAM,KAAG,SAAS,CAAC,MAAM,CAAC;yBAM1B,MAAM,KAAG,SAAS,CAAC,MAAM,CAAC;wBAM7B,SAAS,CAAC,MAAM,CAAC;qBAMpB,SAAS,CAAC,MAAM,CAAC;mBAOnB,SAAS,CAAC,MAAM,CAAC;2BAWf,MAAM,qBAEd,SAAS,CAAC,MAAM,CAAC;yBAGH,MAAM,EAAE,KAAG,SAAS,CAAC,MAAM,CAAC;;IAO/C;;OAEG;;mBAEU,MAAM,KAAG,SAAS,CAAC,MAAM,CAAC;mBAM1B,MAAM,KAAG,SAAS,CAAC,MAAM,CAAC;wBAMvB,SAAS,CAAC,MAAM,CAAC;2BAMd,SAAS,CAAC,MAAM,CAAC;uBAMrB,SAAS,CAAC,MAAM,CAAC;uBAMf,MAAM,OAAO,MAAM,KAAG,SAAS,CAAC,MAAM,CAAC;;IAOxD;;OAEG;;oBAEW,CAAC,OAAQ,MAAM,KAAG,SAAS,CAAC,CAAC,EAAE,CAAC;oBAMhC,CAAC,OAAQ,MAAM,KAAG,SAAS,CAAC,CAAC,EAAE,CAAC;mBAMjC,CAAC,OAAM,SAAS,CAAC,CAAC,EAAE,CAAC;iBAMvB,CAAC,OAAM,SAAS,CAAC,CAAC,EAAE,CAAC;;IAOhC;;OAEG;;sBAEa,IAAI,KAAG,SAAS,CAAC,IAAI,CAAC;uBAMrB,IAAI,KAAG,SAAS,CAAC,IAAI,CAAC;sBAMzB,SAAS,CAAC,IAAI,CAAC;oBAMjB,SAAS,CAAC,IAAI,CAAC;;IAO3B;;OAEG;;sBAEa,CAAC,SAAS,MAAM,QAAQ,MAAM,CAAC,KAAG,SAAS,CAAC,CAAC,CAAC;wBAO9C,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;;CAO/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,GAC/D,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAChC,KAAG,SAAS,CAAC,CAAC,CAAkC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,eAAe,GACzB,CAAC,aAAc,SAAS,CAAC,CAAC,CAAC,aACpB,CAAC,KAAG,CAOX,CAAC"}