UNPKG

openapi-modifier

Version:

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

102 lines (101 loc) 4.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.configSchema = void 0; const zod_1 = require("zod"); const each_schema_1 = require("../common/utils/iterators/each-schema"); const config_1 = require("../common/config"); const parse_component_descriptor_1 = require("../common/utils/config/parse-component-descriptor"); const empty_1 = require("../common/utils/empty"); const configSchema = zod_1.z .object({ ignore: zod_1.z.array(zod_1.z.union([ config_1.simpleComponentDescriptorConfigSchema, config_1.componentDescriptorConfigSchema, zod_1.z.instanceof(RegExp), ])).optional(), printDeletedComponents: zod_1.z.boolean().optional(), }) .strict(); exports.configSchema = configSchema; const REF_SEPARATOR = '/'; const shortenRef = (ref) => { return ref.split(REF_SEPARATOR).slice(0, 4).join(REF_SEPARATOR); }; const processor = { configSchema, defaultConfig: {}, processDocument: (openAPIFile, config, logger) => { const { ignore, printDeletedComponents } = config; const ignoredComponentRegExps = (ignore || []).map(item => { if (item instanceof RegExp) { return item; } return null; }).filter(empty_1.isNonNil); const ignoredComponentNames = (ignore || []).map(item => { if (item instanceof RegExp) { return null; } return (0, parse_component_descriptor_1.parseAnyComponentDescriptor)(item, logger); }).map(componentDescriptor => componentDescriptor === null || componentDescriptor === void 0 ? void 0 : componentDescriptor.componentName).filter(empty_1.isNonNil); logger.trace(`Ignore component names: ${ignoredComponentNames}`); const ignoredComponentNamesSet = new Set(ignoredComponentNames); const usageIgnoredComponentNames = ignoredComponentNames.reduce((acc, componentName) => { acc[componentName] = 0; return acc; }, {}); const components = openAPIFile.document.components || {}; let hasUnusedComponents = true; while (hasUnusedComponents) { logger.trace(`New iteration of removing unused components ...`); let usagedCount = {}; Object.keys(components).forEach((component) => { Object.keys(components[component] || {}).forEach((key) => { const isIgnored = (ignoredComponentNamesSet === null || ignoredComponentNamesSet === void 0 ? void 0 : ignoredComponentNamesSet.has(key)) || ignoredComponentRegExps.some((ignoredComponentRegExp) => { return ignoredComponentRegExp.test(key); }); if (isIgnored) { if (!usageIgnoredComponentNames[key]) { usageIgnoredComponentNames[key] = 0; } usageIgnoredComponentNames[key] += 1; return; } usagedCount[`#/components/${component}/${key}`] = 0; }); }); logger.trace('usageIgnoredComponentNames', usageIgnoredComponentNames); (0, each_schema_1.forEachSchema)(openAPIFile, (schema) => { logger.trace('forEachSchema the callback was called', schema); if ('$ref' in schema) { const shortenedRef = shortenRef(schema['$ref']); usagedCount[shortenedRef] = (usagedCount[shortenedRef] || 0) + 1; } }); logger.trace('usagedCount', usagedCount); hasUnusedComponents = false; Object.keys(usagedCount).forEach((ref) => { var _a; if (!usagedCount[ref]) { logger.trace('Removing ref ... - ', ref); hasUnusedComponents = true; const [, , component, key] = ref.split(REF_SEPARATOR); const componentsObj = (_a = openAPIFile.document.components) === null || _a === void 0 ? void 0 : _a[component]; if (componentsObj) { if (printDeletedComponents) { logger.info(`Deleted the "${key}" component ("${component}") as not used`); } delete componentsObj[key]; } } }); } Object.keys(usageIgnoredComponentNames).forEach((ignoredComponentName) => { if (!usageIgnoredComponentNames[ignoredComponentName]) { logger.warning(`Not usaged ignore component: "${ignoredComponentName}"`); } }); return openAPIFile; }, }; exports.default = processor;