-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.ts
107 lines (104 loc) · 2.9 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import * as validationErrors from './errors';
import * as validationUtils from './utils';
async function validate(
parser: (keyPath: Array<string>, value: any) => Promise<any>,
data: any,
options: { mode: 'greedy' | 'lazy' } = { mode: 'lazy' },
): Promise<any> {
const errors: Array<validationErrors.ErrorParse> = [];
const parse_ = async (
keyPath: Array<string>,
value: any,
context: object,
) => {
if (typeof value === 'object' && value != null) {
for (const key in value) {
value[key] = await parse_([...keyPath, key], value[key], value);
}
}
try {
value = await parser.bind(context)(keyPath, value);
} catch (e) {
if (e instanceof validationErrors.ErrorParse) {
e.keyPath = keyPath;
e.value = value;
e.context = context;
errors.push(e);
// If lazy mode, short circuit evaluation
// And throw the error up
if (options.mode === 'lazy') {
throw e;
}
} else {
throw e;
}
}
return value;
};
try {
// The root context is an object containing the root data but keyed with undefined
data = await parse_([], data, { undefined: data });
} catch (e) {
if (e instanceof validationErrors.ErrorParse) {
throw validationErrors.ErrorValidation.createFromErrors(errors);
} else {
throw e;
}
}
if (errors.length > 0) {
throw validationErrors.ErrorValidation.createFromErrors(errors);
}
return data;
}
function validateSync(
parser: (keyPath: Array<string>, value: any) => any,
data: any,
options: { mode: 'greedy' | 'lazy' } = { mode: 'lazy' },
): any {
const errors: Array<validationErrors.ErrorParse> = [];
const parse_ = (keyPath: Array<string>, value: any, context: object) => {
if (typeof value === 'object' && value != null) {
for (const key in value) {
value[key] = parse_([...keyPath, key], value[key], value);
}
}
try {
value = parser.bind(context)(keyPath, value);
} catch (e) {
if (e instanceof validationErrors.ErrorParse) {
e.keyPath = keyPath;
e.value = value;
e.context = context;
errors.push(e);
// If lazy mode, short circuit evaluation
// And throw the error up
if (options.mode === 'lazy') {
throw e;
}
} else {
throw e;
}
}
return value;
};
try {
// The root context is an object containing the root data but keyed with undefined
data = parse_([], data, { undefined: data });
} catch (e) {
if (e instanceof validationErrors.ErrorParse) {
throw validationErrors.ErrorValidation.createFromErrors(errors);
} else {
throw e;
}
}
if (errors.length > 0) {
throw validationErrors.ErrorValidation.createFromErrors(errors);
}
return data;
}
export {
validate,
validateSync,
validationErrors as errors,
validationUtils as utils,
};