legendaryjs
Version:
LegendaryJS – The ultimate backend framework for speed, power, and simplicity.
138 lines (112 loc) • 4.24 kB
JavaScript
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');
const socketIO = require('socket.io');
const bodyParser = require('body-parser');
const cors = require('cors');
const helmet = require('helmet');
const xss = require('xss-clean');
const mongoSanitize = require('express-mongo-sanitize');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const { loadRoutes } = require('./router');
const { initGraphQL } = require('./graphql');
const { applyRepairLogic } = require('./repair');
const { smartLogger } = require('../logger/smart-logger');
const { connectDatabases } = require('../db');
const { setupSwagger } = require('../docs/swagger');
const { apiKeyMiddleware } = require('../auth/apiKeys');
const tools = require('../tools');
const { setupAuth } = require('../auth');
const { createModel } = require('./helpers/createModel');
const { createRoute } = require('./helpers/createRoute');
const { validate } = require('./helpers/validate');
const { executeHooks } = require('./hooks');
const { loadLogic } = require('./loadLogic');
const { setupStudio } = require('./studio');
const { tenantMiddleware } = require('./middleware/tenant');
function createApp(config) {
const app = express();
// 🛡️ HTTP or HTTPS
let server;
if (config.protocol === 'https') {
const key = fs.readFileSync(config.httpsOptions.key || './certs/key.pem');
const cert = fs.readFileSync(config.httpsOptions.cert || './certs/cert.pem');
server = https.createServer({ key, cert }, app);
} else {
server = http.createServer(app);
}
const io = socketIO(server);
// 🌍 Global utilities
global.createModel = createModel;
global.createRoute = (opts) => createRoute(app, opts);
global.validate = validate;
global.logic = loadLogic();
global.plugins = loadLogic('plugins');
Object.values(global.plugins).forEach(fn => {
if (typeof fn === 'function') fn(app, config);
});
// 🌐 Middleware: pre-processing
app.use(bodyParser.json());
if (config.features?.compression) app.use(compression());
if (config.features?.rateLimit) {
const limiter = rateLimit({
windowMs: config.features.rateLimit.windowMs || 60000,
max: config.features.rateLimit.max || 100,
message: 'Too many requests. Please slow down.',
});
app.use(limiter);
}
if (config.security?.helmet) app.use(helmet());
if (config.security?.xss) app.use(xss());
if (config.security?.sanitize) app.use(mongoSanitize());
if (config.cors?.enabled) {
app.use(cors({
origin: config.cors.origin || '*',
methods: config.cors.methods || ['GET', 'POST', 'PUT', 'DELETE']
}));
}
if (config.multitenant?.enabled) app.use(tenantMiddleware(config));
// 💡 Hooks
app.use((req, res, next) => executeHooks('onRequest', req, res, next));
// 🔐 Auth + DB
setupAuth(app);
connectDatabases();
// 🧠 Studio + Docs
if (config.studio) setupStudio(app, io);
if (config.documentation !== false) setupSwagger(app);
// 🛠️ Tools
app.use(apiKeyMiddleware);
app.use(tools.trackRequest);
app.use(tools.trackError);
io.on('connection', tools.socketConnection);
if (config.logging?.smartLogger) app.use(smartLogger);
// 🧬 GraphQL + REST
loadRoutes(app);
if (config.graphql) initGraphQL(app);
applyRepairLogic(app, io);
// Hook: Error
app.use((err, req, res, next) => executeHooks('onError', err, req, res, next));
// Make socket available
app.use((req, res, next) => {
req.io = io;
next();
});
// 🔄 Start
server.listen(config.port || 3000, () => {
console.log(`🚀 LegendaryJS running at http://localhost:${config.port || 3000}`);
executeHooks('onStart');
});
// ❎ Graceful Exit
if (config.restart?.graceful !== false) {
process.on('SIGINT', () => {
console.log('🛑 Shutting down LegendaryJS...');
server.close(() => {
console.log('✅ Server closed.');
process.exit(0);
});
});
}
}
module.exports = { createApp };