UNPKG

6.78 kBJavaScriptView Raw
1import isFinite from '../polyfills/isFinite';
2import isInteger from '../polyfills/isInteger';
3import inspect from '../jsutils/inspect';
4import isObjectLike from '../jsutils/isObjectLike';
5import { Kind } from '../language/kinds';
6import { GraphQLScalarType, isScalarType } from './definition'; // As per the GraphQL Spec, Integers are only treated as valid when a valid
7// 32-bit signed integer, providing the broadest support across platforms.
8//
9// n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
10// they are internally represented as IEEE 754 doubles.
11
12var MAX_INT = 2147483647;
13var MIN_INT = -2147483648;
14
15function serializeInt(value) {
16 if (typeof value === 'boolean') {
17 return value ? 1 : 0;
18 }
19
20 var num = value;
21
22 if (typeof value === 'string' && value !== '') {
23 num = Number(value);
24 }
25
26 if (!isInteger(num)) {
27 throw new TypeError("Int cannot represent non-integer value: ".concat(inspect(value)));
28 }
29
30 if (num > MAX_INT || num < MIN_INT) {
31 throw new TypeError("Int cannot represent non 32-bit signed integer value: ".concat(inspect(value)));
32 }
33
34 return num;
35}
36
37function coerceInt(value) {
38 if (!isInteger(value)) {
39 throw new TypeError("Int cannot represent non-integer value: ".concat(inspect(value)));
40 }
41
42 if (value > MAX_INT || value < MIN_INT) {
43 throw new TypeError("Int cannot represent non 32-bit signed integer value: ".concat(inspect(value)));
44 }
45
46 return value;
47}
48
49export var GraphQLInt = new GraphQLScalarType({
50 name: 'Int',
51 description: 'The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.',
52 serialize: serializeInt,
53 parseValue: coerceInt,
54 parseLiteral: function parseLiteral(ast) {
55 if (ast.kind === Kind.INT) {
56 var num = parseInt(ast.value, 10);
57
58 if (num <= MAX_INT && num >= MIN_INT) {
59 return num;
60 }
61 }
62
63 return undefined;
64 }
65});
66
67function serializeFloat(value) {
68 if (typeof value === 'boolean') {
69 return value ? 1 : 0;
70 }
71
72 var num = value;
73
74 if (typeof value === 'string' && value !== '') {
75 num = Number(value);
76 }
77
78 if (!isFinite(num)) {
79 throw new TypeError("Float cannot represent non numeric value: ".concat(inspect(value)));
80 }
81
82 return num;
83}
84
85function coerceFloat(value) {
86 if (!isFinite(value)) {
87 throw new TypeError("Float cannot represent non numeric value: ".concat(inspect(value)));
88 }
89
90 return value;
91}
92
93export var GraphQLFloat = new GraphQLScalarType({
94 name: 'Float',
95 description: 'The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).',
96 serialize: serializeFloat,
97 parseValue: coerceFloat,
98 parseLiteral: function parseLiteral(ast) {
99 return ast.kind === Kind.FLOAT || ast.kind === Kind.INT ? parseFloat(ast.value) : undefined;
100 }
101}); // Support serializing objects with custom valueOf() or toJSON() functions -
102// a common way to represent a complex value which can be represented as
103// a string (ex: MongoDB id objects).
104
105function serializeObject(value) {
106 if (isObjectLike(value)) {
107 if (typeof value.valueOf === 'function') {
108 var valueOfResult = value.valueOf();
109
110 if (!isObjectLike(valueOfResult)) {
111 return valueOfResult;
112 }
113 }
114
115 if (typeof value.toJSON === 'function') {
116 // $FlowFixMe(>=0.90.0)
117 return value.toJSON();
118 }
119 }
120
121 return value;
122}
123
124function serializeString(rawValue) {
125 var value = serializeObject(rawValue); // Serialize string, boolean and number values to a string, but do not
126 // attempt to coerce object, function, symbol, or other types as strings.
127
128 if (typeof value === 'string') {
129 return value;
130 }
131
132 if (typeof value === 'boolean') {
133 return value ? 'true' : 'false';
134 }
135
136 if (isFinite(value)) {
137 return value.toString();
138 }
139
140 throw new TypeError("String cannot represent value: ".concat(inspect(rawValue)));
141}
142
143function coerceString(value) {
144 if (typeof value !== 'string') {
145 throw new TypeError("String cannot represent a non string value: ".concat(inspect(value)));
146 }
147
148 return value;
149}
150
151export var GraphQLString = new GraphQLScalarType({
152 name: 'String',
153 description: 'The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.',
154 serialize: serializeString,
155 parseValue: coerceString,
156 parseLiteral: function parseLiteral(ast) {
157 return ast.kind === Kind.STRING ? ast.value : undefined;
158 }
159});
160
161function serializeBoolean(value) {
162 if (typeof value === 'boolean') {
163 return value;
164 }
165
166 if (isFinite(value)) {
167 return value !== 0;
168 }
169
170 throw new TypeError("Boolean cannot represent a non boolean value: ".concat(inspect(value)));
171}
172
173function coerceBoolean(value) {
174 if (typeof value !== 'boolean') {
175 throw new TypeError("Boolean cannot represent a non boolean value: ".concat(inspect(value)));
176 }
177
178 return value;
179}
180
181export var GraphQLBoolean = new GraphQLScalarType({
182 name: 'Boolean',
183 description: 'The `Boolean` scalar type represents `true` or `false`.',
184 serialize: serializeBoolean,
185 parseValue: coerceBoolean,
186 parseLiteral: function parseLiteral(ast) {
187 return ast.kind === Kind.BOOLEAN ? ast.value : undefined;
188 }
189});
190
191function serializeID(rawValue) {
192 var value = serializeObject(rawValue);
193
194 if (typeof value === 'string') {
195 return value;
196 }
197
198 if (isInteger(value)) {
199 return String(value);
200 }
201
202 throw new TypeError("ID cannot represent value: ".concat(inspect(rawValue)));
203}
204
205function coerceID(value) {
206 if (typeof value === 'string') {
207 return value;
208 }
209
210 if (isInteger(value)) {
211 return value.toString();
212 }
213
214 throw new TypeError("ID cannot represent value: ".concat(inspect(value)));
215}
216
217export var GraphQLID = new GraphQLScalarType({
218 name: 'ID',
219 description: 'The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.',
220 serialize: serializeID,
221 parseValue: coerceID,
222 parseLiteral: function parseLiteral(ast) {
223 return ast.kind === Kind.STRING || ast.kind === Kind.INT ? ast.value : undefined;
224 }
225});
226export var specifiedScalarTypes = Object.freeze([GraphQLString, GraphQLInt, GraphQLFloat, GraphQLBoolean, GraphQLID]);
227export function isSpecifiedScalarType(type) {
228 return isScalarType(type) && specifiedScalarTypes.some(function (_ref) {
229 var name = _ref.name;
230 return type.name === name;
231 });
232}