ultimate-crud
Version:
Ultimate dynamic CRUD API generator with REST, GraphQL, OpenAPI support and association handling for Node.js/Express/Sequelize
118 lines (103 loc) • 3.3 kB
JavaScript
/**
* Ultimate CRUD - Dynamic CRUD API generator with REST, GraphQL, OpenAPI support
*
* @license MIT
* @copyright 2025 cnos-dev
* @author Harish Kashyap (CNOS Dev)
*/
const { Sequelize } = require("sequelize");
const { getOpenApiSpec } = require("./utils/openapi");
const { setupGraphQL } = require('./utils/graphql');
const { setupRest } = require('./utils/rest');
const { defineModelFromTable } = require("./utils/dynamicModel");
const { createCrudRouter, createGetRouter } = require('./utils/dynamicRouter');
/**
* UltimateCrud - Dynamic CRUD API generator
*/
class UltimateCrud {
constructor(options = {}) {
this.app = options.app;
this.sequelize = options.sequelize;
this.entities = options.entities || [];
this.options = {
enableGraphQL: options.enableGraphQL !== false,
enableRest: options.enableRest !== false,
enableOpenAPI: options.enableOpenAPI !== false,
graphqlPath: options.graphqlPath || '/graphql',
openapiPath: options.openapiPath || '/openapi.json',
syncDatabase: options.syncDatabase !== false,
...options
};
}
/**
* Initialize the CRUD API
*/
async initialize() {
if (!this.app) {
throw new Error('Express app is required');
}
if (!this.sequelize) {
throw new Error('Sequelize instance is required');
}
if (!Array.isArray(this.entities) || this.entities.length === 0) {
throw new Error('Entities configuration is required');
}
// Add JSON middleware
this.app.use(require('express').json());
// Setup OpenAPI endpoint
if (this.options.enableOpenAPI) {
this.app.get(this.options.openapiPath, async (req, res) => {
try {
const spec = await this.getOpenApiSpec();
res.json(spec);
} catch (error) {
res.status(500).json({ error: 'Failed to generate OpenAPI spec' });
}
});
}
// Setup GraphQL
if (this.options.enableGraphQL) {
await setupGraphQL(this.app, this.sequelize, this.entities, this.options.graphqlPath);
}
// Sync database if enabled
if (this.options.syncDatabase) {
await this.sequelize.sync({ alter: true });
}
// Setup REST endpoints
if (this.options.enableRest) {
await setupRest(this.app, this.sequelize, this.entities);
}
return this;
}
/**
* Get OpenAPI specification
*/
async getOpenApiSpec() {
return await getOpenApiSpec(this.entities, this.sequelize);
}
/**
* Create a CRUD router for a specific model
*/
static createCrudRouter(model, options = {}) {
return createCrudRouter(model, options);
}
/**
* Create a read-only router for a specific model
*/
static createGetRouter(model, options = {}) {
return createGetRouter(model, options);
}
/**
* Define a model from database table
*/
static async defineModelFromTable(sequelize, tableName, schema, associations = []) {
return await defineModelFromTable(sequelize, tableName, schema, associations);
}
/**
* Create UltimateCrud instance
*/
static create(options) {
return new UltimateCrud(options);
}
}
module.exports = UltimateCrud;