-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidate.js
125 lines (106 loc) · 3.13 KB
/
validate.js
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import {isNumber, isString, isBoolean, isArray as _isArray, forEach} from "./lodash";
const baseTypes = ["number", "string", "boolean"];
const mapRegex = /^map\<\s*(\w+)\s*:\s*(.*)\s*\>/;
const arrayRegex = /^array\<\s*(.*)\s*\>/;
function inferDataType(schema) {
let inferedType = schema;
if (schema.match(mapRegex)) {
inferedType = "map";
} else if (schema.match(arrayRegex)) {
inferedType = "array";
}
return inferedType;
}
export default function validate(schema, data) {
switch(inferDataType(schema)) {
case "number":
return isNumber(data);
case "string":
return isString(data);
case "boolean":
return isBoolean(data);
case "regex":
return isString(data) && isRegex(data);
case "range":
return isRange(schema, data);
case "map":
return isMap(schema, data);
case "array":
return isArray(schema, data);
default:
throw new Error("validate: invalid data-type");
}
}
function handleComplexDataType(inferedType, schema, data) {
switch(inferedType) {
case 'map':
if (!isMap(schema, data)) {
throw new Error(`validate: ${data} does not match the schema ${schema}`);
}
return true;
case 'array':
if (!isArray(schema, data)) {
throw new Error(`validate: ${data} does not match the schema ${schema}`);
}
return true;
default:
if (!validate(schema, data)) {
throw new Error(`validate: ${data} does not match the schema ${schema}`);
}
return true;
}
}
function isRegex(data) {
var isValid = true;
try {
new RegExp(data);
} catch(e) {
isValid = false;
}
return isValid;
}
function isRange(schema, data) {
if (schema.length == 2 && isArray('array<number>', schema)) {
return _.isRange(data, schema[0], schema[1])
} else {
throw new Error("validate: min and max are not valid")
}
}
function isArray(schema, data) {
if (!_isArray(data)) {
throw new Error(`validate: data ${data} is not an array`);
}
let match = schema.match(arrayRegex);
if(match && match[1]) {
let valueType = match[1].trim();
let inferedType = inferDataType(valueType);
forEach(data, (v) => { handleComplexDataType(inferedType, valueType, v) });
return true;
} else {
throw new Error(`validate: array schema invalid for ${schema}`);
}
}
function isMap(schema, data) {
if (_isArray(data)) {
throw new Error(`validate: data ${data} is of type array and not map`);
}
let match = schema.match(mapRegex);
if(match && match[1] && match[2]) {
let keyType = match[1].trim();
let valueType = match[2].trim();
if ( baseTypes.indexOf(keyType) != -1 ) {
let inferedType = inferDataType(valueType);
forEach(data, (v, k) => {
if ( !validate(keyType, k) ) {
throw new Error(`validate: ${k} does not match the schema ${keyType}`);
}
handleComplexDataType(inferedType, valueType, v);
});
return true;
} else {
throw new Error(`validate: key has to be a primitive data-type. ${keyType} given`);
}
} else {
throw new Error(`validate: map schema invalid for ${schema}`);
}
}