1+ /**
2+ * Maximum possible Int value as per GraphQL Spec (32-bit signed integer).
3+ * n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe up-to 2^53 - 1
4+ * */
5+ let GRAPHQL_MAX_INT = 2147483647 ;
6+
7+ /**
8+ * Minimum possible Int value as per GraphQL Spec (32-bit signed integer).
9+ * n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe starting at -(2^53 - 1)
10+ * */
11+ let GRAPHQL_MIN_INT = - 2147483648 ;
12+
113public let GraphQLInt = try ! GraphQLScalarType (
214 name: " Int " ,
315 description:
416 " The `Int` scalar type represents non-fractional signed whole numeric " +
517 " values. Int can represent values between -(2^31) and 2^31 - 1. " ,
6- serialize: { try map ( from: $0) } ,
7- parseValue: { try . int( $0. intValue ( converting: true ) ) } ,
18+ serialize: { outputValue in
19+ if let value = outputValue as? Map {
20+ if case let . number( value) = value {
21+ return . int( value. intValue)
22+ }
23+ throw GraphQLError (
24+ message: " Float cannot represent non numeric value: \( value) "
25+ )
26+ }
27+ if let value = outputValue as? Bool {
28+ return value ? . int( 1 ) : . int( 0 )
29+ }
30+ if let value = outputValue as? String , value != " " , let int = Int ( value) {
31+ return . int( int)
32+ }
33+ if let value = outputValue as? Double , Double ( GRAPHQL_MIN_INT) <= value, value <= Double ( GRAPHQL_MAX_INT) , value. isFinite {
34+ return . int( Int ( value) )
35+ }
36+ if let value = outputValue as? Int , GRAPHQL_MIN_INT <= value, value <= GRAPHQL_MAX_INT {
37+ return . int( value)
38+ }
39+ throw GraphQLError (
40+ message: " Int cannot represent non-integer value: \( outputValue) "
41+ )
42+ } ,
43+ parseValue: { inputValue in
44+ if case let . number( value) = inputValue, Double ( GRAPHQL_MIN_INT) <= value. doubleValue, value. doubleValue <= Double ( GRAPHQL_MAX_INT) , value. doubleValue. isFinite {
45+ return . number( value)
46+ }
47+ throw GraphQLError (
48+ message: " Int cannot represent non-integer value: \( inputValue) "
49+ )
50+ } ,
851 parseLiteral: { ast in
952 if let ast = ast as? IntValue , let int = Int ( ast. value) {
1053 return . int( int)
@@ -23,8 +66,39 @@ public let GraphQLFloat = try! GraphQLScalarType(
2366 " The `Float` scalar type represents signed double-precision fractional " +
2467 " values as specified by " +
2568 " [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). " ,
26- serialize: { try map ( from: $0) } ,
27- parseValue: { try . double( $0. doubleValue ( converting: true ) ) } ,
69+ serialize: { outputValue in
70+ if let value = outputValue as? Map {
71+ if case let . number( value) = value {
72+ return . double( value. doubleValue)
73+ }
74+ throw GraphQLError (
75+ message: " Float cannot represent non numeric value: \( value) "
76+ )
77+ }
78+ if let value = outputValue as? Bool {
79+ return value ? . double( 1 ) : . double( 0 )
80+ }
81+ if let value = outputValue as? String , value != " " , let double = Double ( value) {
82+ return . double( double)
83+ }
84+ if let value = outputValue as? Double , value. isFinite {
85+ return . double( value)
86+ }
87+ if let value = outputValue as? Int {
88+ return . double( Double ( value) )
89+ }
90+ throw GraphQLError (
91+ message: " Float cannot represent non numeric value: \( outputValue) "
92+ )
93+ } ,
94+ parseValue: { inputValue in
95+ if case let . number( value) = inputValue, value. doubleValue. isFinite {
96+ return . number( value)
97+ }
98+ throw GraphQLError (
99+ message: " Float cannot represent non numeric value: \( inputValue) "
100+ )
101+ } ,
28102 parseLiteral: { ast in
29103 if let ast = ast as? FloatValue , let double = Double ( ast. value) {
30104 return . double( double)
@@ -47,8 +121,39 @@ public let GraphQLString = try! GraphQLScalarType(
47121 " The `String` scalar type represents textual data, represented as UTF-8 " +
48122 " character sequences. The String type is most often used by GraphQL to " +
49123 " represent free-form human-readable text. " ,
50- serialize: { try map ( from: $0) } ,
51- parseValue: { try . string( $0. stringValue ( converting: true ) ) } ,
124+ serialize: { outputValue in
125+ if let value = outputValue as? Map {
126+ if case let . string( value) = value {
127+ return . string( value)
128+ }
129+ throw GraphQLError (
130+ message: " String cannot represent a non string value: \( value) "
131+ )
132+ }
133+ if let value = outputValue as? String {
134+ return . string( value)
135+ }
136+ if let value = outputValue as? Bool {
137+ return value ? . string( " true " ) : . string( " false " )
138+ }
139+ if let value = outputValue as? Int {
140+ return . string( value. description)
141+ }
142+ if let value = outputValue as? Double , value. isFinite {
143+ return . string( value. description)
144+ }
145+ throw GraphQLError (
146+ message: " String cannot represent value: \( outputValue) "
147+ )
148+ } ,
149+ parseValue: { outputValue in
150+ if case let . string( value) = outputValue {
151+ return . string( value)
152+ }
153+ throw GraphQLError (
154+ message: " String cannot represent a non string value: \( outputValue) "
155+ )
156+ } ,
52157 parseLiteral: { ast in
53158 if let ast = ast as? StringValue {
54159 return . string( ast. value)
@@ -64,8 +169,36 @@ public let GraphQLString = try! GraphQLScalarType(
64169public let GraphQLBoolean = try ! GraphQLScalarType (
65170 name: " Boolean " ,
66171 description: " The `Boolean` scalar type represents `true` or `false`. " ,
67- serialize: { try map ( from: $0) } ,
68- parseValue: { try . bool( $0. boolValue ( converting: true ) ) } ,
172+ serialize: { outputValue in
173+ if let value = outputValue as? Map {
174+ if case let . bool( value) = value {
175+ return . bool( value)
176+ }
177+ if case let . number( value) = value {
178+ return . bool( value. intValue != 0 )
179+ }
180+ throw GraphQLError (
181+ message: " Boolean cannot represent a non boolean value: \( value) "
182+ )
183+ }
184+ if let value = outputValue as? Bool {
185+ return . bool( value)
186+ }
187+ if let value = outputValue as? Int {
188+ return . bool( value != 0 )
189+ }
190+ throw GraphQLError (
191+ message: " Boolean cannot represent a non boolean value: \( outputValue) "
192+ )
193+ } ,
194+ parseValue: { inputValue in
195+ if case let . bool( value) = inputValue {
196+ return inputValue
197+ }
198+ throw GraphQLError (
199+ message: " Boolean cannot represent a non boolean value: \( inputValue) "
200+ )
201+ } ,
69202 parseLiteral: { ast in
70203 if let ast = ast as? BooleanValue {
71204 return . bool( ast. value)
@@ -86,8 +219,35 @@ public let GraphQLID = try! GraphQLScalarType(
86219 " response as a String; however, it is not intended to be human-readable. " +
87220 " When expected as an input type, any string (such as ` \" 4 \" `) or integer " +
88221 " (such as `4`) input value will be accepted as an ID. " ,
89- serialize: { try map ( from: $0) } ,
90- parseValue: { try . string( $0. stringValue ( converting: true ) ) } ,
222+ serialize: { outputValue in
223+ if let value = outputValue as? Map {
224+ if case let . string( value) = value {
225+ return . string( value)
226+ }
227+ if case let . number( value) = value {
228+ return . string( value. description)
229+ }
230+ throw GraphQLError (
231+ message: " ID cannot represent value: \( value) "
232+ )
233+ }
234+ if let value = outputValue as? String {
235+ return . string( value)
236+ }
237+ if let value = outputValue as? Int {
238+ return . string( value. description)
239+ }
240+ throw GraphQLError ( message: " ID cannot represent value: \( outputValue) " )
241+ } ,
242+ parseValue: { inputValue in
243+ if case let . string( value) = inputValue {
244+ return inputValue
245+ }
246+ if case let . number( value) = inputValue, value. storageType == . int {
247+ return . string( value. description)
248+ }
249+ throw GraphQLError ( message: " ID cannot represent value: \( inputValue) " )
250+ } ,
91251 parseLiteral: { ast in
92252 if let ast = ast as? StringValue {
93253 return . string( ast. value)
0 commit comments