@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,38 @@
|
|
|
1
|
+
/** Delay between SIGHUP/SIGTERM and the final SIGKILL. */
|
|
2
|
+
export declare const PROCESS_TREE_KILL_GRACE_MS = 1000;
|
|
3
|
+
/**
|
|
4
|
+
* Environment variable that tags every process a shell starts. Children inherit
|
|
5
|
+
* it, so processes that escaped the tree (re-parented to init, new session) are
|
|
6
|
+
* still found on cleanup unless they deliberately unset it.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SHELL_ID_ENV = "QCLI_SHELL_ID";
|
|
9
|
+
/** A fresh, unguessable shell marker value (128-bit hex). */
|
|
10
|
+
export declare function newShellId(): string;
|
|
11
|
+
/** Linux: does a NUL-separated `/proc/<pid>/environ` contain exactly `QCLI_SHELL_ID=<id>`? */
|
|
12
|
+
export declare function environHasShellId(environ: string, shellId: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* macOS / BSD: does a `ps -E -o command=` line (command line followed by the
|
|
15
|
+
* environment, space separated) contain `QCLI_SHELL_ID=<id>` as a whole token?
|
|
16
|
+
*/
|
|
17
|
+
export declare function psLineHasShellId(line: string, shellId: string): boolean;
|
|
18
|
+
/** PIDs of every process whose environment carries `QCLI_SHELL_ID=<shellId>`. */
|
|
19
|
+
export declare function findMarkedProcesses(shellId: string): number[];
|
|
20
|
+
/**
|
|
21
|
+
* PIDs of everything a shell started: its process group, (Linux) its session,
|
|
22
|
+
* every descendant of those — including background jobs that interactive
|
|
23
|
+
* shells move to their own process groups and `setsid`/`nohup` children — and,
|
|
24
|
+
* when `shellId` is given, every process carrying the shell's
|
|
25
|
+
* `QCLI_SHELL_ID` marker (and their descendants), which also catches processes
|
|
26
|
+
* re-parented to init in a new session. Never includes `rootPid` itself, the
|
|
27
|
+
* server process or the server's process group.
|
|
28
|
+
*/
|
|
29
|
+
export declare function collectProcessTree(rootPid: number, shellId?: string, extraSeeds?: number[]): number[];
|
|
30
|
+
/**
|
|
31
|
+
* Terminates a shell and everything it started (Unix): collects the targets
|
|
32
|
+
* first (the shell's death re-parents its children), then sends SIGHUP and
|
|
33
|
+
* SIGTERM to the shell's process group, the shell and every collected process,
|
|
34
|
+
* and SIGKILL after `graceMs`. The final pass re-collects so that children
|
|
35
|
+
* forked meanwhile by the collected processes die too.
|
|
36
|
+
*/
|
|
37
|
+
export declare function terminateProcessTree(rootPid: number, graceMs?: number, shellId?: string): void;
|
|
38
|
+
//# sourceMappingURL=process-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../../src/services/process-tree.ts"],"names":[],"mappings":"AAaA,0DAA0D;AAC1D,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAID,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAG3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAUvE;AA+BD,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO7D;AA4ED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAMzG;AAUD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,SAA6B,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAYlH"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SHELL_ID_ENV = exports.PROCESS_TREE_KILL_GRACE_MS = void 0;
|
|
37
|
+
exports.newShellId = newShellId;
|
|
38
|
+
exports.environHasShellId = environHasShellId;
|
|
39
|
+
exports.psLineHasShellId = psLineHasShellId;
|
|
40
|
+
exports.findMarkedProcesses = findMarkedProcesses;
|
|
41
|
+
exports.collectProcessTree = collectProcessTree;
|
|
42
|
+
exports.terminateProcessTree = terminateProcessTree;
|
|
43
|
+
const child_process_1 = require("child_process");
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
/** Delay between SIGHUP/SIGTERM and the final SIGKILL. */
|
|
48
|
+
exports.PROCESS_TREE_KILL_GRACE_MS = 1000;
|
|
49
|
+
/**
|
|
50
|
+
* Environment variable that tags every process a shell starts. Children inherit
|
|
51
|
+
* it, so processes that escaped the tree (re-parented to init, new session) are
|
|
52
|
+
* still found on cleanup unless they deliberately unset it.
|
|
53
|
+
*/
|
|
54
|
+
exports.SHELL_ID_ENV = 'QCLI_SHELL_ID';
|
|
55
|
+
/** A fresh, unguessable shell marker value (128-bit hex). */
|
|
56
|
+
function newShellId() {
|
|
57
|
+
return (0, crypto_1.randomBytes)(16).toString('hex');
|
|
58
|
+
}
|
|
59
|
+
const SHELL_ID_RE = /^[0-9a-f]{32}$/;
|
|
60
|
+
/** Linux: does a NUL-separated `/proc/<pid>/environ` contain exactly `QCLI_SHELL_ID=<id>`? */
|
|
61
|
+
function environHasShellId(environ, shellId) {
|
|
62
|
+
const wanted = `${exports.SHELL_ID_ENV}=${shellId}`;
|
|
63
|
+
return environ.split('\0').some((entry) => entry === wanted);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* macOS / BSD: does a `ps -E -o command=` line (command line followed by the
|
|
67
|
+
* environment, space separated) contain `QCLI_SHELL_ID=<id>` as a whole token?
|
|
68
|
+
*/
|
|
69
|
+
function psLineHasShellId(line, shellId) {
|
|
70
|
+
const wanted = ` ${exports.SHELL_ID_ENV}=${shellId}`;
|
|
71
|
+
let from = 0;
|
|
72
|
+
for (;;) {
|
|
73
|
+
const at = line.indexOf(wanted, from);
|
|
74
|
+
if (at < 0)
|
|
75
|
+
return false;
|
|
76
|
+
const end = at + wanted.length;
|
|
77
|
+
if (end === line.length || /\s/.test(line[end]))
|
|
78
|
+
return true;
|
|
79
|
+
from = at + 1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Linux: PIDs whose `/proc/<pid>/environ` carries the marker (unreadable entries are skipped). */
|
|
83
|
+
function markedFromProc(shellId) {
|
|
84
|
+
const found = [];
|
|
85
|
+
for (const name of fs.readdirSync('/proc')) {
|
|
86
|
+
if (!/^\d+$/.test(name))
|
|
87
|
+
continue;
|
|
88
|
+
try {
|
|
89
|
+
if (environHasShellId(fs.readFileSync(`/proc/${name}/environ`, 'latin1'), shellId))
|
|
90
|
+
found.push(Number(name));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// exited, or another user's process
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return found;
|
|
97
|
+
}
|
|
98
|
+
/** macOS / BSD: `ps -A -E -ww -o pid=,command=` shows the environment of the same user's processes. */
|
|
99
|
+
function markedFromPs(shellId) {
|
|
100
|
+
const out = (0, child_process_1.execFileSync)('ps', ['-A', '-E', '-ww', '-o', 'pid=,command='], {
|
|
101
|
+
encoding: 'utf8',
|
|
102
|
+
timeout: 5000,
|
|
103
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
104
|
+
});
|
|
105
|
+
const found = [];
|
|
106
|
+
for (const line of out.split('\n')) {
|
|
107
|
+
const m = /^\s*(\d+)\s/.exec(line);
|
|
108
|
+
if (m && psLineHasShellId(line, shellId))
|
|
109
|
+
found.push(Number(m[1]));
|
|
110
|
+
}
|
|
111
|
+
return found;
|
|
112
|
+
}
|
|
113
|
+
/** PIDs of every process whose environment carries `QCLI_SHELL_ID=<shellId>`. */
|
|
114
|
+
function findMarkedProcesses(shellId) {
|
|
115
|
+
if (!SHELL_ID_RE.test(shellId))
|
|
116
|
+
return [];
|
|
117
|
+
try {
|
|
118
|
+
return isProcLinux() ? markedFromProc(shellId) : markedFromPs(shellId);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function isProcLinux() {
|
|
125
|
+
return os.platform() === 'linux' && fs.existsSync('/proc/self/stat');
|
|
126
|
+
}
|
|
127
|
+
/** Linux: `/proc/<pid>/stat` (no `ps` needed, works in slim containers). */
|
|
128
|
+
function readProcTable() {
|
|
129
|
+
const entries = [];
|
|
130
|
+
for (const name of fs.readdirSync('/proc')) {
|
|
131
|
+
if (!/^\d+$/.test(name))
|
|
132
|
+
continue;
|
|
133
|
+
try {
|
|
134
|
+
const stat = fs.readFileSync(`/proc/${name}/stat`, 'utf8');
|
|
135
|
+
// "pid (comm) state ppid pgrp session ..." — comm may contain spaces and parentheses
|
|
136
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
|
|
137
|
+
entries.push({ pid: Number(name), ppid: Number(fields[1]), pgid: Number(fields[2]), sid: Number(fields[3]) });
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// exited while listing
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return entries;
|
|
144
|
+
}
|
|
145
|
+
/** macOS / BSD: `ps -A -o pid=,ppid=,pgid=`. */
|
|
146
|
+
function readPsTable() {
|
|
147
|
+
const out = (0, child_process_1.execFileSync)('ps', ['-A', '-o', 'pid=,ppid=,pgid='], { encoding: 'utf8', timeout: 5000 });
|
|
148
|
+
const entries = [];
|
|
149
|
+
for (const line of out.split('\n')) {
|
|
150
|
+
const m = /^\s*(\d+)\s+(\d+)\s+(\d+)\s*$/.exec(line);
|
|
151
|
+
if (m)
|
|
152
|
+
entries.push({ pid: Number(m[1]), ppid: Number(m[2]), pgid: Number(m[3]) });
|
|
153
|
+
}
|
|
154
|
+
return entries;
|
|
155
|
+
}
|
|
156
|
+
function readProcessTable() {
|
|
157
|
+
try {
|
|
158
|
+
return isProcLinux() ? readProcTable() : readPsTable();
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** `seeds` (except `rootPid`) and all their descendants, by parent PID. */
|
|
165
|
+
function descendants(table, rootPid, seeds) {
|
|
166
|
+
const children = new Map();
|
|
167
|
+
for (const p of table) {
|
|
168
|
+
const list = children.get(p.ppid);
|
|
169
|
+
if (list)
|
|
170
|
+
list.push(p.pid);
|
|
171
|
+
else
|
|
172
|
+
children.set(p.ppid, [p.pid]);
|
|
173
|
+
}
|
|
174
|
+
const found = new Set();
|
|
175
|
+
const queue = [...seeds];
|
|
176
|
+
while (queue.length) {
|
|
177
|
+
const pid = queue.pop();
|
|
178
|
+
if (pid !== rootPid) {
|
|
179
|
+
if (found.has(pid))
|
|
180
|
+
continue;
|
|
181
|
+
found.add(pid);
|
|
182
|
+
}
|
|
183
|
+
for (const child of children.get(pid) ?? []) {
|
|
184
|
+
if (child !== rootPid && !found.has(child))
|
|
185
|
+
queue.push(child);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
found.delete(process.pid);
|
|
189
|
+
const ownPgid = table.find((p) => p.pid === process.pid)?.pgid;
|
|
190
|
+
if (ownPgid !== undefined)
|
|
191
|
+
for (const p of table)
|
|
192
|
+
if (p.pgid === ownPgid)
|
|
193
|
+
found.delete(p.pid);
|
|
194
|
+
return found;
|
|
195
|
+
}
|
|
196
|
+
function treeSeeds(table, rootPid) {
|
|
197
|
+
const seeds = [rootPid];
|
|
198
|
+
for (const p of table) {
|
|
199
|
+
if (p.pgid === rootPid || p.sid === rootPid)
|
|
200
|
+
seeds.push(p.pid);
|
|
201
|
+
}
|
|
202
|
+
return seeds;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* PIDs of everything a shell started: its process group, (Linux) its session,
|
|
206
|
+
* every descendant of those — including background jobs that interactive
|
|
207
|
+
* shells move to their own process groups and `setsid`/`nohup` children — and,
|
|
208
|
+
* when `shellId` is given, every process carrying the shell's
|
|
209
|
+
* `QCLI_SHELL_ID` marker (and their descendants), which also catches processes
|
|
210
|
+
* re-parented to init in a new session. Never includes `rootPid` itself, the
|
|
211
|
+
* server process or the server's process group.
|
|
212
|
+
*/
|
|
213
|
+
function collectProcessTree(rootPid, shellId, extraSeeds = []) {
|
|
214
|
+
const table = readProcessTable();
|
|
215
|
+
const marked = shellId ? findMarkedProcesses(shellId) : [];
|
|
216
|
+
const alive = new Set(table.map((p) => p.pid));
|
|
217
|
+
const seeds = [...treeSeeds(table, rootPid), ...marked, ...extraSeeds.filter((pid) => alive.has(pid))];
|
|
218
|
+
return [...descendants(table, rootPid, seeds)];
|
|
219
|
+
}
|
|
220
|
+
function signal(pid, sig) {
|
|
221
|
+
try {
|
|
222
|
+
process.kill(pid, sig);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// already gone
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Terminates a shell and everything it started (Unix): collects the targets
|
|
230
|
+
* first (the shell's death re-parents its children), then sends SIGHUP and
|
|
231
|
+
* SIGTERM to the shell's process group, the shell and every collected process,
|
|
232
|
+
* and SIGKILL after `graceMs`. The final pass re-collects so that children
|
|
233
|
+
* forked meanwhile by the collected processes die too.
|
|
234
|
+
*/
|
|
235
|
+
function terminateProcessTree(rootPid, graceMs = exports.PROCESS_TREE_KILL_GRACE_MS, shellId) {
|
|
236
|
+
const pids = collectProcessTree(rootPid, shellId);
|
|
237
|
+
const send = (targets, sig) => {
|
|
238
|
+
if (rootPid !== process.pid) {
|
|
239
|
+
signal(-rootPid, sig);
|
|
240
|
+
signal(rootPid, sig);
|
|
241
|
+
}
|
|
242
|
+
for (const pid of targets)
|
|
243
|
+
signal(pid, sig);
|
|
244
|
+
};
|
|
245
|
+
send(pids, 'SIGHUP');
|
|
246
|
+
send(pids, 'SIGTERM');
|
|
247
|
+
setTimeout(() => send(collectProcessTree(rootPid, shellId, pids), 'SIGKILL'), graceMs);
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=process-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../../src/services/process-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
import { CliServerAuthContext, ICliServerAuth } from '../auth/cli-server-auth';
|
|
3
|
+
/** Close code and reason of a socket whose session ended. */
|
|
4
|
+
export declare const SESSION_ENDED_CLOSE_CODE = 4401;
|
|
5
|
+
export declare const SESSION_ENDED_REASON = "session ended";
|
|
6
|
+
export interface SessionBoundSocketsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Sockets that receive `session-kicked` (the events socket): a revocation
|
|
9
|
+
* closes them only after that event was sent ({@link kicked}), or after a
|
|
10
|
+
* short grace period when it never comes.
|
|
11
|
+
*/
|
|
12
|
+
awaitKick?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Binds authenticated events/logs WebSockets to the stored session behind
|
|
16
|
+
* their ticket: when it ends (logout, revoke, user disabled/deleted, expiry)
|
|
17
|
+
* the socket is closed with 4401 `session ended`. The auth provider's session
|
|
18
|
+
* events drive it: `session-ended` closes the session's sockets, any other
|
|
19
|
+
* event (users/groups changes, the expiry sweep) re-checks every bound socket.
|
|
20
|
+
* Identities without a stored session (external adapter) are not bound.
|
|
21
|
+
*/
|
|
22
|
+
export declare class SessionBoundSockets {
|
|
23
|
+
private readonly _options;
|
|
24
|
+
private readonly _bound;
|
|
25
|
+
private _auth?;
|
|
26
|
+
private _unsubscribe?;
|
|
27
|
+
constructor(_options?: SessionBoundSocketsOptions);
|
|
28
|
+
/** Installs the auth provider and subscribes to its session events. */
|
|
29
|
+
setAuth(auth: ICliServerAuth | undefined): void;
|
|
30
|
+
/** Tracks `ws` when `ctx` comes from a stored session or an API token. */
|
|
31
|
+
bind(ws: WebSocket, ctx: CliServerAuthContext | undefined): void;
|
|
32
|
+
unbind(ws: WebSocket): void;
|
|
33
|
+
/** True once the socket's session ended (it must not receive server-wide events any more). */
|
|
34
|
+
isEnding(ws: WebSocket): boolean;
|
|
35
|
+
/** `session-kicked` was delivered to `ws` for its own session: close it now. */
|
|
36
|
+
kicked(ws: WebSocket): void;
|
|
37
|
+
/** Re-checks every bound socket (optionally only `userId`'s) and closes those whose session ended. */
|
|
38
|
+
recheck(userId?: string): Promise<void>;
|
|
39
|
+
dispose(): void;
|
|
40
|
+
private onSessionEvent;
|
|
41
|
+
/** The session behind `ws` ended; `mayBeKicked`: a `session-kicked` event may still follow. */
|
|
42
|
+
private ended;
|
|
43
|
+
private close;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=session-bound-sockets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bound-sockets.d.ts","sourceRoot":"","sources":["../../../src/services/session-bound-sockets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAyB,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAItG,6DAA6D;AAC7D,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAQpD,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AASD;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAKhB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAa;gBAEL,QAAQ,GAAE,0BAA+B;IAEtE,uEAAuE;IACvE,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI;IAS/C,0EAA0E;IAC1E,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,oBAAoB,GAAG,SAAS,GAAG,IAAI;IAIhE,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAM3B,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO;IAIhC,gFAAgF;IAChF,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAI3B,sGAAsG;IAChG,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7C,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,cAAc;IAUtB,+FAA+F;IAC/F,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,KAAK;CAUhB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionBoundSockets = exports.SESSION_ENDED_REASON = exports.SESSION_ENDED_CLOSE_CODE = void 0;
|
|
4
|
+
const ws_1 = require("ws");
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
const logger = (0, logger_1.createLogger)('SessionBoundSockets');
|
|
7
|
+
/** Close code and reason of a socket whose session ended. */
|
|
8
|
+
exports.SESSION_ENDED_CLOSE_CODE = 4401;
|
|
9
|
+
exports.SESSION_ENDED_REASON = 'session ended';
|
|
10
|
+
/**
|
|
11
|
+
* How long a socket waits for its `session-kicked` event once its session
|
|
12
|
+
* ended by a revocation (or a re-check found it dead) before it is closed anyway.
|
|
13
|
+
*/
|
|
14
|
+
const KICK_GRACE_MS = 1000;
|
|
15
|
+
/**
|
|
16
|
+
* Binds authenticated events/logs WebSockets to the stored session behind
|
|
17
|
+
* their ticket: when it ends (logout, revoke, user disabled/deleted, expiry)
|
|
18
|
+
* the socket is closed with 4401 `session ended`. The auth provider's session
|
|
19
|
+
* events drive it: `session-ended` closes the session's sockets, any other
|
|
20
|
+
* event (users/groups changes, the expiry sweep) re-checks every bound socket.
|
|
21
|
+
* Identities without a stored session (external adapter) are not bound.
|
|
22
|
+
*/
|
|
23
|
+
class SessionBoundSockets {
|
|
24
|
+
_options;
|
|
25
|
+
_bound = new Map();
|
|
26
|
+
_auth;
|
|
27
|
+
_unsubscribe;
|
|
28
|
+
constructor(_options = {}) {
|
|
29
|
+
this._options = _options;
|
|
30
|
+
}
|
|
31
|
+
/** Installs the auth provider and subscribes to its session events. */
|
|
32
|
+
setAuth(auth) {
|
|
33
|
+
this._unsubscribe?.();
|
|
34
|
+
this._unsubscribe = undefined;
|
|
35
|
+
this._auth = auth;
|
|
36
|
+
if (auth?.onSessionEvent) {
|
|
37
|
+
this._unsubscribe = auth.onSessionEvent((event) => this.onSessionEvent(event));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Tracks `ws` when `ctx` comes from a stored session or an API token. */
|
|
41
|
+
bind(ws, ctx) {
|
|
42
|
+
if (ctx?.sessionId || ctx?.tokenId)
|
|
43
|
+
this._bound.set(ws, { ctx });
|
|
44
|
+
}
|
|
45
|
+
unbind(ws) {
|
|
46
|
+
const entry = this._bound.get(ws);
|
|
47
|
+
if (entry?.ending)
|
|
48
|
+
clearTimeout(entry.ending);
|
|
49
|
+
this._bound.delete(ws);
|
|
50
|
+
}
|
|
51
|
+
/** True once the socket's session ended (it must not receive server-wide events any more). */
|
|
52
|
+
isEnding(ws) {
|
|
53
|
+
return !!this._bound.get(ws)?.ending;
|
|
54
|
+
}
|
|
55
|
+
/** `session-kicked` was delivered to `ws` for its own session: close it now. */
|
|
56
|
+
kicked(ws) {
|
|
57
|
+
this.close(ws);
|
|
58
|
+
}
|
|
59
|
+
/** Re-checks every bound socket (optionally only `userId`'s) and closes those whose session ended. */
|
|
60
|
+
async recheck(userId) {
|
|
61
|
+
const auth = this._auth;
|
|
62
|
+
if (!auth?.revalidate)
|
|
63
|
+
return;
|
|
64
|
+
const checks = [];
|
|
65
|
+
for (const [ws, entry] of this._bound) {
|
|
66
|
+
if (entry.ending || entry.checking || (userId && entry.ctx.userId !== userId))
|
|
67
|
+
continue;
|
|
68
|
+
entry.checking = true;
|
|
69
|
+
checks.push((async () => {
|
|
70
|
+
let alive;
|
|
71
|
+
try {
|
|
72
|
+
alive = !!(await auth.revalidate(entry.ctx));
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
logger.warn('Socket session check failed; closing the socket: %s', err?.message ?? err);
|
|
76
|
+
alive = false;
|
|
77
|
+
}
|
|
78
|
+
entry.checking = false;
|
|
79
|
+
if (!alive && this._bound.get(ws) === entry)
|
|
80
|
+
this.ended(ws, entry, true);
|
|
81
|
+
})());
|
|
82
|
+
}
|
|
83
|
+
await Promise.all(checks);
|
|
84
|
+
}
|
|
85
|
+
dispose() {
|
|
86
|
+
this._unsubscribe?.();
|
|
87
|
+
this._unsubscribe = undefined;
|
|
88
|
+
for (const entry of this._bound.values()) {
|
|
89
|
+
if (entry.ending)
|
|
90
|
+
clearTimeout(entry.ending);
|
|
91
|
+
}
|
|
92
|
+
this._bound.clear();
|
|
93
|
+
}
|
|
94
|
+
onSessionEvent(event) {
|
|
95
|
+
if (event.type === 'session-ended') {
|
|
96
|
+
for (const [ws, entry] of [...this._bound]) {
|
|
97
|
+
if (entry.ctx.sessionId === event.sessionId)
|
|
98
|
+
this.ended(ws, entry, !!event.revoked);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
void this.recheck(event.userId);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The session behind `ws` ended; `mayBeKicked`: a `session-kicked` event may still follow. */
|
|
106
|
+
ended(ws, entry, mayBeKicked) {
|
|
107
|
+
if (!this._options.awaitKick || !mayBeKicked) {
|
|
108
|
+
this.close(ws);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (entry.ending)
|
|
112
|
+
return;
|
|
113
|
+
entry.ending = setTimeout(() => this.close(ws), KICK_GRACE_MS);
|
|
114
|
+
entry.ending.unref?.();
|
|
115
|
+
}
|
|
116
|
+
close(ws) {
|
|
117
|
+
this.unbind(ws);
|
|
118
|
+
if (ws.readyState === ws_1.WebSocket.OPEN || ws.readyState === ws_1.WebSocket.CONNECTING) {
|
|
119
|
+
try {
|
|
120
|
+
ws.close(exports.SESSION_ENDED_CLOSE_CODE, exports.SESSION_ENDED_REASON);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
ws.terminate();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.SessionBoundSockets = SessionBoundSockets;
|
|
129
|
+
//# sourceMappingURL=session-bound-sockets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bound-sockets.js","sourceRoot":"","sources":["../../../src/services/session-bound-sockets.ts"],"names":[],"mappings":";;;AAAA,2BAA+B;AAC/B,4CAA+C;AAG/C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,qBAAqB,CAAC,CAAC;AAEnD,6DAA6D;AAChD,QAAA,wBAAwB,GAAG,IAAI,CAAC;AAChC,QAAA,oBAAoB,GAAG,eAAe,CAAC;AAEpD;;;GAGG;AACH,MAAM,aAAa,GAAG,IAAI,CAAC;AAkB3B;;;;;;;GAOG;AACH,MAAa,mBAAmB;IAKC;IAJZ,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,KAAK,CAAkB;IACvB,YAAY,CAAc;IAElC,YAA6B,WAAuC,EAAE;QAAzC,aAAQ,GAAR,QAAQ,CAAiC;IAAG,CAAC;IAE1E,uEAAuE;IACvE,OAAO,CAAC,IAAgC;QACpC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QACnF,CAAC;IACL,CAAC;IAED,0EAA0E;IAC1E,IAAI,CAAC,EAAa,EAAE,GAAqC;QACrD,IAAI,GAAG,EAAE,SAAS,IAAI,GAAG,EAAE,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,CAAC,EAAa;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,MAAM;YAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,8FAA8F;IAC9F,QAAQ,CAAC,EAAa;QAClB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACzC,CAAC;IAED,gFAAgF;IAChF,MAAM,CAAC,EAAa;QAChB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IAED,sGAAsG;IACtG,KAAK,CAAC,OAAO,CAAC,MAAe;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,UAAU;YAAE,OAAO;QAC9B,MAAM,MAAM,GAAoB,EAAE,CAAC;QACnC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;gBAAE,SAAS;YACxF,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;YACtB,MAAM,CAAC,IAAI,CACP,CAAC,KAAK,IAAI,EAAE;gBACR,IAAI,KAAc,CAAC;gBACnB,IAAI,CAAC;oBACD,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,UAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,qDAAqD,EAAG,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;oBACnG,KAAK,GAAG,KAAK,CAAC;gBAClB,CAAC;gBACD,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,KAAK;oBAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7E,CAAC,CAAC,EAAE,CACP,CAAC;QACN,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO;QACH,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM;gBAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAEO,cAAc,CAAC,KAA4B;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;oBAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;IAED,+FAA+F;IACvF,KAAK,CAAC,EAAa,EAAE,KAAY,EAAE,WAAoB;QAC3D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACX,CAAC;QACD,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO;QACzB,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;QAC/D,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,EAAa;QACvB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChB,IAAI,EAAE,CAAC,UAAU,KAAK,cAAS,CAAC,IAAI,IAAI,EAAE,CAAC,UAAU,KAAK,cAAS,CAAC,UAAU,EAAE,CAAC;YAC7E,IAAI,CAAC;gBACD,EAAE,CAAC,KAAK,CAAC,gCAAwB,EAAE,4BAAoB,CAAC,CAAC;YAC7D,CAAC;YAAC,MAAM,CAAC;gBACL,EAAE,CAAC,SAAS,EAAE,CAAC;YACnB,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AAvGD,kDAuGC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple structured logger with category prefixes.
|
|
3
|
+
*/
|
|
4
|
+
export interface Logger {
|
|
5
|
+
debug(message: string, ...args: unknown[]): void;
|
|
6
|
+
info(message: string, ...args: unknown[]): void;
|
|
7
|
+
warn(message: string, ...args: unknown[]): void;
|
|
8
|
+
error(message: string, ...args: unknown[]): void;
|
|
9
|
+
}
|
|
10
|
+
export declare function createLogger(category: string): Logger;
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQrD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLogger = createLogger;
|
|
4
|
+
function createLogger(category) {
|
|
5
|
+
const prefix = `[${category}]`;
|
|
6
|
+
return {
|
|
7
|
+
debug: (msg, ...args) => console.debug(`${prefix} ${msg}`, ...args),
|
|
8
|
+
info: (msg, ...args) => console.log(`${prefix} ${msg}`, ...args),
|
|
9
|
+
warn: (msg, ...args) => console.warn(`${prefix} ${msg}`, ...args),
|
|
10
|
+
error: (msg, ...args) => console.error(`${prefix} ${msg}`, ...args),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":";;AAUA,oCAQC;AARD,SAAgB,YAAY,CAAC,QAAgB;IACzC,MAAM,MAAM,GAAG,IAAI,QAAQ,GAAG,CAAC;IAC/B,OAAO;QACH,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;QACnE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;QAChE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;QACjE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;KACtE,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qodalis/cli-server-node",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.10",
|
|
4
4
|
"description": "Node.js CLI server for Qodalis CLI ecosystem — use as a library in existing Express apps or run standalone",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
-
"qodalis-cli-server": "dist/server.js"
|
|
8
|
+
"qodalis-cli-server": "dist/src/server.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"!dist/src/__tests__",
|
|
13
|
+
"!dist/plugins",
|
|
12
14
|
"LICENSE",
|
|
13
15
|
"README.md"
|
|
14
16
|
],
|
|
15
17
|
"scripts": {
|
|
16
18
|
"build": "tsc",
|
|
17
19
|
"start": "tsx src/server.ts",
|
|
18
|
-
"dev": "tsx watch src/server.ts"
|
|
20
|
+
"dev": "tsx watch src/server.ts",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest"
|
|
19
23
|
},
|
|
20
24
|
"keywords": [
|
|
21
25
|
"cli",
|
|
@@ -33,16 +37,41 @@
|
|
|
33
37
|
},
|
|
34
38
|
"homepage": "https://qodalis.com/",
|
|
35
39
|
"dependencies": {
|
|
40
|
+
"@qodalis/cli-server-abstractions": "^1.0.0-beta.8",
|
|
41
|
+
"@qodalis/cli-server-plugin-data-explorer": "^1.0.0-beta.6",
|
|
42
|
+
"@qodalis/cli-server-plugin-filesystem": "^1.0.0-beta.7",
|
|
43
|
+
"@qodalis/cli-server-plugin-jobs": "^1.0.0-beta.6",
|
|
36
44
|
"cors": "^2.8.5",
|
|
37
|
-
"express": "^4.
|
|
38
|
-
"
|
|
45
|
+
"express": "^4.22.3",
|
|
46
|
+
"multer": "^2.5.0",
|
|
47
|
+
"node-pty": "^1.1.0",
|
|
48
|
+
"ws": "^8.22.0"
|
|
49
|
+
},
|
|
50
|
+
"optionalDependencies": {
|
|
51
|
+
"@elastic/elasticsearch": "^8.16.0",
|
|
52
|
+
"@qodalis/cli-server-plugin-filesystem-json": "^1.0.0-beta.6",
|
|
53
|
+
"@qodalis/cli-server-plugin-filesystem-s3": "^1.0.0-beta.6",
|
|
54
|
+
"@qodalis/cli-server-plugin-filesystem-sqlite": "^1.0.0-beta.7",
|
|
55
|
+
"better-sqlite3": "^13.0.3",
|
|
56
|
+
"ioredis": "^5.4.0",
|
|
57
|
+
"mongodb": "^6.0.0",
|
|
58
|
+
"mssql": "^11.0.0",
|
|
59
|
+
"mysql2": "^3.24.6",
|
|
60
|
+
"pg": "^8.13.0"
|
|
39
61
|
},
|
|
40
62
|
"devDependencies": {
|
|
63
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
41
64
|
"@types/cors": "^2.8.17",
|
|
42
65
|
"@types/express": "^4.17.21",
|
|
66
|
+
"@types/mssql": "^9.1.9",
|
|
67
|
+
"@types/multer": "^2.0.0",
|
|
43
68
|
"@types/node": "^22.0.0",
|
|
69
|
+
"@types/pg": "^8.0.0",
|
|
70
|
+
"@types/supertest": "^7.2.0",
|
|
44
71
|
"@types/ws": "^8.5.13",
|
|
72
|
+
"supertest": "^7.2.2",
|
|
45
73
|
"tsx": "^4.19.0",
|
|
46
|
-
"typescript": "^5.6.0"
|
|
74
|
+
"typescript": "^5.6.0",
|
|
75
|
+
"vitest": "^4.1.12"
|
|
47
76
|
}
|
|
48
77
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface ICliCommandAuthor {
|
|
2
|
-
name: string;
|
|
3
|
-
email: string;
|
|
4
|
-
}
|
|
5
|
-
export declare class CliCommandAuthor implements ICliCommandAuthor {
|
|
6
|
-
name: string;
|
|
7
|
-
email: string;
|
|
8
|
-
constructor(name: string, email: string);
|
|
9
|
-
}
|
|
10
|
-
export declare const DefaultLibraryAuthor: ICliCommandAuthor;
|
|
11
|
-
//# sourceMappingURL=cli-command-author.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-command-author.d.ts","sourceRoot":"","sources":["../../src/abstractions/cli-command-author.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,gBAAiB,YAAW,iBAAiB;IAE3C,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;gBADb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM;CAE3B;AAED,eAAO,MAAM,oBAAoB,EAAE,iBAGlC,CAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DefaultLibraryAuthor = exports.CliCommandAuthor = void 0;
|
|
4
|
-
class CliCommandAuthor {
|
|
5
|
-
name;
|
|
6
|
-
email;
|
|
7
|
-
constructor(name, email) {
|
|
8
|
-
this.name = name;
|
|
9
|
-
this.email = email;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.CliCommandAuthor = CliCommandAuthor;
|
|
13
|
-
exports.DefaultLibraryAuthor = new CliCommandAuthor('Nicolae Lupei', 'nicolae.lupei@qodalis.com');
|
|
14
|
-
//# sourceMappingURL=cli-command-author.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-command-author.js","sourceRoot":"","sources":["../../src/abstractions/cli-command-author.ts"],"names":[],"mappings":";;;AAKA,MAAa,gBAAgB;IAEd;IACA;IAFX,YACW,IAAY,EACZ,KAAa;QADb,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;IACrB,CAAC;CACP;AALD,4CAKC;AAEY,QAAA,oBAAoB,GAAsB,IAAI,gBAAgB,CACvE,eAAe,EACf,2BAA2B,CAC9B,CAAC"}
|