@@ -90,27 +90,7 @@ public function read($scope = null): array
90
90
$ typesToRedo = [];
91
91
$ knownTypes = [];
92
92
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 );
114
94
115
95
// Filter out duplicated ones and save them into a list to be retried
116
96
$ tmpTypes = $ knownTypes ;
@@ -225,6 +205,56 @@ private function readPartialTypes(string $graphQlSchemaContent): array
225
205
return $ this ->removePlaceholderFromResults ($ partialResults );
226
206
}
227
207
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
+
228
258
/**
229
259
* Extract types as string from a larger string that represents the graphql schema using regular expressions
230
260
*
0 commit comments