diff --git a/src/commands/generate/models.ts b/src/commands/generate/models.ts index a53cd0bc383..7e7f23b34cf 100644 --- a/src/commands/generate/models.ts +++ b/src/commands/generate/models.ts @@ -1,6 +1,7 @@ import { CSharpFileGenerator, JavaFileGenerator, JavaScriptFileGenerator, TypeScriptFileGenerator, GoFileGenerator, Logger, DartFileGenerator, PythonFileGenerator, RustFileGenerator } from '@asyncapi/modelina'; import { Flags } from '@oclif/core'; import Command from '../../base'; +import path from 'path'; import { load } from '../../models/SpecificationFile'; import { parse } from '../../utils/parser'; enum Languages { @@ -33,6 +34,11 @@ export default class Models extends Command { description: 'The output directory where the models should be written to. Omitting this flag will write the models to `stdout`.', required: false }), + configFile: Flags.string({ + char: 'c', + description: 'Path to config file', + required: false + }), /** * TypeScript specific options */ @@ -74,6 +80,7 @@ export default class Models extends Command { description: 'C# specific, define the namespace to use for the generated models. This is required when language is `csharp`.', required: false }), + }; async run() { @@ -83,6 +90,14 @@ export default class Models extends Command { const inputFile = await load(file) || await load(); const parsedInput = await parse(inputFile.text()); + let defaultConfig = {}; + if(flags.configFile !== undefined) { + try { + defaultConfig = await import(path.resolve(process.cwd(), flags.configFile)); + } catch(e: any) { + this.error(`There was an error trying to load the Modelina configuration file, it will be ignored. The following error was triggered: ${e}`); + } + } Logger.setLogger({ info: (message) => { this.log(message); @@ -102,8 +117,11 @@ export default class Models extends Command { switch (language) { case Languages.typescript: fileGenerator = new TypeScriptFileGenerator({ - modelType: tsModelType as undefined | 'class' | 'interface', - enumType: tsEnumType as undefined | 'enum' | 'union' + ...defaultConfig, + ...{ + modelType: tsModelType as undefined | 'class' | 'interface', + enumType: tsEnumType as undefined | 'enum' | 'union' + } }); fileOptions = { moduleSystem: tsModuleSystem, @@ -111,16 +129,16 @@ export default class Models extends Command { }; break; case Languages.python: - fileGenerator = new PythonFileGenerator(); + fileGenerator = new PythonFileGenerator(defaultConfig); break; case Languages.rust: - fileGenerator = new RustFileGenerator(); + fileGenerator = new RustFileGenerator(defaultConfig); break; case Languages.csharp: if (namespace === undefined) { throw new Error('In order to generate models to C#, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.'); } - fileGenerator = new CSharpFileGenerator(); + fileGenerator = new CSharpFileGenerator(defaultConfig); fileOptions = { namespace }; @@ -129,7 +147,7 @@ export default class Models extends Command { if (packageName === undefined) { throw new Error('In order to generate models to Go, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.'); } - fileGenerator = new GoFileGenerator(); + fileGenerator = new GoFileGenerator(defaultConfig); fileOptions = { packageName }; @@ -138,19 +156,19 @@ export default class Models extends Command { if (packageName === undefined) { throw new Error('In order to generate models to Java, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.'); } - fileGenerator = new JavaFileGenerator(); + fileGenerator = new JavaFileGenerator(defaultConfig); fileOptions = { packageName }; break; case Languages.javascript: - fileGenerator = new JavaScriptFileGenerator(); + fileGenerator = new JavaScriptFileGenerator(defaultConfig); break; case Languages.dart: if (packageName === undefined) { throw new Error('In order to generate models to Dart, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.'); } - fileGenerator = new DartFileGenerator(); + fileGenerator = new DartFileGenerator(defaultConfig); fileOptions = { packageName }; diff --git a/test/commands/generate/__snapshots__/models.test.ts.snap b/test/commands/generate/__snapshots__/models.test.ts.snap index 06f816c9134..07c2a79323d 100644 --- a/test/commands/generate/__snapshots__/models.test.ts.snap +++ b/test/commands/generate/__snapshots__/models.test.ts.snap @@ -1,10 +1,72 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`models for C# should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for Dart should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for Go should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for Java should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for JavaScript should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for Python should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for Rust should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models for TypeScript should handle configuration file 1`] = ` +"Successfully generated the following models: CustomUserSignedUpPayload +" +`; + +exports[`models should handle incorrect configuration file correctly 1`] = ` +"Error: There was an error trying to load the Modelina configuration file, it will be ignored. The following error was triggered: Error: + × Expected ';', '}' or + ╭─[/Users/lagoni/Documents/github/cli/test/commands/generate/models_configuration/incorrect_models.js:12:1] + 12 │ WRONG SYNTAX + · ────── + ╰──── + +Error: + ☞ This is the expression part of an expression statement + ╭─[/Users/lagoni/Documents/github/cli/test/commands/generate/models_configuration/incorrect_models.js:12:1] + 12 │ WRONG SYNTAX + · ───── + ╰──── + + +Caused by: + 0: failed to process input file + 1: Syntax Error +" +`; + exports[`models works when generating in memory 1`] = ` "Successfully generated the following models: -## Model name: AnonymousSchema_1 +## Model name: UserSignedUpPayload -class AnonymousSchema_1 { +class UserSignedUpPayload { private _displayName?: string; private _email?: string; private _additionalProperties?: Map; @@ -28,7 +90,7 @@ class AnonymousSchema_1 { get additionalProperties(): Map | undefined { return this._additionalProperties; } set additionalProperties(additionalProperties: Map | undefined) { this._additionalProperties = additionalProperties; } } -export default AnonymousSchema_1; +export default UserSignedUpPayload; " diff --git a/test/commands/generate/models.test.ts b/test/commands/generate/models.test.ts index e8174c73959..8173c583326 100644 --- a/test/commands/generate/models.test.ts +++ b/test/commands/generate/models.test.ts @@ -15,17 +15,27 @@ describe('models', () => { expect(ctx.stdout).toMatchSnapshot(); done(); }); - + test .stderr() .stdout() - .command([...generalOptions, 'random', './test/specification.yml', `-o=${ path.resolve(outputDir, './random')}`]) + .command([...generalOptions, 'random', './test/specification.yml', `-o=${path.resolve(outputDir, './random')}`]) .it('fails when it dont know the language', (ctx, done) => { expect(ctx.stderr).toEqual('Error: Expected random to be one of: typescript, csharp, golang, java, javascript, dart, python, rust\nSee more help with --help\n'); expect(ctx.stdout).toEqual(''); done(); }); + test + .stderr() + .stdout() + .command([...generalOptions, 'typescript', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, `-c=${path.resolve(__dirname, './models_configuration/incorrect_models.js')}`]) + .it('should handle incorrect configuration file correctly', (ctx, done) => { + expect(ctx.stderr).toMatchSnapshot(); + expect(ctx.stdout).toEqual(''); + done(); + }); + test .stderr() .stdout() @@ -35,12 +45,12 @@ describe('models', () => { expect(ctx.stdout).toMatchSnapshot(); done(); }); - - describe('for TypeScript', () => { + + describe('for TypeScript', () => { test .stderr() .stdout() - .command([...generalOptions, 'typescript', './test/specification.yml', `-o=${ path.resolve(outputDir, './ts')}`]) + .command([...generalOptions, 'typescript', './test/specification.yml', `-o=${path.resolve(outputDir, './ts')}`]) .it('works when file path is passed', (ctx, done) => { expect(ctx.stderr).toEqual(''); expect(ctx.stdout).toContain( @@ -48,13 +58,23 @@ describe('models', () => { ); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'typescript', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, `-c=${path.resolve(__dirname, './models_configuration/typescript_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for JavaScript', () => { + describe('for JavaScript', () => { test .stderr() .stdout() - .command([...generalOptions, 'javascript', './test/specification.yml', `-o=${ path.resolve(outputDir, './js')}`]) + .command([...generalOptions, 'javascript', './test/specification.yml', `-o=${path.resolve(outputDir, './js')}`]) .it('works when file path is passed', (ctx, done) => { expect(ctx.stdout).toContain( 'Successfully generated the following models: ' @@ -62,13 +82,23 @@ describe('models', () => { expect(ctx.stderr).toEqual(''); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'javascript', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, `-c=${path.resolve(__dirname, './models_configuration/javascript_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for Python', () => { + describe('for Python', () => { test .stderr() .stdout() - .command([...generalOptions, 'python', './test/specification.yml', `-o=${ path.resolve(outputDir, './python')}`]) + .command([...generalOptions, 'python', './test/specification.yml', `-o=${path.resolve(outputDir, './python')}`]) .it('works when file path is passed', (ctx, done) => { expect(ctx.stdout).toContain( 'Successfully generated the following models: ' @@ -76,13 +106,23 @@ describe('models', () => { expect(ctx.stderr).toEqual(''); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'python', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, `-c=${path.resolve(__dirname, './models_configuration/python_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for Rust', () => { + describe('for Rust', () => { test .stderr() .stdout() - .command([...generalOptions, 'rust', './test/specification.yml', `-o=${ path.resolve(outputDir, './rust')}`]) + .command([...generalOptions, 'rust', './test/specification.yml', `-o=${path.resolve(outputDir, './rust')}`]) .it('works when file path is passed', (ctx, done) => { expect(ctx.stdout).toContain( 'Successfully generated the following models: ' @@ -90,9 +130,19 @@ describe('models', () => { expect(ctx.stderr).toEqual(''); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'rust', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, `-c=${path.resolve(__dirname, './models_configuration/rust_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for C#', () => { + describe('for C#', () => { test .stderr() .stdout() @@ -107,19 +157,29 @@ describe('models', () => { test .stderr() .stdout() - .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${ path.resolve(outputDir, './csharp')}`]) + .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${path.resolve(outputDir, './csharp')}`]) .it('fails when no namespace provided', (ctx, done) => { expect(ctx.stderr).toEqual('Error: In order to generate models to C#, we need to know which namespace they are under. Add `--namespace=NAMESPACE` to set the desired namespace.\n'); expect(ctx.stdout).toEqual(''); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'csharp', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, '--namespace=\'test.namespace\'', `-c=${path.resolve(__dirname, './models_configuration/csharp_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for Java', () => { + describe('for Java', () => { test .stderr() .stdout() - .command([...generalOptions, 'java', './test/specification.yml', `-o=${ path.resolve(outputDir, './java')}`, '--packageName', 'test.package']) + .command([...generalOptions, 'java', './test/specification.yml', `-o=${path.resolve(outputDir, './java')}`, '--packageName', 'test.package']) .it('works when file path is passed', (ctx, done) => { expect(ctx.stderr).toEqual(''); expect(ctx.stdout).toContain( @@ -130,19 +190,29 @@ describe('models', () => { test .stderr() .stdout() - .command([...generalOptions, 'java', './test/specification.yml', `-o=${ path.resolve(outputDir, './java')}`]) + .command([...generalOptions, 'java', './test/specification.yml', `-o=${path.resolve(outputDir, './java')}`]) .it('fails when no package defined', (ctx, done) => { expect(ctx.stderr).toEqual('Error: In order to generate models to Java, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.\n'); expect(ctx.stdout).toEqual(''); done(); }); + + test + .stderr() + .stdout() + .command([...generalOptions, 'java', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, '--packageName=\'test.package\'', `-c=${path.resolve(__dirname, './models_configuration/java_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for Go', () => { + describe('for Go', () => { test .stderr() .stdout() - .command([...generalOptions, 'golang', './test/specification.yml', `-o=${ path.resolve(outputDir, './go')}`, '--packageName', 'test.package']) + .command([...generalOptions, 'golang', './test/specification.yml', `-o=${path.resolve(outputDir, './go')}`, '--packageName', 'test.package']) .it('works when file path is passed', (ctx, done) => { expect(ctx.stderr).toEqual(''); expect(ctx.stdout).toContain( @@ -153,19 +223,28 @@ describe('models', () => { test .stderr() .stdout() - .command([...generalOptions, 'golang', './test/specification.yml', `-o=${ path.resolve(outputDir, './go')}`]) + .command([...generalOptions, 'golang', './test/specification.yml', `-o=${path.resolve(outputDir, './go')}`]) .it('fails when no package defined', (ctx, done) => { expect(ctx.stderr).toEqual('Error: In order to generate models to Go, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.\n'); expect(ctx.stdout).toEqual(''); done(); }); + test + .stderr() + .stdout() + .command([...generalOptions, 'golang', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, '--packageName=\'test.package\'', `-c=${path.resolve(__dirname, './models_configuration/go_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); - describe('for Dart', () => { + describe('for Dart', () => { test .stderr() .stdout() - .command([...generalOptions, 'dart', './test/specification.yml', `-o=${ path.resolve(outputDir, './dart')}`, '--packageName', 'test.package']) + .command([...generalOptions, 'dart', './test/specification.yml', `-o=${path.resolve(outputDir, './dart')}`, '--packageName', 'test.package']) .it('works when file path is passed', (ctx, done) => { expect(ctx.stderr).toEqual(''); expect(ctx.stdout).toContain( @@ -176,11 +255,20 @@ describe('models', () => { test .stderr() .stdout() - .command([...generalOptions, 'dart', './test/specification.yml', `-o=${ path.resolve(outputDir, './dart')}`]) + .command([...generalOptions, 'dart', './test/specification.yml', `-o=${path.resolve(outputDir, './dart')}`]) .it('fails when no package defined', (ctx, done) => { expect(ctx.stderr).toEqual('Error: In order to generate models to Dart, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.\n'); expect(ctx.stdout).toEqual(''); done(); }); + test + .stderr() + .stdout() + .command([...generalOptions, 'dart', './test/specification.yml', `-o=${path.resolve(outputDir, './ts_config')}`, '--packageName=\'test.package\'', `-c=${path.resolve(__dirname, './models_configuration/dart_models.js')}`]) + .it('should handle configuration file', (ctx, done) => { + expect(ctx.stderr).toEqual(''); + expect(ctx.stdout).toMatchSnapshot(); + done(); + }); }); }); diff --git a/test/commands/generate/models_configuration/csharp_models.js b/test/commands/generate/models_configuration/csharp_models.js new file mode 100644 index 00000000000..b9f16f1c527 --- /dev/null +++ b/test/commands/generate/models_configuration/csharp_models.js @@ -0,0 +1,17 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/dart_models.js b/test/commands/generate/models_configuration/dart_models.js new file mode 100644 index 00000000000..b9f16f1c527 --- /dev/null +++ b/test/commands/generate/models_configuration/dart_models.js @@ -0,0 +1,17 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/go_models.js b/test/commands/generate/models_configuration/go_models.js new file mode 100644 index 00000000000..b9f16f1c527 --- /dev/null +++ b/test/commands/generate/models_configuration/go_models.js @@ -0,0 +1,17 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/incorrect_models.js b/test/commands/generate/models_configuration/incorrect_models.js new file mode 100644 index 00000000000..78a02bac369 --- /dev/null +++ b/test/commands/generate/models_configuration/incorrect_models.js @@ -0,0 +1,12 @@ +const {TS_COMMON_PRESET} = require('@asyncapi/modelina'); +module.exports = { + presets: [ + { + preset: TS_COMMON_PRESET, + options: { + example: true + } + } + ] +} +WRONG SYNTAX \ No newline at end of file diff --git a/test/commands/generate/models_configuration/java_models.js b/test/commands/generate/models_configuration/java_models.js new file mode 100644 index 00000000000..ce85d15baca --- /dev/null +++ b/test/commands/generate/models_configuration/java_models.js @@ -0,0 +1,23 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + typeMapping: { + Any: (context) => { + // Always map AnyModel to object + return 'object'; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/javascript_models.js b/test/commands/generate/models_configuration/javascript_models.js new file mode 100644 index 00000000000..eb5dedaf5b1 --- /dev/null +++ b/test/commands/generate/models_configuration/javascript_models.js @@ -0,0 +1,25 @@ +const {JS_COMMON_PRESET, JavaScriptOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaScriptOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + moduleSystem: 'CJS', + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ + { + preset: JS_COMMON_PRESET, + options: { + example: true + } + } + ] +} diff --git a/test/commands/generate/models_configuration/python_models.js b/test/commands/generate/models_configuration/python_models.js new file mode 100644 index 00000000000..b9f16f1c527 --- /dev/null +++ b/test/commands/generate/models_configuration/python_models.js @@ -0,0 +1,17 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/rust_models.js b/test/commands/generate/models_configuration/rust_models.js new file mode 100644 index 00000000000..b9f16f1c527 --- /dev/null +++ b/test/commands/generate/models_configuration/rust_models.js @@ -0,0 +1,17 @@ +const {JavaOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {JavaOptions} */ +module.exports = { + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + presets: [ ] +} diff --git a/test/commands/generate/models_configuration/typescript_models.js b/test/commands/generate/models_configuration/typescript_models.js new file mode 100644 index 00000000000..7317e2edd14 --- /dev/null +++ b/test/commands/generate/models_configuration/typescript_models.js @@ -0,0 +1,35 @@ +const {TS_COMMON_PRESET, TypeScriptOptions, IndentationTypes} = require('@asyncapi/modelina'); +/** @type {TypeScriptOptions} */ +module.exports = { + enumType: 'union', + modelType: 'interface', + indentation: { + size: 10, + type: IndentationTypes.SPACES + }, + mapType: 'record', + renderTypes: false, + moduleSystem: 'CJS', + constraints: { + modelName: (context) => { + return `Custom${context.modelName}`; + }, + propertyKey: (context) => { + return `custom_prop_${context.objectPropertyModel.propertyName}`; + } + }, + typeMapping: { + Any: (context) => { + // Always map AnyModel to number + return 'number'; + } + }, + presets: [ + { + preset: TS_COMMON_PRESET, + options: { + example: true + } + } + ] +} diff --git a/test/specification.yml b/test/specification.yml index 8f057c68dcf..050df4feccd 100644 --- a/test/specification.yml +++ b/test/specification.yml @@ -12,12 +12,15 @@ components: messages: UserSignedUp: payload: - type: object - properties: - displayName: - type: string - description: Name of the user - email: - type: string - format: email - description: Email of the user + $ref: '#/components/schemas/UserSignedUpPayload' + schemas: + UserSignedUpPayload: + type: object + properties: + displayName: + type: string + description: Name of the user + email: + type: string + format: email + description: Email of the user \ No newline at end of file