specters 2.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 +159 -0
- package/index.d.ts +164 -0
- package/index.js +130 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Specter Node.js Bindings
|
|
2
|
+
|
|
3
|
+
Node.js bindings for Specter, a high-performance HTTP client with full TLS, HTTP/2, and HTTP/3 fingerprint control.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Native async/await**: Promise-based API with native performance
|
|
8
|
+
- **Browser fingerprinting**: Impersonate Chrome, Firefox, or use custom TLS/HTTP2 settings
|
|
9
|
+
- **HTTP/3 support**: Automatic upgrade via Alt-Svc headers
|
|
10
|
+
- **Connection pooling**: HTTP/2 multiplexing and HTTP/1.1 keep-alive
|
|
11
|
+
- **Timeout control**: Granular timeouts for connect, TTFB, read/write idle, and total request time
|
|
12
|
+
- **Automatic decompression**: gzip, deflate, brotli, zstd
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @specter/client
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const { Client } = require('@specter/client');
|
|
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');
|
|
42
|
+
|
|
43
|
+
// Impersonate Chrome 142
|
|
44
|
+
const client = Client.builder()
|
|
45
|
+
.fingerprint(FingerprintProfile.Chrome142)
|
|
46
|
+
.build();
|
|
47
|
+
|
|
48
|
+
// Or Firefox 133
|
|
49
|
+
const client = Client.builder()
|
|
50
|
+
.fingerprint(FingerprintProfile.Firefox133)
|
|
51
|
+
.build();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Timeout Configuration
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
const { Client, timeoutsApiDefaults, timeoutsStreamingDefaults } = require('@specter/client');
|
|
58
|
+
|
|
59
|
+
// Use preset timeout configurations
|
|
60
|
+
const client1 = Client.builder().apiTimeouts().build();
|
|
61
|
+
const client2 = Client.builder().streamingTimeouts().build();
|
|
62
|
+
|
|
63
|
+
// Or configure manually
|
|
64
|
+
const timeouts = {
|
|
65
|
+
connect: 10.0, // TCP + TLS handshake
|
|
66
|
+
ttfb: 30.0, // Time to first byte
|
|
67
|
+
readIdle: 60.0, // Max time between chunks
|
|
68
|
+
total: 120.0 // Total request deadline
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const client = Client.builder().timeouts(timeouts).build();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## HTTP Methods
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const { Client } = require('@specter/client');
|
|
78
|
+
|
|
79
|
+
const client = Client.builder().build();
|
|
80
|
+
|
|
81
|
+
// GET
|
|
82
|
+
const response = await client.get('https://api.example.com/items').send();
|
|
83
|
+
|
|
84
|
+
// POST
|
|
85
|
+
const response = await client.post('https://api.example.com/items').send();
|
|
86
|
+
|
|
87
|
+
// PUT
|
|
88
|
+
const response = await client.put('https://api.example.com/items/1').send();
|
|
89
|
+
|
|
90
|
+
// DELETE
|
|
91
|
+
const response = await client.delete('https://api.example.com/items/1').send();
|
|
92
|
+
|
|
93
|
+
// PATCH
|
|
94
|
+
const response = await client.patch('https://api.example.com/items/1').send();
|
|
95
|
+
|
|
96
|
+
// HEAD
|
|
97
|
+
const response = await client.head('https://api.example.com/items/1').send();
|
|
98
|
+
|
|
99
|
+
// OPTIONS
|
|
100
|
+
const response = await client.options('https://api.example.com/items').send();
|
|
101
|
+
|
|
102
|
+
// Arbitrary method
|
|
103
|
+
const response = await client.request('PURGE', 'https://api.example.com/cache').send();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Response Handling
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const response = await client.get('https://api.example.com/data').send();
|
|
110
|
+
|
|
111
|
+
// Status code
|
|
112
|
+
console.log(response.status);
|
|
113
|
+
|
|
114
|
+
// Headers
|
|
115
|
+
console.log(response.headers); // Record<string, string>
|
|
116
|
+
console.log(response.getHeader('content-type'));
|
|
117
|
+
|
|
118
|
+
// Body
|
|
119
|
+
console.log(response.text()); // Decompressed text
|
|
120
|
+
console.log(response.json()); // JSON string (use JSON.parse)
|
|
121
|
+
const data = response.bytes(); // Buffer
|
|
122
|
+
|
|
123
|
+
// Response metadata
|
|
124
|
+
console.log(response.httpVersion); // "HTTP/2", "HTTP/1.1", etc.
|
|
125
|
+
console.log(response.isSuccess); // true for 2xx status
|
|
126
|
+
|
|
127
|
+
## Request Builder
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
const { Client } = require('@specter/client');
|
|
131
|
+
|
|
132
|
+
const client = Client.builder().build();
|
|
133
|
+
|
|
134
|
+
const response = await client
|
|
135
|
+
.post('https://api.example.com/items')
|
|
136
|
+
.header('Authorization', 'Bearer token')
|
|
137
|
+
.json(JSON.stringify({ name: 'example' }))
|
|
138
|
+
.send();
|
|
139
|
+
|
|
140
|
+
console.log(response.status);
|
|
141
|
+
```
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Install dependencies
|
|
148
|
+
npm install
|
|
149
|
+
|
|
150
|
+
# Build the native module
|
|
151
|
+
npm run build
|
|
152
|
+
|
|
153
|
+
# Run tests
|
|
154
|
+
npm test
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
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
|
+
export enum FingerprintProfile {
|
|
10
|
+
/** Chrome 142 on macOS */
|
|
11
|
+
Chrome142 = 0,
|
|
12
|
+
/** Firefox 133 on macOS */
|
|
13
|
+
Firefox133 = 1,
|
|
14
|
+
/** No fingerprinting - use default TLS settings */
|
|
15
|
+
None = 2,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** HTTP version preference. */
|
|
19
|
+
export enum HttpVersion {
|
|
20
|
+
/** Force HTTP/1.1 */
|
|
21
|
+
Http1_1 = 0,
|
|
22
|
+
/** Attempt HTTP/2, fallback to HTTP/1.1 */
|
|
23
|
+
Http2 = 1,
|
|
24
|
+
/** Attempt HTTP/3, fallback to HTTP/2, fallback to HTTP/1.1 */
|
|
25
|
+
Http3 = 2,
|
|
26
|
+
/** HTTP/3 only, no fallback */
|
|
27
|
+
Http3Only = 3,
|
|
28
|
+
/** Let the client decide based on server support */
|
|
29
|
+
Auto = 4,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Timeout configuration for HTTP requests. */
|
|
33
|
+
export interface Timeouts {
|
|
34
|
+
/** TCP + TLS/QUIC handshake timeout in seconds */
|
|
35
|
+
connect?: number;
|
|
36
|
+
/** Time-to-first-byte timeout in seconds */
|
|
37
|
+
ttfb?: number;
|
|
38
|
+
/** Maximum time between received bytes in seconds (resets on each chunk) */
|
|
39
|
+
readIdle?: number;
|
|
40
|
+
/** Maximum time between sent bytes in seconds */
|
|
41
|
+
writeIdle?: number;
|
|
42
|
+
/** Absolute deadline for entire request in seconds */
|
|
43
|
+
total?: number;
|
|
44
|
+
/** Time to wait for a pooled connection in seconds */
|
|
45
|
+
poolAcquire?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** HTTP request builder for setting headers and body. */
|
|
49
|
+
export class RequestBuilder {
|
|
50
|
+
/** Add a header to the request. Returns this for chaining. */
|
|
51
|
+
header(key: string, value: string): this;
|
|
52
|
+
/** Set all headers (replaces existing headers). Returns this for chaining. */
|
|
53
|
+
headers(headers: string[][]): this;
|
|
54
|
+
/** Set the request body as bytes. Returns this for chaining. */
|
|
55
|
+
body(body: Buffer): this;
|
|
56
|
+
/** Set the request body as JSON string and add Content-Type header. Returns this for chaining. */
|
|
57
|
+
json(jsonStr: string): this;
|
|
58
|
+
/** Set the request body as form data and add Content-Type header. Returns this for chaining. */
|
|
59
|
+
form(formStr: string): this;
|
|
60
|
+
/** Send the request and return the response. */
|
|
61
|
+
send(): Promise<Response>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** HTTP response with decompression support. */
|
|
65
|
+
export class Response {
|
|
66
|
+
/** HTTP status code */
|
|
67
|
+
get status(): number;
|
|
68
|
+
/** Response headers as an object */
|
|
69
|
+
get headers(): Record<string, string>;
|
|
70
|
+
/** Get all headers as an array of [key, value] pairs */
|
|
71
|
+
headersList(): string[][];
|
|
72
|
+
/** Get a specific header value by name */
|
|
73
|
+
getHeader(name: string): string | null;
|
|
74
|
+
/** Get the response body as text (with decompression if needed) */
|
|
75
|
+
text(): string;
|
|
76
|
+
/** Get the response body as a Buffer */
|
|
77
|
+
bytes(): Buffer;
|
|
78
|
+
/** Parse the response body as JSON and return as string. Use JSON.parse to convert to an object. */
|
|
79
|
+
json(): string;
|
|
80
|
+
/** HTTP version string */
|
|
81
|
+
get httpVersion(): string;
|
|
82
|
+
/** Effective URL (after redirects) */
|
|
83
|
+
get effectiveUrl(): string | null;
|
|
84
|
+
/** Check if the response status is successful (2xx) */
|
|
85
|
+
get isSuccess(): boolean;
|
|
86
|
+
/** Check if the response is a redirect (3xx) */
|
|
87
|
+
get isRedirect(): boolean;
|
|
88
|
+
/** Get the redirect URL from Location header if present */
|
|
89
|
+
get redirectUrl(): string | null;
|
|
90
|
+
/** Get the Content-Type header value */
|
|
91
|
+
get contentType(): string | null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Builder for creating HTTP clients. */
|
|
95
|
+
export class ClientBuilder {
|
|
96
|
+
/** Set the fingerprint profile */
|
|
97
|
+
fingerprint(profile: FingerprintProfile): this;
|
|
98
|
+
/** Set HTTP/2 preference */
|
|
99
|
+
preferHttp2(prefer: boolean): this;
|
|
100
|
+
/** Enable or disable automatic HTTP/3 upgrade via Alt-Svc headers */
|
|
101
|
+
h3Upgrade(enabled: boolean): this;
|
|
102
|
+
/** Set timeout configuration */
|
|
103
|
+
timeouts(timeouts: Timeouts): this;
|
|
104
|
+
/** Use API-optimized timeout defaults */
|
|
105
|
+
apiTimeouts(): this;
|
|
106
|
+
/** Use streaming-optimized timeout defaults */
|
|
107
|
+
streamingTimeouts(): this;
|
|
108
|
+
/** Set total request timeout in seconds */
|
|
109
|
+
totalTimeout(timeoutSecs: number): this;
|
|
110
|
+
/** Set connect timeout in seconds */
|
|
111
|
+
connectTimeout(timeoutSecs: number): this;
|
|
112
|
+
/** Set TTFB (time-to-first-byte) timeout in seconds */
|
|
113
|
+
ttfbTimeout(timeoutSecs: number): this;
|
|
114
|
+
/** Set read idle timeout in seconds */
|
|
115
|
+
readTimeout(timeoutSecs: number): this;
|
|
116
|
+
/** Skip TLS certificate verification for all connections (DANGEROUS - for testing only) */
|
|
117
|
+
dangerAcceptInvalidCerts(accept: boolean): this;
|
|
118
|
+
/** Automatically skip TLS certificate verification for localhost connections */
|
|
119
|
+
localhostAllowsInvalidCerts(allow: boolean): this;
|
|
120
|
+
/** Load root certificates from the operating system's certificate store */
|
|
121
|
+
withPlatformRoots(enabled: boolean): this;
|
|
122
|
+
/** Build the client */
|
|
123
|
+
build(): Client;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** HTTP client with TLS/HTTP2/HTTP3 fingerprint control. */
|
|
127
|
+
export class Client {
|
|
128
|
+
/** Create a GET request builder */
|
|
129
|
+
get(url: string): RequestBuilder;
|
|
130
|
+
/** Create a POST request builder */
|
|
131
|
+
post(url: string): RequestBuilder;
|
|
132
|
+
/** Create a PUT request builder */
|
|
133
|
+
put(url: string): RequestBuilder;
|
|
134
|
+
/** Create a DELETE request builder */
|
|
135
|
+
delete(url: string): RequestBuilder;
|
|
136
|
+
/** Create a PATCH request builder */
|
|
137
|
+
patch(url: string): RequestBuilder;
|
|
138
|
+
/** Create a HEAD request builder */
|
|
139
|
+
head(url: string): RequestBuilder;
|
|
140
|
+
/** Create an OPTIONS request builder */
|
|
141
|
+
options(url: string): RequestBuilder;
|
|
142
|
+
/** Create a request builder for an arbitrary HTTP method */
|
|
143
|
+
request(method: string, url: string): RequestBuilder;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Cookie jar for manual cookie management. */
|
|
147
|
+
export class CookieJar {
|
|
148
|
+
constructor();
|
|
149
|
+
/** Get the number of cookies in the jar */
|
|
150
|
+
get length(): number;
|
|
151
|
+
/** Check if the cookie jar is empty */
|
|
152
|
+
get isEmpty(): boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Create a new client builder */
|
|
156
|
+
export function clientBuilder(): ClientBuilder;
|
|
157
|
+
|
|
158
|
+
/** Sensible defaults for normal API calls. */
|
|
159
|
+
export function timeoutsApiDefaults(): Timeouts;
|
|
160
|
+
|
|
161
|
+
/** Sensible defaults for streaming responses. */
|
|
162
|
+
export function timeoutsStreamingDefaults(): Timeouts;
|
|
163
|
+
|
|
164
|
+
export {};
|
package/index.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
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
|
+
* @example
|
|
8
|
+
* const { clientBuilder, FingerprintProfile } = require('@specter/client');
|
|
9
|
+
*
|
|
10
|
+
* async function main() {
|
|
11
|
+
* // Create a client with default settings
|
|
12
|
+
* const client = clientBuilder().build();
|
|
13
|
+
*
|
|
14
|
+
* // Simple GET request
|
|
15
|
+
* const response = await client.get('https://httpbin.org/get').send();
|
|
16
|
+
* console.log(`Status: ${response.status}`);
|
|
17
|
+
* console.log(response.text());
|
|
18
|
+
*
|
|
19
|
+
* // POST with JSON body
|
|
20
|
+
* const response2 = await client.post('https://api.example.com/data')
|
|
21
|
+
* .header('Authorization', 'Bearer token')
|
|
22
|
+
* .json(JSON.stringify({ name: 'test' }))
|
|
23
|
+
* .send();
|
|
24
|
+
* console.log(JSON.parse(response2.json()));
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* main();
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const { loadBinding } = require('@napi-rs/wasm-runtime');
|
|
31
|
+
const path = require('path');
|
|
32
|
+
|
|
33
|
+
// Try to load the native binding
|
|
34
|
+
let nativeBinding;
|
|
35
|
+
|
|
36
|
+
// Platform to binary name mapping based on napi-rs naming convention
|
|
37
|
+
// Format: specter.{os}-{arch}[-{libc}].node
|
|
38
|
+
const platformBinaries = {
|
|
39
|
+
'darwin-arm64': 'specter.darwin-arm64.node',
|
|
40
|
+
'darwin-x64': 'specter.darwin-x64.node',
|
|
41
|
+
'linux-arm64-gnu': 'specter.linux-arm64-gnu.node',
|
|
42
|
+
'linux-x64-gnu': 'specter.linux-x64-gnu.node',
|
|
43
|
+
'linux-x64-musl': 'specter.linux-x64-musl.node',
|
|
44
|
+
'win32-x64-msvc': 'specter.win32-x64-msvc.node',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function getPlatformKey() {
|
|
48
|
+
const platform = process.platform;
|
|
49
|
+
const arch = process.arch;
|
|
50
|
+
|
|
51
|
+
if (platform === 'darwin') {
|
|
52
|
+
return `darwin-${arch}`;
|
|
53
|
+
}
|
|
54
|
+
if (platform === 'win32') {
|
|
55
|
+
return `win32-${arch}-msvc`;
|
|
56
|
+
}
|
|
57
|
+
if (platform === 'linux') {
|
|
58
|
+
// Check if we're on musl by looking at the libc
|
|
59
|
+
const isMusl = (() => {
|
|
60
|
+
try {
|
|
61
|
+
const { execSync } = require('child_process');
|
|
62
|
+
return execSync('ldd --version 2>&1').toString().includes('musl');
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
return `linux-${arch}-${isMusl ? 'musl' : 'gnu'}`;
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function loadNativeBinding() {
|
|
73
|
+
// Try platform-specific binary first
|
|
74
|
+
const platformKey = getPlatformKey();
|
|
75
|
+
if (platformKey && platformBinaries[platformKey]) {
|
|
76
|
+
try {
|
|
77
|
+
nativeBinding = require(`./${platformBinaries[platformKey]}`);
|
|
78
|
+
return nativeBinding;
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// Continue to fallback
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Try all known binaries
|
|
85
|
+
for (const binaryName of Object.values(platformBinaries)) {
|
|
86
|
+
try {
|
|
87
|
+
nativeBinding = require(`./${binaryName}`);
|
|
88
|
+
return nativeBinding;
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// Continue to next platform
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Try loading from build directory
|
|
95
|
+
try {
|
|
96
|
+
nativeBinding = require('./specter.node');
|
|
97
|
+
return nativeBinding;
|
|
98
|
+
} catch (e) {
|
|
99
|
+
// Fall through
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Try loading from target
|
|
103
|
+
try {
|
|
104
|
+
nativeBinding = require('./build/Release/specter.node');
|
|
105
|
+
return nativeBinding;
|
|
106
|
+
} catch (e) {
|
|
107
|
+
// Fall through
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Failed to load native binding for Specter. ` +
|
|
112
|
+
`Please ensure you've built the native module with "npm run build".`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Load the binding
|
|
117
|
+
const binding = loadNativeBinding();
|
|
118
|
+
|
|
119
|
+
// Export the native types
|
|
120
|
+
module.exports.Client = binding.Client;
|
|
121
|
+
module.exports.ClientBuilder = binding.ClientBuilder;
|
|
122
|
+
module.exports.RequestBuilder = binding.RequestBuilder;
|
|
123
|
+
module.exports.Response = binding.Response;
|
|
124
|
+
module.exports.CookieJar = binding.CookieJar;
|
|
125
|
+
module.exports.FingerprintProfile = binding.FingerprintProfile;
|
|
126
|
+
module.exports.HttpVersion = binding.HttpVersion;
|
|
127
|
+
module.exports.Timeouts = binding.Timeouts;
|
|
128
|
+
module.exports.clientBuilder = binding.clientBuilder;
|
|
129
|
+
module.exports.timeoutsApiDefaults = binding.timeoutsApiDefaults;
|
|
130
|
+
module.exports.timeoutsStreamingDefaults = binding.timeoutsStreamingDefaults;
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "specters",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Node.js bindings for Specter HTTP client with TLS/HTTP2/HTTP3 fingerprint control",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"napi": {
|
|
8
|
+
"binaryName": "specter",
|
|
9
|
+
"targets": [
|
|
10
|
+
"x86_64-apple-darwin",
|
|
11
|
+
"aarch64-apple-darwin",
|
|
12
|
+
"x86_64-unknown-linux-gnu",
|
|
13
|
+
"x86_64-unknown-linux-musl",
|
|
14
|
+
"aarch64-unknown-linux-gnu"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"index.js",
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"*.node"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "napi build --platform --release --dts index.gen.d.ts",
|
|
24
|
+
"build:debug": "napi build --platform",
|
|
25
|
+
"prepublishOnly": "napi prepublish -t npm --no-gh-release",
|
|
26
|
+
"artifacts": "napi artifacts",
|
|
27
|
+
"test": "jest"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@napi-rs/cli": "^3.0.0-alpha",
|
|
31
|
+
"jest": "^29.7.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"http",
|
|
35
|
+
"http3",
|
|
36
|
+
"fingerprint",
|
|
37
|
+
"tls",
|
|
38
|
+
"client",
|
|
39
|
+
"async",
|
|
40
|
+
"native"
|
|
41
|
+
],
|
|
42
|
+
"author": "Jared Boynton",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/jaredboynton/specter.git",
|
|
47
|
+
"directory": "bindings/node"
|
|
48
|
+
},
|
|
49
|
+
"optionalDependencies": {
|
|
50
|
+
"specters-darwin-x64": "2.0.0",
|
|
51
|
+
"specters-darwin-arm64": "2.0.0",
|
|
52
|
+
"specters-linux-x64-gnu": "2.0.0",
|
|
53
|
+
"specters-linux-x64-musl": "2.0.0",
|
|
54
|
+
"specters-linux-arm64-gnu": "2.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|