@qwickapps/server 1.0.0 → 1.1.6
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.
- package/README.md +178 -79
- package/dist/core/control-panel.d.ts.map +1 -1
- package/dist/core/control-panel.js +37 -42
- package/dist/core/control-panel.js.map +1 -1
- package/dist/core/gateway.d.ts +32 -13
- package/dist/core/gateway.d.ts.map +1 -1
- package/dist/core/gateway.js +144 -81
- package/dist/core/gateway.js.map +1 -1
- package/dist/core/guards.d.ts +22 -0
- package/dist/core/guards.d.ts.map +1 -0
- package/dist/core/guards.js +167 -0
- package/dist/core/guards.js.map +1 -0
- package/dist/core/types.d.ts +104 -11
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/frontend-app-plugin.d.ts +39 -0
- package/dist/plugins/frontend-app-plugin.d.ts.map +1 -0
- package/dist/plugins/frontend-app-plugin.js +176 -0
- package/dist/plugins/frontend-app-plugin.js.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/index.js.map +1 -1
- package/package.json +7 -2
- package/src/core/control-panel.ts +41 -50
- package/src/core/gateway.ts +186 -105
- package/src/core/guards.ts +190 -0
- package/src/core/types.ts +115 -9
- package/src/index.ts +18 -0
- package/src/plugins/frontend-app-plugin.ts +211 -0
- package/src/plugins/index.ts +3 -0
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
export { createControlPanel } from './core/control-panel.js';
|
|
10
10
|
export { createGateway } from './core/gateway.js';
|
|
11
11
|
export { HealthManager } from './core/health-manager.js';
|
|
12
|
+
export { createRouteGuard, isAuthenticated, getAuthenticatedUser, } from './core/guards.js';
|
|
12
13
|
export { initializeLogging, getControlPanelLogger, getLoggingSubsystem, } from './core/logging.js';
|
|
13
14
|
export type { LoggingConfig } from './core/logging.js';
|
|
14
|
-
export type { ControlPanelConfig, ControlPanelPlugin, ControlPanelInstance, PluginContext, HealthCheck, HealthCheckType, HealthCheckResult, HealthStatus, LogSource, ConfigDisplayOptions, Logger, DiagnosticsReport, } from './core/types.js';
|
|
15
|
+
export type { ControlPanelConfig, ControlPanelPlugin, ControlPanelInstance, PluginContext, HealthCheck, HealthCheckType, HealthCheckResult, HealthStatus, LogSource, ConfigDisplayOptions, Logger, DiagnosticsReport, RouteGuardType, RouteGuardConfig, BasicAuthGuardConfig, SupabaseAuthGuardConfig, Auth0GuardConfig, NoAuthGuardConfig, MountConfig, FrontendAppConfig, } from './core/types.js';
|
|
15
16
|
export type { GatewayConfig, GatewayInstance, ServiceFactory, } from './core/gateway.js';
|
|
16
|
-
export { createHealthPlugin, createLogsPlugin, createConfigPlugin, createDiagnosticsPlugin, } from './plugins/index.js';
|
|
17
|
-
export type { HealthPluginConfig, LogsPluginConfig, ConfigPluginConfig, DiagnosticsPluginConfig, } from './plugins/index.js';
|
|
17
|
+
export { createHealthPlugin, createLogsPlugin, createConfigPlugin, createDiagnosticsPlugin, createFrontendAppPlugin, } from './plugins/index.js';
|
|
18
|
+
export type { HealthPluginConfig, LogsPluginConfig, ConfigPluginConfig, DiagnosticsPluginConfig, FrontendAppPluginConfig, } from './plugins/index.js';
|
|
18
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,MAAM,EACN,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,MAAM,EACN,iBAAiB,EAEjB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
export { createControlPanel } from './core/control-panel.js';
|
|
11
11
|
export { createGateway } from './core/gateway.js';
|
|
12
12
|
export { HealthManager } from './core/health-manager.js';
|
|
13
|
+
// Guards exports
|
|
14
|
+
export { createRouteGuard, isAuthenticated, getAuthenticatedUser, } from './core/guards.js';
|
|
13
15
|
// Logging exports
|
|
14
16
|
export { initializeLogging, getControlPanelLogger, getLoggingSubsystem, } from './core/logging.js';
|
|
15
17
|
// Built-in plugins
|
|
16
|
-
export { createHealthPlugin, createLogsPlugin, createConfigPlugin, createDiagnosticsPlugin, } from './plugins/index.js';
|
|
18
|
+
export { createHealthPlugin, createLogsPlugin, createConfigPlugin, createDiagnosticsPlugin, createFrontendAppPlugin, } from './plugins/index.js';
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,kBAAkB;AAClB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,iBAAiB;AACjB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,kBAAkB;AAClB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAgC3B,mBAAmB;AACnB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend App Plugin
|
|
3
|
+
*
|
|
4
|
+
* Plugin for serving a frontend application at the root path (/).
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Redirect to another URL
|
|
7
|
+
* - Serve static files
|
|
8
|
+
* - Display a landing page
|
|
9
|
+
*
|
|
10
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
11
|
+
*/
|
|
12
|
+
import type { ControlPanelPlugin, FrontendAppConfig } from '../core/types.js';
|
|
13
|
+
export interface FrontendAppPluginConfig {
|
|
14
|
+
/** Redirect to another URL */
|
|
15
|
+
redirectUrl?: string;
|
|
16
|
+
/** Path to static files to serve */
|
|
17
|
+
staticPath?: string;
|
|
18
|
+
/** Landing page configuration */
|
|
19
|
+
landingPage?: {
|
|
20
|
+
title: string;
|
|
21
|
+
heading?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
links?: Array<{
|
|
24
|
+
label: string;
|
|
25
|
+
url: string;
|
|
26
|
+
}>;
|
|
27
|
+
branding?: {
|
|
28
|
+
logo?: string;
|
|
29
|
+
primaryColor?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/** Route guard configuration */
|
|
33
|
+
guard?: FrontendAppConfig['mount']['guard'];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a frontend app plugin that handles the root path
|
|
37
|
+
*/
|
|
38
|
+
export declare function createFrontendAppPlugin(config: FrontendAppPluginConfig): ControlPanelPlugin;
|
|
39
|
+
//# sourceMappingURL=frontend-app-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-app-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/frontend-app-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,MAAM,WAAW,uBAAuB;IACtC,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,WAAW,CAAC,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC9C,QAAQ,CAAC,EAAE;YACT,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;KACH,CAAC;IACF,gCAAgC;IAChC,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,kBAAkB,CAmE3F"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend App Plugin
|
|
3
|
+
*
|
|
4
|
+
* Plugin for serving a frontend application at the root path (/).
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Redirect to another URL
|
|
7
|
+
* - Serve static files
|
|
8
|
+
* - Display a landing page
|
|
9
|
+
*
|
|
10
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
11
|
+
*/
|
|
12
|
+
import express from 'express';
|
|
13
|
+
import { existsSync } from 'node:fs';
|
|
14
|
+
import { resolve } from 'node:path';
|
|
15
|
+
import { createRouteGuard } from '../core/guards.js';
|
|
16
|
+
/**
|
|
17
|
+
* Create a frontend app plugin that handles the root path
|
|
18
|
+
*/
|
|
19
|
+
export function createFrontendAppPlugin(config) {
|
|
20
|
+
return {
|
|
21
|
+
name: 'frontend-app',
|
|
22
|
+
order: 0, // Run first to capture root path
|
|
23
|
+
async onInit(context) {
|
|
24
|
+
const { app, logger } = context;
|
|
25
|
+
// Apply guard if configured
|
|
26
|
+
if (config.guard && config.guard.type !== 'none') {
|
|
27
|
+
const guardMiddleware = createRouteGuard(config.guard);
|
|
28
|
+
// Apply guard only to root path
|
|
29
|
+
app.use('/', (req, res, next) => {
|
|
30
|
+
// Skip if not at root
|
|
31
|
+
if (req.path !== '/' && !req.path.startsWith('/?')) {
|
|
32
|
+
return next();
|
|
33
|
+
}
|
|
34
|
+
guardMiddleware(req, res, next);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Priority 1: Redirect
|
|
38
|
+
if (config.redirectUrl) {
|
|
39
|
+
logger.info(`Frontend app: Redirecting / to ${config.redirectUrl}`);
|
|
40
|
+
app.get('/', (_req, res) => {
|
|
41
|
+
res.redirect(config.redirectUrl);
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Priority 2: Serve static files
|
|
46
|
+
if (config.staticPath && existsSync(config.staticPath)) {
|
|
47
|
+
logger.info(`Frontend app: Serving static files from ${config.staticPath}`);
|
|
48
|
+
app.use('/', express.static(config.staticPath));
|
|
49
|
+
// SPA fallback
|
|
50
|
+
app.get('/', (_req, res) => {
|
|
51
|
+
res.sendFile(resolve(config.staticPath, 'index.html'));
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Priority 3: Landing page
|
|
56
|
+
if (config.landingPage) {
|
|
57
|
+
logger.info(`Frontend app: Serving landing page`);
|
|
58
|
+
app.get('/', (_req, res) => {
|
|
59
|
+
const html = generateLandingPageHtml(config.landingPage);
|
|
60
|
+
res.type('html').send(html);
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Default: Simple welcome page
|
|
65
|
+
logger.info(`Frontend app: Serving default welcome page`);
|
|
66
|
+
app.get('/', (_req, res) => {
|
|
67
|
+
const html = generateLandingPageHtml({
|
|
68
|
+
title: context.config.productName,
|
|
69
|
+
heading: `Welcome to ${context.config.productName}`,
|
|
70
|
+
description: 'Your application is running.',
|
|
71
|
+
links: [
|
|
72
|
+
{ label: 'Control Panel', url: context.config.mountPath || '/cpanel' },
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
res.type('html').send(html);
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generate landing page HTML
|
|
82
|
+
*/
|
|
83
|
+
function generateLandingPageHtml(config) {
|
|
84
|
+
const primaryColor = config.branding?.primaryColor || '#6366f1';
|
|
85
|
+
const linksHtml = (config.links || [])
|
|
86
|
+
.map((link) => `<a href="${link.url}" class="link">${link.label}</a>`)
|
|
87
|
+
.join('');
|
|
88
|
+
return `<!DOCTYPE html>
|
|
89
|
+
<html lang="en">
|
|
90
|
+
<head>
|
|
91
|
+
<meta charset="UTF-8">
|
|
92
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
93
|
+
<title>${config.title}</title>
|
|
94
|
+
<style>
|
|
95
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
96
|
+
body {
|
|
97
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
98
|
+
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
|
|
99
|
+
color: #e2e8f0;
|
|
100
|
+
min-height: 100vh;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
}
|
|
105
|
+
.container {
|
|
106
|
+
text-align: center;
|
|
107
|
+
max-width: 600px;
|
|
108
|
+
padding: 2rem;
|
|
109
|
+
}
|
|
110
|
+
${config.branding?.logo ? `
|
|
111
|
+
.logo {
|
|
112
|
+
width: 80px;
|
|
113
|
+
height: 80px;
|
|
114
|
+
margin-bottom: 1.5rem;
|
|
115
|
+
}
|
|
116
|
+
` : ''}
|
|
117
|
+
h1 {
|
|
118
|
+
font-size: 2.5rem;
|
|
119
|
+
color: ${primaryColor};
|
|
120
|
+
margin-bottom: 1rem;
|
|
121
|
+
}
|
|
122
|
+
p {
|
|
123
|
+
font-size: 1.125rem;
|
|
124
|
+
color: #94a3b8;
|
|
125
|
+
margin-bottom: 2rem;
|
|
126
|
+
line-height: 1.6;
|
|
127
|
+
}
|
|
128
|
+
.links {
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-wrap: wrap;
|
|
131
|
+
gap: 1rem;
|
|
132
|
+
justify-content: center;
|
|
133
|
+
}
|
|
134
|
+
.link {
|
|
135
|
+
display: inline-block;
|
|
136
|
+
padding: 0.875rem 2rem;
|
|
137
|
+
background: ${primaryColor};
|
|
138
|
+
color: white;
|
|
139
|
+
text-decoration: none;
|
|
140
|
+
border-radius: 0.5rem;
|
|
141
|
+
font-weight: 500;
|
|
142
|
+
transition: all 0.2s;
|
|
143
|
+
}
|
|
144
|
+
.link:hover {
|
|
145
|
+
transform: translateY(-2px);
|
|
146
|
+
box-shadow: 0 10px 20px rgba(0,0,0,0.3);
|
|
147
|
+
}
|
|
148
|
+
.footer {
|
|
149
|
+
position: fixed;
|
|
150
|
+
bottom: 1rem;
|
|
151
|
+
left: 0;
|
|
152
|
+
right: 0;
|
|
153
|
+
text-align: center;
|
|
154
|
+
color: #64748b;
|
|
155
|
+
font-size: 0.875rem;
|
|
156
|
+
}
|
|
157
|
+
.footer a {
|
|
158
|
+
color: ${primaryColor};
|
|
159
|
+
text-decoration: none;
|
|
160
|
+
}
|
|
161
|
+
</style>
|
|
162
|
+
</head>
|
|
163
|
+
<body>
|
|
164
|
+
<div class="container">
|
|
165
|
+
${config.branding?.logo ? `<img src="${config.branding.logo}" alt="Logo" class="logo">` : ''}
|
|
166
|
+
<h1>${config.heading || config.title}</h1>
|
|
167
|
+
${config.description ? `<p>${config.description}</p>` : ''}
|
|
168
|
+
${linksHtml ? `<div class="links">${linksHtml}</div>` : ''}
|
|
169
|
+
</div>
|
|
170
|
+
<div class="footer">
|
|
171
|
+
Powered by <a href="https://qwickapps.com" target="_blank">QwickApps</a>
|
|
172
|
+
</div>
|
|
173
|
+
</body>
|
|
174
|
+
</html>`;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=frontend-app-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-app-plugin.js","sourceRoot":"","sources":["../../src/plugins/frontend-app-plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -11,4 +11,6 @@ export { createConfigPlugin } from './config-plugin.js';
|
|
|
11
11
|
export type { ConfigPluginConfig } from './config-plugin.js';
|
|
12
12
|
export { createDiagnosticsPlugin } from './diagnostics-plugin.js';
|
|
13
13
|
export type { DiagnosticsPluginConfig } from './diagnostics-plugin.js';
|
|
14
|
+
export { createFrontendAppPlugin } from './frontend-app-plugin.js';
|
|
15
|
+
export type { FrontendAppPluginConfig } from './frontend-app-plugin.js';
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/plugins/index.js
CHANGED
|
@@ -7,4 +7,5 @@ export { createHealthPlugin } from './health-plugin.js';
|
|
|
7
7
|
export { createLogsPlugin } from './logs-plugin.js';
|
|
8
8
|
export { createConfigPlugin } from './config-plugin.js';
|
|
9
9
|
export { createDiagnosticsPlugin } from './diagnostics-plugin.js';
|
|
10
|
+
export { createFrontendAppPlugin } from './frontend-app-plugin.js';
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qwickapps/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Plugin-based application server framework for building websites, APIs, admin dashboards, and full-stack products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"@types/react": "^18.2.0",
|
|
59
59
|
"@types/react-dom": "^18.2.0",
|
|
60
60
|
"@vitejs/plugin-react": "^4.3.4",
|
|
61
|
+
"express-openid-connect": "^2.19.3",
|
|
61
62
|
"react": "^18.2.0",
|
|
62
63
|
"react-dom": "^18.2.0",
|
|
63
64
|
"react-router-dom": "^6.30.1",
|
|
@@ -66,11 +67,15 @@
|
|
|
66
67
|
"vitest": "^2.1.0"
|
|
67
68
|
},
|
|
68
69
|
"peerDependencies": {
|
|
69
|
-
"@qwickapps/react-framework": ">=1.0.0"
|
|
70
|
+
"@qwickapps/react-framework": ">=1.0.0",
|
|
71
|
+
"express-openid-connect": ">=2.0.0"
|
|
70
72
|
},
|
|
71
73
|
"peerDependenciesMeta": {
|
|
72
74
|
"@qwickapps/react-framework": {
|
|
73
75
|
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"express-openid-connect": {
|
|
78
|
+
"optional": true
|
|
74
79
|
}
|
|
75
80
|
},
|
|
76
81
|
"keywords": [
|
|
@@ -14,7 +14,8 @@ import { existsSync } from 'node:fs';
|
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
15
|
import { dirname, join } from 'node:path';
|
|
16
16
|
import { HealthManager } from './health-manager.js';
|
|
17
|
-
import { initializeLogging, getControlPanelLogger,
|
|
17
|
+
import { initializeLogging, getControlPanelLogger, type LoggingConfig } from './logging.js';
|
|
18
|
+
import { createRouteGuard } from './guards.js';
|
|
18
19
|
import type {
|
|
19
20
|
ControlPanelConfig,
|
|
20
21
|
ControlPanelPlugin,
|
|
@@ -94,35 +95,15 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
94
95
|
}
|
|
95
96
|
app.use(compression());
|
|
96
97
|
|
|
97
|
-
//
|
|
98
|
-
if (config.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!authHeader || !authHeader.startsWith('Basic ')) {
|
|
102
|
-
res.set('WWW-Authenticate', 'Basic realm="Control Panel"');
|
|
103
|
-
return res.status(401).json({ error: 'Authentication required' });
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const base64Credentials = authHeader.substring(6);
|
|
107
|
-
const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8');
|
|
108
|
-
const [username, password] = credentials.split(':');
|
|
109
|
-
|
|
110
|
-
const validUser = config.auth!.users!.find(
|
|
111
|
-
(u) => u.username === username && u.password === password
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
if (!validUser) {
|
|
115
|
-
return res.status(401).json({ error: 'Invalid credentials' });
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
next();
|
|
119
|
-
});
|
|
98
|
+
// Apply route guard if configured
|
|
99
|
+
if (config.guard && config.guard.type !== 'none') {
|
|
100
|
+
const guardMiddleware = createRouteGuard(config.guard);
|
|
101
|
+
app.use(guardMiddleware);
|
|
120
102
|
}
|
|
121
103
|
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
104
|
+
// Get mount path (defaults to /cpanel)
|
|
105
|
+
const mountPath = config.mountPath || '/cpanel';
|
|
106
|
+
const apiBasePath = mountPath === '/' ? '/api' : `${mountPath}/api`;
|
|
126
107
|
|
|
127
108
|
// Request logging
|
|
128
109
|
app.use((req, _res, next) => {
|
|
@@ -130,8 +111,8 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
130
111
|
next();
|
|
131
112
|
});
|
|
132
113
|
|
|
133
|
-
// Mount router
|
|
134
|
-
app.use(
|
|
114
|
+
// Mount router at the configured path
|
|
115
|
+
app.use(apiBasePath, router);
|
|
135
116
|
|
|
136
117
|
// Built-in routes
|
|
137
118
|
|
|
@@ -173,7 +154,7 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
173
154
|
});
|
|
174
155
|
|
|
175
156
|
/**
|
|
176
|
-
* Serve dashboard UI
|
|
157
|
+
* Serve dashboard UI at the configured mount path
|
|
177
158
|
*
|
|
178
159
|
* Priority:
|
|
179
160
|
* 1. If useRichUI is true and dist-ui exists, serve React SPA
|
|
@@ -185,25 +166,33 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
185
166
|
const hasRichUI = existsSync(effectiveUiPath);
|
|
186
167
|
const useRichUI = config.useRichUI !== false && hasRichUI;
|
|
187
168
|
|
|
188
|
-
logger.debug(`Dashboard config:
|
|
169
|
+
logger.debug(`Dashboard config: mountPath=${mountPath}, effectiveUiPath=${effectiveUiPath}, hasRichUI=${hasRichUI}, useRichUI=${useRichUI}`);
|
|
189
170
|
|
|
190
171
|
if (useRichUI) {
|
|
191
|
-
logger.info(`Serving rich React UI from ${effectiveUiPath}`);
|
|
192
|
-
// Serve static assets from dist-ui
|
|
193
|
-
app.use(express.static(effectiveUiPath));
|
|
194
|
-
|
|
195
|
-
// SPA fallback - serve index.html for all non-API routes
|
|
196
|
-
app.get(
|
|
197
|
-
// Skip API routes
|
|
198
|
-
if (req.path.startsWith(
|
|
172
|
+
logger.info(`Serving rich React UI from ${effectiveUiPath} at ${mountPath}`);
|
|
173
|
+
// Serve static assets from dist-ui at the mount path
|
|
174
|
+
app.use(mountPath, express.static(effectiveUiPath));
|
|
175
|
+
|
|
176
|
+
// SPA fallback - serve index.html for all non-API routes under the mount path
|
|
177
|
+
app.get(`${mountPath}/*`, (req: Request, res: Response, next) => {
|
|
178
|
+
// Skip API routes
|
|
179
|
+
if (req.path.startsWith(apiBasePath)) {
|
|
199
180
|
return next();
|
|
200
181
|
}
|
|
201
182
|
res.sendFile(join(effectiveUiPath, 'index.html'));
|
|
202
183
|
});
|
|
184
|
+
|
|
185
|
+
// Also serve the mount path root
|
|
186
|
+
if (mountPath !== '/') {
|
|
187
|
+
app.get(mountPath, (_req: Request, res: Response) => {
|
|
188
|
+
res.sendFile(join(effectiveUiPath, 'index.html'));
|
|
189
|
+
});
|
|
190
|
+
}
|
|
203
191
|
} else {
|
|
204
|
-
logger.info(
|
|
205
|
-
|
|
206
|
-
|
|
192
|
+
logger.info(`Serving basic HTML dashboard at ${mountPath}`);
|
|
193
|
+
const dashboardPath = mountPath === '/' ? '/' : mountPath;
|
|
194
|
+
app.get(dashboardPath, (_req: Request, res: Response) => {
|
|
195
|
+
const html = generateDashboardHtml(config, healthManager.getResults(), mountPath);
|
|
207
196
|
res.type('html').send(html);
|
|
208
197
|
});
|
|
209
198
|
}
|
|
@@ -288,9 +277,9 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
288
277
|
return new Promise((resolve) => {
|
|
289
278
|
server = app.listen(config.port, () => {
|
|
290
279
|
logger.info(`Control panel started on port ${config.port}`);
|
|
291
|
-
logger.info(`Dashboard: http://localhost:${config.port}`);
|
|
292
|
-
logger.info(`Health: http://localhost:${config.port}/
|
|
293
|
-
logger.info(`Diagnostics: http://localhost:${config.port}/
|
|
280
|
+
logger.info(`Dashboard: http://localhost:${config.port}${mountPath}`);
|
|
281
|
+
logger.info(`Health: http://localhost:${config.port}${apiBasePath}/health`);
|
|
282
|
+
logger.info(`Diagnostics: http://localhost:${config.port}${apiBasePath}/diagnostics`);
|
|
294
283
|
resolve();
|
|
295
284
|
});
|
|
296
285
|
});
|
|
@@ -334,8 +323,10 @@ export function createControlPanel(options: CreateControlPanelOptions): ControlP
|
|
|
334
323
|
*/
|
|
335
324
|
function generateDashboardHtml(
|
|
336
325
|
config: ControlPanelConfig,
|
|
337
|
-
health: Record<string, { status: string; latency?: number; lastChecked: Date }
|
|
326
|
+
health: Record<string, { status: string; latency?: number; lastChecked: Date }>,
|
|
327
|
+
mountPath: string = '/cpanel'
|
|
338
328
|
): string {
|
|
329
|
+
const apiBasePath = mountPath === '/' ? '/api' : `${mountPath}/api`;
|
|
339
330
|
const healthEntries = Object.entries(health);
|
|
340
331
|
const overallStatus = healthEntries.every((e) => e[1].status === 'healthy')
|
|
341
332
|
? 'healthy'
|
|
@@ -478,9 +469,9 @@ function generateDashboardHtml(
|
|
|
478
469
|
|
|
479
470
|
<div class="api-links">
|
|
480
471
|
<strong>API:</strong>
|
|
481
|
-
<a href="/
|
|
482
|
-
<a href="/
|
|
483
|
-
<a href="/
|
|
472
|
+
<a href="${apiBasePath}/health">Health</a>
|
|
473
|
+
<a href="${apiBasePath}/info">Info</a>
|
|
474
|
+
<a href="${apiBasePath}/diagnostics">Diagnostics</a>
|
|
484
475
|
</div>
|
|
485
476
|
</div>
|
|
486
477
|
|