11import GraphQL
22
3- public final class SchemaBuilder < Root> {
3+ public final class SchemaBuilder < Root, Context > {
44 var graphQLTypeMap : [ AnyType : GraphQLType ] = [
55 AnyType ( Int . self) : GraphQLInt,
66 AnyType ( Double . self) : GraphQLFloat,
@@ -17,8 +17,8 @@ public final class SchemaBuilder<Root> {
1717
1818 init ( ) { }
1919
20- public func query( name: String = " Query " , build: ( ObjectTypeBuilder < Root , Root > ) throws -> Void ) throws {
21- let builder = ObjectTypeBuilder < Root , Root > ( schema: self )
20+ public func query( name: String = " Query " , build: ( ObjectTypeBuilder < Root , Context , Root > ) throws -> Void ) throws {
21+ let builder = ObjectTypeBuilder < Root , Context , Root > ( schema: self )
2222 try build ( builder)
2323
2424 query = try GraphQLObjectType (
@@ -29,8 +29,8 @@ public final class SchemaBuilder<Root> {
2929 )
3030 }
3131
32- public func mutation( name: String = " Mutation " , build: ( ObjectTypeBuilder < Root , Root > ) throws -> Void ) throws {
33- let builder = ObjectTypeBuilder < Root , Root > ( schema: self )
32+ public func mutation( name: String = " Mutation " , build: ( ObjectTypeBuilder < Root , Context , Root > ) throws -> Void ) throws {
33+ let builder = ObjectTypeBuilder < Root , Context , Root > ( schema: self )
3434 try build ( builder)
3535
3636 mutation = try GraphQLObjectType (
@@ -41,8 +41,8 @@ public final class SchemaBuilder<Root> {
4141 )
4242 }
4343
44- public func subscription( name: String = " Subscription " , build: ( ObjectTypeBuilder < Root , Root > ) throws -> Void ) throws {
45- let builder = ObjectTypeBuilder < Root , Root > ( schema: self )
44+ public func subscription( name: String = " Subscription " , build: ( ObjectTypeBuilder < Root , Context , Root > ) throws -> Void ) throws {
45+ let builder = ObjectTypeBuilder < Root , Context , Root > ( schema: self )
4646 try build ( builder)
4747
4848 subscription = try GraphQLObjectType (
@@ -56,7 +56,7 @@ public final class SchemaBuilder<Root> {
5656 public func object< Type> (
5757 type: Type . Type ,
5858 interfaces: Any . Type ... ,
59- build: ( ObjectTypeBuilder < Root , Type > ) throws -> Void
59+ build: ( ObjectTypeBuilder < Root , Context , Type > ) throws -> Void
6060 ) throws {
6161 let name = fixName ( String ( describing: Type . self) )
6262 try `object` ( name: name, type: type, interfaces: interfaces, build: build)
@@ -66,7 +66,7 @@ public final class SchemaBuilder<Root> {
6666 type: Type . Type ,
6767 name: String ,
6868 interfaces: Any . Type ... ,
69- build: ( ObjectTypeBuilder < Root , Type > ) throws -> Void
69+ build: ( ObjectTypeBuilder < Root , Context , Type > ) throws -> Void
7070 ) throws {
7171 try `object` ( name: name, type: type, interfaces: interfaces, build: build)
7272 }
@@ -75,9 +75,9 @@ public final class SchemaBuilder<Root> {
7575 name: String ,
7676 type: Type . Type ,
7777 interfaces: [ Any . Type ] ,
78- build: ( ObjectTypeBuilder < Root , Type > ) throws -> Void
78+ build: ( ObjectTypeBuilder < Root , Context , Type > ) throws -> Void
7979 ) throws {
80- let builder = ObjectTypeBuilder < Root , Type > ( schema: self )
80+ let builder = ObjectTypeBuilder < Root , Context , Type > ( schema: self )
8181 try builder. addAllFields ( )
8282 try build ( builder)
8383
@@ -94,7 +94,7 @@ public final class SchemaBuilder<Root> {
9494
9595 public func interface< Type> (
9696 type: Type . Type ,
97- build: ( InterfaceTypeBuilder < Root , Type > ) throws -> Void
97+ build: ( InterfaceTypeBuilder < Root , Context , Type > ) throws -> Void
9898 ) throws {
9999 let name = fixName ( String ( describing: Type . self) )
100100 try interface ( name: name, type: type, build: build)
@@ -103,9 +103,9 @@ public final class SchemaBuilder<Root> {
103103 public func interface< Type> (
104104 name: String ,
105105 type: Type . Type ,
106- build: ( InterfaceTypeBuilder < Root , Type > ) throws -> Void
106+ build: ( InterfaceTypeBuilder < Root , Context , Type > ) throws -> Void
107107 ) throws {
108- let builder = InterfaceTypeBuilder < Root , Type > ( schema: self )
108+ let builder = InterfaceTypeBuilder < Root , Context , Type > ( schema: self )
109109 try build ( builder)
110110
111111 let interfaceType = try GraphQLInterfaceType (
@@ -118,15 +118,15 @@ public final class SchemaBuilder<Root> {
118118 map ( Type . self, to: interfaceType)
119119 }
120120
121- public func `enum`< Type> (
121+ public func `enum`< Type : OutputType > (
122122 type: Type . Type ,
123123 build: ( EnumTypeBuilder < Type > ) throws -> Void
124124 ) throws {
125125 let name = fixName ( String ( describing: Type . self) )
126126 try `enum` ( name: name, type: type, build: build)
127127 }
128128
129- public func `enum`< Type> (
129+ public func `enum`< Type : OutputType > (
130130 name: String ,
131131 type: Type . Type ,
132132 build: ( EnumTypeBuilder < Type > ) throws -> Void
@@ -142,6 +142,55 @@ public final class SchemaBuilder<Root> {
142142
143143 map ( Type . self, to: enumType)
144144 }
145+
146+ public func scalar< Type : OutputType > (
147+ type: Type . Type ,
148+ build: ( ScalarTypeBuilder < Type > ) throws -> Void
149+ ) throws {
150+ let name = fixName ( String ( describing: Type . self) )
151+ try scalar ( name: name, type: type, build: build)
152+ }
153+
154+ public func scalar< Type : OutputType > (
155+ name: String ,
156+ type: Type . Type ,
157+ build: ( ScalarTypeBuilder < Type > ) throws -> Void
158+ ) throws {
159+ let builder = ScalarTypeBuilder < Type > ( )
160+ try build ( builder)
161+
162+ if builder. parseValue != nil && builder. parseLiteral == nil {
163+ throw GraphQLError (
164+ message: " parseLiteral function is required. "
165+ )
166+ }
167+
168+ if builder. parseValue == nil && builder. parseLiteral != nil {
169+ throw GraphQLError (
170+ message: " parseValue function is required. "
171+ )
172+ }
173+
174+ let scalarType : GraphQLScalarType
175+
176+ if let parseValue = builder. parseValue, let parseLiteral = builder. parseLiteral {
177+ scalarType = try GraphQLScalarType (
178+ name: name,
179+ description: builder. description,
180+ serialize: builder. serialize,
181+ parseValue: parseValue,
182+ parseLiteral: parseLiteral
183+ )
184+ } else {
185+ scalarType = try GraphQLScalarType (
186+ name: name,
187+ description: builder. description,
188+ serialize: builder. serialize
189+ )
190+ }
191+
192+ map ( Type . self, to: scalarType)
193+ }
145194}
146195
147196extension SchemaBuilder {
@@ -355,7 +404,7 @@ extension SchemaBuilder {
355404 let argument = GraphQLArgument (
356405 type: try getInputType ( from: propertyType, field: field) ,
357406 description: argumentsType. descriptions [ property. key] ,
358- defaultValue: argumentsType. defaultValues [ property. key] ? . map
407+ defaultValue: try argumentsType. defaultValues [ property. key] ? . asMap ( )
359408 )
360409
361410 arguments [ property. key] = argument
@@ -366,11 +415,14 @@ extension SchemaBuilder {
366415 }
367416}
368417
369- public struct Schema < Root> {
418+ public typealias NoRoot = Void
419+ public typealias NoContext = Void
420+
421+ public struct Schema < Root, Context> {
370422 let schema : GraphQLSchema
371423
372- public init ( _ build: ( SchemaBuilder < Root > ) throws -> Void ) throws {
373- let builder = SchemaBuilder < Root > ( )
424+ public init ( _ build: ( SchemaBuilder < Root , Context > ) throws -> Void ) throws {
425+ let builder = SchemaBuilder < Root , Context > ( )
374426 try build ( builder)
375427
376428 guard let query = builder. query else {
@@ -387,35 +439,86 @@ public struct Schema<Root> {
387439 directives: builder. directives
388440 )
389441 }
442+ public func execute(
443+ request: String ,
444+ variables: [ String : Map ] = [ : ] ,
445+ operationName: String ? = nil
446+ ) throws -> Map {
447+ guard Root . self is Void . Type else {
448+ throw GraphQLError (
449+ message: " Root value is required. "
450+ )
451+ }
452+
453+ guard Context . self is Void . Type else {
454+ throw GraphQLError (
455+ message: " Context value is required. "
456+ )
457+ }
458+
459+ return try graphql (
460+ schema: schema,
461+ request: request,
462+ variableValues: variables,
463+ operationName: operationName
464+ )
465+ }
390466
391467 public func execute(
392468 request: String ,
393- contextValue : Any = Void ( ) ,
394- variableValues : [ String : Map ] = [ : ] ,
469+ rootValue : Root ,
470+ variables : [ String : Map ] = [ : ] ,
395471 operationName: String ? = nil
396- ) throws -> Map {
472+ ) throws -> Map {
473+ guard Context . self is Void . Type else {
474+ throw GraphQLError (
475+ message: " Context value is required. "
476+ )
477+ }
478+
479+ return try graphql (
480+ schema: schema,
481+ request: request,
482+ rootValue: rootValue,
483+ variableValues: variables,
484+ operationName: operationName
485+ )
486+ }
487+
488+ public func execute(
489+ request: String ,
490+ context: Context ,
491+ variables: [ String : Map ] = [ : ] ,
492+ operationName: String ? = nil
493+ ) throws -> Map {
494+ guard Root . self is Void . Type else {
495+ throw GraphQLError (
496+ message: " Root value is required. "
497+ )
498+ }
499+
397500 return try graphql (
398501 schema: schema,
399502 request: request,
400- contextValue: contextValue ,
401- variableValues: variableValues ,
503+ contextValue: context ,
504+ variableValues: variables ,
402505 operationName: operationName
403506 )
404507 }
405508
406509 public func execute(
407510 request: String ,
408511 rootValue: Root ,
409- contextValue : Any = Void ( ) ,
410- variableValues : [ String : Map ] = [ : ] ,
512+ context : Context ,
513+ variables : [ String : Map ] = [ : ] ,
411514 operationName: String ? = nil
412- ) throws -> Map {
515+ ) throws -> Map {
413516 return try graphql (
414517 schema: schema,
415518 request: request,
416519 rootValue: rootValue,
417- contextValue: contextValue ,
418- variableValues: variableValues ,
520+ contextValue: context ,
521+ variableValues: variables ,
419522 operationName: operationName
420523 )
421524 }
0 commit comments