From 04489e2f8f4cfabb5989cc8926eef4d31b843555 Mon Sep 17 00:00:00 2001 From: Lorenzo Dal'Aqua Date: Fri, 19 Jun 2026 14:53:31 -0300 Subject: [PATCH 1/2] fix: remove Str::singular() from relation type name references The inflector was applied to PHP class names before using them as TypeScript type references in both singular and plural relations. This was breaking plural model names like OpeningHours, producing a type reference that never matched the emitted interface name, which always uses the exact class name. Removing Str::singular() makes the reference consistent with what is actually emitted. --- src/Actions/WriteRelationship.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Actions/WriteRelationship.php b/src/Actions/WriteRelationship.php index dbe9e95..d6a54f0 100644 --- a/src/Actions/WriteRelationship.php +++ b/src/Actions/WriteRelationship.php @@ -32,8 +32,8 @@ public function __invoke(array $relation, string $indent = '', bool $jsonOutput $relatedModel = $this->getClassName($relation['related']); $relationType = match ($relation['type']) { - 'BelongsToMany', 'HasMany', 'HasManyThrough', 'MorphToMany', 'MorphMany', 'MorphedByMany' => $plurals === true ? Str::plural($relatedModel) : (Str::singular($relatedModel) . '[]'), - 'BelongsTo', 'HasOne', 'HasOneThrough', 'MorphOne', 'MorphTo' => Str::singular($relatedModel), + 'BelongsToMany', 'HasMany', 'HasManyThrough', 'MorphToMany', 'MorphMany', 'MorphedByMany' => $plurals === true ? Str::plural($relatedModel) : ($relatedModel . '[]'), + 'BelongsTo', 'HasOne', 'HasOneThrough', 'MorphOne', 'MorphTo' => $relatedModel, default => $relatedModel, }; } From c82107a3bd55f2aabbf5e1d5707aba3f1391a008 Mon Sep 17 00:00:00 2001 From: Lorenzo Dal'Aqua Date: Fri, 19 Jun 2026 16:03:10 -0300 Subject: [PATCH 2/2] test: verify Str::singular() is not applied to relation class names --- .../Feature/Actions/WriteRelationshipTest.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/Tests/Feature/Actions/WriteRelationshipTest.php b/test/Tests/Feature/Actions/WriteRelationshipTest.php index 50f702f..befde2e 100644 --- a/test/Tests/Feature/Actions/WriteRelationshipTest.php +++ b/test/Tests/Feature/Actions/WriteRelationshipTest.php @@ -176,6 +176,33 @@ public function test_action_can_return_nullable_plural_relationships() $this->assertStringContainsString('tags: Tag[] | null', $result); } + public function test_plural_class_name_is_not_singularized_in_array_relation(): void + { + $relation = [ + 'name' => 'customer_tests', + 'type' => 'HasMany', + 'related' => 'App\Models\CustomerTests', + ]; + + $result = app(WriteRelationship::class)($relation); + + $this->assertStringContainsString('customer_tests: CustomerTests[]', $result); + $this->assertStringNotContainsString('CustomerTest[]', $result); + } + + public function test_plural_class_name_is_not_singularized_in_singular_relation(): void + { + $relation = [ + 'name' => 'primary_address', + 'type' => 'BelongsTo', + 'related' => 'App\Models\UserAddresses', + ]; + + $result = app(WriteRelationship::class)($relation); + + $this->assertStringContainsString('primary_address: UserAddresses', $result); + } + public function test_action_can_return_morph_to_union_type_relationships() { $morphToRelation = [