11import type { Assert as BaseAssert , Constraint as BaseConstraint } from 'validator.js' ;
22import type { ValidatorJSAsserts } from 'validator.js-asserts' ;
33
4+ /**
5+ * A recursive map of validation failures, keyed by property name.
6+ *
7+ * Returned by `Constraint.check()` when validation fails
8+ * (returns `true` on success).
9+ *
10+ * Each property maps to:
11+ *
12+ * - A single `Violation` — when a property-level check (e.g., `HaveProperty`) fails.
13+ * - A `Violation[]` — when one or more asserts on that property fail.
14+ * - A nested `ValidationErrors` — when a nested constraint or `Collection` assert fails.
15+ * @todo Add a `Violation` type.
16+ */
17+ type ValidationErrors = {
18+ [ property : string ] : unknown | unknown [ ] | ValidationErrors ;
19+ } ;
20+
421/**
522 * The instance‐side of an Assert (no static factory methods).
623 * All core “is.X()” methods and custom asserts produce this.
724 */
825interface AssertInstance {
926 /** Returns `true` if the value passes, otherwise returns a Violation/object. */
10- check ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true | any ;
27+ check ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true | ValidationErrors ;
1128 /** Throws on failure; returns `true` if the value passes. */
1229 validate ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true ;
1330 /** Does this assert apply to the given validation group(s)? */
@@ -22,29 +39,29 @@ interface AssertInstance {
2239
2340/**
2441 * The instance‐side of a Constraint (no static/constructor methods).
25- * Mirrors the Assert API but for Constraint objects.
42+ * Mirrors the API but for Constraint objects.
2643 */
2744interface ConstraintInstance extends BaseConstraint {
28- /** Check if value matches the constraint */
29- check ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true | any ;
30- /** Validate the value against the constraint */
45+ /** Check if value matches the constraint. */
46+ check ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true | ValidationErrors ;
47+ /** Validate the value against the constraint. */
3148 validate ( value : unknown , group ?: string | string [ ] , context ?: unknown ) : true ;
32- /** Check if the constraint requires validation */
49+ /** Check if the constraint requires validation. */
3350 requiresValidation ( group ?: string | string [ ] ) : boolean ;
34- /** Check if the constraint belongs to a specific group */
51+ /** Check if the constraint belongs to a specific group. */
3552 hasGroup ( group : string | string [ ] ) : boolean ;
36- /** Check `hasGroup` over the specified groups */
53+ /** Check `hasGroup` over the specified groups. */
3754 hasOneOf ( groups : string [ ] ) : boolean ;
38- /** Check if the constraint has any groups */
55+ /** Check if the constraint has any groups. */
3956 hasGroups ( ) : boolean ;
4057}
4158
4259/**
4360 * Valid types that can appear in a constraint mapping:
44- * - an Assert instance
45- * - a Constraint instance
46- * - a nested object mapping
47- * - an array of any of the above
61+ * - An Assert instance.
62+ * - A Constraint instance.
63+ * - A nested object mapping.
64+ * - An array of any of the above.
4865 */
4966type ConstraintValue =
5067 | BaseAssert
@@ -149,11 +166,14 @@ interface BaseValidatorJSAsserts {
149166 * If the user passes an object of `extraAsserts` (e.g. `{ MyFoo: () => new FooAssert() }`),
150167 * this type will expose each key as a lowercase method returning `AssertInstance`.
151168 */
152- type ExtraAsserts < EA > = EA extends Record < string , any >
153- ? {
154- [ K in keyof EA as Uncapitalize < string & K > ] : ( ) => AssertInstance ;
155- }
156- : { } ;
169+ type ExtraAsserts < EA > =
170+ EA extends Record < string , unknown >
171+ ? {
172+ [ K in keyof EA as Uncapitalize < string & K > ] : ( ) => AssertInstance ;
173+ }
174+ : {
175+ [ K in never ] : never ;
176+ } ;
157177
158178/** Callable/newable `Assert` constructor function itself. */
159179interface BaseAssertStatic {
@@ -169,9 +189,9 @@ interface BaseAssertStatic {
169189 * - Any user‐passed `extraAsserts` (lowercased).
170190 */
171191type AssertStatic < EA > = BaseAssertStatic &
172- Omit < BaseValidatorJSAsserts , 'callback' > &
173- ValidatorJSAsserts &
174- ExtraAsserts < EA > ;
192+ Omit < BaseValidatorJSAsserts , 'callback' > &
193+ ValidatorJSAsserts &
194+ ExtraAsserts < EA > ;
175195
176196/**
177197 * Given a type `T`, map each key to either:
@@ -188,25 +208,52 @@ type ConstraintMapping<T> =
188208type ValidateFunction = < T > ( data : unknown , constraints : ConstraintMapping < T > | Record < string , ConstraintValue > ) => T ;
189209
190210/** Custom Error type for `AssertionError`/`ValidationError`. */
191- type ValidatorErrorType = new ( ...args : any [ ] ) => Error ;
211+ type ValidatorErrorType = new ( errors : ValidationErrors ) => Error ;
212+
213+ /**
214+ * A logging function called with the (potentially obfuscated) validation errors
215+ * just before the error is thrown. Defaults to a no-op.
216+ */
217+ type ValidatorLogger = ( errors : ValidationErrors ) => void ;
218+
219+ /**
220+ * An obfuscation function that can transform/redact the `errors` map before
221+ * it is passed to the logger and to the Error constructor.
222+ * Must return an object with the same `{ errors }` shape.
223+ * Defaults to the identity function.
224+ */
225+ type ValidatorObfuscator = ( input : { errors : ValidationErrors } ) => { errors : ValidationErrors } ;
226+
227+ /**
228+ * Common options shared by all overloads of the `validator()` factory.
229+ */
230+ interface ValidatorBaseOptions {
231+ logger ?: ValidatorLogger ;
232+ obfuscator ?: ValidatorObfuscator ;
233+ mask ?: boolean ;
234+ }
192235
193236/** You always get an `{ is: AssertStatic<EA> }` back. */
194- interface BaseValidatorExports < EA = any > {
237+ /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
238+ interface BaseValidatorExports < EA = { } > {
195239 is : AssertStatic < EA > ;
196240}
197241
198242/** If `AssertionError` was passed, you also get `assert(data, …)`. */
199- interface ValidatorExportsWithAssert < EA = any > extends BaseValidatorExports < EA > {
243+ /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
244+ interface ValidatorExportsWithAssert < EA = { } > extends BaseValidatorExports < EA > {
200245 assert : ValidateFunction ;
201246}
202247
203248/** If `ValidationError` was passed, you also get `validate(data, …)`. */
204- interface ValidatorExportsWithValidate < EA = any > extends BaseValidatorExports < EA > {
249+ /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
250+ interface ValidatorExportsWithValidate < EA = { } > extends BaseValidatorExports < EA > {
205251 validate : ValidateFunction ;
206252}
207253
208254/** If both errors were passed, you get both `assert` and `validate`. */
209- interface ValidatorExportsWithBoth < EA = any > extends BaseValidatorExports < EA > {
255+ /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
256+ interface ValidatorExportsWithBoth < EA = { } > extends BaseValidatorExports < EA > {
210257 assert : ValidateFunction ;
211258 validate : ValidateFunction ;
212259}
@@ -215,73 +262,62 @@ interface ValidatorExportsWithBoth<EA = any> extends BaseValidatorExports<EA> {
215262 * Create a new validator instance.
216263 * TypeScript will infer `EA` from the shape of `options.extraAsserts`.
217264 *
218- * - If you supply both `AssertionError` and `ValidationError`, you get: `{ is, assert, validate }`
265+ * - If you supply both `AssertionError` and `ValidationError`, you get: `{ is, assert, validate }`.
219266 * - If you supply only one of them, you get exactly that method plus `is`.
220267 * - If you supply neither, you get only `{ is }`.
221268 */
222- declare function validator < EA extends Record < string , any > > ( options : {
223- AssertionError : ValidatorErrorType ;
224- ValidationError : ValidatorErrorType ;
225- extraAsserts : EA ;
226- logger ?: ( errors : any ) => void ;
227- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
228- mask ?: boolean ;
229- } ) : ValidatorExportsWithBoth < EA > ;
230-
231- declare function validator ( options : {
232- AssertionError : ValidatorErrorType ;
233- ValidationError : ValidatorErrorType ;
234- extraAsserts ?: undefined ;
235- logger ?: ( errors : any ) => void ;
236- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
237- mask ?: boolean ;
238- } ) : ValidatorExportsWithBoth < { } > ;
239-
240- declare function validator < EA extends Record < string , any > > ( options : {
241- AssertionError : ValidatorErrorType ;
242- extraAsserts : EA ;
243- logger ?: ( errors : any ) => void ;
244- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
245- mask ?: boolean ;
246- } ) : ValidatorExportsWithAssert < EA > ;
247-
248- declare function validator ( options : {
249- AssertionError : ValidatorErrorType ;
250- extraAsserts ?: undefined ;
251- logger ?: ( errors : any ) => void ;
252- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
253- mask ?: boolean ;
254- } ) : ValidatorExportsWithAssert < { } > ;
255269
256- declare function validator < EA extends Record < string , any > > ( options : {
257- ValidationError : ValidatorErrorType ;
258- extraAsserts : EA ;
259- logger ?: ( errors : any ) => void ;
260- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
261- mask ?: boolean ;
262- } ) : ValidatorExportsWithValidate < EA > ;
263-
264- declare function validator ( options : {
265- ValidationError : ValidatorErrorType ;
266- extraAsserts ?: undefined ;
267- logger ?: ( errors : any ) => void ;
268- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
269- mask ?: boolean ;
270- } ) : ValidatorExportsWithValidate < { } > ;
271-
272- declare function validator < EA extends Record < string , any > > ( options ?: {
273- extraAsserts : EA ;
274- logger ?: ( errors : any ) => void ;
275- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
276- mask ?: boolean ;
277- } ) : BaseValidatorExports < EA > ;
278-
279- declare function validator ( options ?: {
280- extraAsserts ?: undefined ;
281- logger ?: ( errors : any ) => void ;
282- obfuscator ?: ( input : { errors : any } ) => { errors : any } ;
283- mask ?: boolean ;
284- } ) : BaseValidatorExports < { } > ;
270+ declare function validator < EA extends Record < string , unknown > > (
271+ options : {
272+ AssertionError : ValidatorErrorType ;
273+ ValidationError : ValidatorErrorType ;
274+ extraAsserts : EA ;
275+ } & ValidatorBaseOptions
276+ ) : ValidatorExportsWithBoth < EA > ;
277+
278+ declare function validator (
279+ options : {
280+ AssertionError : ValidatorErrorType ;
281+ ValidationError : ValidatorErrorType ;
282+ extraAsserts ?: undefined ;
283+ } & ValidatorBaseOptions
284+ ) : ValidatorExportsWithBoth ;
285+
286+ declare function validator < EA extends Record < string , unknown > > (
287+ options : {
288+ AssertionError : ValidatorErrorType ;
289+ extraAsserts : EA ;
290+ } & ValidatorBaseOptions
291+ ) : ValidatorExportsWithAssert < EA > ;
292+
293+ declare function validator (
294+ options : {
295+ AssertionError : ValidatorErrorType ;
296+ extraAsserts ?: undefined ;
297+ } & ValidatorBaseOptions
298+ ) : ValidatorExportsWithAssert ;
299+
300+ declare function validator < EA extends Record < string , unknown > > (
301+ options : {
302+ ValidationError : ValidatorErrorType ;
303+ extraAsserts : EA ;
304+ } & ValidatorBaseOptions
305+ ) : ValidatorExportsWithValidate < EA > ;
306+
307+ declare function validator (
308+ options : {
309+ ValidationError : ValidatorErrorType ;
310+ extraAsserts ?: undefined ;
311+ } & ValidatorBaseOptions
312+ ) : ValidatorExportsWithValidate ;
313+
314+ declare function validator < EA extends Record < string , unknown > > (
315+ options : {
316+ extraAsserts : EA ;
317+ } & ValidatorBaseOptions
318+ ) : BaseValidatorExports < EA > ;
319+
320+ declare function validator ( options ?: ValidatorBaseOptions ) : BaseValidatorExports ;
285321
286322/**
287323 * Export `validator`.
0 commit comments