11import { inspect } from '../jsutils/inspect' ;
22import { isObjectLike } from '../jsutils/isObjectLike' ;
3+ import { isSignedInt32 } from '../jsutils/isSignedInt32' ;
34
45import type { ConstValueNode } from '../language/ast' ;
56import { Kind } from '../language/kinds' ;
67import { print } from '../language/printer' ;
78
89import { GraphQLError } from '../error/GraphQLError' ;
910
11+ import { defaultScalarLiteralToValue } from '../utilities/literalToValue' ;
12+ import { defaultScalarValueToLiteral } from '../utilities/valueToLiteral' ;
13+
1014import type { GraphQLNamedType } from './definition' ;
1115import { GraphQLScalarType } from './definition' ;
1216
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-
2117function serializeInt ( outputValue : mixed ) : number {
2218 const coercedValue = serializeObject ( outputValue ) ;
2319
@@ -35,7 +31,7 @@ function serializeInt(outputValue: mixed): number {
3531 `Int cannot represent non-integer value: ${ inspect ( coercedValue ) } ` ,
3632 ) ;
3733 }
38- if ( num > MAX_INT || num < MIN_INT ) {
34+ if ( ! isSignedInt32 ( num ) ) {
3935 throw new GraphQLError (
4036 'Int cannot represent non 32-bit signed integer value: ' +
4137 inspect ( coercedValue ) ,
@@ -50,7 +46,7 @@ function coerceInt(inputValue: mixed): number {
5046 `Int cannot represent non-integer value: ${ inspect ( inputValue ) } ` ,
5147 ) ;
5248 }
53- if ( inputValue > MAX_INT || inputValue < MIN_INT ) {
49+ if ( ! isSignedInt32 ( inputValue ) ) {
5450 throw new GraphQLError (
5551 `Int cannot represent non 32-bit signed integer value: ${ inputValue } ` ,
5652 ) ;
@@ -72,14 +68,27 @@ export const GraphQLInt: GraphQLScalarType = new GraphQLScalarType({
7268 ) ;
7369 }
7470 const num = parseInt ( valueNode . value , 10 ) ;
75- if ( num > MAX_INT || num < MIN_INT ) {
71+ if ( ! isSignedInt32 ( num ) ) {
7672 throw new GraphQLError (
7773 `Int cannot represent non 32-bit signed integer value: ${ valueNode . value } ` ,
7874 valueNode ,
7975 ) ;
8076 }
8177 return num ;
8278 } ,
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+ } ,
8392} ) ;
8493
8594function serializeFloat ( outputValue : mixed ) : number {
@@ -126,6 +135,17 @@ export const GraphQLFloat: GraphQLScalarType = new GraphQLScalarType({
126135 }
127136 return parseFloat ( valueNode . value ) ;
128137 } ,
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+ } ,
129149} ) ;
130150
131151// Support serializing objects with custom valueOf() or toJSON() functions -
@@ -190,6 +210,17 @@ export const GraphQLString: GraphQLScalarType = new GraphQLScalarType({
190210 }
191211 return valueNode . value ;
192212 } ,
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+ } ,
193224} ) ;
194225
195226function serializeBoolean ( outputValue : mixed ) : boolean {
@@ -229,6 +260,17 @@ export const GraphQLBoolean: GraphQLScalarType = new GraphQLScalarType({
229260 }
230261 return valueNode . value ;
231262 } ,
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+ } ,
232274} ) ;
233275
234276function serializeID ( outputValue : mixed ) : string {
@@ -270,17 +312,18 @@ export const GraphQLID: GraphQLScalarType = new GraphQLScalarType({
270312 return valueNode . value ;
271313 } ,
272314 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 } ;
279322 }
280323 } ,
281324 literalToValue ( valueNode : ConstValueNode ) : mixed {
282325 // 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 ) {
284327 return valueNode . value ;
285328 }
286329 } ,
0 commit comments