Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ewilan-riviere committed Jul 23, 2024
1 parent 5fc7227 commit d7f3700
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 62 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,15 @@ With options:
- --`R`|`routes-path`: Path to routes directory.
- --`O`|`output-path`: Path to output.

## More
## Advanced

### MongoDB

`kiwilan/typescriptable-laravel` supports [MongoDB](https://github.com/mongodb/laravel-mongodb) with `mongodb/laravel-mongodb`. Due to the MongoDB structure, Typescript conversion aren't the same as SQL databases, precision is lower. If you want to improve it, you can add [an issue](https://github.com/kiwilan/typescriptable-laravel/issues/new/choose).

Database isn't parsed like with relational databases. The package will parse `key`, `fillable` and `hidden` to get all fields. If some fields are missing, you can [override them manually](https://github.com/kiwilan/typescriptable-laravel#override-models). All relations and accessors are supported.

### Troubleshooting

#### Database prefix
### Database prefix

You can use `prefix` variable into `config/database.php` file.

Expand All @@ -236,7 +234,7 @@ You can use `prefix` variable into `config/database.php` file.
],
```

#### Override models
### Override models

`kiwilan/typescriptable-laravel` will cover many cases, but if you want to override some models, you can just create a type like `resources/js/types/index.ts` and extends `Model` type.

Expand Down
241 changes: 184 additions & 57 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,87 +7,195 @@ An example of Eloquent model.
```php
<?php

namespace App\Models;

use Kiwilan\Steward\Enums\PublishStatusEnum;

class Story extends Model
namespace Kiwilan\Typescriptable\Tests\Data\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Kiwilan\Typescriptable\Tests\Data\Enums\PublishStatusEnum;
use Kiwilan\Typescriptable\Tests\Data\Models\Nested\Author;
use Spatie\Image\Enums\Fit;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class Movie extends Model implements \Spatie\MediaLibrary\HasMedia
{
use HasFactory;
use HasUlids;
use InteractsWithMedia;

protected $fillable = [
'title',
'slug',
'abstract',
'original_link',
'picture',
'year',
'subtitles',
'french_title',
'original_title',
'release_date',
'original_language',
'overview',
'popularity',
'is_adult',
'tagline',
'homepage',
'status',
'published_at',
'meta_title',
'meta_description',
'certification',
'tmdb_url',
'poster',
'poster_tmdb',
'poster_color',
'backdrop',
'backdrop_tmdb',
'added_at',
'fetched_at',
'fetched_has_failed',
'slug',
'revenue',
'edition',
'version',
'library',
'is_multilingual',
];

protected $appends = [
'time_to_read',
protected $casts = [
'subtitles' => 'array',
'budget' => PublishStatusEnum::class,
'homepage' => PublishStatusEnum::class,
'revenue' => 'integer',
'is_multilingual' => 'boolean',
'added_at' => 'datetime:Y-m-d',
];

protected $withCount = [
'chapters',
protected $appends = [
'show_route',
'api_route',
];

protected $casts = [
'status' => PublishStatusEnum::class,
'published_at' => 'datetime:Y-m-d',
protected $hidden = [
'budget',
'edition',
];

public function getTimeToReadAttribute(): int
public function registerMediaConversions(?Media $media = null): void
{
$this
->addMediaConversion('preview')
->fit(Fit::Contain, 300, 300)
->nonQueued();
}

public function chapters(): HasMany
public function getShowRouteAttribute(): string
{
return 'movies.show';
}

public function category(): BelongsTo
/**
* @return string
*/
protected function apiRoute(): Attribute
{
return Attribute::make(
get: fn (?string $value) => ucfirst($value),
);
}

public function author(): BelongsTo
public function similars(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
{
return $this->belongsToMany(Movie::class, 'similars', 'movie_id', 'similar_id');
}

public function recommendations(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
{
return $this->belongsToMany(Movie::class, 'recommendations', 'movie_id', 'recommendation_id');
}

public function tags(): BelongsToMany
public function members(): \Illuminate\Database\Eloquent\Relations\MorphToMany
{
return $this
->morphToMany(Member::class, 'memberable')
->withPivot([
'character',
'job',
'department',
'order',
'is_adult',
'known_for_department',
'is_crew',
])
->orderBy('order');
}

public function author(): BelongsTo
{
return $this->belongsTo(Author::class, 'author_id');
}
}
```

TS file generated at `resources/js/types-eloquent.d.ts`

```typescript
declare namespace App {
declare namespace Models {
export type Story = {
id: number;
title: string;
slug?: string;
abstract?: string;
original_link?: string;
picture?: string;
status: "draft" | "scheduled" | "published";
published_at?: Date;
meta_title?: string;
meta_description?: string;
created_at?: Date;
updated_at?: Date;
author_id?: number;
category_id?: number;
time_to_read?: number;
chapters?: Chapter[];
category?: Category;
author?: Author;
tags?: Tag[];
chapters_count?: number;
tags_count?: number;
};
```ts
declare namespace App.Models {
export interface Movie {
id: string;
tmdb_id?: number;
title?: string;
year?: number;
subtitles: any[];
slug: string;
french_title?: string;
original_title?: string;
release_date?: string;
original_language?: string;
overview?: string;
popularity?: number;
is_adult?: number;
homepage?: "draft" | "scheduled" | "published";
tagline?: string;
status?: string;
certification?: string;
tmdb_url?: string;
imdb_id?: string;
runtime?: number;
budget: "draft" | "scheduled" | "published";
revenue?: number;
edition?: string;
version?: string;
library?: string;
is_multilingual: boolean;
poster?: string;
poster_tmdb?: string;
poster_color?: string;
backdrop?: string;
backdrop_tmdb?: string;
author_id?: number;
added_at?: string;
fetched_at?: string;
fetched_has_failed: number;
created_at?: string;
updated_at?: string;
show_route?: string;
api_route?: string;
similars_count?: number;
recommendations_count?: number;
members_count?: number;
media_count?: number;
similars?: App.Models.Movie[];
recommendations?: App.Models.Movie[];
members?: App.Models.Member[];
author?: App.Models.NestedAuthor;
media?: any[];
}
// With `paginate` option.
export type PaginateLink = {
}

declare namespace App {
export interface PaginateLink {
url: string;
label: string;
active: boolean;
};
export type Paginate<T = any> = {
}
export interface Paginate<T = any> {
data: T[];
current_page: number;
first_page_url: string;
Expand All @@ -101,7 +209,26 @@ declare namespace App {
prev_page_url: string;
to: number;
total: number;
};
}
export interface ApiPaginate<T = any> {
data: T[];
links: {
first?: string;
last?: string;
prev?: string;
next?: string;
};
meta: {
current_page: number;
from: number;
last_page: number;
links: App.PaginateLink[];
path: string;
per_page: number;
to: number;
total: number;
};
}
}
```

Expand All @@ -112,7 +239,7 @@ Usage in Vue component.
```vue
<script lang="ts" setup>
defineProps<{
story?: App.Models.Story;
movie?: App.Models.Movie;
}>();
</script>
```
Expand All @@ -122,7 +249,7 @@ Or with paginate option.
```vue
<script lang="ts" setup>
defineProps<{
stories?: App.Paginate<App.Models.Story>;
movies?: App.Paginate<App.Models.Movie>;
}>();
</script>
```
25 changes: 25 additions & 0 deletions tests/EloquentTypeArtisanMysqlTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use Kiwilan\Typescriptable\Tests\TestCase;
use Kiwilan\Typescriptable\Typed\Eloquent\EloquentConfig;
use Kiwilan\Typescriptable\Typed\EloquentType;
use Kiwilan\Typescriptable\TypescriptableConfig;

beforeEach(function () {
deleteFile(outputDir('types-eloquent.d.ts'));
});

it('can be run with artisan', function () {
TestCase::setupDatabase('mysql');

$type = EloquentType::make(new EloquentConfig(
modelsPath: models(),
outputPath: outputDir(),
phpPath: outputDir().'/php',
useParser: false,
skipModels: ['Kiwilan\\Typescriptable\\Tests\\Data\\Models\\SushiTest'],
))->execute();

$eloquent = outputDir(TypescriptableConfig::eloquentFilename());
expect($eloquent)->toBeFile();
});
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit d7f3700

Please sign in to comment.