1
1
import { inspect } from '../jsutils/inspect' ;
2
2
import { isObjectLike } from '../jsutils/isObjectLike' ;
3
+ import { isSignedInt32 } from '../jsutils/isSignedInt32' ;
3
4
4
5
import type { ConstValueNode } from '../language/ast' ;
5
6
import { Kind } from '../language/kinds' ;
6
7
import { print } from '../language/printer' ;
7
8
8
9
import { GraphQLError } from '../error/GraphQLError' ;
9
10
11
+ import { defaultScalarLiteralToValue } from '../utilities/literalToValue' ;
12
+ import { defaultScalarValueToLiteral } from '../utilities/valueToLiteral' ;
13
+
10
14
import type { GraphQLNamedType } from './definition' ;
11
15
import { GraphQLScalarType } from './definition' ;
12
16
13
- // As per the GraphQL Spec, Integers are only treated as valid when a valid
14
- // 32-bit signed integer, providing the broadest support across platforms.
15
- //
16
- // n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
17
- // they are internally represented as IEEE 754 doubles.
18
- const MAX_INT = 2147483647 ;
19
- const MIN_INT = - 2147483648 ;
20
-
21
17
function serializeInt ( outputValue : mixed ) : number {
22
18
const coercedValue = serializeObject ( outputValue ) ;
23
19
@@ -35,7 +31,7 @@ function serializeInt(outputValue: mixed): number {
35
31
`Int cannot represent non-integer value: ${ inspect ( coercedValue ) } ` ,
36
32
) ;
37
33
}
38
- if ( num > MAX_INT || num < MIN_INT ) {
34
+ if ( ! isSignedInt32 ( num ) ) {
39
35
throw new GraphQLError (
40
36
'Int cannot represent non 32-bit signed integer value: ' +
41
37
inspect ( coercedValue ) ,
@@ -50,7 +46,7 @@ function coerceInt(inputValue: mixed): number {
50
46
`Int cannot represent non-integer value: ${ inspect ( inputValue ) } ` ,
51
47
) ;
52
48
}
53
- if ( inputValue > MAX_INT || inputValue < MIN_INT ) {
49
+ if ( ! isSignedInt32 ( inputValue ) ) {
54
50
throw new GraphQLError (
55
51
`Int cannot represent non 32-bit signed integer value: ${ inputValue } ` ,
56
52
) ;
@@ -72,14 +68,27 @@ export const GraphQLInt: GraphQLScalarType = new GraphQLScalarType({
72
68
) ;
73
69
}
74
70
const num = parseInt ( valueNode . value , 10 ) ;
75
- if ( num > MAX_INT || num < MIN_INT ) {
71
+ if ( ! isSignedInt32 ( num ) ) {
76
72
throw new GraphQLError (
77
73
`Int cannot represent non 32-bit signed integer value: ${ valueNode . value } ` ,
78
74
valueNode ,
79
75
) ;
80
76
}
81
77
return num ;
82
78
} ,
79
+ valueToLiteral ( value ) {
80
+ if ( isSignedInt32 ( value ) ) {
81
+ return defaultScalarValueToLiteral ( value ) ;
82
+ }
83
+ } ,
84
+ literalToValue ( valueNode ) {
85
+ if ( valueNode . kind === Kind . INT ) {
86
+ const value = defaultScalarLiteralToValue ( valueNode ) ;
87
+ if ( isSignedInt32 ( value ) ) {
88
+ return value ;
89
+ }
90
+ }
91
+ } ,
83
92
} ) ;
84
93
85
94
function serializeFloat ( outputValue : mixed ) : number {
@@ -126,6 +135,17 @@ export const GraphQLFloat: GraphQLScalarType = new GraphQLScalarType({
126
135
}
127
136
return parseFloat ( valueNode . value ) ;
128
137
} ,
138
+ valueToLiteral ( value ) {
139
+ const literal = defaultScalarValueToLiteral ( value ) ;
140
+ if ( literal . kind === Kind . FLOAT || literal . kind === Kind . INT ) {
141
+ return literal ;
142
+ }
143
+ } ,
144
+ literalToValue ( valueNode ) {
145
+ if ( valueNode . kind === Kind . FLOAT || valueNode . kind === Kind . INT ) {
146
+ return defaultScalarLiteralToValue ( valueNode ) ;
147
+ }
148
+ } ,
129
149
} ) ;
130
150
131
151
// Support serializing objects with custom valueOf() or toJSON() functions -
@@ -190,6 +210,17 @@ export const GraphQLString: GraphQLScalarType = new GraphQLScalarType({
190
210
}
191
211
return valueNode . value ;
192
212
} ,
213
+ valueToLiteral ( value ) {
214
+ const literal = defaultScalarValueToLiteral ( value ) ;
215
+ if ( literal . kind === Kind . STRING ) {
216
+ return literal ;
217
+ }
218
+ } ,
219
+ literalToValue ( valueNode ) {
220
+ if ( valueNode . kind === Kind . STRING ) {
221
+ return defaultScalarLiteralToValue ( valueNode ) ;
222
+ }
223
+ } ,
193
224
} ) ;
194
225
195
226
function serializeBoolean ( outputValue : mixed ) : boolean {
@@ -229,6 +260,17 @@ export const GraphQLBoolean: GraphQLScalarType = new GraphQLScalarType({
229
260
}
230
261
return valueNode . value ;
231
262
} ,
263
+ valueToLiteral ( value ) {
264
+ const literal = defaultScalarValueToLiteral ( value ) ;
265
+ if ( literal . kind === Kind . BOOLEAN ) {
266
+ return literal ;
267
+ }
268
+ } ,
269
+ literalToValue ( valueNode ) {
270
+ if ( valueNode . kind === Kind . BOOLEAN ) {
271
+ return defaultScalarLiteralToValue ( valueNode ) ;
272
+ }
273
+ } ,
232
274
} ) ;
233
275
234
276
function serializeID ( outputValue : mixed ) : string {
@@ -270,17 +312,18 @@ export const GraphQLID: GraphQLScalarType = new GraphQLScalarType({
270
312
return valueNode . value ;
271
313
} ,
272
314
valueToLiteral ( value : mixed ) : ?ConstValueNode {
273
- // ID types can use Int literals.
274
- if ( typeof value === 'string' ) {
275
- if ( / ^ - ? (?: 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / . test ( value ) ) {
276
- return { kind : Kind . INT , value } ;
277
- }
278
- return { kind : Kind . STRING , value } ;
315
+ // ID types can use number values and Int literals.
316
+ const stringValue = Number . isInteger ( value ) ? String ( value ) : value ;
317
+ if ( typeof stringValue === 'string' ) {
318
+ // Will parse as an IntValue.
319
+ return / ^ - ? (?: 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / . test ( stringValue )
320
+ ? { kind : Kind . INT , value : stringValue }
321
+ : { kind : Kind . STRING , value : stringValue , block : false } ;
279
322
}
280
323
} ,
281
324
literalToValue ( valueNode : ConstValueNode ) : mixed {
282
325
// ID Int literals are represented as string values.
283
- if ( valueNode . kind === Kind . INT || valueNode . kind === Kind . STRING ) {
326
+ if ( valueNode . kind === Kind . STRING || valueNode . kind === Kind . INT ) {
284
327
return valueNode . value ;
285
328
}
286
329
} ,
0 commit comments