@digitalsamba/validate 2.0.0-canary.1b923c9db3e2
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/CHANGELOG.md +209 -0
- package/LICENSE +190 -0
- package/README.md +5 -0
- package/dist-cjs/index.d.ts +341 -0
- package/dist-cjs/index.js +41 -0
- package/dist-cjs/index.js.map +7 -0
- package/dist-cjs/lib/validation.js +418 -0
- package/dist-cjs/lib/validation.js.map +7 -0
- package/dist-esm/index.d.mts +341 -0
- package/dist-esm/index.mjs +17 -0
- package/dist-esm/index.mjs.map +7 -0
- package/dist-esm/lib/validation.mjs +402 -0
- package/dist-esm/lib/validation.mjs.map +7 -0
- package/package.json +66 -0
- package/src/index.ts +10 -0
- package/src/lib/validation.ts +609 -0
- package/src/test/validation.test.ts +124 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { JsonValue } from '@digitalsamba/utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validation that accepts any value. Generally this should be avoided, but you can use it as an
|
|
5
|
+
* escape hatch if you want to work without validations for e.g. a prototype.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
declare const any: Validator<any>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validates that a value is an array. To check the contents of the array, use T.arrayOf.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
declare const array: Validator<unknown[]>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Validates that a value is an array whose contents matches the passed-in validator.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
declare function arrayOf<T>(itemValidator: Validatable<T>): ArrayOfValidator<T>;
|
|
24
|
+
|
|
25
|
+
/** @public */
|
|
26
|
+
export declare class ArrayOfValidator<T> extends Validator<T[]> {
|
|
27
|
+
readonly itemValidator: Validatable<T>;
|
|
28
|
+
constructor(itemValidator: Validatable<T>);
|
|
29
|
+
nonEmpty(): Validator<T[]>;
|
|
30
|
+
lengthGreaterThan1(): Validator<T[]>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Validates that a value is a bigint.
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
declare const bigint: Validator<bigint>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Validates that a value is boolean.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
declare const boolean: Validator<boolean>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Validation that an option is a dict with particular keys and values.
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
declare function dict<Key extends string, Value>(keyValidator: Validatable<Key>, valueValidator: Validatable<Value>): DictValidator<Key, Value>;
|
|
53
|
+
|
|
54
|
+
/** @public */
|
|
55
|
+
export declare class DictValidator<Key extends string, Value> extends Validator<Record<Key, Value>> {
|
|
56
|
+
readonly keyValidator: Validatable<Key>;
|
|
57
|
+
readonly valueValidator: Validatable<Value>;
|
|
58
|
+
constructor(keyValidator: Validatable<Key>, valueValidator: Validatable<Value>);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Fails if number is not an integer
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
declare const integer: Validator<number>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Validate an object has a particular shape.
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
declare function jsonDict(): DictValidator<string, JsonValue>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Validate that a value is valid JSON.
|
|
77
|
+
*
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
declare const jsonValue: Validator<JsonValue>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Validates that a value matches another that was passed in.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
*
|
|
87
|
+
* ```ts
|
|
88
|
+
* const trueValidator = T.literal(true)
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
declare function literal<T extends boolean | number | string>(expectedValue: T): Validator<T>;
|
|
94
|
+
|
|
95
|
+
/** @public */
|
|
96
|
+
declare function literalEnum<const Values extends readonly unknown[]>(...values: Values): Validator<Values[number]>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A named object with an ID. Errors will be reported as being part of the object with the given
|
|
100
|
+
* name.
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
declare function model<T extends {
|
|
105
|
+
readonly id: string;
|
|
106
|
+
}>(name: string, validator: Validatable<T>): Validator<T>;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Fails if value \<= 0 and is not an integer
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
declare const nonZeroInteger: Validator<number>;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Fails if value \<= 0
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
declare const nonZeroNumber: Validator<number>;
|
|
121
|
+
|
|
122
|
+
/** @public */
|
|
123
|
+
declare function nullable<T>(validator: Validatable<T>): Validator<null | T>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Validates that a value is a finite non-NaN number.
|
|
127
|
+
*
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
130
|
+
declare const number: Validator<number>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Validate an object has a particular shape.
|
|
134
|
+
*
|
|
135
|
+
* @public
|
|
136
|
+
*/
|
|
137
|
+
declare function object<Shape extends object>(config: {
|
|
138
|
+
readonly [K in keyof Shape]: Validatable<Shape[K]>;
|
|
139
|
+
}): ObjectValidator<Shape>;
|
|
140
|
+
|
|
141
|
+
/** @public */
|
|
142
|
+
export declare class ObjectValidator<Shape extends object> extends Validator<Shape> {
|
|
143
|
+
readonly config: {
|
|
144
|
+
readonly [K in keyof Shape]: Validatable<Shape[K]>;
|
|
145
|
+
};
|
|
146
|
+
private readonly shouldAllowUnknownProperties;
|
|
147
|
+
constructor(config: {
|
|
148
|
+
readonly [K in keyof Shape]: Validatable<Shape[K]>;
|
|
149
|
+
}, shouldAllowUnknownProperties?: boolean);
|
|
150
|
+
allowUnknownProperties(): ObjectValidator<Shape>;
|
|
151
|
+
/**
|
|
152
|
+
* Extend an object validator by adding additional properties.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
*
|
|
156
|
+
* ```ts
|
|
157
|
+
* const animalValidator = T.object({
|
|
158
|
+
* name: T.string,
|
|
159
|
+
* })
|
|
160
|
+
* const catValidator = animalValidator.extend({
|
|
161
|
+
* meowVolume: T.number,
|
|
162
|
+
* })
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
extend<Extension extends Record<string, unknown>>(extension: {
|
|
166
|
+
readonly [K in keyof Extension]: Validatable<Extension[K]>;
|
|
167
|
+
}): ObjectValidator<Shape & Extension>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** @public */
|
|
171
|
+
declare function optional<T>(validator: Validatable<T>): Validator<T | undefined>;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Fails if value \< 0 and is not an integer
|
|
175
|
+
*
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
declare const positiveInteger: Validator<number>;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Fails if value \< 0
|
|
182
|
+
*
|
|
183
|
+
* @public
|
|
184
|
+
*/
|
|
185
|
+
declare const positiveNumber: Validator<number>;
|
|
186
|
+
|
|
187
|
+
/** @public */
|
|
188
|
+
declare function setEnum<T>(values: ReadonlySet<T>): Validator<T>;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Validates that a value is a string.
|
|
192
|
+
*
|
|
193
|
+
* @public
|
|
194
|
+
*/
|
|
195
|
+
declare const string: Validator<string>;
|
|
196
|
+
|
|
197
|
+
declare namespace T {
|
|
198
|
+
export {
|
|
199
|
+
literal,
|
|
200
|
+
arrayOf,
|
|
201
|
+
object,
|
|
202
|
+
jsonDict,
|
|
203
|
+
dict,
|
|
204
|
+
union,
|
|
205
|
+
model,
|
|
206
|
+
setEnum,
|
|
207
|
+
optional,
|
|
208
|
+
nullable,
|
|
209
|
+
literalEnum,
|
|
210
|
+
ValidatorFn,
|
|
211
|
+
Validatable,
|
|
212
|
+
ValidationError,
|
|
213
|
+
TypeOf,
|
|
214
|
+
Validator,
|
|
215
|
+
ArrayOfValidator,
|
|
216
|
+
ObjectValidator,
|
|
217
|
+
UnionValidator,
|
|
218
|
+
DictValidator,
|
|
219
|
+
unknown,
|
|
220
|
+
any,
|
|
221
|
+
string,
|
|
222
|
+
number,
|
|
223
|
+
positiveNumber,
|
|
224
|
+
nonZeroNumber,
|
|
225
|
+
integer,
|
|
226
|
+
positiveInteger,
|
|
227
|
+
nonZeroInteger,
|
|
228
|
+
boolean,
|
|
229
|
+
bigint,
|
|
230
|
+
array,
|
|
231
|
+
unknownObject,
|
|
232
|
+
jsonValue
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
export { T }
|
|
236
|
+
|
|
237
|
+
/** @public */
|
|
238
|
+
declare type TypeOf<V extends Validatable<unknown>> = V extends Validatable<infer T> ? T : never;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Validate a union of several object types. Each object must have a property matching `key` which
|
|
242
|
+
* should be a unique string.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
*
|
|
246
|
+
* ```ts
|
|
247
|
+
* const catValidator = T.object({ kind: T.value('cat'), meow: T.boolean })
|
|
248
|
+
* const dogValidator = T.object({ kind: T.value('dog'), bark: T.boolean })
|
|
249
|
+
* const animalValidator = T.union('kind', { cat: catValidator, dog: dogValidator })
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @public
|
|
253
|
+
*/
|
|
254
|
+
declare function union<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(key: Key, config: Config): UnionValidator<Key, Config>;
|
|
255
|
+
|
|
256
|
+
/** @public */
|
|
257
|
+
export declare class UnionValidator<Key extends string, Config extends UnionValidatorConfig<Key, Config>, UnknownValue = never> extends Validator<TypeOf<Config[keyof Config]> | UnknownValue> {
|
|
258
|
+
private readonly key;
|
|
259
|
+
private readonly config;
|
|
260
|
+
private readonly unknownValueValidation;
|
|
261
|
+
constructor(key: Key, config: Config, unknownValueValidation: (value: object, variant: string) => UnknownValue);
|
|
262
|
+
validateUnknownVariants<Unknown>(unknownValueValidation: (value: object, variant: string) => Unknown): UnionValidator<Key, Config, Unknown>;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
declare type UnionValidatorConfig<Key extends string, Config> = {
|
|
266
|
+
readonly [Variant in keyof Config]: Validatable<any> & {
|
|
267
|
+
validate: (input: any) => {
|
|
268
|
+
readonly [K in Key]: Variant;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Validation that accepts any value. Useful as a starting point for building your own custom
|
|
275
|
+
* validations.
|
|
276
|
+
*
|
|
277
|
+
* @public
|
|
278
|
+
*/
|
|
279
|
+
declare const unknown: Validator<unknown>;
|
|
280
|
+
|
|
281
|
+
/** @public */
|
|
282
|
+
declare const unknownObject: Validator<Record<string, unknown>>;
|
|
283
|
+
|
|
284
|
+
/** @public */
|
|
285
|
+
declare type Validatable<T> = {
|
|
286
|
+
validate: (value: unknown) => T;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/** @public */
|
|
290
|
+
declare class ValidationError extends Error {
|
|
291
|
+
readonly rawMessage: string;
|
|
292
|
+
readonly path: ReadonlyArray<number | string>;
|
|
293
|
+
name: string;
|
|
294
|
+
constructor(rawMessage: string, path?: ReadonlyArray<number | string>);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** @public */
|
|
298
|
+
export declare class Validator<T> implements Validatable<T> {
|
|
299
|
+
readonly validationFn: ValidatorFn<T>;
|
|
300
|
+
constructor(validationFn: ValidatorFn<T>);
|
|
301
|
+
/**
|
|
302
|
+
* Asserts that the passed value is of the correct type and returns it. The returned value is
|
|
303
|
+
* guaranteed to be referentially equal to the passed value.
|
|
304
|
+
*/
|
|
305
|
+
validate(value: unknown): T;
|
|
306
|
+
/**
|
|
307
|
+
* Returns a new validator that also accepts null or undefined. The resulting value will always be
|
|
308
|
+
* null.
|
|
309
|
+
*/
|
|
310
|
+
nullable(): Validator<null | T>;
|
|
311
|
+
/**
|
|
312
|
+
* Returns a new validator that also accepts null or undefined. The resulting value will always be
|
|
313
|
+
* null.
|
|
314
|
+
*/
|
|
315
|
+
optional(): Validator<T | undefined>;
|
|
316
|
+
/**
|
|
317
|
+
* Refine this validation to a new type. The passed-in validation function should throw an error
|
|
318
|
+
* if the value can't be converted to the new type, or return the new type otherwise.
|
|
319
|
+
*/
|
|
320
|
+
refine<U>(otherValidationFn: (value: T) => U): Validator<U>;
|
|
321
|
+
/**
|
|
322
|
+
* Refine this validation with an additional check that doesn't change the resulting value.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
*
|
|
326
|
+
* ```ts
|
|
327
|
+
* const numberLessThan10Validator = T.number.check((value) => {
|
|
328
|
+
* if (value >= 10) {
|
|
329
|
+
* throw new ValidationError(`Expected number less than 10, got ${value}`)
|
|
330
|
+
* }
|
|
331
|
+
* })
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
check(name: string, checkFn: (value: T) => void): Validator<T>;
|
|
335
|
+
check(checkFn: (value: T) => void): Validator<T>;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** @public */
|
|
339
|
+
declare type ValidatorFn<T> = (value: unknown) => T;
|
|
340
|
+
|
|
341
|
+
export { }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var src_exports = {};
|
|
30
|
+
__export(src_exports, {
|
|
31
|
+
ArrayOfValidator: () => import_validation.ArrayOfValidator,
|
|
32
|
+
DictValidator: () => import_validation.DictValidator,
|
|
33
|
+
ObjectValidator: () => import_validation.ObjectValidator,
|
|
34
|
+
T: () => T,
|
|
35
|
+
UnionValidator: () => import_validation.UnionValidator,
|
|
36
|
+
Validator: () => import_validation.Validator
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(src_exports);
|
|
39
|
+
var T = __toESM(require("./lib/validation"));
|
|
40
|
+
var import_validation = require("./lib/validation");
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import * as T from './lib/validation'\n\nexport {\n\tArrayOfValidator,\n\tDictValidator,\n\tObjectValidator,\n\tUnionValidator,\n\tValidator,\n} from './lib/validation'\nexport { T }\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAmB;AAEnB,wBAMO;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|