From 35f3dca60966ab17d0a84f5245bddf6c8146e002 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 24 Jul 2023 13:42:39 +0200 Subject: [PATCH] fix: parameter conversion for v3 (#190) --- src/third-version.ts | 54 +++++++++++++++++++ .../2.6.0/for-3.0.0-with-mixed-parameters.yml | 54 +++++++++++++++++++ .../from-2.6.0-with-custom-schema-format.yml | 4 +- .../from-2.6.0-with-deep-local-references.yml | 2 - .../from-2.6.0-with-mixed-parameters.yml | 40 ++++++++++++++ ...0-with-servers-and-channels-components.yml | 2 - test/output/3.0.0/from-2.6.0.yml | 2 - 7 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 test/input/2.6.0/for-3.0.0-with-mixed-parameters.yml create mode 100644 test/output/3.0.0/from-2.6.0-with-mixed-parameters.yml diff --git a/src/third-version.ts b/src/third-version.ts index 5327e384..406cdb21 100644 --- a/src/third-version.ts +++ b/src/third-version.ts @@ -156,6 +156,11 @@ function convertChannelObjects(channels: Record, asyncapi: AsyncAPI channel.servers = servers.map((serverName: string) => createRefObject('servers', serverName)); } + //Change parameter formats + if (isPlainObject(channel.parameters)) { + channel.parameters = convertParameters(channel.parameters); + } + const operations: Record = {}; // serialize publish and subscribe Operation Objects to standalone object const publishMessages = toStandaloneOperation({kind: 'publish', channel, asyncapi, operations, context, inComponents, channelId, channelAddress, options, oldPath}); @@ -356,8 +361,57 @@ function convertComponents(asyncapi: AsyncAPIDocument, options: RequiredConvertV messages: components.messages }); } + + if (isPlainObject(components.parameters)) { + components.parameters = convertParameters(components.parameters); + } +} +/** + * Convert all parameters to the new v3 format + */ +function convertParameters(parameters: Record): Record { + const newParameters: Record = {}; + Object.entries(parameters).forEach(([name, parameter]) => { + newParameters[name] = convertParameter(parameter); + }); + return newParameters; } +/** + * Convert the old v2 parameter object to v3. + * + * Ensure that extensions and references are all kept as is. + * + * Does not include extensions from schema. + */ +function convertParameter(parameter: any): any { + const ref = parameter['$ref'] ?? null; + if(ref !== null) { + return { + $ref: ref + } + } + + const enumValues = parameter.schema?.enum ?? null; + const defaultValues = parameter.schema?.default ?? null; + const description = parameter.description ?? parameter.schema?.description ?? null; + const examples = parameter.schema?.examples ?? null; + const location = parameter.location ?? null; + //Make sure we keep parameter extensions + const v2ParameterObjectProperties = ["location", "schema", "description"]; + const v2ParameterObjectExtensions = Object.entries(parameter).filter(([key,]) => { + return !v2ParameterObjectProperties.includes(key); + }); + + //Return the new v3 parameter object + return Object.assign({...v2ParameterObjectExtensions}, + enumValues === null ? null : {enum: enumValues}, + defaultValues === null ? null : {default: defaultValues}, + description === null ? null : {description}, + examples === null ? null : {examples}, + location === null ? null : {location} + ); +} /** * Convert `channels`, `servers` and `securitySchemes` in components. */ diff --git a/test/input/2.6.0/for-3.0.0-with-mixed-parameters.yml b/test/input/2.6.0/for-3.0.0-with-mixed-parameters.yml new file mode 100644 index 00000000..522c919c --- /dev/null +++ b/test/input/2.6.0/for-3.0.0-with-mixed-parameters.yml @@ -0,0 +1,54 @@ +asyncapi: 2.6.0 +channels: + '{enum}/{default}/{description}/{examples}/{location}/{mixed}': + publish: + operationId: lightMeasured + message: + payload: + type: string + parameters: + enum: + $ref: '#/components/parameters/enum' + default: + $ref: '#/components/parameters/default' + description: + $ref: '#/components/parameters/description' + examples: + $ref: '#/components/parameters/examples' + location: + $ref: '#/components/parameters/location' + mixed: + $ref: '#/components/parameters/mixed' +components: + parameters: + enum: + schema: + type: string + enum: ["test"] + default: + schema: + type: string + default: "test" + description: + description: Just a test description + schema: + description: Just a test description 2 + type: string + examples: + schema: + type: string + examples: ["test"] + location: + location: "$message.payload" + schema: + type: string + mixed: + location: "$message.payload" + description: Just a test description + schema: + type: string + enum: ["test"] + default: "test" + description: Just a test description 2 + examples: ["test"] + x-custom-extension: "test" \ No newline at end of file diff --git a/test/output/3.0.0/from-2.6.0-with-custom-schema-format.yml b/test/output/3.0.0/from-2.6.0-with-custom-schema-format.yml index cdb93a02..0e180e66 100644 --- a/test/output/3.0.0/from-2.6.0-with-custom-schema-format.yml +++ b/test/output/3.0.0/from-2.6.0-with-custom-schema-format.yml @@ -70,6 +70,4 @@ components: type: int parameters: streetlightId: - description: The ID of the streetlight. - schema: - type: string \ No newline at end of file + description: The ID of the streetlight. \ No newline at end of file diff --git a/test/output/3.0.0/from-2.6.0-with-deep-local-references.yml b/test/output/3.0.0/from-2.6.0-with-deep-local-references.yml index 900fdf50..aac96226 100644 --- a/test/output/3.0.0/from-2.6.0-with-deep-local-references.yml +++ b/test/output/3.0.0/from-2.6.0-with-deep-local-references.yml @@ -94,8 +94,6 @@ components: parameters: streetlightId: description: The ID of the streetlight. - schema: - type: string operations: someChannel.publish: action: receive diff --git a/test/output/3.0.0/from-2.6.0-with-mixed-parameters.yml b/test/output/3.0.0/from-2.6.0-with-mixed-parameters.yml new file mode 100644 index 00000000..44d40cbd --- /dev/null +++ b/test/output/3.0.0/from-2.6.0-with-mixed-parameters.yml @@ -0,0 +1,40 @@ +asyncapi: 3.0.0 +channels: + '{enum}/{default}/{description}/{examples}/{location}/{mixed}': + address: '{enum}/{default}/{description}/{examples}/{location}/{mixed}' + messages: + lightMeasured.message: + payload: + type: string + parameters: + enum: + $ref: '#/components/parameters/enum' + default: + $ref: '#/components/parameters/default' + description: + $ref: '#/components/parameters/description' + examples: + $ref: '#/components/parameters/examples' + location: + $ref: '#/components/parameters/location' + mixed: + $ref: '#/components/parameters/mixed' +components: + parameters: + enum: + enum: ["test"] + default: + default: "test" + description: + description: Just a test description + examples: + examples: ["test"] + location: + location: "$message.payload" + mixed: + enum: ["test"] + default: "test" + description: Just a test description + examples: ["test"] + location: "$message.payload" + x-custom-extension: "test" \ No newline at end of file diff --git a/test/output/3.0.0/from-2.6.0-with-servers-and-channels-components.yml b/test/output/3.0.0/from-2.6.0-with-servers-and-channels-components.yml index d98eb2e3..5401a259 100644 --- a/test/output/3.0.0/from-2.6.0-with-servers-and-channels-components.yml +++ b/test/output/3.0.0/from-2.6.0-with-servers-and-channels-components.yml @@ -152,8 +152,6 @@ components: parameters: streetlightId: description: The ID of the streetlight. - schema: - type: string operations: usedChannel.publish: action: receive diff --git a/test/output/3.0.0/from-2.6.0.yml b/test/output/3.0.0/from-2.6.0.yml index ad5aac63..93cdabbb 100644 --- a/test/output/3.0.0/from-2.6.0.yml +++ b/test/output/3.0.0/from-2.6.0.yml @@ -256,5 +256,3 @@ components: parameters: streetlightId: description: The ID of the streetlight. - schema: - type: string