u
This commit is contained in:
@@ -2,8 +2,8 @@
|
|||||||
PORT=4208
|
PORT=4208
|
||||||
# HTTPS server port (defaults to 8443, set to 0 or false to disable)
|
# HTTPS server port (defaults to 8443, set to 0 or false to disable)
|
||||||
HTTPS_PORT=8443
|
HTTPS_PORT=8443
|
||||||
# SQL Studio port (served when backend is started with npm run dev)
|
# Backend Monitor Interface port (served when backend is started with npm run dev)
|
||||||
SQL_STUDIO_PORT=4210
|
MONITOR_PORT=4210
|
||||||
# Optional custom TLS cert/key paths (defaults to auto-generated certs/key.pem and certs/cert.pem)
|
# Optional custom TLS cert/key paths (defaults to auto-generated certs/key.pem and certs/cert.pem)
|
||||||
# HTTPS_KEY_PATH=./certs/key.pem
|
# HTTPS_KEY_PATH=./certs/key.pem
|
||||||
# HTTPS_CERT_PATH=./certs/cert.pem
|
# HTTPS_CERT_PATH=./certs/cert.pem
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node src/index.js",
|
"start": "node src/index.js",
|
||||||
"dev": "cross-env DEV_SQL_STUDIO=true node --watch-path=./src --watch-path=./.env --watch-path=../dashdbschema/src --watch-path=../llmorbiter/src src/index.js",
|
"dev": "cross-env DEV_BACKEND_MONITOR=true node --watch-path=./src --watch-path=./.env --watch-path=../dashdbschema/src --watch-path=../llmorbiter/src src/index.js",
|
||||||
"manage-users": "node scripts/manageUsers.js",
|
"manage-users": "node scripts/manageUsers.js",
|
||||||
"wipe-company": "node scripts/wipeCompany.js",
|
"wipe-company": "node scripts/wipeCompany.js",
|
||||||
"docs:api": "node scripts/generateApiDocs.js",
|
"docs:api": "node scripts/generateApiDocs.js",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { shutdownJavascriptSandboxWorkers } from '../services/javascriptSandbox.
|
|||||||
import { getOrCreateCert } from '../util/cert.js';
|
import { getOrCreateCert } from '../util/cert.js';
|
||||||
import { createLogger } from '../util/logger.js';
|
import { createLogger } from '../util/logger.js';
|
||||||
import v1Router from '../v1/index.js';
|
import v1Router from '../v1/index.js';
|
||||||
import { startSqlStudio, stopSqlStudio, isDevMode } from '../sqlstudio/server.js';
|
import { startBackendMonitor, stopBackendMonitor, isDevMode } from '../backendmonitor/server.js';
|
||||||
|
|
||||||
const apiLog = createLogger('api');
|
const apiLog = createLogger('api');
|
||||||
|
|
||||||
@@ -239,9 +239,9 @@ export async function startApi() {
|
|||||||
|
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
try {
|
try {
|
||||||
await startSqlStudio();
|
await startBackendMonitor();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
apiLog.error('Failed to start SQL Studio:', err.message);
|
apiLog.error('Failed to start Backend Monitor Interface:', err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ export async function startApi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function stopApi() {
|
export async function stopApi() {
|
||||||
await stopSqlStudio();
|
await stopBackendMonitor();
|
||||||
if (!server && !httpsServer) return;
|
if (!server && !httpsServer) return;
|
||||||
// Long-lived SSE (and keep-alive) sockets otherwise block server.close()
|
// Long-lived SSE (and keep-alive) sockets otherwise block server.close()
|
||||||
// forever — node --watch hangs on "Waiting for graceful termination...".
|
// forever — node --watch hangs on "Waiting for graceful termination...".
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export async function getDatabaseInfo() {
|
|||||||
dialect,
|
dialect,
|
||||||
database: dialect === 'sqlite' ? env.sqlite.filename : env.mssql.database,
|
database: dialect === 'sqlite' ? env.sqlite.filename : env.mssql.database,
|
||||||
server: dialect === 'sqlite' ? 'local' : (env.mssql.server || 'localhost'),
|
server: dialect === 'sqlite' ? 'local' : (env.mssql.server || 'localhost'),
|
||||||
port: env.sqlStudioPort,
|
port: env.monitorPort,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Dash SQL Studio — Web Database Studio
|
* Backend Monitor Interface — Web Database Studio
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
let queryHistory = [];
|
let queryHistory = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saved = localStorage.getItem('dash_sql_studio_history');
|
const saved = localStorage.getItem('dash_backend_monitor_history') || localStorage.getItem('dash_sql_studio_history');
|
||||||
if (saved) queryHistory = JSON.parse(saved);
|
if (saved) queryHistory = JSON.parse(saved);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
queryHistory = [];
|
queryHistory = [];
|
||||||
@@ -1159,7 +1159,7 @@
|
|||||||
queryHistory.unshift(item);
|
queryHistory.unshift(item);
|
||||||
if (queryHistory.length > 50) queryHistory.pop();
|
if (queryHistory.length > 50) queryHistory.pop();
|
||||||
try {
|
try {
|
||||||
localStorage.setItem('dash_sql_studio_history', JSON.stringify(queryHistory));
|
localStorage.setItem('dash_backend_monitor_history', JSON.stringify(queryHistory));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
@@ -1319,7 +1319,7 @@
|
|||||||
await loadDbStatus();
|
await loadDbStatus();
|
||||||
await loadTables();
|
await loadTables();
|
||||||
// Default initial query tab
|
// Default initial query tab
|
||||||
openQueryTab('-- Dash SQL Studio\nSELECT 1 as connected;');
|
openQueryTab('-- Backend Monitor Interface\nSELECT 1 as connected;');
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Dash SQL Studio</title>
|
<title>Backend Monitor Interface</title>
|
||||||
<!-- Google Fonts: Inter & JetBrains Mono -->
|
<!-- Google Fonts: Inter & JetBrains Mono -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path>
|
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span class="brand-title">Dash SQL Studio</span>
|
<span class="brand-title">Backend Monitor Interface</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-badge">DEV MODE • NO AUTH</div>
|
<div class="dev-badge">DEV MODE • NO AUTH</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Dash SQL Studio — Modern SSMS Dark Theme
|
Backend Monitor Interface — Modern SSMS Dark Theme
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
@@ -6,15 +6,16 @@ import env from '../config/env.js';
|
|||||||
import { createLogger } from '../util/logger.js';
|
import { createLogger } from '../util/logger.js';
|
||||||
import * as dbHelper from './dbHelper.js';
|
import * as dbHelper from './dbHelper.js';
|
||||||
|
|
||||||
const studioLog = createLogger('sqlstudio');
|
const monitorLog = createLogger('backendmonitor');
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
let studioServer;
|
let monitorServer;
|
||||||
let studioApp;
|
let monitorApp;
|
||||||
|
|
||||||
export function isDevMode() {
|
export function isDevMode() {
|
||||||
return (
|
return (
|
||||||
process.env.npm_lifecycle_event === 'dev' ||
|
process.env.npm_lifecycle_event === 'dev' ||
|
||||||
|
process.env.DEV_BACKEND_MONITOR === 'true' ||
|
||||||
process.env.DEV_SQL_STUDIO === 'true' ||
|
process.env.DEV_SQL_STUDIO === 'true' ||
|
||||||
process.env.DEV_MODE === 'true'
|
process.env.DEV_MODE === 'true'
|
||||||
);
|
);
|
||||||
@@ -138,39 +139,43 @@ export function buildStudioApp() {
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startSqlStudio() {
|
export async function startBackendMonitor() {
|
||||||
if (studioServer) {
|
if (monitorServer) {
|
||||||
return studioServer;
|
return monitorServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = buildStudioApp();
|
const app = buildStudioApp();
|
||||||
studioApp = app;
|
monitorApp = app;
|
||||||
|
|
||||||
const serverInstance = http.createServer(app);
|
const serverInstance = http.createServer(app);
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
serverInstance.once('listening', () => resolve());
|
serverInstance.once('listening', () => resolve());
|
||||||
serverInstance.once('error', (err) => {
|
serverInstance.once('error', (err) => {
|
||||||
studioLog.error(`Failed to listen on port ${env.sqlStudioPort}:`, err.message);
|
monitorLog.error(`Failed to listen on port ${env.monitorPort}:`, err.message);
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
serverInstance.listen(env.sqlStudioPort);
|
serverInstance.listen(env.monitorPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
studioServer = serverInstance;
|
monitorServer = serverInstance;
|
||||||
studioLog.info(`SQL Studio running on http://localhost:${env.sqlStudioPort} (dev mode, no auth)`);
|
monitorLog.info(`Backend Monitor Interface running on http://localhost:${env.monitorPort} (dev mode, no auth)`);
|
||||||
return studioServer;
|
return monitorServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stopSqlStudio() {
|
export async function stopBackendMonitor() {
|
||||||
if (!studioServer) return;
|
if (!monitorServer) return;
|
||||||
const s = studioServer;
|
const s = monitorServer;
|
||||||
studioServer = undefined;
|
monitorServer = undefined;
|
||||||
studioApp = undefined;
|
monitorApp = undefined;
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
s.close((err) => (err ? reject(err) : resolve()));
|
s.close((err) => (err ? reject(err) : resolve()));
|
||||||
s.closeAllConnections();
|
s.closeAllConnections();
|
||||||
});
|
});
|
||||||
studioLog.info('SQL Studio stopped');
|
monitorLog.info('Backend Monitor Interface stopped');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Aliases for compatibility
|
||||||
|
export const startSqlStudio = startBackendMonitor;
|
||||||
|
export const stopSqlStudio = stopBackendMonitor;
|
||||||
@@ -15,7 +15,7 @@ function parseHttpsPort(val) {
|
|||||||
export default {
|
export default {
|
||||||
port: Number(process.env.PORT) || 4208,
|
port: Number(process.env.PORT) || 4208,
|
||||||
httpsPort: parseHttpsPort(process.env.HTTPS_PORT),
|
httpsPort: parseHttpsPort(process.env.HTTPS_PORT),
|
||||||
sqlStudioPort: Number(process.env.SQL_STUDIO_PORT) || 4210,
|
monitorPort: Number(process.env.MONITOR_PORT || process.env.SQL_STUDIO_PORT) || 4210,
|
||||||
httpsKeyPath: process.env.HTTPS_KEY_PATH || resolve(__dirname, '../../certs/key.pem'),
|
httpsKeyPath: process.env.HTTPS_KEY_PATH || resolve(__dirname, '../../certs/key.pem'),
|
||||||
httpsCertPath: process.env.HTTPS_CERT_PATH || resolve(__dirname, '../../certs/cert.pem'),
|
httpsCertPath: process.env.HTTPS_CERT_PATH || resolve(__dirname, '../../certs/cert.pem'),
|
||||||
logLevel: process.env.LOG_LEVEL || 'debug',
|
logLevel: process.env.LOG_LEVEL || 'debug',
|
||||||
|
|||||||
Reference in New Issue
Block a user