diff --git a/composer.json b/composer.json index ceadaa31..e8dbc7bb 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,6 @@ "illuminate/http": ">=5.7", "illuminate/pagination": ">=5.7", "illuminate/support": ">=5.7", - "laravel/legacy-factories": "^1.3", "symfony/yaml": "^5.3|^6.0" }, "require-dev": { diff --git a/src/Concerns/ExtendsResources.php b/src/Concerns/ExtendsResources.php index 06a5e193..2e60a818 100644 --- a/src/Concerns/ExtendsResources.php +++ b/src/Concerns/ExtendsResources.php @@ -4,28 +4,9 @@ namespace Orion\Concerns; use Illuminate\Http\Request; -use Illuminate\Http\Resources\MergeValue; trait ExtendsResources { - public static $mergeAll = false; - - /** - * Override when to force merge when mergeAll is enabled - */ - protected function when($condition, $value, $default = null) - { - return static::$mergeAll ? value($value) : parent::when($condition, $value, $default); - } - - /** - * Override mergeWhen to force merge when mergeAll is enabled - */ - protected function mergeWhen($condition, $value) - { - return static::$mergeAll ? new MergeValue(value($value)) : parent::mergeWhen($condition, $value); - } - /** * Merges transformed resource with the given data. * diff --git a/src/Specs/Builders/Components/Model/BaseModelComponentBuilder.php b/src/Specs/Builders/Components/Model/BaseModelComponentBuilder.php index 5a7fc318..1e4de572 100644 --- a/src/Specs/Builders/Components/Model/BaseModelComponentBuilder.php +++ b/src/Specs/Builders/Components/Model/BaseModelComponentBuilder.php @@ -8,7 +8,6 @@ use Doctrine\DBAL\Schema\Column; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; -use Orion\Http\Resources\Resource; use Orion\Specs\Builders\Components\ModelComponentBuilder; use Orion\ValueObjects\Specs\Component; @@ -21,7 +20,7 @@ class BaseModelComponentBuilder extends ModelComponentBuilder * @return Component * @throws Exception */ - public function build(Model $resourceModel, Resource $resourceResource): Component + public function build(Model $resourceModel): Component { $component = new Component(); $component->title = class_basename($resourceModel); @@ -48,18 +47,21 @@ protected function getPropertiesFromSchema(Model $resourceModel, array $excluded $columns = $this->schemaManager->getSchemaColumns($resourceModel); return collect($columns) - ->filter(function (Column $column) use ($excludedColumns) { - return !in_array($column->getName(), $excludedColumns, true); - }) - ->filter(function (Column $column) use ($resourceModel) { - return $resourceModel->isFillable($column->getName()); - }) - ->map(function (Column $column) use ($resourceModel) { - $propertyClass = $this->schemaManager->resolveSchemaPropertyClass($column, $resourceModel); + ->filter( + function (Column $column) use ($excludedColumns) { + return !in_array($column->getName(), $excludedColumns, true); + } + )->filter( + function (Column $column) use ($resourceModel) { + return $resourceModel->isFillable($column->getName()); + } + )->map( + function (Column $column) use ($resourceModel) { + $propertyClass = $this->schemaManager->resolveSchemaPropertyClass($column, $resourceModel); - return $this->propertyBuilder->build($column, $propertyClass); - }) - ->values() + return $this->propertyBuilder->build($column, $propertyClass); + } + )->values() ->keyBy('name') ->toArray(); } diff --git a/src/Specs/Builders/Components/Model/ModelResourceComponentBuilder.php b/src/Specs/Builders/Components/Model/ModelResourceComponentBuilder.php index 315963ed..d96fbedb 100644 --- a/src/Specs/Builders/Components/Model/ModelResourceComponentBuilder.php +++ b/src/Specs/Builders/Components/Model/ModelResourceComponentBuilder.php @@ -7,8 +7,6 @@ use Doctrine\DBAL\Exception; use Doctrine\DBAL\Schema\Column; use Illuminate\Database\Eloquent\Model; -use Illuminate\Http\Resources\MergeValue; -use Orion\Http\Resources\Resource; use Orion\Specs\Builders\Components\ModelComponentBuilder; use Orion\ValueObjects\Specs\ModelResourceComponent; @@ -16,72 +14,50 @@ class ModelResourceComponentBuilder extends ModelComponentBuilder { /** * @param Model $resourceModel - * @param Resource $resourceResource * @return ModelResourceComponent * @throws Exception */ - public function build(Model $resourceModel, Resource $resourceResource): ModelResourceComponent + public function build(Model $resourceModel): ModelResourceComponent { + $resourceComponentBaseName = class_basename($resourceModel); + $component = new ModelResourceComponent(); - $component->title = class_basename($resourceResource); + $component->title = "{$resourceComponentBaseName}Resource"; $component->type = 'object'; - - $resourceProperties = $this->getPropertiesFromResource($resourceResource); - $includedProperties = array_keys($resourceProperties); - - $component->properties = array_merge( - $resourceProperties, - $this->getPropertiesFromSchema($resourceModel, $includedProperties) - ); + $component->properties = [ + 'allOf' => [ + ['$ref' => "#/components/schemas/{$resourceComponentBaseName}"], + [ + 'type' => 'object', + 'properties' => $this->getPropertiesFromSchema($resourceModel) + ], + ], + ]; return $component; } - /** - * @param Resource $resourceResource - * @return array - * @throws Exception - */ - protected function getPropertiesFromResource(Resource $resourceResource): array - { - $properties = $this->resourceManager->getResourceProperties($resourceResource); - - return collect($properties) - ->mapWithKeys(function ($value, $property) { - return is_a($value, MergeValue::class) ? $value->data : [$property => $value]; - }) - ->filter(function ($value, $property) { - return is_string($property); - }) - ->map(function ($value, $property) { - $propertyClass = $this->resourceManager->resolveResourcePropertyClass($property, $value); - - return $this->propertyBuilder->buildFromResource($property, true, $propertyClass); - }) - ->values() - ->keyBy('name') - ->toArray(); - } - /** * @param Model $resourceModel * @return array * @throws Exception */ - protected function getPropertiesFromSchema(Model $resourceModel, array $includedProperties): array + protected function getPropertiesFromSchema(Model $resourceModel): array { $columns = $this->schemaManager->getSchemaColumns($resourceModel); return collect($columns) - ->filter(function (Column $column) use ($includedProperties) { - return in_array($column->getName(), $includedProperties, true); - }) - ->map(function (Column $column) use ($resourceModel) { - $propertyClass = $this->schemaManager->resolveSchemaPropertyClass($column, $resourceModel); + ->filter( + function (Column $column) use ($resourceModel) { + return !$resourceModel->isFillable($column->getName()); + } + )->map( + function (Column $column) use ($resourceModel) { + $propertyClass = $this->schemaManager->resolveSchemaPropertyClass($column, $resourceModel); - return $this->propertyBuilder->build($column, $propertyClass); - }) - ->values() + return $this->propertyBuilder->build($column, $propertyClass); + } + )->values() ->keyBy('name') ->toArray(); } diff --git a/src/Specs/Builders/Components/ModelComponentBuilder.php b/src/Specs/Builders/Components/ModelComponentBuilder.php index 78e84b6c..c5284dde 100644 --- a/src/Specs/Builders/Components/ModelComponentBuilder.php +++ b/src/Specs/Builders/Components/ModelComponentBuilder.php @@ -5,7 +5,6 @@ namespace Orion\Specs\Builders\Components; use Orion\Specs\Builders\PropertyBuilder; -use Orion\Specs\Managers\ResourceManager; use Orion\Specs\Managers\SchemaManager; abstract class ModelComponentBuilder @@ -14,10 +13,6 @@ abstract class ModelComponentBuilder * @var SchemaManager */ protected $schemaManager; - /** - * @var ResourceManager - */ - protected $resourceManager; /** * @var PropertyBuilder */ @@ -27,13 +22,12 @@ abstract class ModelComponentBuilder * BaseModelComponentBuilder constructor. * * @param SchemaManager $schemaManager - * @param ResourceManager $resourceManager * @param PropertyBuilder $propertyBuilder */ - public function __construct(SchemaManager $schemaManager, ResourceManager $resourceManager, PropertyBuilder $propertyBuilder) + public function __construct(SchemaManager $schemaManager, PropertyBuilder $propertyBuilder) { $this->schemaManager = $schemaManager; - $this->resourceManager = $resourceManager; $this->propertyBuilder = $propertyBuilder; } + } diff --git a/src/Specs/Builders/ComponentsBuilder.php b/src/Specs/Builders/ComponentsBuilder.php index 6149d1c7..be1f86d1 100644 --- a/src/Specs/Builders/ComponentsBuilder.php +++ b/src/Specs/Builders/ComponentsBuilder.php @@ -100,13 +100,10 @@ protected function buildModelComponents(Collection $components, array $resources $resourceModelClass = app()->make($resource->controller)->resolveResourceModelClass(); $resourceModel = app()->make($resourceModelClass); - $resourceResourceClass = app()->make($resource->controller)->getResource(); - $resourceResource = app()->make($resourceResourceClass, ['resource' => optional()]); - foreach (static::SCHEMA_MODEL_COMPONENT_BUILDERS as $modelComponentBuilderClass) { $modelComponentBuilder = app()->make($modelComponentBuilderClass); - $modelComponent = $modelComponentBuilder->build($resourceModel, $resourceResource); + $modelComponent = $modelComponentBuilder->build($resourceModel); $schemas[$modelComponent->title] = $modelComponent->toArray(); } diff --git a/src/Specs/Builders/PropertyBuilder.php b/src/Specs/Builders/PropertyBuilder.php index 3676e6c0..8761a229 100644 --- a/src/Specs/Builders/PropertyBuilder.php +++ b/src/Specs/Builders/PropertyBuilder.php @@ -24,21 +24,4 @@ public function build(Column $column, string $concretePropertyClass): SchemaProp return $property; } - - /** - * @param string $name - * @param bool $nullable - * @param string|SchemaProperty $concretePropertyClass - * - * @return SchemaProperty - */ - public function buildFromResource(string $name, bool $nullable, string $concretePropertyClass): SchemaProperty - { - /** @var SchemaProperty $property */ - $property = new $concretePropertyClass(); - $property->name = $name; - $property->nullable = $nullable; - - return $property; - } } diff --git a/src/Specs/Managers/ResourceManager.php b/src/Specs/Managers/ResourceManager.php deleted file mode 100644 index de28d1f2..00000000 --- a/src/Specs/Managers/ResourceManager.php +++ /dev/null @@ -1,67 +0,0 @@ -toArray(optional()); - } - - /** - * @param string $property - * @param $value - * @return string - */ - public function resolveResourcePropertyClass(string $property, $value): string - { - if ($value instanceof DateTimeInterface) { - return DateTimeSchemaProperty::class; - } - - if (is_int($value)) { - return IntegerSchemaProperty::class; - } - - if (is_bool($value)) { - return BooleanSchemaProperty::class; - } - - if (is_float($value)) { - return NumberSchemaProperty::class; - } - - if (is_string($value)) { - return StringSchemaProperty::class; - } - - if (is_array($value) || is_a($value, ResourceCollection::class) || is_a($value, Collection::class)) { - return ArraySchemaProperty::class; - } - - if (is_object($value) || is_a($value, JsonResource::class)) { - return ObjectSchemaProperty::class; - } - - return AnySchemaProperty::class; - } -} diff --git a/src/ValueObjects/Specs/ModelResourceComponent.php b/src/ValueObjects/Specs/ModelResourceComponent.php index 92916adb..b57e2af0 100644 --- a/src/ValueObjects/Specs/ModelResourceComponent.php +++ b/src/ValueObjects/Specs/ModelResourceComponent.php @@ -8,10 +8,11 @@ class ModelResourceComponent extends Component { public function toArray(): array { - return [ - 'title' => $this->title, - 'type' => $this->type, - 'properties' => $this->properties, - ]; + return array_merge( + [ + 'title' => $this->title, + ], + $this->properties + ); } } diff --git a/tests/Fixtures/app/Http/Controllers/ProductsController.php b/tests/Fixtures/app/Http/Controllers/ProductsController.php deleted file mode 100644 index 4d772df3..00000000 --- a/tests/Fixtures/app/Http/Controllers/ProductsController.php +++ /dev/null @@ -1,20 +0,0 @@ - $this->id, - - 'title' => $this->name, - 'description' => $this->description, - 'active' => $this->active, - 'company_id' => $this->company_id, - - 'updated_at' => $this->updated_at, // Ommited schema property - 'created_at' => $this->created_at, - - // Test added properties - 'short_description' => substr($this->description, 90), // Computed property - 'company' => $this->whenLoaded('company', $this->company), // Added relation - $this->mergeWhen(true, ['merge_true' => 0]), // Merged - $this->mergeWhen(false, ['merge_false' => 0]), // MissingValue - - // Test removed properties - // 'total_revenue' => $this->updated_at, // Ommited schema property - ]; - } -} diff --git a/tests/Fixtures/app/Models/Product.php b/tests/Fixtures/app/Models/Product.php deleted file mode 100644 index d78e91c6..00000000 --- a/tests/Fixtures/app/Models/Product.php +++ /dev/null @@ -1,21 +0,0 @@ -belongsTo(Company::class); - } -} diff --git a/tests/Fixtures/database/factories/ProductFactory.php b/tests/Fixtures/database/factories/ProductFactory.php deleted file mode 100644 index 91e3142c..00000000 --- a/tests/Fixtures/database/factories/ProductFactory.php +++ /dev/null @@ -1,12 +0,0 @@ -define(Product::class, function (Faker $faker) { - return [ - 'title' => $faker->words(5, true), - 'description' => $faker->sentences(), - 'total_revenue' => $faker->numberBetween(0, 200) - ]; -}); diff --git a/tests/Fixtures/database/migrations/2022_07_30_131500_create_products_table.php b/tests/Fixtures/database/migrations/2022_07_30_131500_create_products_table.php deleted file mode 100644 index a19031c6..00000000 --- a/tests/Fixtures/database/migrations/2022_07_30_131500_create_products_table.php +++ /dev/null @@ -1,40 +0,0 @@ -bigIncrements('id'); - - $table->string('title'); - $table->text('description'); - $table->boolean('active')->default(false); - $table->unsignedBigInteger('company_id')->nullable(); - $table->unsignedInteger('total_revenue')->default(0); - - $table->timestamps(); - - $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('products'); - } -} diff --git a/tests/Unit/Specs/Builders/ComponentsBuilderTest.php b/tests/Unit/Specs/Builders/ComponentsBuilderTest.php deleted file mode 100644 index e39870ae..00000000 --- a/tests/Unit/Specs/Builders/ComponentsBuilderTest.php +++ /dev/null @@ -1,60 +0,0 @@ -addResource( - new RegisteredResource(ProductsController::class, ['show']) - ); - - $this->componentsBuilder = new ComponentsBuilder($resourcesCacheStore); - } - - /** @test */ - public function test_build(): void - { - if ((float) app()->version() <= 8.0) { - $this->markTestSkipped('Unsupported framework version'); - } - - $components = $this->componentsBuilder->build(); - $this->assertArrayHasKey('schemas', $components); - - $schemas = $components['schemas']; - $this->assertArrayHasKey('Product', $schemas); - - $resource = $schemas['ProductResource']['properties']; - - // Schema properties - $this->assertArrayHasKey('title', $resource); - $this->assertArrayHasKey('description', $resource); - - // Added properties - $this->assertArrayHasKey('short_description', $resource); - $this->assertArrayHasKey('company', $resource); - $this->assertArrayHasKey('merge_true', $resource); - $this->assertArrayHasKey('merge_false', $resource); - - // Removed properties - $this->assertArrayNotHasKey('total_revenue', $resource); - } -}