@opendoc/openapi-shaking
Version:
Remove the useless components and paths of openapi document.
89 lines (86 loc) • 3.25 kB
JavaScript
// src/shaking-orphaned-components.ts
import * as R from "ramda";
import { OpenapiReferenceParser } from "@opendoc/openapi-reference-parser";
function openapiShakingOrphanedComponents(document, options = {}) {
const dependencies = new OpenapiReferenceParser(document, options).parse();
const refs = R.unnest(Object.values(dependencies.paths || {}).map(
(pathObj) => R.unnest(Object.values(pathObj || {}).map((op) => op.dependencies))
));
const exists = refs.map((ref) => ref.match(/#\/components\/(.+?)\/(.+)/)).filter((matched) => !!matched).map((matched) => ({
scopeName: matched[1],
componentName: matched[2]
}));
const isExist = (scopeName, componentName) => exists.some(
(item) => item.scopeName === scopeName && item.componentName === componentName
);
let doc = document;
for (const scopeName in document.components) {
if (!document.components[scopeName]) continue;
for (const componentName in document.components[scopeName]) {
if (!document.components[scopeName][componentName]) continue;
if (!isExist(scopeName, componentName)) {
doc = R.dissocPath(["components", scopeName, componentName], doc);
}
}
if (R.isEmpty(R.path(["components", scopeName], doc))) {
doc = R.dissocPath(["components", scopeName], doc);
}
}
return doc;
}
// src/shaking.ts
import * as R2 from "ramda";
// src/utils/is-valid-method.ts
function isValidMethod(method) {
if (typeof method !== "string") return false;
return ["get", "put", "post", "delete", "options", "head", "patch", "trace", "connect"].includes(method);
}
// src/shaking.ts
async function openapiShaking(document, filter, options = {}) {
let doc = document;
const pairs = await Promise.all(
Object.entries(document.paths || {}).map(async ([path3, methods]) => {
if (!methods) return [path3, methods];
const pairs2 = await Promise.all(
Object.entries(methods || {}).map(async ([method, operation]) => {
if (!isValidMethod(method)) return [method, operation];
if (await filter(path3, method, operation)) {
return [method, operation];
}
})
);
const pairsWithoutNil = pairs2.filter(R2.isNotNil);
if (!pairsWithoutNil.length) return void 0;
return [
path3,
R2.fromPairs(pairsWithoutNil)
];
})
);
const paths = R2.fromPairs(pairs.filter(R2.isNotNil));
doc = R2.assoc("paths", paths, doc);
return openapiShakingOrphanedComponents(doc, options);
}
function openapiShakingSync(document, filter, options = {}) {
let doc = document;
for (const path3 in document.paths) {
for (const method in document.paths[path3]) {
if (!isValidMethod(method)) continue;
const operation = R2.path(["paths", path3, method], document);
if (!operation) continue;
if (!filter(path3, method, operation)) {
doc = R2.dissocPath(["paths", path3, method], doc);
}
}
if (R2.isEmpty(R2.path(["paths", path3], doc))) {
doc = R2.dissocPath(["paths", path3], doc);
}
}
return openapiShakingOrphanedComponents(doc, options);
}
export {
openapiShaking,
openapiShakingOrphanedComponents,
openapiShakingSync
};
//# sourceMappingURL=index.mjs.map