UNPKG

openapi-modifier

Version:

This package allows you to automate the process of modifying OpenAPI specifications by applying a set of predefined rules

169 lines (168 loc) 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.configSchema = void 0; const zod_1 = require("zod"); const normilizers_1 = require("../common/utils/normilizers"); const config_1 = require("../common/config"); const refs_1 = require("../common/utils/refs"); const each_operation_1 = require("../common/utils/iterators/each-operation"); const each_schema_1 = require("../common/utils/iterators/each-schema"); const object_schema_1 = require("../common/utils/object-schema"); const deep_clone_1 = require("../common/utils/deep-clone"); const factory_1 = require("../../logger/messages/factory"); const parse_component_descriptor_1 = require("../common/utils/config/parse-component-descriptor"); const empty_1 = require("../common/utils/empty"); const parse_endpoint_descriptor_1 = require("../common/utils/config/parse-endpoint-descriptor"); const configSchema = zod_1.z .object({ ignoreComponents: zod_1.z.array(config_1.anyComponentDescriptorConfigSchema).optional(), ignoreEndpoints: zod_1.z.array(config_1.anyEndpointDescriptorConfigSchema).optional(), ignoreEndpointParameters: zod_1.z.array(config_1.parameterDescriptorConfigSchema).optional(), showDeprecatedDescriptions: zod_1.z.boolean().optional(), }) .strict(); exports.configSchema = configSchema; const processor = { configSchema, defaultConfig: {}, processDocument: (openAPIFile, config, logger) => { var _a, _b; const { ignoreComponents, ignoreEndpoints, ignoreEndpointParameters, showDeprecatedDescriptions } = config; const sourceOpenAPIFile = (0, deep_clone_1.deepClone)(openAPIFile); const parsedIgnoreComponents = ignoreComponents === null || ignoreComponents === void 0 ? void 0 : ignoreComponents.map((componentDescriptor) => { return (0, parse_component_descriptor_1.parseAnyComponentDescriptor)(componentDescriptor, logger); }).filter(empty_1.isNonNil); const parsedIgnoreEndpoints = ignoreEndpoints === null || ignoreEndpoints === void 0 ? void 0 : ignoreEndpoints.map((endpointDescriptor) => { return (0, parse_endpoint_descriptor_1.parseAnyEndpointDescriptor)(endpointDescriptor, logger); }).filter(empty_1.isNonNil); const usageIgnoreComponents = (parsedIgnoreComponents === null || parsedIgnoreComponents === void 0 ? void 0 : parsedIgnoreComponents.reduce((acc, item) => { acc[item.componentName] = 0; return acc; }, {})) || {}; const componentSchemas = (_b = (_a = openAPIFile.document) === null || _a === void 0 ? void 0 : _a.components) === null || _b === void 0 ? void 0 : _b.schemas; Object.keys(componentSchemas || {}).forEach((name) => { if (!componentSchemas) { return; } const schema = componentSchemas === null || componentSchemas === void 0 ? void 0 : componentSchemas[name]; const checkIsIgnoredComponent = ({ name }) => { if (!parsedIgnoreComponents) { return false; } const shouldIgnore = parsedIgnoreComponents.some((item) => { return item.componentName === name; }); if (!usageIgnoreComponents[name]) { usageIgnoreComponents[name] = 0; } usageIgnoreComponents[name] += 1; return shouldIgnore; }; if (!(0, refs_1.checkIsRefSchema)(schema) && (schema === null || schema === void 0 ? void 0 : schema.deprecated) && !checkIsIgnoredComponent({ name })) { logger.trace(`Deleted component - "${name}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.field(name, schema === null || schema === void 0 ? void 0 : schema.description)); } delete componentSchemas[name]; } if ((0, refs_1.checkIsRefSchema)(schema) && !checkIsIgnoredComponent({ name })) { const resolvedSchema = (0, refs_1.resolveRef)(sourceOpenAPIFile, schema); if (resolvedSchema === null || resolvedSchema === void 0 ? void 0 : resolvedSchema.deprecated) { logger.trace(`Deleted component by resolving ref - "${name}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.fieldByRef(name, resolvedSchema === null || resolvedSchema === void 0 ? void 0 : resolvedSchema.description)); } componentSchemas === null || componentSchemas === void 0 ? true : delete componentSchemas[name]; } } }); (0, each_operation_1.forEachOperation)(openAPIFile, ({ operationSchema, method, path }) => { var _a, _b, _c; const pathObjSchema = (_b = (_a = openAPIFile === null || openAPIFile === void 0 ? void 0 : openAPIFile.document) === null || _a === void 0 ? void 0 : _a.paths) === null || _b === void 0 ? void 0 : _b[path]; const checkIsIgnoredEndpoint = ({ path, method }) => { if (!parsedIgnoreEndpoints) { return false; } return parsedIgnoreEndpoints.some((item) => { return item.path === path && (0, normilizers_1.normalizeMethod)(item.method) === (0, normilizers_1.normalizeMethod)(method); }); }; if (operationSchema.deprecated && pathObjSchema && !checkIsIgnoredEndpoint({ path, method, })) { logger.trace(`Deleted endpoint - "${JSON.stringify({ path, method })}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.endpoint(method, path, (_c = pathObjSchema[method]) === null || _c === void 0 ? void 0 : _c.description)); } delete pathObjSchema[method]; } if (operationSchema === null || operationSchema === void 0 ? void 0 : operationSchema.parameters) { operationSchema.parameters = operationSchema.parameters.filter((parameter) => { const checkIsIgnoredEndpointParameter = ({ path, method, parameterName, parameterIn }) => { if (!ignoreEndpointParameters) { return false; } return ignoreEndpointParameters.some((item) => { return (item.path === path && (0, normilizers_1.normalizeMethod)(item.method) === (0, normilizers_1.normalizeMethod)(method) && item.name === parameterName && item.in === parameterIn); }); }; if (!(0, refs_1.checkIsRefSchema)(parameter) && (parameter === null || parameter === void 0 ? void 0 : parameter.deprecated) && !checkIsIgnoredEndpointParameter({ path, method, parameterName: parameter.name, parameterIn: parameter.in, })) { logger.trace(`Deleted parameter - "${JSON.stringify(parameter)}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.endpointParameter(method, path, parameter.name, parameter.in, parameter === null || parameter === void 0 ? void 0 : parameter.description)); } return false; } return true; }); } }); (0, each_schema_1.forEachSchema)(openAPIFile, (schema) => { if ((0, object_schema_1.checkIsObjectSchema)(schema)) { const properties = (schema === null || schema === void 0 ? void 0 : schema.properties) || {}; Object.keys(properties).forEach((propertyKey) => { const propertySchema = properties[propertyKey]; if (!(0, refs_1.checkIsRefSchema)(propertySchema) && (propertySchema === null || propertySchema === void 0 ? void 0 : propertySchema.deprecated)) { logger.trace(`Deleted property - "${propertyKey}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.field(propertyKey, propertySchema === null || propertySchema === void 0 ? void 0 : propertySchema.description)); } delete properties[propertyKey]; } if ((0, refs_1.checkIsRefSchema)(propertySchema)) { const resolvedPropertySchema = (0, refs_1.resolveRef)(sourceOpenAPIFile, propertySchema); if (resolvedPropertySchema === null || resolvedPropertySchema === void 0 ? void 0 : resolvedPropertySchema.deprecated) { logger.trace(`Deleted property by resolving ref - "${propertyKey}"`); if (showDeprecatedDescriptions) { logger.notImportantWarning(factory_1.messagesFactory.deprecated.fieldByRef(propertyKey, resolvedPropertySchema === null || resolvedPropertySchema === void 0 ? void 0 : resolvedPropertySchema.description)); } delete properties[propertyKey]; } } }); } }); Object.keys(usageIgnoreComponents).forEach((componentName) => { if (!usageIgnoreComponents[componentName]) { logger.warning(`Not usaged ignore component: "${componentName}"`); } }); return openAPIFile; }, }; exports.default = processor;