-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
Normalize more fields
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,13 +7,18 @@ | |
use Mthole\OpenApiMerge\FileHandling\File; | ||
use openapiphp\openapi\spec\MediaType; | ||
use openapiphp\openapi\spec\OpenApi; | ||
use openapiphp\openapi\spec\Parameter; | ||
use openapiphp\openapi\spec\Reference; | ||
use openapiphp\openapi\spec\RequestBody; | ||
use openapiphp\openapi\spec\Response; | ||
use openapiphp\openapi\spec\Schema; | ||
|
||
use function array_map; | ||
use function array_values; | ||
use function assert; | ||
use function count; | ||
use function preg_match; | ||
use function sha1; | ||
|
||
use const DIRECTORY_SEPARATOR; | ||
|
||
|
@@ -26,17 +31,55 @@ public function normalizeInlineReferences( | |
$refFileCollection = []; | ||
foreach ($openApiDefinition->paths as $path) { | ||
foreach ($path->getOperations() as $operation) { | ||
assert($operation->responses !== null); | ||
foreach ($operation->responses->getResponses() as $statusCode => $response) { | ||
if ($response === null) { | ||
foreach (($operation->parameters ?? []) as $parameterIndex => $parameter) { | ||
if (! $parameter instanceof Parameter) { | ||
continue; | ||
} | ||
|
||
/** @var array<int, Parameter> $allParameters */ | ||
$allParameters = $operation->parameters; | ||
if ($parameter->schema instanceof Reference) { | ||
$allParameters[$parameterIndex]->schema = $this->normalizeReference( | ||
$parameter->schema, | ||
$refFileCollection, | ||
); | ||
} | ||
|
||
if ($parameter->schema instanceof Schema) { | ||
$allParameters[$parameterIndex]->schema = $this->normalizeProperties( | ||
$parameter->schema, | ||
$refFileCollection, | ||
); | ||
} | ||
|
||
$operation->parameters = $allParameters; | ||
} | ||
|
||
if ($operation->requestBody instanceof RequestBody) { | ||
foreach ($operation->requestBody->content as $contentType => $content) { | ||
$allRequestBodyContent = $operation->requestBody->content; | ||
if (! $content->schema instanceof Schema) { | ||
Check warning on line 61 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
|
||
continue; | ||
} | ||
|
||
$allRequestBodyContent[$contentType]->schema = $this->normalizeProperties( | ||
$content->schema, | ||
$refFileCollection, | ||
); | ||
$operation->requestBody->content = $allRequestBodyContent; | ||
} | ||
} | ||
|
||
assert($operation->responses !== null); | ||
foreach ($operation->responses->getResponses() as $statusCode => $response) { | ||
if ($response instanceof Reference) { | ||
$operation->responses->addResponse( | ||
(string) $statusCode, | ||
$this->normalizeReference($response, $refFileCollection), | ||
); | ||
} | ||
|
||
if (! ($response instanceof Response)) { | ||
continue; | ||
} | ||
|
||
|
@@ -89,13 +132,46 @@ public function normalizeInlineReferences( | |
} | ||
} | ||
|
||
if ($openApiDefinition->components !== null) { | ||
Check warning on line 135 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
|
||
foreach (($openApiDefinition->components->schemas ?? []) as $key => $schema) { | ||
Check warning on line 136 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
Check warning on line 136 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
|
||
$allSchemas = $openApiDefinition->components->schemas; | ||
if (! $schema instanceof Schema) { | ||
continue; | ||
} | ||
|
||
$allSchemas[$key] = $this->normalizeProperties($schema, $refFileCollection); | ||
$openApiDefinition->components->schemas = $allSchemas; | ||
} | ||
|
||
foreach (($openApiDefinition->components->responses ?? []) as $key => $response) { | ||
Check warning on line 146 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
Check warning on line 146 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
|
||
if (! $response instanceof Response) { | ||
Check warning on line 147 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
Check warning on line 147 in src/Merge/ReferenceNormalizer.php GitHub Actions / Tests with coverage and PR Comments (8.3)
|
||
continue; | ||
} | ||
|
||
/** @var array<string, Response> $allSchemas */ | ||
$allSchemas = $openApiDefinition->components->responses; | ||
foreach ($response->content as $contentKey => $content) { | ||
if (! $content->schema instanceof Schema) { | ||
continue; | ||
} | ||
|
||
$allSchemas[$key]->content[$contentKey]->schema = $this->normalizeProperties( | ||
$content->schema, | ||
$refFileCollection, | ||
); | ||
} | ||
|
||
$openApiDefinition->components->responses = $allSchemas; | ||
} | ||
} | ||
|
||
return new ReferenceResolverResult( | ||
$openApiDefinition, | ||
$this->normalizeFilePaths($openApiFile, $refFileCollection), | ||
); | ||
} | ||
|
||
/** @param list<string> $refFileCollection */ | ||
/** @param array<string, string> $refFileCollection */ | ||
private function normalizeReference(Reference $reference, array &$refFileCollection): Reference | ||
{ | ||
$matches = []; | ||
|
@@ -104,7 +180,7 @@ private function normalizeReference(Reference $reference, array &$refFileCollect | |
$refFile = $matches['referenceFile']; | ||
|
||
if ($refFile !== '') { | ||
$refFileCollection[] = $refFile; | ||
$refFileCollection[sha1($refFile)] = $refFile; | ||
} | ||
|
||
return new Reference(['$ref' => $matches['referenceString']]); | ||
|
@@ -114,17 +190,79 @@ private function normalizeReference(Reference $reference, array &$refFileCollect | |
} | ||
|
||
/** | ||
* @param list<string> $refFileCollection | ||
* @param array<string, string> $refFileCollection | ||
* | ||
* @return list<File> | ||
*/ | ||
private function normalizeFilePaths(File $openApiFile, array $refFileCollection): array | ||
{ | ||
return array_map( | ||
static fn (string $refFile): File => new File( | ||
$openApiFile->getAbsolutePath() . DIRECTORY_SEPARATOR . $refFile, | ||
), | ||
$refFileCollection, | ||
static function (string $refFile) use ($openApiFile): File { | ||
$absoluteFile = new File($refFile); | ||
if ($absoluteFile->exists()) { | ||
return $absoluteFile; | ||
} | ||
|
||
return new File( | ||
$openApiFile->getAbsolutePath() . DIRECTORY_SEPARATOR . $refFile, | ||
); | ||
}, | ||
array_values($refFileCollection), | ||
); | ||
} | ||
|
||
/** @param array<string, string> $refFileCollection */ | ||
public function normalizeProperties(Schema $schema, array &$refFileCollection): Schema | ||
{ | ||
if (! isset($schema->properties)) { | ||
return $schema; | ||
} | ||
|
||
$schema = $this->normalizeProperty($schema, $refFileCollection); | ||
$newProperties = $schema->properties; | ||
foreach ($schema->properties as $propertyName => $property) { | ||
$newProperties[$propertyName] = $this->normalizeProperty($property, $refFileCollection); | ||
$schema->properties = $newProperties; | ||
} | ||
|
||
return $schema; | ||
} | ||
|
||
/** | ||
* @param TArg $property | ||
* @param array<string, string> $refFileCollection | ||
* | ||
* @phpstan-return TArg | ||
* | ||
* @template TArg of Reference|Schema | ||
*/ | ||
public function normalizeProperty(Reference|Schema $property, array &$refFileCollection): Reference|Schema | ||
{ | ||
if ($property instanceof Reference) { | ||
return $this->normalizeReference($property, $refFileCollection); | ||
} | ||
|
||
if (! ($property instanceof Schema)) { | ||
return $property; | ||
} | ||
|
||
if ($property->items !== null) { | ||
$property->items = $this->normalizeProperty($property->items, $refFileCollection); | ||
} | ||
|
||
if ($property->additionalProperties instanceof Reference || $property->additionalProperties instanceof Schema) { | ||
$property->additionalProperties = $this->normalizeProperty( | ||
$property->additionalProperties, | ||
$refFileCollection, | ||
); | ||
} | ||
|
||
foreach (($property->anyOf ?? []) as $index => $anyOf) { | ||
$anyOfs = $property->anyOf; | ||
$anyOfs[$index] = $this->normalizeProperty($anyOf, $refFileCollection); | ||
$property->anyOf = $anyOfs; | ||
} | ||
|
||
return $property; | ||
} | ||
} |