Skip to content

Commit 0c461b2

Browse files
committed
Fix bug where mapped relations wouldn't persist parent config. Add support for controlling relation mapping
1 parent ec8e52c commit 0c461b2

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

src/Commands/TypeScriptifyModelCommand.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class TypeScriptifyModelCommand extends Command {
1414
*/
1515
protected $signature = 'typescriptify:model
1616
{model : The fully qualified class name for the model - e.g. App\Models\User}
17-
{--includeHidden : Include the protected $hidden properties}';
17+
{--includeHidden : Include the protected $hidden properties}
18+
{--includeRelations=true : Map foreign key columns to interface definitions}';
1819

1920
/**
2021
* The console command description.
@@ -23,14 +24,26 @@ class TypeScriptifyModelCommand extends Command {
2324
*/
2425
protected $description = 'Convert a model to it\'s TypeScript definition.';
2526

27+
/**
28+
* Cast the `$name` option to a boolean.
29+
*
30+
* @param string $name
31+
*
32+
* @return bool
33+
*/
34+
private function boolOption(string $name): bool {
35+
return filter_var($this->option($name), FILTER_VALIDATE_BOOLEAN);
36+
}
37+
2638
/**
2739
* Execute the console command.
2840
*
2941
* @return int
3042
*/
3143
public function handle() {
3244
echo (new TypeScriptifyModel($this->argument('model')))
33-
->includeHidden($this->option('includeHidden'))
45+
->includeHidden($this->boolOption('includeHidden'))
46+
->includeRelations($this->boolOption('includeRelations'))
3447
->generate();
3548

3649
return Command::SUCCESS;

src/TypeScriptifyModel.php

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ final class TypeScriptifyModel {
4545
/**
4646
* Whether to include the model's $hidden properties.
4747
*
48-
* @var bool $includeHidden
48+
* @var bool
4949
*/
5050
private bool $includeHidden = false;
5151

52+
/**
53+
* Whether to map the model's foreign keys to interfaces.
54+
*
55+
* @var bool
56+
*/
57+
private bool $includeRelations = true;
58+
5259
/**
5360
* @param string $fullyQualifiedModelName The fully qualified model class name.
5461
* @param ?array<string,string> $convertedModelsMap The map of `fully qualified model name => interface name` definitions this class can use instead of generating its own definitions.
@@ -282,7 +289,7 @@ private function convertForeignKeyToFullyQualifiedModelName(string $attribute):
282289
* @return string
283290
*/
284291
private function getTypeScriptType(stdClass $columnSchema): string {
285-
if ($this->isAttributeRelation($columnSchema->Field)) {
292+
if ($this->includeRelations && $this->isAttributeRelation($columnSchema->Field)) {
286293
$fullyQualifiedRelatedModelName = $this->convertForeignKeyToFullyQualifiedModelName($columnSchema->Field);
287294

288295
if (array_key_exists($fullyQualifiedRelatedModelName, $this->convertedModelsMap)) {
@@ -296,7 +303,10 @@ private function getTypeScriptType(stdClass $columnSchema): string {
296303
// as many interface definitions for relational attributes as we need.
297304
// We pass our existing convertedModelsMap instance here to prevent this class
298305
// mapping models we've already mapped in this current class instance.
299-
$mappedType = (new self($fullyQualifiedRelatedModelName, $this->convertedModelsMap))->generate();
306+
$mappedType = (new self($fullyQualifiedRelatedModelName, $this->convertedModelsMap))
307+
->includeHidden($this->includeHidden)
308+
->includeRelations($this->includeRelations)
309+
->generate();
300310
}
301311
} else {
302312
// If the attribute is natively casted, we'll want to perform native cast checking
@@ -339,6 +349,19 @@ public function includeHidden(bool $includeHidden): self {
339349
return $this;
340350
}
341351

352+
/**
353+
* Set whether we should map the model's foreign keys to interfaces.
354+
*
355+
* @param bool $includeRelations
356+
*
357+
* @return self
358+
*/
359+
public function includeRelations(bool $includeRelations): self {
360+
$this->includeRelations = $includeRelations;
361+
362+
return $this;
363+
}
364+
342365
/**
343366
* Generate the TypeScript interface.
344367
*
@@ -363,7 +386,7 @@ public function generate(): string {
363386
// If this attribute is hidden and we're not including hidden, we'll skip it.
364387
if (!$this->includeHidden && $this->isAttributeHidden($columnSchema->Field)) return;
365388

366-
if ($this->isAttributeRelation($columnSchema->Field)) {
389+
if ($this->includeRelations && $this->isAttributeRelation($columnSchema->Field)) {
367390
$relationName = $this->convertForeignKeyToPredictedRelationName($columnSchema->Field);
368391
$generatedTypeScriptType = Str::of($this->getTypeScriptType($columnSchema));
369392

@@ -373,7 +396,7 @@ public function generate(): string {
373396
$isRelationInterfaceDefinition = $generatedTypeScriptType->startsWith('interface ');
374397

375398
if ($isRelationInterfaceDefinition) {
376-
// interface User { => User
399+
// `interface User {` => `User`
377400
$generatedInterfaceName = $generatedTypeScriptType
378401
->after('interface ')
379402
->before(' {');

0 commit comments

Comments
 (0)