Skip to content

Commit

Permalink
refactor(converter): allow plugins to perform mutable operations (#3812)
Browse files Browse the repository at this point in the history
This change will make plugins creation much simpler.
ApiDOM is deep cloned before the plugins touch it.
That way from outside, the converter still remains
immutable, but the plugins work in mutable way.
  • Loading branch information
char0n authored Feb 12, 2024
1 parent bf6702a commit 42b78bc
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ParseResultElement,
dispatchRefractorPlugins,
AnnotationElement,
cloneShallow,
cloneDeep,
} from '@swagger-api/apidom-core';

import ConvertStrategy, { IFile } from '../ConvertStrategy';
Expand Down Expand Up @@ -53,22 +53,20 @@ class OpenAPI31ToOpenAPI30ConvertStrategy extends ConvertStrategy {
}

async convert(file: IFile): Promise<ParseResultElement> {
const parseResultElement = file.parseResult;
const annotations: AnnotationElement[] = [];
const converted = dispatchRefractorPlugins(
parseResultElement,
const parseResultElement = dispatchRefractorPlugins(
cloneDeep(file.parseResult),
[openAPIVersionRefractorPlugin(), webhooksRefractorPlugin({ annotations })],
{
toolboxCreator: createToolbox,
visitorOptions: { keyMap, nodeTypeGetter: getNodeType },
},
);

const annotated = cloneShallow(converted);
annotations.forEach((a) => annotated.push(a));
annotated.replaceResult(OpenApi3_0Element.refract(converted.api));
annotations.forEach((a) => parseResultElement.push(a));
parseResultElement.replaceResult(OpenApi3_0Element.refract(parseResultElement.api));

return annotated;
return parseResultElement;
}
}
/* eslint-enable class-methods-use-this */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"no-param-reassign": 0
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { OpenapiElement as Openapi30Element } from '@swagger-api/apidom-ns-openapi-3-0';
import { OpenapiElement } from '@swagger-api/apidom-ns-openapi-3-1';

const openAPIVersionRefractorPlugin = () => () => ({
visitor: {
OpenapiElement() {
return new Openapi30Element('3.0.3');
OpenapiElement(element: OpenapiElement) {
(element.content as unknown as string) = '3.0.3';
},
},
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import { OpenApi3_1Element } from '@swagger-api/apidom-ns-openapi-3-1';
import { AnnotationElement, cloneShallow } from '@swagger-api/apidom-core';
import { AnnotationElement } from '@swagger-api/apidom-core';

type WebhooksRefractorPluginOptions = {
annotations: AnnotationElement[];
};

const webhooksRefractorPlugin =
({ annotations }: WebhooksRefractorPluginOptions) =>
() => ({
visitor: {
OpenApi3_1Element(element: OpenApi3_1Element) {
if (!element.hasKey('webhooks')) return undefined;
() => {
const annotation = new AnnotationElement(
'Webhooks are not supported in OpenAPI 3.0.3. They will be removed from the converted document.',
{ classes: ['warning'] },
{ code: 'webhooks' },
);

const copy = cloneShallow(element);
const annotation = new AnnotationElement(
'Webhooks are not supported in OpenAPI 3.0.3. They will be removed from the converted document.',
{ classes: ['warning'] },
{ code: 'webhooks' },
);
return {
visitor: {
OpenApi3_1Element(element: OpenApi3_1Element) {
if (!element.hasKey('webhooks')) return undefined;

annotations.push(annotation);
copy.remove('webhooks');
annotations.push(annotation);
element.remove('webhooks');

return copy;
return undefined;
},
},
},
});
};
};

export default webhooksRefractorPlugin;

0 comments on commit 42b78bc

Please sign in to comment.