From ca14b8d9c4ea782cad178b54e157df3d0c77291c Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Thu, 24 Aug 2023 13:01:20 +0200 Subject: [PATCH 1/6] feat: PHP JsonSerializable Preset In PHP objects (and also arrays and scalars) can be serialized to JSON using the function `json_encode()`. In order to maintain the correct property names and values for Enums, normalization of values needs to be implemented manually using the `JsonSerializable` interface. The serialization to JSON can be enabled by using the optional preset `PHP_JSON_SERIALIZABLE_PRESET`. This way of serializing PHP objects does not require any user land package and works out of the box with each PHP version. It is also compatible with different serialization frameworks, like Symfony. --- docs/languages/Php.md | 20 ++++- .../README.md | 17 ++++ .../__snapshots__/index.spec.ts.snap | 28 ++++++ .../index.spec.ts | 15 ++++ .../index.ts | 33 +++++++ .../package-lock.json | 10 +++ .../package.json | 10 +++ .../php/presets/JsonSerializablePreset.ts | 88 +++++++++++++++++++ src/generators/php/presets/index.ts | 1 + .../presets/JsonSerializablePreset.spec.ts | 41 +++++++++ .../JsonSerializablePreset.spec.ts.snap | 46 ++++++++++ 11 files changed, 305 insertions(+), 4 deletions(-) create mode 100644 examples/php-generate-json-serializable-preset/README.md create mode 100644 examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap create mode 100644 examples/php-generate-json-serializable-preset/index.spec.ts create mode 100644 examples/php-generate-json-serializable-preset/index.ts create mode 100644 examples/php-generate-json-serializable-preset/package-lock.json create mode 100644 examples/php-generate-json-serializable-preset/package.json create mode 100644 src/generators/php/presets/JsonSerializablePreset.ts create mode 100644 test/generators/php/presets/JsonSerializablePreset.spec.ts create mode 100644 test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap diff --git a/docs/languages/Php.md b/docs/languages/Php.md index 8c0ed7800f..fa9aebd2bf 100644 --- a/docs/languages/Php.md +++ b/docs/languages/Php.md @@ -15,21 +15,33 @@ There are special use-cases that each language supports; this document pertains ## Description Present -By default, descriptions are not rendered for the model, you can change that by applying `PHP_DESCRIPTION_PRESET`. +By default, descriptions are not rendered for the model; you can change that by applying `PHP_DESCRIPTION_PRESET`. Check out this [example for a live demonstration](../../examples/php-generate-documentation-preset). ## Generate serializer and deserializer functionality -The most widely used usecase for Modelina is to generate models that include serilization and deserialization functionality to convert the models into payload data. This payload data can of course be many different kinds, JSON, XML, raw binary, you name it. +The most widely used usecase for Modelina is to generate models that include serialization and deserialization functionality to convert the models into payload data. +This payload data can, of course, be many different kinds, JSON, XML, raw binary, you name it. -As you normally only need one library to do this, we developers can never get enough with creating new stuff, therefore there might be one specific library you need or want to integrate with. Therefore there is not one specific preset that offers everything. Below is a list of all the supported serialization presets. +As you normally only need one library to do this, we developers can never get enough of creating new stuff, therefore, there might be one specific library you need or want to integrate with. +Therefore, there is not one specific preset that offers everything. Below is a list of all the supported serialization presets. ### To and from JSON -Currently not supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)! + +Objects in PHP can generally be serialized to JSON using the [`json_encode()` function](https://www.php.net/manual/en/function.json-encode.php). +To ensure that the data is serialized correctly, the [`JsonSerializable` interface](https://www.php.net/manual/en/class.jsonserializable.php) needs to be implemented. +This will ensure that, for example, enum values and property names are serialized correctly. + +To add support of serialization to JSON, apply the `PHP_JSON_SERIALIZABLE_PRESET` preset. +Check out this [example for a live demonstration](../../examples/php-generate-json-serializable-preset). + +Marshalling PHP objects from JSON is currently supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)! ### To and from XML + Currently not supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)! ### To and from binary + Currently not supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)! diff --git a/examples/php-generate-json-serializable-preset/README.md b/examples/php-generate-json-serializable-preset/README.md new file mode 100644 index 0000000000..3e816a6fd0 --- /dev/null +++ b/examples/php-generate-json-serializable-preset/README.md @@ -0,0 +1,17 @@ +# PHP Generate JSON Serializable Models Example + +A basic example of how to use Modelina and output PHP model. + +## How to run this example + +Run this example using: + +```sh +npm i && npm run start +``` + +If you are on Windows, use the `start:windows` script instead: + +```sh +npm i && npm run start:windows +``` diff --git a/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..abe1fd08fb --- /dev/null +++ b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should be able to render PHP and should log expected output to console 1`] = ` +Array [ + "email; } + public function setEmail(?string $email): void { $this->email = $email; } + + public function jsonSerialize(): array + { + return [ + 'email' => $this->email, + ]; + } +} +", +] +`; diff --git a/examples/php-generate-json-serializable-preset/index.spec.ts b/examples/php-generate-json-serializable-preset/index.spec.ts new file mode 100644 index 0000000000..04cdadefcc --- /dev/null +++ b/examples/php-generate-json-serializable-preset/index.spec.ts @@ -0,0 +1,15 @@ +const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { + return; +}); +import { generate } from './index'; + +describe('Should be able to render PHP', () => { + afterAll(() => { + jest.restoreAllMocks(); + }); + test('and should log expected output to console', async () => { + await generate(); + expect(spy.mock.calls.length).toEqual(1); + expect(spy.mock.calls[0]).toMatchSnapshot(); + }); +}); diff --git a/examples/php-generate-json-serializable-preset/index.ts b/examples/php-generate-json-serializable-preset/index.ts new file mode 100644 index 0000000000..d13f53f60b --- /dev/null +++ b/examples/php-generate-json-serializable-preset/index.ts @@ -0,0 +1,33 @@ +import { + OutputModel, + PHP_JSON_SERIALIZABLE_PRESET, + PhpGenerator +} from '../../src'; + +const generator: PhpGenerator = new PhpGenerator({ + presets: [PHP_JSON_SERIALIZABLE_PRESET] +}); +const jsonSchemaDraft7 = { + $schema: 'http://json-schema.org/draft-07/schema#', + type: 'object', + additionalProperties: false, + properties: { + email: { + type: 'string', + format: 'email' + } + } +}; + +export async function generate(): Promise { + const models: OutputModel[] = await generator.generateCompleteModels( + jsonSchemaDraft7, + {} + ); + for (const model of models) { + console.log(model.result); + } +} +if (require.main === module) { + generate(); +} diff --git a/examples/php-generate-json-serializable-preset/package-lock.json b/examples/php-generate-json-serializable-preset/package-lock.json new file mode 100644 index 0000000000..2938ea8d4c --- /dev/null +++ b/examples/php-generate-json-serializable-preset/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "php-generate-json-serializable-preset", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "hasInstallScript": true + } + } +} diff --git a/examples/php-generate-json-serializable-preset/package.json b/examples/php-generate-json-serializable-preset/package.json new file mode 100644 index 0000000000..e912e9678a --- /dev/null +++ b/examples/php-generate-json-serializable-preset/package.json @@ -0,0 +1,10 @@ +{ + "config" : { "example_name" : "php-generate-json-serializable-preset" }, + "scripts": { + "install": "cd ../.. && npm i", + "start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts", + "start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts", + "test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts", + "test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts" + } +} diff --git a/src/generators/php/presets/JsonSerializablePreset.ts b/src/generators/php/presets/JsonSerializablePreset.ts new file mode 100644 index 0000000000..b883e6da43 --- /dev/null +++ b/src/generators/php/presets/JsonSerializablePreset.ts @@ -0,0 +1,88 @@ +import { PhpPreset } from '../PhpPreset'; +import { PhpRenderer } from '../PhpRenderer'; +import { ConstrainedMetaModel } from '../../../models'; + +function renderSelf({ + content, + renderer +}: { + content: string; + renderer: PhpRenderer; +}): string { + renderer.dependencyManager.addDependency('use JsonSerializable;'); + + const contentLines = content.split('\n'); + contentLines[0] += ` implements JsonSerializable`; + + return contentLines.join('\n'); +} + +/** + * Preset, which implements PHP’s JsonSerializable interface. + * + * Using this will allow to json serialize the model using `json_encode()`. + * + * @implements {PhpPreset} + */ +export const PHP_JSON_SERIALIZABLE_PRESET: PhpPreset = { + class: { + self({ content, renderer }): string { + return renderSelf({ content, renderer }); + }, + additionalContent({ renderer, model, content }): string { + return ( + content + + renderer.renderBlock([ + 'public function jsonSerialize(): array', + '{', + renderer.indent( + renderer.renderBlock([ + 'return [', + renderer.indent( + renderer.renderBlock( + Object.values(model.properties).map((property) => { + if (property.propertyName === 'additionalProperties') { + return `...$this->${property.propertyName},`; + } + + return `'${property.unconstrainedPropertyName}' => $this->${property.propertyName},`; + }) + ) + ), + '];' + ]) + ), + '}' + ]) + ); + } + }, + enum: { + self({ content, renderer }): string { + return renderSelf({ content, renderer }); + }, + additionalContent({ content, model, renderer }) { + return ( + content + + renderer.renderBlock([ + `public function jsonSerialize(): mixed`, + '{', + renderer.indent( + renderer.renderBlock([ + 'return match($this) {', + renderer.indent( + renderer.renderBlock([ + ...model.values.map( + (value) => `self::${value.key} => ${value.value},` + ) + ]) + ), + '};' + ]) + ), + '}' + ]) + ); + } + } +}; diff --git a/src/generators/php/presets/index.ts b/src/generators/php/presets/index.ts index e74c57b288..6b339e34ab 100644 --- a/src/generators/php/presets/index.ts +++ b/src/generators/php/presets/index.ts @@ -1 +1,2 @@ export * from './DescriptionPreset'; +export * from './JsonSerializablePreset'; diff --git a/test/generators/php/presets/JsonSerializablePreset.spec.ts b/test/generators/php/presets/JsonSerializablePreset.spec.ts new file mode 100644 index 0000000000..168b7971dd --- /dev/null +++ b/test/generators/php/presets/JsonSerializablePreset.spec.ts @@ -0,0 +1,41 @@ +import { PHP_JSON_SERIALIZABLE_PRESET, PhpGenerator } from '../../../../src'; + +describe('PHP_JSON_SERIALIZABLE_PRESET', () => { + let generator: PhpGenerator; + beforeEach(() => { + generator = new PhpGenerator({ + presets: [PHP_JSON_SERIALIZABLE_PRESET] + }); + }); + + test('should render jsonSerialize method for class', async () => { + const doc = { + $id: 'Clazz', + type: 'object', + properties: { + prop: { + type: 'string' + }, + 'prop-with-dash': { + type: 'string' + } + } + }; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + }); + + test('should render jsonSerialize method for enum', async () => { + const doc = { + $id: 'Enumm', + type: 'enum', + enum: ['value-A', 'value-B'] + }; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + }); +}); diff --git a/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap b/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap new file mode 100644 index 0000000000..352f685508 --- /dev/null +++ b/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for class 1`] = ` +"final class Clazz implements JsonSerializable +{ + private ?string $prop; + private ?string $propMinusWithMinusDash; + private mixed $additionalProperties; + + public function getProp(): ?string { return $this->prop; } + public function setProp(?string $prop): void { $this->prop = $prop; } + + public function getPropMinusWithMinusDash(): ?string { return $this->propMinusWithMinusDash; } + public function setPropMinusWithMinusDash(?string $propMinusWithMinusDash): void { $this->propMinusWithMinusDash = $propMinusWithMinusDash; } + + public function getAdditionalProperties(): mixed { return $this->additionalProperties; } + public function setAdditionalProperties(mixed $additionalProperties): void { $this->additionalProperties = $additionalProperties; } + + public function jsonSerialize(): array + { + return [ + 'prop' => $this->prop, + 'prop-with-dash' => $this->propMinusWithMinusDash, + ...$this->additionalProperties, + ]; + } +} +" +`; + +exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for enum 1`] = ` +"enum Enumm implements JsonSerializable +{ + case VALUE_MINUS_A; + case VALUE_MINUS_B; + + public function jsonSerialize(): mixed + { + return match($this) { + self::VALUE_MINUS_A => \\"value-A\\", + self::VALUE_MINUS_B => \\"value-B\\", + }; + } +} +" +`; From 18459f39d5f0cb048aec18a9d8ff45baf910c5b3 Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Thu, 24 Aug 2023 17:34:24 +0200 Subject: [PATCH 2/6] Update docs/languages/Php.md Co-authored-by: Jonas Lagoni --- docs/languages/Php.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/languages/Php.md b/docs/languages/Php.md index fa9aebd2bf..d69b3b5fa4 100644 --- a/docs/languages/Php.md +++ b/docs/languages/Php.md @@ -36,7 +36,6 @@ This will ensure that, for example, enum values and property names are serialize To add support of serialization to JSON, apply the `PHP_JSON_SERIALIZABLE_PRESET` preset. Check out this [example for a live demonstration](../../examples/php-generate-json-serializable-preset). -Marshalling PHP objects from JSON is currently supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)! ### To and from XML From 1304e309b3b15b975de99b49fbc8cfe9f9f6fcb0 Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Thu, 24 Aug 2023 17:34:53 +0200 Subject: [PATCH 3/6] Update examples/php-generate-json-serializable-preset/README.md Co-authored-by: Jonas Lagoni --- examples/php-generate-json-serializable-preset/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/php-generate-json-serializable-preset/README.md b/examples/php-generate-json-serializable-preset/README.md index 3e816a6fd0..b9af014bd8 100644 --- a/examples/php-generate-json-serializable-preset/README.md +++ b/examples/php-generate-json-serializable-preset/README.md @@ -1,6 +1,6 @@ # PHP Generate JSON Serializable Models Example -A basic example of how to use Modelina and output PHP model. +A basic example of how to use Modelina and output PHP model that supports JSON serialization. ## How to run this example From 048c9e17d7e0431f032f707e0810dc93ffd4b3c5 Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Fri, 25 Aug 2023 11:05:57 +0200 Subject: [PATCH 4/6] Apply feedback from code review * remove import of JsonSerializable * add test for mixed (int and string) enums --- .../__snapshots__/index.spec.ts.snap | 2 +- .../php/presets/JsonSerializablePreset.ts | 7 ++----- .../presets/JsonSerializablePreset.spec.ts | 12 +++++++++++ .../JsonSerializablePreset.spec.ts.snap | 21 +++++++++++++++++-- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap index abe1fd08fb..fa84483dd4 100644 --- a/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap +++ b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap @@ -9,7 +9,7 @@ namespace Asyncapi; use JsonSerializable; -final class Root implements JsonSerializable +final class Root implements \\\\JsonSerializable { private ?string $email; diff --git a/src/generators/php/presets/JsonSerializablePreset.ts b/src/generators/php/presets/JsonSerializablePreset.ts index b883e6da43..9a1fdc29c7 100644 --- a/src/generators/php/presets/JsonSerializablePreset.ts +++ b/src/generators/php/presets/JsonSerializablePreset.ts @@ -3,16 +3,13 @@ import { PhpRenderer } from '../PhpRenderer'; import { ConstrainedMetaModel } from '../../../models'; function renderSelf({ - content, - renderer + content }: { content: string; renderer: PhpRenderer; }): string { - renderer.dependencyManager.addDependency('use JsonSerializable;'); - const contentLines = content.split('\n'); - contentLines[0] += ` implements JsonSerializable`; + contentLines[0] += ` implements \\JsonSerializable`; return contentLines.join('\n'); } diff --git a/test/generators/php/presets/JsonSerializablePreset.spec.ts b/test/generators/php/presets/JsonSerializablePreset.spec.ts index 168b7971dd..5c44e8c3f1 100644 --- a/test/generators/php/presets/JsonSerializablePreset.spec.ts +++ b/test/generators/php/presets/JsonSerializablePreset.spec.ts @@ -38,4 +38,16 @@ describe('PHP_JSON_SERIALIZABLE_PRESET', () => { expect(models).toHaveLength(1); expect(models[0].result).toMatchSnapshot(); }); + + test('should render jsonSerialize method for enum with mixed types', async () => { + const doc = { + $id: 'Enumm', + type: 'enum', + enum: [1, 'B'] + }; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + }); }); diff --git a/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap b/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap index 352f685508..913a42c9dc 100644 --- a/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap +++ b/test/generators/php/presets/__snapshots__/JsonSerializablePreset.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for class 1`] = ` -"final class Clazz implements JsonSerializable +"final class Clazz implements \\\\JsonSerializable { private ?string $prop; private ?string $propMinusWithMinusDash; @@ -29,7 +29,7 @@ exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for cla `; exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for enum 1`] = ` -"enum Enumm implements JsonSerializable +"enum Enumm implements \\\\JsonSerializable { case VALUE_MINUS_A; case VALUE_MINUS_B; @@ -44,3 +44,20 @@ exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for enu } " `; + +exports[`PHP_JSON_SERIALIZABLE_PRESET should render jsonSerialize method for enum with mixed types 1`] = ` +"enum Enumm implements \\\\JsonSerializable +{ + case NUMBER_1; + case B; + + public function jsonSerialize(): mixed + { + return match($this) { + self::NUMBER_1 => 1, + self::B => \\"B\\", + }; + } +} +" +`; From f2616f9d2e741282ccee785ecefea35b9c6f5299 Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Fri, 25 Aug 2023 11:37:23 +0200 Subject: [PATCH 5/6] Apply code review feedback * extract serializing properties to own variable to make code more readable. * use ConstrainedDictionaryModel to detect additional properties --- .../php/presets/JsonSerializablePreset.ts | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/generators/php/presets/JsonSerializablePreset.ts b/src/generators/php/presets/JsonSerializablePreset.ts index 9a1fdc29c7..f26fd8e114 100644 --- a/src/generators/php/presets/JsonSerializablePreset.ts +++ b/src/generators/php/presets/JsonSerializablePreset.ts @@ -1,6 +1,9 @@ import { PhpPreset } from '../PhpPreset'; import { PhpRenderer } from '../PhpRenderer'; -import { ConstrainedMetaModel } from '../../../models'; +import { + ConstrainedDictionaryModel, + ConstrainedMetaModel +} from '../../../models'; function renderSelf({ content @@ -27,6 +30,19 @@ export const PHP_JSON_SERIALIZABLE_PRESET: PhpPreset = { return renderSelf({ content, renderer }); }, additionalContent({ renderer, model, content }): string { + const serializedProperties = Object.values(model.properties).map( + (property) => { + if ( + property.property instanceof ConstrainedDictionaryModel && + property.property.serializationType === 'unwrap' + ) { + return `...$this->${property.propertyName},`; + } + + return `'${property.unconstrainedPropertyName}' => $this->${property.propertyName},`; + } + ); + return ( content + renderer.renderBlock([ @@ -35,17 +51,7 @@ export const PHP_JSON_SERIALIZABLE_PRESET: PhpPreset = { renderer.indent( renderer.renderBlock([ 'return [', - renderer.indent( - renderer.renderBlock( - Object.values(model.properties).map((property) => { - if (property.propertyName === 'additionalProperties') { - return `...$this->${property.propertyName},`; - } - - return `'${property.unconstrainedPropertyName}' => $this->${property.propertyName},`; - }) - ) - ), + renderer.indent(renderer.renderBlock(serializedProperties)), '];' ]) ), @@ -68,11 +74,11 @@ export const PHP_JSON_SERIALIZABLE_PRESET: PhpPreset = { renderer.renderBlock([ 'return match($this) {', renderer.indent( - renderer.renderBlock([ - ...model.values.map( + renderer.renderBlock( + Object.values(model.values).map( (value) => `self::${value.key} => ${value.value},` ) - ]) + ) ), '};' ]) From 6e8fba3886c78d886c9509e23a0b790a46c11bd9 Mon Sep 17 00:00:00 2001 From: Markus Poerschke Date: Fri, 25 Aug 2023 13:54:50 +0200 Subject: [PATCH 6/6] Fix tests --- .../__snapshots__/index.spec.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap index fa84483dd4..d04c11f34b 100644 --- a/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap +++ b/examples/php-generate-json-serializable-preset/__snapshots__/index.spec.ts.snap @@ -8,7 +8,7 @@ declare(strict_types=1); namespace Asyncapi; -use JsonSerializable; + final class Root implements \\\\JsonSerializable { private ?string $email;