-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
96 lines (75 loc) · 2.83 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
export function isValid<T extends { [key: string]: any }>(
testSubject: T,
validators: {[K in keyof Partial<T>]: Function[]},
): boolean {
const result = validate(testSubject, validators);
const testedProperties = Object.keys(validators);
const passingTests = testedProperties
.map(property => result[property])
.filter(isPassingTest => !!isPassingTest);
return passingTests.length === testedProperties.length;
}
export function validate<T extends { [key: string]: any }>(
testSubject: T,
validators: {[K in keyof Partial<T>]: Function[]},
): {[K in keyof Partial<T>]: boolean} {
const results = {} as {[K in keyof Partial<T>]: boolean};
const propertiesToTest = Object.keys(validators);
propertiesToTest.forEach((property: string) => {
let isValid = true;
const propertyUnderTest = testSubject[property];
const propertyValidators = validators[property];
while (isValid && propertyValidators.length > 0) {
const validate = propertyValidators.shift();
const result = validate(propertyUnderTest);
const isTestFunctionVoid = typeof result === 'undefined';
isValid = isTestFunctionVoid ? isValid : result;
}
results[property as keyof Partial<T>] = isValid;
});
return results;
}
export function isNotNull(value: any | null): boolean {
return value !== null;
}
export function isNotEmpty(value: any[] | string | object): boolean {
let isNotEmpty = false;
if (value instanceof Object && value.constructor === Object) {
isNotEmpty = !!Object.keys(value).length;
} else if (isTruthy(value)) {
isNotEmpty = !!(value as any[] | string).length;
}
return isNotEmpty;
}
export function isNotUndefined(value: any | undefined): boolean {
return typeof value !== 'undefined';
}
export function isTruthy(value: any | null | undefined): boolean {
return !!value;
}
export function isRequired(value: any | null | undefined): boolean {
return isTruthy(value);
}
function getLength(value: any[] | string): number {
return isNotEmpty(value) ? value.length : NaN;
}
export function minLength(value: any[] | string, minLength: number): boolean {
return getLength(value) >= minLength;
}
export function maxLength(value: any[] | string, maxLength: number): boolean {
return getLength(value) <= maxLength;
}
export function isEnumSubset(
values: string | string[],
enumerable: EnumWithNumericKeys | EnumWithStringKeys,
): boolean {
const acceptableValues = Object.keys(enumerable)
.map(key => enumerable[key]);
const actualValues = Array.isArray(values) ? values : [values];
const noValuesOutsideOfEnum = 0;
return actualValues.map(value => acceptableValues.indexOf(value) > -1)
.filter(result => !result)
.length === noValuesOutsideOfEnum;
}
type EnumWithStringKeys = { [id: string]: string };
type EnumWithNumericKeys = { [id: number]: string };