UNPKG

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
/** * 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 };