-
Notifications
You must be signed in to change notification settings - Fork 5
/
validator.js
107 lines (105 loc) · 2.51 KB
/
validator.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
var Transform = require('readable-stream').Transform;
var inherits = require('inherits');
inherits(Validator, Transform);
module.exports = validator;
function validator(warning, schema) {
return new Validator(warning, schema);
}
function Validator(warning, schema) {
Transform.call(this, {
objectMode: true
});
this.warning = warning;
this.extraKeys = new Set();
this.schema = schema;
this.nope = Symbol('nope');
}
Validator.prototype.keyWarning = function (key) {
if (this.extraKeys.has(key)) {
return;
}
this.extraKeys.add(key);
this.warning(`An unexpected field "${key}" was encountered. This field was not uploaded`);
};
Validator.prototype._transform = function (chunk, _, next) {
var self = this;
var props = chunk.properties;
chunk.properties = {};
const schema = this.schema;
Object.keys(props).forEach(function (key) {
if (!schema.has(key)) {
self.keyWarning(key);
return;
}
var typed = self.coerceType(props[key], schema.get(key));
if (typed === self.nope) {
return;
}
chunk.properties[key] = typed;
});
if (chunk.geometry || Object.keys(chunk.properties).length) {
self.push(chunk);
}
next();
};
const falses = new Set(['f','false','n','no','off','0']);
const trues = new Set(['t','true','y','yes','on','1']);
Validator.prototype.coerceType = function (value, type) {
if (typeof value === 'undefined' || value === null) {
return this.nope;
}
var out;
switch(type) {
case 'character':
case 'text':
out = String(value);
if (!out) {
return this.nope;
}
return out;
case 'double precision':
out = parseFloat(value);
if (out !== out) {
return this.nope;
}
return out;
case 'integer':
out = parseInt(value, 10);
if (out !== out) {
return this.nope;
}
if (out > 2147483647 || out < -2147483648 ) {
return this.nope;
}
return out;
case 'bigint':
out = parseInt(value, 10);
if (out !== out) {
return this.nope;
}
return out;
case 'timestamp with time zone':
case 'date':
out = new Date(value);
if (out.toString() === 'Invalid Date') {
return this.nope;
}
return out;
case 'boolean':
if (value === 'NULL') {
return this.nope;
}
if (typeof value !== 'string') {
return Boolean(value);
}
if (falses.has(value.trim().toLowerCase())) {
return false;
}
if (trues.has(value.trim().toLowerCase())) {
return true;
}
return this.nope;
default:
return this.nope;
}
};