Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ composer.lock
#~ Overridden condigs
phpstan.neon
phpunit.xml

#~ Example generated part
example/*
!example/.gitkeep
6 changes: 4 additions & 2 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
->setRules(
[
'@PER-CS3x0' => true,
]
],
)

//~ Format
Expand All @@ -20,5 +20,7 @@
[
__DIR__ . '/src',
__DIR__ . '/tests',
]))
__DIR__ . '/example',
],
))
;
38 changes: 2 additions & 36 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

```yaml
## [tag] - YYYY-MM-DD
[tag]: https://github.com/eureka-framework/component-template/compare/1.0.0...master
[tag]: https://github.com/eureka-framework/component-client-api-generator/compare/1.0.0...master
### Changed
- Change 1
### Added
Expand All @@ -17,40 +17,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

----

## [2.0.0] - 2026-01-05
### Added
- PHP 8.5 support
### Removed
- PHP support of versions < 8.3
### Changed
- Update Makefile
- Update CI configs
- Update dependencies

----

## [1.1.0] - 2023-03-15
### Changed
- Update Makefile
- Update CI GitHub Action
- Update composer.json
- Now compatible with PHP 8.2

## [1.0.2] - 2022-11-13
### Changed
- Update Makefile
- Update CI GitHub Action
- Update composer.json

## [1.0.1] - 2022-06-12
### Changed
- Fix changelog template link
- Update github workflow ci file

## [1.0.0] - 2022-06-12
### Added
- Add phpstan for static analyze & php compatibility
- Add Check compatibility with PHP 7.4 & 8.1 in CI
- Add Makefile & .dist files for CI
- Add Dummy Source & Dummy Test
- Add GitHub CI file & sonar project file
- Add initial version of the component client API generator.
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,16 @@ clean:
@if [ "$(shell ls -A ./build)" ]; then rm -rf ./build/*; fi; echo " done"

ci: clean validate install php/deps php/check php/tests php/integration php/min-compatibility php/max-compatibility php/analyze

#################################################################################################################
# Client API Generator

generate/query-mercury:
$(call header,Generating Client API)
@./vendor/bin/console ClientApiGenerator/Script/Generator --debug --config=example/query-mercury/config.json
@XDEBUG_MODE=off ./vendor/bin/php-cs-fixer fix -q

generate/artifacts-mmo:
$(call header,Generating Client API)
@./vendor/bin/console ClientApiGenerator/Script/Generator --debug --config=example/artifacts-mmo/config.json
@XDEBUG_MODE=off ./vendor/bin/php-cs-fixer fix -q
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# component-template
[![Current version](https://img.shields.io/packagist/v/eureka/component-template.svg?logo=composer)](https://packagist.org/packages/eureka/component-template)
[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=>%3D8.3&color=777bb4)](https://packagist.org/packages/eureka/component-template)
![CI](https://github.com/eureka-framework/component-template/workflows/CI/badge.svg)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-template&metric=alert_status)](https://sonarcloud.io/dashboard?id=eureka-framework_component-template)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-template&metric=coverage)](https://sonarcloud.io/dashboard?id=eureka-framework_component-template)
# component-client-api-generator
[![Current version](https://img.shields.io/packagist/v/eureka/component-client-api-generator.svg?logo=composer)](https://packagist.org/packages/eureka/component-client-api-generator)
[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=>%3D8.3&color=777bb4)](https://packagist.org/packages/eureka/component-client-api-generator)
![CI](https://github.com/eureka-framework/component-client-api-generator/workflows/CI/badge.svg)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-client-api-generator&metric=alert_status)](https://sonarcloud.io/dashboard?id=eureka-framework_component-client-api-generator)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-client-api-generator&metric=coverage)](https://sonarcloud.io/dashboard?id=eureka-framework_component-client-api-generator)

## Why?

Template for new components
Libs to generate Client API / SDK based on OpenApi json schema.



Expand All @@ -16,7 +16,7 @@ Template for new components
If you wish to install it in your project, require it via composer:

```bash
composer require eureka/component-template
composer require eureka/component-client-api-generator
```


Expand Down
18 changes: 11 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eureka/component-template",
"description": "Template for new component & domain",
"name": "eureka/component-client-api-generator",
"description": "Libs to generate Client API / SDK based on openapi json schema.",
"type": "library",
"minimum-stability": "stable",
"license": "MIT",
Expand All @@ -14,12 +14,13 @@

"autoload": {
"psr-4": {
"Eureka\\Component\\Template\\": "./src"
"Eureka\\Component\\ClientApiGenerator\\": "./src",
"Eureka\\Component\\ClientApiGenerator\\Script\\": "./scripts"
}
},
"autoload-dev": {
"psr-4": {
"Eureka\\Component\\Template\\Tests\\": "./tests"
"Eureka\\Component\\ClientApiGenerator\\Tests\\": "./tests"
}
},

Expand All @@ -31,17 +32,20 @@
},

"require": {
"php": ">=8.3"
"php": ">=8.3",
"cebe/php-openapi": "^1.0",
"eureka/component-console": "^7.0",
"nikic/php-parser": "^5.0"
},

"require-dev": {
"friendsofphp/php-cs-fixer": "^3.95.2",
"phpstan/phpstan": "^2.1.55",
"phpstan/phpstan": "^2.1.56",
"phpstan/phpstan-deprecation-rules": "^2.0.4",
"phpstan/phpstan-phpunit": "^2.0.16",
"phpstan/phpstan-strict-rules": "^2.0.11",
"phpunit/phpcov": "^11.0.4",
"phpunit/phpunit": "^12.5.25",
"phpunit/phpunit": "^12.5.28",
"shipmonk/composer-dependency-analyser": "^1.8.4"
}
}
Empty file added example/.gitkeep
Empty file.
7 changes: 7 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ parameters:
paths:
- ./src
- ./tests
- ./scripts

bootstrapFiles:
- ./vendor/autoload.php

treatPhpDocTypesAsCertain: false
strictRules:
disallowedEmpty: false

ignoreErrors: []
140 changes: 140 additions & 0 deletions scripts/Generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

/*
* Copyright (c) Romain Cottard
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Eureka\Component\ClientApiGenerator\Script;

use cebe\openapi\exceptions\IOException;
use cebe\openapi\exceptions\TypeErrorException;
use cebe\openapi\exceptions\UnresolvableReferenceException;
use cebe\openapi\json\InvalidJsonPointerSyntaxException;
use cebe\openapi\Reader;
use cebe\openapi\spec\Schema;
use Eureka\Component\ClientApiGenerator\ClientBuilder;
use Eureka\Component\ClientApiGenerator\Config\Config;
use Eureka\Component\ClientApiGenerator\Enum\OperationType;
use Eureka\Component\ClientApiGenerator\FormatterBuilder;
use Eureka\Component\ClientApiGenerator\Schema\JsonApiSchema;
use Eureka\Component\ClientApiGenerator\Schema\SchemaResolver;
use Eureka\Component\ClientApiGenerator\Type\TypeResolver;
use Eureka\Component\ClientApiGenerator\VOBuilder;
use Eureka\Component\Console\AbstractScript;
use Eureka\Component\Console\Help;
use Eureka\Component\Console\Option\Option;
use Eureka\Component\Console\Option\Options;
use PhpParser\BuilderFactory;

/**
* @phpstan-import-type ConfigData from Config
*/
class Generator extends AbstractScript
{
public function __construct(
) {
$this->setDescription('Orm generator');
$this->setExecutable();

$this->initOptions(
(new Options())
->add(new Option('c', 'config', 'Json config file for generator', mandatory: false, hasArgument: true))
->add(new Option('f', 'file', 'OpenAPI file to process', mandatory: false, hasArgument: true))
->add(new Option('n', 'namespace', 'Base namespace for all generated classes', mandatory: false, hasArgument: true))
->add(new Option('d', 'destination', 'Destination path for generated code', mandatory: false, hasArgument: true)),
);
}

public function help(): void
{
(new Help('...', $this->declaredOptions(), $this->output(), $this->options()))->display();
}

/**
* @throws IOException
* @throws TypeErrorException
* @throws UnresolvableReferenceException
* @throws InvalidJsonPointerSyntaxException
* @throws \JsonException
*/
public function run(): void
{
$config = $this->initConfig();

$builderFactory = new BuilderFactory();
$schemaResolver = new SchemaResolver($config);
$typeResolver = new TypeResolver($config);
$jsonApiSchema = new JsonApiSchema();
$voBuilder = new VOBuilder($builderFactory, $schemaResolver, $typeResolver);
$formatterBuilder = new FormatterBuilder($builderFactory, $voBuilder, $schemaResolver, $typeResolver);
$clientBuilder = new ClientBuilder($builderFactory, $formatterBuilder, $voBuilder, $jsonApiSchema, $schemaResolver, $typeResolver);

if (\str_ends_with($config->file, '.yaml')) {
$openapi = Reader::readFromYamlFile((string) \realpath($config->file));
} else {
$openapi = Reader::readFromJsonFile((string) \realpath($config->file));
}

//~ Add each path as client
$paths = $openapi->paths->getPaths();
foreach ($paths as $path => $pathItem) {
if ($config->isIgnoredPath($path)) {
continue;
}
$clientBuilder->add($path, $pathItem);
}

if (!\is_dir($config->destination) && !\mkdir($config->destination, 0755, true)) {
throw new \UnexpectedValueException("Failed to create directory '$config->destination' !");
}

$clientBuilder->generate($config->destination, $config->namespace);
$formatterBuilder->generate($config->destination, $config->namespace);
$voBuilder->generate($config->destination, $config->namespace);
}

/**
* @throws \JsonException
*/
private function initConfig(): Config
{
$configData = [];

$configFile = \trim((string) $this->options()->value('c', 'config'));
if (\file_exists($configFile)) {
/** @var ConfigData $configData */
$configData = \json_decode((string) \file_get_contents($configFile), associative: true, flags: \JSON_THROW_ON_ERROR);
}

$file = $this->options()->value('f', 'file');
$destination = $this->options()->value('d', 'destination');
$namespace = $this->options()->value('n', 'namespace');

$file = \trim((string) ($file ?? $configData['file'] ?? ''));
if (!\file_exists($file)) {
throw new \UnexpectedValueException('Cannot found file');
}

$schemas = [];
if (isset($configData['custom']['schemas']) && $configData['custom']['schemas'] !== []) {
foreach ($configData['custom']['schemas'] as $name => $definition) {
$schemas[$name] = new Schema($definition);
}
}

return new Config(
$file,
(string) ($namespace ?? $configData['namespace'] ?? ''),
(string) ($destination ?? $configData['destination'] ?? ''),
$configData['ignorePaths'] ?? [],
$configData['overrides']['types'] ?? [],
$configData['overrides']['schemas'] ?? [],
$schemas,
);
}
}
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Project
sonar.organization=eureka-framework
sonar.projectKey=eureka-framework_component-template
sonar.projectKey=eureka-framework_component-client-api-generator

# Path to sources
sonar.sources=src/
Expand Down
Loading
Loading