From 67ced87d30c90ad1bc0b95b4a4ebea11452b6b77 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Sat, 27 Sep 2025 02:12:55 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=F0=9F=90=9B=20simple=20mistake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Hydra/JsonSchema/SchemaFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydra/JsonSchema/SchemaFactory.php b/src/Hydra/JsonSchema/SchemaFactory.php index 4328d52f47..480c77e0f9 100644 --- a/src/Hydra/JsonSchema/SchemaFactory.php +++ b/src/Hydra/JsonSchema/SchemaFactory.php @@ -140,7 +140,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string return $schema; } - $baseName = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_NAME : self::ITEM_BASE_SCHEMA_OUTPUT_NAME; + $baseName = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT_NAME : self::ITEM_BASE_SCHEMA_NAME; if (!isset($definitions[$baseName])) { $definitions[$baseName] = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT : self::ITEM_BASE_SCHEMA; From 7b829728181bff123bb023d2f2f1fb321c3de9d4 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Mon, 6 Oct 2025 23:09:33 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=F0=9F=90=9B=20force=20input=20schem?= =?UTF-8?q?a=20to=20json=20format=20instead=20of=20jsonld=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we were to delegate the processing to the original `SchemaFactory` while keeping the `jsonld` format, the `$definitionName` would be `Book.jsonld` instead of `Book` at [here](https://github.com/api-platform/core/blob/v4.2.1/src/JsonSchema/SchemaFactory.php#L84), and the `Book.jsonld` schema would be returned as is at [here](https://github.com/api-platform/core/blob/v4.2.1/src/JsonSchema/SchemaFactory.php#L106-L109), so the input schema would be the same jsonld schema as the output schema. --- src/Hydra/JsonSchema/SchemaFactory.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Hydra/JsonSchema/SchemaFactory.php b/src/Hydra/JsonSchema/SchemaFactory.php index 480c77e0f9..f0ad4f95bb 100644 --- a/src/Hydra/JsonSchema/SchemaFactory.php +++ b/src/Hydra/JsonSchema/SchemaFactory.php @@ -104,7 +104,15 @@ public function __construct( */ public function buildSchema(string $className, string $format = 'jsonld', string $type = Schema::TYPE_OUTPUT, ?Operation $operation = null, ?Schema $schema = null, ?array $serializerContext = null, bool $forceCollection = false): Schema { - if ('jsonld' !== $format || 'input' === $type) { + // The input schema must not include `@id` or `@type` as required fields, so it should be a pure JSON schema. + // Strictly speaking, it is possible to include `@id` or `@context` in the input, + // but the generated JSON Schema does not include `"additionalProperties": false` by default, + // so it is possible to include `@id` or `@context` in the input even if the input schema is a JSON schema. + if (Schema::TYPE_INPUT === $type) { + $format = 'json'; + } + + if ('jsonld' !== $format) { return $this->schemaFactory->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection); } if (!$this->isResourceClass($className)) { From 13e4ea34b085cf5bed76b3b0d04212913f06e43f Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Mon, 6 Oct 2025 23:27:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20remove=20paths?= =?UTF-8?q?=20that=20are=20never=20executed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Hydra/JsonSchema/SchemaFactory.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Hydra/JsonSchema/SchemaFactory.php b/src/Hydra/JsonSchema/SchemaFactory.php index f0ad4f95bb..17474ca5bd 100644 --- a/src/Hydra/JsonSchema/SchemaFactory.php +++ b/src/Hydra/JsonSchema/SchemaFactory.php @@ -37,7 +37,6 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI use SchemaUriPrefixTrait; private const ITEM_BASE_SCHEMA_NAME = 'HydraItemBaseSchema'; - private const ITEM_BASE_SCHEMA_OUTPUT_NAME = 'HydraOutputBaseSchema'; private const COLLECTION_BASE_SCHEMA_NAME = 'HydraCollectionBaseSchema'; private const BASE_PROP = [ 'type' => 'string', @@ -69,11 +68,8 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI ], ], ] + self::BASE_PROPS, - ]; - - private const ITEM_BASE_SCHEMA_OUTPUT = [ 'required' => ['@id', '@type'], - ] + self::ITEM_BASE_SCHEMA; + ]; /** * @var array @@ -148,10 +144,10 @@ public function buildSchema(string $className, string $format = 'jsonld', string return $schema; } - $baseName = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT_NAME : self::ITEM_BASE_SCHEMA_NAME; + $baseName = self::ITEM_BASE_SCHEMA_NAME; if (!isset($definitions[$baseName])) { - $definitions[$baseName] = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT : self::ITEM_BASE_SCHEMA; + $definitions[$baseName] = self::ITEM_BASE_SCHEMA; } $allOf = new \ArrayObject(['allOf' => [ From 50a46f7029d45c3e533d3cd18ef78cee3da815c5 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Mon, 6 Oct 2025 23:54:47 +0900 Subject: [PATCH 4/4] =?UTF-8?q?test:=20=F0=9F=92=8D=20fix=20existing=20tes?= =?UTF-8?q?ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Functional/JsonSchema/JsonSchemaTest.php | 12 ++++++------ .../Command/JsonSchemaGenerateCommandTest.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/Functional/JsonSchema/JsonSchemaTest.php b/tests/Functional/JsonSchema/JsonSchemaTest.php index 4145c1ecbb..63b57c9b3e 100644 --- a/tests/Functional/JsonSchema/JsonSchemaTest.php +++ b/tests/Functional/JsonSchema/JsonSchemaTest.php @@ -134,24 +134,24 @@ public function testArraySchemaWithReference(): void $schema = $this->schemaFactory->buildSchema(BagOfTests::class, 'jsonld', Schema::TYPE_INPUT); - $this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['tests'], new \ArrayObject([ + $this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['tests'], new \ArrayObject([ 'type' => 'string', 'foo' => 'bar', ])); - $this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['nonResourceTests'], new \ArrayObject([ + $this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['nonResourceTests'], new \ArrayObject([ 'type' => 'array', 'items' => [ - '$ref' => '#/definitions/NonResourceTestEntity.jsonld-write', + '$ref' => '#/definitions/NonResourceTestEntity-write', ], ])); - $this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['description'], new \ArrayObject([ + $this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['description'], new \ArrayObject([ 'maxLength' => 255, ])); - $this->assertEquals($schema['definitions']['BagOfTests.jsonld-write']['properties']['type'], new \ArrayObject([ - '$ref' => '#/definitions/TestEntity.jsonld-write', + $this->assertEquals($schema['definitions']['BagOfTests-write']['properties']['type'], new \ArrayObject([ + '$ref' => '#/definitions/TestEntity-write', ])); } diff --git a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php index da735dd744..5f6dc9c90e 100644 --- a/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php +++ b/tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php @@ -141,7 +141,7 @@ public function testWritableNonResourceRef(): void $result = $this->tester->getDisplay(); $json = json_decode($result, associative: true); - $this->assertEquals($json['definitions']['SaveProduct.jsonld']['properties']['codes']['items']['$ref'], '#/definitions/ProductCode.jsonld'); + $this->assertEquals($json['definitions']['SaveProduct']['properties']['codes']['items']['$ref'], '#/definitions/ProductCode'); } /**