@@ -112,17 +112,19 @@ struct CodeGenCtx {
112
112
113
113
/// True when we are parsing the inputs of a field with arguments
114
114
parsing_inputs : bool ,
115
+ /// True when we are parsing the output of a field with arguments
116
+ parsing_output : bool ,
115
117
}
116
118
117
119
impl CodeGenCtx {
118
120
/// `manifest` is generated from the first pass in the Typescript compiler API code
119
121
fn new ( manifest : HashMap < String , GraphQLKind > ) -> Self {
120
122
let schema = Schema :: new ( ) ;
121
- println ! ( "MANIFESET: {:?}" , manifest) ;
122
123
Self {
123
124
schema,
124
125
manifest,
125
126
parsing_inputs : false ,
127
+ parsing_output : false ,
126
128
}
127
129
}
128
130
@@ -234,14 +236,30 @@ impl CodeGenCtx {
234
236
TsType :: TsKeywordType ( TsKeywordType { kind, .. } ) => {
235
237
( Self :: parse_keyword_type ( kind) ?, None )
236
238
}
237
- TsType :: TsArrayType ( TsArrayType { elem_type, .. } ) => (
238
- Type_ :: List {
239
- // TODO: There is no way to set non-nullable array elements in TS,
240
- // meaning we cant represent [Int!]!
241
- ty : Box :: new ( self . parse_type ( field_name, elem_type, true ) ?. 0 ) ,
242
- } ,
243
- None ,
244
- ) ,
239
+ TsType :: TsArrayType ( TsArrayType { elem_type, .. } ) => {
240
+ match ( self . parsing_output , & * * elem_type) {
241
+ ( true , TsType :: TsTypeLit ( _) ) => {
242
+ let name = Self :: compute_new_name ( ComputeNameKind :: Output , field_name) ;
243
+ self . parse_type_literal ( FieldKind :: Object , & name, elem_type) ?;
244
+ (
245
+ Type_ :: List {
246
+ ty : Box :: new ( Type_ :: NamedType { name } ) ,
247
+ } ,
248
+ None ,
249
+ )
250
+ }
251
+ _ => {
252
+ (
253
+ Type_ :: List {
254
+ // TODO: There is no way to set non-nullable array elements in TS,
255
+ // meaning we cant represent [Int!]!
256
+ ty : Box :: new ( self . parse_type ( field_name, elem_type, true ) ?. 0 ) ,
257
+ } ,
258
+ None ,
259
+ )
260
+ }
261
+ }
262
+ }
245
263
TsType :: TsTypeRef ( TsTypeRef {
246
264
type_name,
247
265
type_params,
@@ -318,7 +336,7 @@ impl CodeGenCtx {
318
336
319
337
return Ok ( ( Type_ :: NamedType { name } , None ) ) ;
320
338
}
321
- _ => self . parse_type ( "" , non_null, true ) ,
339
+ _ => self . parse_type ( field_name , non_null, true ) ,
322
340
} ;
323
341
}
324
342
TsType :: TsTypeLit ( _) => {
@@ -383,17 +401,20 @@ impl CodeGenCtx {
383
401
. collect :: < Result < Vec < InputValue > > > ( ) ?;
384
402
self . parsing_inputs = false ;
385
403
404
+ self . parsing_output = true ;
386
405
// Last param can be anything here, since we don't know if the return type is
387
406
// optional until we parse it. `self.parse_type()` will make sure to return
388
407
// the correct type if we are parsing return type
389
408
let ( ret_ty, _) = self . parse_type ( field_name, & type_ann. type_ann , true ) ?;
409
+ self . parsing_output = false ;
390
410
391
411
return Ok ( ( ret_ty, Some ( args) ) ) ;
392
412
}
393
413
TsType :: TsUnionOrIntersectionType ( TsUnionOrIntersectionType :: TsUnionType ( uni) ) => {
394
414
let typ = Self :: unwrap_union ( uni) ?;
395
415
return self . parse_type ( field_name, typ, true ) ;
396
416
}
417
+ // TODO: Move TsTypeLit in here
397
418
r => {
398
419
println ! ( "{:?}" , r) ;
399
420
todo ! ( ) ;
@@ -1168,39 +1189,40 @@ mod tests {
1168
1189
] ,
1169
1190
) ;
1170
1191
1171
- // let src = "
1172
- // type User = { id: string; name: string; karma: number; }
1173
- // type GetUserInput = { id?: string; name?: string; karma?: number; }
1174
- // type Foo = { id: string; name: string; karma: number; }
1175
- // type Query = { getUser: (input: { user?: GetUserInput; karma?: number;}) => Promise<{ id: string; name: string; karma: number;}[] | null>; }
1176
- // type Mutation = {
1177
- // createUser: (input: { name?: string; karma?: number;}) => Promise<{ name: string;}>;
1178
- // updateUser: (input: { user: { id?: string; name?: string; };}) => Promise<{ id: string; name: string; karma: number;} | null>;
1179
- // }
1180
- // ";
1181
- // test(
1182
- // src,
1183
- // indoc! { r#"
1184
- // type User {
1185
- // id: String!
1186
- // name: String!
1187
- // karma: Int!
1188
- // }
1189
- // type FindUserOutput {
1190
- // user: User!
1191
- // success: Boolean!
1192
- // }
1193
- // type Query {
1194
- // findUser(id: String!): FindUserOutput
1195
- // }
1196
- // "# },
1197
- // vec![
1198
- // ("User", GraphQLKind::Object),
1199
- // ("GetUserInput", GraphQLKind::Input),
1200
- // ("Query", GraphQLKind::Object),
1201
- // ("Mutation", GraphQLKind::Object),
1202
- // ],
1203
- // );
1192
+ let src = "
1193
+ type User = { id: string; name: string; karma: number; }
1194
+ type Mutation = {
1195
+ updateUser: (input: { user: { id?: string; name?: string; };}) => Promise<{ id: string; name: string; karma: number;}[] | null>;
1196
+ }
1197
+ " ;
1198
+ test (
1199
+ src,
1200
+ indoc ! { r#"
1201
+ type User {
1202
+ id: String!
1203
+ name: String!
1204
+ karma: Int!
1205
+ }
1206
+ input UpdateUserInput {
1207
+ id: String
1208
+ name: String
1209
+ }
1210
+ type UpdateUserOutput {
1211
+ id: String!
1212
+ name: String!
1213
+ karma: Int!
1214
+ }
1215
+ type Mutation {
1216
+ updateUser(user: UpdateUserInput!): [UpdateUserOutput]
1217
+ }
1218
+ "# } ,
1219
+ vec ! [
1220
+ ( "User" , GraphQLKind :: Object ) ,
1221
+ ( "GetUserInput" , GraphQLKind :: Input ) ,
1222
+ ( "Query" , GraphQLKind :: Object ) ,
1223
+ ( "Mutation" , GraphQLKind :: Object ) ,
1224
+ ] ,
1225
+ ) ;
1204
1226
}
1205
1227
}
1206
1228
}
0 commit comments