initial commit
This commit is contained in:
133
server/index.js
Normal file
133
server/index.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @cc-platform/server — Main entry point for the shared server foundation
|
||||
*
|
||||
* Provides a createPlatformServer() factory that sets up Express, HTTP server,
|
||||
* auth middleware, CORS, JSON parsing, and health endpoint — the common
|
||||
* boilerplate that is structurally identical across all platform services.
|
||||
*
|
||||
* Also re-exports all sub-modules for convenient access.
|
||||
*
|
||||
* Usage:
|
||||
* const {
|
||||
* createPlatformServer,
|
||||
* createWebSocketManager,
|
||||
* createDatabase,
|
||||
* setupGracefulShutdown,
|
||||
* createRateLimiter,
|
||||
* createProxyEndpoint,
|
||||
* } = require('@cc-platform/server');
|
||||
*
|
||||
* const { app, server, start } = createPlatformServer({
|
||||
* serviceName: 'inventory-manager',
|
||||
* port: 3001,
|
||||
* });
|
||||
*
|
||||
* // Add service-specific routes
|
||||
* app.get('/api/items', (req, res) => { ... });
|
||||
*
|
||||
* // Set up WebSocket, DB, etc.
|
||||
* const wsManager = createWebSocketManager(server, { ... });
|
||||
* const db = createDatabase('/data/inventory.db', { schema: '...' });
|
||||
*
|
||||
* // Start listening
|
||||
* start();
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const http = require('http');
|
||||
|
||||
const { createAuthMiddleware } = require('./auth');
|
||||
const { createWebSocketManager } = require('./websocket');
|
||||
const { createDatabase } = require('./db');
|
||||
const { proxyRequest, createProxyEndpoint } = require('./proxy');
|
||||
const { createHealthEndpoint } = require('./health');
|
||||
const { setupGracefulShutdown } = require('./shutdown');
|
||||
const { createRateLimiter } = require('./rate');
|
||||
|
||||
/**
|
||||
* @typedef {Object} PlatformServerOptions
|
||||
* @property {string} [serviceName] Service identifier for logs and health endpoint
|
||||
* @property {number} [port] Listen port (default: env.PORT || 3001)
|
||||
* @property {string} [host] Listen host (default: env.HOST || '0.0.0.0')
|
||||
* @property {string} [apiKey] API key for auth (default: env.API_KEY)
|
||||
* @property {string} [jsonLimit] Express JSON body limit (default: '5mb')
|
||||
* @property {boolean} [cors] Enable CORS (default: true)
|
||||
* @property {string} [corsOrigin] CORS origin (default: '*')
|
||||
* @property {boolean} [rateLimit] Enable rate limiting (default: true)
|
||||
* @property {Object} [rateLimitOpts] Rate limiter options
|
||||
* @property {Function} [healthExtras] Returns additional health check fields
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a fully configured Express + HTTP server with platform defaults.
|
||||
*
|
||||
* @param {PlatformServerOptions} opts - Configuration options
|
||||
* @returns {{ app, server, auth, start, port, host }}
|
||||
*/
|
||||
function createPlatformServer(opts = {}) {
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
|
||||
const port = opts.port || process.env.PORT || 3001;
|
||||
const host = opts.host || process.env.HOST || '0.0.0.0';
|
||||
const apiKey = opts.apiKey || process.env.API_KEY || '';
|
||||
const serviceName = opts.serviceName || 'platform';
|
||||
|
||||
// --- Standard middleware ---
|
||||
app.use(express.json({ limit: opts.jsonLimit || '5mb' }));
|
||||
|
||||
// CORS
|
||||
if (opts.cors !== false) {
|
||||
app.use((_req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', opts.corsOrigin || '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key');
|
||||
if (_req.method === 'OPTIONS') return res.sendStatus(204);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
// Auth middleware — protect non-GET methods by default
|
||||
const auth = createAuthMiddleware(apiKey);
|
||||
app.use(auth.protectMutations);
|
||||
|
||||
// Rate limiting
|
||||
if (opts.rateLimit !== false) {
|
||||
const limiter = createRateLimiter(opts.rateLimitOpts || {});
|
||||
app.use(limiter);
|
||||
}
|
||||
|
||||
// Health endpoint
|
||||
createHealthEndpoint(app, {
|
||||
serviceName,
|
||||
getExtras: opts.healthExtras,
|
||||
});
|
||||
|
||||
// --- Start ---
|
||||
function start(callback) {
|
||||
server.listen(port, host, () => {
|
||||
console.log(`[${serviceName}] Server listening on ${host}:${port}`);
|
||||
if (apiKey) console.log(`[${serviceName}] API key authentication enabled`);
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
return { app, server, auth, start, port, host };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// Server factory
|
||||
createPlatformServer,
|
||||
|
||||
// Sub-modules
|
||||
createAuthMiddleware,
|
||||
createWebSocketManager,
|
||||
createDatabase,
|
||||
proxyRequest,
|
||||
createProxyEndpoint,
|
||||
createHealthEndpoint,
|
||||
setupGracefulShutdown,
|
||||
createRateLimiter,
|
||||
};
|
||||
Reference in New Issue
Block a user