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 = 2_147_483_647
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 = - 2_147_483_648
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
34+ let value = outputValue as? Double , Double ( GRAPHQL_MIN_INT) <= value,
35+ value <= Double ( GRAPHQL_MAX_INT) , value. isFinite
36+ {
37+ return . int( Int ( value) )
38+ }
39+ if let value = outputValue as? Int , GRAPHQL_MIN_INT <= value, value <= GRAPHQL_MAX_INT {
40+ return . int( value)
41+ }
42+ throw GraphQLError (
43+ message: " Int cannot represent non-integer value: \( outputValue) "
44+ )
45+ } ,
46+ parseValue: { inputValue in
47+ if
48+ case let . number( value) = inputValue, Double ( GRAPHQL_MIN_INT) <= value. doubleValue,
49+ value. doubleValue <= Double ( GRAPHQL_MAX_INT) , value. doubleValue. isFinite
50+ {
51+ return . number( value)
52+ }
53+ throw GraphQLError (
54+ message: " Int cannot represent non-integer value: \( inputValue) "
55+ )
56+ } ,
857 parseLiteral: { ast in
958 if let ast = ast as? IntValue , let int = Int ( ast. value) {
1059 return . int( int)
@@ -23,8 +72,39 @@ public let GraphQLFloat = try! GraphQLScalarType(
2372 " The `Float` scalar type represents signed double-precision fractional " +
2473 " values as specified by " +
2574 " [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). " ,
26- serialize: { try map ( from: $0) } ,
27- parseValue: { try . double( $0. doubleValue ( converting: true ) ) } ,
75+ serialize: { outputValue in
76+ if let value = outputValue as? Map {
77+ if case let . number( value) = value {
78+ return . double( value. doubleValue)
79+ }
80+ throw GraphQLError (
81+ message: " Float cannot represent non numeric value: \( value) "
82+ )
83+ }
84+ if let value = outputValue as? Bool {
85+ return value ? . double( 1 ) : . double( 0 )
86+ }
87+ if let value = outputValue as? String , value != " " , let double = Double ( value) {
88+ return . double( double)
89+ }
90+ if let value = outputValue as? Double , value. isFinite {
91+ return . double( value)
92+ }
93+ if let value = outputValue as? Int {
94+ return . double( Double ( value) )
95+ }
96+ throw GraphQLError (
97+ message: " Float cannot represent non numeric value: \( outputValue) "
98+ )
99+ } ,
100+ parseValue: { inputValue in
101+ if case let . number( value) = inputValue, value. doubleValue. isFinite {
102+ return . number( value)
103+ }
104+ throw GraphQLError (
105+ message: " Float cannot represent non numeric value: \( inputValue) "
106+ )
107+ } ,
28108 parseLiteral: { ast in
29109 if let ast = ast as? FloatValue , let double = Double ( ast. value) {
30110 return . double( double)
@@ -47,8 +127,39 @@ public let GraphQLString = try! GraphQLScalarType(
47127 " The `String` scalar type represents textual data, represented as UTF-8 " +
48128 " character sequences. The String type is most often used by GraphQL to " +
49129 " represent free-form human-readable text. " ,
50- serialize: { try map ( from: $0) } ,
51- parseValue: { try . string( $0. stringValue ( converting: true ) ) } ,
130+ serialize: { outputValue in
131+ if let value = outputValue as? Map {
132+ if case let . string( value) = value {
133+ return . string( value)
134+ }
135+ throw GraphQLError (
136+ message: " String cannot represent a non string value: \( value) "
137+ )
138+ }
139+ if let value = outputValue as? String {
140+ return . string( value)
141+ }
142+ if let value = outputValue as? Bool {
143+ return value ? . string( " true " ) : . string( " false " )
144+ }
145+ if let value = outputValue as? Int {
146+ return . string( value. description)
147+ }
148+ if let value = outputValue as? Double , value. isFinite {
149+ return . string( value. description)
150+ }
151+ throw GraphQLError (
152+ message: " String cannot represent value: \( outputValue) "
153+ )
154+ } ,
155+ parseValue: { outputValue in
156+ if case let . string( value) = outputValue {
157+ return . string( value)
158+ }
159+ throw GraphQLError (
160+ message: " String cannot represent a non string value: \( outputValue) "
161+ )
162+ } ,
52163 parseLiteral: { ast in
53164 if let ast = ast as? StringValue {
54165 return . string( ast. value)
@@ -64,8 +175,36 @@ public let GraphQLString = try! GraphQLScalarType(
64175public let GraphQLBoolean = try ! GraphQLScalarType (
65176 name: " Boolean " ,
66177 description: " The `Boolean` scalar type represents `true` or `false`. " ,
67- serialize: { try map ( from: $0) } ,
68- parseValue: { try . bool( $0. boolValue ( converting: true ) ) } ,
178+ serialize: { outputValue in
179+ if let value = outputValue as? Map {
180+ if case let . bool( value) = value {
181+ return . bool( value)
182+ }
183+ if case let . number( value) = value {
184+ return . bool( value. intValue != 0 )
185+ }
186+ throw GraphQLError (
187+ message: " Boolean cannot represent a non boolean value: \( value) "
188+ )
189+ }
190+ if let value = outputValue as? Bool {
191+ return . bool( value)
192+ }
193+ if let value = outputValue as? Int {
194+ return . bool( value != 0 )
195+ }
196+ throw GraphQLError (
197+ message: " Boolean cannot represent a non boolean value: \( outputValue) "
198+ )
199+ } ,
200+ parseValue: { inputValue in
201+ if case let . bool( value) = inputValue {
202+ return inputValue
203+ }
204+ throw GraphQLError (
205+ message: " Boolean cannot represent a non boolean value: \( inputValue) "
206+ )
207+ } ,
69208 parseLiteral: { ast in
70209 if let ast = ast as? BooleanValue {
71210 return . bool( ast. value)
@@ -86,8 +225,35 @@ public let GraphQLID = try! GraphQLScalarType(
86225 " response as a String; however, it is not intended to be human-readable. " +
87226 " When expected as an input type, any string (such as ` \" 4 \" `) or integer " +
88227 " (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 ) ) } ,
228+ serialize: { outputValue in
229+ if let value = outputValue as? Map {
230+ if case let . string( value) = value {
231+ return . string( value)
232+ }
233+ if case let . number( value) = value {
234+ return . string( value. description)
235+ }
236+ throw GraphQLError (
237+ message: " ID cannot represent value: \( value) "
238+ )
239+ }
240+ if let value = outputValue as? String {
241+ return . string( value)
242+ }
243+ if let value = outputValue as? Int {
244+ return . string( value. description)
245+ }
246+ throw GraphQLError ( message: " ID cannot represent value: \( outputValue) " )
247+ } ,
248+ parseValue: { inputValue in
249+ if case let . string( value) = inputValue {
250+ return inputValue
251+ }
252+ if case let . number( value) = inputValue, value. storageType == . int {
253+ return . string( value. description)
254+ }
255+ throw GraphQLError ( message: " ID cannot represent value: \( inputValue) " )
256+ } ,
91257 parseLiteral: { ast in
92258 if let ast = ast as? StringValue {
93259 return . string( ast. value)
0 commit comments