@qwickapps/server 1.0.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 (81) hide show
  1. package/LICENSE +45 -0
  2. package/README.md +321 -0
  3. package/dist/core/control-panel.d.ts +21 -0
  4. package/dist/core/control-panel.d.ts.map +1 -0
  5. package/dist/core/control-panel.js +416 -0
  6. package/dist/core/control-panel.js.map +1 -0
  7. package/dist/core/gateway.d.ts +133 -0
  8. package/dist/core/gateway.d.ts.map +1 -0
  9. package/dist/core/gateway.js +270 -0
  10. package/dist/core/gateway.js.map +1 -0
  11. package/dist/core/health-manager.d.ts +52 -0
  12. package/dist/core/health-manager.d.ts.map +1 -0
  13. package/dist/core/health-manager.js +192 -0
  14. package/dist/core/health-manager.js.map +1 -0
  15. package/dist/core/index.d.ts +10 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/index.js +8 -0
  18. package/dist/core/index.js.map +1 -0
  19. package/dist/core/logging.d.ts +83 -0
  20. package/dist/core/logging.d.ts.map +1 -0
  21. package/dist/core/logging.js +191 -0
  22. package/dist/core/logging.js.map +1 -0
  23. package/dist/core/types.d.ts +195 -0
  24. package/dist/core/types.d.ts.map +1 -0
  25. package/dist/core/types.js +7 -0
  26. package/dist/core/types.js.map +1 -0
  27. package/dist/index.d.ts +18 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +17 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/plugins/config-plugin.d.ts +15 -0
  32. package/dist/plugins/config-plugin.d.ts.map +1 -0
  33. package/dist/plugins/config-plugin.js +96 -0
  34. package/dist/plugins/config-plugin.js.map +1 -0
  35. package/dist/plugins/diagnostics-plugin.d.ts +29 -0
  36. package/dist/plugins/diagnostics-plugin.d.ts.map +1 -0
  37. package/dist/plugins/diagnostics-plugin.js +142 -0
  38. package/dist/plugins/diagnostics-plugin.js.map +1 -0
  39. package/dist/plugins/health-plugin.d.ts +17 -0
  40. package/dist/plugins/health-plugin.d.ts.map +1 -0
  41. package/dist/plugins/health-plugin.js +25 -0
  42. package/dist/plugins/health-plugin.js.map +1 -0
  43. package/dist/plugins/index.d.ts +14 -0
  44. package/dist/plugins/index.d.ts.map +1 -0
  45. package/dist/plugins/index.js +10 -0
  46. package/dist/plugins/index.js.map +1 -0
  47. package/dist/plugins/logs-plugin.d.ts +22 -0
  48. package/dist/plugins/logs-plugin.d.ts.map +1 -0
  49. package/dist/plugins/logs-plugin.js +242 -0
  50. package/dist/plugins/logs-plugin.js.map +1 -0
  51. package/dist-ui/assets/index-Bk7ypbI4.js +465 -0
  52. package/dist-ui/assets/index-Bk7ypbI4.js.map +1 -0
  53. package/dist-ui/assets/index-CiizQQnb.css +1 -0
  54. package/dist-ui/index.html +13 -0
  55. package/package.json +98 -0
  56. package/src/core/control-panel.ts +493 -0
  57. package/src/core/gateway.ts +421 -0
  58. package/src/core/health-manager.ts +227 -0
  59. package/src/core/index.ts +25 -0
  60. package/src/core/logging.ts +234 -0
  61. package/src/core/types.ts +218 -0
  62. package/src/index.ts +55 -0
  63. package/src/plugins/config-plugin.ts +117 -0
  64. package/src/plugins/diagnostics-plugin.ts +178 -0
  65. package/src/plugins/health-plugin.ts +35 -0
  66. package/src/plugins/index.ts +17 -0
  67. package/src/plugins/logs-plugin.ts +314 -0
  68. package/ui/index.html +12 -0
  69. package/ui/src/App.tsx +65 -0
  70. package/ui/src/api/controlPanelApi.ts +148 -0
  71. package/ui/src/config/AppConfig.ts +18 -0
  72. package/ui/src/index.css +29 -0
  73. package/ui/src/index.tsx +11 -0
  74. package/ui/src/pages/ConfigPage.tsx +199 -0
  75. package/ui/src/pages/DashboardPage.tsx +264 -0
  76. package/ui/src/pages/DiagnosticsPage.tsx +315 -0
  77. package/ui/src/pages/HealthPage.tsx +204 -0
  78. package/ui/src/pages/LogsPage.tsx +267 -0
  79. package/ui/src/pages/NotFoundPage.tsx +41 -0
  80. package/ui/tsconfig.json +19 -0
  81. package/ui/vite.config.ts +21 -0
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Gateway Server for @qwickapps/server
3
+ *
4
+ * Provides a production-ready gateway pattern that:
5
+ * 1. Serves the control panel UI (always responsive)
6
+ * 2. Proxies API requests to an internal service
7
+ * 3. Provides health and diagnostics endpoints
8
+ *
9
+ * Architecture:
10
+ * Internet → Gateway (GATEWAY_PORT, public) → Service (SERVICE_PORT, internal)
11
+ *
12
+ * The gateway is always responsive even if the internal service is down,
13
+ * allowing diagnostics and error visibility.
14
+ *
15
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
16
+ */
17
+ import { createControlPanel } from './control-panel.js';
18
+ import { initializeLogging, getControlPanelLogger } from './logging.js';
19
+ import { createProxyMiddleware } from 'http-proxy-middleware';
20
+ import { randomBytes } from 'crypto';
21
+ import express from 'express';
22
+ import { existsSync } from 'fs';
23
+ import { resolve } from 'path';
24
+ /**
25
+ * Basic auth middleware for gateway protection (control panel only)
26
+ * - Skips localhost requests
27
+ * - Skips API routes (/api/v1/*) - they have their own service auth
28
+ * - Skips health endpoints - these should be public
29
+ * - Requires valid credentials for non-localhost control panel access
30
+ */
31
+ function createBasicAuthMiddleware(username, password, apiPaths) {
32
+ const expectedAuth = `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;
33
+ return (req, res, next) => {
34
+ const path = req.path;
35
+ // Skip auth for API routes - they use their own authentication
36
+ for (const apiPath of apiPaths) {
37
+ if (path.startsWith(apiPath)) {
38
+ return next();
39
+ }
40
+ }
41
+ // Skip auth for health endpoints - these should be publicly accessible
42
+ if (path === '/health' || path === '/api/health') {
43
+ return next();
44
+ }
45
+ // Allow localhost without auth
46
+ const remoteAddress = req.ip || req.socket?.remoteAddress || '';
47
+ const host = req.hostname || req.headers.host || '';
48
+ const isLocalhost = host === 'localhost' ||
49
+ host === '127.0.0.1' ||
50
+ host.startsWith('localhost:') ||
51
+ host.startsWith('127.0.0.1:') ||
52
+ remoteAddress === '127.0.0.1' ||
53
+ remoteAddress === '::1' ||
54
+ remoteAddress === '::ffff:127.0.0.1';
55
+ if (isLocalhost) {
56
+ return next();
57
+ }
58
+ // Check for valid basic auth
59
+ const authHeader = req.headers.authorization;
60
+ if (authHeader === expectedAuth) {
61
+ return next();
62
+ }
63
+ // Request authentication
64
+ res.setHeader('WWW-Authenticate', 'Basic realm="Control Panel"');
65
+ res.status(401).json({
66
+ error: 'Unauthorized',
67
+ message: 'Authentication required.',
68
+ });
69
+ };
70
+ }
71
+ /**
72
+ * Create a gateway that proxies to an internal service
73
+ *
74
+ * @param config - Gateway configuration
75
+ * @param serviceFactory - Factory function to create the internal service
76
+ * @returns Gateway instance
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * import { createGateway } from '@qwickapps/server';
81
+ *
82
+ * const gateway = createGateway(
83
+ * {
84
+ * productName: 'My Service',
85
+ * gatewayPort: 3101,
86
+ * servicePort: 3100,
87
+ * },
88
+ * async (port) => {
89
+ * const app = createMyApp();
90
+ * const server = app.listen(port);
91
+ * return {
92
+ * app,
93
+ * server,
94
+ * shutdown: async () => { server.close(); },
95
+ * };
96
+ * }
97
+ * );
98
+ *
99
+ * await gateway.start();
100
+ * ```
101
+ */
102
+ export function createGateway(config, serviceFactory) {
103
+ // Initialize logging subsystem first
104
+ const loggingSubsystem = initializeLogging({
105
+ namespace: config.productName,
106
+ ...config.logging,
107
+ });
108
+ // Use provided logger or get one from the logging subsystem
109
+ const logger = config.logger || getControlPanelLogger('Gateway');
110
+ const gatewayPort = config.gatewayPort || parseInt(process.env.GATEWAY_PORT || process.env.PORT || '3101', 10);
111
+ const servicePort = config.servicePort || parseInt(process.env.SERVICE_PORT || '3100', 10);
112
+ const nodeEnv = process.env.NODE_ENV || 'development';
113
+ // Auth configuration
114
+ const authMode = config.authMode || 'auto';
115
+ const basicAuthUser = config.basicAuthUser || process.env.BASIC_AUTH_USER || 'admin';
116
+ const providedPassword = config.basicAuthPassword || process.env.BASIC_AUTH_PASSWORD;
117
+ const basicAuthPassword = providedPassword || (authMode === 'auto' ? randomBytes(16).toString('base64url') : '');
118
+ const isPasswordAutoGenerated = !providedPassword && authMode === 'auto';
119
+ // API paths to proxy
120
+ const proxyPaths = config.proxyPaths || ['/api/v1'];
121
+ let service = null;
122
+ // Create control panel
123
+ const controlPanel = createControlPanel({
124
+ config: {
125
+ productName: config.productName,
126
+ port: gatewayPort,
127
+ version: config.version || process.env.npm_package_version || '1.0.0',
128
+ branding: config.branding,
129
+ cors: config.corsOrigins ? { origins: config.corsOrigins } : undefined,
130
+ // Skip body parsing for proxied paths
131
+ skipBodyParserPaths: [...proxyPaths, '/health'],
132
+ // Disable built-in dashboard if custom UI is provided
133
+ disableDashboard: !!config.customUiPath,
134
+ links: config.links,
135
+ },
136
+ plugins: config.plugins || [],
137
+ logger,
138
+ });
139
+ // Add basic auth middleware if enabled
140
+ if (authMode === 'basic' || authMode === 'auto') {
141
+ controlPanel.app.use(createBasicAuthMiddleware(basicAuthUser, basicAuthPassword, proxyPaths));
142
+ }
143
+ // Setup proxy middleware for API paths
144
+ const setupProxyMiddleware = () => {
145
+ const target = `http://localhost:${servicePort}`;
146
+ // Proxy each API path
147
+ for (const apiPath of proxyPaths) {
148
+ const proxyOptions = {
149
+ target,
150
+ changeOrigin: false,
151
+ pathFilter: `${apiPath}/**`,
152
+ on: {
153
+ error: (err, _req, res) => {
154
+ logger.error('Proxy error', { error: err.message, path: apiPath });
155
+ if (res && 'writeHead' in res && !res.headersSent) {
156
+ res.writeHead(503, { 'Content-Type': 'application/json' });
157
+ res.end(JSON.stringify({
158
+ error: 'Service Unavailable',
159
+ message: 'The service is currently unavailable. Please try again later.',
160
+ details: nodeEnv === 'development' ? err.message : undefined,
161
+ }));
162
+ }
163
+ },
164
+ },
165
+ };
166
+ controlPanel.app.use(createProxyMiddleware(proxyOptions));
167
+ }
168
+ // Proxy /health endpoint to internal service
169
+ const healthProxyOptions = {
170
+ target,
171
+ changeOrigin: false,
172
+ pathFilter: '/health',
173
+ on: {
174
+ error: (_err, _req, res) => {
175
+ if (res && 'writeHead' in res && !res.headersSent) {
176
+ res.writeHead(503, { 'Content-Type': 'application/json' });
177
+ res.end(JSON.stringify({
178
+ status: 'unhealthy',
179
+ error: 'Service unavailable',
180
+ gateway: 'healthy',
181
+ }));
182
+ }
183
+ },
184
+ },
185
+ };
186
+ controlPanel.app.use(createProxyMiddleware(healthProxyOptions));
187
+ };
188
+ // Serve custom React UI if provided
189
+ const setupCustomUI = () => {
190
+ if (config.customUiPath && existsSync(config.customUiPath)) {
191
+ logger.info(`Serving custom UI from ${config.customUiPath}`);
192
+ controlPanel.app.use(express.static(config.customUiPath));
193
+ // SPA fallback
194
+ controlPanel.app.get('*', (req, res, next) => {
195
+ if (req.path.startsWith('/api/') || req.path === '/api') {
196
+ return next();
197
+ }
198
+ res.sendFile(resolve(config.customUiPath, 'index.html'));
199
+ });
200
+ }
201
+ };
202
+ const start = async () => {
203
+ logger.info('Starting gateway...');
204
+ // 1. Start internal service
205
+ logger.info(`Starting internal service on port ${servicePort}...`);
206
+ service = await serviceFactory(servicePort);
207
+ logger.info(`Internal service started on port ${servicePort}`);
208
+ // 2. Setup proxy middleware (after service is started)
209
+ setupProxyMiddleware();
210
+ // 3. Setup custom UI (after proxy middleware)
211
+ setupCustomUI();
212
+ // 4. Start control panel gateway
213
+ await controlPanel.start();
214
+ // Log startup info
215
+ logger.info('');
216
+ logger.info('========================================');
217
+ logger.info(` ${config.productName} Gateway`);
218
+ logger.info('========================================');
219
+ logger.info('');
220
+ logger.info(` Gateway Port: ${gatewayPort} (public)`);
221
+ logger.info(` Service Port: ${servicePort} (internal)`);
222
+ logger.info('');
223
+ if (authMode === 'basic' || authMode === 'auto') {
224
+ logger.info(' Control Panel Auth: HTTP Basic Auth');
225
+ logger.info(' ----------------------------------------');
226
+ logger.info(` Username: ${basicAuthUser}`);
227
+ if (isPasswordAutoGenerated) {
228
+ logger.info(` Password: ${basicAuthPassword}`);
229
+ logger.info(' (auto-generated, set BASIC_AUTH_PASSWORD to use a fixed password)');
230
+ }
231
+ else {
232
+ logger.info(' Password: ********** (from environment)');
233
+ }
234
+ logger.info(' ----------------------------------------');
235
+ }
236
+ else {
237
+ logger.info(' Control Panel Auth: None (not recommended)');
238
+ }
239
+ logger.info('');
240
+ logger.info(' Endpoints:');
241
+ logger.info(` GET / - Control Panel UI`);
242
+ logger.info(` GET /api/health - Gateway health`);
243
+ logger.info(` GET /health - Service health (proxied)`);
244
+ for (const apiPath of proxyPaths) {
245
+ logger.info(` * ${apiPath}/* - Service API (proxied)`);
246
+ }
247
+ logger.info('========================================');
248
+ logger.info('');
249
+ };
250
+ const stop = async () => {
251
+ logger.info('Shutting down gateway...');
252
+ // Stop control panel
253
+ await controlPanel.stop();
254
+ // Stop internal service
255
+ if (service) {
256
+ await service.shutdown();
257
+ service.server.close();
258
+ }
259
+ logger.info('Gateway shutdown complete');
260
+ };
261
+ return {
262
+ controlPanel,
263
+ service,
264
+ start,
265
+ stop,
266
+ gatewayPort,
267
+ servicePort,
268
+ };
269
+ }
270
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/core/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Health Check Manager
3
+ *
4
+ * Manages health checks for various services and provides aggregated status
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+ import type { HealthCheck, HealthCheckResult, HealthStatus, Logger } from './types.js';
9
+ export declare class HealthManager {
10
+ private checks;
11
+ private results;
12
+ private intervals;
13
+ private logger;
14
+ constructor(logger: Logger);
15
+ /**
16
+ * Register a health check
17
+ */
18
+ register(check: HealthCheck): void;
19
+ /**
20
+ * Run a health check
21
+ */
22
+ private runCheck;
23
+ /**
24
+ * Run HTTP health check
25
+ */
26
+ private runHttpCheck;
27
+ /**
28
+ * Run TCP health check (simplified - just tries to connect)
29
+ */
30
+ private runTcpCheck;
31
+ /**
32
+ * Get all health check results
33
+ */
34
+ getResults(): Record<string, HealthCheckResult>;
35
+ /**
36
+ * Get specific health check result
37
+ */
38
+ getResult(name: string): HealthCheckResult | undefined;
39
+ /**
40
+ * Get aggregated status
41
+ */
42
+ getAggregatedStatus(): HealthStatus;
43
+ /**
44
+ * Force run all checks
45
+ */
46
+ checkAll(): Promise<void>;
47
+ /**
48
+ * Shutdown - clear all intervals
49
+ */
50
+ shutdown(): void;
51
+ }
52
+ //# sourceMappingURL=health-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-manager.d.ts","sourceRoot":"","sources":["../../src/core/health-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEvF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,OAAO,CAA6C;IAC5D,OAAO,CAAC,SAAS,CAA0D;IAC3E,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAI1B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAyBlC;;OAEG;YACW,QAAQ;IA2DtB;;OAEG;YACW,YAAY;IAmC1B;;OAEG;YACW,WAAW;IAuBzB;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAI/C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAItD;;OAEG;IACH,mBAAmB,IAAI,YAAY;IAiBnC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACH,QAAQ,IAAI,IAAI;CAOjB"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Health Check Manager
3
+ *
4
+ * Manages health checks for various services and provides aggregated status
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+ export class HealthManager {
9
+ constructor(logger) {
10
+ this.checks = new Map();
11
+ this.results = new Map();
12
+ this.intervals = new Map();
13
+ this.logger = logger;
14
+ }
15
+ /**
16
+ * Register a health check
17
+ */
18
+ register(check) {
19
+ this.checks.set(check.name, check);
20
+ // Initialize result
21
+ this.results.set(check.name, {
22
+ status: 'unknown',
23
+ lastChecked: new Date(),
24
+ });
25
+ // Start periodic check
26
+ const interval = check.interval || 30000; // Default 30 seconds
27
+ this.runCheck(check.name);
28
+ const timer = setInterval(() => {
29
+ this.runCheck(check.name);
30
+ }, interval);
31
+ this.intervals.set(check.name, timer);
32
+ this.logger.info(`[HealthManager] Registered health check: ${check.name}`, {
33
+ type: check.type,
34
+ interval,
35
+ });
36
+ }
37
+ /**
38
+ * Run a health check
39
+ */
40
+ async runCheck(name) {
41
+ const check = this.checks.get(name);
42
+ if (!check)
43
+ return;
44
+ const startTime = Date.now();
45
+ const timeout = check.timeout || 5000;
46
+ try {
47
+ let result;
48
+ switch (check.type) {
49
+ case 'http':
50
+ result = await this.runHttpCheck(check, timeout);
51
+ break;
52
+ case 'tcp':
53
+ result = await this.runTcpCheck(check, timeout);
54
+ break;
55
+ case 'custom':
56
+ if (check.check) {
57
+ result = await Promise.race([
58
+ check.check(),
59
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeout)),
60
+ ]);
61
+ }
62
+ else {
63
+ result = { healthy: false, details: { error: 'No check function provided' } };
64
+ }
65
+ break;
66
+ default:
67
+ result = { healthy: false, details: { error: 'Unknown check type' } };
68
+ }
69
+ const latency = result.latency || Date.now() - startTime;
70
+ this.results.set(name, {
71
+ status: result.healthy ? 'healthy' : 'unhealthy',
72
+ latency,
73
+ lastChecked: new Date(),
74
+ details: result.details,
75
+ });
76
+ }
77
+ catch (error) {
78
+ const latency = Date.now() - startTime;
79
+ const message = error instanceof Error ? error.message : String(error);
80
+ this.results.set(name, {
81
+ status: 'unhealthy',
82
+ latency,
83
+ message,
84
+ lastChecked: new Date(),
85
+ });
86
+ this.logger.warn(`[HealthManager] Health check failed: ${name}`, {
87
+ error: message,
88
+ latency,
89
+ });
90
+ }
91
+ }
92
+ /**
93
+ * Run HTTP health check
94
+ */
95
+ async runHttpCheck(check, timeout) {
96
+ if (!check.url) {
97
+ return { healthy: false, details: { error: 'No URL provided' } };
98
+ }
99
+ const controller = new AbortController();
100
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
101
+ try {
102
+ const startTime = Date.now();
103
+ const response = await fetch(check.url, {
104
+ method: 'GET',
105
+ signal: controller.signal,
106
+ });
107
+ const latency = Date.now() - startTime;
108
+ clearTimeout(timeoutId);
109
+ return {
110
+ healthy: response.ok,
111
+ latency,
112
+ details: {
113
+ status: response.status,
114
+ statusText: response.statusText,
115
+ },
116
+ };
117
+ }
118
+ catch (error) {
119
+ clearTimeout(timeoutId);
120
+ throw error;
121
+ }
122
+ }
123
+ /**
124
+ * Run TCP health check (simplified - just tries to connect)
125
+ */
126
+ async runTcpCheck(check, timeout) {
127
+ if (!check.host || !check.port) {
128
+ return { healthy: false, details: { error: 'Host and port required for TCP check' } };
129
+ }
130
+ // Use HTTP check as a proxy for TCP (simplified for browser compatibility)
131
+ // In a real Node.js environment, you'd use net.createConnection
132
+ const url = `http://${check.host}:${check.port}`;
133
+ try {
134
+ return await this.runHttpCheck({ ...check, url }, timeout);
135
+ }
136
+ catch {
137
+ // TCP check failed
138
+ return {
139
+ healthy: false,
140
+ details: { error: `Cannot connect to ${check.host}:${check.port}` },
141
+ };
142
+ }
143
+ }
144
+ /**
145
+ * Get all health check results
146
+ */
147
+ getResults() {
148
+ return Object.fromEntries(this.results);
149
+ }
150
+ /**
151
+ * Get specific health check result
152
+ */
153
+ getResult(name) {
154
+ return this.results.get(name);
155
+ }
156
+ /**
157
+ * Get aggregated status
158
+ */
159
+ getAggregatedStatus() {
160
+ const results = Array.from(this.results.values());
161
+ if (results.length === 0)
162
+ return 'unknown';
163
+ const unhealthyCount = results.filter((r) => r.status === 'unhealthy').length;
164
+ const degradedCount = results.filter((r) => r.status === 'degraded').length;
165
+ if (unhealthyCount > 0)
166
+ return 'unhealthy';
167
+ if (degradedCount > 0)
168
+ return 'degraded';
169
+ const hasUnknown = results.some((r) => r.status === 'unknown');
170
+ if (hasUnknown)
171
+ return 'unknown';
172
+ return 'healthy';
173
+ }
174
+ /**
175
+ * Force run all checks
176
+ */
177
+ async checkAll() {
178
+ const promises = Array.from(this.checks.keys()).map((name) => this.runCheck(name));
179
+ await Promise.all(promises);
180
+ }
181
+ /**
182
+ * Shutdown - clear all intervals
183
+ */
184
+ shutdown() {
185
+ for (const timer of this.intervals.values()) {
186
+ clearInterval(timer);
187
+ }
188
+ this.intervals.clear();
189
+ this.logger.info('[HealthManager] Shutdown complete');
190
+ }
191
+ }
192
+ //# sourceMappingURL=health-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-manager.js","sourceRoot":"","sources":["../../src/core/health-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Core exports for @qwickapps/server
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export { createControlPanel } from './control-panel.js';
7
+ export type { CreateControlPanelOptions } from './control-panel.js';
8
+ export { HealthManager } from './health-manager.js';
9
+ export type { ControlPanelConfig, ControlPanelPlugin, ControlPanelInstance, PluginContext, HealthCheck, HealthCheckType, HealthStatus, HealthCheckResult, LogSource, ConfigDisplayOptions, Logger, DiagnosticsReport, } from './types.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,oBAAoB,EACpB,MAAM,EACN,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core exports for @qwickapps/server
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export { createControlPanel } from './control-panel.js';
7
+ export { HealthManager } from './health-manager.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Control Panel Logging Subsystem
3
+ *
4
+ * Provides centralized logging for the control panel and all plugins.
5
+ * Configures @qwickapps/logging to write to files that the LogsPage can display.
6
+ *
7
+ * Environment Variables:
8
+ * LOG_LEVEL - Minimum log level (debug, info, warn, error). Default: debug in dev, info in prod
9
+ * LOG_DIR - Directory for log files. Default: ./logs
10
+ * LOG_FILE - Enable file logging. Default: true
11
+ * LOG_FILE_PATH - Path to log file. Default: ./logs/app.log (used by pino if available)
12
+ * LOG_CONSOLE - Enable console output. Default: true
13
+ *
14
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
15
+ */
16
+ import { LogLevel } from '@qwickapps/logging';
17
+ import type { Logger } from './types.js';
18
+ export interface LoggingConfig {
19
+ /** Product namespace for log entries */
20
+ namespace?: string;
21
+ /** Minimum log level */
22
+ level?: LogLevel;
23
+ /** Directory for log files */
24
+ logDir?: string;
25
+ /** Enable file logging */
26
+ fileLogging?: boolean;
27
+ /** Enable console output */
28
+ consoleOutput?: boolean;
29
+ }
30
+ /**
31
+ * Logging subsystem instance
32
+ */
33
+ declare class LoggingSubsystem {
34
+ private config;
35
+ private rootLogger;
36
+ private fileTransport;
37
+ private initialized;
38
+ constructor();
39
+ /**
40
+ * Initialize the logging subsystem with configuration
41
+ */
42
+ initialize(config?: LoggingConfig): void;
43
+ /**
44
+ * Get a logger for a specific component/plugin
45
+ */
46
+ getLogger(namespace: string): Logger;
47
+ /**
48
+ * Get the root logger
49
+ */
50
+ getRootLogger(): Logger;
51
+ /**
52
+ * Check if file logging is enabled and working
53
+ */
54
+ isFileLoggingEnabled(): boolean;
55
+ /**
56
+ * Get the log directory path
57
+ */
58
+ getLogDir(): string;
59
+ /**
60
+ * Get the default log file paths
61
+ */
62
+ getLogPaths(): {
63
+ appLog: string;
64
+ errorLog: string;
65
+ };
66
+ }
67
+ /**
68
+ * Get or create the logging subsystem
69
+ */
70
+ export declare function getLoggingSubsystem(): LoggingSubsystem;
71
+ /**
72
+ * Initialize the logging subsystem with configuration
73
+ */
74
+ export declare function initializeLogging(config?: LoggingConfig): LoggingSubsystem;
75
+ /**
76
+ * Get a logger for a specific namespace
77
+ */
78
+ export declare function getControlPanelLogger(namespace: string): Logger;
79
+ /**
80
+ * Export for convenience
81
+ */
82
+ export { LoggingSubsystem };
83
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/core/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAoC,QAAQ,EAAgB,MAAM,oBAAoB,CAAC;AAC9F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyDD;;GAEG;AACH,cAAM,gBAAgB;IACpB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;OAEG;IACH,UAAU,CAAC,MAAM,GAAE,aAAkB,GAAG,IAAI;IAwC5C;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAoBpC;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,oBAAoB,IAAI,OAAO;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,WAAW,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAMpD;AAKD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAKtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,aAAkB,GAAG,gBAAgB,CAI9E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAC"}