Skip to content

Commit

Permalink
use content type shape and content type as class
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskapp committed Sep 21, 2024
1 parent 243ddea commit 449460d
Show file tree
Hide file tree
Showing 27 changed files with 99 additions and 82 deletions.
1 change: 1 addition & 0 deletions src/Generator/Client/Dto/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function __construct(
public array $queryStructNames,
public ?string $bodyName,
public ?string $bodyContentType,
public ?string $bodyContentShape,
public array $imports,
)
{
Expand Down
1 change: 1 addition & 0 deletions src/Generator/Client/Dto/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function __construct(
public ?string $className = null,
public ?Type $innerSchema = null,
public ?string $contentType = null,
public ?string $contentShape = null,
)
{
}
Expand Down
23 changes: 10 additions & 13 deletions src/Generator/Client/Language/php-operation.php.twig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
'headers' => [
{% if operation.bodyContentType %}
'Content-Type' => '{{ operation.bodyContentType }}',
{% elseif operation.bodyName %}
'Content-Type' => 'application/json'
{% endif %}
],
'query' => $this->parser->query([
Expand All @@ -36,14 +38,12 @@
{% endfor %}
]),
{% if operation.bodyName %}
{% if operation.bodyContentType == 'application/octet-stream' or operation.bodyContentType == 'text/plain' %}
{% if operation.bodyContentShape == 'application/octet-stream' or operation.bodyContentShape == 'application/xml' or operation.bodyContentShape == 'text/plain' %}
'body' => ${{ operation.bodyName }}
{% elseif operation.bodyContentType == 'application/x-www-form-urlencoded' %}
{% elseif operation.bodyContentShape == 'application/x-www-form-urlencoded' %}
'form_params' => ${{ operation.bodyName }}
{% elseif operation.bodyContentType == 'multipart/form-data' %}
{% elseif operation.bodyContentShape == 'multipart/form-data' %}
'multipart' => ${{ operation.bodyName }}
{% elseif operation.bodyContentType == 'application/xml' %}
'body' => ${{ operation.bodyName }}->saveXML()
{% else %}
'json' => ${{ operation.bodyName }}
{% endif %}
Expand Down Expand Up @@ -80,21 +80,18 @@
{% endfor %}

{% macro response(payload, in_throw) %}
{% if payload.contentType == 'application/octet-stream' %}
{% if payload.contentShape == 'application/octet-stream' %}
{% if in_throw %} {% endif %}$data = $body;
{% elseif payload.contentType == 'application/x-www-form-urlencoded' %}
{% elseif payload.contentShape == 'application/x-www-form-urlencoded' %}
{% if in_throw %} {% endif %}$data = [];
{% if in_throw %} {% endif %}parse_str((string) $body, $data);
{% elseif payload.contentType == 'application/json' %}
{% elseif payload.contentShape == 'application/json' %}
{% if in_throw %} {% endif %}$data = \json_decode((string) $body);
{% elseif payload.contentType == 'multipart/form-data' %}
{% elseif payload.contentShape == 'multipart/form-data' %}
{% if in_throw %} {% endif %}// @TODO currently not possible, please create an issue at https://github.com/apioo/psx-api if needed
{% if in_throw %} {% endif %}$data = [];
{% elseif payload.contentType == 'text/plain' %}
{% elseif payload.contentShape == 'text/plain' or payload.contentShape == 'application/xml' %}
{% if in_throw %} {% endif %}$data = (string) $body;
{% elseif payload.contentType == 'application/xml' %}
{% if in_throw %} {% endif %}$data = new \DOMDocument();
{% if in_throw %} {% endif %}$data->loadXML((string) $body);
{% else %}
{% if payload.innerSchema.isMap %}
{% if in_throw %} {% endif %}$data = $this->parser->parse((string) $body, {{ payload.innerSchema.type }}::class, isMap: true);
Expand Down
10 changes: 5 additions & 5 deletions src/Generator/Client/Language/typescript-operation.ts.twig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
headers: {
{% if operation.bodyContentType %}
'Content-Type': '{{ operation.bodyContentType }}',
{% elseif operation.bodyName %}
'Content-Type': 'application/json',
{% endif %}
},
params: this.parser.query({
Expand All @@ -34,14 +36,12 @@
'{{ realName }}',
{% endfor %}
]),
{% if operation.return.contentType == 'application/octet-stream' %}
{% if operation.return.contentShape == 'application/octet-stream' %}
responseType: 'arraybuffer',
{% elseif operation.return.contentType == 'application/json' %}
{% elseif operation.return.contentShape == 'application/json' %}
responseType: 'json',
{% elseif operation.return.contentType == 'text/plain' %}
{% elseif operation.return.contentShape == 'text/plain' or operation.return.contentShape == 'application/xml' %}
responseType: 'text',
{% elseif operation.return.contentType == 'application/xml' %}
responseType: 'document',
{% endif %}
{% if operation.bodyName %}
data: {{ operation.bodyName }}
Expand Down
25 changes: 21 additions & 4 deletions src/Generator/Client/LanguageBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$imports = [];
$path = $pathNames = [];
$query = $queryNames = $queryStructNames = [];
$body = $bodyName = $bodyContentType = null;
$body = $bodyName = $bodyContentType = $bodyContentShape = null;
foreach ($operation->getArguments()->getAll() as $name => $argument) {
$realName = $argument->getName();
if (empty($realName)) {
Expand All @@ -172,7 +172,8 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$bodyName = $normalized;

if ($argument->getSchema() instanceof ContentType) {
$bodyContentType = $argument->getSchema()->value;
$bodyContentType = $argument->getSchema()->toString();
$bodyContentShape = $argument->getSchema()->getShape();
}
}

Expand All @@ -185,6 +186,7 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$body = null;
$bodyName = null;
$bodyContentType = null;
$bodyContentShape = null;
}

$arguments = array_merge($path, $body !== null ? [$bodyName => $body] : [], $query);
Expand All @@ -195,7 +197,14 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$returnType = $this->newType($returnSchema, false, $definitions, Type\GeneratorInterface::CONTEXT_CLIENT | Type\GeneratorInterface::CONTEXT_RESPONSE);
$innerSchema = $returnSchema instanceof TypeInterface ? $this->getInnerSchema($returnSchema, $definitions) : null;

$return = new Dto\Response($operation->getReturn()->getCode(), $returnType, null, $innerSchema, $returnSchema instanceof ContentType ? $returnSchema->value : null);
$return = new Dto\Response(
$operation->getReturn()->getCode(),
$returnType,
null,
$innerSchema,
$returnSchema instanceof ContentType ? $returnSchema->toString() : null,
$returnSchema instanceof ContentType ? $returnSchema->getShape() : null,
);

if ($returnSchema instanceof TypeInterface) {
$this->resolveImport($returnSchema, $imports);
Expand All @@ -217,7 +226,14 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$exceptionClassName = $this->naming->buildExceptionClassNameByType($throwSchema);
$exceptions[$exceptionClassName] = new Dto\Exception($exceptionClassName, $exceptionType, 'The server returned an error', $exceptionImports);

$throws[$throw->getCode()] = new Dto\Response($throw->getCode(), $exceptionType, $exceptionClassName, $innerSchema, $throwSchema instanceof ContentType ? $throwSchema->value : null);
$throws[$throw->getCode()] = new Dto\Response(
$throw->getCode(),
$exceptionType,
$exceptionClassName,
$innerSchema,
$throwSchema instanceof ContentType ? $throwSchema->toString() : null,
$throwSchema instanceof ContentType ? $throwSchema->getShape() : null,
);

$imports[$this->normalizer->file($exceptionClassName)] = $exceptionClassName;
}
Expand All @@ -235,6 +251,7 @@ private function getOperations(array $operations, DefinitionsInterface $definiti
$queryStructNames,
$bodyName,
$bodyContentType,
$bodyContentShape,
$imports
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Generator/Client/Util/Naming.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function buildMethodNameByTag(string $tagName): string
public function buildExceptionClassNameByType(TypeInterface|ContentType $type): string
{
if ($type instanceof ContentType) {
return match ($type) {
return match ($type->getShape()) {
ContentType::BINARY => 'BinaryException',
ContentType::FORM => 'FormException',
ContentType::JSON => 'JsonException',
Expand Down
12 changes: 5 additions & 7 deletions src/Parser/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,18 +360,16 @@ private function getSchemaFromTypeHint(?\ReflectionType $type): string|ContentTy
if ($type instanceof \ReflectionNamedType) {
if ($type->getName() === 'mixed') {
return Passthru::class;
} elseif ($type->getName() === \DOMDocument::class) {
return ContentType::XML;
} elseif ($type->getName() === StreamInterface::class) {
return ContentType::BINARY;
return new ContentType(ContentType::BINARY);
} elseif ($type->getName() === 'string') {
return ContentType::TEXT;
return new ContentType(ContentType::TEXT);
} elseif ($type->getName() === 'PSX\\Data\\Body\\Json') {
return ContentType::JSON;
return new ContentType(ContentType::JSON);
} elseif ($type->getName() === 'PSX\\Data\\Body\\Multipart') {
return ContentType::MULTIPART;
return new ContentType(ContentType::MULTIPART);
} elseif ($type->getName() === 'PSX\\Data\\Body\\Form') {
return ContentType::FORM;
return new ContentType(ContentType::FORM);
} elseif (class_exists($type->getName())) {
return $type->getName();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/TypeAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private function parseArgument(\stdClass $data): Operation\Argument
}

$contentType = $data->contentType ?? null;
if (is_string($contentType)) {
if (is_string($contentType) && !empty($contentType)) {
$type = ContentType::from($contentType);
} else {
$schema = $data->schema ?? null;
Expand Down
3 changes: 3 additions & 0 deletions tests/Generator/Client/resource/php/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public function create(string $name, string $type, EntryCreate $payload): EntryM

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down Expand Up @@ -144,6 +145,7 @@ public function update(string $name, string $type, \PSX\Record\Record $payload):

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down Expand Up @@ -237,6 +239,7 @@ public function patch(string $name, string $type, array $payload): array

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down
1 change: 1 addition & 0 deletions tests/Generator/Client/resource/php_collection/BarTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function put(EntryCreate $payload): EntryMessage

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function create(EntryCreate $payload): EntryMessage

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function create(EntryCreate $payload): EntryMessage

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down
14 changes: 6 additions & 8 deletions tests/Generator/Client/resource/php_content_type/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,12 @@ public function text(string $body): string
}

/**
* @param \DOMDocument $body
* @return \DOMDocument
* @param string $body
* @return string
* @throws XmlException
* @throws ClientException
*/
public function xml(\DOMDocument $body): \DOMDocument
public function xml(string $body): string
{
$url = $this->parser->url('/xml', [
]);
Expand All @@ -269,15 +269,14 @@ public function xml(\DOMDocument $body): \DOMDocument
'query' => $this->parser->query([
], [
]),
'body' => $body->saveXML()
'body' => $body
];

try {
$response = $this->httpClient->request('POST', $url, $options);
$body = $response->getBody();

$data = new \DOMDocument();
$data->loadXML((string) $body);
$data = (string) $body;

return $data;
} catch (ClientException $e) {
Expand All @@ -287,8 +286,7 @@ public function xml(\DOMDocument $body): \DOMDocument
$statusCode = $e->getResponse()->getStatusCode();

if ($statusCode === 500) {
$data = new \DOMDocument();
$data->loadXML((string) $body);
$data = (string) $body;

throw new XmlException($data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@

class XmlException extends KnownStatusCodeException
{
private \DOMDocument $payload;
private string $payload;

public function __construct(\DOMDocument $payload)
public function __construct(string $payload)
{
parent::__construct('The server returned an error');

$this->payload = $payload;
}

/**
* @return \DOMDocument
* @return string
*/
public function getPayload(): \DOMDocument
public function getPayload(): string
{
return $this->payload;
}
Expand Down
3 changes: 3 additions & 0 deletions tests/Generator/Client/resource/php_test/ProductTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public function create(TestRequest $payload): TestResponse

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down Expand Up @@ -114,6 +115,7 @@ public function update(int $id, TestRequest $payload): TestResponse

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down Expand Up @@ -156,6 +158,7 @@ public function patch(int $id, TestRequest $payload): TestResponse

$options = [
'headers' => [
'Content-Type' => 'application/json'
],
'query' => $this->parser->query([
], [
Expand Down
3 changes: 3 additions & 0 deletions tests/Generator/Client/resource/typescript/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export class Client extends ClientAbstract {
url: url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down Expand Up @@ -127,6 +128,7 @@ export class Client extends ClientAbstract {
url: url,
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down Expand Up @@ -209,6 +211,7 @@ export class Client extends ClientAbstract {
url: url,
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class BarTag extends TagAbstract {
url: url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class FooBarTag extends TagAbstract {
url: url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class FooBazTag extends TagAbstract {
url: url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: this.parser.query({
}, [
Expand Down
Loading

0 comments on commit 449460d

Please sign in to comment.