-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
156 lines (148 loc) · 6.27 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// External
import 'validator';
import Q = require("q");
// Internal
import { Sanitizable } from './Sanitizables'
export default function (object: Object, ruleClass: Sanitizable, rejectOnAdditionalProperty?: boolean): Q.Promise<{} | { [key: string]: boolean }>
{
if (ruleClass && ruleClass['__ts-apiguard:typeRules__'])
{
let expectedPropertyMap = ruleClass['__ts-apiguard:typeRules__'];
let objectMirror = (<any>Object).assign({}, object);
if (object)
{
let propertyNames = Object.keys(expectedPropertyMap);
let propertyNamesLength = propertyNames.length;
let optionalPropertyMap: { [key: string]: boolean } = {};
for (let i = 0; i < propertyNamesLength; i++)
{
let propertyName = propertyNames[i];
let propertyNormalizedType = expectedPropertyMap[propertyName];
let propertyValue;
// Optional Rule
if (propertyName.slice(-1) === '?')
{
propertyName = propertyName.substr(0, propertyName.length - 1);
propertyValue = object[propertyName];
if (propertyValue === undefined || propertyValue === '')
{
// Add status to parameter status object
optionalPropertyMap[propertyName] = false;
if (propertyValue === '')
{
// Remove rule from mirror if empty
delete objectMirror[propertyName];
}
// Skip rule checking if it's object value is undefined
continue;
}
else
{
optionalPropertyMap[propertyName] = true;
}
}
else
{
propertyValue = object[propertyName];
}
if (propertyValue !== undefined && propertyValue !== '')
{
// Check for a self-validating type
if (propertyNormalizedType['validateOwnType'] && typeof propertyNormalizedType['validateOwnType'] === 'function')
{
let isValid = propertyNormalizedType['validateOwnType'](propertyValue);
if (!isValid)
{
return Q.reject(new TypeError('Type "' + propertyNormalizedType['name'] + '" could not validate itself with value "' + propertyValue + '"'));
}
if (propertyNormalizedType['transformOwnType'] && typeof propertyNormalizedType['transformOwnType'] === 'function')
{
propertyValue = propertyNormalizedType['transformOwnType'].transformOwnType(propertyValue);
}
}
else
{
// Fallback to native types
switch (propertyNormalizedType)
{
case String:
if (typeof propertyValue !== 'string')
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'string')));
}
break;
case Number:
if (typeof propertyValue !== 'number')
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'number')));
}
break;
case Boolean:
if (typeof propertyValue !== 'boolean')
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'boolean')));
}
break;
case Date:
if (typeof propertyValue !== 'string')
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'string that matches a date')));
}
else if (!validator.isDate(propertyValue))
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'string that matches a date')));
}
object[propertyName] = new Date(propertyValue);
break;
case Array:
if (!Array.isArray(propertyValue))
{
return Q.reject(new TypeError(genericTypeErrorText(propertyName, propertyValue, 'array')));
}
break;
default:
return Q.reject(new Error('Tried to validate "' + propertyName + '" for unchecked type "' + propertyNormalizedType + '"'));
}
}
// Remove from mirror
delete objectMirror[propertyName];
}
else
{
return Q.reject(new TypeError('Expected object property "' + propertyName + '" to exist.'));
}
}
if (rejectOnAdditionalProperty || true)
{
let remainingKeys = Object.keys(objectMirror);
if (remainingKeys.length > 0)
{
let errorMessage = 'Passed prohibited additional propert';
if (remainingKeys.length > 1)
{
let lastKey = remainingKeys.pop();
errorMessage += 'ies "' + remainingKeys.join(',') + ' and ' + lastKey + '"';
}
else
{
errorMessage += 'y "' + remainingKeys[0] + '"';
}
return Q.reject(new Error(errorMessage));
}
}
return Q.resolve(optionalPropertyMap);
}
else
{
return Q.reject(new TypeError('Request to sanitize does not exist'));
}
}
else
{
return Q.reject(new Error('Sanitization rules do not exist.'));
}
}
function genericTypeErrorText(propertyName, propertyValue, propertyType)
{
return 'Expected object parameter "' + propertyName + '" to be a ' + propertyType + ', instead got "' + propertyValue + '".';
}