Skip to content

Commit

Permalink
Add new mappings for Laravel 11 Fixes 71 & some minor fixes (#72)
Browse files Browse the repository at this point in the history
* Update TypescriptMappings.php

add new mappings for laravel 11

* add Complex Model

Create Complex Model with table to use in tests

* Update GetModelsTest.php

* Add test for Complex Model

Add test for Complex Model and expectations

* run pint

* fix composer i warnings

The lock file is not up to date with the latest changes in composer.json, replace nunomaduro/larastan with larastan/larastan

* rerun composer pint with new pint version

* Fix PHPStan error

Key'type' on array $interfaces always exists and is not nullable, as is set as 'unknown' on line 46
  • Loading branch information
ayrtonandino authored Apr 19, 2024
1 parent cf50033 commit dd252e6
Show file tree
Hide file tree
Showing 14 changed files with 905 additions and 741 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"orchestra/testbench": "^8.0|^9.0",
"phpunit/phpunit": "^10.0",
"laravel/pint": "^1.7",
"nunomaduro/larastan": "^2.2",
"larastan/larastan": "^2.2",
"consolidation/robo": "^4.0",
"totten/lurkerlite": "^1.3",
"doctrine/dbal": "^3.6",
Expand Down
1,458 changes: 750 additions & 708 deletions composer.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
includes:
- ./vendor/nunomaduro/larastan/extension.neon
- ./vendor/larastan/larastan/extension.neon

parameters:
paths:
Expand Down
8 changes: 3 additions & 5 deletions src/Actions/BuildModelDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ public function __invoke(SplFileInfo $modelFile, bool $resolveAbstract = false):
$columns = $columns->map(function ($column) use (&$interfaces) {
$interfaces->each(function ($interface, $key) use (&$column, &$interfaces) {
if ($key === $column['name']) {
if (isset($interface['type'])) {
$column['type'] = $interface['type'];
$column['forceType'] = true;
$column['type'] = $interface['type'];
$column['forceType'] = true;

$interfaces->forget($key);
}
$interfaces->forget($key);
}
});

Expand Down
4 changes: 2 additions & 2 deletions src/Actions/GenerateCliOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ public function __invoke(Collection $models, bool $global = false, bool $plurals
$entry .= "{$this->indent}export interface {$name}Response extends api.MetApiResponse { data: {$name}MetApiData }\n";
}

if($fillables) {
if ($fillables) {
$fillableAttributes = $reflectionModel->newInstanceWithoutConstructor()->getFillable();
$fillablesUnion = implode('|', array_map(fn($fillableAttribute) => "'$fillableAttribute'" ,$fillableAttributes));
$fillablesUnion = implode('|', array_map(fn ($fillableAttribute) => "'$fillableAttribute'", $fillableAttributes));
$entry .= "{$this->indent}export type {$name}{$fillableSuffix} = Pick<$name, $fillablesUnion>\n";
}

Expand Down
4 changes: 2 additions & 2 deletions src/Actions/RunModelShowCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function __invoke(string $model, bool $resolveAbstract = false): array
* from being intercepted by mock output handler. Resets the mock output handler after
* command execution so that mock testing is not disturbed.
*
* @param string $command Name of the command to run.
* @param array<string, mixed> $args Arguments for the command.
* @param string $command Name of the command to run.
* @param array<string, mixed> $args Arguments for the command.
* @return int $exitCode Exit code returned by the command.
*/
private function runCommandWithoutMockOutput(string $command, array $args = []): int
Expand Down
42 changes: 27 additions & 15 deletions src/Constants/TypescriptMappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,38 @@ class TypescriptMappings
* @var array<string, string>
*/
public static array $mappings = [
'array' => 'string[]',
'bigint' => 'number',
'int' => 'number',
'integer' => 'number',
'text' => 'string',
'float' => 'number',
'double' => 'number',
'string' => 'string',
'decimal' => 'number',
'datetime' => 'string',
'date' => 'string',
'timestamp' => 'string',
'bool' => 'boolean',
'boolean' => 'boolean',
'json' => 'Record<string, unknown>',
'object' => 'Record<string, unknown>',
'collection' => 'Record<string, unknown>',
'array' => 'string[]',
'point' => 'Point',
'date' => 'string',
'datetime' => 'string',
'decimal' => 'number',
'double' => 'number',
'encrypted' => 'string',
'float' => 'number',
'guid' => 'string',
'hashed' => 'string',
'encrypted' => 'string',
'integer' => 'number',
'json' => 'Record<string, unknown>',
'numeric' => 'number',
'object' => 'Record<string, unknown>',
'string' => 'string',
'text' => 'string',
'timestamp' => 'string',

// mappings for Laravel 11
'char' => 'string',
'enum' => 'string',
'int' => 'number',
'longtext' => 'string',
'mediumint' => 'number',
'mediumtext' => 'string',
'smallint' => 'number',
'tinyint' => 'boolean',
'time' => 'string',
'varchar' => 'string',
'year' => 'number',
];
}
2 changes: 1 addition & 1 deletion src/ModelInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ interfaces: $interfaces,
/**
* Get all Casts for models
*
* @param Collection $models - Collection of models
* @param Collection $models - Collection of models
*
* @throws ReflectionException
*/
Expand Down
9 changes: 5 additions & 4 deletions test/Tests/Feature/Actions/GetModelsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ public function testActionCanFindAllModelsInProject()

$foundModels = $action();

$this->assertCount(3, $foundModels);
$this->assertStringContainsString('Pivot.php', $foundModels[0]->getRelativePathname());
$this->assertStringContainsString('User.php', $foundModels[1]->getRelativePathname());
$this->assertStringContainsString('Team.php', $foundModels[2]->getRelativePathname());
$this->assertCount(4, $foundModels);
$this->assertStringContainsString('Complex.php', $foundModels[0]->getRelativePathname());
$this->assertStringContainsString('Pivot.php', $foundModels[1]->getRelativePathname());
$this->assertStringContainsString('User.php', $foundModels[2]->getRelativePathname());
$this->assertStringContainsString('Team.php', $foundModels[3]->getRelativePathname());
}
}
18 changes: 17 additions & 1 deletion test/Tests/Feature/Console/ModelTyperCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Tests\Feature\Console;

use App\Models\Complex;
use App\Models\User;
use FumeApp\ModelTyper\Commands\ModelTyperCommand;
use Tests\Feature\TestCase;
Expand Down Expand Up @@ -43,15 +44,30 @@ public function testCommandGeneratesExpectedOutputForUserModel()
$this->artisan(ModelTyperCommand::class, ['--model' => User::class])->expectsOutput($expected);
}

/** @test */
public function testCommandGeneratesFillablesWhenFillableOptionIsEnabled()
{
$expected = $this->getExpectedContent('user-fillables.ts');
$options = [
'--model' => User::class,
'--fillables' => true,
'--fillable-suffix' => 'Editable'
'--fillable-suffix' => 'Editable',
];

$this->artisan(ModelTyperCommand::class, $options)->expectsOutput($expected);
}

/** @test */
public function testCommandGeneratesExpectedOutputForComplexModel()
{
// Migrate database
$this->artisan('migrate:fresh')->assertSuccessful();

// assert table complex_model_table exists
$this->assertDatabaseEmpty('complex_model_table');

// check if Complex::class generates expected interface
$expected = $this->getExpectedContent('complex-model.ts');
$this->artisan(ModelTyperCommand::class, ['--model' => Complex::class])->expectsOutput($expected);
}
}
33 changes: 33 additions & 0 deletions test/input/expectations/complex-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export interface Complex {
// columns
id: number
big_integer: number
binary: unknown
boolean: boolean
char: string
date_time: string
date: string
decimal: number
double: number
enum: string
float: number
integer: number
ip_address: string
json: Record<string, unknown>
jsonb: Record<string, unknown>
long_text: string
mac_address: string
medium_integer: number
medium_text: string
small_integer: number
string: string
text: string
time: string
timestamp: string
year: number
uuid: string
ulid: string
created_at: string|null
updated_at: string|null
deleted_at: string|null
}
16 changes: 16 additions & 0 deletions test/laravel-skeleton/app/Models/Complex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Complex extends Model
{
protected $table = 'complex_model_table';

protected $casts = [
'json' => 'json',
'jsonb' => 'json',
'year' => 'int',
];
}
2 changes: 1 addition & 1 deletion test/laravel-skeleton/app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class User extends Model
{
protected $fillable = [
'role_traditional',
'role_new'
'role_new',
];

protected $casts = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('complex_model_table', function (Blueprint $table) {
$table->id();
$table->bigInteger('bigInteger');
$table->binary('binary');
$table->boolean('boolean');
$table->char('char');
$table->dateTime('dateTime');
$table->date('date');
$table->decimal('decimal');
$table->double('double');
$table->enum('enum', [1, 2, 3, 'A', 'B']);
$table->float('float');
$table->integer('integer');
$table->ipAddress('ipAddress');
$table->json('json');
$table->jsonb('jsonb');
$table->longText('longText');
$table->macAddress('macAddress');
$table->mediumInteger('mediumInteger');
$table->mediumText('mediumText');
$table->smallInteger('smallInteger');
$table->string('string');
$table->text('text');
$table->time('time');
$table->timestamp('timestamp');
$table->year('year');
$table->uuid('uuid');
$table->ulid('ulid');
$table->timestamps();
$table->softDeletes();
});
}
};

0 comments on commit dd252e6

Please sign in to comment.