specters 2.2.0 → 3.0.0
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 +50 -116
- package/index.d.ts +121 -89
- package/index.js +21 -1
- package/package.json +12 -7
package/README.md
CHANGED
|
@@ -1,161 +1,95 @@
|
|
|
1
1
|
# Specter Node.js Bindings
|
|
2
2
|
|
|
3
|
-
Node.js bindings for Specter, a high-performance HTTP client with
|
|
3
|
+
Node.js bindings for Specter, a high-performance async HTTP client with TLS, HTTP/2, HTTP/3, RFC 6455 WebSocket, and RFC 8441 Extended CONNECT support.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- **Automatic decompression**: gzip, deflate, brotli, zstd
|
|
7
|
+
- Promise-based HTTP, RFC 6455 WebSocket, and RFC 8441 raw tunnel APIs
|
|
8
|
+
- Browser fingerprinting for Chrome, Firefox, or default TLS settings
|
|
9
|
+
- HTTP/2, HTTP/3, connection pooling, and automatic decompression
|
|
10
|
+
- Cookie store and shared cookie jar support across HTTP and WebSocket handshakes
|
|
11
|
+
- Granular connect, TTFB, read/write idle, total, pool, and WebSocket handshake timeouts
|
|
13
12
|
|
|
14
13
|
## Installation
|
|
15
14
|
|
|
16
15
|
```bash
|
|
17
|
-
npm install
|
|
16
|
+
npm install specters
|
|
18
17
|
```
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## HTTP
|
|
21
20
|
|
|
22
21
|
```javascript
|
|
23
|
-
const {
|
|
24
|
-
|
|
25
|
-
async function main() {
|
|
26
|
-
// Create a client with default settings
|
|
27
|
-
const client = Client.builder().build();
|
|
28
|
-
|
|
29
|
-
// Make a GET request
|
|
30
|
-
const response = await client.get('https://httpbin.org/get').send();
|
|
31
|
-
console.log(`Status: ${response.status}`);
|
|
32
|
-
console.log(await response.text());
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
main();
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Browser Impersonation
|
|
39
|
-
|
|
40
|
-
```javascript
|
|
41
|
-
const { Client, FingerprintProfile } = require('@specter/client');
|
|
22
|
+
const { clientBuilder, FingerprintProfile } = require('specters');
|
|
42
23
|
|
|
43
|
-
|
|
44
|
-
const client = Client.builder()
|
|
45
|
-
.fingerprint(FingerprintProfile.Chrome146)
|
|
46
|
-
.build();
|
|
47
|
-
|
|
48
|
-
// Or pick a specific version (142, 143, 144, 145, 146)
|
|
49
|
-
const client = Client.builder()
|
|
24
|
+
const client = clientBuilder()
|
|
50
25
|
.fingerprint(FingerprintProfile.Chrome142)
|
|
26
|
+
.cookieStore(true)
|
|
51
27
|
.build();
|
|
52
28
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
.
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
## Timeout Configuration
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
const { Client, timeoutsApiDefaults, timeoutsStreamingDefaults } = require('@specter/client');
|
|
63
|
-
|
|
64
|
-
// Use preset timeout configurations
|
|
65
|
-
const client1 = Client.builder().apiTimeouts().build();
|
|
66
|
-
const client2 = Client.builder().streamingTimeouts().build();
|
|
67
|
-
|
|
68
|
-
// Or configure manually
|
|
69
|
-
const timeouts = {
|
|
70
|
-
connect: 10.0, // TCP + TLS handshake
|
|
71
|
-
ttfb: 30.0, // Time to first byte
|
|
72
|
-
readIdle: 60.0, // Max time between chunks
|
|
73
|
-
total: 120.0 // Total request deadline
|
|
74
|
-
};
|
|
29
|
+
const response = await client
|
|
30
|
+
.post('https://example.com/items')
|
|
31
|
+
.header('Authorization', 'Bearer token')
|
|
32
|
+
.json(JSON.stringify({ name: 'example' }))
|
|
33
|
+
.send();
|
|
75
34
|
|
|
76
|
-
|
|
35
|
+
console.log(response.status);
|
|
36
|
+
console.log(response.text());
|
|
77
37
|
```
|
|
78
38
|
|
|
79
|
-
##
|
|
39
|
+
## RFC 6455 WebSockets
|
|
80
40
|
|
|
81
41
|
```javascript
|
|
82
|
-
const {
|
|
83
|
-
|
|
84
|
-
const client = Client.builder().build();
|
|
85
|
-
|
|
86
|
-
// GET
|
|
87
|
-
const response = await client.get('https://api.example.com/items').send();
|
|
42
|
+
const { CLOSE_NORMAL, clientBuilder } = require('specters');
|
|
88
43
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const response = await client.put('https://api.example.com/items/1').send();
|
|
94
|
-
|
|
95
|
-
// DELETE
|
|
96
|
-
const response = await client.delete('https://api.example.com/items/1').send();
|
|
44
|
+
const client = clientBuilder()
|
|
45
|
+
.cookieStore(true)
|
|
46
|
+
.http2PriorKnowledge(false)
|
|
47
|
+
.build();
|
|
97
48
|
|
|
98
|
-
|
|
99
|
-
|
|
49
|
+
const ws = await client.websocket('wss://example.com/socket')
|
|
50
|
+
.header('Origin', 'https://example.com')
|
|
51
|
+
.subprotocol('chat.v1')
|
|
52
|
+
.maxMessageSize(1 << 20)
|
|
53
|
+
.handshakeTimeout(10)
|
|
54
|
+
.connect();
|
|
100
55
|
|
|
101
|
-
|
|
102
|
-
const
|
|
56
|
+
await ws.sendText('hello');
|
|
57
|
+
const message = await ws.next();
|
|
103
58
|
|
|
104
|
-
|
|
105
|
-
|
|
59
|
+
if (message.type === 'text') {
|
|
60
|
+
console.log(message.text);
|
|
61
|
+
}
|
|
106
62
|
|
|
107
|
-
|
|
108
|
-
const response = await client.request('PURGE', 'https://api.example.com/cache').send();
|
|
63
|
+
await ws.close({ code: CLOSE_NORMAL, reason: 'done' });
|
|
109
64
|
```
|
|
110
65
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```javascript
|
|
114
|
-
const response = await client.get('https://api.example.com/data').send();
|
|
115
|
-
|
|
116
|
-
// Status code
|
|
117
|
-
console.log(response.status);
|
|
118
|
-
|
|
119
|
-
// Headers
|
|
120
|
-
console.log(response.headers); // Record<string, string>
|
|
121
|
-
console.log(response.getHeader('content-type'));
|
|
122
|
-
|
|
123
|
-
// Body
|
|
124
|
-
console.log(response.text()); // Decompressed text
|
|
125
|
-
console.log(response.json()); // JSON string (use JSON.parse)
|
|
126
|
-
const data = response.bytes(); // Buffer
|
|
127
|
-
|
|
128
|
-
// Response metadata
|
|
129
|
-
console.log(response.httpVersion); // "HTTP/2", "HTTP/1.1", etc.
|
|
130
|
-
console.log(response.isSuccess); // true for 2xx status
|
|
66
|
+
RFC 6455 sockets are framed message connections. `send*`, `next`, and `close` operations are serialized per socket to preserve Rust's mutable socket contract; avoid running multiple receive loops on the same socket.
|
|
131
67
|
|
|
132
|
-
##
|
|
68
|
+
## RFC 8441 HTTP/2 Tunnels
|
|
133
69
|
|
|
134
70
|
```javascript
|
|
135
|
-
const {
|
|
71
|
+
const { clientBuilder } = require('specters');
|
|
136
72
|
|
|
137
|
-
const client =
|
|
73
|
+
const client = clientBuilder()
|
|
74
|
+
.http2PriorKnowledge(true)
|
|
75
|
+
.build();
|
|
138
76
|
|
|
139
|
-
const
|
|
140
|
-
.
|
|
141
|
-
.
|
|
142
|
-
.json(JSON.stringify({ name: 'example' }))
|
|
143
|
-
.send();
|
|
77
|
+
const tunnel = await client.websocketH2('https://example.com/h2-tunnel')
|
|
78
|
+
.header('Origin', 'https://example.com')
|
|
79
|
+
.open();
|
|
144
80
|
|
|
145
|
-
|
|
146
|
-
|
|
81
|
+
await tunnel.sendBytes(Buffer.from('raw bytes'), false);
|
|
82
|
+
const data = await tunnel.recvBytes();
|
|
83
|
+
await tunnel.closeSend();
|
|
147
84
|
```
|
|
148
85
|
|
|
86
|
+
RFC 8441 exposes a raw byte tunnel over HTTP/2 Extended CONNECT. It is intentionally separate from the RFC 6455 framed `WebSocket` API.
|
|
87
|
+
|
|
149
88
|
## Development
|
|
150
89
|
|
|
151
90
|
```bash
|
|
152
|
-
# Install dependencies
|
|
153
91
|
npm install
|
|
154
|
-
|
|
155
|
-
# Build the native module
|
|
156
92
|
npm run build
|
|
157
|
-
|
|
158
|
-
# Run tests
|
|
159
93
|
npm test
|
|
160
94
|
```
|
|
161
95
|
|
package/index.d.ts
CHANGED
|
@@ -1,164 +1,196 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Specter - Node.js bindings for the Specter HTTP client.
|
|
3
|
-
*
|
|
4
|
-
* A high-performance async HTTP client with full TLS, HTTP/2, and HTTP/3
|
|
5
|
-
* fingerprint control for browser impersonation.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/** Browser fingerprint profiles for impersonation. */
|
|
9
1
|
export enum FingerprintProfile {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
Chrome142,
|
|
3
|
+
Chrome143,
|
|
4
|
+
Chrome144,
|
|
5
|
+
Chrome145,
|
|
6
|
+
Chrome146,
|
|
7
|
+
Firefox133,
|
|
8
|
+
None,
|
|
16
9
|
}
|
|
17
10
|
|
|
18
|
-
/** HTTP version preference. */
|
|
19
11
|
export enum HttpVersion {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Http3Only = 3,
|
|
28
|
-
/** Let the client decide based on server support */
|
|
29
|
-
Auto = 4,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Timeout configuration for HTTP requests. */
|
|
12
|
+
Http1_1,
|
|
13
|
+
Http2,
|
|
14
|
+
Http3,
|
|
15
|
+
Http3Only,
|
|
16
|
+
Auto,
|
|
17
|
+
}
|
|
18
|
+
|
|
33
19
|
export interface Timeouts {
|
|
34
|
-
/** TCP + TLS/QUIC handshake timeout in seconds */
|
|
35
20
|
connect?: number;
|
|
36
|
-
/** Time-to-first-byte timeout in seconds */
|
|
37
21
|
ttfb?: number;
|
|
38
|
-
/** Maximum time between received bytes in seconds (resets on each chunk) */
|
|
39
22
|
readIdle?: number;
|
|
40
|
-
/** Maximum time between sent bytes in seconds */
|
|
41
23
|
writeIdle?: number;
|
|
42
|
-
/** Absolute deadline for entire request in seconds */
|
|
43
24
|
total?: number;
|
|
44
|
-
/** Time to wait for a pooled connection in seconds */
|
|
45
25
|
poolAcquire?: number;
|
|
46
26
|
}
|
|
47
27
|
|
|
48
|
-
|
|
28
|
+
export interface WebSocketMessage {
|
|
29
|
+
type: 'text' | 'binary' | 'ping' | 'pong' | 'close';
|
|
30
|
+
text?: string;
|
|
31
|
+
data?: Buffer;
|
|
32
|
+
code?: number;
|
|
33
|
+
reason?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WebSocketCloseFrame {
|
|
37
|
+
code?: number;
|
|
38
|
+
reason?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface H2TunnelEvent {
|
|
42
|
+
type: 'data' | 'endStream' | 'reset' | 'goAway';
|
|
43
|
+
data?: Buffer;
|
|
44
|
+
reason?: string;
|
|
45
|
+
lastStreamId?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface H3TunnelEvent {
|
|
49
|
+
type: 'data' | 'endStream' | 'reset' | 'goAway';
|
|
50
|
+
data?: Buffer;
|
|
51
|
+
reason?: string;
|
|
52
|
+
lastStreamId?: bigint;
|
|
53
|
+
}
|
|
54
|
+
|
|
49
55
|
export class RequestBuilder {
|
|
50
|
-
/** Add a header to the request. Returns this for chaining. */
|
|
51
56
|
header(key: string, value: string): this;
|
|
52
|
-
/** Set all headers (replaces existing headers). Returns this for chaining. */
|
|
53
57
|
headers(headers: string[][]): this;
|
|
54
|
-
/** Set the request body as bytes. Returns this for chaining. */
|
|
55
58
|
body(body: Buffer): this;
|
|
56
|
-
/** Set the request body as JSON string and add Content-Type header. Returns this for chaining. */
|
|
57
59
|
json(jsonStr: string): this;
|
|
58
|
-
/** Set the request body as form data and add Content-Type header. Returns this for chaining. */
|
|
59
60
|
form(formStr: string): this;
|
|
60
|
-
/** Send the request and return the response. */
|
|
61
61
|
send(): Promise<Response>;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
/** HTTP response with decompression support. */
|
|
65
64
|
export class Response {
|
|
66
|
-
/** HTTP status code */
|
|
67
65
|
get status(): number;
|
|
68
|
-
/** Response headers as an object */
|
|
69
66
|
get headers(): Record<string, string>;
|
|
70
|
-
/** Get all headers as an array of [key, value] pairs */
|
|
71
67
|
headersList(): string[][];
|
|
72
|
-
/** Get a specific header value by name */
|
|
73
68
|
getHeader(name: string): string | null;
|
|
74
|
-
/** Get the response body as text (with decompression if needed) */
|
|
75
69
|
text(): string;
|
|
76
|
-
/** Get the response body as a Buffer */
|
|
77
70
|
bytes(): Buffer;
|
|
78
|
-
/** Parse the response body as JSON and return as string. Use JSON.parse to convert to an object. */
|
|
79
71
|
json(): string;
|
|
80
|
-
/** HTTP version string */
|
|
81
72
|
get httpVersion(): string;
|
|
82
|
-
/** Effective URL (after redirects) */
|
|
83
73
|
get effectiveUrl(): string | null;
|
|
84
|
-
/** Check if the response status is successful (2xx) */
|
|
85
74
|
get isSuccess(): boolean;
|
|
86
|
-
/** Check if the response is a redirect (3xx) */
|
|
87
75
|
get isRedirect(): boolean;
|
|
88
|
-
/** Get the redirect URL from Location header if present */
|
|
89
76
|
get redirectUrl(): string | null;
|
|
90
|
-
/** Get the Content-Type header value */
|
|
91
77
|
get contentType(): string | null;
|
|
92
78
|
}
|
|
93
79
|
|
|
94
|
-
/** Builder for creating HTTP clients. */
|
|
95
80
|
export class ClientBuilder {
|
|
96
|
-
/** Set the fingerprint profile */
|
|
97
81
|
fingerprint(profile: FingerprintProfile): this;
|
|
98
|
-
/** Set HTTP/2 preference */
|
|
99
82
|
preferHttp2(prefer: boolean): this;
|
|
100
|
-
|
|
83
|
+
http2PriorKnowledge(enabled: boolean): this;
|
|
101
84
|
h3Upgrade(enabled: boolean): this;
|
|
102
|
-
|
|
85
|
+
cookieStore(enabled: boolean): this;
|
|
86
|
+
cookieJar(jar: CookieJar): this;
|
|
103
87
|
timeouts(timeouts: Timeouts): this;
|
|
104
|
-
/** Use API-optimized timeout defaults */
|
|
105
88
|
apiTimeouts(): this;
|
|
106
|
-
/** Use streaming-optimized timeout defaults */
|
|
107
89
|
streamingTimeouts(): this;
|
|
108
|
-
/** Set total request timeout in seconds */
|
|
109
90
|
totalTimeout(timeoutSecs: number): this;
|
|
110
|
-
/** Set connect timeout in seconds */
|
|
111
91
|
connectTimeout(timeoutSecs: number): this;
|
|
112
|
-
/** Set TTFB (time-to-first-byte) timeout in seconds */
|
|
113
92
|
ttfbTimeout(timeoutSecs: number): this;
|
|
114
|
-
/** Set read idle timeout in seconds */
|
|
115
93
|
readTimeout(timeoutSecs: number): this;
|
|
116
|
-
/** Skip TLS certificate verification for all connections (DANGEROUS - for testing only) */
|
|
117
94
|
dangerAcceptInvalidCerts(accept: boolean): this;
|
|
118
|
-
/** Automatically skip TLS certificate verification for localhost connections */
|
|
119
95
|
localhostAllowsInvalidCerts(allow: boolean): this;
|
|
120
|
-
/** Load root certificates from the operating system's certificate store */
|
|
121
96
|
withPlatformRoots(enabled: boolean): this;
|
|
122
|
-
/** Build the client */
|
|
123
97
|
build(): Client;
|
|
124
98
|
}
|
|
125
99
|
|
|
126
|
-
/** HTTP client with TLS/HTTP2/HTTP3 fingerprint control. */
|
|
127
100
|
export class Client {
|
|
128
|
-
|
|
101
|
+
websocket(url: string): WebSocketBuilder;
|
|
102
|
+
websocketH2(url: string): WebSocketH2Builder;
|
|
103
|
+
websocketH3(url: string): WebSocketH3Builder;
|
|
129
104
|
get(url: string): RequestBuilder;
|
|
130
|
-
/** Create a POST request builder */
|
|
131
105
|
post(url: string): RequestBuilder;
|
|
132
|
-
/** Create a PUT request builder */
|
|
133
106
|
put(url: string): RequestBuilder;
|
|
134
|
-
/** Create a DELETE request builder */
|
|
135
107
|
delete(url: string): RequestBuilder;
|
|
136
|
-
/** Create a PATCH request builder */
|
|
137
108
|
patch(url: string): RequestBuilder;
|
|
138
|
-
/** Create a HEAD request builder */
|
|
139
109
|
head(url: string): RequestBuilder;
|
|
140
|
-
/** Create an OPTIONS request builder */
|
|
141
110
|
options(url: string): RequestBuilder;
|
|
142
|
-
/** Create a request builder for an arbitrary HTTP method */
|
|
143
111
|
request(method: string, url: string): RequestBuilder;
|
|
144
112
|
}
|
|
145
113
|
|
|
146
|
-
/** Cookie jar for manual cookie management. */
|
|
147
114
|
export class CookieJar {
|
|
148
115
|
constructor();
|
|
149
|
-
/** Get the number of cookies in the jar */
|
|
150
116
|
get length(): number;
|
|
151
|
-
/** Check if the cookie jar is empty */
|
|
152
117
|
get isEmpty(): boolean;
|
|
153
118
|
}
|
|
154
119
|
|
|
155
|
-
|
|
156
|
-
|
|
120
|
+
export class WebSocketBuilder {
|
|
121
|
+
header(key: string, value: string): this;
|
|
122
|
+
headers(headers: Record<string, string>): this;
|
|
123
|
+
subprotocol(value: string): this;
|
|
124
|
+
subprotocols(values: string[]): this;
|
|
125
|
+
maxMessageSize(bytes: number): this;
|
|
126
|
+
maxFrameSize(bytes: number): this;
|
|
127
|
+
connectTimeout(timeoutSecs: number): this;
|
|
128
|
+
handshakeTimeout(timeoutSecs: number): this;
|
|
129
|
+
readTimeout(timeoutSecs: number): this;
|
|
130
|
+
writeTimeout(timeoutSecs: number): this;
|
|
131
|
+
connect(): Promise<WebSocket>;
|
|
132
|
+
}
|
|
157
133
|
|
|
158
|
-
|
|
159
|
-
|
|
134
|
+
export class WebSocket {
|
|
135
|
+
get url(): string;
|
|
136
|
+
get protocol(): string | null;
|
|
137
|
+
send(message: WebSocketMessage): Promise<void>;
|
|
138
|
+
sendText(text: string): Promise<void>;
|
|
139
|
+
sendBinary(data: Buffer): Promise<void>;
|
|
140
|
+
sendPing(data?: Buffer): Promise<void>;
|
|
141
|
+
sendPong(data?: Buffer): Promise<void>;
|
|
142
|
+
next(): Promise<WebSocketMessage>;
|
|
143
|
+
close(frame?: WebSocketCloseFrame): Promise<void>;
|
|
144
|
+
}
|
|
160
145
|
|
|
161
|
-
|
|
162
|
-
|
|
146
|
+
export class WebSocketH2Builder {
|
|
147
|
+
header(key: string, value: string): this;
|
|
148
|
+
headers(headers: string[][]): this;
|
|
149
|
+
subprotocol(value: string): this;
|
|
150
|
+
connectTimeout(timeoutSecs: number): this;
|
|
151
|
+
readTimeout(timeoutSecs: number): this;
|
|
152
|
+
writeTimeout(timeoutSecs: number): this;
|
|
153
|
+
connect(): Promise<WebSocketH2Tunnel>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export class WebSocketH2Tunnel {
|
|
157
|
+
sendBytes(data: Buffer, endStream?: boolean): Promise<void>;
|
|
158
|
+
recvBytes(): Promise<Buffer | null>;
|
|
159
|
+
recvEvent(): Promise<H2TunnelEvent | null>;
|
|
160
|
+
closeSend(): Promise<void>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export class WebSocketH3Builder {
|
|
164
|
+
header(key: string, value: string): this;
|
|
165
|
+
headers(headers: string[][]): this;
|
|
166
|
+
subprotocol(value: string): this;
|
|
167
|
+
connectTimeout(timeoutSecs: number): this;
|
|
168
|
+
readTimeout(timeoutSecs: number): this;
|
|
169
|
+
writeTimeout(timeoutSecs: number): this;
|
|
170
|
+
connect(): Promise<WebSocketH3Tunnel>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export class WebSocketH3Tunnel {
|
|
174
|
+
sendBytes(data: Buffer, fin?: boolean): Promise<void>;
|
|
175
|
+
recvBytes(): Promise<Buffer | null>;
|
|
176
|
+
recvEvent(): Promise<H3TunnelEvent | null>;
|
|
177
|
+
closeSend(): Promise<void>;
|
|
178
|
+
}
|
|
163
179
|
|
|
164
|
-
export
|
|
180
|
+
export const CLOSE_NORMAL: number;
|
|
181
|
+
export const CLOSE_GOING_AWAY: number;
|
|
182
|
+
export const CLOSE_PROTOCOL_ERROR: number;
|
|
183
|
+
export const CLOSE_UNSUPPORTED: number;
|
|
184
|
+
export const CLOSE_NO_STATUS: number;
|
|
185
|
+
export const CLOSE_ABNORMAL: number;
|
|
186
|
+
export const CLOSE_INVALID_PAYLOAD: number;
|
|
187
|
+
export const CLOSE_POLICY_VIOLATION: number;
|
|
188
|
+
export const CLOSE_MESSAGE_TOO_BIG: number;
|
|
189
|
+
export const CLOSE_MANDATORY_EXTENSION: number;
|
|
190
|
+
export const CLOSE_INTERNAL_ERROR: number;
|
|
191
|
+
export const CLOSE_TLS_ERROR: number;
|
|
192
|
+
|
|
193
|
+
export function isValidCloseCode(code: number): boolean;
|
|
194
|
+
export function clientBuilder(): ClientBuilder;
|
|
195
|
+
export function timeoutsApiDefaults(): Timeouts;
|
|
196
|
+
export function timeoutsStreamingDefaults(): Timeouts;
|
package/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const { execSync } = require('node:child_process');
|
|
9
9
|
const { readFileSync } = require('node:fs');
|
|
10
10
|
|
|
11
|
-
const PACKAGE_VERSION = '
|
|
11
|
+
const PACKAGE_VERSION = '3.0.0';
|
|
12
12
|
|
|
13
13
|
const targets = {
|
|
14
14
|
'darwin-x64': {
|
|
@@ -131,9 +131,29 @@ module.exports.ClientBuilder = binding.ClientBuilder;
|
|
|
131
131
|
module.exports.RequestBuilder = binding.RequestBuilder;
|
|
132
132
|
module.exports.Response = binding.Response;
|
|
133
133
|
module.exports.CookieJar = binding.CookieJar;
|
|
134
|
+
module.exports.WebSocketBuilder = binding.WebSocketBuilder;
|
|
135
|
+
module.exports.WebSocket = binding.WebSocket;
|
|
136
|
+
module.exports.WebSocketH2Builder = binding.WebSocketH2Builder;
|
|
137
|
+
module.exports.WebSocketH2Tunnel = binding.WebSocketH2Tunnel;
|
|
138
|
+
module.exports.WebSocketH3Builder = binding.WebSocketH3Builder;
|
|
139
|
+
module.exports.WebSocketH3Tunnel = binding.WebSocketH3Tunnel;
|
|
140
|
+
module.exports.WebSocketCloseFrame = binding.WebSocketCloseFrame;
|
|
134
141
|
module.exports.FingerprintProfile = binding.FingerprintProfile;
|
|
135
142
|
module.exports.HttpVersion = binding.HttpVersion;
|
|
136
143
|
module.exports.Timeouts = binding.Timeouts;
|
|
144
|
+
module.exports.CLOSE_NORMAL = binding.CLOSE_NORMAL;
|
|
145
|
+
module.exports.CLOSE_GOING_AWAY = binding.CLOSE_GOING_AWAY;
|
|
146
|
+
module.exports.CLOSE_PROTOCOL_ERROR = binding.CLOSE_PROTOCOL_ERROR;
|
|
147
|
+
module.exports.CLOSE_UNSUPPORTED = binding.CLOSE_UNSUPPORTED;
|
|
148
|
+
module.exports.CLOSE_NO_STATUS = binding.CLOSE_NO_STATUS;
|
|
149
|
+
module.exports.CLOSE_ABNORMAL = binding.CLOSE_ABNORMAL;
|
|
150
|
+
module.exports.CLOSE_INVALID_PAYLOAD = binding.CLOSE_INVALID_PAYLOAD;
|
|
151
|
+
module.exports.CLOSE_POLICY_VIOLATION = binding.CLOSE_POLICY_VIOLATION;
|
|
152
|
+
module.exports.CLOSE_MESSAGE_TOO_BIG = binding.CLOSE_MESSAGE_TOO_BIG;
|
|
153
|
+
module.exports.CLOSE_MANDATORY_EXTENSION = binding.CLOSE_MANDATORY_EXTENSION;
|
|
154
|
+
module.exports.CLOSE_INTERNAL_ERROR = binding.CLOSE_INTERNAL_ERROR;
|
|
155
|
+
module.exports.CLOSE_TLS_ERROR = binding.CLOSE_TLS_ERROR;
|
|
156
|
+
module.exports.isValidCloseCode = binding.isValidCloseCode;
|
|
137
157
|
module.exports.clientBuilder = binding.clientBuilder;
|
|
138
158
|
module.exports.timeoutsApiDefaults = binding.timeoutsApiDefaults;
|
|
139
159
|
module.exports.timeoutsStreamingDefaults = binding.timeoutsStreamingDefaults;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specters",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Node.js bindings for Specter HTTP
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Node.js bindings for Specter HTTP, WebSocket, HTTP/2, and HTTP/3 tunnel client",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"napi": {
|
|
@@ -29,11 +29,16 @@
|
|
|
29
29
|
"artifacts": "napi artifacts --output-dir ./artifacts",
|
|
30
30
|
"test": "jest"
|
|
31
31
|
},
|
|
32
|
+
"jest": {
|
|
33
|
+
"testMatch": [
|
|
34
|
+
"**/__tests__/*.test.js"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
32
37
|
"optionalDependencies": {
|
|
33
|
-
"specters-darwin-x64": "
|
|
34
|
-
"specters-darwin-arm64": "
|
|
35
|
-
"specters-linux-x64-gnu": "
|
|
36
|
-
"specters-linux-arm64-gnu": "
|
|
38
|
+
"specters-darwin-x64": "3.0.0",
|
|
39
|
+
"specters-darwin-arm64": "3.0.0",
|
|
40
|
+
"specters-linux-x64-gnu": "3.0.0",
|
|
41
|
+
"specters-linux-arm64-gnu": "3.0.0"
|
|
37
42
|
},
|
|
38
43
|
"devDependencies": {
|
|
39
44
|
"@napi-rs/cli": "^3.6.2",
|
|
@@ -55,4 +60,4 @@
|
|
|
55
60
|
"url": "https://github.com/jaredboynton/specter.git",
|
|
56
61
|
"directory": "bindings/node"
|
|
57
62
|
}
|
|
58
|
-
}
|
|
63
|
+
}
|