Skip to content

Commit

Permalink
updated docs & made timestamps strings by default
Browse files Browse the repository at this point in the history
  • Loading branch information
nurdism committed Mar 7, 2023
1 parent 8a821fc commit 3eb2dec
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 80 deletions.
126 changes: 72 additions & 54 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,35 @@ will output

```ts
export interface User {
// columns
id: number;
email: string;
name: string;
created_at?: Date;
updated_at?: Date;
// mutators
first_name: string;
initials: string;
// relations
teams: Teams;
// columns
id: number
email: string
name: string
created_at?: Date
updated_at?: Date
// mutators
first_name: string
initials: string
// relations
teams: Teams
}
export type Users = Array<User>;
export type Users = Array<User>

export interface Team {
// columns
id: number;
name: string;
logo: string;
created_at?: Date;
updated_at?: Date;
// mutators
initials: string;
slug: string;
url: string;
// relations
users: Users;
// columns
id: number
name: string
logo: string
created_at?: Date
updated_at?: Date
// mutators
initials: string
slug: string
url: string
// relations
users: Users
}
export type Teams = Array<Team>;
export type Teams = Array<Team>
```
### What does this do?
Expand All @@ -61,11 +61,11 @@ Starting support is for Laravel v9.21+ and PHP v8.1+
> **Note**
> This package may require you to install Doctrine DBAL. If so you can run
```bash
composer require doctrine/dbal
```

1. You must have a [return type](https://www.php.net/manual/en/language.types.declarations.php) for your model relationships
```php
Expand All @@ -84,6 +84,16 @@ public function getFirstNameAttribute(): string // <- this
}
```
### Additional Options
```
--no-relations : Do not include relations
--optional-relations : Make relations optional fields on the model type
--no-hidden : Do not include hidden model attributes
--timestamps-date : Output timestamps as a Date object type
--optional-nullables : Output nullable attributes as optional fields
```
### Custom Interfaces
If you have custom interfaces you are using for your models you can specify them in a reserved `interfaces` array
Expand All @@ -102,11 +112,11 @@ public array $interfaces = [
And it should generate:

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

export interface Location {
// columns
coordinate: Point;
// columns
coordinate: Point
}
```

Expand Down Expand Up @@ -138,8 +148,8 @@ And it should generate:

```ts
export interface Location {
// columns
choices: "good" | "bad";
// columns
choices: 'good' | 'bad'
}
```

Expand All @@ -159,10 +169,10 @@ This will generate:

```ts
export interface Location {
// ...
// overrides
state: "found" | "not_found" | "searching" | "reset";
// ...
// ...
// overrides
state: 'found' | 'not_found' | 'searching' | 'reset'
// ...
}
```

Expand Down Expand Up @@ -192,13 +202,14 @@ declare global {
```bash
artisan model:typer --plurals
```
Exports for example, when a `User` model exists:
```ts
export type Users = User[]
```
### Output Api.MetApi* resources
### Output Api.MetApi\* resources
```bash
artisan model:typer --api-resources
Expand All @@ -207,10 +218,18 @@ artisan model:typer --api-resources
Exports:
```ts
export interface UserResults extends api.MetApiResults { data: Users }
export interface UserResult extends api.MetApiResults { data: User }
export interface UserMetApiData extends api.MetApiData { data: User }
export interface UserResponse extends api.MetApiResponse { data: UserMetApiData }
export interface UserResults extends api.MetApiResults {
data: Users
}
export interface UserResult extends api.MetApiResults {
data: User
}
export interface UserMetApiData extends api.MetApiData {
data: User
}
export interface UserResponse extends api.MetApiResponse {
data: UserMetApiData
}
```
### Enable all output options
Expand Down Expand Up @@ -248,16 +267,16 @@ This will generate something like:
```ts
export interface User {
// columns
id: number;
email: string;
name?: string;
created_at?: Date;
updated_at?: Date;
// mutators
is_captain: boolean;
// relations
teams: TeamUsers;
// columns
id: number
email: string
name?: string
created_at?: Date
updated_at?: Date
// mutators
is_captain: boolean
// relations
teams: TeamUsers
}
```
Expand Down Expand Up @@ -292,10 +311,9 @@ namespace App\Enums;
* @property ADMIN - Can do anything
* @property USER - Standard read-only
*/
enum UserRoleEnum: string
{
case ADMIN = 'admin';
case USER = 'user';
enum UserRoleEnum: string {
case ADMIN = 'admin';
case USER = 'user';
}
```
Expand Down
16 changes: 8 additions & 8 deletions src/Actions/GenerateCliOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class GenerateCliOutput
*
* @param Collection<int, SplFileInfo> $models
*/
public function __invoke(Collection $models, bool $global = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampStrings = false, bool $optionalNullables = false): string
public function __invoke(Collection $models, bool $global = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false): string
{
$modelBuilder = app(BuildModelDetails::class);
$colAttrWriter = app(WriteColumnAttribute::class);
Expand All @@ -38,7 +38,7 @@ public function __invoke(Collection $models, bool $global = false, bool $plurals
$this->indent = ' ';
}

$models->each(function (SplFileInfo $model) use ($modelBuilder, $colAttrWriter, $relationWriter, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampStrings, $optionalNullables) {
$models->each(function (SplFileInfo $model) use ($modelBuilder, $colAttrWriter, $relationWriter, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampsDate, $optionalNullables) {
$entry = '';

[
Expand All @@ -57,8 +57,8 @@ public function __invoke(Collection $models, bool $global = false, bool $plurals

if ($columns->isNotEmpty()) {
$entry .= "{$this->indent} // columns\n";
$columns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $timestampStrings, $optionalNullables) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, indent: $this->indent, noHidden: $noHidden, timestampStrings: $timestampStrings, optionalNullables: $optionalNullables);
$columns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $timestampsDate, $optionalNullables) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, indent: $this->indent, noHidden: $noHidden, timestampsDate: $timestampsDate, optionalNullables: $optionalNullables);
if (!empty($line)) {
$entry .= $line;
if ($enum) {
Expand All @@ -70,8 +70,8 @@ public function __invoke(Collection $models, bool $global = false, bool $plurals

if ($nonColumns->isNotEmpty()) {
$entry .= "{$this->indent} // mutators\n";
$nonColumns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $timestampStrings, $optionalNullables) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, indent: $this->indent, noHidden: $noHidden, timestampStrings: $timestampStrings, optionalNullables: $optionalNullables);
$nonColumns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $timestampsDate, $optionalNullables) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, indent: $this->indent, noHidden: $noHidden, timestampsDate: $timestampsDate, optionalNullables: $optionalNullables);
if (!empty($line)) {
$entry .= $line;
if ($enum) {
Expand All @@ -83,8 +83,8 @@ public function __invoke(Collection $models, bool $global = false, bool $plurals

if ($interfaces->isNotEmpty()) {
$entry .= "{$this->indent} // overrides\n";
$interfaces->each(function ($interface) use (&$entry, $reflectionModel, $colAttrWriter, $timestampStrings) {
[$line] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $interface, indent: $this->indent, timestampStrings: $timestampStrings);
$interfaces->each(function ($interface) use (&$entry, $reflectionModel, $colAttrWriter, $timestampsDate) {
[$line] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $interface, indent: $this->indent, timestampsDate: $timestampsDate);
$entry .= $line;
});
}
Expand Down
8 changes: 4 additions & 4 deletions src/Actions/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ class Generator
*
* @return string
*/
public function __invoke(?string $specificModel = null, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampStrings = false, bool $optionalNullables = false)
public function __invoke(?string $specificModel = null, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false)
{
$models = $this->getModels($specificModel);

return $this->display($models, $global, $json, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampStrings, $optionalNullables);
return $this->display($models, $global, $json, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampsDate, $optionalNullables);
}

/**
Expand All @@ -41,7 +41,7 @@ protected function getModels(?string $model = null): Collection
*
* @param Collection<int, SplFileInfo> $models
*/
protected function display(Collection $models, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampStrings = false, bool $optionalNullables = false): string
protected function display(Collection $models, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false): string
{
if ($models->isEmpty()) {
return 'ERROR: No models found.';
Expand All @@ -51,6 +51,6 @@ protected function display(Collection $models, bool $global = false, bool $json
return app(GenerateJsonOutput::class)($models);
}

return app(GenerateCliOutput::class)($models, $global, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampStrings, $optionalNullables);
return app(GenerateCliOutput::class)($models, $global, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $timestampsDate, $optionalNullables);
}
}
8 changes: 4 additions & 4 deletions src/Actions/MapReturnType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class MapReturnType
* @param string $returnType
* @return string
*/
public function __invoke(string $returnType, bool $timestampStrings = false): string
public function __invoke(string $returnType, bool $timestampsDate = false): string
{
$mappings = TypescriptMappings::$mappings;
if ($timestampStrings) {
$mappings['datetime'] = 'string';
$mappings['date'] = 'string';
if ($timestampsDate) {
$mappings['datetime'] = 'Date';
$mappings['date'] = 'Date';
}

$returnType = explode(' ', $returnType)[0];
Expand Down
10 changes: 5 additions & 5 deletions src/Actions/WriteColumnAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class WriteColumnAttribute
* @param bool $jsonOutput
* @return array
*/
public function __invoke(ReflectionClass $reflectionModel, array $attribute, string $indent = '', bool $jsonOutput = false, bool $noHidden = false, bool $timestampStrings = false, bool $optionalNullables = false): array
public function __invoke(ReflectionClass $reflectionModel, array $attribute, string $indent = '', bool $jsonOutput = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false): array
{
$enumRef = null;
$returnType = app(MapReturnType::class);
Expand All @@ -39,7 +39,7 @@ public function __invoke(ReflectionClass $reflectionModel, array $attribute, str
} else {
if (! is_null($attribute['cast']) && $attribute['cast'] !== $attribute['type']) {
if (isset(TypescriptMappings::$mappings[$attribute['cast']])) {
$type = $returnType($attribute['cast'], $timestampStrings);
$type = $returnType($attribute['cast'], $timestampsDate);
} else {
if ($attribute['type'] === 'json' || $this->getClassName($attribute['cast']) === 'AsCollection' || $this->getClassName($attribute['cast']) === 'AsArrayObject') {
$type = $returnType('json');
Expand All @@ -54,7 +54,7 @@ public function __invoke(ReflectionClass $reflectionModel, array $attribute, str
if (! is_null($closure->get)) {
$rf = new ReflectionFunction($closure->get);
if ($rf->hasReturnType()) {
$type = $returnType($rf->getReturnType()->getName(), $timestampStrings);
$type = $returnType($rf->getReturnType()->getName(), $timestampsDate);
}
}
} else {
Expand All @@ -72,7 +72,7 @@ public function __invoke(ReflectionClass $reflectionModel, array $attribute, str
$cleanStr = Str::of($attribute['cast'])->before(':')->__toString();

if (isset(TypescriptMappings::$mappings[$cleanStr])) {
$type = $returnType($cleanStr, $timestampStrings);
$type = $returnType($cleanStr, $timestampsDate);
} else {
dump('Unknown cast type: ' . $attribute['cast']);
}
Expand All @@ -81,7 +81,7 @@ public function __invoke(ReflectionClass $reflectionModel, array $attribute, str
}
}
} else {
$type = $returnType($attribute['type'], $timestampStrings);
$type = $returnType($attribute['type'], $timestampsDate);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Commands/ModelTyperCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class ModelTyperCommand extends Command
{--json : Output the result as json}
{--plurals : Output model plurals}
{--no-relations : Do not include relations}
{--optional-relations : Make relations optional types}
{--optional-relations : Make relations optional fields on the model type}
{--no-hidden : Do not include hidden model attributes}
{--timestamp-strings : Output timestamps as strings}
{--timestamps-date : Output timestamps as a Date object type}
{--optional-nullables : Output nullable attributes as optional fields}
{--api-resources : Output api.MetApi interfaces}
{--all : Enable all output options (equivalent to --plurals --api-resources)}';
Expand Down Expand Up @@ -66,7 +66,7 @@ public function handle(Generator $generator): int
$plurals = $this->option('plurals') || $this->option('all');
$apiResources = $this->option('api-resources') || $this->option('all');

echo $generator($this->option('model'), $this->option('global'), $this->option('json'), $plurals, $apiResources, $this->option('optional-relations'), $this->option('no-relations'), $this->option('no-hidden'), $this->option('timestamp-strings'), $this->option('optional-nullables'));
echo $generator($this->option('model'), $this->option('global'), $this->option('json'), $plurals, $apiResources, $this->option('optional-relations'), $this->option('no-relations'), $this->option('no-hidden'), $this->option('timestamps-date'), $this->option('optional-nullables'));

return Command::SUCCESS;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Constants/TypescriptMappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class TypescriptMappings
'float' => 'number',
'string' => 'string',
'decimal' => 'number',
'datetime' => 'Date',
'date' => 'Date',
'datetime' => 'string',
'date' => 'string',
'bool' => 'boolean',
'boolean' => 'boolean',
'json' => 'Record<string, unknown>',
Expand Down

0 comments on commit 3eb2dec

Please sign in to comment.