-
Notifications
You must be signed in to change notification settings - Fork 4
/
GraphQLValidatedScalar.js
110 lines (93 loc) · 2.2 KB
/
GraphQLValidatedScalar.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
const {GraphQLScalarType} = require('graphql');
class GraphQLValidatedScalar extends GraphQLScalarType {
constructor ({name, description = 'custom scalar type'}) {
if (!name) {
name = 'Scalar';
}
super({
name,
description,
serialize: (value)=> {
return this._serialize(value);
},
parseValue: (value)=> {
return this._parseValue(value);
},
parseLiteral: (ast)=> {
return this._parseLiteral(ast);
}
});
this._default = null;
this.clearValidators();
}
clearValidators () {
this.validators = [];
}
validKinds () {
return null;
}
validTypes () {
return null;
}
_ensureValidType (value) {
const types = this.validTypes();
if (types) {
const type = typeof value;
if (!types.includes(type)) {
this.throwTypeError();
}
}
}
_serialize (value) {
this._ensureValidType(value);
return this.validate(value);
}
_parseValue (value) {
value = this.ensureDefault(value);
this._ensureValidType(value);
return this.validate(value);
}
_parseLiteral (ast) {
const {kind} = ast;
const value = this.ensureDefault(ast.value);
const kinds = this.validKinds();
if (kinds) {
if (!kinds.includes(kind)) {
this.throwTypeError();
}
}
return this.validate(value);
}
throwTypeError () {
const types = this.validTypes();
let description = 'has invalid type';
if (types) {
description = `is not ${types.join(' or ')}`;
}
throw new TypeError(`${this.name} ${description}`);
}
ensureDefault (value) {
if (this.shouldDefault(value) && this._default) {
value = this._default;
}
return value;
}
shouldDefault (value) {
return !value;
}
default (_default) {
this._default = _default;
return this;
}
validate (value) {
return this.validators.reduce((result, validator)=> {
return validator(result);
}, value);
}
validator (validator) {
const new_validators = Array.isArray(validator) ? validator : [validator];
this.validators = [...this.validators, ...new_validators];
return this;
}
}
module.exports = GraphQLValidatedScalar;