@opendoc/openapi-reference-parser
Version:
Get the dependencies of reference in openapi.
120 lines • 5.49 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "ramda", "./utils/is-object", "jsonpath-plus", "./reference"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenapiReferenceParser = void 0;
const R = require("ramda");
const is_object_1 = require("./utils/is-object");
const jsonpath_plus_1 = require("jsonpath-plus");
const reference_1 = require("./reference");
class OpenapiReferenceParser {
document;
options;
directDependenciesStorage = {};
transitiveDependenciesStorage = {};
dependenciesStorage = {};
constructor(document, options = {}) {
this.document = document;
this.options = options;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
forEach(fn) {
for (const [pathname, pathItem] of Object.entries(this.document.paths || {})) {
if (!(0, is_object_1.isObject)(this.document.paths))
continue;
for (const m in pathItem) {
const method = m.toLowerCase();
const operation = pathItem[method];
if (R.isNil(operation))
continue;
fn(reference_1.Reference.from(['paths', pathname, method]), operation);
}
}
for (const [scopeName, scope] of Object.entries(this.document.components || {})) {
if (!(0, is_object_1.isObject)(this.document.components))
continue;
for (const [componentName, component] of Object.entries(scope)) {
if (R.isNil(component))
continue;
fn(reference_1.Reference.from(['components', scopeName, componentName]), component);
}
}
}
pickRefs(json) {
const arr = (0, jsonpath_plus_1.JSONPath)({
path: "$..*['$ref']",
json,
});
return arr.map((ref) => reference_1.Reference.from(ref));
}
buildDirectDependenciesStorage() {
this.forEach((ref, item) => {
const refs = this.pickRefs(item)
.filter((r) => !r.equals(ref));
ref.set(this.directDependenciesStorage, R.uniqWith((a, b) => a.equals(b), refs));
});
}
buildTransitiveDependenciesStorage() {
this.forEach((ref) => {
const directDependencies = ref.get(this.directDependenciesStorage);
if (!directDependencies)
return;
const transitiveDependencies = [];
const dependencies = [...directDependencies];
const isDuplicate = (r) => ref.equals(r) || dependencies.some((d) => d.equals(r));
const appendToDependencies = (refs) => {
for (const r of refs) {
if (isDuplicate(r))
continue;
dependencies.push(r);
transitiveDependencies.push(r);
}
};
for (let i = 0; i < dependencies.length; i++) {
try {
const dep = dependencies[i];
const depDirectDependencies = dep.get(this.directDependenciesStorage);
const depTransitiveDependencies = dep.get(this.transitiveDependenciesStorage);
if (depTransitiveDependencies)
appendToDependencies(depTransitiveDependencies);
else if (depDirectDependencies)
appendToDependencies(depDirectDependencies);
}
catch (err) {
if (!this.options.tolerant)
throw err;
}
}
ref.set(this.transitiveDependenciesStorage, transitiveDependencies);
ref.set(this.dependenciesStorage, dependencies);
});
}
parse() {
this.buildDirectDependenciesStorage();
this.buildTransitiveDependenciesStorage();
const result = {};
this.forEach((ref) => {
const dependencies = ref.get(this.dependenciesStorage);
const transitiveDependencies = ref.get(this.transitiveDependenciesStorage);
const directDependencies = ref.get(this.directDependenciesStorage);
if (!dependencies || !transitiveDependencies || !directDependencies)
return;
ref.set(result, {
dependencies: dependencies.map((r) => r.toString()),
transitiveDependencies: transitiveDependencies.map((r) => r.toString()),
directDependencies: directDependencies.map((r) => r.toString()),
});
});
return result;
}
}
exports.OpenapiReferenceParser = OpenapiReferenceParser;
});
//# sourceMappingURL=parser.js.map