openapi-graph-core
Version:
A TS library to manage large API projects defined by OpenAPIv3 specification.
124 lines (123 loc) • 4.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveReference = exports.getRefEdges = exports.getSchemaNodes = exports.getInlineSchemasNodes = exports.getDefinedSchemasNodes = void 0;
const openapi_graph_types_1 = require("openapi-graph-types");
const SchemaNode_1 = require("../../graph/nodes/SchemaNode");
const utils_1 = require("../../utils");
const edges_1 = require("../edges");
/**
* Creates a new Schema depends on its type. Swagger schemas can be Array or NonArray
*
* @param schema source
* @param name The given name for the schema
* @returns the new schema instance
*/
function createSchema(schemaNodes, schema, schemaName, isInline) {
if (schema && !('$ref' in schema)) {
if ('type' in schema && schema?.type === 'array') {
schemaNodes[schemaName] = new SchemaNode_1.SchemaNode(schemaName, schema, isInline);
}
else {
schemaNodes[schemaName] = new SchemaNode_1.SchemaNode(schemaName, schema, isInline);
}
}
}
function getDefinedSchemasNodes(api) {
const nodes = {};
const schemas = api.components?.schemas;
if (schemas) {
Object.keys(schemas).forEach((schemaName) => createSchema(nodes, schemas[schemaName], schemaName, false));
}
return nodes;
}
exports.getDefinedSchemasNodes = getDefinedSchemasNodes;
/**
* It will find all the schemas defined in the specification
*
* @param api source
* @param fn callback which will be executed for every node
*/
function getInlineSchemasNodes(json, currentIndex = 1, nodes = {}) {
const schema = json?.schema;
if (schema) {
createSchema(nodes, schema, `inline-schema-${currentIndex++}`, true);
if (schema?.type === 'array') {
getInlineSchemasNodes(json.items, currentIndex, nodes);
}
}
else if (json) {
function handleJson() {
Object.keys(json).forEach((key) => {
nodes = getInlineSchemasNodes(json[key], currentIndex, nodes);
});
}
if ({}.constructor === json.constructor) {
handleJson();
}
else if ([].constructor === json.constructor) {
json.forEach(handleJson);
}
}
return nodes;
}
exports.getInlineSchemasNodes = getInlineSchemasNodes;
function getSchemaNodes(api) {
const schemas = getDefinedSchemasNodes(api);
const inlineSchemas = getInlineSchemasNodes(api);
utils_1.log(`Found ${Object.values(schemas).length} schemas and ${Object.values(inlineSchemas).length} inline schemas in ${api.info.title}`, openapi_graph_types_1.LogLevel.DEBUG);
return { ...schemas, ...inlineSchemas };
}
exports.getSchemaNodes = getSchemaNodes;
/**
* It will find all the references defined in the specification
*
* @param api source
* @param fn callback which will be executed for every node
*/
function getRefEdges(json, absolutePath, edges = { schemaRef: {} }) {
const ref = json?.$ref;
if (ref) {
// TODO Should test any type of component
if (/components\/schemas/.test(ref)) {
edges.schemaRef[ref] = new edges_1.RefEdge(absolutePath, ref);
}
}
else if (json !== null) {
function handleJson() {
Object.keys(json).forEach((key) => {
getRefEdges(json[key], absolutePath, edges);
});
}
if ({}.constructor === json.constructor) {
handleJson();
}
else if ([].constructor === json.constructor) {
json.forEach(handleJson);
}
}
return edges;
}
exports.getRefEdges = getRefEdges;
/**
* Sets the edges' child value
* @param graphs
* @param refs
* @returns
*/
function resolveReference(graphs, refs) {
const filteredRefs = {
schemaRef: {},
};
Object.values(refs.schemaRef)
.filter((r) => graphs?.[r.refToFilePath] && graphs?.[r.refToFilePath].nodes.schemas[r.tokenName])
.forEach((r) => {
const schema = graphs?.[r.refToFilePath].nodes.schemas[r.tokenName];
if (schema) {
schema.referencedBy[r.path] = r;
r.child = schema;
filteredRefs.schemaRef[r.path] = r;
}
});
return filteredRefs;
}
exports.resolveReference = resolveReference;