ultimate-crud
Version:
Ultimate dynamic CRUD API generator with REST, GraphQL, OpenAPI support and association handling for Node.js/Express/Sequelize
147 lines (141 loc) • 4.87 kB
JavaScript
/**
* OpenAPI utilities for Ultimate CRUD
*
* @license MIT
* @copyright 2025 cnos-dev
* @author Harish Kashyap (CNOS Dev)
*/
// Generates a basic OpenAPI spec from entities configuration
const { getSchemaForEntity } = require("./openapiSchema");
async function getPathsAndSchemas(entities, sequelize) {
const paths = {};
const schemas = {};
for (const entity of entities) {
const messages = entity.responseMessages || {};
if (entity.type === "table" || entity.type === "view") {
const schema = await getSchemaForEntity(entity.name, entity.schema, sequelize, entities);
schemas[entity.name] = schema;
paths[entity.route] = {
get: {
summary: `Get all ${entity.name}`,
responses: {
200: {
description: messages[200] || "Success",
content: {
"application/json": {
schema: {
type: "array",
items: { $ref: `#/components/schemas/${entity.name}` },
},
},
},
},
500: { description: messages[500] || "Internal server error" },
},
},
post:
entity.type === "table"
? {
summary: `Create ${entity.name}`,
requestBody: {
content: {
"application/json": {
schema: { $ref: `#/components/schemas/${entity.name}` },
},
},
},
responses: {
201: { description: messages[201] || "Created" },
400: { description: messages[400] || "Bad request" },
500: { description: messages[500] || "Internal server error" },
},
}
: undefined,
};
if (entity.type === "table") {
paths[`${entity.route}/{id}`] = {
get: {
summary: `Get ${entity.name} by ID`,
responses: {
200: {
description: messages[200] || "Success",
content: {
"application/json": {
schema: { $ref: `#/components/schemas/${entity.name}` },
},
},
},
404: { description: messages[404] || "Not found" },
500: { description: messages[500] || "Internal server error" },
},
},
put: {
summary: `Update ${entity.name} by ID`,
requestBody: {
content: {
"application/json": {
schema: { $ref: `#/components/schemas/${entity.name}` },
},
},
},
responses: {
200: { description: messages[200] || "Updated" },
400: { description: messages[400] || "Bad request" },
404: { description: messages[404] || "Not found" },
500: { description: messages[500] || "Internal server error" },
},
},
delete: {
summary: `Delete ${entity.name} by ID`,
responses: {
200: { description: messages[200] || "Deleted" },
404: { description: messages[404] || "Not found" },
500: { description: messages[500] || "Internal server error" },
},
},
};
}
} else if (entity.type === "query") {
paths[entity.route] = {
get: {
summary: `Get ${entity.route}`,
responses: {
200: { description: messages[200] || "Success" },
500: { description: messages[500] || "Internal server error" },
},
},
};
} else if (entity.type === "procedure") {
paths[entity.route] = {
post: {
summary: `Execute procedure ${entity.procedure}`,
requestBody: {
content: {
"application/json": {
schema: { type: "object" }, // Accept any params
},
},
},
responses: {
200: { description: messages[200] || "Procedure executed successfully" },
500: { description: messages[500] || "Server error while executing procedure" },
},
},
};
}
}
return { paths, schemas };
}
async function getOpenApiSpec(entities, sequelize) {
const { paths, schemas } = await getPathsAndSchemas(entities, sequelize);
return {
openapi: "3.0.0",
info: {
title: "Dynamic API",
version: "1.0.0",
},
paths,
components: { schemas },
};
}
module.exports = { getOpenApiSpec };