@superdangerous/app-framework 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +652 -0
  3. package/dist/api/logsRouter.d.ts +20 -0
  4. package/dist/api/logsRouter.d.ts.map +1 -0
  5. package/dist/api/logsRouter.js +515 -0
  6. package/dist/api/logsRouter.js.map +1 -0
  7. package/dist/cli/dev-server.d.ts +7 -0
  8. package/dist/cli/dev-server.d.ts.map +1 -0
  9. package/dist/cli/dev-server.js +640 -0
  10. package/dist/cli/dev-server.js.map +1 -0
  11. package/dist/cli/index.d.ts +7 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +26 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/core/StandardServer.d.ts +129 -0
  16. package/dist/core/StandardServer.d.ts.map +1 -0
  17. package/dist/core/StandardServer.js +453 -0
  18. package/dist/core/StandardServer.js.map +1 -0
  19. package/dist/core/apiResponse.d.ts +69 -0
  20. package/dist/core/apiResponse.d.ts.map +1 -0
  21. package/dist/core/apiResponse.js +127 -0
  22. package/dist/core/apiResponse.js.map +1 -0
  23. package/dist/core/healthCheck.d.ts +160 -0
  24. package/dist/core/healthCheck.d.ts.map +1 -0
  25. package/dist/core/healthCheck.js +398 -0
  26. package/dist/core/healthCheck.js.map +1 -0
  27. package/dist/core/index.d.ts +40 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +40 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/logger.d.ts +117 -0
  32. package/dist/core/logger.d.ts.map +1 -0
  33. package/dist/core/logger.js +826 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/portUtils.d.ts +71 -0
  36. package/dist/core/portUtils.d.ts.map +1 -0
  37. package/dist/core/portUtils.js +240 -0
  38. package/dist/core/portUtils.js.map +1 -0
  39. package/dist/core/storageService.d.ts +119 -0
  40. package/dist/core/storageService.d.ts.map +1 -0
  41. package/dist/core/storageService.js +405 -0
  42. package/dist/core/storageService.js.map +1 -0
  43. package/dist/desktop/bundler.d.ts +40 -0
  44. package/dist/desktop/bundler.d.ts.map +1 -0
  45. package/dist/desktop/bundler.js +176 -0
  46. package/dist/desktop/bundler.js.map +1 -0
  47. package/dist/desktop/index.d.ts +25 -0
  48. package/dist/desktop/index.d.ts.map +1 -0
  49. package/dist/desktop/index.js +15 -0
  50. package/dist/desktop/index.js.map +1 -0
  51. package/dist/desktop/native-modules.d.ts +66 -0
  52. package/dist/desktop/native-modules.d.ts.map +1 -0
  53. package/dist/desktop/native-modules.js +200 -0
  54. package/dist/desktop/native-modules.js.map +1 -0
  55. package/dist/index.d.ts +29 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +39 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/logging/LogCategories.d.ts +87 -0
  60. package/dist/logging/LogCategories.d.ts.map +1 -0
  61. package/dist/logging/LogCategories.js +205 -0
  62. package/dist/logging/LogCategories.js.map +1 -0
  63. package/dist/middleware/aiErrorHandler.d.ts +31 -0
  64. package/dist/middleware/aiErrorHandler.d.ts.map +1 -0
  65. package/dist/middleware/aiErrorHandler.js +181 -0
  66. package/dist/middleware/aiErrorHandler.js.map +1 -0
  67. package/dist/middleware/auth.d.ts +101 -0
  68. package/dist/middleware/auth.d.ts.map +1 -0
  69. package/dist/middleware/auth.js +230 -0
  70. package/dist/middleware/auth.js.map +1 -0
  71. package/dist/middleware/cors.d.ts +56 -0
  72. package/dist/middleware/cors.d.ts.map +1 -0
  73. package/dist/middleware/cors.js +123 -0
  74. package/dist/middleware/cors.js.map +1 -0
  75. package/dist/middleware/errorHandler.d.ts +13 -0
  76. package/dist/middleware/errorHandler.d.ts.map +1 -0
  77. package/dist/middleware/errorHandler.js +85 -0
  78. package/dist/middleware/errorHandler.js.map +1 -0
  79. package/dist/middleware/fileUpload.d.ts +62 -0
  80. package/dist/middleware/fileUpload.d.ts.map +1 -0
  81. package/dist/middleware/fileUpload.js +175 -0
  82. package/dist/middleware/fileUpload.js.map +1 -0
  83. package/dist/middleware/health.d.ts +48 -0
  84. package/dist/middleware/health.d.ts.map +1 -0
  85. package/dist/middleware/health.js +143 -0
  86. package/dist/middleware/health.js.map +1 -0
  87. package/dist/middleware/index.d.ts +20 -0
  88. package/dist/middleware/index.d.ts.map +1 -0
  89. package/dist/middleware/index.js +18 -0
  90. package/dist/middleware/index.js.map +1 -0
  91. package/dist/middleware/openapi.d.ts +64 -0
  92. package/dist/middleware/openapi.d.ts.map +1 -0
  93. package/dist/middleware/openapi.js +258 -0
  94. package/dist/middleware/openapi.js.map +1 -0
  95. package/dist/middleware/requestLogging.d.ts +22 -0
  96. package/dist/middleware/requestLogging.d.ts.map +1 -0
  97. package/dist/middleware/requestLogging.js +61 -0
  98. package/dist/middleware/requestLogging.js.map +1 -0
  99. package/dist/middleware/session.d.ts +84 -0
  100. package/dist/middleware/session.d.ts.map +1 -0
  101. package/dist/middleware/session.js +189 -0
  102. package/dist/middleware/session.js.map +1 -0
  103. package/dist/middleware/validation.d.ts +1337 -0
  104. package/dist/middleware/validation.d.ts.map +1 -0
  105. package/dist/middleware/validation.js +483 -0
  106. package/dist/middleware/validation.js.map +1 -0
  107. package/dist/services/aiService.d.ts +180 -0
  108. package/dist/services/aiService.d.ts.map +1 -0
  109. package/dist/services/aiService.js +547 -0
  110. package/dist/services/aiService.js.map +1 -0
  111. package/dist/services/conversationStorage.d.ts +38 -0
  112. package/dist/services/conversationStorage.d.ts.map +1 -0
  113. package/dist/services/conversationStorage.js +158 -0
  114. package/dist/services/conversationStorage.js.map +1 -0
  115. package/dist/services/crossPlatformBuffer.d.ts +84 -0
  116. package/dist/services/crossPlatformBuffer.d.ts.map +1 -0
  117. package/dist/services/crossPlatformBuffer.js +246 -0
  118. package/dist/services/crossPlatformBuffer.js.map +1 -0
  119. package/dist/services/index.d.ts +17 -0
  120. package/dist/services/index.d.ts.map +1 -0
  121. package/dist/services/index.js +18 -0
  122. package/dist/services/index.js.map +1 -0
  123. package/dist/services/networkService.d.ts +81 -0
  124. package/dist/services/networkService.d.ts.map +1 -0
  125. package/dist/services/networkService.js +268 -0
  126. package/dist/services/networkService.js.map +1 -0
  127. package/dist/services/queueService.d.ts +112 -0
  128. package/dist/services/queueService.d.ts.map +1 -0
  129. package/dist/services/queueService.js +338 -0
  130. package/dist/services/queueService.js.map +1 -0
  131. package/dist/services/settingsService.d.ts +135 -0
  132. package/dist/services/settingsService.d.ts.map +1 -0
  133. package/dist/services/settingsService.js +425 -0
  134. package/dist/services/settingsService.js.map +1 -0
  135. package/dist/services/systemMonitor.d.ts +208 -0
  136. package/dist/services/systemMonitor.d.ts.map +1 -0
  137. package/dist/services/systemMonitor.js +693 -0
  138. package/dist/services/systemMonitor.js.map +1 -0
  139. package/dist/services/updateService.d.ts +78 -0
  140. package/dist/services/updateService.d.ts.map +1 -0
  141. package/dist/services/updateService.js +252 -0
  142. package/dist/services/updateService.js.map +1 -0
  143. package/dist/services/websocketEvents.d.ts +372 -0
  144. package/dist/services/websocketEvents.d.ts.map +1 -0
  145. package/dist/services/websocketEvents.js +338 -0
  146. package/dist/services/websocketEvents.js.map +1 -0
  147. package/dist/services/websocketServer.d.ts +80 -0
  148. package/dist/services/websocketServer.d.ts.map +1 -0
  149. package/dist/services/websocketServer.js +299 -0
  150. package/dist/services/websocketServer.js.map +1 -0
  151. package/dist/settings/SettingsSchema.d.ts +151 -0
  152. package/dist/settings/SettingsSchema.d.ts.map +1 -0
  153. package/dist/settings/SettingsSchema.js +424 -0
  154. package/dist/settings/SettingsSchema.js.map +1 -0
  155. package/dist/testing/TestServer.d.ts +69 -0
  156. package/dist/testing/TestServer.d.ts.map +1 -0
  157. package/dist/testing/TestServer.js +250 -0
  158. package/dist/testing/TestServer.js.map +1 -0
  159. package/dist/types/index.d.ts +137 -0
  160. package/dist/types/index.d.ts.map +1 -0
  161. package/dist/types/index.js +5 -0
  162. package/dist/types/index.js.map +1 -0
  163. package/dist/utils/appPaths.d.ts +74 -0
  164. package/dist/utils/appPaths.d.ts.map +1 -0
  165. package/dist/utils/appPaths.js +162 -0
  166. package/dist/utils/appPaths.js.map +1 -0
  167. package/dist/utils/fs-utils.d.ts +50 -0
  168. package/dist/utils/fs-utils.d.ts.map +1 -0
  169. package/dist/utils/fs-utils.js +114 -0
  170. package/dist/utils/fs-utils.js.map +1 -0
  171. package/dist/utils/index.d.ts +12 -0
  172. package/dist/utils/index.d.ts.map +1 -0
  173. package/dist/utils/index.js +10 -0
  174. package/dist/utils/index.js.map +1 -0
  175. package/dist/utils/standardConfig.d.ts +61 -0
  176. package/dist/utils/standardConfig.d.ts.map +1 -0
  177. package/dist/utils/standardConfig.js +109 -0
  178. package/dist/utils/standardConfig.js.map +1 -0
  179. package/dist/utils/startupBanner.d.ts +34 -0
  180. package/dist/utils/startupBanner.d.ts.map +1 -0
  181. package/dist/utils/startupBanner.js +169 -0
  182. package/dist/utils/startupBanner.js.map +1 -0
  183. package/dist/utils/startupLogger.d.ts +45 -0
  184. package/dist/utils/startupLogger.d.ts.map +1 -0
  185. package/dist/utils/startupLogger.js +200 -0
  186. package/dist/utils/startupLogger.js.map +1 -0
  187. package/package.json +151 -0
  188. package/src/api/logsRouter.ts +600 -0
  189. package/src/cli/dev-server.ts +803 -0
  190. package/src/cli/index.ts +31 -0
  191. package/src/core/StandardServer.ts +587 -0
  192. package/src/core/apiResponse.ts +202 -0
  193. package/src/core/healthCheck.ts +565 -0
  194. package/src/core/index.ts +80 -0
  195. package/src/core/logger.ts +1092 -0
  196. package/src/core/portUtils.ts +319 -0
  197. package/src/core/storageService.ts +595 -0
  198. package/src/desktop/bundler.ts +271 -0
  199. package/src/desktop/index.ts +18 -0
  200. package/src/desktop/native-modules.ts +289 -0
  201. package/src/index.ts +142 -0
  202. package/src/logging/LogCategories.ts +302 -0
  203. package/src/middleware/aiErrorHandler.ts +278 -0
  204. package/src/middleware/auth.ts +329 -0
  205. package/src/middleware/cors.ts +187 -0
  206. package/src/middleware/errorHandler.ts +103 -0
  207. package/src/middleware/fileUpload.ts +252 -0
  208. package/src/middleware/health.ts +206 -0
  209. package/src/middleware/index.ts +71 -0
  210. package/src/middleware/openapi.ts +305 -0
  211. package/src/middleware/requestLogging.ts +92 -0
  212. package/src/middleware/session.ts +238 -0
  213. package/src/middleware/validation.ts +603 -0
  214. package/src/services/aiService.ts +789 -0
  215. package/src/services/conversationStorage.ts +232 -0
  216. package/src/services/crossPlatformBuffer.ts +341 -0
  217. package/src/services/index.ts +47 -0
  218. package/src/services/networkService.ts +351 -0
  219. package/src/services/queueService.ts +446 -0
  220. package/src/services/settingsService.ts +549 -0
  221. package/src/services/systemMonitor.ts +936 -0
  222. package/src/services/updateService.ts +334 -0
  223. package/src/services/websocketEvents.ts +409 -0
  224. package/src/services/websocketServer.ts +394 -0
  225. package/src/settings/SettingsSchema.ts +664 -0
  226. package/src/testing/TestServer.ts +312 -0
  227. package/src/types/index.ts +154 -0
  228. package/src/utils/appPaths.ts +196 -0
  229. package/src/utils/fs-utils.ts +130 -0
  230. package/src/utils/index.ts +15 -0
  231. package/src/utils/standardConfig.ts +178 -0
  232. package/src/utils/startupBanner.ts +287 -0
  233. package/src/utils/startupLogger.ts +268 -0
  234. package/ui/dist/index.d.mts +1221 -0
  235. package/ui/dist/index.d.ts +1221 -0
  236. package/ui/dist/index.js +73 -0
  237. package/ui/dist/index.js.map +1 -0
  238. package/ui/dist/index.mjs +73 -0
  239. package/ui/dist/index.mjs.map +1 -0
@@ -0,0 +1,453 @@
1
+ /**
2
+ * Standard Server Implementation
3
+ * A simplified, consistent server pattern for all SuperDangerous applications
4
+ * Combines the best of StartupOrchestrator with the simplicity apps need
5
+ */
6
+ import express from "express";
7
+ import { createServer } from "http";
8
+ import cors from "cors";
9
+ import { createWebSocketServer } from "../services/websocketServer.js";
10
+ import { displayStartupBanner } from "../utils/startupBanner.js";
11
+ import { getProcessOnPort } from "./portUtils.js";
12
+ import { createLogger, getLogger } from "./index.js";
13
+ import { aiErrorHandler } from "../middleware/aiErrorHandler.js";
14
+ import { apiErrorHandler } from "./apiResponse.js";
15
+ import { createRequestLoggingMiddleware } from "../middleware/requestLogging.js";
16
+ import { getAppDataPath, getLogsPath, isDesktopApp, } from "../utils/appPaths.js";
17
+ let logger; // Will be initialized when needed
18
+ function ensureLogger() {
19
+ if (!logger) {
20
+ logger = createLogger("Server");
21
+ }
22
+ return logger;
23
+ }
24
+ /**
25
+ * Standard server implementation that all apps should use
26
+ * Handles startup, error handling, and banner display consistently
27
+ */
28
+ export class StandardServer {
29
+ app;
30
+ httpServer;
31
+ config;
32
+ wsServer;
33
+ startTime;
34
+ isInitialized = false;
35
+ shuttingDown = false;
36
+ signalsBound = false;
37
+ connections = new Set();
38
+ constructor(config) {
39
+ const environment = process.env.NODE_ENV || "development";
40
+ // Default to localhost for development/test, 0.0.0.0 for production/containerized environments
41
+ const defaultHost = environment === "development" || environment === "test"
42
+ ? "localhost"
43
+ : "0.0.0.0";
44
+ // Auto-enable desktop integration if running in Electron or explicitly enabled
45
+ const enableDesktopIntegration = config.enableDesktopIntegration ?? isDesktopApp();
46
+ this.config = {
47
+ port: 8080,
48
+ host: process.env.HOST || config.host || defaultHost,
49
+ environment,
50
+ enableWebSocket: true,
51
+ bodyLimit: "10mb",
52
+ requestTimeoutMs: 120_000,
53
+ headersTimeoutMs: 65_000,
54
+ keepAliveTimeoutMs: 60_000,
55
+ gracefulShutdownSignals: ["SIGTERM", "SIGINT"],
56
+ enableRequestLogging: true,
57
+ enableDesktopIntegration,
58
+ appId: config.appId ||
59
+ `com.company.${config.appName.toLowerCase().replace(/[^a-z0-9]/g, "-")}`,
60
+ exitOnStartupError: config.exitOnStartupError ?? process.env.NODE_ENV !== "test",
61
+ ...config,
62
+ };
63
+ this.app = express();
64
+ this.httpServer = createServer(this.app);
65
+ this.httpServer.on("connection", (socket) => {
66
+ this.connections.add(socket);
67
+ socket.on("close", () => this.connections.delete(socket));
68
+ });
69
+ this.startTime = Date.now();
70
+ this.bindShutdownSignals();
71
+ }
72
+ /**
73
+ * Get the Express app instance for middleware setup
74
+ */
75
+ getApp() {
76
+ return this.app;
77
+ }
78
+ /**
79
+ * Get the HTTP server instance
80
+ */
81
+ getServer() {
82
+ return this.httpServer;
83
+ }
84
+ /**
85
+ * Initialize the server (setup middleware, routes, etc.)
86
+ */
87
+ async initialize() {
88
+ if (this.isInitialized)
89
+ return;
90
+ this.isInitialized = true;
91
+ try {
92
+ // Setup desktop-specific paths, CORS, and logging if running as desktop app
93
+ if (this.config.enableDesktopIntegration) {
94
+ await this.setupDesktopIntegration();
95
+ }
96
+ // Initialize the logger first to ensure file output works
97
+ const logger = getLogger;
98
+ if (logger &&
99
+ typeof logger.isInitialized === "function" &&
100
+ !logger.isInitialized()) {
101
+ // Use proper logs directory for desktop apps
102
+ const logsDir = this.config.enableDesktopIntegration
103
+ ? getLogsPath(this.config.appId, this.config.appName)
104
+ : "./data/logs";
105
+ await logger.initialize({
106
+ appName: this.config.appName,
107
+ logLevel: this.config.logging?.level || process.env.LOG_LEVEL || "info",
108
+ consoleOutput: true,
109
+ fileOutput: true,
110
+ logsDir,
111
+ });
112
+ }
113
+ // Setup default middleware
114
+ this.setupDefaultMiddleware();
115
+ // Initialize WebSocket if enabled (before onInitialize so it can be passed)
116
+ if (this.config.enableWebSocket) {
117
+ this.wsServer = await Promise.resolve(createWebSocketServer(this.httpServer));
118
+ }
119
+ // Call custom initialization if provided, passing the WebSocket server
120
+ if (this.config.onInitialize) {
121
+ const wantsWebSocket = this.config.onInitialize.length >= 2;
122
+ if (wantsWebSocket) {
123
+ await this.config.onInitialize(this.app, this.wsServer);
124
+ }
125
+ else {
126
+ await this.config.onInitialize(this.app);
127
+ }
128
+ }
129
+ // Setup error handlers (should be last)
130
+ this.setupErrorHandlers();
131
+ }
132
+ catch (_error) {
133
+ ensureLogger().error("Server initialization failed:", _error);
134
+ this.isInitialized = false;
135
+ throw _error;
136
+ }
137
+ }
138
+ /**
139
+ * Setup desktop app integration (CORS, data paths, logging, etc.)
140
+ */
141
+ async setupDesktopIntegration() {
142
+ ensureLogger().info("Setting up desktop app integration", {
143
+ appId: this.config.appId,
144
+ isDesktopApp: isDesktopApp(),
145
+ dataPath: this.config.desktopDataPath ||
146
+ getAppDataPath(this.config.appId, this.config.appName),
147
+ });
148
+ // Initialize logging for desktop apps
149
+ const logger = getLogger;
150
+ if (!logger.isInitialized()) {
151
+ const logsDir = getLogsPath(this.config.appId, this.config.appName);
152
+ await logger.initialize({
153
+ appName: this.config.appName,
154
+ logLevel: process.env.LOG_LEVEL || "info",
155
+ consoleOutput: true,
156
+ fileOutput: true,
157
+ logsDir,
158
+ });
159
+ ensureLogger().info("Logging initialized for desktop app", { logsDir });
160
+ }
161
+ // Setup CORS for desktop apps
162
+ const corsOrigins = [...(this.config.corsOrigins || [])];
163
+ // Add localhost origins based on webPort if specified
164
+ if (this.config.webPort) {
165
+ corsOrigins.push(`http://localhost:${this.config.webPort}`, `http://localhost:${this.config.webPort + 1}`);
166
+ }
167
+ // Add Electron origins when running in desktop mode
168
+ if (isDesktopApp()) {
169
+ // Electron file:// protocol sends null or file:// origin
170
+ corsOrigins.push("file://", "null");
171
+ }
172
+ this.app.use(cors({
173
+ origin: corsOrigins,
174
+ credentials: true,
175
+ }));
176
+ }
177
+ /**
178
+ * Setup default middleware for all applications
179
+ */
180
+ setupDefaultMiddleware() {
181
+ // Basic middleware that should be present in all apps
182
+ this.app.use(express.json({ limit: this.config.bodyLimit }));
183
+ this.app.use(express.urlencoded({ extended: true, limit: this.config.bodyLimit }));
184
+ // CORS setup for non-desktop apps (desktop setup happens in setupDesktopIntegration)
185
+ if (!this.config.enableDesktopIntegration) {
186
+ const corsOrigins = [...(this.config.corsOrigins || [])];
187
+ // Add localhost origins based on webPort if specified
188
+ if (this.config.webPort) {
189
+ corsOrigins.push(`http://localhost:${this.config.webPort}`, `http://localhost:${this.config.webPort + 1}`);
190
+ }
191
+ if (corsOrigins.length > 0) {
192
+ this.app.use(cors({
193
+ origin: corsOrigins,
194
+ credentials: true,
195
+ }));
196
+ }
197
+ else {
198
+ this.app.use(cors());
199
+ }
200
+ }
201
+ // Request logging (can be disabled)
202
+ if (this.config.enableRequestLogging) {
203
+ this.app.use(createRequestLoggingMiddleware({
204
+ logger: ensureLogger(),
205
+ ...this.config.requestLogging,
206
+ }));
207
+ }
208
+ // Trust proxy to respect X-Forwarded-* headers in containerized/proxy envs
209
+ const trustProxy = this.config.trustProxy ??
210
+ (this.config.environment !== "development" ? true : false);
211
+ if (typeof this.app.set === "function") {
212
+ this.app.set("trust proxy", trustProxy);
213
+ }
214
+ }
215
+ /**
216
+ * Setup error handlers (should be last in middleware chain)
217
+ */
218
+ setupErrorHandlers() {
219
+ // AI error handler for AI service errors
220
+ this.app.use(aiErrorHandler);
221
+ // Standardized API error handler
222
+ this.app.use(apiErrorHandler);
223
+ }
224
+ /**
225
+ * Start the server and listen on the configured port
226
+ */
227
+ async start() {
228
+ if (!this.isInitialized) {
229
+ throw new Error("Server not initialized. Call initialize() first.");
230
+ }
231
+ const port = this.config.port;
232
+ const host = this.config.host;
233
+ const exitOnError = this.config.exitOnStartupError !== false;
234
+ // Check if API port is available (skip for port 0 which means "pick any available")
235
+ if (port !== 0) {
236
+ const processOnPort = await getProcessOnPort(port);
237
+ if (processOnPort) {
238
+ const message = `Port ${port} is already in use`;
239
+ if (exitOnError) {
240
+ ensureLogger().error(message);
241
+ process.exit(1);
242
+ }
243
+ else {
244
+ ensureLogger().warn(`${message} (PID ${processOnPort.pid} - ${processOnPort.command})`);
245
+ return;
246
+ }
247
+ }
248
+ }
249
+ return new Promise((resolve, reject) => {
250
+ const fail = (error) => {
251
+ ensureLogger().error("Server error:", error);
252
+ if (exitOnError) {
253
+ process.exit(1);
254
+ }
255
+ reject(error);
256
+ };
257
+ // Handle server errors
258
+ this.httpServer.on("error", (error) => {
259
+ if (error.code === "EADDRINUSE") {
260
+ const message = `Port ${port} is already in use`;
261
+ ensureLogger().error(message);
262
+ if (exitOnError) {
263
+ process.exit(1);
264
+ }
265
+ reject(new Error(message));
266
+ return;
267
+ }
268
+ else if (error.code === "EACCES") {
269
+ const message = `Port ${port} requires elevated privileges`;
270
+ ensureLogger().error(message);
271
+ if (exitOnError) {
272
+ process.exit(1);
273
+ }
274
+ reject(new Error(message));
275
+ return;
276
+ }
277
+ else {
278
+ fail(error instanceof Error ? error : new Error(String(error)));
279
+ return;
280
+ }
281
+ });
282
+ // Start listening
283
+ // Apply safer timeouts for production workloads
284
+ this.httpServer.requestTimeout = this.config.requestTimeoutMs;
285
+ this.httpServer.headersTimeout = this.config.headersTimeoutMs;
286
+ this.httpServer.keepAliveTimeout = this.config.keepAliveTimeoutMs;
287
+ try {
288
+ this.httpServer.listen(port, host, async () => {
289
+ // Display banner only after successful binding
290
+ // Note: In production, webPort is typically not used because the API server
291
+ // serves the UI assets directly from the main port. However, if webPort
292
+ // is explicitly configured, respect it.
293
+ // Only display banner if not suppressed
294
+ if (process.env.SUPPRESS_STARTUP_BANNER !== "true") {
295
+ displayStartupBanner({
296
+ appName: this.config.appName,
297
+ appVersion: this.config.appVersion,
298
+ description: this.config.description,
299
+ port: this.config.port,
300
+ webPort: this.config.webPort, // Pass the actual configured webPort
301
+ environment: this.config.environment,
302
+ startTime: this.startTime,
303
+ });
304
+ }
305
+ // Call custom start handler if provided
306
+ if (this.config.onStart) {
307
+ try {
308
+ await this.config.onStart();
309
+ }
310
+ catch (_error) {
311
+ const error = _error instanceof Error ? _error : new Error(String(_error));
312
+ ensureLogger().error("Custom start handler failed:", error);
313
+ if (exitOnError) {
314
+ process.exit(1);
315
+ }
316
+ reject(error);
317
+ return;
318
+ }
319
+ }
320
+ if (this.config.webPort) {
321
+ ensureLogger().info(`Web UI Port: ${this.config.webPort}`);
322
+ }
323
+ // Bind graceful shutdown signals once per instance
324
+ this.bindShutdownSignals();
325
+ resolve();
326
+ });
327
+ }
328
+ catch (err) {
329
+ const error = err instanceof Error ? err : new Error(String(err));
330
+ ensureLogger().error("Failed to start server:", error);
331
+ if (exitOnError) {
332
+ process.exit(1);
333
+ }
334
+ reject(error);
335
+ }
336
+ });
337
+ }
338
+ /**
339
+ * Get the data path for desktop apps (platform-specific)
340
+ */
341
+ getDataPath() {
342
+ if (this.config.enableDesktopIntegration) {
343
+ return (this.config.desktopDataPath ||
344
+ getAppDataPath(this.config.appId, this.config.appName));
345
+ }
346
+ return "./data";
347
+ }
348
+ /**
349
+ * Check if running as desktop app
350
+ */
351
+ isDesktopApp() {
352
+ return this.config.enableDesktopIntegration || false;
353
+ }
354
+ /**
355
+ * Attach signal listeners for graceful shutdown
356
+ */
357
+ bindShutdownSignals() {
358
+ if (this.signalsBound)
359
+ return;
360
+ if (!this.config.gracefulShutdownSignals?.length)
361
+ return;
362
+ const signals = this.config.gracefulShutdownSignals;
363
+ if (process.setMaxListeners) {
364
+ const current = process.getMaxListeners ? process.getMaxListeners() : 10;
365
+ process.setMaxListeners(Math.max(current, signals.length + 20));
366
+ }
367
+ signals.forEach((signal) => {
368
+ process.on(signal, async () => {
369
+ ensureLogger().info(`Received ${signal}, shutting down gracefully...`);
370
+ try {
371
+ await this.stop();
372
+ process.exit(0);
373
+ }
374
+ catch (error) {
375
+ ensureLogger().error("Graceful shutdown failed", error);
376
+ process.exit(1);
377
+ }
378
+ });
379
+ });
380
+ this.signalsBound = true;
381
+ }
382
+ /**
383
+ * Stop the server gracefully
384
+ */
385
+ async stop() {
386
+ if (this.shuttingDown)
387
+ return Promise.resolve();
388
+ this.shuttingDown = true;
389
+ return new Promise((resolve, reject) => {
390
+ const timeout = setTimeout(() => {
391
+ ensureLogger().warn("Force closing server after timeout");
392
+ this.forceCloseConnections();
393
+ resolve();
394
+ }, 10_000);
395
+ const close = () => {
396
+ clearTimeout(timeout);
397
+ ensureLogger().info("Server stopped gracefully");
398
+ resolve();
399
+ };
400
+ try {
401
+ if (this.wsServer?.shutdown) {
402
+ this.wsServer.shutdown();
403
+ }
404
+ if (this.wsServer?.close) {
405
+ this.wsServer.close();
406
+ }
407
+ this.httpServer.close((err) => {
408
+ if (err) {
409
+ ensureLogger().error("Error while stopping server", err);
410
+ reject(err);
411
+ return;
412
+ }
413
+ this.forceCloseConnections();
414
+ close();
415
+ });
416
+ }
417
+ catch (error) {
418
+ clearTimeout(timeout);
419
+ reject(error);
420
+ }
421
+ });
422
+ }
423
+ forceCloseConnections() {
424
+ // Prefer native closeAllConnections if available
425
+ if (typeof this.httpServer.closeAllConnections === "function") {
426
+ try {
427
+ this.httpServer.closeAllConnections();
428
+ }
429
+ catch (err) {
430
+ ensureLogger().warn("closeAllConnections failed", err);
431
+ }
432
+ }
433
+ this.connections.forEach((socket) => {
434
+ try {
435
+ socket.destroy();
436
+ }
437
+ catch {
438
+ // ignore
439
+ }
440
+ });
441
+ this.connections.clear();
442
+ }
443
+ }
444
+ /**
445
+ * Convenience function to create and start a standard server
446
+ */
447
+ export async function createStandardServer(config) {
448
+ const server = new StandardServer(config);
449
+ await server.initialize();
450
+ await server.start();
451
+ return server;
452
+ }
453
+ //# sourceMappingURL=StandardServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StandardServer.js","sourceRoot":"","sources":["../../src/core/StandardServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Standardized API Response Utilities
3
+ * Provides consistent response format across all applications
4
+ */
5
+ import { Response } from "express";
6
+ export interface ApiResponse<T = any> {
7
+ success: boolean;
8
+ data?: T;
9
+ error?: string;
10
+ message?: string;
11
+ timestamp?: string;
12
+ metadata?: Record<string, any>;
13
+ }
14
+ export interface ApiErrorResponse extends ApiResponse {
15
+ success: false;
16
+ error: string;
17
+ code?: string;
18
+ details?: any;
19
+ stack?: string;
20
+ }
21
+ export interface ApiSuccessResponse<T = any> extends ApiResponse<T> {
22
+ success: true;
23
+ data: T;
24
+ }
25
+ /**
26
+ * Send a successful response
27
+ */
28
+ export declare function sendSuccess<T = any>(res: Response, data: T, message?: string, statusCode?: number): Response<ApiSuccessResponse<T>>;
29
+ /**
30
+ * Send an error response
31
+ */
32
+ export declare function sendError(res: Response, error: string | Error, statusCode?: number, details?: any): Response<ApiErrorResponse>;
33
+ /**
34
+ * Send a validation error response
35
+ */
36
+ export declare function sendValidationError(res: Response, errors: any, message?: string): Response<ApiErrorResponse>;
37
+ /**
38
+ * Send a not found response
39
+ */
40
+ export declare function sendNotFound(res: Response, resource?: string): Response<ApiErrorResponse>;
41
+ /**
42
+ * Send an unauthorized response
43
+ */
44
+ export declare function sendUnauthorized(res: Response, message?: string): Response<ApiErrorResponse>;
45
+ /**
46
+ * Send a forbidden response
47
+ */
48
+ export declare function sendForbidden(res: Response, message?: string): Response<ApiErrorResponse>;
49
+ /**
50
+ * Send a bad request response
51
+ */
52
+ export declare function sendBadRequest(res: Response, message?: string): Response<ApiErrorResponse>;
53
+ /**
54
+ * Send a created response
55
+ */
56
+ export declare function sendCreated<T = any>(res: Response, data: T, message?: string): Response<ApiSuccessResponse<T>>;
57
+ /**
58
+ * Send a no content response
59
+ */
60
+ export declare function sendNoContent(res: Response): Response;
61
+ /**
62
+ * Wrap async route handlers to catch errors
63
+ */
64
+ export declare function asyncHandler(fn: (req: any, res: any, next: any) => any): (req: any, res: any, next: any) => void;
65
+ /**
66
+ * Standard error handler middleware
67
+ */
68
+ export declare function apiErrorHandler(err: any, _req: any, res: any, next: any): any;
69
+ //# sourceMappingURL=apiResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiResponse.d.ts","sourceRoot":"","sources":["../../src/core/apiResponse.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAMnC,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,WAAW,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,EACjC,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,SAAM,GACf,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CASjC;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,MAAM,GAAG,KAAK,EACrB,UAAU,SAAM,EAChB,OAAO,CAAC,EAAE,GAAG,GACZ,QAAQ,CAAC,gBAAgB,CAAC,CAoB5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,GAAG,EACX,OAAO,SAAsB,GAC5B,QAAQ,CAAC,gBAAgB,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,QAAQ,SAAa,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,QAAQ,EACb,OAAO,SAAiB,GACvB,QAAQ,CAAC,gBAAgB,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,QAAQ,EACb,OAAO,SAAc,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,QAAQ,EACb,OAAO,SAAgB,GACtB,QAAQ,CAAC,gBAAgB,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,EACjC,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,CAAC,EACP,OAAO,SAAkC,GACxC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAEjC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,CAErD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,GAAG,IAC7D,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAGtC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OAsCvE"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Standardized API Response Utilities
3
+ * Provides consistent response format across all applications
4
+ */
5
+ import { ZodError } from "zod";
6
+ import { createLogger } from "../core/logger.js";
7
+ const logger = createLogger("api-error");
8
+ /**
9
+ * Send a successful response
10
+ */
11
+ export function sendSuccess(res, data, message, statusCode = 200) {
12
+ const requestId = res.locals?.requestId;
13
+ return res.status(statusCode).json({
14
+ success: true,
15
+ data,
16
+ message,
17
+ timestamp: new Date().toISOString(),
18
+ metadata: requestId ? { requestId } : undefined,
19
+ });
20
+ }
21
+ /**
22
+ * Send an error response
23
+ */
24
+ export function sendError(res, error, statusCode = 500, details) {
25
+ const requestId = res.locals?.requestId;
26
+ const errorMessage = typeof error === "string" ? error : error.message;
27
+ const response = {
28
+ success: false,
29
+ error: errorMessage,
30
+ timestamp: new Date().toISOString(),
31
+ metadata: requestId ? { requestId } : undefined,
32
+ };
33
+ if (details) {
34
+ response.details = details;
35
+ }
36
+ // Include stack trace in development
37
+ if (process.env.NODE_ENV === "development" && error instanceof Error) {
38
+ response.stack = error.stack;
39
+ }
40
+ return res.status(statusCode).json(response);
41
+ }
42
+ /**
43
+ * Send a validation error response
44
+ */
45
+ export function sendValidationError(res, errors, message = "Validation failed") {
46
+ return sendError(res, message, 400, errors);
47
+ }
48
+ /**
49
+ * Send a not found response
50
+ */
51
+ export function sendNotFound(res, resource = "Resource") {
52
+ return sendError(res, `${resource} not found`, 404);
53
+ }
54
+ /**
55
+ * Send an unauthorized response
56
+ */
57
+ export function sendUnauthorized(res, message = "Unauthorized") {
58
+ return sendError(res, message, 401);
59
+ }
60
+ /**
61
+ * Send a forbidden response
62
+ */
63
+ export function sendForbidden(res, message = "Forbidden") {
64
+ return sendError(res, message, 403);
65
+ }
66
+ /**
67
+ * Send a bad request response
68
+ */
69
+ export function sendBadRequest(res, message = "Bad request") {
70
+ return sendError(res, message, 400);
71
+ }
72
+ /**
73
+ * Send a created response
74
+ */
75
+ export function sendCreated(res, data, message = "Resource created successfully") {
76
+ return sendSuccess(res, data, message, 201);
77
+ }
78
+ /**
79
+ * Send a no content response
80
+ */
81
+ export function sendNoContent(res) {
82
+ return res.status(204).send();
83
+ }
84
+ /**
85
+ * Wrap async route handlers to catch errors
86
+ */
87
+ export function asyncHandler(fn) {
88
+ return (req, res, next) => {
89
+ Promise.resolve(fn(req, res, next)).catch(next);
90
+ };
91
+ }
92
+ /**
93
+ * Standard error handler middleware
94
+ */
95
+ export function apiErrorHandler(err, _req, res, next) {
96
+ // If response was already sent, delegate to default Express error handler
97
+ if (res.headersSent) {
98
+ return next(err);
99
+ }
100
+ // Log the error using the framework's enhanced logger
101
+ logger.error("API Error:", {
102
+ error: err.message,
103
+ stack: err.stack,
104
+ name: err.name,
105
+ statusCode: err.statusCode || err.status || 500,
106
+ });
107
+ // Handle different error types
108
+ if (err instanceof ZodError || err?.name === "ZodError") {
109
+ const issues = err instanceof ZodError ? err.issues : err?.issues;
110
+ return sendValidationError(res, issues || err.message);
111
+ }
112
+ if (err.name === "ValidationError") {
113
+ return sendValidationError(res, err.errors || err.message);
114
+ }
115
+ if (err.name === "UnauthorizedError") {
116
+ return sendUnauthorized(res, err.message);
117
+ }
118
+ if (err.name === "CastError" || err.name === "TypeError") {
119
+ return sendBadRequest(res, "Invalid request parameters");
120
+ }
121
+ if (err.statusCode || err.status) {
122
+ return sendError(res, err.message, err.statusCode || err.status);
123
+ }
124
+ // Default to internal server error
125
+ return sendError(res, err.message || "Internal server error");
126
+ }
127
+ //# sourceMappingURL=apiResponse.js.map