Skip to content

Commit

Permalink
refactor to use empty asyncAPI object and to seperate version of asyn…
Browse files Browse the repository at this point in the history
…capi and openapi
  • Loading branch information
Gmin2 committed Jul 1, 2024
1 parent b16a8c4 commit fcd73bd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 65 deletions.
12 changes: 6 additions & 6 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { converters as openapiConverters } from "./openapi";

import { serializeInput } from "./utils";

import type { AsyncAPIDocument, ConvertVersion, ConvertOptions, ConvertFunction, ConvertOpenAPIFunction, OpenAPIDocument } from './interfaces';
import type { AsyncAPIDocument, AsyncAPIConvertVersion, OpenAPIConvertVersion, ConvertOptions, ConvertFunction, ConvertOpenAPIFunction, OpenAPIDocument } from './interfaces';

/**
* Value for key (version) represents the function which converts specification from previous version to the given as key.
Expand All @@ -20,9 +20,9 @@ const asyncAPIconverters: Record<string, ConvertFunction> = {

const conversionVersions = Object.keys(asyncAPIconverters);

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 {
export function convert(input: string, version: AsyncAPIConvertVersion, options?: ConvertOptions): string;
export function convert(input: AsyncAPIDocument, version: AsyncAPIConvertVersion, options?: ConvertOptions): AsyncAPIDocument;
export function convert(input: string | AsyncAPIDocument, version: AsyncAPIConvertVersion , options: ConvertOptions= {}): string | AsyncAPIDocument {
const { format, document } = serializeInput(input);

if ('openapi' in document) {
Expand All @@ -47,7 +47,7 @@ export function convert(input: string | AsyncAPIDocument, version: ConvertVersio
fromVersion++;
let converted = document;
for (let i = fromVersion; i <= toVersion; i++) {
const v = conversionVersions[i] as ConvertVersion;
const v = conversionVersions[i] as AsyncAPIConvertVersion;
converted = asyncAPIconverters[v](converted, options);
}

Expand All @@ -63,7 +63,7 @@ export function convertOpenAPI(input: string | OpenAPIDocument,options: ConvertO

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

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

if (!openapiToAsyncapiConverter) {
throw new Error("OpenAPI to AsyncAPI converter is not available.");
Expand Down
4 changes: 3 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
*/
export type AsyncAPIDocument = { asyncapi: string } & Record<string, any>;
export type OpenAPIDocument = { openapi: string } & Record<string, any>;
export type ConvertVersion = '1.1.0' | '1.2.0' | '2.0.0-rc1' | '2.0.0-rc2' | '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0' | '2.5.0' | '2.6.0' | '3.0.0' | 'openapi';
export type AsyncAPIConvertVersion = '1.1.0' | '1.2.0' | '2.0.0-rc1' | '2.0.0-rc2' | '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0' | '2.5.0' | '2.6.0' | '3.0.0';
// for now it is hardcoded to 'openapi' but in the future it can be extended to support multiple versions
export type OpenAPIConvertVersion = 'openapi';
export type ConvertV2ToV3Options = {
idGenerator?: (data: { asyncapi: AsyncAPIDocument, kind: 'channel' | 'operation' | 'message', key: string | number | undefined, path: Array<string | number>, object: any, parentId?: string }) => string,
pointOfView?: 'application' | 'client',
Expand Down
114 changes: 56 additions & 58 deletions src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,25 @@ export const converters: Record<string, ConvertOpenAPIFunction > = {
'openapi': from_openapi_to_asyncapi,
}

function from_openapi_to_asyncapi(openapi: OpenAPIDocument, options: ConvertOptions): AsyncAPIDocument{
convertName(openapi)
function from_openapi_to_asyncapi(openapi: OpenAPIDocument, options?: ConvertOptions): AsyncAPIDocument {
const asyncapi: Partial<AsyncAPIDocument> = {
asyncapi: openapi.openapi,
info: convertInfoObject(openapi.info, openapi),
servers: isPlainObject(openapi.servers[0]) ? convertServerObjects(openapi.servers, openapi) : undefined,
};

convertInfoObject(openapi);
if (isPlainObject(openapi.servers)) {
openapi.servers = convertServerObjects(openapi.servers, openapi);
}

return sortObjectKeys(
openapi,
['asyncapi', 'info', 'defaultContentType', 'servers', 'channels', 'operations', 'components']
)
}

function convertName(openapi: OpenAPIDocument): AsyncAPIDocument {
let { openapi: version } = openapi;
openapi.asyncapi = version;
delete (openapi as any).openapi;;

return sortObjectKeys(
openapi,
['asyncapi', 'info', 'defaultContentType', 'servers', 'channels', 'operations', 'components']
)
return sortObjectKeys(
asyncapi as AsyncAPIDocument,
['asyncapi', 'info', 'defaultContentType', 'servers', 'channels', 'operations', 'components']
);
}

function convertInfoObject(openapi: OpenAPIDocument) {
if(openapi.tags) {
openapi.info.tags = openapi.tags;
delete openapi.tags;
}

if(openapi.externalDocs) {
openapi.info.externalDocs = openapi.externalDocs;
delete openapi.externalDocs;
}

return (openapi.info = sortObjectKeys(openapi.info, [
function convertInfoObject(info: OpenAPIDocument['info'], openapi: OpenAPIDocument): AsyncAPIDocument['info'] {
return sortObjectKeys({
...info,
tags: openapi.tags || undefined,
externalDocs: openapi.externalDocs || undefined,
}, [
"title",
"version",
"description",
Expand All @@ -50,10 +32,10 @@ function convertInfoObject(openapi: OpenAPIDocument) {
"license",
"tags",
"externalDocs",
]));
}
]);
}

function convertServerObjects(servers: Record<string, any>, openapi: OpenAPIDocument) {
function convertServerObjects(servers: Record<string, any>, openapi: OpenAPIDocument): AsyncAPIDocument['servers'] {
const newServers: Record<string, any> = {};
const security: Record<string, any> = openapi.security;
Object.entries(servers).forEach(([serverName, server]: [string, any]) => {
Expand All @@ -77,43 +59,59 @@ function convertServerObjects(servers: Record<string, any>, openapi: OpenAPIDocu
server.security = security;
delete openapi.security;
}

newServers[serverName] = sortObjectKeys(
server,
['host', 'pathname', 'protocol', 'protocolVersion', 'title', 'summary', 'description', 'variables', 'security', 'tags', 'externalDocs', 'bindings'],
);
});
return newServers

return newServers;
}

function resolveServerUrl(url: string): {
host: string;
pathname: string | undefined;
protocol: string | undefined;
pathname?: string;
protocol: string;
} {
let [maybeProtocol, maybeHost] = url.split("://");
console.log("maybeProtocol", maybeProtocol);
console.log("maybeProtocol", maybeProtocol, "maybeshost:", maybeHost)
if (!maybeHost) {
maybeHost = maybeProtocol;
maybeHost = maybeProtocol;
}
const [host, ...pathnames] = maybeHost.split("/");
console.log("pathname1", pathnames);
console.log("host", host, "pathnames", pathnames)
console.log(`/${pathnames.join("/")}`)
if (pathnames.length) {
return {
host,
pathname: `/${pathnames.join("/")}`,
protocol: maybeProtocol,
};
return {
host,
pathname: `/${pathnames.join("/")}`,
protocol: maybeProtocol,
};
}
return { host, pathname: undefined, protocol: maybeProtocol };
return { host, pathname: undefined , protocol: maybeProtocol };
}

function convertSecurity(security: Record<string, any>) {
if(security.type === 'oauth2' && security.flows.authorizationCode.scopes) {
const availableScopes = security.flows.authorizationCode.scopes;
security.flows.authorizationCode.availableScopes = availableScopes;
delete security.flows.authorizationCode.scopes;
}
return security;
function convertSecurity(security: Record<string, any>): Record<string, any> {
return security.map((securityRequirement: Record<string, any>) => {
const newSecurityRequirement: Record<string, any> = {};
Object.entries(securityRequirement).forEach(([key, value]) => {
if (value.type === 'oauth2' && value.flows.authorizationCode?.scopes) {
newSecurityRequirement[key] = {
...value,
flows: {
...value.flows,
authorizationCode: {
...value.flows.authorizationCode,
availableScopes: value.flows.authorizationCode.scopes,
},
},
};
delete newSecurityRequirement[key].flows.authorizationCode.scopes;
} else {
newSecurityRequirement[key] = value;
}
});
return newSecurityRequirement;
});
}

0 comments on commit fcd73bd

Please sign in to comment.