@redocly/cli
Version:
[@Redocly](https://redocly.com) CLI is your all-in-one API documentation utility. It builds, manages, improves, and quality-checks your API descriptions, all of which comes in handy for various phases of the API Lifecycle. Create your own rulesets to make
172 lines • 7.06 kB
JavaScript
import { isRef, dequal, logger, keysOf, } from '@redocly/openapi-core';
import { exitWithError } from '../../../utils/error.js';
import { OPENAPI3_METHOD_NAMES } from '../../split/types.js';
import { addPrefix } from './add-prefix.js';
import { addSecurityPrefix } from './add-security-prefix.js';
import { formatTags } from './format-tags.js';
import { populateTags } from './populate-tags.js';
export function collectPaths({ joinedDef, withoutXTagGroups, openapi, context, serversAreTheSame, }) {
const { apiFilename, apiTitle, api, potentialConflicts, tagsPrefix, componentsPrefix, oasVersion, } = context;
const { paths, servers: rootServers } = openapi;
const operationsSet = new Set(OPENAPI3_METHOD_NAMES);
if (paths) {
if (!joinedDef.hasOwnProperty('paths')) {
joinedDef['paths'] = {};
}
for (const path of keysOf(paths)) {
if (!joinedDef.paths.hasOwnProperty(path)) {
joinedDef.paths[path] = {};
}
if (!potentialConflicts.paths.hasOwnProperty(path)) {
potentialConflicts.paths[path] = {};
}
const pathItem = paths[path];
const servers = serversAreTheSame ? pathItem.servers : pathItem.servers || rootServers || [];
if (servers) {
collectPathServers(servers, path);
}
for (const field of keysOf(pathItem)) {
if (operationsSet.has(field)) {
collectPathOperation(pathItem, path, field);
}
if (field === 'parameters') {
collectPathParameters(pathItem, path);
}
if (typeof pathItem[field] === 'string') {
collectPathStringFields(pathItem, path, field);
}
}
}
}
function collectPathStringFields(pathItem, path, field) {
const fieldValue = pathItem[field];
if (joinedDef.paths[path].hasOwnProperty(field) &&
joinedDef.paths[path][field] !== fieldValue) {
logger.warn(`warning: different ${field} values in ${path}\n`);
return;
}
joinedDef.paths[path][field] = fieldValue;
}
function collectPathServers(servers, path) {
if (!servers) {
return;
}
if (!joinedDef.paths[path].hasOwnProperty('servers')) {
joinedDef.paths[path].servers = [];
}
for (const server of servers) {
let isFoundServer = false;
for (const pathServer of joinedDef.paths[path].servers) {
if (pathServer.url === server.url) {
if (!isServersEqual(pathServer, server)) {
exitWithError(`Different server values for (${server.url}) in ${path}.`);
}
isFoundServer = true;
}
}
if (!isFoundServer) {
joinedDef.paths[path].servers.push(server);
}
}
}
function collectPathParameters(pathItem, path) {
if (!pathItem.parameters) {
return;
}
if (!joinedDef.paths[path].hasOwnProperty('parameters')) {
joinedDef.paths[path].parameters = [];
}
for (const parameter of pathItem.parameters) {
let isFoundParameter = false;
for (const pathParameter of joinedDef.paths[path].parameters) {
// Compare $ref only if both are reference objects
if (isRef(pathParameter) && isRef(parameter)) {
if (pathParameter['$ref'] === parameter['$ref']) {
isFoundParameter = true;
}
}
// Compare properties only if both are reference objects
if (!isRef(pathParameter) && !isRef(parameter)) {
if (pathParameter.name === parameter.name && pathParameter.in === parameter.in) {
if (!dequal(pathParameter.schema, parameter.schema)) {
exitWithError(`Different parameter schemas for (${parameter.name}) in ${path}.`);
}
isFoundParameter = true;
}
}
}
if (!isFoundParameter) {
joinedDef.paths[path].parameters.push(parameter);
}
}
}
function collectPathOperation(pathItem, path, operation) {
const pathOperation = pathItem[operation];
if (!pathOperation) {
return;
}
joinedDef.paths[path][operation] = pathOperation;
potentialConflicts.paths[path][operation] = [
...(potentialConflicts.paths[path][operation] || []),
api,
];
const { operationId } = pathOperation;
if (operationId) {
if (!potentialConflicts.paths.hasOwnProperty('operationIds')) {
potentialConflicts.paths['operationIds'] = {};
}
potentialConflicts.paths.operationIds[operationId] = [
...(potentialConflicts.paths.operationIds[operationId] || []),
api,
];
}
const { tags, security } = joinedDef.paths[path][operation];
if (tags) {
joinedDef.paths[path][operation].tags = tags.map((tag) => addPrefix(tag, tagsPrefix));
populateTags({
joinedDef,
withoutXTagGroups,
context: {
api,
apiFilename,
apiTitle,
tags: formatTags(tags),
potentialConflicts,
tagsPrefix,
componentsPrefix,
oasVersion,
},
});
}
else {
joinedDef.paths[path][operation]['tags'] = [addPrefix('other', tagsPrefix || apiFilename)];
populateTags({
joinedDef,
withoutXTagGroups,
context: {
api,
apiFilename,
apiTitle,
tags: formatTags(['other']),
potentialConflicts,
tagsPrefix: tagsPrefix || apiFilename,
componentsPrefix,
oasVersion,
},
});
}
if (!security && openapi.hasOwnProperty('security')) {
joinedDef.paths[path][operation]['security'] = addSecurityPrefix(openapi.security, componentsPrefix);
}
else if (pathOperation.security) {
joinedDef.paths[path][operation].security = addSecurityPrefix(pathOperation.security, componentsPrefix);
}
}
}
function isServersEqual(serverOne, serverTwo) {
if (serverOne.description === serverTwo.description) {
return dequal(serverOne.variables, serverTwo.variables);
}
return false;
}
//# sourceMappingURL=collect-paths.js.map