Skip to content

Commit

Permalink
✨ custom interface support take one
Browse files Browse the repository at this point in the history
  • Loading branch information
acidjazz committed Aug 18, 2021
1 parent 1901c23 commit 741beee
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
22 changes: 22 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,27 @@ public function getFirstNameAttribute(): string // <- this
}
```
### Custom Interfaces
If you have custom interfaces you are using for your models you can specify them in a reserved `interfaces` array
For example for a custom `Point` interface in a `Location` model you can put this in the model
```php
public array $interfaces = [
'coordinate' => [
'name' => 'Point',
'import' => "@/types/api",
],
];
```

And it should generate:

```ts
import { Point } from '@/types/api'

export interface Location {
// columns
coordinate: Point
}
```
41 changes: 38 additions & 3 deletions src/ModelInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class ModelInterface
'point' => 'Point',
];

public array $imports = [];


public function __construct()
{
Expand All @@ -49,15 +51,36 @@ public function __construct()
*/
public function generate(): string
{
$allCode = '';
$models = $this->getModels();
$allCode = $this->getImports($models);
foreach ($models as $model) {
$interface = $this->getInterface(new $model());
$allCode .= $this->getCode($interface);
}
return $allCode;
}

/**
* Generate a list of imports from specified interfaces
* @param Collection $models
* @return string
*/
private function getImports(Collection $models): string {
$code = '';
$imports = [];
foreach ($models as $model) {
if ($interfaces = (new $model())->interfaces) {
foreach ($interfaces as $interface) {
$imports[$interface['import']][] = $interface['name'];
}
}
}
foreach ($imports as $import=>$names) {
$code .= "import { ". join(', ', array_unique($names)) . " } from '$import'\n";
}
return $code;
}

/**
* Build an interface from a model
* @param Model $model
Expand Down Expand Up @@ -128,7 +151,6 @@ public function getRelations(Model $model): array
$type = (string) $reflection->getReturnType();
$code = file($reflection->getFileName())[$reflection->getEndLine()-2];
preg_match('/\((.*?)::class/', $code, $matches);
if (strstr($type, 'or')) ray($type);
if ($matches && $matches[1]) {

if ($type === 'Illuminate\Database\Eloquent\Relations\BelongsTo' ||
Expand Down Expand Up @@ -181,6 +203,12 @@ public function getMutators(Model $model): array
$mutations = [];
$mutators = $model->getMutatedAttributes();
foreach ($mutators as $mutator) {

if (isset($model->interfaces) && isset($model->interfaces[$mutator])) {
$mutations[$mutator] = $model->interfaces[$mutator]['name'];
continue;
}

$method = 'get' . $this->camelize($mutator) . 'Attribute';
$reflection = new ReflectionMethod($model, $method);
if (!$reflection->hasReturnType()) {
Expand Down Expand Up @@ -219,10 +247,17 @@ private function getColumns(Model $model): array
{
$columns = [];
foreach ($this->getColumnList($model) as $columnName) {

try {
$column = $this->getColumn($model, $columnName);

if (!isset($this->mappings[$column->getType()->getName()])) {
if ($model->interfaces && $model->interfaces[$columnName]) {
if ($column->getNotnull()) {
$columns [ $columnName ] = $model->interfaces[ $columnName ][ 'name' ];
} else {
$columns [ $columnName . '?' ] = $model->interfaces[ $columnName ][ 'name' ];
}
} else if (!isset($this->mappings[$column->getType()->getName()])) {
throw new Exception('Unknown type found: ' . $column->getType()->getName());
} else {
if ($column->getNotnull()) {
Expand Down

0 comments on commit 741beee

Please sign in to comment.