@@ -19,6 +19,8 @@ public class ViewModel
1919 private List < EnumViewModel > enumCollection = new List < EnumViewModel > ( ) ;
2020 private List < OperationViewModel > operationCollection ;
2121
22+ private Dictionary < string , string > fragmentQueries = new Dictionary < string , string > ( ) ;
23+
2224 public IEnumerable < TypeViewModel > Types => this . typeCollection ;
2325 public IEnumerable < EnumViewModel > Enums => this . enumCollection ;
2426 public IEnumerable < OperationViewModel > Operations => this . operationCollection ;
@@ -53,7 +55,7 @@ internal ViewModel(GraphQLDocument query, CodeGeneratorSettings settings)
5355 {
5456 Name = opName ,
5557 Arguments = argCollection ,
56- Query = op . Query ,
58+ QueryFragment = op . Query ,
5759 NamedQuery = op . Name ?? string . Empty ,
5860 ResultType = new TypeReferenceModel
5961 {
@@ -63,13 +65,44 @@ internal ViewModel(GraphQLDocument query, CodeGeneratorSettings settings)
6365 TypeName = GenerateType ( op . Selection , opName )
6466 }
6567 } ;
66-
68+ // collect all fragments reference from this query and grab thier nodes query strings too
69+ opVM . Query = FullQuery ( opVM ) ;
6770 this . operationCollection . Add ( opVM ) ;
6871 }
72+ }
73+ private string FullQuery ( OperationViewModel opVM )
74+ {
75+ StringBuilder sb = new StringBuilder ( ) ;
76+ sb . AppendLine ( opVM . QueryFragment ) ;
77+ var allTypes = ReferencedTypeList ( opVM . ResultType . TypeName ) . Distinct ( ) ;
78+ foreach ( var t in allTypes )
79+ {
80+ if ( this . fragmentQueries . ContainsKey ( t ) )
81+ {
82+ sb . AppendLine ( this . fragmentQueries [ t ] ) ;
83+ }
84+ }
85+ return sb . ToString ( ) ;
6986
70- // lets convert each to a type with a back track to lookup a type based on unique reference
71-
72- // I need type definitions for Operation Result and Argument types graphs
87+ IEnumerable < string > ReferencedTypeList ( string typeName )
88+ {
89+ var types = this . typeCollection . Where ( x => x . Name == typeName ) ;
90+ foreach ( var t in types )
91+ {
92+ foreach ( var f in t . Interfaces )
93+ {
94+ yield return f ;
95+ }
96+ foreach ( var f in t . Fields )
97+ {
98+ var childTypes = ReferencedTypeList ( f . Type . TypeName ) ;
99+ foreach ( var ct in childTypes )
100+ {
101+ yield return ct ;
102+ }
103+ }
104+ }
105+ }
73106 }
74107
75108 private TypeReferenceModel GenerateTypeReference ( FieldSelection field )
@@ -97,19 +130,28 @@ private string GenerateType(SetSelection selection, string operationName = null)
97130 return this . typeLookup [ $ "{ operationName } _{ selection . UniqueIdentifier } "] ? . Name ;
98131 }
99132
100- string name = FindBestName ( operationName ?? selection . RootType . Name , "Result" ) ;
133+ string name = FindBestName ( ( operationName ?? selection . RootType . Name ) , "Result" ) ;
134+ var lookupName = $ "{ operationName } _{ selection . UniqueIdentifier } ";
101135
136+ TypeViewModel type = BuildTypeViewModel ( selection , name , lookupName ) ;
137+
138+ return type . Name ;
139+ }
140+
141+ private TypeViewModel BuildTypeViewModel ( SetSelection selection , string name , string lookupName )
142+ {
102143 TypeViewModel type = new TypeViewModel ( name ) ;
103144
104- this . typeLookup . Add ( $ " { operationName } _ { selection . UniqueIdentifier } " , type ) ;
145+ this . typeLookup . Add ( lookupName , type ) ;
105146 this . typeCollection . Add ( type ) ;
106147 type . Fields = selection . Fields . Select ( x => new NamedTypeViewModel ( )
107148 {
108149 Name = x . Name ,
109150 Type = GenerateTypeReference ( x )
110151 } ) . ToList ( ) ;
111152
112- return type . Name ;
153+ type . Interfaces = selection . Fragments . Select ( x => GenerateType ( x ) ) . ToList ( ) ;
154+ return type ;
113155 }
114156
115157 private TypeReferenceModel GenerateTypeReference ( ObjectModel . ValueTypeReference type )
@@ -179,6 +221,17 @@ private string GenerateType(IGraphQLType type)
179221 this . enumCollection . Add ( typeVm ) ;
180222 return typeVm . Name ;
181223 }
224+ else if ( type is FragmentType fragment )
225+ {
226+
227+ TypeViewModel typeVm = BuildTypeViewModel ( fragment . Selection , name , $ "_{ fragment . Selection } _[fragment]") ;
228+ typeVm . IsInterface = true ;
229+
230+ fragmentQueries . Add ( typeVm . Name , fragment . Query ) ;
231+ this . inputTypeLookup . Add ( type , typeVm . Name ) ;
232+
233+ return typeVm . Name ;
234+ }
182235 else
183236 {
184237 throw new Exception ( "unkown type" ) ;
@@ -206,6 +259,7 @@ public class OperationViewModel
206259 public TypeReferenceModel ResultType { get ; internal set ; }
207260 public List < NamedTypeViewModel > Arguments { get ; internal set ; }
208261 public string Query { get ; internal set ; }
262+ public string QueryFragment { get ; internal set ; }
209263 public string NamedQuery { get ; internal set ; }
210264
211265 public OperationViewModel ( )
@@ -249,7 +303,12 @@ public TypeViewModel(string name)
249303
250304 // a type is a list of fields and and unique name
251305 public string Name { get ; set ; }
306+
307+ public bool IsInterface { get ; set ; }
308+
252309 public IEnumerable < NamedTypeViewModel > Fields { get ; set ; }
310+
311+ public IEnumerable < string > Interfaces { get ; set ; }
253312 }
254313
255314
0 commit comments