openapi-modifier
Version:
This package allows you to automate the process of modifying OpenAPI specifications by applying a set of predefined rules
121 lines (120 loc) • 6.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.configSchema = void 0;
const zod_1 = require("zod");
const normilizers_1 = require("../common/utils/normilizers");
const each_operation_1 = require("../common/utils/iterators/each-operation");
const openapi_models_1 = require("../common/openapi-models");
const config_1 = require("../common/config");
const parse_endpoint_descriptor_1 = require("../common/utils/config/parse-endpoint-descriptor");
const empty_1 = require("../common/utils/empty");
const configSchema = zod_1.z
.object({
enabled: zod_1.z
.array(config_1.anyEndpointDescriptorConfigSchema)
.optional(),
enabledPathRegExp: zod_1.z.array(zod_1.z.instanceof(RegExp)).optional(),
disabled: zod_1.z
.array(config_1.anyEndpointDescriptorConfigSchema)
.optional(),
disabledPathRegExp: zod_1.z.array(zod_1.z.instanceof(RegExp)).optional(),
printIgnoredEndpoints: zod_1.z.boolean().optional(),
})
.strict();
exports.configSchema = configSchema;
const normalizeEndpoint = (endpoint) => {
return Object.assign(Object.assign({}, endpoint), { method: (0, normilizers_1.normalizeMethod)(endpoint.method) });
};
const getEndpointHash = (endpoint) => {
return `${endpoint.method}/${endpoint.path}`;
};
const processor = {
configSchema,
defaultConfig: {},
processDocument: (openAPIFile, config, logger) => {
var _a;
const { enabled, enabledPathRegExp, disabled, disabledPathRegExp, printIgnoredEndpoints } = config;
const parsedEnabled = enabled ? enabled.map((descriptor) => {
return (0, parse_endpoint_descriptor_1.parseAnyEndpointDescriptor)(descriptor, logger);
}).filter(empty_1.isNonNil) : null;
const normalizedEnabled = parsedEnabled ? parsedEnabled.map(normalizeEndpoint) : null;
const normalizedEnabledPathRegExps = enabledPathRegExp || null;
const parsedDisabled = disabled ? disabled.map((descriptor) => {
return (0, parse_endpoint_descriptor_1.parseAnyEndpointDescriptor)(descriptor, logger);
}).filter(empty_1.isNonNil) : null;
const normalizedDisabled = parsedDisabled ? parsedDisabled.map(normalizeEndpoint) : null;
const normalizedDisabledPathRegExps = disabledPathRegExp || null;
const enabledEndpointHashSet = normalizedEnabled ? new Set(normalizedEnabled.map(getEndpointHash)) : null;
const disabledEndpointHashSet = normalizedDisabled ? new Set(normalizedDisabled.map(getEndpointHash)) : null;
const checkIsEnabledEndpoint = (endpoint) => {
const hash = getEndpointHash(endpoint);
const isEnabled = (enabledEndpointHashSet && enabledEndpointHashSet.has(hash)) ||
(normalizedEnabledPathRegExps &&
normalizedEnabledPathRegExps.some((normalizedEnabledPathRegExp) => {
return normalizedEnabledPathRegExp.test(endpoint.path);
})) ||
(!enabledEndpointHashSet && !normalizedEnabledPathRegExps);
const isDisabled = (disabledEndpointHashSet && disabledEndpointHashSet.has(hash)) ||
(normalizedDisabledPathRegExps &&
normalizedDisabledPathRegExps.some((normalizedDisabledPathRegExp) => {
return normalizedDisabledPathRegExp.test(endpoint.path);
}));
return isEnabled && !isDisabled;
};
let usageCount = {};
const increaseUsageCount = (endpoint) => {
const hash = getEndpointHash(endpoint);
usageCount[hash] = (usageCount[hash] || 0) + 1;
};
const ignoredEndpoints = [];
(0, each_operation_1.forEachOperation)(openAPIFile, ({ operationSchema, method, path }) => {
var _a, _b;
const endpoint = normalizeEndpoint({
path,
method,
});
increaseUsageCount(endpoint);
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];
if (!checkIsEnabledEndpoint(endpoint) && pathObjSchema) {
delete pathObjSchema[method];
ignoredEndpoints.push({
path,
method,
});
}
});
const paths = (_a = openAPIFile.document) === null || _a === void 0 ? void 0 : _a.paths;
Object.keys(paths || {}).forEach((pathKey) => {
const path = paths === null || paths === void 0 ? void 0 : paths[pathKey];
const methods = Object.keys(path || {}).filter(openapi_models_1.checkIsHttpMethod);
if (!(methods === null || methods === void 0 ? void 0 : methods.length) && (paths === null || paths === void 0 ? void 0 : paths[pathKey])) {
delete paths[pathKey];
}
});
if (printIgnoredEndpoints && ignoredEndpoints.length) {
logger.info(`Ignored endpoints: \n
${ignoredEndpoints.map((endpoint) => {
const { method, path } = endpoint;
return `[${method}] - ${path} \n`;
})}\n`);
}
if (normalizedEnabled) {
normalizedEnabled.forEach((endpoint) => {
const hash = getEndpointHash(endpoint);
if (!usageCount[hash]) {
logger.warning(`Non-existent enabled endpoint "${JSON.stringify(endpoint)}"`);
}
});
}
if (normalizedDisabled) {
normalizedDisabled.forEach((endpoint) => {
const hash = getEndpointHash(endpoint);
if (!usageCount[hash]) {
logger.warning(`Non-existent disabled endpoint "${JSON.stringify(endpoint)}"`);
}
});
}
return openAPIFile;
},
};
exports.default = processor;