@qodalis/cli-server-node 1.0.0-beta.1 → 1.0.0-beta.10
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/LICENSE +1 -1
- package/README.md +348 -74
- package/dist/package.json +77 -0
- package/dist/src/abstractions/cli-command-author.d.ts +2 -0
- package/dist/src/abstractions/cli-command-author.d.ts.map +1 -0
- package/dist/src/abstractions/cli-command-author.js +7 -0
- package/dist/src/abstractions/cli-command-author.js.map +1 -0
- package/dist/src/abstractions/cli-command-parameter-descriptor.d.ts +2 -0
- package/dist/src/abstractions/cli-command-parameter-descriptor.d.ts.map +1 -0
- package/dist/src/abstractions/cli-command-parameter-descriptor.js +6 -0
- package/dist/src/abstractions/cli-command-parameter-descriptor.js.map +1 -0
- package/dist/src/abstractions/cli-command-processor.d.ts +2 -0
- package/dist/src/abstractions/cli-command-processor.d.ts.map +1 -0
- package/dist/src/abstractions/cli-command-processor.js +6 -0
- package/dist/src/abstractions/cli-command-processor.js.map +1 -0
- package/dist/src/abstractions/cli-process-command.d.ts +2 -0
- package/dist/src/abstractions/cli-process-command.d.ts.map +1 -0
- package/dist/src/abstractions/cli-process-command.js.map +1 -0
- package/dist/src/abstractions/index.d.ts +2 -0
- package/dist/src/abstractions/index.d.ts.map +1 -0
- package/dist/src/abstractions/index.js +18 -0
- package/dist/src/abstractions/index.js.map +1 -0
- package/dist/src/auth/cli-server-auth-gate.d.ts +33 -0
- package/dist/src/auth/cli-server-auth-gate.d.ts.map +1 -0
- package/dist/src/auth/cli-server-auth-gate.js +121 -0
- package/dist/src/auth/cli-server-auth-gate.js.map +1 -0
- package/dist/src/auth/cli-server-auth.d.ts +149 -0
- package/dist/src/auth/cli-server-auth.d.ts.map +1 -0
- package/dist/src/auth/cli-server-auth.js +143 -0
- package/dist/src/auth/cli-server-auth.js.map +1 -0
- package/dist/src/auth/index.d.ts +4 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +19 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/ws-upgrade-auth.d.ts +30 -0
- package/dist/src/auth/ws-upgrade-auth.d.ts.map +1 -0
- package/dist/src/auth/ws-upgrade-auth.js +49 -0
- package/dist/src/auth/ws-upgrade-auth.js.map +1 -0
- package/dist/src/controllers/cli-controller.d.ts +11 -0
- package/dist/src/controllers/cli-controller.d.ts.map +1 -0
- package/dist/src/controllers/cli-controller.js +169 -0
- package/dist/src/controllers/cli-controller.js.map +1 -0
- package/dist/src/controllers/cli-version-controller.d.ts +18 -0
- package/dist/src/controllers/cli-version-controller.d.ts.map +1 -0
- package/dist/src/controllers/cli-version-controller.js +81 -0
- package/dist/src/controllers/cli-version-controller.js.map +1 -0
- package/dist/src/controllers/filesystem-controller.d.ts +9 -0
- package/dist/src/controllers/filesystem-controller.d.ts.map +1 -0
- package/dist/src/controllers/filesystem-controller.js +243 -0
- package/dist/src/controllers/filesystem-controller.js.map +1 -0
- package/dist/src/create-cli-server.d.ts +123 -0
- package/dist/src/create-cli-server.d.ts.map +1 -0
- package/dist/src/create-cli-server.js +201 -0
- package/dist/src/create-cli-server.js.map +1 -0
- package/dist/src/extensions/cli-builder.d.ts +54 -0
- package/dist/src/extensions/cli-builder.d.ts.map +1 -0
- package/dist/src/extensions/cli-builder.js +97 -0
- package/dist/src/extensions/cli-builder.js.map +1 -0
- package/dist/src/extensions/index.d.ts.map +1 -0
- package/dist/src/extensions/index.js.map +1 -0
- package/dist/src/filesystem/filesystem-options.d.ts +16 -0
- package/dist/src/filesystem/filesystem-options.d.ts.map +1 -0
- package/dist/src/filesystem/filesystem-options.js +6 -0
- package/dist/src/filesystem/filesystem-options.js.map +1 -0
- package/dist/src/filesystem/filesystem-path-validator.d.ts +15 -0
- package/dist/src/filesystem/filesystem-path-validator.d.ts.map +1 -0
- package/dist/src/filesystem/filesystem-path-validator.js +72 -0
- package/dist/src/filesystem/filesystem-path-validator.js.map +1 -0
- package/dist/src/filesystem/index.d.ts +3 -0
- package/dist/src/filesystem/index.d.ts.map +1 -0
- package/dist/src/filesystem/index.js +8 -0
- package/dist/src/filesystem/index.js.map +1 -0
- package/dist/src/index.d.ts +24 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +121 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/index.d.ts +10 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/mcp/index.js +34 -0
- package/dist/src/mcp/index.js.map +1 -0
- package/dist/src/mcp/mcp-controller.d.ts +54 -0
- package/dist/src/mcp/mcp-controller.d.ts.map +1 -0
- package/dist/src/mcp/mcp-controller.js +358 -0
- package/dist/src/mcp/mcp-controller.js.map +1 -0
- package/dist/src/mcp/mcp-render.d.ts +10 -0
- package/dist/src/mcp/mcp-render.d.ts.map +1 -0
- package/dist/src/mcp/mcp-render.js +66 -0
- package/dist/src/mcp/mcp-render.js.map +1 -0
- package/dist/src/mcp/mcp-schema.d.ts +8 -0
- package/dist/src/mcp/mcp-schema.d.ts.map +1 -0
- package/dist/src/mcp/mcp-schema.js +64 -0
- package/dist/src/mcp/mcp-schema.js.map +1 -0
- package/dist/src/mcp/mcp-types.d.ts +70 -0
- package/dist/src/mcp/mcp-types.d.ts.map +1 -0
- package/dist/src/mcp/mcp-types.js +21 -0
- package/dist/src/mcp/mcp-types.js.map +1 -0
- package/dist/src/mcp/providers/commands-provider.d.ts +30 -0
- package/dist/src/mcp/providers/commands-provider.d.ts.map +1 -0
- package/dist/src/mcp/providers/commands-provider.js +145 -0
- package/dist/src/mcp/providers/commands-provider.js.map +1 -0
- package/dist/src/mcp/providers/data-explorer-provider.d.ts +15 -0
- package/dist/src/mcp/providers/data-explorer-provider.d.ts.map +1 -0
- package/dist/src/mcp/providers/data-explorer-provider.js +83 -0
- package/dist/src/mcp/providers/data-explorer-provider.js.map +1 -0
- package/dist/src/mcp/providers/filesystem-provider.d.ts +15 -0
- package/dist/src/mcp/providers/filesystem-provider.d.ts.map +1 -0
- package/dist/src/mcp/providers/filesystem-provider.js +166 -0
- package/dist/src/mcp/providers/filesystem-provider.js.map +1 -0
- package/dist/src/mcp/providers/jobs-provider.d.ts +23 -0
- package/dist/src/mcp/providers/jobs-provider.d.ts.map +1 -0
- package/dist/src/mcp/providers/jobs-provider.js +121 -0
- package/dist/src/mcp/providers/jobs-provider.js.map +1 -0
- package/dist/src/mcp/providers/server-provider.d.ts +19 -0
- package/dist/src/mcp/providers/server-provider.d.ts.map +1 -0
- package/dist/src/mcp/providers/server-provider.js +73 -0
- package/dist/src/mcp/providers/server-provider.js.map +1 -0
- package/dist/{models → src/models}/cli-server-command-descriptor.d.ts +2 -0
- package/dist/src/models/cli-server-command-descriptor.d.ts.map +1 -0
- package/dist/src/models/cli-server-command-descriptor.js.map +1 -0
- package/dist/src/models/cli-server-output.d.ts +2 -0
- package/dist/src/models/cli-server-output.d.ts.map +1 -0
- package/dist/src/models/cli-server-output.js.map +1 -0
- package/dist/src/models/cli-server-response.d.ts +2 -0
- package/dist/src/models/cli-server-response.d.ts.map +1 -0
- package/dist/src/models/cli-server-response.js.map +1 -0
- package/dist/src/models/index.d.ts.map +1 -0
- package/dist/{models → src/models}/index.js.map +1 -1
- package/dist/{processors → src/processors}/cli-base64-command-processor.d.ts +1 -0
- package/dist/src/processors/cli-base64-command-processor.d.ts.map +1 -0
- package/dist/{processors → src/processors}/cli-base64-command-processor.js +8 -2
- package/dist/src/processors/cli-base64-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/cli-echo-command-processor.d.ts +2 -0
- package/dist/src/processors/cli-echo-command-processor.d.ts.map +1 -0
- package/dist/src/processors/cli-echo-command-processor.js +20 -0
- package/dist/src/processors/cli-echo-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/cli-hash-command-processor.d.ts +2 -0
- package/dist/src/processors/cli-hash-command-processor.d.ts.map +1 -0
- package/dist/{processors → src/processors}/cli-hash-command-processor.js +4 -1
- package/dist/src/processors/cli-hash-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/cli-http-command-processor.d.ts +1 -0
- package/dist/src/processors/cli-http-command-processor.d.ts.map +1 -0
- package/dist/src/processors/cli-http-command-processor.js +161 -0
- package/dist/src/processors/cli-http-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/cli-status-command-processor.d.ts +1 -0
- package/dist/src/processors/cli-status-command-processor.d.ts.map +1 -0
- package/dist/{processors → src/processors}/cli-status-command-processor.js +1 -0
- package/dist/src/processors/cli-status-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/cli-system-command-processor.d.ts +1 -0
- package/dist/src/processors/cli-system-command-processor.d.ts.map +1 -0
- package/dist/{processors → src/processors}/cli-system-command-processor.js +1 -0
- package/dist/src/processors/cli-system-command-processor.js.map +1 -0
- package/dist/{processors → src/processors}/index.d.ts +1 -2
- package/dist/src/processors/index.d.ts.map +1 -0
- package/dist/{processors → src/processors}/index.js +2 -3
- package/dist/src/processors/index.js.map +1 -0
- package/dist/{server.d.ts.map → src/server.d.ts.map} +1 -1
- package/dist/{server.js → src/server.js} +22 -7
- package/dist/src/server.js.map +1 -0
- package/dist/src/services/cli-command-executor-service.d.ts +33 -0
- package/dist/src/services/cli-command-executor-service.d.ts.map +1 -0
- package/dist/src/services/cli-command-executor-service.js +77 -0
- package/dist/src/services/cli-command-executor-service.js.map +1 -0
- package/dist/src/services/cli-command-registry.d.ts +25 -0
- package/dist/src/services/cli-command-registry.d.ts.map +1 -0
- package/dist/{services → src/services}/cli-command-registry.js +5 -0
- package/dist/src/services/cli-command-registry.js.map +1 -0
- package/dist/src/services/cli-event-socket-manager.d.ts +77 -0
- package/dist/src/services/cli-event-socket-manager.d.ts.map +1 -0
- package/dist/src/services/cli-event-socket-manager.js +246 -0
- package/dist/src/services/cli-event-socket-manager.js.map +1 -0
- package/dist/src/services/cli-log-socket-manager.d.ts +67 -0
- package/dist/src/services/cli-log-socket-manager.d.ts.map +1 -0
- package/dist/src/services/cli-log-socket-manager.js +225 -0
- package/dist/src/services/cli-log-socket-manager.js.map +1 -0
- package/dist/{services → src/services}/cli-response-builder.d.ts +9 -0
- package/dist/src/services/cli-response-builder.d.ts.map +1 -0
- package/dist/{services → src/services}/cli-response-builder.js +1 -0
- package/dist/src/services/cli-response-builder.js.map +1 -0
- package/dist/src/services/cli-shell-options.d.ts +107 -0
- package/dist/src/services/cli-shell-options.d.ts.map +1 -0
- package/dist/src/services/cli-shell-options.js +139 -0
- package/dist/src/services/cli-shell-options.js.map +1 -0
- package/dist/src/services/cli-shell-session-manager.d.ts +92 -0
- package/dist/src/services/cli-shell-session-manager.d.ts.map +1 -0
- package/dist/src/services/cli-shell-session-manager.js +588 -0
- package/dist/src/services/cli-shell-session-manager.js.map +1 -0
- package/dist/src/services/index.d.ts +8 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +20 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/process-tree.d.ts +38 -0
- package/dist/src/services/process-tree.d.ts.map +1 -0
- package/dist/src/services/process-tree.js +249 -0
- package/dist/src/services/process-tree.js.map +1 -0
- package/dist/src/services/session-bound-sockets.d.ts +45 -0
- package/dist/src/services/session-bound-sockets.d.ts.map +1 -0
- package/dist/src/services/session-bound-sockets.js +129 -0
- package/dist/src/services/session-bound-sockets.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +13 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/package.json +37 -8
- package/dist/abstractions/cli-command-author.d.ts +0 -11
- package/dist/abstractions/cli-command-author.d.ts.map +0 -1
- package/dist/abstractions/cli-command-author.js +0 -14
- package/dist/abstractions/cli-command-author.js.map +0 -1
- package/dist/abstractions/cli-command-parameter-descriptor.d.ts +0 -18
- package/dist/abstractions/cli-command-parameter-descriptor.d.ts.map +0 -1
- package/dist/abstractions/cli-command-parameter-descriptor.js +0 -21
- package/dist/abstractions/cli-command-parameter-descriptor.js.map +0 -1
- package/dist/abstractions/cli-command-processor.d.ts +0 -26
- package/dist/abstractions/cli-command-processor.d.ts.map +0 -1
- package/dist/abstractions/cli-command-processor.js +0 -14
- package/dist/abstractions/cli-command-processor.js.map +0 -1
- package/dist/abstractions/cli-process-command.d.ts +0 -9
- package/dist/abstractions/cli-process-command.d.ts.map +0 -1
- package/dist/abstractions/cli-process-command.js.map +0 -1
- package/dist/abstractions/index.d.ts +0 -5
- package/dist/abstractions/index.d.ts.map +0 -1
- package/dist/abstractions/index.js +0 -11
- package/dist/abstractions/index.js.map +0 -1
- package/dist/controllers/cli-controller.d.ts +0 -4
- package/dist/controllers/cli-controller.d.ts.map +0 -1
- package/dist/controllers/cli-controller.js +0 -42
- package/dist/controllers/cli-controller.js.map +0 -1
- package/dist/create-cli-server.d.ts +0 -25
- package/dist/create-cli-server.d.ts.map +0 -1
- package/dist/create-cli-server.js +0 -35
- package/dist/create-cli-server.js.map +0 -1
- package/dist/extensions/cli-builder.d.ts +0 -9
- package/dist/extensions/cli-builder.d.ts.map +0 -1
- package/dist/extensions/cli-builder.js +0 -18
- package/dist/extensions/cli-builder.js.map +0 -1
- package/dist/extensions/index.d.ts.map +0 -1
- package/dist/extensions/index.js.map +0 -1
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -40
- package/dist/index.js.map +0 -1
- package/dist/models/cli-server-command-descriptor.d.ts.map +0 -1
- package/dist/models/cli-server-command-descriptor.js.map +0 -1
- package/dist/models/cli-server-output.d.ts +0 -23
- package/dist/models/cli-server-output.d.ts.map +0 -1
- package/dist/models/cli-server-output.js.map +0 -1
- package/dist/models/cli-server-response.d.ts +0 -6
- package/dist/models/cli-server-response.d.ts.map +0 -1
- package/dist/models/cli-server-response.js.map +0 -1
- package/dist/models/index.d.ts.map +0 -1
- package/dist/processors/cli-base64-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-base64-command-processor.js.map +0 -1
- package/dist/processors/cli-echo-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-echo-command-processor.js +0 -14
- package/dist/processors/cli-echo-command-processor.js.map +0 -1
- package/dist/processors/cli-hash-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-hash-command-processor.js.map +0 -1
- package/dist/processors/cli-http-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-http-command-processor.js +0 -79
- package/dist/processors/cli-http-command-processor.js.map +0 -1
- package/dist/processors/cli-status-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-status-command-processor.js.map +0 -1
- package/dist/processors/cli-system-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-system-command-processor.js.map +0 -1
- package/dist/processors/cli-uuid-command-processor.d.ts +0 -10
- package/dist/processors/cli-uuid-command-processor.d.ts.map +0 -1
- package/dist/processors/cli-uuid-command-processor.js +0 -27
- package/dist/processors/cli-uuid-command-processor.js.map +0 -1
- package/dist/processors/index.d.ts.map +0 -1
- package/dist/processors/index.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/services/cli-command-executor-service.d.ts +0 -12
- package/dist/services/cli-command-executor-service.d.ts.map +0 -1
- package/dist/services/cli-command-executor-service.js +0 -45
- package/dist/services/cli-command-executor-service.js.map +0 -1
- package/dist/services/cli-command-registry.d.ts +0 -14
- package/dist/services/cli-command-registry.d.ts.map +0 -1
- package/dist/services/cli-command-registry.js.map +0 -1
- package/dist/services/cli-event-socket-manager.d.ts +0 -15
- package/dist/services/cli-event-socket-manager.d.ts.map +0 -1
- package/dist/services/cli-event-socket-manager.js +0 -60
- package/dist/services/cli-event-socket-manager.js.map +0 -1
- package/dist/services/cli-response-builder.d.ts.map +0 -1
- package/dist/services/cli-response-builder.js.map +0 -1
- package/dist/services/index.d.ts +0 -5
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -12
- package/dist/services/index.js.map +0 -1
- /package/dist/{abstractions → src/abstractions}/cli-process-command.js +0 -0
- /package/dist/{extensions → src/extensions}/index.d.ts +0 -0
- /package/dist/{extensions → src/extensions}/index.js +0 -0
- /package/dist/{models → src/models}/cli-server-command-descriptor.js +0 -0
- /package/dist/{models → src/models}/cli-server-output.js +0 -0
- /package/dist/{models → src/models}/cli-server-response.js +0 -0
- /package/dist/{models → src/models}/index.d.ts +0 -0
- /package/dist/{models → src/models}/index.js +0 -0
- /package/dist/{server.d.ts → src/server.d.ts} +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CliEventSocketManager = void 0;
|
|
4
|
+
const ws_1 = require("ws");
|
|
5
|
+
const url_1 = require("url");
|
|
6
|
+
const cli_shell_session_manager_1 = require("./cli-shell-session-manager");
|
|
7
|
+
const logger_1 = require("../utils/logger");
|
|
8
|
+
const cli_server_auth_1 = require("../auth/cli-server-auth");
|
|
9
|
+
const ws_upgrade_auth_1 = require("../auth/ws-upgrade-auth");
|
|
10
|
+
const session_bound_sockets_1 = require("./session-bound-sockets");
|
|
11
|
+
const logger = (0, logger_1.createLogger)('EventSocket');
|
|
12
|
+
/** Events delivered only to sockets authenticated as the event's user. */
|
|
13
|
+
const USER_SCOPED_EVENTS = new Set(['session-kicked']);
|
|
14
|
+
/**
|
|
15
|
+
* Manages WebSocket connections for server-push events and interactive shell sessions.
|
|
16
|
+
* Handles upgrades on `/ws/v1/qcli/events` and (when `enableShell` is set)
|
|
17
|
+
* `/ws/v1/qcli/shell`. With an auth provider that protects the server, event
|
|
18
|
+
* upgrades need a single-use `?ticket=`; `session-kicked` is delivered only to
|
|
19
|
+
* the affected user. Sockets authenticated with a stored session are bound to
|
|
20
|
+
* it: once it ends they are closed with 4401 `session ended` (after
|
|
21
|
+
* `session-kicked` for revocations; see {@link SessionBoundSockets}). Shell
|
|
22
|
+
* access (modes, limits, session binding) is decided by {@link CliShellSessionManager}.
|
|
23
|
+
*/
|
|
24
|
+
class CliEventSocketManager {
|
|
25
|
+
_wss = null;
|
|
26
|
+
_clients = new Set();
|
|
27
|
+
_clientMeta = new Map();
|
|
28
|
+
_shellManager;
|
|
29
|
+
_nextClientId = 1;
|
|
30
|
+
_auth;
|
|
31
|
+
_allowedOrigins;
|
|
32
|
+
_trustProxy;
|
|
33
|
+
_sessionBound = new session_bound_sockets_1.SessionBoundSockets({ awaitKick: true });
|
|
34
|
+
constructor(options = {}) {
|
|
35
|
+
this._shellManager = new cli_shell_session_manager_1.CliShellSessionManager({
|
|
36
|
+
enabled: options.enableShell ?? false,
|
|
37
|
+
shell: options.shell,
|
|
38
|
+
trustProxy: options.trustProxy,
|
|
39
|
+
});
|
|
40
|
+
this._allowedOrigins = options.allowedOrigins;
|
|
41
|
+
this._trustProxy = options.trustProxy ?? false;
|
|
42
|
+
}
|
|
43
|
+
/** Installs the auth provider (users plugin) used to authenticate upgrades with tickets. */
|
|
44
|
+
setAuth(auth) {
|
|
45
|
+
this._auth = auth;
|
|
46
|
+
this._shellManager.setAuth(auth);
|
|
47
|
+
this._sessionBound.setAuth(auth);
|
|
48
|
+
}
|
|
49
|
+
setAllowedOrigins(origins) {
|
|
50
|
+
this._allowedOrigins = origins;
|
|
51
|
+
}
|
|
52
|
+
setShellEnabled(enabled) {
|
|
53
|
+
this._shellManager.setEnabled(enabled);
|
|
54
|
+
}
|
|
55
|
+
get shellEnabled() {
|
|
56
|
+
return this._shellManager.enabled;
|
|
57
|
+
}
|
|
58
|
+
/** Shell access mode (`undefined` while the shell is disabled). */
|
|
59
|
+
get shellAuthMode() {
|
|
60
|
+
return this._shellManager.authMode;
|
|
61
|
+
}
|
|
62
|
+
/** The shell session manager (open sessions, limits, binding). */
|
|
63
|
+
get shellManager() {
|
|
64
|
+
return this._shellManager;
|
|
65
|
+
}
|
|
66
|
+
static EVENT_PATHS = new Set([
|
|
67
|
+
'/ws/v1/qcli/events',
|
|
68
|
+
'/ws/qcli/events',
|
|
69
|
+
]);
|
|
70
|
+
static SHELL_PATHS = new Set([
|
|
71
|
+
'/ws/v1/qcli/shell',
|
|
72
|
+
'/ws/qcli/shell',
|
|
73
|
+
]);
|
|
74
|
+
/**
|
|
75
|
+
* Attach to an HTTP server and listen for WebSocket upgrades on
|
|
76
|
+
* event and shell paths.
|
|
77
|
+
*/
|
|
78
|
+
attach(server) {
|
|
79
|
+
this._wss = new ws_1.WebSocketServer({ noServer: true });
|
|
80
|
+
this._shellManager.logStartupState();
|
|
81
|
+
server.on('upgrade', (request, socket, head) => {
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = new url_1.URL(request.url ?? '', 'http://localhost');
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return; // malformed request target: not one of our paths
|
|
88
|
+
}
|
|
89
|
+
const pathname = parsed.pathname;
|
|
90
|
+
if (CliEventSocketManager.EVENT_PATHS.has(pathname)) {
|
|
91
|
+
(0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, { auth: this._auth, allowedOrigins: this._allowedOrigins, trustProxy: this._trustProxy }).then((result) => {
|
|
92
|
+
if (!result.ok) {
|
|
93
|
+
(0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this._wss.handleUpgrade(request, socket, head, (ws) => {
|
|
97
|
+
this._wss.emit('connection', ws, request, result.ctx);
|
|
98
|
+
});
|
|
99
|
+
}, () => (0, ws_upgrade_auth_1.rejectUpgrade)(socket, 401));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (CliEventSocketManager.SHELL_PATHS.has(pathname)) {
|
|
103
|
+
// Origin rejection stays an HTTP 403; every other refusal is
|
|
104
|
+
// "accept, then close" with a code the browser can read (C5).
|
|
105
|
+
(0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, { allowedOrigins: this._allowedOrigins, trustProxy: this._trustProxy }).then((result) => {
|
|
106
|
+
if (!result.ok) {
|
|
107
|
+
(0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this._wss.handleUpgrade(request, socket, head, (ws) => {
|
|
111
|
+
this._shellManager.accept(ws, request, parsed).catch((err) => {
|
|
112
|
+
logger.error('Shell session error: %s', err?.message ?? err);
|
|
113
|
+
try {
|
|
114
|
+
ws.close(1011, 'shell error');
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// ignore
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Unrecognized path; leave for other upgrade handlers
|
|
125
|
+
});
|
|
126
|
+
this._wss.on('connection', (ws, request, auth) => {
|
|
127
|
+
this._clients.add(ws);
|
|
128
|
+
const id = `evt-${this._nextClientId++}`;
|
|
129
|
+
this._clientMeta.set(ws, {
|
|
130
|
+
id,
|
|
131
|
+
connectedAt: new Date(),
|
|
132
|
+
remoteAddress: request.socket.remoteAddress ?? 'unknown',
|
|
133
|
+
auth,
|
|
134
|
+
});
|
|
135
|
+
this._sessionBound.bind(ws, auth);
|
|
136
|
+
logger.info('Client connected (id=%s)', id);
|
|
137
|
+
ws.send(JSON.stringify({ type: 'connected' }));
|
|
138
|
+
const disconnected = () => {
|
|
139
|
+
const meta = this._clientMeta.get(ws);
|
|
140
|
+
logger.info('Client disconnected (id=%s)', meta?.id ?? 'unknown');
|
|
141
|
+
this._sessionBound.unbind(ws);
|
|
142
|
+
this._clients.delete(ws);
|
|
143
|
+
this._clientMeta.delete(ws);
|
|
144
|
+
};
|
|
145
|
+
ws.on('close', disconnected);
|
|
146
|
+
ws.on('error', disconnected);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Broadcast an arbitrary message to all connected event clients.
|
|
151
|
+
*/
|
|
152
|
+
broadcastMessage(message) {
|
|
153
|
+
const data = JSON.stringify(message);
|
|
154
|
+
const type = typeof message.type === 'string' ? message.type : '';
|
|
155
|
+
const payload = (message.data ?? {});
|
|
156
|
+
const toClose = [];
|
|
157
|
+
for (const ws of this._clients) {
|
|
158
|
+
if (ws.readyState !== ws_1.WebSocket.OPEN)
|
|
159
|
+
continue;
|
|
160
|
+
const auth = this._clientMeta.get(ws)?.auth;
|
|
161
|
+
if (USER_SCOPED_EVENTS.has(type)) {
|
|
162
|
+
// Only the affected user's sockets learn about it
|
|
163
|
+
if (!auth || auth.userId !== payload.userId)
|
|
164
|
+
continue;
|
|
165
|
+
ws.send(data);
|
|
166
|
+
if (type === 'session-kicked' && auth.sessionId && auth.sessionId === payload.sessionId) {
|
|
167
|
+
toClose.push(ws);
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
// A socket whose session ended only waits for its session-kicked
|
|
172
|
+
if (this._sessionBound.isEnding(ws))
|
|
173
|
+
continue;
|
|
174
|
+
if (this._auth?.protectServer) {
|
|
175
|
+
// Server-wide events need the matching read permission
|
|
176
|
+
const needed = type === 'log' || type.startsWith('log:')
|
|
177
|
+
? cli_server_auth_1.CliServerPermissions.LogsRead
|
|
178
|
+
: type.startsWith('job:')
|
|
179
|
+
? cli_server_auth_1.CliServerPermissions.JobsRead
|
|
180
|
+
: undefined;
|
|
181
|
+
if (needed && (!auth || !this._auth.hasPermission(auth, needed)))
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
ws.send(data);
|
|
185
|
+
}
|
|
186
|
+
for (const ws of toClose) {
|
|
187
|
+
this._sessionBound.kicked(ws);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Broadcast a disconnect event to all connected clients and close sockets.
|
|
192
|
+
*/
|
|
193
|
+
async broadcastDisconnect() {
|
|
194
|
+
logger.info('Broadcasting disconnect to %d clients', this._clients.size);
|
|
195
|
+
const message = JSON.stringify({ type: 'disconnect' });
|
|
196
|
+
const promises = [];
|
|
197
|
+
for (const ws of this._clients) {
|
|
198
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
199
|
+
promises.push(new Promise((resolve) => {
|
|
200
|
+
ws.send(message, () => {
|
|
201
|
+
ws.close(1000, 'Server shutting down');
|
|
202
|
+
resolve();
|
|
203
|
+
});
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
await Promise.all(promises);
|
|
208
|
+
this._shellManager.dispose();
|
|
209
|
+
this._sessionBound.dispose();
|
|
210
|
+
this._clients.clear();
|
|
211
|
+
this._clientMeta.clear();
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Return information about all currently connected event clients.
|
|
215
|
+
*/
|
|
216
|
+
getClients() {
|
|
217
|
+
const result = [];
|
|
218
|
+
for (const ws of this._clients) {
|
|
219
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
220
|
+
const meta = this._clientMeta.get(ws);
|
|
221
|
+
if (meta) {
|
|
222
|
+
result.push({
|
|
223
|
+
id: meta.id,
|
|
224
|
+
connectedAt: meta.connectedAt.toISOString(),
|
|
225
|
+
remoteAddress: meta.remoteAddress,
|
|
226
|
+
type: 'events',
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
/** Terminates all connections and closes the WebSocket server. */
|
|
234
|
+
dispose() {
|
|
235
|
+
this._shellManager.dispose();
|
|
236
|
+
this._sessionBound.dispose();
|
|
237
|
+
for (const ws of this._clients) {
|
|
238
|
+
ws.terminate();
|
|
239
|
+
}
|
|
240
|
+
this._clients.clear();
|
|
241
|
+
this._clientMeta.clear();
|
|
242
|
+
this._wss?.close();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.CliEventSocketManager = CliEventSocketManager;
|
|
246
|
+
//# sourceMappingURL=cli-event-socket-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-event-socket-manager.js","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Server } from 'http';
|
|
2
|
+
import { ICliServerAuth } from '../auth/cli-server-auth';
|
|
3
|
+
/** Information about a connected WebSocket log-streaming client. */
|
|
4
|
+
export interface CliLogWebSocketClientInfo {
|
|
5
|
+
id: string;
|
|
6
|
+
connectedAt: string;
|
|
7
|
+
remoteAddress: string;
|
|
8
|
+
levelFilter: string | null;
|
|
9
|
+
type: 'logs';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Manages WebSocket connections for streaming log messages to clients.
|
|
13
|
+
*
|
|
14
|
+
* Parity with CliLogSocketManager in the .NET and Python servers.
|
|
15
|
+
* Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths. Sockets
|
|
16
|
+
* authenticated with a stored session are bound to it: once it ends they are
|
|
17
|
+
* closed with 4401 `session ended` (see {@link SessionBoundSockets}).
|
|
18
|
+
*/
|
|
19
|
+
export declare class CliLogSocketManager {
|
|
20
|
+
private _wss;
|
|
21
|
+
private readonly _clients;
|
|
22
|
+
private _nextClientId;
|
|
23
|
+
private _auth?;
|
|
24
|
+
private _allowedOrigins?;
|
|
25
|
+
private readonly _trustProxy;
|
|
26
|
+
private readonly _sessionBound;
|
|
27
|
+
constructor(options?: {
|
|
28
|
+
allowedOrigins?: string[];
|
|
29
|
+
trustProxy?: boolean | number;
|
|
30
|
+
});
|
|
31
|
+
/** Installs the auth provider; when it protects the server, upgrades need a ticket and `logs:read`. */
|
|
32
|
+
setAuth(auth: ICliServerAuth | undefined): void;
|
|
33
|
+
setAllowedOrigins(origins: string[] | undefined): void;
|
|
34
|
+
private static readonly LOG_PATHS;
|
|
35
|
+
/**
|
|
36
|
+
* Check whether a log at `logLevel` passes the `filterLevel` gate.
|
|
37
|
+
*/
|
|
38
|
+
static shouldSendLog(filterLevel: string | null, logLevel: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Format a log message as a JSON string matching the cross-server schema.
|
|
41
|
+
*/
|
|
42
|
+
static formatLogMessage(level: string, message: string, category?: string | null): string;
|
|
43
|
+
/**
|
|
44
|
+
* Attach to an HTTP server and handle WebSocket upgrades on log paths.
|
|
45
|
+
*
|
|
46
|
+
* If you already have a `CliEventSocketManager` attached, call this
|
|
47
|
+
* method on the same `server` — Node's `upgrade` event supports
|
|
48
|
+
* multiple listeners, and each manager only handles its own paths.
|
|
49
|
+
*/
|
|
50
|
+
attach(server: Server): void;
|
|
51
|
+
/**
|
|
52
|
+
* Broadcast a log message to all connected clients whose filter allows it.
|
|
53
|
+
*/
|
|
54
|
+
broadcastLog(level: string, message: string, category?: string | null): void;
|
|
55
|
+
/**
|
|
56
|
+
* Send a disconnect message to all clients and close connections.
|
|
57
|
+
*/
|
|
58
|
+
broadcastDisconnect(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Return information about all currently connected log clients.
|
|
61
|
+
*/
|
|
62
|
+
getClients(): CliLogWebSocketClientInfo[];
|
|
63
|
+
/** Terminates all connections and closes the WebSocket server. */
|
|
64
|
+
dispose(): void;
|
|
65
|
+
private _handleConnection;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=cli-log-socket-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-log-socket-manager.d.ts","sourceRoot":"","sources":["../../../src/services/cli-log-socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,MAAM,CAAC;AAGpD,OAAO,EAA8C,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMrG,oEAAoE;AACpE,MAAM,WAAW,yBAAyB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;gBAE/C,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAO;IAKtF,uGAAuG;IACvG,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI;IAK/C,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI;IAItD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAG9B;IAEH;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAY3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAUzF;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAmC5B;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAsB5E;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1C;;OAEG;IACH,UAAU,IAAI,yBAAyB,EAAE;IAgBzC,kEAAkE;IAClE,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,iBAAiB;CAwB5B"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CliLogSocketManager = void 0;
|
|
4
|
+
const ws_1 = require("ws");
|
|
5
|
+
const url_1 = require("url");
|
|
6
|
+
const logger_1 = require("../utils/logger");
|
|
7
|
+
const cli_server_auth_1 = require("../auth/cli-server-auth");
|
|
8
|
+
const ws_upgrade_auth_1 = require("../auth/ws-upgrade-auth");
|
|
9
|
+
const session_bound_sockets_1 = require("./session-bound-sockets");
|
|
10
|
+
const logger = (0, logger_1.createLogger)('LogSocket');
|
|
11
|
+
/**
|
|
12
|
+
* Level ordering from lowest to highest severity.
|
|
13
|
+
* Matches the Python/C# implementations.
|
|
14
|
+
*/
|
|
15
|
+
const LEVEL_ORDER = {
|
|
16
|
+
verbose: 0,
|
|
17
|
+
debug: 1,
|
|
18
|
+
information: 2,
|
|
19
|
+
warning: 3,
|
|
20
|
+
error: 4,
|
|
21
|
+
fatal: 5,
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Maps short/uppercase log levels (used by LogRingBuffer) to the
|
|
25
|
+
* standard level names used across all three servers.
|
|
26
|
+
*/
|
|
27
|
+
const LEVEL_ALIASES = {
|
|
28
|
+
info: 'information',
|
|
29
|
+
warn: 'warning',
|
|
30
|
+
err: 'error',
|
|
31
|
+
};
|
|
32
|
+
function normalizeLevel(level) {
|
|
33
|
+
const lower = level.toLowerCase();
|
|
34
|
+
return LEVEL_ALIASES[lower] ?? lower;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Manages WebSocket connections for streaming log messages to clients.
|
|
38
|
+
*
|
|
39
|
+
* Parity with CliLogSocketManager in the .NET and Python servers.
|
|
40
|
+
* Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths. Sockets
|
|
41
|
+
* authenticated with a stored session are bound to it: once it ends they are
|
|
42
|
+
* closed with 4401 `session ended` (see {@link SessionBoundSockets}).
|
|
43
|
+
*/
|
|
44
|
+
class CliLogSocketManager {
|
|
45
|
+
_wss = null;
|
|
46
|
+
_clients = new Map();
|
|
47
|
+
_nextClientId = 1;
|
|
48
|
+
_auth;
|
|
49
|
+
_allowedOrigins;
|
|
50
|
+
_trustProxy;
|
|
51
|
+
_sessionBound = new session_bound_sockets_1.SessionBoundSockets();
|
|
52
|
+
constructor(options = {}) {
|
|
53
|
+
this._allowedOrigins = options.allowedOrigins;
|
|
54
|
+
this._trustProxy = options.trustProxy ?? false;
|
|
55
|
+
}
|
|
56
|
+
/** Installs the auth provider; when it protects the server, upgrades need a ticket and `logs:read`. */
|
|
57
|
+
setAuth(auth) {
|
|
58
|
+
this._auth = auth;
|
|
59
|
+
this._sessionBound.setAuth(auth);
|
|
60
|
+
}
|
|
61
|
+
setAllowedOrigins(origins) {
|
|
62
|
+
this._allowedOrigins = origins;
|
|
63
|
+
}
|
|
64
|
+
static LOG_PATHS = new Set([
|
|
65
|
+
'/ws/v1/qcli/logs',
|
|
66
|
+
'/ws/qcli/logs',
|
|
67
|
+
]);
|
|
68
|
+
/**
|
|
69
|
+
* Check whether a log at `logLevel` passes the `filterLevel` gate.
|
|
70
|
+
*/
|
|
71
|
+
static shouldSendLog(filterLevel, logLevel) {
|
|
72
|
+
if (!filterLevel)
|
|
73
|
+
return true;
|
|
74
|
+
const filterOrd = LEVEL_ORDER[normalizeLevel(filterLevel)];
|
|
75
|
+
const logOrd = LEVEL_ORDER[normalizeLevel(logLevel)];
|
|
76
|
+
// Unknown levels always pass
|
|
77
|
+
if (filterOrd === undefined || logOrd === undefined)
|
|
78
|
+
return true;
|
|
79
|
+
return logOrd >= filterOrd;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Format a log message as a JSON string matching the cross-server schema.
|
|
83
|
+
*/
|
|
84
|
+
static formatLogMessage(level, message, category) {
|
|
85
|
+
return JSON.stringify({
|
|
86
|
+
type: 'log',
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
level: normalizeLevel(level),
|
|
89
|
+
message,
|
|
90
|
+
category: category ?? null,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Attach to an HTTP server and handle WebSocket upgrades on log paths.
|
|
95
|
+
*
|
|
96
|
+
* If you already have a `CliEventSocketManager` attached, call this
|
|
97
|
+
* method on the same `server` — Node's `upgrade` event supports
|
|
98
|
+
* multiple listeners, and each manager only handles its own paths.
|
|
99
|
+
*/
|
|
100
|
+
attach(server) {
|
|
101
|
+
this._wss = new ws_1.WebSocketServer({ noServer: true });
|
|
102
|
+
server.on('upgrade', (request, socket, head) => {
|
|
103
|
+
let parsed;
|
|
104
|
+
try {
|
|
105
|
+
parsed = new url_1.URL(request.url ?? '', 'http://localhost');
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return; // malformed request target: not one of our paths
|
|
109
|
+
}
|
|
110
|
+
const pathname = parsed.pathname;
|
|
111
|
+
if (!CliLogSocketManager.LOG_PATHS.has(pathname))
|
|
112
|
+
return;
|
|
113
|
+
(0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, {
|
|
114
|
+
auth: this._auth,
|
|
115
|
+
allowedOrigins: this._allowedOrigins,
|
|
116
|
+
trustProxy: this._trustProxy,
|
|
117
|
+
permission: cli_server_auth_1.CliServerPermissions.LogsRead,
|
|
118
|
+
}).then((result) => {
|
|
119
|
+
if (!result.ok) {
|
|
120
|
+
(0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this._wss.handleUpgrade(request, socket, head, (ws) => {
|
|
124
|
+
const levelFilter = parsed.searchParams.get('level') || null;
|
|
125
|
+
this._handleConnection(ws, request, levelFilter, result.ctx);
|
|
126
|
+
});
|
|
127
|
+
}, () => (0, ws_upgrade_auth_1.rejectUpgrade)(socket, 401));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Broadcast a log message to all connected clients whose filter allows it.
|
|
132
|
+
*/
|
|
133
|
+
broadcastLog(level, message, category) {
|
|
134
|
+
if (this._clients.size === 0)
|
|
135
|
+
return;
|
|
136
|
+
let formatted = null;
|
|
137
|
+
for (const entry of this._clients.values()) {
|
|
138
|
+
if (entry.ws.readyState !== ws_1.WebSocket.OPEN)
|
|
139
|
+
continue;
|
|
140
|
+
if (!CliLogSocketManager.shouldSendLog(entry.levelFilter, level))
|
|
141
|
+
continue;
|
|
142
|
+
// Lazy-format only when there's at least one recipient
|
|
143
|
+
if (!formatted) {
|
|
144
|
+
formatted = CliLogSocketManager.formatLogMessage(level, message, category);
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
entry.ws.send(formatted);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// ignore send errors; cleanup happens on close/error events
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Send a disconnect message to all clients and close connections.
|
|
156
|
+
*/
|
|
157
|
+
async broadcastDisconnect() {
|
|
158
|
+
logger.info('Broadcasting disconnect to %d log clients', this._clients.size);
|
|
159
|
+
const disconnectMsg = JSON.stringify({ type: 'disconnect' });
|
|
160
|
+
const promises = [];
|
|
161
|
+
for (const entry of this._clients.values()) {
|
|
162
|
+
if (entry.ws.readyState === ws_1.WebSocket.OPEN) {
|
|
163
|
+
promises.push(new Promise((resolve) => {
|
|
164
|
+
entry.ws.send(disconnectMsg, () => {
|
|
165
|
+
entry.ws.close(1000, 'Server shutting down');
|
|
166
|
+
resolve();
|
|
167
|
+
});
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
await Promise.all(promises);
|
|
172
|
+
this._sessionBound.dispose();
|
|
173
|
+
this._clients.clear();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Return information about all currently connected log clients.
|
|
177
|
+
*/
|
|
178
|
+
getClients() {
|
|
179
|
+
const result = [];
|
|
180
|
+
for (const entry of this._clients.values()) {
|
|
181
|
+
if (entry.ws.readyState === ws_1.WebSocket.OPEN) {
|
|
182
|
+
result.push({
|
|
183
|
+
id: entry.id,
|
|
184
|
+
connectedAt: entry.connectedAt.toISOString(),
|
|
185
|
+
remoteAddress: entry.remoteAddress,
|
|
186
|
+
levelFilter: entry.levelFilter,
|
|
187
|
+
type: 'logs',
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
/** Terminates all connections and closes the WebSocket server. */
|
|
194
|
+
dispose() {
|
|
195
|
+
this._sessionBound.dispose();
|
|
196
|
+
for (const entry of this._clients.values()) {
|
|
197
|
+
entry.ws.terminate();
|
|
198
|
+
}
|
|
199
|
+
this._clients.clear();
|
|
200
|
+
this._wss?.close();
|
|
201
|
+
}
|
|
202
|
+
_handleConnection(ws, request, levelFilter, auth) {
|
|
203
|
+
const id = `log-${this._nextClientId++}`;
|
|
204
|
+
const entry = {
|
|
205
|
+
id,
|
|
206
|
+
ws,
|
|
207
|
+
connectedAt: new Date(),
|
|
208
|
+
remoteAddress: request.socket.remoteAddress ?? 'unknown',
|
|
209
|
+
levelFilter,
|
|
210
|
+
};
|
|
211
|
+
this._clients.set(id, entry);
|
|
212
|
+
this._sessionBound.bind(ws, auth);
|
|
213
|
+
ws.send(JSON.stringify({ type: 'connected' }));
|
|
214
|
+
logger.info('Log client connected (id=%s, level=%s)', id, levelFilter ?? 'all');
|
|
215
|
+
const disconnected = () => {
|
|
216
|
+
logger.info('Log client disconnected (id=%s)', id);
|
|
217
|
+
this._sessionBound.unbind(ws);
|
|
218
|
+
this._clients.delete(id);
|
|
219
|
+
};
|
|
220
|
+
ws.on('close', disconnected);
|
|
221
|
+
ws.on('error', disconnected);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.CliLogSocketManager = CliLogSocketManager;
|
|
225
|
+
//# sourceMappingURL=cli-log-socket-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-log-socket-manager.js","sourceRoot":"","sources":["../../../src/services/cli-log-socket-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { CliServerResponse } from '../models';
|
|
2
|
+
/** Fluent interface for building a structured CLI server response with typed output blocks. */
|
|
2
3
|
export interface ICliResponseBuilder {
|
|
4
|
+
/** Appends a text output block with an optional style. */
|
|
3
5
|
writeText(text: string, style?: 'success' | 'error' | 'info' | 'warning'): void;
|
|
6
|
+
/** Appends a table output block. */
|
|
4
7
|
writeTable(headers: string[], rows: string[][]): void;
|
|
8
|
+
/** Appends a list output block. */
|
|
5
9
|
writeList(items: string[], ordered?: boolean): void;
|
|
10
|
+
/** Appends a JSON output block. */
|
|
6
11
|
writeJson(value: any): void;
|
|
12
|
+
/** Appends a key-value pairs output block. */
|
|
7
13
|
writeKeyValue(entries: Record<string, string>): void;
|
|
14
|
+
/** Sets the exit code for the response. */
|
|
8
15
|
setExitCode(code: number): void;
|
|
16
|
+
/** Builds and returns the final structured response. */
|
|
9
17
|
build(): CliServerResponse;
|
|
10
18
|
}
|
|
19
|
+
/** Default implementation of {@link ICliResponseBuilder} that accumulates output blocks. */
|
|
11
20
|
export declare class CliResponseBuilder implements ICliResponseBuilder {
|
|
12
21
|
private _exitCode;
|
|
13
22
|
private _outputs;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-response-builder.d.ts","sourceRoot":"","sources":["../../../src/services/cli-response-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,+FAA+F;AAC/F,MAAM,WAAW,mBAAmB;IAChC,0DAA0D;IAC1D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAChF,oCAAoC;IACpC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC;IACtD,mCAAmC;IACnC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,mCAAmC;IACnC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAC5B,8CAA8C;IAC9C,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACrD,2CAA2C;IAC3C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wDAAwD;IACxD,KAAK,IAAI,iBAAiB,CAAC;CAC9B;AAED,4FAA4F;AAC5F,qBAAa,kBAAmB,YAAW,mBAAmB;IAC1D,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAyB;IAEzC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAI/E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAIrD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,UAAQ,GAAG,IAAI;IAIjD,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAI3B,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOpD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,KAAK,IAAI,iBAAiB;CAM7B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CliResponseBuilder = void 0;
|
|
4
|
+
/** Default implementation of {@link ICliResponseBuilder} that accumulates output blocks. */
|
|
4
5
|
class CliResponseBuilder {
|
|
5
6
|
_exitCode = 0;
|
|
6
7
|
_outputs = [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-response-builder.js","sourceRoot":"","sources":["../../../src/services/cli-response-builder.ts"],"names":[],"mappings":";;;AAqBA,4FAA4F;AAC5F,MAAa,kBAAkB;IACnB,SAAS,GAAG,CAAC,CAAC;IACd,QAAQ,GAAsB,EAAE,CAAC;IAEzC,SAAS,CAAC,IAAY,EAAE,KAAgD;QACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,UAAU,CAAC,OAAiB,EAAE,IAAgB;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,SAAS,CAAC,KAAe,EAAE,OAAO,GAAG,KAAK;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,SAAS,CAAC,KAAU;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,aAAa,CAAC,OAA+B;QACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;SAC3E,CAAC,CAAC;IACP,CAAC;IAED,WAAW,CAAC,IAAY;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK;QACD,OAAO;YACH,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,OAAO,EAAE,IAAI,CAAC,QAAQ;SACzB,CAAC;IACN,CAAC;CACJ;AArCD,gDAqCC"}
|