recker 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -97
- package/dist/ai/providers/anthropic.d.ts.map +1 -1
- package/dist/ai/providers/anthropic.js +4 -1
- package/dist/ai/providers/base.d.ts.map +1 -1
- package/dist/ai/providers/base.js +7 -2
- package/dist/ai/rate-limiter.d.ts.map +1 -1
- package/dist/ai/rate-limiter.js +4 -1
- package/dist/bench/generator.d.ts.map +1 -1
- package/dist/bench/generator.js +8 -3
- package/dist/bench/stats.d.ts +15 -1
- package/dist/bench/stats.d.ts.map +1 -1
- package/dist/bench/stats.js +117 -5
- package/dist/cache/memory-storage.d.ts.map +1 -1
- package/dist/cache/memory-storage.js +3 -2
- package/dist/cli/handler.js +14 -14
- package/dist/cli/index.js +602 -48
- package/dist/cli/presets.js +5 -5
- package/dist/cli/tui/ai-chat.js +10 -10
- package/dist/cli/tui/load-dashboard.d.ts.map +1 -1
- package/dist/cli/tui/load-dashboard.js +127 -32
- package/dist/cli/tui/scroll-buffer.d.ts +43 -0
- package/dist/cli/tui/scroll-buffer.d.ts.map +1 -0
- package/dist/cli/tui/scroll-buffer.js +162 -0
- package/dist/cli/tui/search-panel.d.ts +41 -0
- package/dist/cli/tui/search-panel.d.ts.map +1 -0
- package/dist/cli/tui/search-panel.js +419 -0
- package/dist/cli/tui/shell.d.ts +14 -0
- package/dist/cli/tui/shell.d.ts.map +1 -1
- package/dist/cli/tui/shell.js +424 -46
- package/dist/cli/tui/websocket.js +17 -17
- package/dist/contract/index.js +3 -2
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +18 -26
- package/dist/core/errors.d.ts +109 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +214 -1
- package/dist/core/request-promise.d.ts.map +1 -1
- package/dist/core/request-promise.js +5 -6
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +5 -6
- package/dist/dns/index.d.ts +1 -0
- package/dist/dns/index.d.ts.map +1 -1
- package/dist/dns/index.js +1 -0
- package/dist/dns/propagation.d.ts +21 -0
- package/dist/dns/propagation.d.ts.map +1 -0
- package/dist/dns/propagation.js +169 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +10 -11
- package/dist/mcp/embeddings-loader.d.ts +18 -0
- package/dist/mcp/embeddings-loader.d.ts.map +1 -0
- package/dist/mcp/embeddings-loader.js +162 -0
- package/dist/mcp/geoip-loader.d.ts +11 -0
- package/dist/mcp/geoip-loader.d.ts.map +1 -0
- package/dist/mcp/geoip-loader.js +107 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/ip-intel.d.ts +28 -0
- package/dist/mcp/ip-intel.d.ts.map +1 -0
- package/dist/mcp/ip-intel.js +209 -0
- package/dist/mcp/search/hybrid-search.d.ts.map +1 -1
- package/dist/mcp/search/hybrid-search.js +12 -22
- package/dist/mcp/search/math.d.ts.map +1 -1
- package/dist/mcp/search/math.js +5 -1
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +122 -2
- package/dist/plugins/compression.js +4 -2
- package/dist/plugins/har-player.d.ts.map +1 -1
- package/dist/plugins/har-player.js +8 -11
- package/dist/plugins/odata.d.ts.map +1 -1
- package/dist/plugins/odata.js +5 -2
- package/dist/protocols/ftp.d.ts.map +1 -1
- package/dist/protocols/ftp.js +69 -16
- package/dist/protocols/sftp.d.ts.map +1 -1
- package/dist/protocols/sftp.js +13 -3
- package/dist/protocols/telnet.d.ts.map +1 -1
- package/dist/protocols/telnet.js +25 -6
- package/dist/recker.d.ts +47 -0
- package/dist/recker.d.ts.map +1 -0
- package/dist/recker.js +99 -0
- package/dist/transport/base-udp.d.ts.map +1 -1
- package/dist/transport/base-udp.js +7 -4
- package/dist/transport/udp-response.d.ts.map +1 -1
- package/dist/transport/udp-response.js +10 -3
- package/dist/transport/udp.d.ts.map +1 -1
- package/dist/transport/udp.js +5 -1
- package/dist/transport/undici.d.ts.map +1 -1
- package/dist/transport/undici.js +75 -63
- package/dist/utils/agent-manager.d.ts +1 -0
- package/dist/utils/agent-manager.d.ts.map +1 -1
- package/dist/utils/agent-manager.js +11 -0
- package/dist/utils/client-pool.d.ts.map +1 -1
- package/dist/utils/client-pool.js +4 -1
- package/dist/utils/colors.d.ts +16 -0
- package/dist/utils/colors.d.ts.map +1 -1
- package/dist/utils/colors.js +16 -0
- package/dist/utils/dns-toolkit.d.ts +88 -1
- package/dist/utils/dns-toolkit.d.ts.map +1 -1
- package/dist/utils/dns-toolkit.js +704 -6
- package/dist/utils/doh.d.ts.map +1 -1
- package/dist/utils/doh.js +13 -16
- package/dist/utils/download.d.ts.map +1 -1
- package/dist/utils/download.js +10 -11
- package/dist/utils/rdap.d.ts +9 -0
- package/dist/utils/rdap.d.ts.map +1 -1
- package/dist/utils/rdap.js +78 -9
- package/dist/utils/security-grader.d.ts +47 -0
- package/dist/utils/security-grader.d.ts.map +1 -0
- package/dist/utils/security-grader.js +637 -0
- package/dist/utils/sparkline.d.ts +18 -0
- package/dist/utils/sparkline.d.ts.map +1 -0
- package/dist/utils/sparkline.js +55 -0
- package/dist/utils/sse.d.ts.map +1 -1
- package/dist/utils/sse.js +5 -6
- package/dist/utils/system-metrics.d.ts +26 -0
- package/dist/utils/system-metrics.d.ts.map +1 -0
- package/dist/utils/system-metrics.js +81 -0
- package/dist/utils/tls-inspector.d.ts +6 -0
- package/dist/utils/tls-inspector.d.ts.map +1 -1
- package/dist/utils/tls-inspector.js +35 -1
- package/dist/webrtc/index.d.ts.map +1 -1
- package/dist/webrtc/index.js +21 -7
- package/dist/websocket/client.d.ts.map +1 -1
- package/dist/websocket/client.js +13 -16
- package/package.json +4 -3
- package/dist/mcp/data/embeddings.json +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const SPARK_CHARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
2
|
+
const EMPTY_CHAR = '·';
|
|
3
|
+
export function sparkline(data, options = {}) {
|
|
4
|
+
const { width = 30, min: fixedMin, max: fixedMax } = options;
|
|
5
|
+
if (width === 0)
|
|
6
|
+
return '';
|
|
7
|
+
if (data.length === 0)
|
|
8
|
+
return EMPTY_CHAR.repeat(width);
|
|
9
|
+
const start = Math.max(0, data.length - width);
|
|
10
|
+
const slice = data.slice(start);
|
|
11
|
+
const min = fixedMin ?? Math.min(...slice, 0);
|
|
12
|
+
const max = fixedMax ?? Math.max(...slice, 0);
|
|
13
|
+
const range = Math.max(max - min, Number.EPSILON);
|
|
14
|
+
let result = '';
|
|
15
|
+
const padding = Math.max(0, width - slice.length);
|
|
16
|
+
if (padding > 0) {
|
|
17
|
+
result += EMPTY_CHAR.repeat(padding);
|
|
18
|
+
}
|
|
19
|
+
for (const value of slice) {
|
|
20
|
+
const normalized = Math.max(0, Math.min(1, (value - min) / range));
|
|
21
|
+
const idx = Math.round(normalized * (SPARK_CHARS.length - 1));
|
|
22
|
+
result += SPARK_CHARS[Math.min(idx, SPARK_CHARS.length - 1)];
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
export class SparklineBuffer {
|
|
27
|
+
data = [];
|
|
28
|
+
capacity;
|
|
29
|
+
constructor(capacity = 60) {
|
|
30
|
+
this.capacity = capacity;
|
|
31
|
+
}
|
|
32
|
+
push(value) {
|
|
33
|
+
if (this.data.length >= this.capacity) {
|
|
34
|
+
this.data.shift();
|
|
35
|
+
}
|
|
36
|
+
this.data.push(value);
|
|
37
|
+
}
|
|
38
|
+
getData() {
|
|
39
|
+
return this.data;
|
|
40
|
+
}
|
|
41
|
+
render(options = {}) {
|
|
42
|
+
return sparkline(this.data, { width: this.capacity, ...options });
|
|
43
|
+
}
|
|
44
|
+
clear() {
|
|
45
|
+
this.data = [];
|
|
46
|
+
}
|
|
47
|
+
latest() {
|
|
48
|
+
return this.data[this.data.length - 1];
|
|
49
|
+
}
|
|
50
|
+
average() {
|
|
51
|
+
if (this.data.length === 0)
|
|
52
|
+
return 0;
|
|
53
|
+
return this.data.reduce((a, b) => a + b, 0) / this.data.length;
|
|
54
|
+
}
|
|
55
|
+
}
|
package/dist/utils/sse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/utils/sse.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAuB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/utils/sse.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAuB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAoF5E"}
|
package/dist/utils/sse.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StreamError } from '../core/errors.js';
|
|
2
2
|
export async function* parseSSE(response) {
|
|
3
3
|
if (!response.body) {
|
|
4
|
-
throw new
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
]);
|
|
4
|
+
throw new StreamError('Response body is empty; cannot parse SSE stream.', {
|
|
5
|
+
streamType: 'sse',
|
|
6
|
+
retriable: true,
|
|
7
|
+
});
|
|
9
8
|
}
|
|
10
9
|
const reader = response.body.getReader();
|
|
11
10
|
const decoder = new TextDecoder();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface SystemSnapshot {
|
|
2
|
+
cpu: number;
|
|
3
|
+
memory: number;
|
|
4
|
+
memoryUsed: number;
|
|
5
|
+
memoryTotal: number;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class SystemMetrics {
|
|
9
|
+
private previousCpuTimes;
|
|
10
|
+
private intervalId;
|
|
11
|
+
private listeners;
|
|
12
|
+
getMemory(): {
|
|
13
|
+
used: number;
|
|
14
|
+
total: number;
|
|
15
|
+
percent: number;
|
|
16
|
+
};
|
|
17
|
+
private getCpuTimes;
|
|
18
|
+
getCpuUsage(): number;
|
|
19
|
+
getSnapshot(): SystemSnapshot;
|
|
20
|
+
startPolling(intervalMs?: number): void;
|
|
21
|
+
stopPolling(): void;
|
|
22
|
+
onSnapshot(callback: (snapshot: SystemSnapshot) => void): () => void;
|
|
23
|
+
static formatBytes(bytes: number): string;
|
|
24
|
+
static formatMemory(used: number, total: number): string;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=system-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-metrics.d.ts","sourceRoot":"","sources":["../../src/utils/system-metrics.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,MAAM,CAAC;IAEf,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,aAAa;IACxB,OAAO,CAAC,gBAAgB,CAAgD;IACxE,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAsD;IAKvE,SAAS,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAY7D,OAAO,CAAC,WAAW;IAgBnB,WAAW,IAAI,MAAM;IAsBrB,WAAW,IAAI,cAAc;IAgB7B,YAAY,CAAC,UAAU,GAAE,MAAa,GAAG,IAAI;IAiB7C,WAAW,IAAI,IAAI;IAUnB,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAQpE,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUzC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;CAGzD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
export class SystemMetrics {
|
|
3
|
+
previousCpuTimes = null;
|
|
4
|
+
intervalId = null;
|
|
5
|
+
listeners = new Set();
|
|
6
|
+
getMemory() {
|
|
7
|
+
const total = os.totalmem();
|
|
8
|
+
const free = os.freemem();
|
|
9
|
+
const used = total - free;
|
|
10
|
+
const percent = (used / total) * 100;
|
|
11
|
+
return { used, total, percent };
|
|
12
|
+
}
|
|
13
|
+
getCpuTimes() {
|
|
14
|
+
const cpus = os.cpus();
|
|
15
|
+
let idle = 0;
|
|
16
|
+
let total = 0;
|
|
17
|
+
for (const cpu of cpus) {
|
|
18
|
+
idle += cpu.times.idle;
|
|
19
|
+
total += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;
|
|
20
|
+
}
|
|
21
|
+
return { idle, total };
|
|
22
|
+
}
|
|
23
|
+
getCpuUsage() {
|
|
24
|
+
const current = this.getCpuTimes();
|
|
25
|
+
if (!this.previousCpuTimes) {
|
|
26
|
+
this.previousCpuTimes = current;
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
const idleDelta = current.idle - this.previousCpuTimes.idle;
|
|
30
|
+
const totalDelta = current.total - this.previousCpuTimes.total;
|
|
31
|
+
this.previousCpuTimes = current;
|
|
32
|
+
if (totalDelta === 0)
|
|
33
|
+
return 0;
|
|
34
|
+
const usage = 100 - (idleDelta / totalDelta) * 100;
|
|
35
|
+
return Math.max(0, Math.min(100, usage));
|
|
36
|
+
}
|
|
37
|
+
getSnapshot() {
|
|
38
|
+
const memory = this.getMemory();
|
|
39
|
+
const cpu = this.getCpuUsage();
|
|
40
|
+
return {
|
|
41
|
+
cpu,
|
|
42
|
+
memory: memory.percent,
|
|
43
|
+
memoryUsed: memory.used,
|
|
44
|
+
memoryTotal: memory.total,
|
|
45
|
+
timestamp: Date.now()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
startPolling(intervalMs = 1000) {
|
|
49
|
+
if (this.intervalId)
|
|
50
|
+
return;
|
|
51
|
+
this.previousCpuTimes = this.getCpuTimes();
|
|
52
|
+
this.intervalId = setInterval(() => {
|
|
53
|
+
const snapshot = this.getSnapshot();
|
|
54
|
+
for (const listener of this.listeners) {
|
|
55
|
+
listener(snapshot);
|
|
56
|
+
}
|
|
57
|
+
}, intervalMs);
|
|
58
|
+
}
|
|
59
|
+
stopPolling() {
|
|
60
|
+
if (this.intervalId) {
|
|
61
|
+
clearInterval(this.intervalId);
|
|
62
|
+
this.intervalId = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
onSnapshot(callback) {
|
|
66
|
+
this.listeners.add(callback);
|
|
67
|
+
return () => this.listeners.delete(callback);
|
|
68
|
+
}
|
|
69
|
+
static formatBytes(bytes) {
|
|
70
|
+
if (bytes < 1024)
|
|
71
|
+
return `${bytes}B`;
|
|
72
|
+
if (bytes < 1024 * 1024)
|
|
73
|
+
return `${(bytes / 1024).toFixed(1)}K`;
|
|
74
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
75
|
+
return `${(bytes / 1024 / 1024).toFixed(1)}M`;
|
|
76
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)}G`;
|
|
77
|
+
}
|
|
78
|
+
static formatMemory(used, total) {
|
|
79
|
+
return `${this.formatBytes(used)}/${this.formatBytes(total)}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -16,6 +16,12 @@ export interface TLSInfo {
|
|
|
16
16
|
} | null;
|
|
17
17
|
authorized: boolean;
|
|
18
18
|
authorizationError?: Error;
|
|
19
|
+
altNames?: string[];
|
|
20
|
+
pubkey: {
|
|
21
|
+
algo: string;
|
|
22
|
+
size: number;
|
|
23
|
+
} | null;
|
|
24
|
+
extKeyUsage?: string[];
|
|
19
25
|
}
|
|
20
26
|
export declare function inspectTLS(host: string, port?: number, options?: ConnectionOptions): Promise<TLSInfo>;
|
|
21
27
|
//# sourceMappingURL=tls-inspector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tls-inspector.d.ts","sourceRoot":"","sources":["../../src/utils/tls-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tls-inspector.d.ts","sourceRoot":"","sources":["../../src/utils/tls-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGjE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAE3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAY,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkF9G"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { connect } from 'node:tls';
|
|
2
|
+
import * as crypto from 'node:crypto';
|
|
2
3
|
export function inspectTLS(host, port = 443, options = {}) {
|
|
3
4
|
return new Promise((resolve, reject) => {
|
|
4
5
|
const socket = connect(port, host, { ...options, servername: host }, () => {
|
|
@@ -11,6 +12,36 @@ export function inspectTLS(host, port = 443, options = {}) {
|
|
|
11
12
|
const validTo = new Date(cert.valid_to);
|
|
12
13
|
const now = new Date();
|
|
13
14
|
const daysRemaining = Math.floor((validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
|
15
|
+
const altNames = cert.subjectaltname
|
|
16
|
+
? cert.subjectaltname.split(', ').map(s => s.replace(/^DNS:|^IP Address:/, '')).filter(Boolean)
|
|
17
|
+
: [];
|
|
18
|
+
let pubkey = null;
|
|
19
|
+
if (cert.pubkey) {
|
|
20
|
+
try {
|
|
21
|
+
const keyObject = crypto.createPublicKey(cert.pubkey);
|
|
22
|
+
let keySize;
|
|
23
|
+
const keyAlgo = keyObject.asymmetricKeyType || 'unknown';
|
|
24
|
+
if (keyObject.asymmetricKeyDetails) {
|
|
25
|
+
if (keyObject.asymmetricKeyDetails.modulusLength) {
|
|
26
|
+
keySize = keyObject.asymmetricKeyDetails.modulusLength;
|
|
27
|
+
}
|
|
28
|
+
else if (keyObject.asymmetricKeyDetails.namedCurve) {
|
|
29
|
+
const curve = keyObject.asymmetricKeyDetails.namedCurve;
|
|
30
|
+
if (curve.includes('256') || curve.includes('p256'))
|
|
31
|
+
keySize = 256;
|
|
32
|
+
else if (curve.includes('384') || curve.includes('p384'))
|
|
33
|
+
keySize = 384;
|
|
34
|
+
else if (curve.includes('521') || curve.includes('p521'))
|
|
35
|
+
keySize = 521;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (keySize) {
|
|
39
|
+
pubkey = { algo: keyAlgo, size: keySize };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
14
45
|
const info = {
|
|
15
46
|
valid: now >= validFrom && now <= validTo,
|
|
16
47
|
validFrom,
|
|
@@ -24,7 +55,10 @@ export function inspectTLS(host, port = 443, options = {}) {
|
|
|
24
55
|
protocol: socket.getProtocol(),
|
|
25
56
|
cipher: socket.getCipher(),
|
|
26
57
|
authorized: socket.authorized,
|
|
27
|
-
authorizationError: socket.authorizationError
|
|
58
|
+
authorizationError: socket.authorizationError,
|
|
59
|
+
altNames,
|
|
60
|
+
pubkey,
|
|
61
|
+
extKeyUsage: cert.ext_key_usage || []
|
|
28
62
|
};
|
|
29
63
|
socket.end();
|
|
30
64
|
resolve(info);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"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"}
|
package/dist/webrtc/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { StateError, TimeoutError, ConnectionError, UnsupportedError, } from '../core/errors.js';
|
|
1
2
|
import { EventEmitter } from 'node:events';
|
|
2
3
|
export class SignalingChannel extends EventEmitter {
|
|
3
4
|
options;
|
|
@@ -79,7 +80,10 @@ export class WebRTCClient extends EventEmitter {
|
|
|
79
80
|
}
|
|
80
81
|
async connect(remotePeerId) {
|
|
81
82
|
if (this.connections.has(remotePeerId)) {
|
|
82
|
-
throw new
|
|
83
|
+
throw new StateError(`Already connected to peer: ${remotePeerId}`, {
|
|
84
|
+
expectedState: 'disconnected',
|
|
85
|
+
actualState: 'connected',
|
|
86
|
+
});
|
|
83
87
|
}
|
|
84
88
|
this.log(`Connecting to peer: ${remotePeerId}`);
|
|
85
89
|
const pc = this.createPeerConnection(remotePeerId);
|
|
@@ -116,7 +120,10 @@ export class WebRTCClient extends EventEmitter {
|
|
|
116
120
|
if (remotePeerId) {
|
|
117
121
|
const dc = this.dataChannels.get(remotePeerId);
|
|
118
122
|
if (!dc || dc.readyState !== 'open') {
|
|
119
|
-
throw new
|
|
123
|
+
throw new StateError(`No open data channel to peer: ${remotePeerId}`, {
|
|
124
|
+
expectedState: 'open',
|
|
125
|
+
actualState: dc?.readyState ?? 'no-channel',
|
|
126
|
+
});
|
|
120
127
|
}
|
|
121
128
|
dc.send(message);
|
|
122
129
|
}
|
|
@@ -132,7 +139,10 @@ export class WebRTCClient extends EventEmitter {
|
|
|
132
139
|
if (remotePeerId) {
|
|
133
140
|
const dc = this.dataChannels.get(remotePeerId);
|
|
134
141
|
if (!dc || dc.readyState !== 'open') {
|
|
135
|
-
throw new
|
|
142
|
+
throw new StateError(`No open data channel to peer: ${remotePeerId}`, {
|
|
143
|
+
expectedState: 'open',
|
|
144
|
+
actualState: dc?.readyState ?? 'no-channel',
|
|
145
|
+
});
|
|
136
146
|
}
|
|
137
147
|
dc.send(data);
|
|
138
148
|
}
|
|
@@ -154,8 +164,7 @@ export class WebRTCClient extends EventEmitter {
|
|
|
154
164
|
}
|
|
155
165
|
createPeerConnection(remotePeerId) {
|
|
156
166
|
if (typeof RTCPeerConnection === 'undefined') {
|
|
157
|
-
throw new
|
|
158
|
-
'In Node.js, install the "wrtc" package and ensure it\'s loaded before using WebRTC.');
|
|
167
|
+
throw new UnsupportedError('RTCPeerConnection is not available. In Node.js, install the "wrtc" package and ensure it\'s loaded before using WebRTC.', { feature: 'RTCPeerConnection' });
|
|
159
168
|
}
|
|
160
169
|
const pc = new RTCPeerConnection({
|
|
161
170
|
iceServers: this.iceServers,
|
|
@@ -264,7 +273,10 @@ export class WebRTCClient extends EventEmitter {
|
|
|
264
273
|
waitForConnection(remotePeerId) {
|
|
265
274
|
return new Promise((resolve, reject) => {
|
|
266
275
|
const timeout = setTimeout(() => {
|
|
267
|
-
reject(new
|
|
276
|
+
reject(new TimeoutError(undefined, {
|
|
277
|
+
phase: 'webrtc-connect',
|
|
278
|
+
timeout: this.connectionTimeout,
|
|
279
|
+
}));
|
|
268
280
|
}, this.connectionTimeout);
|
|
269
281
|
const checkConnection = () => {
|
|
270
282
|
const dc = this.dataChannels.get(remotePeerId);
|
|
@@ -282,7 +294,9 @@ export class WebRTCClient extends EventEmitter {
|
|
|
282
294
|
this.on('disconnected', (peerId) => {
|
|
283
295
|
if (peerId === remotePeerId) {
|
|
284
296
|
clearTimeout(timeout);
|
|
285
|
-
reject(new
|
|
297
|
+
reject(new ConnectionError(`Connection failed to peer: ${remotePeerId}`, {
|
|
298
|
+
host: remotePeerId,
|
|
299
|
+
}));
|
|
286
300
|
}
|
|
287
301
|
});
|
|
288
302
|
checkConnection();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAKvC,MAAM,WAAW,gBAAgB;IAI/B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAK9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAKjC,UAAU,CAAC,EAAE,UAAU,CAAC;IAKxB,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAK9B,GAAG,CAAC,EAAE,UAAU,CAAC;IAMjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAM5B,SAAS,CAAC,EAAE,OAAO,CAAC;IAMpB,cAAc,CAAC,EAAE,MAAM,CAAC;IAMxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAO9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAM3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAYD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAgP;IAC/P,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,YAAY,CAAS;gBAEjB,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IA4BjD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"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"}
|
package/dist/websocket/client.js
CHANGED
|
@@ -2,7 +2,7 @@ import { WebSocket } from 'undici';
|
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import { pipeline } from 'node:stream/promises';
|
|
4
4
|
import { webToNodeStream } from '../utils/streaming.js';
|
|
5
|
-
import {
|
|
5
|
+
import { StateError, StreamError, ConnectionError } from '../core/errors.js';
|
|
6
6
|
export class ReckerWebSocket extends EventEmitter {
|
|
7
7
|
ws = null;
|
|
8
8
|
url;
|
|
@@ -83,11 +83,10 @@ export class ReckerWebSocket extends EventEmitter {
|
|
|
83
83
|
this.ws.addEventListener('error', (event) => {
|
|
84
84
|
const err = event.error instanceof Error
|
|
85
85
|
? event.error
|
|
86
|
-
: new
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
]);
|
|
86
|
+
: new ConnectionError('WebSocket connection error', {
|
|
87
|
+
host: this.url,
|
|
88
|
+
retriable: true,
|
|
89
|
+
});
|
|
91
90
|
this.emit('error', err);
|
|
92
91
|
reject(err);
|
|
93
92
|
});
|
|
@@ -99,11 +98,10 @@ export class ReckerWebSocket extends EventEmitter {
|
|
|
99
98
|
}
|
|
100
99
|
async send(data, options) {
|
|
101
100
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
102
|
-
throw new
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
]);
|
|
101
|
+
throw new StateError('WebSocket is not connected', {
|
|
102
|
+
expectedState: 'open',
|
|
103
|
+
actualState: this.ws ? 'closed' : 'not-created',
|
|
104
|
+
});
|
|
107
105
|
}
|
|
108
106
|
const awaitDrain = options?.awaitDrain ?? false;
|
|
109
107
|
const highWaterMark = options?.highWaterMark ?? 16 * 1024;
|
|
@@ -169,11 +167,10 @@ export class ReckerWebSocket extends EventEmitter {
|
|
|
169
167
|
async pipeTo(destination) {
|
|
170
168
|
const readable = this.toReadable();
|
|
171
169
|
if (!readable) {
|
|
172
|
-
throw new
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
]);
|
|
170
|
+
throw new StreamError('WebSocket has no readable stream', {
|
|
171
|
+
streamType: 'websocket',
|
|
172
|
+
retriable: false,
|
|
173
|
+
});
|
|
177
174
|
}
|
|
178
175
|
await pipeline(readable, destination);
|
|
179
176
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "AI & DevX focused HTTP client for Node.js 18+",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
"access": "public"
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
|
+
"@maxmind/geoip2-node": "^6.3.4",
|
|
118
119
|
"cheerio": "^1.0.0",
|
|
119
120
|
"commander": "^12.0.0",
|
|
120
121
|
"fuse.js": "^7.1.0",
|
|
@@ -166,13 +167,13 @@
|
|
|
166
167
|
"zod": "^3.24.0"
|
|
167
168
|
},
|
|
168
169
|
"scripts": {
|
|
169
|
-
"build": "tsc
|
|
170
|
+
"build": "tsc",
|
|
170
171
|
"build:embeddings": "tsx scripts/build-embeddings.ts",
|
|
171
172
|
"test": "vitest run",
|
|
172
173
|
"test:coverage": "vitest run --coverage",
|
|
173
174
|
"bench": "tsx benchmark/index.ts",
|
|
174
175
|
"bench:all": "tsx benchmark/run-all.ts",
|
|
175
|
-
"docs": "
|
|
176
|
+
"docs": "pnpm serve docs -p 3000",
|
|
176
177
|
"lint": "echo \"No linting configured for this project.\" && exit 0",
|
|
177
178
|
"cli": "tsx src/cli/index.ts",
|
|
178
179
|
"mcp:start": "tsx src/mcp/cli.ts",
|