fortify2-js
Version:
MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.
600 lines (596 loc) • 27.1 kB
JavaScript
'use strict';
var _default = require('./const/default.js');
var express = require('express');
var ConfigLoader = require('./utils/ConfigLoader.js');
var CacheManager = require('./components/fastapi/CacheManager.js');
var MiddlewareMethodsManager = require('./components/fastapi/middlewares/MiddlewareMethodsManager.js');
var RequestProcessor = require('./components/fastapi/RequestProcessor.js');
var RouteManager = require('./components/fastapi/RouteManager.js');
var PerformanceManager = require('./components/fastapi/PerformanceManager.js');
var MonitoringManager = require('./components/fastapi/MonitoringManager.js');
var PluginManager = require('./components/fastapi/PluginManager.js');
var ClusterManagerComponent = require('./components/fastapi/ClusterManagerComponent.js');
var FileWatcherManager = require('./components/fastapi/FileWatcherManager.js');
var PortManager = require('./utils/PortManager.js');
var Logger = require('./utils/Logger.js');
var middlewareManager = require('./components/fastapi/middlewares/middlewareManager.js');
var RedirectManager = require('./components/fastapi/RedirectManager.js');
var ConsoleInterceptor = require('./components/fastapi/console/ConsoleInterceptor.js');
var forceClosePort = require('./utils/forceClosePort.js');
/**
* Ultra-Fast Express Server with Advanced Performance Optimization
*/
class UltraFastServer {
constructor(userOptions = {
server: {
enableMiddleware: true,
},
}) {
this.ready = false;
this.currentPort = 0; // Track the actual running port
// Load configuration from file system if available
const fileConfig = ConfigLoader.ConfigLoader.loadConfig();
// Merge configurations: defaults < file config < user options
this.options = this.mergeWithDefaults(userOptions, fileConfig);
// Initialize logger with user configuration
this.logger = Logger.initializeLogger(this.options.logging);
this.logger.startup("server", "Creating fast server...");
// Create Express app immediately
this.app = express();
// Initialize components
this.initializeComponents();
// Add middleware methods to app (synchronous)
this.middlewareMethodsManager.addMiddlewareMethods();
this.routeManager.addMethods();
this.monitoringManager.addMonitoringEndpoints();
this.addStartMethod();
this.addConsoleInterceptionMethods();
// Initialize cache in background
this.initPromise = this.cacheManager.initializeCache();
this.logger.debug("server", "Ultra-fast Express server created (cache initializing in background)");
}
/**
* Initialize all component instances with proper dependencies
*/
initializeComponents() {
this.logger.startup("server", "Initializing components...");
// Initialize CacheManager first (foundation component)
this.cacheManager = new CacheManager.CacheManager({
cache: this.options.cache,
performance: this.options.performance,
server: this.options.server,
env: this.options.env,
});
// Set cache on app for backward compatibility
this.app.cache = this.cacheManager.getCache();
// Initialize PerformanceManager (depends on CacheManager)
this.performanceManager = new PerformanceManager.PerformanceManager({
performance: this.options.performance,
server: this.options.server,
env: this.options.env,
}, {
app: this.app,
cacheManager: this.cacheManager,
});
// Initialize PluginManager (depends on CacheManager)
this.pluginManager = new PluginManager.PluginManager({
app: this.app,
cacheManager: this.cacheManager,
});
// Initialize ClusterManager
this.clusterManager = new ClusterManagerComponent.ClusterManagerComponent({
cluster: this.options.cluster,
}, {
app: this.app,
});
// Initialize FileWatcherManager
this.fileWatcherManager = new FileWatcherManager.FileWatcherManager({
fileWatcher: this.options.fileWatcher,
}, {
app: this.app,
clusterManager: this.clusterManager,
});
// Initialize RequestProcessor (depends on PerformanceManager and PluginManager)
this.requestProcessor = new RequestProcessor.RequestProcessor({
performanceProfiler: this.performanceManager.getPerformanceProfiler(),
executionPredictor: this.performanceManager.getExecutionPredictor(),
requestPreCompiler: this.performanceManager.getRequestPreCompiler(),
pluginEngine: this.pluginManager.getPluginEngine(),
cacheManager: this.cacheManager,
});
// Initialize middlewareManager (new middleware system)
this.middlewareManager = new middlewareManager.MiddlewareManager({
server: this.options.server,
security: this.options.security,
performance: this.options.performance,
middleware: this.options.middleware,
}, {
app: this.app,
cache: this.cacheManager.getCache(),
performanceProfiler: this.performanceManager.getPerformanceProfiler(),
executionPredictor: this.performanceManager.getExecutionPredictor(),
optimizationEnabled: this.performanceManager.isOptimizationEnabled(),
optimizationStats: this.performanceManager.getOptimizationStats(),
handleUltraFastPath: this.requestProcessor.handleUltraFastPath.bind(this.requestProcessor),
handleFastPath: this.requestProcessor.handleFastPath.bind(this.requestProcessor),
handleStandardPath: this.requestProcessor.handleStandardPath.bind(this.requestProcessor),
});
// Initialize MiddlewareMethodsManager (adds methods to app)
this.middlewareMethodsManager = new MiddlewareMethodsManager.MiddlewareMethodsManager({
app: this.app,
middlewareManager: this.middlewareManager,
});
// Initialize RouteManager (depends on CacheManager and middlewareManager)
this.routeManager = new RouteManager.RouteManager({
app: this.app,
cacheManager: this.cacheManager,
middlewareManager: this.middlewareManager,
ultraFastOptimizer: this.performanceManager.getUltraFastOptimizer(),
});
// Initialize MonitoringManager (depends on CacheManager and PerformanceManager)
this.monitoringManager = new MonitoringManager.MonitoringManager({
monitoring: this.options.monitoring,
}, {
app: this.app,
cacheManager: this.cacheManager,
performanceManager: this.performanceManager,
});
// Initialize RedirectManager (lightweight component)
this.redirectManager = new RedirectManager.RedirectManager(this.logger);
// Initialize ConsoleInterceptor (logging enhancement)
this.consoleInterceptor = new ConsoleInterceptor.ConsoleInterceptor(this.logger, this.options.logging);
// Start console interception if enabled
if (this.options.logging?.consoleInterception?.enabled) {
this.consoleInterceptor.start();
this.logger.info("console", "Console interception system activated");
}
// Add file watcher monitoring endpoints if enabled
if (this.options.fileWatcher?.enabled) {
this.fileWatcherManager.addFileWatcherMonitoringEndpoints("/fortify");
}
// console.log("Components initialized successfully");
}
/**
* Get the Express app instance (ready to use immediately)
*/
getApp() {
return this.app;
}
/**
* Wait for full initialization (cache, console interceptor, and all components)
*/
async waitForReady() {
// Wait for cache initialization
await this.initPromise;
// Wait for console interceptor to be ready if enabled
if (this.options.logging?.consoleInterception?.enabled &&
this.consoleInterceptor) {
// Give console interceptor a moment to fully initialize
await new Promise((resolve) => setTimeout(resolve, 10));
}
// Mark as ready
this.ready = true;
this.logger.debug("server", "All components initialized and ready");
}
/**
* Get the RequestPreCompiler instance for configuration
*/
getRequestPreCompiler() {
return this.performanceManager.getRequestPreCompiler();
}
/**
* Get the ConsoleInterceptor instance for configuration
*/
getConsoleInterceptor() {
return this.consoleInterceptor;
}
/**
* Merge user options with defaults and file config
*/
mergeWithDefaults(userOptions, fileConfig = null) {
const defaults = _default.DEFAULT_OPTIONS;
// Use ConfigLoader's merge function for proper deep merging
return ConfigLoader.ConfigLoader.mergeConfigs(defaults, fileConfig, userOptions);
}
/**
* Handle automatic port switching when port is in use
*/
async handlePortSwitching(requestedPort) {
const portManager = new PortManager.PortManager(requestedPort, this.options.server?.autoPortSwitch);
const result = await portManager.findAvailablePort();
if (result.switched) {
this.logger.portSwitching("server", `🔄 Port ${requestedPort} was in use, switched to port ${result.port}`);
this.logger.portSwitching("server", ` Attempts: ${result.attempts}, Strategy: ${portManager.getConfig()?.strategy || "increment"}`);
}
if (!result.success) {
const maxAttempts = this.options.server?.autoPortSwitch?.maxAttempts || 10;
throw new Error(`Failed to find an available port after ${maxAttempts} attempts. ` +
`Original port: ${requestedPort}, Last attempted: ${result.port}`);
}
return result;
}
/**
* Start server with error handling and port switching
*/
async startServerWithPortHandling(port, host, callback) {
try {
// Try to start server on the requested port
return new Promise((resolve, reject) => {
const server = this.app.listen(port, host, () => {
this.currentPort = port; // Track the actual running port
this.logger.info("server", `Server running on ${host}:${port}`);
this.logger.info("server", `State: ${this.ready ? "Ready" : "Initializing..."}`);
if (callback)
callback();
resolve(server);
});
server.on("error", async (error) => {
if (error.code === "EADDRINUSE") {
// Port is in use, try auto-switching if enabled
if (this.options.server?.autoPortSwitch?.enabled) {
try {
const result = await this.handlePortSwitching(port);
// Recursively try with the new port
const newServer = await this.startServerWithPortHandling(result.port, host, callback);
resolve(newServer);
}
catch (switchError) {
reject(switchError);
}
}
else {
reject(new Error(`Failed to start server. Port ${port} is already in use. ` +
`Enable autoPortSwitch in server config to automatically find an available port.`));
}
}
else {
reject(error);
}
});
});
}
catch (error) {
throw error;
}
}
/**
* Add start method to app with cluster support
*/
addStartMethod() {
this.app.start = async (port, callback) => {
const serverPort = port || this.options.server?.port || 3000;
const host = this.options.server?.host || "localhost";
// If we're in main process and hot reloader is enabled, start it first
if (this.fileWatcherManager.isInMainProcess() &&
this.fileWatcherManager.getHotReloader()) {
this.logger.startup("fileWatcher", "Starting with hot reload support...");
try {
// Start the hot reloader (which will spawn child process)
await this.fileWatcherManager.getHotReloader().start();
// Start file watcher in main process to monitor changes
if (this.fileWatcherManager.getFileWatcher()) {
await this.fileWatcherManager.startFileWatcherWithHotReload();
}
// Start the actual HTTP server in the main process too
this.httpServer = await this.startServerWithPortHandling(serverPort, host, async () => {
this.fileWatcherManager.setHttpServer(this.httpServer);
if (callback)
callback();
});
return this.httpServer;
}
catch (error) {
this.logger.error("fileWatcher", "Hot reload startup failed:", error.message);
// Fall through to regular startup
}
}
// Regular startup (child process or hot reload disabled)
// If cluster is enabled, use cluster manager
if (this.clusterManager.isClusterEnabled()) {
// console.log("Starting cluster...");
try {
// Start cluster manager
await this.clusterManager.startCluster();
// Check if we're in master or worker process
if (process.env.NODE_ENV !== "worker") {
this.logger.startup("cluster", "Starting as cluster master process");
// Setup cluster event handlers
this.clusterManager.setupClusterEventHandlers();
// Start HTTP server in master process
this.httpServer =
await this.startServerWithPortHandling(serverPort, host, async () => {
// Set HTTP server reference for file watcher restarts
this.fileWatcherManager.setHttpServer(this.httpServer);
const clusterStats = await this.clusterManager.getClusterStats();
this.logger.debug("cluster", `Cluster master started with ${clusterStats.workers?.total || 0} workers`);
// Start file watcher if enabled
if (this.fileWatcherManager.getFileWatcher()) {
if (this.fileWatcherManager.isInMainProcess()) {
// Main process: start with hot reload
await this.fileWatcherManager.startFileWatcherWithHotReload();
}
else {
// Child process: start regular file watcher
await this.fileWatcherManager.startFileWatcher();
}
}
if (callback)
callback();
});
return this.httpServer;
}
else {
// Worker process
this.logger.startup("cluster", `Worker ${process.pid} started`);
const httpServer = await this.startServerWithPortHandling(serverPort, host, () => {
this.logger.info("cluster", `Worker ${process.pid} listening on ${host}:${serverPort}`);
if (callback)
callback();
});
return httpServer;
}
}
catch (error) {
this.logger.error("cluster", "Failed to start cluster:", error.message);
// Fallback to single process
this.logger.info("cluster", "Falling back to single process mode");
}
}
// Single process mode (default)
this.httpServer = await this.startServerWithPortHandling(serverPort, host, async () => {
// Set HTTP server reference for file watcher restarts
this.fileWatcherManager.setHttpServer(this.httpServer);
// Start file watcher if enabled
if (this.fileWatcherManager.getFileWatcher()) {
if (this.fileWatcherManager.isInMainProcess()) {
// Main process: start with hot reload
await this.fileWatcherManager.startFileWatcherWithHotReload();
}
else {
// Child process: start regular file watcher
await this.fileWatcherManager.startFileWatcher();
}
}
if (callback)
callback();
});
return this.httpServer;
};
this.app.waitForReady = () => this.waitForReady();
// Add port management methods
this.app.getPort = () => this.getPort();
this.app.forceClosePort = (port) => this.forceClosePort(port);
this.app.redirectFromPort = (fromPort, toPort, options) => this.redirectManager.redirectFromPort(fromPort, toPort, options);
// Add advanced redirect management methods
this.app.getRedirectInstance = (fromPort) => this.redirectManager.getRedirectInstance(fromPort);
this.app.getAllRedirectInstances = () => this.redirectManager.getAllRedirectInstances();
this.app.disconnectRedirect = (fromPort) => this.redirectManager.disconnectRedirect(fromPort);
this.app.disconnectAllRedirects = () => this.redirectManager.disconnectAllRedirects();
this.app.getRedirectStats = (fromPort) => this.redirectManager.getRedirectStats(fromPort);
// Cluster methods are already added in constructor if cluster is enabled
}
// File watcher functionality now handled by FileWatcherManager component
/**
* Stop file watcher
*/
async stopFileWatcher() {
await this.fileWatcherManager.stopFileWatcher();
}
/**
* Get file watcher status
*/
getFileWatcherStatus() {
return this.fileWatcherManager.getFileWatcherStatus();
}
/**
* Get file watcher restart stats
*/
getFileWatcherStats() {
return this.fileWatcherManager.getFileWatcherStats();
}
// ===== PLUGIN MANAGEMENT METHODS =====
/**
* Register a plugin with the server
*/
async registerPlugin(plugin) {
await this.pluginManager.registerPlugin(plugin);
}
/**
* Unregister a plugin from the server
*/
async unregisterPlugin(pluginId) {
await this.pluginManager.unregisterPlugin(pluginId);
}
/**
* Get plugin by ID
*/
getPlugin(pluginId) {
return this.pluginManager.getPlugin(pluginId);
}
/**
* Get all registered plugins
*/
getAllPlugins() {
return this.pluginManager.getAllPlugins();
}
/**
* Get plugins by type
*/
getPluginsByType(type) {
return this.pluginManager.getPluginsByType(type);
}
/**
* Get plugin execution statistics
*/
getPluginStats(pluginId) {
return this.pluginManager.getPluginStats(pluginId);
}
/**
* Get plugin registry statistics
*/
getPluginRegistryStats() {
return this.pluginManager.getPluginRegistryStats();
}
/**
* Get plugin engine statistics
*/
getPluginEngineStats() {
return this.pluginManager.getPluginEngineStats();
}
/**
* Initialize built-in plugins
*/
async initializeBuiltinPlugins() {
try {
// Import and register built-in plugins
const { JWTAuthPlugin } = await Promise.resolve().then(function () { return require('./plugins/builtin/JWTAuthPlugin.js'); });
const { ResponseTimePlugin } = await Promise.resolve().then(function () { return require('./plugins/builtin/ResponseTimePlugin.js'); });
const { SmartCachePlugin } = await Promise.resolve().then(function () { return require('./plugins/builtin/SmartCachePlugin.js'); });
// Register security plugins
await this.registerPlugin(new JWTAuthPlugin());
// Register performance plugins
await this.registerPlugin(new ResponseTimePlugin());
// Register cache plugins
await this.registerPlugin(new SmartCachePlugin());
this.logger.debug("plugins", "Built-in plugins initialized successfully");
}
catch (error) {
this.logger.error("plugins", "Failed to initialize built-in plugins:", error.message);
}
}
/**
* Get comprehensive server statistics including plugins
*/
async getServerStats() {
const cacheStats = await this.cacheManager.getCacheStats();
const pluginRegistryStats = this.getPluginRegistryStats();
const pluginEngineStats = this.getPluginEngineStats();
return {
server: {
ready: this.ready,
uptime: process.uptime(),
memoryUsage: process.memoryUsage(),
cpuUsage: process.cpuUsage(),
},
cache: cacheStats,
plugins: {
registry: pluginRegistryStats,
engine: pluginEngineStats,
totalPlugins: pluginRegistryStats.totalPlugins,
averageExecutionTime: pluginRegistryStats.averageExecutionTime,
},
cluster: await this.clusterManager.getClusterStats(),
fileWatcher: this.getFileWatcherStats(),
};
}
// ===== CONSOLE INTERCEPTION METHODS =====
/**
* Add console interception methods to the Express app
*/
addConsoleInterceptionMethods() {
// Get console interceptor instance
this.app.getConsoleInterceptor = () => {
return this.consoleInterceptor;
};
// Enable console interception
this.app.enableConsoleInterception = () => {
this.consoleInterceptor.start();
};
// Disable console interception
this.app.disableConsoleInterception = () => {
this.consoleInterceptor.stop();
};
// Get console interception statistics
this.app.getConsoleStats = () => {
return this.consoleInterceptor.getStats();
};
// Reset console interception statistics
this.app.resetConsoleStats = () => {
this.consoleInterceptor.resetStats();
};
// File watcher methods
this.app.getFileWatcherStatus = () => {
return this.getFileWatcherStatus();
};
this.app.getFileWatcherStats = () => {
return this.getFileWatcherStats();
};
this.app.stopFileWatcher = async () => {
return await this.stopFileWatcher();
};
// TypeScript checking methods
this.app.checkTypeScript = async (files) => {
return await this.fileWatcherManager.checkTypeScript(files);
};
this.app.getTypeScriptStatus = () => {
return this.fileWatcherManager.getTypeScriptStatus();
};
this.app.enableTypeScriptChecking = () => {
this.fileWatcherManager.enableTypeScriptChecking();
};
this.app.disableTypeScriptChecking = () => {
this.fileWatcherManager.disableTypeScriptChecking();
};
// TypeScript checking methods
this.app.checkTypeScript = async (files) => {
return await this.fileWatcherManager.checkTypeScript(files);
};
this.app.getTypeScriptStatus = () => {
return this.fileWatcherManager.getTypeScriptStatus();
};
this.app.enableTypeScriptChecking = () => {
this.fileWatcherManager.enableTypeScriptChecking();
};
this.app.disableTypeScriptChecking = () => {
this.fileWatcherManager.disableTypeScriptChecking();
};
// 🔐 Console encryption methods
this.app.enableConsoleEncryption = (key) => {
this.consoleInterceptor.enableEncryption(key);
};
this.app.disableConsoleEncryption = () => {
this.consoleInterceptor.disableEncryption();
};
// Simple encrypt method
this.app.encrypt = (key) => {
this.consoleInterceptor.encrypt(key);
};
this.app.setConsoleEncryptionKey = (key) => {
this.consoleInterceptor.setEncryptionKey(key);
};
this.app.setConsoleEncryptionDisplayMode = (displayMode, showEncryptionStatus) => {
this.consoleInterceptor.setEncryptionDisplayMode(displayMode, showEncryptionStatus);
};
this.app.getEncryptedLogs = () => {
return this.consoleInterceptor.getEncryptedLogs();
};
this.app.restoreConsoleFromEncrypted = async (encryptedData, key) => {
return await this.consoleInterceptor.restoreFromEncrypted(encryptedData, key);
};
this.app.isConsoleEncryptionEnabled = () => {
return this.consoleInterceptor.isEncryptionEnabled();
};
this.app.getConsoleEncryptionStatus = () => {
return this.consoleInterceptor.getEncryptionStatus();
};
}
// ===== PORT MANAGEMENT METHODS =====
/**
* Get the actual running port number
* @returns The current port the server is running on
*/
getPort() {
return this.currentPort;
}
/**
* Attempt to forcefully close/free up the specified port
* @param port - The port number to force close
* @returns Promise<boolean> - true if successful, false if failed
*/
async forceClosePort(port) {
return await new forceClosePort.Port(port).forceClosePort();
}
}
exports.FastServer = UltraFastServer;
exports.UltraFastServer = UltraFastServer;
//# sourceMappingURL=FastServer.js.map