Commit 040c1790 authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Extraction du générateur de typescript sour la forme d'un bundle.

parents
{
"name": "irstea/ng-model-generator-bundle",
"description": "Génération de modèles Typescript pour Angular à partir des données d'API-platform.",
"type": "symfony-bundle",
"license": "lgpl-3+",
"authors": [
{
"name": "Guillaume Perréal",
"email": "guillaume.perreal@irstea.fr"
}
],
"require": {}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Class AnonymousObject.
*/
class AnonymousObject extends Type
{
/**
* @var Property[]
*/
private $properties = [];
/**
* Resource constructor.
*
* @param Property[] $properties
*/
public function __construct(array $properties = [])
{
foreach ($properties as $p) {
$this->addProperty($p);
}
}
/**
* Get properties.
*
* @return Property[]
*/
public function getProperties(): array
{
return $this->properties;
}
/**
* @param Property $property
*/
public function addProperty(Property $property): void
{
$name = $property->getName();
if (isset($this->properties[$name])) {
throw new \InvalidArgumentException("Property $name already defined");
}
$this->properties[$name] = $property;
}
/**
* @param Property $property
*/
public function mergeProperty(Property $property): void
{
$name = $property->getName();
if (!isset($this->properties[$name])) {
$this->properties[$name] = $property;
return;
}
$this->properties[$name]->mergeWith($property);
}
/**
* @param string $name
* @param Type $type
* @param bool $nullable
* @param bool $identifier
* @param bool $readonly
*/
public function declareProperty(string $name, Type $type, bool $nullable = true, bool $identifier = false, bool $readonly = false): void
{
$l = \strlen($name);
if (substr($name, $l - 2) === '[]') {
$this->declareProperty(substr($name, 0, $l - 2), new Collection($type), $nullable, $identifier, $readonly);
return;
}
// $opening = strpos($name, '[');
// if ($opening !== false) {
// $closing = strpos($name, ']', $opening);
// $tail = substr($name, $opening + 1, $closing - $opening - 1) . substr($name, $closing + 1);
// $name = substr($name, 0, $opening);
//
// $newType = new AnonymousObject();
// $newType->declareProperty($tail, $type, $nullable, $identifier, $readonly);
// $type = $newType;
// $nullable = true;
// $identifier = $readonly = false;
// }
$this->mergeProperty(new Property($name, '', $type, $identifier, $nullable, $readonly));
}
/**
* @param string $name
*
* @return bool
*/
public function hasProperty(string $name): bool
{
return isset($this->properties[$name]);
}
/**
* @param string $name
*
* @return Property
*/
public function getProperty(string $name): Property
{
return $this->properties[$name];
}
/**
* {@inheritdoc}
*/
public function getReference(): string
{
return $this->getDeclaration();
}
/**
* {@inheritdoc}
*/
public function getDeclaration(): string
{
$parts = ['{'];
uasort($this->properties, [Property::class, 'compare']);
foreach ($this->properties as $prop) {
$parts[] = ' ' . $prop->getDeclaration() . '; ' . $prop->getComment();
}
$parts[] = '}';
return implode("\n", $parts);
}
/**
* {@inheritdoc}
*/
public function mergeWith(Type $t): Type
{
if ($t instanceof self) {
$obj = clone $this;
foreach ($t->getProperties() as $p) {
$obj->mergeProperty($p);
}
return $obj;
}
return parent::mergeWith($t);
}
}
return $obj;
}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Class BuiltinType.
*/
class BuiltinType extends NamedType
{
/**
* {@inheritdoc}
*/
public function mergeWith(Type $t): Type
{
return ($t instanceof self && $t->getName() === $this->getName()) ? $this : new Union([$this]);
}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Class Collection.
*/
class Collection extends Type
{
/** @var Type */
private $itemType;
/**
* Collection constructor.
*
* @param Type $itemType
*/
public function __construct(Type $itemType)
{
$this->itemType = $itemType;
}
/**
* {@inheritdoc}
*/
public function getReference(): string
{
return sprintf($this->itemType->hasSimpleReference() ? '%s[]' : 'Array<%s>', $this->itemType->getReference());
}
/**
* {@inheritdoc}
*/
public function hasSimpleReference(): bool
{
return false;
}
/**
* {@inheritdoc}
*/
public function getComment(): string
{
return $this->itemType->getComment();
}
/**
* @return Type
*/
public function getItemType(): Type
{
return $this->itemType;
}
/**
* @param Type $t
*
* @return Type
*/
public function mergeWith(Type $t): Type
{
if ($t instanceof self) {
return new self($this->itemType->mergeWith($t->itemType));
}
return parent::mergeWith($t);
}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
use ApiPlatform\Core\Api\OperationType;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
/**
* Class Context.
*/
class Context
{
/**
* @var string
*/
private $baseClass;
/**
* @var ResourceMetadata
*/
private $baseResourceMeta;
/**
* @var string
*/
private $operationName = '';
/**
* @var string
*/
private $operationType = '';
/**
* @var string
*/
private $method = '';
/**
* @var string[]
*/
private $groups = [];
/**
* @var bool
*/
private $normalization = true;
/**
* Context constructor.
*
* @param string $baseClass
* @param ResourceMetadata $baseResourceMeta
*/
public function __construct(string $baseClass, ResourceMetadata $baseResourceMeta)
{
$this->baseClass = $baseClass;
$this->baseResourceMeta = $baseResourceMeta;
}
/**
* @param string $operationName
* @param string $operationType
*
* @return Context
*/
public function withOperation(string $operationName, string $operationType): self
{
$new = clone $this;
$new->operationName = $operationName;
$new->operationType = $operationType;
return $new;
}
/**
* @param string $method
*
* @return Context
*/
public function withMethod(string $method): self
{
$new = clone $this;
$new->method = $method;
return $new;
}
/**
* @param array $groups
* @param bool $normalization
*
* @return Context
*/
public function withSerializerContext(array $groups, bool $normalization): self
{
$new = clone $this;
sort($groups);
$new->groups = $groups;
$new->normalization = $normalization;
return $new;
}
/**
* Get baseClass.
*
* @return string
*/
public function getBaseClass(): string
{
return $this->baseClass;
}
/**
* Get baseResourceMeta.
*
* @return ResourceMetadata
*/
public function getBaseResourceMeta(): ResourceMetadata
{
return $this->baseResourceMeta;
}
/**
* @param string $attributeName
* @param null $defaultValue
* @param bool $resourceFallback
*
* @return mixed
*/
public function getOperationAttribute(
string $attributeName,
$defaultValue = null,
bool $resourceFallback = false
) {
if ($this->isCollectionOperation()) {
return $this->getCollectionOperationAttribute($attributeName, $defaultValue, $resourceFallback);
}
return $this->getItemOperationAttribute($attributeName, $defaultValue, $resourceFallback);
}
/**
* @param string $key
* @param null $defaultValue
* @param bool $resourceFallback
*
* @return mixed
*/
public function getCollectionOperationAttribute(
string $key,
$defaultValue = null,
bool $resourceFallback = false
) {
return $this->baseResourceMeta->getCollectionOperationAttribute($this->operationName, $key, $defaultValue, $resourceFallback);
}
/**
* @param string $key
* @param null $defaultValue
* @param bool $resourceFallback
*
* @return mixed
*/
public function getItemOperationAttribute(
string $key,
$defaultValue = null,
bool $resourceFallback = false
) {
return $this->baseResourceMeta->getItemOperationAttribute($this->operationName, $key, $defaultValue, $resourceFallback);
}
/**
* Get operationName.
*
* @return string
*/
public function getOperationName(): string
{
return $this->operationName;
}
/**
* Get operationType.
*
* @return string
*/
public function getOperationType(): string
{
return $this->operationType;
}
/**
* @return bool
*/
public function isCollectionOperation(): bool
{
return $this->operationType === OperationType::COLLECTION;
}
/**
* Get method.
*
* @return string
*/
public function getMethod(): string
{
return $this->method;
}
/**
* Get groups.
*
* @return string[]
*/
public function getGroups(): array
{
return $this->groups;
}
/**
* Get normalization.
*
* @return bool
*/
public function isNormalization(): bool
{
return $this->normalization;
}
/**
* @return string
*/
public function getSuffix(): string
{
return ucfirst($this->operationType) .
ucfirst(\Doctrine\Common\Inflector\Inflector::camelize($this->operationName)) .
($this->normalization ? 'Response' : 'Request');
}
/**
* @return string
*/
public function getKeySuffix(): string
{
return sha1($this->getSuffix());
}
/**
* @return array
*/
public function getNameCollectionOptions(): array
{
return !empty($this->groups) ? ['serializer_groups' => $this->groups] : [];
}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Interface Declarable.
*/
interface Declarable
{
/**
* @return string
*/
public function getDeclaration(): string;
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Class NamedTrait.
*/
trait NamedTrait
{
/**
* @var string
*/
private $name;
/**
* @param string $name
*/
private function setName(string $name): void
{
$this->name = $name;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return bool
*/
public function getReference(): string
{
return $this->getName();
}
/**
* @return bool
*/
public function hasSimpleReference(): bool
{
return true;
}
/**
* @return string
*/
public function getEscapedName(): string
{
return preg_match('/^[a-z_][0-9a-z_]*$/i', $this->name) ? $this->name : "'{$this->name}'";
}
}
<?php declare(strict_types=1);
/*
* Copyright (C) 2017-2018 IRSTEA
* All rights reserved.
*/
namespace App\Serializer\Typescript;
/**
* Class NamedType.
*/
abstract class NamedType extends Type
{
use NamedTrait;
/**
* BuiltinType constructor.
*
* @param string $name
*/
public function __construct(string $name)
{