Skip to content

Commit

Permalink
feat(ns-openapi-3-1): add servers normalization refractor plugin (#2372)
Browse files Browse the repository at this point in the history
Refs #2362
  • Loading branch information
char0n authored Dec 14, 2022
1 parent 7c451e1 commit 3f7b8cc
Show file tree
Hide file tree
Showing 6 changed files with 851 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/apidom-ns-openapi-3-1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export { default } from './namespace';
export { default as refractorPluginReplaceEmptyElement } from './refractor/plugins/replace-empty-element';
export { default as refractorPluginNormalizeParameters } from './refractor/plugins/normalize-parameters';
export { default as refractorPluginNormalizeSecurityRequirements } from './refractor/plugins/normalize-security-requirements';
export { default as refractorPluginNormalizeServers } from './refractor/plugins/normalize-servers';

export {
isCallbackElement,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { last } from 'ramda';
import { isArrayElement } from '@swagger-api/apidom-core';
import {
PathItemServersElement,
OperationServersElement,
} from '@swagger-api/apidom-ns-openapi-3-0';

import OpenApi3_1Element from '../../elements/OpenApi3-1';
import PathItemElement from '../../elements/PathItem';
import ServerElement from '../../elements/Server';
import OperationElement from '../../elements/Operation';
import { isComponentsElement } from '../../predicates';

/**
* Override of Server Objects.
*
* List of Server Objects can be defined in OpenAPI 3.1 on multiple levels:
*
* - OpenAPI.servers
* - PathItem.servers
* - Operation.servers
*
* If an alternative server object is specified at the Path Item Object level, it will override OpenAPI.servers.
* If an alternative server object is specified at the Operation Object level, it will override PathItem.servers and OpenAPI.servers respectively.
*/

/* eslint-disable no-param-reassign */
const plugin = () => () => {
let openAPIServers: ServerElement[] | undefined;
const pathItemServers: (ServerElement[] | undefined)[] = [];

return {
visitor: {
OpenApi3_1Element: {
enter(openapiElement: OpenApi3_1Element) {
if (isArrayElement(openapiElement.servers)) {
openAPIServers = openapiElement.servers?.content as ServerElement[];
}
},
leave() {
openAPIServers = undefined;
},
},
PathItemElement: {
enter(
pathItemElement: PathItemElement,
key: any,
parent: any,
path: any,
ancestors: any[],
) {
// skip visiting this Path Item
if (ancestors.some(isComponentsElement)) {
return false;
}

// duplicate OpenAPI.servers into this Path Item object
if (
typeof pathItemElement.servers === 'undefined' &&
typeof openAPIServers !== 'undefined'
) {
pathItemElement.servers = new PathItemServersElement(openAPIServers);
}

// prepare Server Objects for child Operation Objects
const { servers } = pathItemElement;
if (typeof servers !== 'undefined' && isArrayElement(servers)) {
pathItemServers.push([...servers.content] as ServerElement[]);
} else {
pathItemServers.push(undefined);
}

return undefined;
},
leave() {
pathItemServers.pop();
},
},
OperationElement: {
enter(operationElement: OperationElement) {
const parentPathItemServers = last(pathItemServers);

// no Server Objects defined in parents
if (typeof parentPathItemServers === 'undefined') return;
// Server Objects are defined for this Operation Object
if (isArrayElement(operationElement.servers)) return;

// duplicate parent PathItem.servers into this Operation object
operationElement.servers = new OperationServersElement(parentPathItemServers);
},
},
},
};
};
/* eslint-enable */

export default plugin;
Loading

0 comments on commit 3f7b8cc

Please sign in to comment.