@alexop/openapi-zod-client
Version:
[](https://openapi-zod-client.vercel.app/)
98 lines (76 loc) • 2.98 kB
text/typescript
import type { ReferenceObject, SchemaObject } from "openapi3-ts";
import { isReferenceObject } from "./isReferenceObject";
export const getOpenApiDependencyGraph = (
schemaRef: string[],
getSchemaByRef: (ref: string) => SchemaObject | ReferenceObject
) => {
const visitedsRefs = {} as Record<string, boolean>;
const refsDependencyGraph = {} as Record<string, Set<string>>;
const visit = (schema: SchemaObject | ReferenceObject, fromRef: string): void => {
if (!schema) return;
if (isReferenceObject(schema)) {
if (!refsDependencyGraph[fromRef]) {
refsDependencyGraph[fromRef] = new Set();
}
refsDependencyGraph[fromRef]!.add(schema.$ref);
if (visitedsRefs[schema.$ref]) return;
visitedsRefs[fromRef] = true;
visit(getSchemaByRef(schema.$ref), schema.$ref);
return;
}
if (schema.allOf) {
for (const allOf of schema.allOf) {
visit(allOf, fromRef);
}
return;
}
if (schema.oneOf) {
for (const oneOf of schema.oneOf) {
visit(oneOf, fromRef);
}
return;
}
if (schema.anyOf) {
for (const anyOf of schema.anyOf) {
visit(anyOf, fromRef);
}
return;
}
if (schema.type === "array") {
if (!schema.items) return;
return void visit(schema.items, fromRef);
}
if (schema.type === "object" || schema.properties || schema.additionalProperties) {
if (schema.properties) {
for (const property in schema.properties) {
visit(schema.properties[property]!, fromRef);
}
}
if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
visit(schema.additionalProperties, fromRef);
}
}
};
schemaRef.forEach((ref) => visit(getSchemaByRef(ref), ref));
const deepDependencyGraph = {} as Record<string, Set<string>>;
const visitedsDeepRefs = {} as Record<string, boolean>;
schemaRef.forEach((ref) => {
const deps = refsDependencyGraph[ref];
if (!deps) return;
if (!deepDependencyGraph[ref]) {
deepDependencyGraph[ref] = new Set();
}
const visit = (dep: string) => {
deepDependencyGraph[ref]!.add(dep);
if (refsDependencyGraph[dep] && ref !== dep) {
refsDependencyGraph[dep]!.forEach((transitive) => {
if (visitedsDeepRefs[ref + "__" + transitive]) return;
visitedsDeepRefs[ref + "__" + transitive] = true;
visit(transitive);
});
}
};
deps.forEach((dep) => visit(dep));
});
return { refsDependencyGraph, deepDependencyGraph };
};