Skip to content

Commit

Permalink
Merge pull request #70 from shopware/ppi-1058/adjust-openapi-schema-g…
Browse files Browse the repository at this point in the history
…eneration-65

PPI-1058 - Adjust OpenAPI schema generation 6.5
  • Loading branch information
cyl3x authored Jan 24, 2025
2 parents f7b9a91 + be30b54 commit 7dead97
Show file tree
Hide file tree
Showing 9 changed files with 12,364 additions and 269 deletions.
1 change: 1 addition & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ jobs:
composer openapi:generate
git update-index --refresh || printf ''
git diff-index "${{ github.sha }}" --quiet -- src/Resources/app/administration/src/types/openapi.d.ts || (echo "Please run 'composer openapi:generate' to update openapi.d.ts" && exit 1)
git diff-index "${{ github.sha }}" --quiet -- src/Resources/Schema || (echo "Please run 'composer openapi:generate' to update Resources/Schema files" && exit 1)
20 changes: 0 additions & 20 deletions src/Checkout/ExpressCheckout/SalesChannel/ExpressCategoryRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,6 @@ public function getDecorated(): AbstractCategoryRoute
return $this->inner;
}

#[OA\Post(
path: '/store-api/category/{navigationId}',
operationId: 'readCategory',
description: 'This endpoint returns information about the category, as well as a fully resolved (hydrated with mapping values) CMS page, if one is assigned to the category. You can pass slots which should be resolved exclusively.',
tags: ['Store API', 'Category'],
parameters: [
new OA\Parameter(
name: 'navigationId',
description: 'Identifier of the navigation to be fetched',
in: 'path',
required: true,
schema: new OA\Schema(type: 'string', pattern: '^[0-9a-f]{32}$')
),
],
responses: [new OA\Response(
ref: '#/components/schemas/category_flat',
response: Response::HTTP_OK,
description: 'The loaded category with cms page'
)]
)]
#[Route(path: '/store-api/category/{navigationId}', name: 'store-api.category.detail', methods: ['GET', 'POST'])]
public function load(string $navigationId, Request $request, SalesChannelContext $context): CategoryRouteResponse
{
Expand Down
92 changes: 78 additions & 14 deletions src/DevOps/Command/GenerateOpenApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'swag:paypal:openapi:generate',
Expand All @@ -26,6 +28,8 @@
class GenerateOpenApi extends Command
{
private const ROOT_DIR = __DIR__ . '/../../..';
private const STORE_API_DIR = self::ROOT_DIR . '/src/Resources/Schema/StoreApi';
private const ADMIN_API_DIR = self::ROOT_DIR . '/src/Resources/Schema/AdminApi';

protected function execute(InputInterface $input, OutputInterface $output): int
{
Expand All @@ -36,28 +40,88 @@ protected function execute(InputInterface $input, OutputInterface $output): int
->add(new PayPalApiStructSnakeCasePropertiesProcessor())
->add(new RequireNonOptionalPropertiesProcessor());

$openApi = $generator->setProcessorPipeline($pipeline)->generate([
Util::finder(
self::ROOT_DIR . '/src',
[self::ROOT_DIR . '/src/DevOps', self::ROOT_DIR . '/src/Resources'] // ignored directories
),
]);
$generator = $generator->setProcessorPipeline($pipeline);

$storeApi = $input->getOption('store-api');
$adminApi = $input->getOption('admin-api');
$style = new SymfonyStyle($input, $output);

try {
if ($storeApi) {
$this->generateStoreApiSchema($style, $generator);
}

if ($adminApi) {
$this->generateAdminApiSchema($style, $generator);
}
} catch (\RuntimeException $e) {
$style->error($e->getMessage());

return Command::FAILURE;
}

return Command::SUCCESS;
}

protected function generateStoreApiSchema(SymfonyStyle $style, Generator $generator): void
{
$file = \realpath(self::STORE_API_DIR . '/openapi.json');
\assert($file !== false);

if (!\is_dir(self::STORE_API_DIR)) {
throw new \RuntimeException('Failed to find Store API directory at: ' . self::STORE_API_DIR);
}

$openApi = $generator->generate([
Util::finder(self::ROOT_DIR . '/src/RestApi'),
Util::finder(self::ROOT_DIR . '/src/Checkout'),
])?->toJson();

if ($openApi === null) {
// @phpstan-ignore-next-line
throw new \RuntimeException('Failed to generate OpenAPI schema');
throw new \RuntimeException('Failed to generate OpenAPI schema for Store API');
}

$cacheDir = self::ROOT_DIR . '/var/cache';
if (\file_put_contents($file, $openApi) === false) {
throw new \RuntimeException('Failed to write Store API schema to: ' . $file);
}

$style->success('Written Store API schema to: ' . $file);
}

protected function generateAdminApiSchema(SymfonyStyle $style, Generator $generator): void
{
$file = \realpath(self::ADMIN_API_DIR . '/openapi.json');
\assert($file !== false);

if (!\is_dir(self::ADMIN_API_DIR)) {
throw new \RuntimeException('Failed to find Admin API directory at: ' . self::ADMIN_API_DIR);
}

$openApi = $generator->generate([
Util::finder(self::ROOT_DIR . '/src/RestApi'),
Util::finder(self::ROOT_DIR . '/src/Administration'),
Util::finder(self::ROOT_DIR . '/src/Dispute'),
Util::finder(self::ROOT_DIR . '/src/OrdersApi'),
Util::finder(self::ROOT_DIR . '/src/PaymentsApi'),
Util::finder(self::ROOT_DIR . '/src/Pos'),
Util::finder(self::ROOT_DIR . '/src/Setting'),
Util::finder(self::ROOT_DIR . '/src/Webhook'),
])?->toJson();

if (!\is_dir($cacheDir) && !\mkdir($cacheDir, 0777, true)) {
echo 'Failed to create var/cache directory';
if ($openApi === null) {
throw new \RuntimeException('Failed to generate OpenAPI schema for Admin API');
}

return 1;
if (\file_put_contents($file, $openApi) === false) {
throw new \RuntimeException('Failed to write Admin API schema to: ' . $file);
}

\file_put_contents($cacheDir . '/openapi.yaml', $openApi->toYaml());
$style->success('Written Admin API schema to: ' . $file);
}

return 0;
protected function configure(): void
{
$this->addOption('store-api', null, InputOption::VALUE_NEGATABLE, 'Generate store-api schema into src/Resources/Schema/StoreApi', true);
$this->addOption('admin-api', null, InputOption::VALUE_NEGATABLE, 'Generate store-api schema into src/Resources/Schema/AdminApi', true);
}
}
Loading

0 comments on commit 7dead97

Please sign in to comment.