@@ -90,27 +90,7 @@ public function read($scope = null): array
9090 $ typesToRedo = [];
9191 $ knownTypes = [];
9292 foreach ($ schemaFiles as $ partialSchemaContent ) {
93- $ partialSchemaTypes = $ this ->parseTypes ($ partialSchemaContent );
94-
95- /**
96- * TODO fix this
97- * There is a bug in parseTypes where the union type is also containing the information for the type below
98- * in this case that meant that we were missing the type directly below CompanyStructureEntity
99- *
100- * This means that we cannot find CompanyStructureItem later in getTypesToUse
101- *
102- * Manually split them out in a proof of concept hack, while we review the regex
103- */
104- if (isset ($ partialSchemaTypes ['CompanyStructureEntity ' ])) {
105- if (strpos ($ partialSchemaTypes ['CompanyStructureEntity ' ], 'type CompanyStructureItem ' ) !== false ) {
106- $ lines = explode (PHP_EOL . PHP_EOL , $ partialSchemaTypes ['CompanyStructureEntity ' ]);
107- if (isset ($ lines [0 ], $ lines [1 ]) && count ($ lines ) === 2 ) {
108- $ partialSchemaTypes ['CompanyStructureEntity ' ] = $ lines [0 ];
109- $ partialSchemaTypes ['CompanyStructureItem ' ] = $ lines [1 ];
110- }
111- unset($ lines );
112- }
113- }
93+ $ partialSchemaTypes = $ this ->parseTypesWithUnionHandling ($ partialSchemaContent );
11494
11595 // Filter out duplicated ones and save them into a list to be retried
11696 $ tmpTypes = $ knownTypes ;
@@ -225,6 +205,56 @@ private function readPartialTypes(string $graphQlSchemaContent): array
225205 return $ this ->removePlaceholderFromResults ($ partialResults );
226206 }
227207
208+ /**
209+ * Extract types as string from a larger string that represents the graphql schema using regular expressions
210+ *
211+ * The regex in parseTypes does not have the ability to split out the union data from the type below it for example
212+ *
213+ * > union X = Y | Z
214+ * >
215+ * > type foo {}
216+ *
217+ * This would produce only type key from parseTypes, X, which would contain also the type foo entry.
218+ *
219+ * This wrapper does some post processing as a workaround to split out the union data from the type data below it
220+ * which would give us two entries, X and foo
221+ *
222+ * @param string $graphQlSchemaContent
223+ * @return string[] [$typeName => $typeDeclaration, ...]
224+ */
225+ private function parseTypesWithUnionHandling (string $ graphQlSchemaContent ): array
226+ {
227+ $ types = $ this ->parseTypes ($ graphQlSchemaContent );
228+
229+ /*
230+ * A union schema contains also the data from the schema below it
231+ *
232+ * If there are two newlines in this union schema then it has data below its definition, meaning it contains
233+ * type information not relevant to its actual type
234+ */
235+ $ unionTypes = array_filter (
236+ $ types ,
237+ function ($ t ) {
238+ return (strpos ($ t , 'union ' ) !== false ) && (strpos ($ t , PHP_EOL . PHP_EOL ) !== false );
239+ }
240+ );
241+
242+ foreach ($ unionTypes as $ type => $ schema ) {
243+ $ splitSchema = explode (PHP_EOL . PHP_EOL , $ schema );
244+ // Get the type data at the bottom, this will be the additional type data not related to the union
245+ $ additionalTypeSchema = end ($ splitSchema );
246+ // Parse the additional type from the bottom so we can have its type key => schema pair
247+ $ additionalTypeData = $ this ->parseTypes ($ additionalTypeSchema );
248+ // Fix the union type schema so it does not contain the definition below it
249+ $ types [$ type ] = str_replace ($ additionalTypeSchema , '' , $ schema );
250+ // Append the additional data to types array
251+ $ additionalTypeKey = array_key_first ($ additionalTypeData );
252+ $ types [$ additionalTypeKey ] = $ additionalTypeData [$ additionalTypeKey ];
253+ }
254+
255+ return $ types ;
256+ }
257+
228258 /**
229259 * Extract types as string from a larger string that represents the graphql schema using regular expressions
230260 *
0 commit comments