1 | "use strict";
|
---|
2 |
|
---|
3 | exports.__esModule = true;
|
---|
4 | exports.default = void 0;
|
---|
5 | var _ramda = require("ramda");
|
---|
6 | var _apidomCore = require("@swagger-api/apidom-core");
|
---|
7 | const removeSpaces = operationId => {
|
---|
8 | return operationId.replace(/\s/g, '');
|
---|
9 | };
|
---|
10 | const replaceSpecialCharsWithUnderscore = operationId => {
|
---|
11 | return operationId.replace(/\W/gi, '_');
|
---|
12 | };
|
---|
13 | const createNormalizedOperationId = (path, method) => {
|
---|
14 | const normalizedMethod = replaceSpecialCharsWithUnderscore(removeSpaces(method.toLowerCase()));
|
---|
15 | const normalizedPath = replaceSpecialCharsWithUnderscore(removeSpaces(path));
|
---|
16 | return `${normalizedMethod}${normalizedPath}`;
|
---|
17 | };
|
---|
18 | const normalizeOperationId = (operationId, path, method) => {
|
---|
19 | const withoutSpaces = removeSpaces(operationId);
|
---|
20 | if (withoutSpaces.length > 0) {
|
---|
21 | return replaceSpecialCharsWithUnderscore(withoutSpaces);
|
---|
22 | }
|
---|
23 | return createNormalizedOperationId(path, method);
|
---|
24 | };
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * Normalization of Operation.operationId field.
|
---|
28 | *
|
---|
29 | * This normalization is not guided by OpenAPI 3.1 specification.
|
---|
30 | *
|
---|
31 | * Existing Operation.operationId fields are normalized into snake case form.
|
---|
32 | *
|
---|
33 | * Operation Objects, that do not define operationId field, are left untouched.
|
---|
34 | *
|
---|
35 | * Original operationId is stored in meta and as new `__originalOperationId` field.
|
---|
36 | *
|
---|
37 | * This plugin also guarantees the uniqueness of all defined Operation.operationId fields,
|
---|
38 | * and make sure Link.operationId fields are pointing to correct and normalized Operation.operationId fields.
|
---|
39 | *
|
---|
40 | */
|
---|
41 | /* eslint-disable no-param-reassign */
|
---|
42 |
|
---|
43 | const plugin = ({
|
---|
44 | operationIdNormalizer = normalizeOperationId
|
---|
45 | } = {}) => ({
|
---|
46 | predicates,
|
---|
47 | namespace
|
---|
48 | }) => {
|
---|
49 | const paths = [];
|
---|
50 | const normalizedOperations = [];
|
---|
51 | const links = [];
|
---|
52 | return {
|
---|
53 | visitor: {
|
---|
54 | OpenApi3_1Element: {
|
---|
55 | leave() {
|
---|
56 | // group normalized operations by normalized operationId
|
---|
57 | const normalizedOperationGroups = (0, _ramda.groupBy)(operationElement => {
|
---|
58 | return (0, _apidomCore.toValue)(operationElement.operationId);
|
---|
59 | }, normalizedOperations);
|
---|
60 |
|
---|
61 | // append incremental numerical suffixes to identical operationIds
|
---|
62 | Object.entries(normalizedOperationGroups).forEach(([normalizedOperationId, operationElements]) => {
|
---|
63 | if (!Array.isArray(operationElements)) return;
|
---|
64 | if (operationElements.length <= 1) return;
|
---|
65 | operationElements.forEach((operationElement, index) => {
|
---|
66 | const indexedNormalizedOperationId = `${normalizedOperationId}${index + 1}`;
|
---|
67 | // @ts-ignore
|
---|
68 | operationElement.operationId = new namespace.elements.String(indexedNormalizedOperationId);
|
---|
69 | });
|
---|
70 | });
|
---|
71 |
|
---|
72 | // rectify possibly broken Link.operationId fields
|
---|
73 | links.forEach(linkElement => {
|
---|
74 | if (typeof linkElement.operationId === 'undefined') return;
|
---|
75 | const linkOperationId = String((0, _apidomCore.toValue)(linkElement.operationId));
|
---|
76 | const operationElement = normalizedOperations.find(normalizedOperationElement => {
|
---|
77 | const originalOperationId = (0, _apidomCore.toValue)(normalizedOperationElement.meta.get('originalOperationId'));
|
---|
78 | return originalOperationId === linkOperationId;
|
---|
79 | });
|
---|
80 |
|
---|
81 | // Link Object doesn't need to be rectified
|
---|
82 | if (typeof operationElement === 'undefined') return;
|
---|
83 | linkElement.operationId = _apidomCore.cloneDeep.safe(operationElement.operationId);
|
---|
84 | linkElement.meta.set('originalOperationId', linkOperationId);
|
---|
85 | linkElement.set('__originalOperationId', linkOperationId);
|
---|
86 | });
|
---|
87 |
|
---|
88 | // cleanup the references
|
---|
89 | normalizedOperations.length = 0;
|
---|
90 | links.length = 0;
|
---|
91 | }
|
---|
92 | },
|
---|
93 | PathItemElement: {
|
---|
94 | enter(pathItemElement) {
|
---|
95 | // `path` meta may not be always available, e.g. in Callback Object or Components Object
|
---|
96 | const path = (0, _ramda.defaultTo)('path', (0, _apidomCore.toValue)(pathItemElement.meta.get('path')));
|
---|
97 | paths.push(path);
|
---|
98 | },
|
---|
99 | leave() {
|
---|
100 | paths.pop();
|
---|
101 | }
|
---|
102 | },
|
---|
103 | OperationElement: {
|
---|
104 | enter(operationElement) {
|
---|
105 | // operationId field is undefined, needs no normalization
|
---|
106 | if (typeof operationElement.operationId === 'undefined') return;
|
---|
107 |
|
---|
108 | // cast operationId to string type
|
---|
109 | const originalOperationId = String((0, _apidomCore.toValue)(operationElement.operationId));
|
---|
110 | // perform operationId normalization
|
---|
111 | const path = (0, _ramda.last)(paths);
|
---|
112 | // `http-method` meta may not be always available, e.g. in Callback Object or Components Object
|
---|
113 | const method = (0, _ramda.defaultTo)('method', (0, _apidomCore.toValue)(operationElement.meta.get('http-method')));
|
---|
114 | const normalizedOperationId = operationIdNormalizer(originalOperationId, path, method);
|
---|
115 |
|
---|
116 | // normalization is not necessary
|
---|
117 | if (originalOperationId === normalizedOperationId) return;
|
---|
118 |
|
---|
119 | // @ts-ignore
|
---|
120 | operationElement.operationId = new namespace.elements.String(normalizedOperationId);
|
---|
121 | operationElement.set('__originalOperationId', originalOperationId);
|
---|
122 | operationElement.meta.set('originalOperationId', originalOperationId);
|
---|
123 | normalizedOperations.push(operationElement);
|
---|
124 | }
|
---|
125 | },
|
---|
126 | LinkElement: {
|
---|
127 | leave(linkElement) {
|
---|
128 | // make sure this Link elements doesn't come from base namespace
|
---|
129 | if (!predicates.isLinkElement(linkElement)) return;
|
---|
130 | // ignore Link Objects with undefined operationId
|
---|
131 | if (typeof linkElement.operationId === 'undefined') return;
|
---|
132 | links.push(linkElement);
|
---|
133 | }
|
---|
134 | }
|
---|
135 | }
|
---|
136 | };
|
---|
137 | };
|
---|
138 | /* eslint-enable */
|
---|
139 | var _default = exports.default = plugin; |
---|