Skip to content

Commit

Permalink
refactor the code to use convertOpenAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
Gmin2 committed Jun 27, 2024
1 parent e258575 commit b16a8c4
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 70 deletions.
48 changes: 27 additions & 21 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,21 @@ import type { AsyncAPIDocument, ConvertVersion, ConvertOptions, ConvertFunction,
/**
* Value for key (version) represents the function which converts specification from previous version to the given as key.
*/
const converters: Record<string, ConvertFunction | ConvertOpenAPIFunction> = {
const asyncAPIconverters: Record<string, ConvertFunction> = {
...firstConverters,
...secondConverters,
...thirdConverters,
...openapiConverters,
};

const conversionVersions = Object.keys(converters);
const conversionVersions = Object.keys(asyncAPIconverters);

function convertOpenAPIToAsyncAPI(openapiDocument: OpenAPIDocument | AsyncAPIDocument, options: ConvertOptions): AsyncAPIDocument {
const openapiToAsyncapiConverter = converters['openapi'];
if (openapiToAsyncapiConverter) {
return openapiToAsyncapiConverter(openapiDocument as any, options) as AsyncAPIDocument;
} else {
throw new Error(`Unsupported OpenAPI version. This converter only supports OpenAPI 3.0.`);
}
}

// export function convert(input: string, version?: ConvertVersion, options?: ConvertOptions): string;
// export function convert(input: AsyncAPIDocument, version?: ConvertVersion, options?: ConvertOptions): AsyncAPIDocument;
export function convert(input: string | AsyncAPIDocument | OpenAPIDocument, version: ConvertVersion , options: ConvertOptions= {}): string | AsyncAPIDocument | OpenAPIDocument {
export function convert(input: string, version: ConvertVersion, options?: ConvertOptions): string;
export function convert(input: AsyncAPIDocument, version: ConvertVersion, options?: ConvertOptions): AsyncAPIDocument;
export function convert(input: string | AsyncAPIDocument, version: ConvertVersion , options: ConvertOptions= {}): string | AsyncAPIDocument {
const { format, document } = serializeInput(input);

if ('openapi' in document) {
let convertedAsyncAPI = convertOpenAPIToAsyncAPI(document, options);
return format === 'yaml' ? dump(convertedAsyncAPI, { skipInvalid: true }) : convertedAsyncAPI;
throw new Error('Cannot convert OpenAPI document. Use convertOpenAPI function instead.');
}

const asyncapiVersion = document.asyncapi;
Expand All @@ -59,14 +48,31 @@ export function convert(input: string | AsyncAPIDocument | OpenAPIDocument, vers
let converted = document;
for (let i = fromVersion; i <= toVersion; i++) {
const v = conversionVersions[i] as ConvertVersion;
const convertFunction = converters[v];
converted = ('asyncapi' in converted)
? (convertFunction as ConvertFunction)(converted as AsyncAPIDocument, options)
: (convertFunction as ConvertOpenAPIFunction)(converted as OpenAPIDocument, options);
converted = asyncAPIconverters[v](converted, options);
}

if (format === 'yaml') {
return dump(converted, { skipInvalid: true });
}
return converted;
}

export function convertOpenAPI(input: string ,options?: ConvertOptions): string;
export function convertOpenAPI(input: OpenAPIDocument ,options?: ConvertOptions): AsyncAPIDocument;
export function convertOpenAPI(input: string | OpenAPIDocument,options: ConvertOptions = {}): string | AsyncAPIDocument {

const { format, document } = serializeInput(input);

const openapiToAsyncapiConverter = openapiConverters["openapi"] as ConvertOpenAPIFunction;

if (!openapiToAsyncapiConverter) {
throw new Error("OpenAPI to AsyncAPI converter is not available.");
}

const convertedAsyncAPI = openapiToAsyncapiConverter(document as OpenAPIDocument, options);

if (format === "yaml") {
return dump(convertedAsyncAPI, { skipInvalid: true });
}
return convertedAsyncAPI;
}
1 change: 0 additions & 1 deletion src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ function convertInfoObject(openapi: OpenAPIDocument) {
}

function convertServerObjects(servers: Record<string, any>, openapi: OpenAPIDocument) {
console.log("security",openapi.security)
const newServers: Record<string, any> = {};
const security: Record<string, any> = openapi.security;
Object.entries(servers).forEach(([serverName, server]: [string, any]) => {
Expand Down
3 changes: 2 additions & 1 deletion test/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
It is a helper required for testing on windows. It can't be solved by editor configuration and the end line setting because expected result is converted during tests.
We need to remove all line breaks from the string
as well as all multiple spaces and trim the string.
*/
export function removeLineBreaks(str: string) {
return str.replace(/\r?\n|\r/g, '')
return str.replace(/\r?\n|\r/g, '').replace(/\s+/g, ' ').trim();
}

export function assertResults(output: string, result: string){
Expand Down
38 changes: 19 additions & 19 deletions test/input/openapi/no-channel-operation.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
openapi: '3.0.0'
openapi: 3.0.0
info:
title: Sample Pet Store App
description: This is a sample server for a pet store.
termsOfService: http://example.com/terms/
termsOfService: 'http://example.com/terms/'
contact:
name: API Support
url: http://www.example.com/support
url: 'http://www.example.com/support'
email: support@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
version: 1.0.1

servers:
- url: https://{username}.gigantic-server.com:{port}/{basePath}
description: The production API server
variables:
username:
default: demo
description: this value is assigned by the service provider, in this example `gigantic-server.com`
port:
enum:
- '8443'
- '443'
default: '8443'
basePath:
default: v2

- url: 'https://{username}.gigantic-server.com:{port}/{basePath}'
description: The production API server
variables:
username:
default: demo
description: this value is assigned by the service provider, in this example `gigantic-server.com`
port:
enum:
- '8443'
- '443'
default: '8443'
basePath:
default: v2
security:
- {}
- petstore_auth:
Expand All @@ -39,4 +39,4 @@ tags:

externalDocs:
description: Find more info here
url: https://example.com
url: 'https://example.com'
6 changes: 3 additions & 3 deletions test/openapi-to-asyncapi.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import fs from 'fs';
import path from 'path';

import { convert } from '../src/convert';
import { convertOpenAPI } from '../src/convert';
import { assertResults } from './helpers';

describe("convert() - openapi to asyncapi", () => {
it("should convert the basic structure of openapi to asyncapi", () => {
const input = fs.readFileSync(path.resolve(__dirname, "input", "openapi", "no-channel-parameter.yml"), "utf8");
const input = fs.readFileSync(path.resolve(__dirname, "input", "openapi", "no-channel-operation.yml"), "utf8");
const output = fs.readFileSync(path.resolve(__dirname, "output", "openapi-to-asyncapi", "no-channel-parameter.yml"), "utf8");
const result = convert(input, '3.0.0');
const result = convertOpenAPI(input);
assertResults(output, result);
});
});
42 changes: 42 additions & 0 deletions test/output/openapi-to-asyncapi/no-channel-parameter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
asyncapi: 3.0.0
info:
title: Sample Pet Store App
version: 1.0.1
description: This is a sample server for a pet store.
termsOfService: 'http://example.com/terms/'
contact:
name: API Support
url: 'http://www.example.com/support'
email: support@example.com
license:
name: Apache 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
name: pet
description: Pets operations
externalDocs:
description: Find more info here
url: 'https://example.com'

servers:
- url: 'https://{username}.gigantic-server.com:{port}/{basePath}'
description: The production API server
variables:
username:
default: demo
description: >-
this value is assigned by the service provider, in this example
`gigantic-server.com`
port:
enum:
- '8443'
- '443'
default: '8443'
basePath:
default: v2

security:
- {}
- petstore_auth:
- 'write:pets'
- 'read:pets'
25 changes: 0 additions & 25 deletions test/output/openapi_to_asyncapi/no-channel-parameter.yml

This file was deleted.

0 comments on commit b16a8c4

Please sign in to comment.