Skip to content

Commit

Permalink
feat: generate OpenAPI JSON from APIB
Browse files Browse the repository at this point in the history
  • Loading branch information
SMillerDev committed Sep 29, 2024
1 parent 71bb7ec commit f571f28
Show file tree
Hide file tree
Showing 18 changed files with 1,058 additions and 338 deletions.
83 changes: 83 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,89 @@ jobs:
name: coverage-${{ matrix.php-versions }}
path: coverage.xml

openapi:
name: File generation
needs: test
runs-on: ubuntu-latest
env:
PHPDRAFT_THIRD_PARTY: 1
extensions: curl,json,mbstring,uopz
key: cache-v1 # can be any string, change to clear the extension cache.
strategy:
matrix:
php-versions: [ '8.3' ]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- name: Setup cache environment
id: extcache
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ matrix.php-versions }}
extensions: ${{ env.extensions }}
key: ${{ env.key }}

- name: Cache extensions
uses: actions/cache@v4
with:
path: ${{ steps.extcache.outputs.dir }}
key: ${{ steps.extcache.outputs.key }}
restore-keys: ${{ steps.extcache.outputs.key }}

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: ${{ env.extensions }}
coverage: pcov
tools: pecl,phpunit

- name: Get Composer Cache Directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Validate composer.json and composer.lock
run: composer validate

- name: Install dependencies
run: composer install --prefer-dist --no-progress --ignore-platform-reqs

- name: Generate OpenAPI definition and HTML
run: php ./phpdraft --online --file tests/statics/full_test.apib --openapi openapi.json > out.html 2> error.txt || true

- name: Install check-jsonschema
run: pipx install check-jsonschema

- name: Validate OpenAPI spec
run: |
if [ -s "error.txt" ]; then
echo "The file 'error.txt' is not empty."
cat error.txt
exit 1
fi
if [ ! -s "index.html" ]; then
echo "The file 'index.html' is empty."
exit 1
fi
if [ ! -s "openapi.json" ]; then
echo "The file 'openapi.json' is empty."
exit 1
fi
check-jsonschema --schemafile https://spec.openapis.org/oas/3.1/schema/latest openapi.json
analytics:
name: Analytics
needs: test
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
/build/out
/build/*.phar
/tests/statics/index.*
src/Michelf/*
src/.gitignore
vendor/**

Expand All @@ -21,6 +20,8 @@ atlassian-ide-plugin.xml
*.pem

/index.html
/openapi.json

/coverage.xml
/event.json
!/src/PHPDraft/Out/
6 changes: 6 additions & 0 deletions phpdraft
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ try
->opt('help:h', 'This help text', false)
->opt('version:v', 'Print the version for PHPDraft.', false)
->opt('file:f', 'Specifies the file to parse.', false)
->opt('openapi:a', 'Output location for an OpenAPI file.', false)
->opt('yes:y', 'Always accept using the online mode.', false, 'bool')
->opt('online:o', 'Always use the online mode.', false, 'bool')
->opt('template:t', 'Specifies the template to use. (defaults to \'default\').', false)
Expand Down Expand Up @@ -90,6 +91,11 @@ try
$data = json_decode($json_string);
}

if (isset($args['openapi'])) {
$openapi = ParserFactory::getOpenAPI()->init($data);
$openapi->write($args['openapi']);
}

$html = ParserFactory::getJson()->init($data);
$name = 'PHPD_SORT_' . strtoupper($args->getOpt('sort', ''));
$html->sorting = Sorting::${$name} ?? Sorting::PHPD_SORT_NONE->value;
Expand Down
8 changes: 5 additions & 3 deletions src/PHPDraft/Model/HTTPRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace PHPDraft\Model;

use PHPDraft\Model\Elements\ObjectStructureElement;
use PHPDraft\Model\Elements\RequestBodyElement;
use PHPDraft\Model\Elements\StructureElement;

Expand Down Expand Up @@ -43,7 +44,7 @@ class HTTPRequest implements Comparable
*
* @var string
*/
public string $description;
public string $description = '';

/**
* Parent class.
Expand All @@ -68,9 +69,10 @@ class HTTPRequest implements Comparable
/**
* Structure of the request.
*
* @var RequestBodyElement[]|RequestBodyElement
* @var RequestBodyElement[]|RequestBodyElement|ObjectStructureElement
*/
public mixed $struct = [];
public RequestBodyElement|ObjectStructureElement|array|null $struct = [];

/**
* Identifier for the request.
*
Expand Down
4 changes: 2 additions & 2 deletions src/PHPDraft/Model/Transition.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class Transition extends HierarchyElement
/**
* HTTP method used.
*
* @var string
* @var string|null
*/
public string $method;
public ?string $method = NULL;

/**
* URI.
Expand Down
64 changes: 42 additions & 22 deletions src/PHPDraft/Out/BaseTemplateRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,21 @@ abstract class BaseTemplateRenderer
* @var int
*/
public int $sorting;

/**
* CSS Files to load.
*
* @var string[]
*/
public array $css = [];
/**
* JS Files to load.
*
* @var string[]
*/
public array $js = [];
/**
* The image to use as a logo.
*
* @var string|null
*/
protected ?string $image = null;
/**
* The template file to load.
* JSON representation of an API Blueprint.
*
* @var string
* @var object
*/
protected string $template;
protected object $object;

/**
* The base data of the API.
*
* @var array<string, mixed>
*/
protected array $base_data;
protected array $base_data = [];

/**
* JSON object of the API blueprint.
*
Expand All @@ -66,4 +51,39 @@ abstract class BaseTemplateRenderer
* @var BasicStructureElement[]
*/
protected array $base_structures = [];

/**
* Parse base data
*
* @param object $object
*/
protected function parse_base_data(object $object): void
{
//Prepare base data
if (!is_array($object->content[0]->content)) {
return;
}

$this->base_data['TITLE'] = $object->content[0]->meta->title->content ?? '';

foreach ($object->content[0]->attributes->metadata->content as $meta) {
$this->base_data[$meta->content->key->content] = $meta->content->value->content;
}

foreach ($object->content[0]->content as $value) {
if ($value->element === 'copy') {
$this->base_data['DESC'] = $value->content;
continue;
}

$cat = new Category();
$cat = $cat->parse($value);

Check warning on line 80 in src/PHPDraft/Out/BaseTemplateRenderer.php

View check run for this annotation

Codecov / codecov/patch

src/PHPDraft/Out/BaseTemplateRenderer.php#L79-L80

Added lines #L79 - L80 were not covered by tests

if (($value->meta->classes->content[0]->content ?? null) === 'dataStructures') {
$this->base_structures = array_merge($this->base_structures, $cat->structures);

Check warning on line 83 in src/PHPDraft/Out/BaseTemplateRenderer.php

View check run for this annotation

Codecov / codecov/patch

src/PHPDraft/Out/BaseTemplateRenderer.php#L82-L83

Added lines #L82 - L83 were not covered by tests
} else {
$this->categories[] = $cat;

Check warning on line 85 in src/PHPDraft/Out/BaseTemplateRenderer.php

View check run for this annotation

Codecov / codecov/patch

src/PHPDraft/Out/BaseTemplateRenderer.php#L85

Added line #L85 was not covered by tests
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,36 @@
use Twig\TwigFilter;
use Twig\TwigTest;

class TemplateRenderer extends BaseTemplateRenderer
class HtmlTemplateRenderer extends BaseTemplateRenderer
{


/**
* CSS Files to load.
*
* @var string[]
*/
public array $css = [];

/**
* JS Files to load.
*
* @var string[]
*/
public array $js = [];
/**
* The image to use as a logo.
*
* @var string|null
*/
protected ?string $image = null;
/**
* The template file to load.
*
* @var string
*/
protected string $template;

/**
* TemplateGenerator constructor.
*
Expand Down Expand Up @@ -109,41 +137,6 @@ public function get(object $object): string
]);
}

/**
* Parse base data
*
* @param object $object
*/
private function parse_base_data(object $object): void
{
//Prepare base data
if (!is_array($object->content[0]->content)) {
return;
}

$this->base_data['TITLE'] = $object->content[0]->meta->title->content ?? '';

foreach ($object->content[0]->attributes->metadata->content as $meta) {
$this->base_data[$meta->content->key->content] = $meta->content->value->content;
}

foreach ($object->content[0]->content as $value) {
if ($value->element === 'copy') {
$this->base_data['DESC'] = $value->content;
continue;
}

$cat = new Category();
$cat = $cat->parse($value);

if (($value->meta->classes->content[0]->content ?? null) === 'dataStructures') {
$this->base_structures = array_merge($this->base_structures, $cat->structures);
} else {
$this->categories[] = $cat;
}
}
}

/**
* Get the path to a file to include.
*
Expand Down
Loading

0 comments on commit f571f28

Please sign in to comment.