UNPKG

legendaryjs

Version:

LegendaryJS – The ultimate backend framework for speed, power, and simplicity.

343 lines (293 loc) 10.5 kB
const express = require('express'); const http = require('http'); const socketIO = require('socket.io'); const path = require('path'); const app = express(); const server = http.createServer(app); const io = socketIO(server); const context = { multiTenant: false, app, server, io, config: { port: 3000 }, features: { auth: {}, db: {}, docs: false, dashboard: false, routes: [], devtools: false, webhooks: {}, apiKeys: [], plugins: false, middleware: [] } }; // --- Smart API Functions --- function on(event, handler) { if (!context.hooks[event]) { context.hooks[event] = []; } context.hooks[event].push(handler); console.log(`🪝 Hook registered: ${event}`); } function createApp(userConfig = null) { let configData = userConfig; if (!userConfig) { try { configData = require(path.join(process.cwd(), 'legendary.config.js')); console.log('⚙️ legendary.config.js loaded.'); } catch { console.warn('⚠️ No config passed and legendary.config.js not found.'); configData = {}; } } context.config = { ...context.config, ...configData }; if (configData.multiTenant) { context.multiTenant = true; console.log('🏢 Multi-Tenant Mode activated.'); } if (configData.auth) useAuth(configData.auth); if (configData.routes) loadRoutes(configData.routes); if (configData.db) connectDatabase(configData.db); if (configData.docs) enableDocs(); if (configData.dashboard) enableDashboard(); if (configData.devtools) enableDevTools(); if (configData.webhooks) enableWebhooks(configData.webhooks); if (configData.plugins) loadPlugins(); if (configData.apiKeys) setApiKeys(configData.apiKeys); if (configData.middleware) useMiddleware(configData.middleware); console.log(`📦 LegendaryJS App initialized on port ${context.config.port}`); } function useAuth(authConfig) { context.features.auth = authConfig; } function loadRoutes(routeFiles) { context.features.routes = routeFiles; } function connectDatabase(dbConfig) { context.features.db = dbConfig; } function enableDevTools() { context.features.devtools = true; } function enableDashboard() { context.features.dashboard = true; } function enableDocs() { context.features.docs = true; } function enableWebhooks(webhookConfig) { context.features.webhooks = webhookConfig; } function loadPlugins() { context.features.plugins = true; } function setApiKeys(keys = []) { context.features.apiKeys = keys; } function useMiddleware(middlewareArray) { const { app } = context; if (!Array.isArray(middlewareArray)) return; middlewareArray.forEach(entry => { const route = entry.match || '*'; const type = entry.type; if (type === 'log') { app.use(route, (req, res, next) => { if (entry.format === 'detailed') { console.log(`📥 ${req.method} ${req.originalUrl}${new Date().toISOString()}`); } else { console.log(`📥 ${req.method} ${req.originalUrl}`); } next(); }); } else if (type === 'headers') { app.use(route, (req, res, next) => { Object.entries(entry.headers || {}).forEach(([key, val]) => { res.setHeader(key, val); }); next(); }); } else if (type === 'auth' && entry.role) { app.use(route, (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Token required' }); try { const decoded = require('jsonwebtoken').verify(token, process.env.JWT_SECRET || 'legendary-secret'); if (decoded.role !== entry.role) return res.status(403).json({ message: 'Insufficient role' }); req.user = decoded; next(); } catch { return res.status(403).json({ message: 'Invalid token' }); } }); } console.log(`⚙️ Middleware ${type} bound to ${route}`); }); } function startServer() { const { app, io, config, features } = context; // 🏢 Multi-Tenant API Key Handler if (context.multiTenant) { app.use((req, res, next) => { const apikey = req.query.apikey; if (!apikey) return res.status(403).json({ message: 'API key required' }); const fs = require('fs'); const path = require('path'); const configFile = path.join(process.cwd(), 'tenants', `${apikey}.json`); if (!fs.existsSync(configFile)) { return res.status(403).json({ message: 'Invalid API key' }); } try { const dynamicConfig = JSON.parse(fs.readFileSync(configFile)); if (dynamicConfig.routes) loadRoutes(dynamicConfig.routes); if (dynamicConfig.auth) useAuth(dynamicConfig.auth); if (dynamicConfig.db) connectDatabase(dynamicConfig.db); if (dynamicConfig.docs) enableDocs(); if (dynamicConfig.dashboard) enableDashboard(); if (dynamicConfig.plugins) loadPlugins(); if (dynamicConfig.webhooks) enableWebhooks(dynamicConfig.webhooks); if (dynamicConfig.devtools) enableDevTools(); if (dynamicConfig.middleware) useMiddleware(dynamicConfig.middleware); } catch (err) { return res.status(500).json({ message: 'Tenant config error' }); } next(); }); } if (features.db.mongo) { const mongoose = require('mongoose'); const uri = process.env.MONGO_URI || 'mongodb://localhost:27017/legendary'; mongoose.connect(uri).then(() => { console.log('✅ MongoDB connected'); }).catch(err => console.error('❌ MongoDB error:', err.message)); } if (features.auth.jwt) { const jwt = require('jsonwebtoken'); app.post('/auth/jwt/login', (req, res) => { const { username, password } = req.body; if (username === 'admin' && password === '123456') { const token = jwt.sign({ username, role: 'admin' }, process.env.JWT_SECRET || 'legendary-secret'); return res.json({ success: true, token }); } res.status(401).json({ message: 'Invalid credentials' }); }); app.get('/auth/jwt/protected', (req, res) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Token required' }); try { const decoded = jwt.verify(token, process.env.JWT_SECRET || 'legendary-secret'); res.json({ success: true, user: decoded }); } catch { res.status(403).json({ message: 'Invalid token' }); } }); console.log('🔐 JWT Auth enabled'); if (features.auth.session) { const session = require('express-session'); app.use(session({ secret: process.env.SESSION_SECRET || 'legendary-session', resave: false, saveUninitialized: true, cookie: { secure: false } })); app.post('/auth/session/login', (req, res) => { const { username, password } = req.body; if (username === 'admin' && password === '123456') { req.session.user = { username, role: 'admin' }; return res.json({ success: true }); } res.status(401).json({ message: 'Invalid credentials' }); }); app.get('/auth/session/me', (req, res) => { if (!req.session.user) return res.status(401).json({ message: 'Not logged in' }); res.json({ success: true, user: req.session.user }); }); console.log('🔐 Session Auth enabled'); } } if (features.routes.length > 0) { const fs = require('fs'); features.routes.forEach(file => { const fullPath = path.join(process.cwd(), file); if (fs.existsSync(fullPath)) { const routeSet = require(fullPath); routeSet.routes.forEach(route => { const method = route.method.toLowerCase(); const handler = (req, res) => res.json({ success: true, data: route.response || null }); app[method](route.path, handler); console.log(`🧭 Loaded route: [${route.method}] ${route.path}`); }); } }); } if (features.plugins) { const pluginDir = path.join(process.cwd(), 'plugins'); if (require('fs').existsSync(pluginDir)) { require('fs').readdirSync(pluginDir).forEach(file => { const plugin = require(`${pluginDir}/${file}`); if (typeof plugin === 'function') plugin(app); console.log(`🧩 Plugin loaded: ${file}`); }); } } if (features.docs) { const swaggerUi = require('swagger-ui-express'); const swaggerDoc = { swagger: '2.0', info: { title: 'LegendaryJS API', version: '1.0.0' }, paths: {} }; app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc)); console.log('📘 Swagger Docs enabled at /docs'); } if (features.dashboard || features.devtools) { const devmode = require('../tools/devmode'); app.use('/legendary-dashboard', express.static(path.join(__dirname, '../dashboard/public'))); if (features.devtools) app.use(devmode.devMiddleware); io.of('/dashboard').on('connection', (socket) => { devmode.socketTrack(socket); setInterval(() => { socket.emit('devstats', devmode.getStats()); }, 2000); }); console.log('📊 Dashboard running at /legendary-dashboard'); } if (features.webhooks.stripe) { const bodyParser = require('body-parser'); const stripe = require('stripe')(process.env.STRIPE_SECRET || 'sk_test_placeholder'); app.post('/webhook/stripe', bodyParser.raw({ type: 'application/json' }), (req, res) => { const sig = req.headers['stripe-signature']; try { stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_SECRET); console.log('📡 Stripe event received'); } catch { return res.status(400).send('Invalid webhook'); } res.sendStatus(200); }); } const port = config.port || 3000; server.listen(port, () => { console.log(`🚀 LegendaryJS running at http://localhost:${port}`); }); } module.exports = { on, createApp, useAuth, loadRoutes, connectDatabase, enableDevTools, enableDashboard, enableDocs, enableWebhooks, loadPlugins, setApiKeys, useMiddleware, startServer, context };