7
7
GraphQLNamedType ,
8
8
GraphQLNonNull ,
9
9
GraphQLObjectType ,
10
+ GraphQLOutputType ,
10
11
GraphQLSchema ,
11
12
GraphQLSemanticNonNull ,
12
13
GraphQLType ,
@@ -87,11 +88,14 @@ function makeConvertType(toStrict: boolean) {
87
88
. filter ( ( v ) => v . kind === Kind . INT )
88
89
. map ( ( v ) => Number ( v . value ) )
89
90
: [ 0 ] ;
91
+ const type = directive
92
+ ? applySemanticNonNull ( spec . type , levels )
93
+ : spec . type ;
90
94
return [
91
95
fieldName ,
92
96
{
93
97
...spec ,
94
- type : convertType ( spec . type , directive ? levels : undefined ) ,
98
+ type : convertType ( type ) ,
95
99
astNode : spec . astNode && {
96
100
...spec . astNode ,
97
101
directives : spec . astNode ?. directives ?. filter (
@@ -105,6 +109,48 @@ function makeConvertType(toStrict: boolean) {
105
109
} ;
106
110
}
107
111
112
+ /**
113
+ * Takes a GraphQL type along with levels at which to apply
114
+ * semantic-non-null, and returns a converted type with these levels applied.
115
+ */
116
+ function applySemanticNonNull ( type : GraphQLOutputType , levels : number [ ] ) {
117
+ function recurse (
118
+ type : GraphQLOutputType ,
119
+ level : number ,
120
+ ) : GraphQLOutputType {
121
+ if ( type instanceof GraphQLSemanticNonNull ) {
122
+ // Strip semantic-non-null types; this should never happen but if someone
123
+ // uses both semantic-non-null and the `@semanticNonNull` directive, we
124
+ // want the directive to win (I guess?)
125
+ return recurse ( type . ofType , level ) ;
126
+ } else if ( type instanceof GraphQLNonNull ) {
127
+ const inner = recurse ( type . ofType , level ) ;
128
+ if ( levels . includes ( level ) ) {
129
+ // Semantic non-null from `inner` replaces our GrpahQLNonNull wrapper
130
+ return inner ;
131
+ } else {
132
+ // Keep non-null wrapper; no semantic-non-null was added to `inner`
133
+ return new GraphQLNonNull ( inner ) ;
134
+ }
135
+ } else if ( type instanceof GraphQLList ) {
136
+ const inner = new GraphQLList ( recurse ( type . ofType , level + 1 ) ) ;
137
+ if ( levels . includes ( level ) ) {
138
+ return new GraphQLSemanticNonNull ( inner ) ;
139
+ } else {
140
+ return inner ;
141
+ }
142
+ } else {
143
+ if ( levels . includes ( level ) ) {
144
+ return new GraphQLSemanticNonNull ( type ) ;
145
+ } else {
146
+ return type ;
147
+ }
148
+ }
149
+ }
150
+
151
+ return recurse ( type , 0 ) ;
152
+ }
153
+
108
154
function convertTypes (
109
155
types : readonly GraphQLInterfaceType [ ] | null | undefined ,
110
156
) : undefined | ( ( ) => readonly GraphQLInterfaceType [ ] ) ;
@@ -124,30 +170,14 @@ function makeConvertType(toStrict: boolean) {
124
170
return ( ) => types . map ( ( t ) => convertType ( t ) ) ;
125
171
}
126
172
127
- function convertType (
128
- type : null | undefined ,
129
- semanticNonNullLevels ?: number [ ] ,
130
- ) : null | undefined ;
131
- function convertType (
132
- type : GraphQLObjectType ,
133
- semanticNonNullLevels ?: number [ ] ,
134
- ) : GraphQLObjectType ;
173
+ function convertType ( type : null | undefined ) : null | undefined ;
174
+ function convertType ( type : GraphQLObjectType ) : GraphQLObjectType ;
135
175
function convertType (
136
176
type : Maybe < GraphQLObjectType > ,
137
- semanticNonNullLevels ?: number [ ] ,
138
177
) : Maybe < GraphQLObjectType > ;
139
- function convertType (
140
- type : GraphQLNamedType ,
141
- semanticNonNullLevels ?: number [ ] ,
142
- ) : GraphQLNamedType ;
143
- function convertType (
144
- type : GraphQLType ,
145
- semanticNonNullLevels ?: number [ ] ,
146
- ) : GraphQLType ;
147
- function convertType (
148
- type : GraphQLType | null | undefined ,
149
- semanticNonNullLevels ?: number [ ] ,
150
- ) {
178
+ function convertType ( type : GraphQLNamedType ) : GraphQLNamedType ;
179
+ function convertType ( type : GraphQLType ) : GraphQLType ;
180
+ function convertType ( type : GraphQLType | null | undefined ) {
151
181
if ( ! type ) return type ;
152
182
if ( type instanceof GraphQLSemanticNonNull ) {
153
183
const unwrapped = convertType ( type . ofType ) ;
@@ -160,16 +190,7 @@ function makeConvertType(toStrict: boolean) {
160
190
} else if ( type instanceof GraphQLNonNull ) {
161
191
return new GraphQLNonNull ( convertType ( type . ofType ) ) ;
162
192
} else if ( type instanceof GraphQLList ) {
163
- const innerLevels = semanticNonNullLevels ?. includes ( 1 ) ? [ 0 ] : undefined ;
164
- if ( semanticNonNullLevels ?. includes ( 0 ) && toStrict ) {
165
- return new GraphQLNonNull (
166
- new GraphQLList ( convertType ( type . ofType , innerLevels ) ) ,
167
- ) ;
168
- } else {
169
- return new GraphQLList ( convertType ( type . ofType , innerLevels ) ) ;
170
- }
171
- } else if ( semanticNonNullLevels ?. includes ( 0 ) && toStrict ) {
172
- return new GraphQLNonNull ( convertType ( type ) ) ;
193
+ return new GraphQLList ( convertType ( type . ofType ) ) ;
173
194
}
174
195
if ( type . name . startsWith ( "__" ) ) {
175
196
return null ;
0 commit comments