1
+ import {
2
+ GraphQLUnionType ,
3
+ GraphQLWrappingType ,
4
+ GraphQLObjectType ,
5
+ GraphQLInputObjectType ,
6
+ GraphQLInputField ,
7
+ GraphQLField ,
8
+ GraphQLInputType ,
9
+ GraphQLOutputType ,
10
+ GraphQLScalarType ,
11
+ GraphQLNamedType ,
12
+
13
+ isNonNullType ,
14
+ isListType ,
15
+ GraphQLFieldMap ,
16
+ GraphQLEnumType ,
17
+ GraphQLType ,
18
+ GraphQLInterfaceType ,
19
+ } from 'graphql'
20
+
21
+ import { Generator } from '../types'
22
+
23
+ export const generator : Generator = {
24
+ GraphQLUnionType : renderUnionType ,
25
+ GraphQLObjectType : renderObjectType ,
26
+ GraphQLInputObjectType : renderObjectType ,
27
+ GraphQLScalarType : renderScalarType ,
28
+ GraphQLEnumType : renderEnumType ,
29
+ GraphQLInterfaceType : renderObjectType ,
30
+ RootType : renderRootType ,
31
+ SchemaType : renderSchemaInterface ,
32
+ Main : renderMainMethod ,
33
+ }
34
+
35
+ const scalarMapping = {
36
+ Int : 'number' ,
37
+ String : 'string' ,
38
+ ID : 'string | number' ,
39
+ Float : 'number' ,
40
+ Boolean : 'boolean'
41
+ }
42
+
43
+ function renderMainMethod ( queryType : GraphQLObjectType , mutationType ?: GraphQLObjectType | null , subscriptionType ?: GraphQLObjectType | null ) {
44
+ return `export const binding: Schema = {
45
+ query: {
46
+ ${ renderMainMethodFields ( queryType . getFields ( ) ) }
47
+ }${ mutationType ? `,
48
+ mutation: {
49
+ ${ renderMainMethodFields ( mutationType . getFields ( ) ) }
50
+ }` : '' } ${ subscriptionType ? `,
51
+ subscription: {
52
+ ${ renderMainMethodFields ( subscriptionType . getFields ( ) ) }
53
+ }` : '' }
54
+ }`
55
+ }
56
+
57
+ function renderMainMethodFields ( fields : GraphQLFieldMap < any , any > ) : string {
58
+ return Object . keys ( fields ) . map ( f => {
59
+ const field = fields [ f ]
60
+ return ` ${ field . name } : (args, info): ${ renderFieldType ( field . type ) } ${ ! isNonNullType ( field . type ) ? ' | null' : '' } => { return /* TODO: Get actual implementation here from graphql-binding */ }`
61
+ } ) . join ( ',\n' )
62
+ }
63
+
64
+ function renderScalarType ( type : GraphQLScalarType ) : string {
65
+ return `${ type . description ? `/*
66
+ ${ type . description }
67
+ */
68
+ ` : '' } export type ${ type . name } = ${ scalarMapping [ type . name ] || 'string' } `
69
+ }
70
+
71
+ function renderEnumType ( type : GraphQLEnumType ) : string {
72
+ return `${ renderDescription ( type . description ) } export enum ${ type . name } {
73
+ ${ type . getValues ( ) . map ( e => ` ${ e . name } = '${ e . value } '` ) . join ( ',\n' ) }
74
+ }`
75
+ }
76
+
77
+ function renderRootType ( type : GraphQLObjectType ) : string {
78
+ const fieldDefinition = Object . keys ( type . getFields ( ) ) . map ( f => {
79
+ const field = type . getFields ( ) [ f ]
80
+ return ` ${ field . name } : (args: {${ field . args . length > 0 ? ' ' : '' } ${ field . args . map ( f => `${ renderFieldName ( f ) } : ${ renderFieldType ( f . type ) } ` ) . join ( ', ' ) } ${ field . args . length > 0 ? ' ' : '' } }, info: any) => ${ renderFieldType ( field . type ) } ${ ! isNonNullType ( field . type ) ? ' | null' : '' } `
81
+ } ) . join ( '\n' )
82
+
83
+ return renderInterfaceWrapper ( type . name , type . description , type . getInterfaces ( ) , fieldDefinition )
84
+ }
85
+
86
+ function renderUnionType ( type : GraphQLUnionType ) : string {
87
+ return `${ renderDescription ( type . description ) } export type ${ type . name } = ${ type . getTypes ( ) . map ( t => t . name ) . join ( ' | ' ) } `
88
+ }
89
+
90
+ function renderObjectType ( type : GraphQLObjectType | GraphQLInputObjectType | GraphQLInterfaceType ) : string {
91
+ const fieldDefinition = Object . keys ( type . getFields ( ) ) . map ( f => {
92
+ const field = type . getFields ( ) [ f ]
93
+ return ` ${ renderFieldName ( field ) } : ${ renderFieldType ( field . type ) } `
94
+ } ) . join ( '\n' )
95
+
96
+ let interfaces : GraphQLInterfaceType [ ] = [ ]
97
+ if ( type instanceof GraphQLObjectType ) {
98
+ interfaces = type . getInterfaces ( )
99
+ }
100
+
101
+ return renderInterfaceWrapper ( type . name , type . description , interfaces , fieldDefinition )
102
+ }
103
+
104
+
105
+
106
+ function renderFieldName ( field : GraphQLInputField | GraphQLField < any , any > ) {
107
+ return `${ field . name } ${ isNonNullType ( field . type ) ? '' : '?' } `
108
+ }
109
+
110
+ function renderFieldType ( type : GraphQLInputType | GraphQLOutputType ) {
111
+ if ( isNonNullType ( type ) ) {
112
+ return renderFieldType ( ( type as GraphQLWrappingType ) . ofType )
113
+ }
114
+ if ( isListType ( type ) ) {
115
+ return `Array<${ renderFieldType ( ( type as GraphQLWrappingType ) . ofType ) } >`
116
+ }
117
+ return ( type as GraphQLNamedType ) . name
118
+ }
119
+
120
+ function renderSchemaInterface ( queryType : GraphQLObjectType , mutationType ?: GraphQLObjectType | null , subscriptionType ?: GraphQLObjectType | null ) {
121
+ return `export interface Schema {
122
+ query: ${ queryType . name }
123
+ ${ mutationType ? ` mutation: ${ mutationType . name }
124
+ ` : '' } ${ subscriptionType ? ` subscription: ${ subscriptionType . name }
125
+ ` : '' } }`
126
+ }
127
+
128
+ function renderInterfaceWrapper ( typeName : string , typeDescription : string , interfaces : GraphQLInterfaceType [ ] , fieldDefinition : string ) : string {
129
+ return `${ renderDescription ( typeDescription ) } export interface ${ typeName } ${ interfaces . length > 0 ? ` extends ${ interfaces . map ( i => i . name ) . join ( ', ' ) } ` : '' } {
130
+ ${ fieldDefinition }
131
+ }`
132
+ }
133
+
134
+ function renderDescription ( description ?: string ) {
135
+ return `${ description ? `/*
136
+ ${ description }
137
+ */
138
+ ` : '' } `
139
+ }
0 commit comments