@amazon/vinyl-validation 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1325 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.js +1308 -0
- package/dist/index.js.map +7 -0
- package/dist/types/current/index.d.ts +18 -0
- package/dist/types/current/index.d.ts.map +1 -0
- package/dist/types/current/index.js +17 -0
- package/dist/types/current/tsconfig.tsbuildinfo +1 -0
- package/dist/types/current/validation/ArraySchema.d.ts +82 -0
- package/dist/types/current/validation/ArraySchema.d.ts.map +1 -0
- package/dist/types/current/validation/ArraySchema.js +148 -0
- package/dist/types/current/validation/FunctionSchema.d.ts +21 -0
- package/dist/types/current/validation/FunctionSchema.d.ts.map +1 -0
- package/dist/types/current/validation/FunctionSchema.js +42 -0
- package/dist/types/current/validation/NumberSchema.d.ts +100 -0
- package/dist/types/current/validation/NumberSchema.d.ts.map +1 -0
- package/dist/types/current/validation/NumberSchema.js +146 -0
- package/dist/types/current/validation/ObjectSchema.d.ts +54 -0
- package/dist/types/current/validation/ObjectSchema.d.ts.map +1 -0
- package/dist/types/current/validation/ObjectSchema.js +125 -0
- package/dist/types/current/validation/PropertyValidator.d.ts +23 -0
- package/dist/types/current/validation/PropertyValidator.d.ts.map +1 -0
- package/dist/types/current/validation/PropertyValidator.js +5 -0
- package/dist/types/current/validation/RecordSchema.d.ts +58 -0
- package/dist/types/current/validation/RecordSchema.d.ts.map +1 -0
- package/dist/types/current/validation/RecordSchema.js +101 -0
- package/dist/types/current/validation/SchemaBase.d.ts +65 -0
- package/dist/types/current/validation/SchemaBase.d.ts.map +1 -0
- package/dist/types/current/validation/SchemaBase.js +90 -0
- package/dist/types/current/validation/SetSchema.d.ts +38 -0
- package/dist/types/current/validation/SetSchema.d.ts.map +1 -0
- package/dist/types/current/validation/SetSchema.js +74 -0
- package/dist/types/current/validation/StringSchema.d.ts +68 -0
- package/dist/types/current/validation/StringSchema.d.ts.map +1 -0
- package/dist/types/current/validation/StringSchema.js +109 -0
- package/dist/types/current/validation/Validator.d.ts +88 -0
- package/dist/types/current/validation/Validator.d.ts.map +1 -0
- package/dist/types/current/validation/Validator.js +95 -0
- package/dist/types/current/validation/ValidatorWithPartial.d.ts +26 -0
- package/dist/types/current/validation/ValidatorWithPartial.d.ts.map +1 -0
- package/dist/types/current/validation/ValidatorWithPartial.js +31 -0
- package/dist/types/current/validation/ValueSchema.d.ts +52 -0
- package/dist/types/current/validation/ValueSchema.d.ts.map +1 -0
- package/dist/types/current/validation/ValueSchema.js +81 -0
- package/dist/types/current/validation/andValidators.d.ts +19 -0
- package/dist/types/current/validation/andValidators.d.ts.map +1 -0
- package/dist/types/current/validation/andValidators.js +48 -0
- package/dist/types/current/validation/orValidators.d.ts +19 -0
- package/dist/types/current/validation/orValidators.d.ts.map +1 -0
- package/dist/types/current/validation/orValidators.js +74 -0
- package/dist/types/current/validation/typeOfValidators.d.ts +15 -0
- package/dist/types/current/validation/typeOfValidators.d.ts.map +1 -0
- package/dist/types/current/validation/typeOfValidators.js +58 -0
- package/dist/types/current/validation/validators.d.ts +127 -0
- package/dist/types/current/validation/validators.d.ts.map +1 -0
- package/dist/types/current/validation/validators.js +168 -0
- package/dist/types/ts3.7/index.d.ts +18 -0
- package/dist/types/ts3.7/validation/ArraySchema.d.ts +86 -0
- package/dist/types/ts3.7/validation/FunctionSchema.d.ts +21 -0
- package/dist/types/ts3.7/validation/NumberSchema.d.ts +100 -0
- package/dist/types/ts3.7/validation/ObjectSchema.d.ts +56 -0
- package/dist/types/ts3.7/validation/PropertyValidator.d.ts +23 -0
- package/dist/types/ts3.7/validation/RecordSchema.d.ts +58 -0
- package/dist/types/ts3.7/validation/SchemaBase.d.ts +65 -0
- package/dist/types/ts3.7/validation/SetSchema.d.ts +38 -0
- package/dist/types/ts3.7/validation/StringSchema.d.ts +68 -0
- package/dist/types/ts3.7/validation/Validator.d.ts +88 -0
- package/dist/types/ts3.7/validation/ValidatorWithPartial.d.ts +26 -0
- package/dist/types/ts3.7/validation/ValueSchema.d.ts +52 -0
- package/dist/types/ts3.7/validation/andValidators.d.ts +19 -0
- package/dist/types/ts3.7/validation/orValidators.d.ts +19 -0
- package/dist/types/ts3.7/validation/typeOfValidators.d.ts +15 -0
- package/dist/types/ts3.7/validation/validators.d.ts +127 -0
- package/dist/types/ts4.1/index.d.ts +18 -0
- package/dist/types/ts4.1/validation/ArraySchema.d.ts +86 -0
- package/dist/types/ts4.1/validation/FunctionSchema.d.ts +21 -0
- package/dist/types/ts4.1/validation/NumberSchema.d.ts +100 -0
- package/dist/types/ts4.1/validation/ObjectSchema.d.ts +56 -0
- package/dist/types/ts4.1/validation/PropertyValidator.d.ts +23 -0
- package/dist/types/ts4.1/validation/RecordSchema.d.ts +58 -0
- package/dist/types/ts4.1/validation/SchemaBase.d.ts +65 -0
- package/dist/types/ts4.1/validation/SetSchema.d.ts +38 -0
- package/dist/types/ts4.1/validation/StringSchema.d.ts +68 -0
- package/dist/types/ts4.1/validation/Validator.d.ts +88 -0
- package/dist/types/ts4.1/validation/ValidatorWithPartial.d.ts +26 -0
- package/dist/types/ts4.1/validation/ValueSchema.d.ts +52 -0
- package/dist/types/ts4.1/validation/andValidators.d.ts +19 -0
- package/dist/types/ts4.1/validation/orValidators.d.ts +19 -0
- package/dist/types/ts4.1/validation/typeOfValidators.d.ts +15 -0
- package/dist/types/ts4.1/validation/validators.d.ts +128 -0
- package/dist/types/ts4.7/index.d.ts +18 -0
- package/dist/types/ts4.7/validation/ArraySchema.d.ts +86 -0
- package/dist/types/ts4.7/validation/FunctionSchema.d.ts +21 -0
- package/dist/types/ts4.7/validation/NumberSchema.d.ts +100 -0
- package/dist/types/ts4.7/validation/ObjectSchema.d.ts +56 -0
- package/dist/types/ts4.7/validation/PropertyValidator.d.ts +23 -0
- package/dist/types/ts4.7/validation/RecordSchema.d.ts +58 -0
- package/dist/types/ts4.7/validation/SchemaBase.d.ts +65 -0
- package/dist/types/ts4.7/validation/SetSchema.d.ts +38 -0
- package/dist/types/ts4.7/validation/StringSchema.d.ts +68 -0
- package/dist/types/ts4.7/validation/Validator.d.ts +88 -0
- package/dist/types/ts4.7/validation/ValidatorWithPartial.d.ts +26 -0
- package/dist/types/ts4.7/validation/ValueSchema.d.ts +52 -0
- package/dist/types/ts4.7/validation/andValidators.d.ts +19 -0
- package/dist/types/ts4.7/validation/orValidators.d.ts +19 -0
- package/dist/types/ts4.7/validation/typeOfValidators.d.ts +15 -0
- package/dist/types/ts4.7/validation/validators.d.ts +127 -0
- package/docs/VALIDATION.md +344 -0
- package/package.json +82 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type Invariant } from '@amazon/vinyl-util';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a validation failure.
|
|
4
|
+
*/
|
|
5
|
+
export interface ValidationErrorMessage {
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly path: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface ValidationOptions {
|
|
10
|
+
/**
|
|
11
|
+
* If true, collect all validation errors.
|
|
12
|
+
* Default: false
|
|
13
|
+
*/
|
|
14
|
+
readonly all?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A Validator can assert that an input matches this validator's schema.
|
|
18
|
+
*/
|
|
19
|
+
export interface Validator<Output extends Input, in Input = unknown> {
|
|
20
|
+
/**
|
|
21
|
+
* Enforces T is in an invariant position.
|
|
22
|
+
* This prevents a validator with more strict rules is assigned to a less strict type, which
|
|
23
|
+
* can cause unexpected validation errors.
|
|
24
|
+
*/
|
|
25
|
+
__type?: Invariant<Output>;
|
|
26
|
+
/**
|
|
27
|
+
* A short description of the validator.
|
|
28
|
+
*/
|
|
29
|
+
readonly description: string;
|
|
30
|
+
/**
|
|
31
|
+
* Returns true if the input is valid according to this validator.
|
|
32
|
+
*
|
|
33
|
+
* @param input
|
|
34
|
+
*/
|
|
35
|
+
readonly isValid: (input: Input) => input is Output;
|
|
36
|
+
/**
|
|
37
|
+
* Validates the provided input, returning a list of error messages, or an empty array if the
|
|
38
|
+
* input passes this validator.
|
|
39
|
+
*
|
|
40
|
+
* @param input The input to validate.
|
|
41
|
+
* @param options Validation options.
|
|
42
|
+
* @param path The current field path to this validator.
|
|
43
|
+
* @return Returns an array of validation failures. If `options.all` is not true, only the
|
|
44
|
+
* first error will be returned.
|
|
45
|
+
*/
|
|
46
|
+
readonly validate: (input: Input, options?: ValidationOptions, path?: readonly string[]) => readonly ValidationErrorMessage[];
|
|
47
|
+
/**
|
|
48
|
+
* Validates the given input, asserting that the input is type `T`.
|
|
49
|
+
* If the input is not valid, a {@link ValidationError} will be thrown.
|
|
50
|
+
*
|
|
51
|
+
* @param input The input to validate.
|
|
52
|
+
* @param origin The error origin. `ErrorOrigin.API` by default.
|
|
53
|
+
* @param path The current field path to this validator.
|
|
54
|
+
* @return Returns the input, cast as the validated type T
|
|
55
|
+
*/
|
|
56
|
+
readonly assert: (input: Input, origin?: string, path?: readonly string[]) => asserts input is Output;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Creates a message string for a ValidationErrorMessage based on the input and its expectation.
|
|
60
|
+
*
|
|
61
|
+
* @param expectationMessage
|
|
62
|
+
* @param input
|
|
63
|
+
* @param path
|
|
64
|
+
* @param inputStringify
|
|
65
|
+
*/
|
|
66
|
+
export declare function createValidationExpectationMessage<Input>(expectationMessage: string, input: Input, path: readonly string[], inputStringify?: (input: Input) => string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new basic validator.
|
|
69
|
+
*
|
|
70
|
+
* For a deep validator which has sub-fields, use {@link createDeepValidator}.
|
|
71
|
+
*
|
|
72
|
+
* @param expectationMessage The message to use to describe what is expected. This will be used in
|
|
73
|
+
* the error message template.
|
|
74
|
+
* @param isValid Returns true if the given input is valid.
|
|
75
|
+
* @param inputStringify Stringifies the input for use as the actual `{actual}` token in the validation
|
|
76
|
+
* expectation template. Default is `stringifyForPrint` with a 500 character max length.
|
|
77
|
+
*/
|
|
78
|
+
export declare function createValidator<Output extends Input, Input = unknown>(expectationMessage: string, isValid: (input: Input) => boolean, inputStringify?: (input: Input) => string): Validator<Output, Input>;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new deep validator.
|
|
81
|
+
*
|
|
82
|
+
* For a shallow validator which validates one value, use {@link createValidator}.
|
|
83
|
+
*
|
|
84
|
+
* @param description Describes the validator.
|
|
85
|
+
* @param validate Returns an array of validation failures.
|
|
86
|
+
*/
|
|
87
|
+
export declare function createDeepValidator<Output extends Input, Input = unknown>(description: string, validate: (input: Input, options: ValidationOptions, path: readonly string[]) => readonly ValidationErrorMessage[]): Validator<Output, Input>;
|
|
88
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PartialDeep } from '@amazon/vinyl-util';
|
|
2
|
+
import type { Validator } from './Validator';
|
|
3
|
+
export interface ValidatorWithPartial<Output extends Input, Input> extends Validator<Output, Input> {
|
|
4
|
+
partial(): ValidatorWithPartial<Partial<Output> & Input, Input>;
|
|
5
|
+
partialDeep(): ValidatorWithPartial<PartialDeep<Output> & Input, Input>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if the given validator is an object validator.
|
|
9
|
+
* @param validator
|
|
10
|
+
*/
|
|
11
|
+
export declare function isValidatorWithPartial<Output extends Input, Input>(validator: Validator<Output, Input>): validator is ValidatorWithPartial<Output, Input>;
|
|
12
|
+
/**
|
|
13
|
+
* If the given validator is an object validator, it will be cloned to a deep partial validator,
|
|
14
|
+
* otherwise returns the validator as is.
|
|
15
|
+
*
|
|
16
|
+
* @param validator
|
|
17
|
+
*/
|
|
18
|
+
export declare function maybeToDeepPartial(validator: Validator<any>): Validator<any>;
|
|
19
|
+
/**
|
|
20
|
+
* If the given validator is an object validator, it will be cloned to a partial validator,
|
|
21
|
+
* otherwise returns the validator as is.
|
|
22
|
+
*
|
|
23
|
+
* @param validator
|
|
24
|
+
*/
|
|
25
|
+
export declare function maybeToPartial(validator: Validator<any>): Validator<any>;
|
|
26
|
+
//# sourceMappingURL=ValidatorWithPartial.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SchemaBase } from './SchemaBase';
|
|
2
|
+
import type { Validator } from './Validator';
|
|
3
|
+
export declare const valueValidators: {
|
|
4
|
+
readonly any: () => Validator<any>;
|
|
5
|
+
/**
|
|
6
|
+
* Creates a validator that asserts that the input is nullish.
|
|
7
|
+
*/
|
|
8
|
+
readonly nullish: () => Validator<null | undefined>;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a validator that asserts that the input is strictly null.
|
|
11
|
+
*/
|
|
12
|
+
readonly null: () => Validator<null>;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a validator that asserts that the input is strictly undefined.
|
|
15
|
+
*/
|
|
16
|
+
readonly undefined: () => Validator<undefined>;
|
|
17
|
+
};
|
|
18
|
+
export declare class ValueSchema<T> extends SchemaBase<T> {
|
|
19
|
+
/**
|
|
20
|
+
* Prepends this validator allowing for null or undefined.
|
|
21
|
+
*/
|
|
22
|
+
maybe(): ValueSchema<T | undefined | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Prepends this validator allowing for null.
|
|
25
|
+
*/
|
|
26
|
+
orNull(): ValueSchema<T | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Prepends this validator allowing for undefined.
|
|
29
|
+
*/
|
|
30
|
+
orUndefined(): ValueSchema<T | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Returns a validator that asserts if this validator and the next passes.
|
|
33
|
+
*
|
|
34
|
+
* @see andValidators
|
|
35
|
+
*
|
|
36
|
+
* @param nextValidator The validator to run after the current.
|
|
37
|
+
* @return Returns a new ValueSchema intersecting this validator and the next.
|
|
38
|
+
*/
|
|
39
|
+
and<U>(nextValidator: Validator<U>): ValueSchema<T & U>;
|
|
40
|
+
/**
|
|
41
|
+
* Returns a validator that asserts if this validator or the next passes.
|
|
42
|
+
*
|
|
43
|
+
* Implementation note:
|
|
44
|
+
* subclasses should not change the schema instance returned unless all chainable validators
|
|
45
|
+
* accept input type 'unknown'.
|
|
46
|
+
*
|
|
47
|
+
* @param nextValidator The validator to run after the current.
|
|
48
|
+
* @return Returns a new ValueSchema providing the union of this validator and the next.
|
|
49
|
+
*/
|
|
50
|
+
or<U>(nextValidator: Validator<U, any>): ValueSchema<T | U>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ValueSchema.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Validator } from './Validator';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that all the given validators pass.
|
|
4
|
+
*/
|
|
5
|
+
export declare function andValidators<A extends Input, B, Input>(validatorA: Validator<A, Input>, validatorB: Validator<B, any>): Validator<A & B, Input>;
|
|
6
|
+
/**
|
|
7
|
+
* Validates that all the given validators pass.
|
|
8
|
+
*/
|
|
9
|
+
export declare function andValidators<A extends Input, B, C, Input>(validatorA: Validator<A, Input>, validatorB: Validator<B, any>, validatorC: Validator<C, any>): Validator<A & B & C, Input>;
|
|
10
|
+
/**
|
|
11
|
+
* Validates that all the given validators pass.
|
|
12
|
+
*/
|
|
13
|
+
export declare function andValidators<A extends Input, B, C, D, Input>(validatorA: Validator<A, Input>, validatorB: Validator<B, any>, validatorC: Validator<C, any>, validatorD: Validator<D, any>): Validator<A & B & C & D, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Validates that all the given validators pass.
|
|
16
|
+
*/
|
|
17
|
+
export declare function andValidators<A extends Input, B, C, D, E, Input>(validatorA: Validator<A, Input>, validatorB: Validator<B, any>, validatorC: Validator<C, any>, validatorD: Validator<D, any>, validatorE: Validator<E, any>): Validator<A & B & C & D & E, any>;
|
|
18
|
+
export declare function andValidators(...validators: Validator<any, any>[]): Validator<any, any>;
|
|
19
|
+
//# sourceMappingURL=andValidators.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Validator } from './Validator';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that one of the given validators pass.
|
|
4
|
+
*/
|
|
5
|
+
export declare function orValidators<A, B>(validatorA: Validator<A, any>, validatorB: Validator<B, any>): Validator<A | B, any>;
|
|
6
|
+
/**
|
|
7
|
+
* Validates that one of the given validators pass.
|
|
8
|
+
*/
|
|
9
|
+
export declare function orValidators<A, B, C>(validatorA: Validator<A, any>, validatorB: Validator<B, any>, validatorC: Validator<C, any>): Validator<A | B | C, any>;
|
|
10
|
+
/**
|
|
11
|
+
* Validates that one of the given validators pass.
|
|
12
|
+
*/
|
|
13
|
+
export declare function orValidators<A, B, C, D>(validatorA: Validator<A, any>, validatorB: Validator<B, any>, validatorC: Validator<C, any>, validatorD: Validator<D, any>): Validator<A | B | C | D, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Validates that one of the given validators pass.
|
|
16
|
+
*/
|
|
17
|
+
export declare function orValidators<A, B, C, D, E>(validatorA: Validator<A, any>, validatorB: Validator<B, any>, validatorC: Validator<C, any>, validatorD: Validator<D, any>, validatorE: Validator<E, any>): Validator<A | B | C | D | E, any>;
|
|
18
|
+
export declare function orValidators(...validators: Validator<any, any>[]): Validator<any, any>;
|
|
19
|
+
//# sourceMappingURL=orValidators.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Validator } from './Validator';
|
|
2
|
+
/**
|
|
3
|
+
* Validators asserting typeof input matches the expected value.
|
|
4
|
+
*
|
|
5
|
+
* Note: bigint is omitted; not all supported platforms can use BigInt.
|
|
6
|
+
*/
|
|
7
|
+
export declare const typeOfValidators: {
|
|
8
|
+
readonly boolean: Validator<boolean, unknown>;
|
|
9
|
+
readonly func: Validator<import("@amazon/vinyl-util").Fun, unknown>;
|
|
10
|
+
readonly number: Validator<number, unknown>;
|
|
11
|
+
readonly object: Validator<object, unknown>;
|
|
12
|
+
readonly string: Validator<string, unknown>;
|
|
13
|
+
readonly symbol: Validator<symbol, unknown>;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=typeOfValidators.d.ts.map
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { type AnyRecord, type Fun, type Primitive, type ReadonlyRecord } from '@amazon/vinyl-util';
|
|
2
|
+
import { ArraySchema } from './ArraySchema';
|
|
3
|
+
import { FunctionSchema } from './FunctionSchema';
|
|
4
|
+
import { SetSchema } from './SetSchema';
|
|
5
|
+
import { ValueSchema } from './ValueSchema';
|
|
6
|
+
import { NumberSchema } from './NumberSchema';
|
|
7
|
+
import { type ExtendedPropertyValidators, ObjectSchema } from './ObjectSchema';
|
|
8
|
+
import { RecordSchema } from './RecordSchema';
|
|
9
|
+
import { StringSchema } from './StringSchema';
|
|
10
|
+
import type { Validator } from './Validator';
|
|
11
|
+
/**
|
|
12
|
+
* Creates a no-op validator. The value can be any type.
|
|
13
|
+
*/
|
|
14
|
+
export declare function any(): ValueSchema<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a validator that asserts that the input is an array.
|
|
17
|
+
*/
|
|
18
|
+
export declare function array(): ArraySchema<unknown[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a validator that asserts that the input is an array and every element passes the
|
|
21
|
+
* given validator.
|
|
22
|
+
*
|
|
23
|
+
* @param elementValidator
|
|
24
|
+
*/
|
|
25
|
+
export declare function array<U>(elementValidator: Validator<U>): ArraySchema<U[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a validator that asserts that the input is a boolean.
|
|
28
|
+
*/
|
|
29
|
+
export declare function boolean(): ValueSchema<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a validator that asserts that the input is a function.
|
|
32
|
+
*/
|
|
33
|
+
export declare function func(): FunctionSchema<Fun>;
|
|
34
|
+
/**
|
|
35
|
+
* Validates that the input is an instanceof the given prototype.
|
|
36
|
+
* @param clazz
|
|
37
|
+
*/
|
|
38
|
+
export declare function instanceOf<T>(clazz: new (...args: any[]) => T): ValueSchema<T>;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a validator that asserts that the input is nullish or one of the given possible values.
|
|
41
|
+
*
|
|
42
|
+
* @param possibleValues
|
|
43
|
+
*/
|
|
44
|
+
export declare function isOneOf<U extends readonly Primitive[]>(...possibleValues: U): ValueSchema<U[number]>;
|
|
45
|
+
/**
|
|
46
|
+
* Creates a validator that asserts that the input is one of the values of the given enum.
|
|
47
|
+
*
|
|
48
|
+
* @param enumObject The enum to validate against.
|
|
49
|
+
*/
|
|
50
|
+
export declare function enumOf<T extends Record<string, Primitive>>(enumObject: T): ValueSchema<T[keyof T]>;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a validator that asserts that the input is null.
|
|
53
|
+
*/
|
|
54
|
+
export declare function exactlyNull(): Validator<null>;
|
|
55
|
+
/**
|
|
56
|
+
* Creates a validator that asserts that the input is nullish.
|
|
57
|
+
*/
|
|
58
|
+
export declare function nullish(): Validator<null | undefined>;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a validator that asserts that the input is a number.
|
|
61
|
+
*/
|
|
62
|
+
export declare function number(): NumberSchema;
|
|
63
|
+
/**
|
|
64
|
+
* Creates a validator that validates the input has properties that pass their respective
|
|
65
|
+
* validators.
|
|
66
|
+
*/
|
|
67
|
+
export declare function object<U extends object>(propertyValidators: ExtendedPropertyValidators<AnyRecord, U>): ObjectSchema<U>;
|
|
68
|
+
/**
|
|
69
|
+
* Returns a validator that asserts that the object's own enumerable properties has keys and
|
|
70
|
+
* values that match their respective validators.
|
|
71
|
+
*
|
|
72
|
+
* Prototype members are not included.
|
|
73
|
+
* Numeric keys are validated as strings. For example the object `{ [0]: 1 }` will be passed
|
|
74
|
+
* to the key validator as '0'.
|
|
75
|
+
*
|
|
76
|
+
* To assume string keys, use {@link recordValues}
|
|
77
|
+
*
|
|
78
|
+
* @param keyValidator Validates each key.
|
|
79
|
+
* @param valueValidator Validates each value.
|
|
80
|
+
*/
|
|
81
|
+
export declare function record<K extends string | symbol, V>(keyValidator: Validator<K>, valueValidator: Validator<V>): RecordSchema<ReadonlyRecord<K, V>>;
|
|
82
|
+
/**
|
|
83
|
+
* Returns a validator that asserts that the input object's own enumerable properties has
|
|
84
|
+
* string keys and values that match the given validator.
|
|
85
|
+
*
|
|
86
|
+
* Prototype members are not included.
|
|
87
|
+
*
|
|
88
|
+
* @param valueValidator Validates each value.
|
|
89
|
+
*/
|
|
90
|
+
export declare function recordValues<V>(valueValidator: Validator<V>): RecordSchema<Record<string, V>>;
|
|
91
|
+
/**
|
|
92
|
+
* Returns a validator that asserts the input is a set with elements that match the given
|
|
93
|
+
* element validator.
|
|
94
|
+
* @param elementValidator
|
|
95
|
+
*/
|
|
96
|
+
export declare function set<U>(elementValidator: Validator<U>): SetSchema<Set<U>>;
|
|
97
|
+
/**
|
|
98
|
+
* Creates a validator that asserts that the input is type 'string'.
|
|
99
|
+
*/
|
|
100
|
+
export declare function string(): StringSchema;
|
|
101
|
+
/**
|
|
102
|
+
* Creates a validator that asserts that the input array is a tuple whose elements match
|
|
103
|
+
* the given validators.
|
|
104
|
+
*
|
|
105
|
+
* @param validators
|
|
106
|
+
*/
|
|
107
|
+
export declare function tuple<U extends readonly any[]>(...validators: {
|
|
108
|
+
[Index in keyof U]: Validator<U[Index]>;
|
|
109
|
+
}): ArraySchema<{
|
|
110
|
+
[Index in keyof U]: U[Index];
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Creates a validator that asserts that the input is type 'symbol'.
|
|
114
|
+
*/
|
|
115
|
+
export declare function symbol(): ValueSchema<symbol>;
|
|
116
|
+
/**
|
|
117
|
+
* Creates a validator that asserts that the input is strictly undefined.
|
|
118
|
+
*/
|
|
119
|
+
export declare function exactlyUndefined(): ValueSchema<undefined>;
|
|
120
|
+
/**
|
|
121
|
+
* Returns a custom
|
|
122
|
+
* @param expectationMessage
|
|
123
|
+
* @param isValid
|
|
124
|
+
* @param inputStringify
|
|
125
|
+
*/
|
|
126
|
+
export declare function custom<T>(expectationMessage: string, isValid: (input: unknown) => boolean, inputStringify?: (input: unknown) => string): ValueSchema<T>;
|
|
127
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Validation
|
|
2
|
+
|
|
3
|
+
A TypeScript-first validation library for runtime type checking and schema
|
|
4
|
+
validation.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @amazon/vinyl-validation
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Basic Usage
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { string, number, object, array } from '@amazon/vinyl-validation'
|
|
16
|
+
|
|
17
|
+
// Create validators
|
|
18
|
+
const nameValidator = string().notEmpty()
|
|
19
|
+
const ageValidator = number().gte(0)
|
|
20
|
+
|
|
21
|
+
// Validate values
|
|
22
|
+
console.log(nameValidator.isValid('John')) // true
|
|
23
|
+
console.log(ageValidator.isValid(-5)) // false
|
|
24
|
+
|
|
25
|
+
// Get validation errors
|
|
26
|
+
const errors = nameValidator.validate('')
|
|
27
|
+
console.log(errors) // [{ message: 'Expected: not empty, but was: "". At: ', path: [] }]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Core Validators
|
|
31
|
+
|
|
32
|
+
### Primitive Types
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { string, number, boolean, symbol, any } from '@amazon/vinyl-validation'
|
|
36
|
+
|
|
37
|
+
const stringValidator = string()
|
|
38
|
+
const numberValidator = number()
|
|
39
|
+
const booleanValidator = boolean()
|
|
40
|
+
const symbolValidator = symbol()
|
|
41
|
+
const anyValidator = any() // accepts any value
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Null and Undefined
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import {
|
|
48
|
+
exactlyNull,
|
|
49
|
+
exactlyUndefined,
|
|
50
|
+
nullish,
|
|
51
|
+
} from '@amazon/vinyl-validation'
|
|
52
|
+
|
|
53
|
+
const nullValidator = exactlyNull() // only null
|
|
54
|
+
const undefinedValidator = exactlyUndefined() // only undefined
|
|
55
|
+
const nullishValidator = nullish() // null or undefined
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Value Matching
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { isOneOf, instanceOf } from '@amazon/vinyl-validation'
|
|
62
|
+
|
|
63
|
+
// Literal values
|
|
64
|
+
const statusValidator = isOneOf('active', 'inactive', 'pending')
|
|
65
|
+
|
|
66
|
+
// Instance checking
|
|
67
|
+
const dateValidator = instanceOf(Date)
|
|
68
|
+
const errorValidator = instanceOf(Error)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## String Validation
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { string } from '@amazon/vinyl-validation'
|
|
75
|
+
|
|
76
|
+
const validator = string()
|
|
77
|
+
.notEmpty() // not empty string
|
|
78
|
+
.minLength(3) // at least 3 characters
|
|
79
|
+
.maxLength(50) // at most 50 characters
|
|
80
|
+
.noWhitespace() // no whitespace characters
|
|
81
|
+
.matches(/^[a-z]+$/) // matches regex pattern
|
|
82
|
+
|
|
83
|
+
// Usage
|
|
84
|
+
validator.isValid('hello') // true
|
|
85
|
+
validator.isValid('') // false (empty)
|
|
86
|
+
validator.isValid('ab') // false (too short)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Number Validation
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { number } from '@amazon/vinyl-validation'
|
|
93
|
+
|
|
94
|
+
const validator = number()
|
|
95
|
+
.gte(0) // greater than or equal to 0
|
|
96
|
+
.gt(0) // greater than 0
|
|
97
|
+
.lte(100) // less than or equal to 100
|
|
98
|
+
.lt(100) // less than 100
|
|
99
|
+
.within(1, 99) // between 1 and 99 (inclusive)
|
|
100
|
+
.safeInteger() // safe integer
|
|
101
|
+
.finite() // finite number
|
|
102
|
+
|
|
103
|
+
// Usage
|
|
104
|
+
validator.isValid(50) // true
|
|
105
|
+
validator.isValid(-1) // false (less than 0)
|
|
106
|
+
validator.isValid(Infinity) // false (not finite)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Object Validation
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { object, string, number } from '@amazon/vinyl-validation'
|
|
113
|
+
|
|
114
|
+
const userValidator = object({
|
|
115
|
+
name: string().notEmpty(),
|
|
116
|
+
age: number().gte(0),
|
|
117
|
+
email: string().matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// Usage
|
|
121
|
+
const user = { name: 'John', age: 30, email: 'john@example.com' }
|
|
122
|
+
console.log(userValidator.isValid(user)) // true
|
|
123
|
+
|
|
124
|
+
// Extend existing schemas
|
|
125
|
+
const adminValidator = userValidator.extend({
|
|
126
|
+
role: isOneOf('admin', 'superadmin'),
|
|
127
|
+
permissions: array(string()),
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Array Validation
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { array, string, number, tuple } from '@amazon/vinyl-validation'
|
|
135
|
+
|
|
136
|
+
// Array of strings
|
|
137
|
+
const stringArrayValidator = array(string())
|
|
138
|
+
|
|
139
|
+
// Array of numbers with constraints
|
|
140
|
+
const numberArrayValidator = array(number().gte(0))
|
|
141
|
+
.minLength(1) // at least 1 element
|
|
142
|
+
.maxLength(10) // at most 10 elements
|
|
143
|
+
.notEmpty() // not empty array
|
|
144
|
+
|
|
145
|
+
// Tuple validation (fixed-length array with specific types)
|
|
146
|
+
const coordinateValidator = tuple(number(), number()) // [x, y]
|
|
147
|
+
const personValidator = tuple(string(), number(), boolean()) // [name, age, active]
|
|
148
|
+
|
|
149
|
+
// Usage
|
|
150
|
+
stringArrayValidator.isValid(['a', 'b', 'c']) // true
|
|
151
|
+
coordinateValidator.isValid([10, 20]) // true
|
|
152
|
+
coordinateValidator.isValid([10, 20, 30]) // false (wrong length)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Record Validation
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { record, recordValues, string, number } from '@amazon/vinyl-validation'
|
|
159
|
+
|
|
160
|
+
// Record with string keys and number values
|
|
161
|
+
const scoresValidator = recordValues(number().gte(0))
|
|
162
|
+
|
|
163
|
+
// Record with specific key and value types
|
|
164
|
+
const configValidator = record(
|
|
165
|
+
string().matches(/^[A-Z_]+$/), // keys must be uppercase with underscores
|
|
166
|
+
string().notEmpty() // values must be non-empty strings
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
// Usage
|
|
170
|
+
scoresValidator.isValid({ alice: 95, bob: 87 }) // true
|
|
171
|
+
configValidator.isValid({ API_KEY: 'secret', DB_URL: 'localhost' }) // true
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Set Validation
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { set, string } from '@amazon/vinyl-validation'
|
|
178
|
+
|
|
179
|
+
const tagValidator = set(string().notEmpty())
|
|
180
|
+
|
|
181
|
+
// Usage
|
|
182
|
+
tagValidator.isValid(new Set(['tag1', 'tag2'])) // true
|
|
183
|
+
tagValidator.isValid(new Set(['tag1', ''])) // false (empty string)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Function Validation
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { func } from '@amazon/vinyl-validation'
|
|
190
|
+
|
|
191
|
+
const functionValidator = func()
|
|
192
|
+
.withArity(2) // exactly 2 parameters
|
|
193
|
+
.withMinArity(1) // at least 1 parameter
|
|
194
|
+
.withMaxArity(3) // at most 3 parameters
|
|
195
|
+
|
|
196
|
+
// Usage
|
|
197
|
+
functionValidator.isValid((a, b) => a + b) // true
|
|
198
|
+
functionValidator.isValid(() => 'hello') // false (wrong arity)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Optional and Nullable Values
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { string, number } from '@amazon/vinyl-validation'
|
|
205
|
+
|
|
206
|
+
// Optional (allows undefined)
|
|
207
|
+
const optionalName = string().optional()
|
|
208
|
+
|
|
209
|
+
// Nullable (allows null)
|
|
210
|
+
const nullableName = string().nullable()
|
|
211
|
+
|
|
212
|
+
// Maybe (allows null or undefined)
|
|
213
|
+
const maybeName = string().maybe()
|
|
214
|
+
|
|
215
|
+
// Usage
|
|
216
|
+
optionalName.isValid(undefined) // true
|
|
217
|
+
nullableName.isValid(null) // true
|
|
218
|
+
maybeName.isValid(null) // true
|
|
219
|
+
maybeName.isValid(undefined) // true
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Combining Validators
|
|
223
|
+
|
|
224
|
+
### OR Logic
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { or, string, number } from '@amazon/vinyl-validation'
|
|
228
|
+
|
|
229
|
+
const stringOrNumber = or(string(), number())
|
|
230
|
+
|
|
231
|
+
stringOrNumber.isValid('hello') // true
|
|
232
|
+
stringOrNumber.isValid(42) // true
|
|
233
|
+
stringOrNumber.isValid(true) // false
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### AND Logic
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { and, string } from '@amazon/vinyl-validation'
|
|
240
|
+
|
|
241
|
+
const shortUppercaseString = and(
|
|
242
|
+
string().maxLength(10),
|
|
243
|
+
string().matches(/^[A-Z]+$/)
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
shortUppercaseString.isValid('HELLO') // true
|
|
247
|
+
shortUppercaseString.isValid('hello') // false (not uppercase)
|
|
248
|
+
shortUppercaseString.isValid('VERYLONGSTRING') // false (too long)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Custom Validators
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { custom } from '@amazon/vinyl-validation'
|
|
255
|
+
|
|
256
|
+
const evenNumberValidator = custom<number>(
|
|
257
|
+
'even number',
|
|
258
|
+
(input): input is number => typeof input === 'number' && input % 2 === 0
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
// With custom stringify function
|
|
262
|
+
const positiveValidator = custom<number>(
|
|
263
|
+
'positive number',
|
|
264
|
+
(input): input is number => typeof input === 'number' && input > 0,
|
|
265
|
+
(input) => `number: ${input}`
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
// Usage
|
|
269
|
+
evenNumberValidator.isValid(4) // true
|
|
270
|
+
evenNumberValidator.isValid(3) // false
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Validation Options
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { string, object } from '@amazon/vinyl-validation'
|
|
277
|
+
|
|
278
|
+
const validator = object({
|
|
279
|
+
name: string().notEmpty(),
|
|
280
|
+
email: string().matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
// Collect all errors (default: stop at first error)
|
|
284
|
+
const errors = validator.validate({ name: '', email: 'invalid' }, { all: true })
|
|
285
|
+
|
|
286
|
+
console.log(errors)
|
|
287
|
+
// [
|
|
288
|
+
// { message: 'Expected: not empty, but was: "". At: name', path: ['name'] },
|
|
289
|
+
// { message: 'Expected: matches /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/, but was: "invalid". At: email', path: ['email'] }
|
|
290
|
+
// ]
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Error Handling
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { ValidationError } from '@amazon/vinyl-util'
|
|
297
|
+
import { string } from '@amazon/vinyl-validation'
|
|
298
|
+
|
|
299
|
+
const validator = string().notEmpty()
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
validator.assert('') // throws ValidationError if invalid
|
|
303
|
+
} catch (error) {
|
|
304
|
+
if (error instanceof ValidationError) {
|
|
305
|
+
console.log(error.message) // validation error details
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Or use validate() for non-throwing validation
|
|
310
|
+
const errors = validator.validate('')
|
|
311
|
+
if (errors.length > 0) {
|
|
312
|
+
console.log('Validation failed:', errors)
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## TypeScript Integration
|
|
317
|
+
|
|
318
|
+
The idiomatic usage is to start with an interface and create a schema for it:
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
import { object, string, number, array } from '@amazon/vinyl-validation'
|
|
322
|
+
|
|
323
|
+
// Define your interface first
|
|
324
|
+
interface User {
|
|
325
|
+
name: string
|
|
326
|
+
age?: number
|
|
327
|
+
tags: string[]
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Create a validator that matches the interface
|
|
331
|
+
const userValidator = object<User>({
|
|
332
|
+
name: string(),
|
|
333
|
+
age: number().optional(),
|
|
334
|
+
tags: array(string()),
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
// Type-safe validation
|
|
338
|
+
function processUser(data: unknown) {
|
|
339
|
+
if (userValidator.isValid(data)) {
|
|
340
|
+
// data is now typed as User
|
|
341
|
+
console.log(data.name) // TypeScript knows this is a string
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|