Skip to content

Commit c36fb66

Browse files
committed
Update GraphQlReader, generalise union handling
This workaround handles a bug where parseTypes also contains the data from below it ``` union X = Y | Z type foo {} ``` Would return ```php [ 'x' => 'union X = Y | Z type foo {}' ] ``` instead of ```php [ 'x' => 'union X = Y | Z', 'foo' => 'type foo {}' ] ``` This workaround deals only with union types, so doesnt materially affect anything in most cases.
1 parent 603963e commit c36fb66

File tree

1 file changed

+51
-21
lines changed

1 file changed

+51
-21
lines changed

lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader.php

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)