wreq-js 2.2.1 → 2.3.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/dist/wreq-js.cjs CHANGED
@@ -1,2734 +1,2205 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/wreq-js.ts
21
- var wreq_js_exports = {};
22
- __export(wreq_js_exports, {
23
- Headers: () => Headers,
24
- RequestError: () => RequestError,
25
- Response: () => Response,
26
- Session: () => Session,
27
- Transport: () => Transport,
28
- WebSocket: () => WebSocket,
29
- createSession: () => createSession,
30
- createTransport: () => createTransport,
31
- default: () => wreq_js_default,
32
- fetch: () => fetch,
33
- get: () => get,
34
- getOperatingSystems: () => getOperatingSystems,
35
- getProfiles: () => getProfiles,
36
- post: () => post,
37
- request: () => request,
38
- websocket: () => websocket,
39
- withSession: () => withSession
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
40
4
  });
41
- module.exports = __toCommonJS(wreq_js_exports);
42
- var import_node_crypto = require("crypto");
43
- var import_node_http = require("http");
44
- var import_node_module = require("module");
45
- var import_node_stream = require("stream");
46
- var import_web = require("stream/web");
47
-
48
- // src/types.ts
5
+ let node_crypto = require("node:crypto");
6
+ let node_http = require("node:http");
7
+ let node_stream = require("node:stream");
8
+ let node_stream_web = require("node:stream/web");
9
+ //#region src/native-require-cjs.ts
10
+ const nativeRequire = require;
11
+ //#endregion
12
+ //#region src/types.ts
13
+ /**
14
+ * Error thrown when a request fails. This can occur due to network errors,
15
+ * timeouts, invalid URLs, or other request-related issues.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * try {
20
+ * const response = await fetch('https://api.example.com');
21
+ * } catch (error) {
22
+ * if (error instanceof RequestError) {
23
+ * console.error('Request failed:', error.message);
24
+ * }
25
+ * }
26
+ * ```
27
+ */
49
28
  var RequestError = class extends TypeError {
50
- constructor(message) {
51
- super(message);
52
- this.name = "RequestError";
53
- }
29
+ constructor(message) {
30
+ super(message);
31
+ this.name = "RequestError";
32
+ }
54
33
  };
55
-
56
- // src/wreq-js.ts
57
- var import_meta = {};
58
- var nativeBinding;
59
- var cachedProfiles;
60
- var cachedProfileSet;
61
- var cachedOperatingSystems;
62
- var cachedOperatingSystemSet;
34
+ //#endregion
35
+ //#region src/wreq-js.ts
36
+ let nativeBinding;
37
+ let cachedProfiles;
38
+ let cachedProfileSet;
39
+ let cachedOperatingSystems;
40
+ let cachedOperatingSystemSet;
63
41
  function detectLibc() {
64
- if (process.platform !== "linux") {
65
- return void 0;
66
- }
67
- const envLibc = process.env.LIBC ?? process.env.npm_config_libc;
68
- if (envLibc) {
69
- return envLibc.toLowerCase().includes("musl") ? "musl" : "gnu";
70
- }
71
- try {
72
- const report = process.report?.getReport?.();
73
- const glibcVersion = report?.header?.glibcVersionRuntime;
74
- if (glibcVersion) {
75
- return "gnu";
76
- }
77
- return "musl";
78
- } catch {
79
- return "gnu";
80
- }
81
- }
82
- var require2 = typeof import_meta !== "undefined" && import_meta.url ? (0, import_node_module.createRequire)(import_meta.url) : (0, import_node_module.createRequire)(__filename);
83
- function requirePlatformBinary(platformArch) {
84
- switch (platformArch) {
85
- case "darwin-x64":
86
- return require2("../rust/wreq-js.darwin-x64.node");
87
- case "darwin-arm64":
88
- return require2("../rust/wreq-js.darwin-arm64.node");
89
- case "linux-x64-gnu":
90
- return require2("../rust/wreq-js.linux-x64-gnu.node");
91
- case "linux-x64-musl":
92
- return require2("../rust/wreq-js.linux-x64-musl.node");
93
- case "linux-arm64-gnu":
94
- return require2("../rust/wreq-js.linux-arm64-gnu.node");
95
- case "win32-x64-msvc":
96
- return require2("../rust/wreq-js.win32-x64-msvc.node");
97
- default:
98
- return void 0;
99
- }
42
+ if (process.platform !== "linux") return;
43
+ const envLibc = process.env.LIBC ?? process.env.npm_config_libc;
44
+ if (envLibc) return envLibc.toLowerCase().includes("musl") ? "musl" : "gnu";
45
+ try {
46
+ if ((process.report?.getReport?.())?.header?.glibcVersionRuntime) return "gnu";
47
+ return "musl";
48
+ } catch {
49
+ return "gnu";
50
+ }
100
51
  }
101
52
  function loadNativeBinding() {
102
- const platform = process.platform;
103
- const arch = process.arch;
104
- const libc = detectLibc();
105
- const platformArchMap = {
106
- darwin: { x64: "darwin-x64", arm64: "darwin-arm64" },
107
- linux: {
108
- x64: { gnu: "linux-x64-gnu", musl: "linux-x64-musl" },
109
- arm64: "linux-arm64-gnu"
110
- },
111
- win32: { x64: "win32-x64-msvc" }
112
- };
113
- const platformArchMapEntry = platformArchMap[platform]?.[arch];
114
- const platformArch = typeof platformArchMapEntry === "string" ? platformArchMapEntry : platformArchMapEntry?.[libc ?? "gnu"];
115
- if (!platformArch) {
116
- throw new Error(
117
- `Unsupported platform: ${platform}-${arch}${libc ? `-${libc}` : ""}. Supported platforms: darwin-x64, darwin-arm64, linux-x64-gnu, linux-x64-musl, linux-arm64-gnu, win32-x64-msvc`
118
- );
119
- }
120
- const binaryName = `wreq-js.${platformArch}.node`;
121
- try {
122
- const platformBinding = requirePlatformBinary(platformArch);
123
- if (platformBinding) {
124
- return platformBinding;
125
- }
126
- } catch {
127
- }
128
- try {
129
- return require2("../rust/wreq-js.node");
130
- } catch {
131
- throw new Error(
132
- `Failed to load native module for ${platform}-${arch}. Tried: ../rust/${binaryName} and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.`
133
- );
134
- }
53
+ const platform = process.platform;
54
+ const arch = process.arch;
55
+ const libc = detectLibc();
56
+ if (platform === "darwin" && arch === "x64") try {
57
+ return nativeRequire("../rust/wreq-js.darwin-x64.node");
58
+ } catch {
59
+ try {
60
+ return nativeRequire("../rust/wreq-js.node");
61
+ } catch {
62
+ throw new Error("Failed to load native module for darwin-x64. Tried: ../rust/wreq-js.darwin-x64.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
63
+ }
64
+ }
65
+ if (platform === "darwin" && arch === "arm64") try {
66
+ return nativeRequire("../rust/wreq-js.darwin-arm64.node");
67
+ } catch {
68
+ try {
69
+ return nativeRequire("../rust/wreq-js.node");
70
+ } catch {
71
+ throw new Error("Failed to load native module for darwin-arm64. Tried: ../rust/wreq-js.darwin-arm64.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
72
+ }
73
+ }
74
+ if (platform === "linux" && arch === "x64") {
75
+ if (libc === "musl") try {
76
+ return nativeRequire("../rust/wreq-js.linux-x64-musl.node");
77
+ } catch {
78
+ try {
79
+ return nativeRequire("../rust/wreq-js.node");
80
+ } catch {
81
+ throw new Error("Failed to load native module for linux-x64-musl. Tried: ../rust/wreq-js.linux-x64-musl.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
82
+ }
83
+ }
84
+ try {
85
+ return nativeRequire("../rust/wreq-js.linux-x64-gnu.node");
86
+ } catch {
87
+ try {
88
+ return nativeRequire("../rust/wreq-js.node");
89
+ } catch {
90
+ throw new Error("Failed to load native module for linux-x64-gnu. Tried: ../rust/wreq-js.linux-x64-gnu.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
91
+ }
92
+ }
93
+ }
94
+ if (platform === "linux" && arch === "arm64") try {
95
+ return nativeRequire("../rust/wreq-js.linux-arm64-gnu.node");
96
+ } catch {
97
+ try {
98
+ return nativeRequire("../rust/wreq-js.node");
99
+ } catch {
100
+ throw new Error("Failed to load native module for linux-arm64-gnu. Tried: ../rust/wreq-js.linux-arm64-gnu.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
101
+ }
102
+ }
103
+ if (platform === "win32" && arch === "x64") try {
104
+ return nativeRequire("../rust/wreq-js.win32-x64-msvc.node");
105
+ } catch {
106
+ try {
107
+ return nativeRequire("../rust/wreq-js.node");
108
+ } catch {
109
+ throw new Error("Failed to load native module for win32-x64-msvc. Tried: ../rust/wreq-js.win32-x64-msvc.node and ../rust/wreq-js.node. Make sure the package is installed correctly and the native module is built for your platform.");
110
+ }
111
+ }
112
+ throw new Error(`Unsupported platform: ${platform}-${arch}${libc ? `-${libc}` : ""}. Supported platforms: darwin-x64, darwin-arm64, linux-x64-gnu, linux-x64-musl, linux-arm64-gnu, win32-x64-msvc`);
135
113
  }
136
114
  nativeBinding = loadNativeBinding();
137
- var websocketFinalizer = typeof FinalizationRegistry === "function" ? new FinalizationRegistry((connection) => {
138
- void nativeBinding.websocketClose(connection).catch(() => void 0);
115
+ const websocketFinalizer = typeof FinalizationRegistry === "function" ? new FinalizationRegistry((connection) => {
116
+ nativeBinding.websocketClose(connection).catch(() => void 0);
139
117
  }) : void 0;
140
- var bodyHandleFinalizer = typeof FinalizationRegistry === "function" ? new FinalizationRegistry((handle) => {
141
- if (handle.released) {
142
- return;
143
- }
144
- handle.released = true;
145
- try {
146
- nativeBinding.cancelBody(handle.id);
147
- } catch {
148
- }
118
+ const bodyHandleFinalizer = typeof FinalizationRegistry === "function" ? new FinalizationRegistry((handle) => {
119
+ if (handle.released) return;
120
+ handle.released = true;
121
+ try {
122
+ nativeBinding.cancelBody(handle.id);
123
+ } catch {}
149
124
  }) : void 0;
150
- var DEFAULT_BROWSER = "chrome_142";
151
- var DEFAULT_OS = "macos";
152
- var DEFAULT_REQUEST_TIMEOUT_MS = 3e5;
153
- var SUPPORTED_OSES = ["windows", "macos", "linux", "android", "ios"];
154
- var UTF8_DECODER = new TextDecoder("utf-8");
155
- var ephemeralIdCounter = 0;
125
+ const DEFAULT_BROWSER = "chrome_142";
126
+ const DEFAULT_OS = "macos";
127
+ const DEFAULT_REQUEST_TIMEOUT_MS = 3e5;
128
+ const DEFAULT_TRUST_STORE = "combined";
129
+ const SUPPORTED_OSES = [
130
+ "windows",
131
+ "macos",
132
+ "linux",
133
+ "android",
134
+ "ios"
135
+ ];
136
+ const UTF8_DECODER = new TextDecoder("utf-8");
137
+ let ephemeralIdCounter = 0;
156
138
  function generateEphemeralSessionId() {
157
- return `_e${++ephemeralIdCounter}`;
139
+ return `_e${++ephemeralIdCounter}`;
158
140
  }
159
141
  function generateSessionId() {
160
- return (0, import_node_crypto.randomUUID)();
142
+ return (0, node_crypto.randomUUID)();
161
143
  }
162
144
  function normalizeSessionOptions(options) {
163
- const sessionId = options?.sessionId ?? generateSessionId();
164
- const defaults = {
165
- transportMode: resolveEmulationMode(options?.browser, options?.os, options?.emulation)
166
- };
167
- if (options?.proxy !== void 0) {
168
- defaults.proxy = options.proxy;
169
- }
170
- if (options?.timeout !== void 0) {
171
- validateTimeout(options.timeout);
172
- defaults.timeout = options.timeout;
173
- }
174
- if (options?.insecure !== void 0) {
175
- defaults.insecure = options.insecure;
176
- }
177
- if (options?.defaultHeaders !== void 0) {
178
- defaults.defaultHeaders = headersToTuples(options.defaultHeaders);
179
- }
180
- return { sessionId, defaults };
145
+ const sessionId = options?.sessionId ?? generateSessionId();
146
+ const defaults = {
147
+ transportMode: resolveEmulationMode(options?.browser, options?.os, options?.emulation),
148
+ trustStore: DEFAULT_TRUST_STORE
149
+ };
150
+ if (options?.proxy !== void 0) defaults.proxy = options.proxy;
151
+ if (options?.timeout !== void 0) {
152
+ validateTimeout(options.timeout);
153
+ defaults.timeout = options.timeout;
154
+ }
155
+ if (options?.insecure !== void 0) defaults.insecure = options.insecure;
156
+ if (options?.trustStore !== void 0) {
157
+ validateTrustStore(options.trustStore);
158
+ defaults.trustStore = options.trustStore;
159
+ }
160
+ if (options?.defaultHeaders !== void 0) defaults.defaultHeaders = headersToTuples(options.defaultHeaders);
161
+ if (options?.captureDiagnostics !== void 0) defaults.captureDiagnostics = options.captureDiagnostics;
162
+ return {
163
+ sessionId,
164
+ defaults
165
+ };
181
166
  }
182
167
  function isIterable(value) {
183
- return Boolean(value) && typeof value[Symbol.iterator] === "function";
168
+ return Boolean(value) && typeof value[Symbol.iterator] === "function";
184
169
  }
185
170
  function isPlainObject(value) {
186
- if (typeof value !== "object" || value === null) {
187
- return false;
188
- }
189
- const proto = Object.getPrototypeOf(value);
190
- return proto === Object.prototype || proto === null;
171
+ if (typeof value !== "object" || value === null) return false;
172
+ const proto = Object.getPrototypeOf(value);
173
+ return proto === Object.prototype || proto === null;
191
174
  }
192
175
  function coerceHeaderValue(value) {
193
- return String(value);
194
- }
195
- var Headers = class _Headers {
196
- store = /* @__PURE__ */ new Map();
197
- constructor(init) {
198
- if (init) {
199
- this.applyInit(init);
200
- }
201
- }
202
- applyInit(init) {
203
- if (init instanceof _Headers) {
204
- for (const [name, value] of init) {
205
- this.append(name, value);
206
- }
207
- return;
208
- }
209
- if (Array.isArray(init) || isIterable(init)) {
210
- for (const tuple of init) {
211
- if (!tuple) {
212
- continue;
213
- }
214
- const [name, value] = tuple;
215
- this.append(name, value);
216
- }
217
- return;
218
- }
219
- if (isPlainObject(init)) {
220
- for (const [name, value] of Object.entries(init)) {
221
- if (value === void 0 || value === null) {
222
- continue;
223
- }
224
- this.set(name, coerceHeaderValue(value));
225
- }
226
- }
227
- }
228
- normalizeName(name) {
229
- if (typeof name !== "string") {
230
- throw new TypeError("Header name must be a string");
231
- }
232
- const trimmed = name.trim();
233
- if (!trimmed) {
234
- throw new TypeError("Header name must not be empty");
235
- }
236
- return { key: trimmed.toLowerCase(), display: trimmed };
237
- }
238
- assertValue(value) {
239
- if (value === void 0 || value === null) {
240
- throw new TypeError("Header value must not be null or undefined");
241
- }
242
- return coerceHeaderValue(value);
243
- }
244
- append(name, value) {
245
- const normalized = this.normalizeName(name);
246
- const existing = this.store.get(normalized.key);
247
- const coercedValue = this.assertValue(value);
248
- if (existing) {
249
- existing.values.push(coercedValue);
250
- return;
251
- }
252
- this.store.set(normalized.key, {
253
- name: normalized.display,
254
- values: [coercedValue]
255
- });
256
- }
257
- set(name, value) {
258
- const normalized = this.normalizeName(name);
259
- const coercedValue = this.assertValue(value);
260
- this.store.set(normalized.key, {
261
- name: normalized.display,
262
- values: [coercedValue]
263
- });
264
- }
265
- get(name) {
266
- const normalized = this.normalizeName(name);
267
- const entry = this.store.get(normalized.key);
268
- return entry ? entry.values.join(", ") : null;
269
- }
270
- has(name) {
271
- const normalized = this.normalizeName(name);
272
- return this.store.has(normalized.key);
273
- }
274
- delete(name) {
275
- const normalized = this.normalizeName(name);
276
- this.store.delete(normalized.key);
277
- }
278
- entries() {
279
- return this[Symbol.iterator]();
280
- }
281
- *keys() {
282
- for (const [name] of this) {
283
- yield name;
284
- }
285
- }
286
- *values() {
287
- for (const [, value] of this) {
288
- yield value;
289
- }
290
- }
291
- forEach(callback, thisArg) {
292
- for (const [name, value] of this) {
293
- callback.call(thisArg, value, name, this);
294
- }
295
- }
296
- [Symbol.iterator]() {
297
- const generator = function* (store) {
298
- for (const entry of store.values()) {
299
- yield [entry.name, entry.values.join(", ")];
300
- }
301
- };
302
- return generator(this.store);
303
- }
304
- toObject() {
305
- const result = {};
306
- for (const [name, value] of this) {
307
- result[name] = value;
308
- }
309
- return result;
310
- }
311
- toTuples() {
312
- const result = [];
313
- for (const [name, value] of this) {
314
- result.push([name, value]);
315
- }
316
- return result;
317
- }
176
+ return String(value);
177
+ }
178
+ var Headers = class Headers {
179
+ store = /* @__PURE__ */ new Map();
180
+ constructor(init) {
181
+ if (init) this.applyInit(init);
182
+ }
183
+ applyInit(init) {
184
+ if (init instanceof Headers) {
185
+ for (const [name, value] of init) this.append(name, value);
186
+ return;
187
+ }
188
+ if (Array.isArray(init) || isIterable(init)) {
189
+ for (const tuple of init) {
190
+ if (!tuple) continue;
191
+ const [name, value] = tuple;
192
+ this.append(name, value);
193
+ }
194
+ return;
195
+ }
196
+ if (isPlainObject(init)) for (const [name, value] of Object.entries(init)) {
197
+ if (value === void 0 || value === null) continue;
198
+ this.set(name, coerceHeaderValue(value));
199
+ }
200
+ }
201
+ normalizeName(name) {
202
+ if (typeof name !== "string") throw new TypeError("Header name must be a string");
203
+ const trimmed = name.trim();
204
+ if (!trimmed) throw new TypeError("Header name must not be empty");
205
+ return {
206
+ key: trimmed.toLowerCase(),
207
+ display: trimmed
208
+ };
209
+ }
210
+ assertValue(value) {
211
+ if (value === void 0 || value === null) throw new TypeError("Header value must not be null or undefined");
212
+ return coerceHeaderValue(value);
213
+ }
214
+ append(name, value) {
215
+ const normalized = this.normalizeName(name);
216
+ const existing = this.store.get(normalized.key);
217
+ const coercedValue = this.assertValue(value);
218
+ if (existing) {
219
+ existing.values.push(coercedValue);
220
+ return;
221
+ }
222
+ this.store.set(normalized.key, {
223
+ name: normalized.display,
224
+ values: [coercedValue]
225
+ });
226
+ }
227
+ set(name, value) {
228
+ const normalized = this.normalizeName(name);
229
+ const coercedValue = this.assertValue(value);
230
+ this.store.set(normalized.key, {
231
+ name: normalized.display,
232
+ values: [coercedValue]
233
+ });
234
+ }
235
+ get(name) {
236
+ const normalized = this.normalizeName(name);
237
+ const entry = this.store.get(normalized.key);
238
+ return entry ? entry.values.join(", ") : null;
239
+ }
240
+ has(name) {
241
+ const normalized = this.normalizeName(name);
242
+ return this.store.has(normalized.key);
243
+ }
244
+ delete(name) {
245
+ const normalized = this.normalizeName(name);
246
+ this.store.delete(normalized.key);
247
+ }
248
+ entries() {
249
+ return this[Symbol.iterator]();
250
+ }
251
+ *keys() {
252
+ for (const [name] of this) yield name;
253
+ }
254
+ *values() {
255
+ for (const [, value] of this) yield value;
256
+ }
257
+ forEach(callback, thisArg) {
258
+ for (const [name, value] of this) callback.call(thisArg, value, name, this);
259
+ }
260
+ [Symbol.iterator]() {
261
+ const generator = function* (store) {
262
+ for (const entry of store.values()) yield [entry.name, entry.values.join(", ")];
263
+ };
264
+ return generator(this.store);
265
+ }
266
+ toObject() {
267
+ const result = {};
268
+ for (const [name, value] of this) result[name] = value;
269
+ return result;
270
+ }
271
+ toTuples() {
272
+ const result = [];
273
+ for (const [name, value] of this) result.push([name, value]);
274
+ return result;
275
+ }
318
276
  };
319
277
  function headersToTuples(init) {
320
- return new Headers(init).toTuples();
278
+ return new Headers(init).toTuples();
321
279
  }
322
280
  function hasHeaderName(tuples, name) {
323
- if (!tuples) {
324
- return false;
325
- }
326
- const target = name.toLowerCase();
327
- for (const [headerName] of tuples) {
328
- if (headerName.toLowerCase() === target) {
329
- return true;
330
- }
331
- }
332
- return false;
281
+ if (!tuples) return false;
282
+ const target = name.toLowerCase();
283
+ for (const [headerName] of tuples) if (headerName.toLowerCase() === target) return true;
284
+ return false;
333
285
  }
334
286
  function hasWebSocketProtocolHeader(headers) {
335
- const protocolHeaderName = "Sec-WebSocket-Protocol";
336
- if (!headers) {
337
- return false;
338
- }
339
- return hasHeaderName(headersToTuples(headers), protocolHeaderName);
287
+ const protocolHeaderName = "Sec-WebSocket-Protocol";
288
+ if (!headers) return false;
289
+ return hasHeaderName(headersToTuples(headers), protocolHeaderName);
340
290
  }
341
291
  function assertNoManualWebSocketProtocolHeader(headers) {
342
- if (hasWebSocketProtocolHeader(headers)) {
343
- throw new RequestError("Do not set `Sec-WebSocket-Protocol` header manually; use the `protocols` option instead.");
344
- }
292
+ if (hasWebSocketProtocolHeader(headers)) throw new RequestError("Do not set `Sec-WebSocket-Protocol` header manually; use the `protocols` option instead.");
345
293
  }
346
294
  function normalizeWebSocketProtocolList(protocols) {
347
- if (protocols === void 0) {
348
- return void 0;
349
- }
350
- return typeof protocols === "string" ? [protocols] : [...protocols];
295
+ if (protocols === void 0) return;
296
+ return typeof protocols === "string" ? [protocols] : [...protocols];
351
297
  }
352
298
  function mergeHeaderTuples(defaults, overrides) {
353
- if (!defaults) {
354
- return overrides === void 0 ? void 0 : headersToTuples(overrides);
355
- }
356
- if (overrides === void 0) {
357
- return defaults;
358
- }
359
- const overrideTuples = headersToTuples(overrides);
360
- if (overrideTuples.length === 0) {
361
- return defaults;
362
- }
363
- const overrideKeys = /* @__PURE__ */ new Set();
364
- for (const tuple of overrideTuples) {
365
- overrideKeys.add(tuple[0].toLowerCase());
366
- }
367
- const merged = [];
368
- for (const tuple of defaults) {
369
- if (!overrideKeys.has(tuple[0].toLowerCase())) {
370
- merged.push(tuple);
371
- }
372
- }
373
- for (const tuple of overrideTuples) {
374
- merged.push(tuple);
375
- }
376
- return merged;
299
+ if (!defaults) return overrides === void 0 ? void 0 : headersToTuples(overrides);
300
+ if (overrides === void 0) return defaults;
301
+ const overrideTuples = headersToTuples(overrides);
302
+ if (overrideTuples.length === 0) return defaults;
303
+ const overrideKeys = /* @__PURE__ */ new Set();
304
+ for (const tuple of overrideTuples) overrideKeys.add(tuple[0].toLowerCase());
305
+ const merged = [];
306
+ for (const tuple of defaults) if (!overrideKeys.has(tuple[0].toLowerCase())) merged.push(tuple);
307
+ for (const tuple of overrideTuples) merged.push(tuple);
308
+ return merged;
377
309
  }
378
310
  function cloneNativeResponse(payload) {
379
- return {
380
- status: payload.status,
381
- headers: payload.headers.map(([name, value]) => [name, value]),
382
- bodyHandle: payload.bodyHandle,
383
- bodyBytes: payload.bodyBytes,
384
- contentLength: payload.contentLength,
385
- cookies: payload.cookies.map(([name, value]) => [name, value]),
386
- url: payload.url
387
- };
311
+ return {
312
+ status: payload.status,
313
+ headers: payload.headers.map(([name, value]) => [name, value]),
314
+ bodyHandle: payload.bodyHandle,
315
+ bodyBytes: payload.bodyBytes,
316
+ contentLength: payload.contentLength,
317
+ cookies: payload.cookies.map(([name, value]) => [name, value]),
318
+ url: payload.url,
319
+ diagnostics: payload.diagnostics ? { ...payload.diagnostics } : null
320
+ };
388
321
  }
389
322
  function releaseNativeBody(handle) {
390
- if (handle.released) {
391
- return;
392
- }
393
- handle.released = true;
394
- try {
395
- nativeBinding.cancelBody(handle.id);
396
- } catch {
397
- }
398
- bodyHandleFinalizer?.unregister(handle);
323
+ if (handle.released) return;
324
+ handle.released = true;
325
+ try {
326
+ nativeBinding.cancelBody(handle.id);
327
+ } catch {}
328
+ bodyHandleFinalizer?.unregister(handle);
399
329
  }
400
330
  function markNativeBodyReleased(handle) {
401
- if (handle.released) {
402
- return;
403
- }
404
- handle.released = true;
405
- bodyHandleFinalizer?.unregister(handle);
331
+ if (handle.released) return;
332
+ handle.released = true;
333
+ bodyHandleFinalizer?.unregister(handle);
406
334
  }
407
335
  function createNativeBodyStream(handle) {
408
- const stream = new import_web.ReadableStream({
409
- async pull(controller) {
410
- try {
411
- const chunk = await nativeBinding.readBodyChunk(handle.id);
412
- if (chunk === null) {
413
- releaseNativeBody(handle);
414
- controller.close();
415
- return;
416
- }
417
- controller.enqueue(chunk);
418
- } catch (error) {
419
- releaseNativeBody(handle);
420
- controller.error(error);
421
- }
422
- },
423
- cancel() {
424
- releaseNativeBody(handle);
425
- }
426
- });
427
- bodyHandleFinalizer?.register(stream, handle, handle);
428
- return stream;
336
+ const stream = new node_stream_web.ReadableStream({
337
+ async pull(controller) {
338
+ try {
339
+ const chunk = await nativeBinding.readBodyChunk(handle.id);
340
+ if (chunk === null) {
341
+ releaseNativeBody(handle);
342
+ controller.close();
343
+ return;
344
+ }
345
+ controller.enqueue(chunk);
346
+ } catch (error) {
347
+ releaseNativeBody(handle);
348
+ controller.error(error);
349
+ }
350
+ },
351
+ cancel() {
352
+ releaseNativeBody(handle);
353
+ }
354
+ });
355
+ bodyHandleFinalizer?.register(stream, handle, handle);
356
+ return stream;
429
357
  }
430
358
  function wrapBodyStream(source, onFirstUse) {
431
- let started = false;
432
- let reader = null;
433
- return new import_web.ReadableStream({
434
- async pull(controller) {
435
- if (!started) {
436
- started = true;
437
- onFirstUse();
438
- }
439
- if (!reader) {
440
- reader = source.getReader();
441
- }
442
- try {
443
- const { done, value } = await reader.read();
444
- if (done) {
445
- controller.close();
446
- return;
447
- }
448
- controller.enqueue(value);
449
- } catch (error) {
450
- controller.error(error);
451
- }
452
- },
453
- cancel(reason) {
454
- if (!reader) {
455
- return source.cancel(reason);
456
- }
457
- return reader.cancel(reason);
458
- }
459
- });
460
- }
461
- var Response = class _Response {
462
- status;
463
- ok;
464
- contentLength;
465
- url;
466
- type = "basic";
467
- bodyUsed = false;
468
- payload;
469
- requestUrl;
470
- redirectedMemo;
471
- headersInit;
472
- headersInstance;
473
- cookiesInit;
474
- cookiesRecord;
475
- inlineBody;
476
- bodySource;
477
- bodyStream;
478
- // Track if we can use the fast path (native handle not yet wrapped in a stream)
479
- nativeHandleAvailable;
480
- nativeHandle;
481
- constructor(payload, requestUrl, bodySource) {
482
- this.payload = payload;
483
- this.requestUrl = requestUrl;
484
- this.status = this.payload.status;
485
- this.ok = this.status >= 200 && this.status < 300;
486
- this.headersInit = this.payload.headers;
487
- this.headersInstance = null;
488
- this.url = this.payload.url;
489
- this.cookiesInit = this.payload.cookies;
490
- this.cookiesRecord = null;
491
- this.contentLength = this.payload.contentLength ?? null;
492
- this.inlineBody = this.payload.bodyBytes ?? null;
493
- this.nativeHandle = null;
494
- if (typeof bodySource !== "undefined") {
495
- this.bodySource = bodySource;
496
- this.nativeHandleAvailable = false;
497
- } else if (this.inlineBody !== null) {
498
- this.bodySource = null;
499
- this.nativeHandleAvailable = false;
500
- } else if (this.payload.bodyHandle !== null) {
501
- this.bodySource = null;
502
- this.nativeHandleAvailable = true;
503
- this.nativeHandle = { id: this.payload.bodyHandle, released: false };
504
- bodyHandleFinalizer?.register(this, this.nativeHandle, this.nativeHandle);
505
- } else {
506
- this.bodySource = null;
507
- this.nativeHandleAvailable = false;
508
- }
509
- this.bodyStream = void 0;
510
- }
511
- get redirected() {
512
- if (this.redirectedMemo !== void 0) {
513
- return this.redirectedMemo;
514
- }
515
- if (this.url === this.requestUrl) {
516
- this.redirectedMemo = false;
517
- return false;
518
- }
519
- const normalizedRequestUrl = normalizeUrlForComparison(this.requestUrl);
520
- this.redirectedMemo = normalizedRequestUrl ? this.url !== normalizedRequestUrl : true;
521
- return this.redirectedMemo;
522
- }
523
- get statusText() {
524
- return import_node_http.STATUS_CODES[this.status] ?? "";
525
- }
526
- get headers() {
527
- if (!this.headersInstance) {
528
- this.headersInstance = new Headers(this.headersInit);
529
- }
530
- return this.headersInstance;
531
- }
532
- get cookies() {
533
- if (!this.cookiesRecord) {
534
- const record = /* @__PURE__ */ Object.create(null);
535
- for (const [name, value] of this.cookiesInit) {
536
- const existing = record[name];
537
- if (existing === void 0) {
538
- record[name] = value;
539
- } else if (Array.isArray(existing)) {
540
- existing.push(value);
541
- } else {
542
- record[name] = [existing, value];
543
- }
544
- }
545
- this.cookiesRecord = record;
546
- }
547
- return this.cookiesRecord;
548
- }
549
- get body() {
550
- if (this.inlineBody && this.bodySource === null) {
551
- const bytes = this.inlineBody;
552
- this.inlineBody = null;
553
- this.bodySource = new import_web.ReadableStream({
554
- start(controller) {
555
- controller.enqueue(bytes);
556
- controller.close();
557
- }
558
- });
559
- }
560
- if (this.inlineBody === null && this.payload.bodyHandle === null && this.bodySource === null) {
561
- return null;
562
- }
563
- if (this.bodySource === null && this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
564
- if (this.nativeHandle) {
565
- bodyHandleFinalizer?.unregister(this.nativeHandle);
566
- }
567
- const handle = this.nativeHandle ?? { id: this.payload.bodyHandle, released: false };
568
- this.nativeHandle = handle;
569
- this.bodySource = createNativeBodyStream(handle);
570
- this.nativeHandleAvailable = false;
571
- }
572
- if (this.bodySource === null) {
573
- return null;
574
- }
575
- if (this.bodyStream === void 0) {
576
- this.bodyStream = wrapBodyStream(this.bodySource, () => {
577
- this.bodyUsed = true;
578
- });
579
- }
580
- return this.bodyStream;
581
- }
582
- async json() {
583
- const text = await this.text();
584
- return JSON.parse(text);
585
- }
586
- async arrayBuffer() {
587
- const bytes = await this.consumeBody();
588
- const { buffer, byteOffset, byteLength } = bytes;
589
- if (buffer instanceof ArrayBuffer) {
590
- if (byteOffset === 0 && byteLength === buffer.byteLength) {
591
- return buffer;
592
- }
593
- return buffer.slice(byteOffset, byteOffset + byteLength);
594
- }
595
- const view = new Uint8Array(byteLength);
596
- view.set(bytes);
597
- return view.buffer;
598
- }
599
- async text() {
600
- const bytes = await this.consumeBody();
601
- return UTF8_DECODER.decode(bytes);
602
- }
603
- async blob() {
604
- const bytes = await this.consumeBody();
605
- const contentType = this.headers.get("content-type") ?? "";
606
- return new Blob([bytes], contentType ? { type: contentType } : void 0);
607
- }
608
- async formData() {
609
- const bytes = await this.consumeBody();
610
- const contentType = this.headers.get("content-type");
611
- const response = new globalThis.Response(
612
- bytes,
613
- contentType ? { headers: { "content-type": contentType } } : void 0
614
- );
615
- return response.formData();
616
- }
617
- readable() {
618
- this.assertBodyAvailable();
619
- this.bodyUsed = true;
620
- const stream = this.body;
621
- if (stream === null) {
622
- return import_node_stream.Readable.from([]);
623
- }
624
- return import_node_stream.Readable.fromWeb(stream);
625
- }
626
- clone() {
627
- if (this.bodyUsed) {
628
- throw new TypeError("Cannot clone a Response whose body is already used");
629
- }
630
- if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
631
- if (this.nativeHandle) {
632
- bodyHandleFinalizer?.unregister(this.nativeHandle);
633
- }
634
- const handle = this.nativeHandle ?? { id: this.payload.bodyHandle, released: false };
635
- this.nativeHandle = handle;
636
- this.bodySource = createNativeBodyStream(handle);
637
- this.nativeHandleAvailable = false;
638
- }
639
- if (this.bodySource === null) {
640
- return new _Response(cloneNativeResponse(this.payload), this.requestUrl, null);
641
- }
642
- const [branchA, branchB] = this.bodySource.tee();
643
- this.bodySource = branchA;
644
- this.bodyStream = void 0;
645
- return new _Response(cloneNativeResponse(this.payload), this.requestUrl, branchB);
646
- }
647
- assertBodyAvailable() {
648
- if (this.bodyUsed) {
649
- throw new TypeError("Response body is already used");
650
- }
651
- }
652
- async consumeBody() {
653
- this.assertBodyAvailable();
654
- this.bodyUsed = true;
655
- if (this.inlineBody) {
656
- const bytes = this.inlineBody;
657
- this.inlineBody = null;
658
- return bytes;
659
- }
660
- if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
661
- this.nativeHandleAvailable = false;
662
- try {
663
- return await nativeBinding.readBodyAll(this.payload.bodyHandle);
664
- } catch (error) {
665
- if (String(error).includes("Body handle") && String(error).includes("not found")) {
666
- return Buffer.alloc(0);
667
- }
668
- throw error;
669
- } finally {
670
- if (this.nativeHandle) {
671
- markNativeBodyReleased(this.nativeHandle);
672
- }
673
- }
674
- }
675
- const stream = this.body;
676
- if (!stream) {
677
- return Buffer.alloc(0);
678
- }
679
- const reader = stream.getReader();
680
- const chunks = [];
681
- try {
682
- while (true) {
683
- const { done, value } = await reader.read();
684
- if (done) {
685
- break;
686
- }
687
- if (value && value.byteLength > 0) {
688
- if (Buffer.isBuffer(value)) {
689
- chunks.push(value);
690
- } else {
691
- chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
692
- }
693
- }
694
- }
695
- } finally {
696
- }
697
- return chunks.length === 0 ? Buffer.alloc(0) : Buffer.concat(chunks);
698
- }
359
+ let started = false;
360
+ let reader = null;
361
+ return new node_stream_web.ReadableStream({
362
+ async pull(controller) {
363
+ if (!started) {
364
+ started = true;
365
+ onFirstUse();
366
+ }
367
+ if (!reader) reader = source.getReader();
368
+ try {
369
+ const { done, value } = await reader.read();
370
+ if (done) {
371
+ controller.close();
372
+ return;
373
+ }
374
+ controller.enqueue(value);
375
+ } catch (error) {
376
+ controller.error(error);
377
+ }
378
+ },
379
+ cancel(reason) {
380
+ if (!reader) return source.cancel(reason);
381
+ return reader.cancel(reason);
382
+ }
383
+ });
384
+ }
385
+ var Response = class Response {
386
+ status;
387
+ ok;
388
+ contentLength;
389
+ url;
390
+ diagnostics;
391
+ type = "basic";
392
+ bodyUsed = false;
393
+ payload;
394
+ requestUrl;
395
+ redirectedMemo;
396
+ headersInit;
397
+ headersInstance;
398
+ cookiesInit;
399
+ cookiesRecord;
400
+ inlineBody;
401
+ bodySource;
402
+ bodyStream;
403
+ nativeHandleAvailable;
404
+ nativeHandle;
405
+ constructor(payload, requestUrl, bodySource) {
406
+ this.payload = payload;
407
+ this.requestUrl = requestUrl;
408
+ this.status = this.payload.status;
409
+ this.ok = this.status >= 200 && this.status < 300;
410
+ this.headersInit = this.payload.headers;
411
+ this.headersInstance = null;
412
+ this.url = this.payload.url;
413
+ this.diagnostics = this.payload.diagnostics ?? null;
414
+ this.cookiesInit = this.payload.cookies;
415
+ this.cookiesRecord = null;
416
+ this.contentLength = this.payload.contentLength ?? null;
417
+ this.inlineBody = this.payload.bodyBytes ?? null;
418
+ this.nativeHandle = null;
419
+ if (typeof bodySource !== "undefined") {
420
+ this.bodySource = bodySource;
421
+ this.nativeHandleAvailable = false;
422
+ } else if (this.inlineBody !== null) {
423
+ this.bodySource = null;
424
+ this.nativeHandleAvailable = false;
425
+ } else if (this.payload.bodyHandle !== null) {
426
+ this.bodySource = null;
427
+ this.nativeHandleAvailable = true;
428
+ this.nativeHandle = {
429
+ id: this.payload.bodyHandle,
430
+ released: false
431
+ };
432
+ bodyHandleFinalizer?.register(this, this.nativeHandle, this.nativeHandle);
433
+ } else {
434
+ this.bodySource = null;
435
+ this.nativeHandleAvailable = false;
436
+ }
437
+ this.bodyStream = void 0;
438
+ }
439
+ get redirected() {
440
+ if (this.redirectedMemo !== void 0) return this.redirectedMemo;
441
+ if (this.url === this.requestUrl) {
442
+ this.redirectedMemo = false;
443
+ return false;
444
+ }
445
+ const normalizedRequestUrl = normalizeUrlForComparison(this.requestUrl);
446
+ this.redirectedMemo = normalizedRequestUrl ? this.url !== normalizedRequestUrl : true;
447
+ return this.redirectedMemo;
448
+ }
449
+ get statusText() {
450
+ return node_http.STATUS_CODES[this.status] ?? "";
451
+ }
452
+ get headers() {
453
+ if (!this.headersInstance) this.headersInstance = new Headers(this.headersInit);
454
+ return this.headersInstance;
455
+ }
456
+ get cookies() {
457
+ if (!this.cookiesRecord) {
458
+ const record = Object.create(null);
459
+ for (const [name, value] of this.cookiesInit) {
460
+ const existing = record[name];
461
+ if (existing === void 0) record[name] = value;
462
+ else if (Array.isArray(existing)) existing.push(value);
463
+ else record[name] = [existing, value];
464
+ }
465
+ this.cookiesRecord = record;
466
+ }
467
+ return this.cookiesRecord;
468
+ }
469
+ get body() {
470
+ if (this.inlineBody && this.bodySource === null) {
471
+ const bytes = this.inlineBody;
472
+ this.inlineBody = null;
473
+ this.bodySource = new node_stream_web.ReadableStream({ start(controller) {
474
+ controller.enqueue(bytes);
475
+ controller.close();
476
+ } });
477
+ }
478
+ if (this.inlineBody === null && this.payload.bodyHandle === null && this.bodySource === null) return null;
479
+ if (this.bodySource === null && this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
480
+ if (this.nativeHandle) bodyHandleFinalizer?.unregister(this.nativeHandle);
481
+ const handle = this.nativeHandle ?? {
482
+ id: this.payload.bodyHandle,
483
+ released: false
484
+ };
485
+ this.nativeHandle = handle;
486
+ this.bodySource = createNativeBodyStream(handle);
487
+ this.nativeHandleAvailable = false;
488
+ }
489
+ if (this.bodySource === null) return null;
490
+ if (this.bodyStream === void 0) this.bodyStream = wrapBodyStream(this.bodySource, () => {
491
+ this.bodyUsed = true;
492
+ });
493
+ return this.bodyStream;
494
+ }
495
+ async json() {
496
+ const text = await this.text();
497
+ return JSON.parse(text);
498
+ }
499
+ async arrayBuffer() {
500
+ const bytes = await this.consumeBody();
501
+ const { buffer, byteOffset, byteLength } = bytes;
502
+ if (buffer instanceof ArrayBuffer) {
503
+ if (byteOffset === 0 && byteLength === buffer.byteLength) return buffer;
504
+ return buffer.slice(byteOffset, byteOffset + byteLength);
505
+ }
506
+ const view = new Uint8Array(byteLength);
507
+ view.set(bytes);
508
+ return view.buffer;
509
+ }
510
+ async text() {
511
+ const bytes = await this.consumeBody();
512
+ return UTF8_DECODER.decode(bytes);
513
+ }
514
+ async blob() {
515
+ const bytes = await this.consumeBody();
516
+ const contentType = this.headers.get("content-type") ?? "";
517
+ return new Blob([bytes], contentType ? { type: contentType } : void 0);
518
+ }
519
+ async formData() {
520
+ const bytes = await this.consumeBody();
521
+ const contentType = this.headers.get("content-type");
522
+ return new globalThis.Response(bytes, contentType ? { headers: { "content-type": contentType } } : void 0).formData();
523
+ }
524
+ readable() {
525
+ this.assertBodyAvailable();
526
+ this.bodyUsed = true;
527
+ const stream = this.body;
528
+ if (stream === null) return node_stream.Readable.from([]);
529
+ return node_stream.Readable.fromWeb(stream);
530
+ }
531
+ clone() {
532
+ if (this.bodyUsed) throw new TypeError("Cannot clone a Response whose body is already used");
533
+ if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
534
+ if (this.nativeHandle) bodyHandleFinalizer?.unregister(this.nativeHandle);
535
+ const handle = this.nativeHandle ?? {
536
+ id: this.payload.bodyHandle,
537
+ released: false
538
+ };
539
+ this.nativeHandle = handle;
540
+ this.bodySource = createNativeBodyStream(handle);
541
+ this.nativeHandleAvailable = false;
542
+ }
543
+ if (this.bodySource === null) return new Response(cloneNativeResponse(this.payload), this.requestUrl, null);
544
+ const [branchA, branchB] = this.bodySource.tee();
545
+ this.bodySource = branchA;
546
+ this.bodyStream = void 0;
547
+ return new Response(cloneNativeResponse(this.payload), this.requestUrl, branchB);
548
+ }
549
+ assertBodyAvailable() {
550
+ if (this.bodyUsed) throw new TypeError("Response body is already used");
551
+ }
552
+ async consumeBody() {
553
+ this.assertBodyAvailable();
554
+ this.bodyUsed = true;
555
+ if (this.inlineBody) {
556
+ const bytes = this.inlineBody;
557
+ this.inlineBody = null;
558
+ return bytes;
559
+ }
560
+ if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
561
+ this.nativeHandleAvailable = false;
562
+ try {
563
+ return await nativeBinding.readBodyAll(this.payload.bodyHandle);
564
+ } catch (error) {
565
+ if (String(error).includes("Body handle") && String(error).includes("not found")) return Buffer.alloc(0);
566
+ throw error;
567
+ } finally {
568
+ if (this.nativeHandle) markNativeBodyReleased(this.nativeHandle);
569
+ }
570
+ }
571
+ const stream = this.body;
572
+ if (!stream) return Buffer.alloc(0);
573
+ const reader = stream.getReader();
574
+ const chunks = [];
575
+ try {
576
+ while (true) {
577
+ const { done, value } = await reader.read();
578
+ if (done) break;
579
+ if (value && value.byteLength > 0) if (Buffer.isBuffer(value)) chunks.push(value);
580
+ else chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
581
+ }
582
+ } finally {}
583
+ return chunks.length === 0 ? Buffer.alloc(0) : Buffer.concat(chunks);
584
+ }
699
585
  };
700
586
  var Transport = class {
701
- id;
702
- disposed = false;
703
- constructor(id) {
704
- this.id = id;
705
- }
706
- get closed() {
707
- return this.disposed;
708
- }
709
- async close() {
710
- if (this.disposed) {
711
- return;
712
- }
713
- this.disposed = true;
714
- try {
715
- nativeBinding.dropTransport(this.id);
716
- } catch (error) {
717
- throw new RequestError(String(error));
718
- }
719
- }
587
+ id;
588
+ disposed = false;
589
+ constructor(id) {
590
+ this.id = id;
591
+ }
592
+ get closed() {
593
+ return this.disposed;
594
+ }
595
+ async close() {
596
+ if (this.disposed) return;
597
+ this.disposed = true;
598
+ try {
599
+ nativeBinding.dropTransport(this.id);
600
+ } catch (error) {
601
+ throw new RequestError(String(error));
602
+ }
603
+ }
720
604
  };
721
605
  var Session = class {
722
- id;
723
- disposed = false;
724
- defaults;
725
- constructor(id, defaults) {
726
- this.id = id;
727
- this.defaults = defaults;
728
- }
729
- get closed() {
730
- return this.disposed;
731
- }
732
- ensureActive() {
733
- if (this.disposed) {
734
- throw new RequestError("Session has been closed");
735
- }
736
- }
737
- /** @internal */
738
- getDefaults() {
739
- const snapshot = { ...this.defaults };
740
- if (this.defaults.defaultHeaders) {
741
- snapshot.defaultHeaders = [...this.defaults.defaultHeaders];
742
- }
743
- return snapshot;
744
- }
745
- /** @internal */
746
- _defaultsRef() {
747
- return this.defaults;
748
- }
749
- async fetch(input, init) {
750
- this.ensureActive();
751
- const config = init ? { ...init, session: this } : { session: this };
752
- return fetch(input, config);
753
- }
754
- async clearCookies() {
755
- this.ensureActive();
756
- try {
757
- nativeBinding.clearSession(this.id);
758
- } catch (error) {
759
- throw new RequestError(String(error));
760
- }
761
- }
762
- getCookies(url) {
763
- this.ensureActive();
764
- try {
765
- return nativeBinding.getCookies(this.id, String(url));
766
- } catch (error) {
767
- throw new RequestError(String(error));
768
- }
769
- }
770
- setCookie(name, value, url) {
771
- this.ensureActive();
772
- try {
773
- nativeBinding.setCookie(this.id, name, value, String(url));
774
- } catch (error) {
775
- throw new RequestError(String(error));
776
- }
777
- }
778
- async websocket(urlOrOptions, options) {
779
- this.ensureActive();
780
- const normalized = normalizeSessionWebSocketArgs(urlOrOptions, options);
781
- validateWebSocketProtocols(normalized.options.protocols);
782
- assertNoManualWebSocketProtocolHeader(normalized.options.headers);
783
- const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
784
- const transportId = this.defaults.transportId;
785
- if (!transportId) {
786
- throw new RequestError(
787
- "Session has no transport. Create the session with browser/os options or pass a transport to use session.websocket()."
788
- );
789
- }
790
- return WebSocket._connectWithInit({
791
- _internal: true,
792
- url: normalized.url,
793
- options: normalized.options,
794
- openDispatchMode: "deferred",
795
- connect: (callbacks) => nativeBinding.websocketConnectSession({
796
- url: normalized.url,
797
- sessionId: this.id,
798
- transportId,
799
- headers: headersToTuples(normalized.options.headers ?? {}),
800
- ...protocols && protocols.length > 0 && { protocols },
801
- onMessage: callbacks.onMessage,
802
- onClose: callbacks.onClose,
803
- onError: callbacks.onError
804
- }),
805
- legacyCallbacks: normalized.legacyCallbacks
806
- });
807
- }
808
- async close() {
809
- if (this.disposed) {
810
- return;
811
- }
812
- this.disposed = true;
813
- const transportId = this.defaults.transportId;
814
- const ownsTransport = this.defaults.ownsTransport;
815
- try {
816
- nativeBinding.dropSession(this.id);
817
- } catch (error) {
818
- if (!ownsTransport || !transportId) {
819
- throw new RequestError(String(error));
820
- }
821
- const originalError = error;
822
- try {
823
- nativeBinding.dropTransport(transportId);
824
- } catch {
825
- }
826
- throw new RequestError(String(originalError));
827
- }
828
- if (ownsTransport && transportId) {
829
- try {
830
- nativeBinding.dropTransport(transportId);
831
- } catch (error) {
832
- throw new RequestError(String(error));
833
- }
834
- }
835
- }
606
+ id;
607
+ disposed = false;
608
+ defaults;
609
+ constructor(id, defaults) {
610
+ this.id = id;
611
+ this.defaults = defaults;
612
+ }
613
+ get closed() {
614
+ return this.disposed;
615
+ }
616
+ ensureActive() {
617
+ if (this.disposed) throw new RequestError("Session has been closed");
618
+ }
619
+ /** @internal */
620
+ getDefaults() {
621
+ const snapshot = { ...this.defaults };
622
+ if (this.defaults.defaultHeaders) snapshot.defaultHeaders = [...this.defaults.defaultHeaders];
623
+ return snapshot;
624
+ }
625
+ /** @internal */
626
+ _defaultsRef() {
627
+ return this.defaults;
628
+ }
629
+ async fetch(input, init) {
630
+ this.ensureActive();
631
+ return fetch(input, init ? {
632
+ ...init,
633
+ session: this
634
+ } : { session: this });
635
+ }
636
+ async clearCookies() {
637
+ this.ensureActive();
638
+ try {
639
+ nativeBinding.clearSession(this.id);
640
+ } catch (error) {
641
+ throw new RequestError(String(error));
642
+ }
643
+ }
644
+ getCookies(url) {
645
+ this.ensureActive();
646
+ try {
647
+ return nativeBinding.getCookies(this.id, String(url));
648
+ } catch (error) {
649
+ throw new RequestError(String(error));
650
+ }
651
+ }
652
+ getAllCookies() {
653
+ this.ensureActive();
654
+ try {
655
+ return nativeBinding.getAllCookies(this.id);
656
+ } catch (error) {
657
+ throw new RequestError(String(error));
658
+ }
659
+ }
660
+ setCookie(name, value, url) {
661
+ this.ensureActive();
662
+ try {
663
+ nativeBinding.setCookie(this.id, name, value, String(url));
664
+ } catch (error) {
665
+ throw new RequestError(String(error));
666
+ }
667
+ }
668
+ async websocket(urlOrOptions, options) {
669
+ this.ensureActive();
670
+ const normalized = normalizeSessionWebSocketArgs(urlOrOptions, options);
671
+ validateWebSocketProtocols(normalized.options.protocols);
672
+ assertNoManualWebSocketProtocolHeader(normalized.options.headers);
673
+ const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
674
+ const transportId = this.defaults.transportId;
675
+ if (!transportId) throw new RequestError("Session has no transport. Create the session with browser/os options or pass a transport to use session.websocket().");
676
+ return WebSocket._connectWithInit({
677
+ _internal: true,
678
+ url: normalized.url,
679
+ options: normalized.options,
680
+ openDispatchMode: "deferred",
681
+ connect: (callbacks) => nativeBinding.websocketConnectSession({
682
+ url: normalized.url,
683
+ sessionId: this.id,
684
+ transportId,
685
+ headers: headersToTuples(normalized.options.headers ?? {}),
686
+ ...protocols && protocols.length > 0 && { protocols },
687
+ ...normalized.options.maxFrameSize !== void 0 && { maxFrameSize: normalized.options.maxFrameSize },
688
+ ...normalized.options.maxMessageSize !== void 0 && { maxMessageSize: normalized.options.maxMessageSize },
689
+ onMessage: callbacks.onMessage,
690
+ onClose: callbacks.onClose,
691
+ onError: callbacks.onError
692
+ }),
693
+ legacyCallbacks: normalized.legacyCallbacks
694
+ });
695
+ }
696
+ async close() {
697
+ if (this.disposed) return;
698
+ this.disposed = true;
699
+ const transportId = this.defaults.transportId;
700
+ const ownsTransport = this.defaults.ownsTransport;
701
+ try {
702
+ nativeBinding.dropSession(this.id);
703
+ } catch (error) {
704
+ if (!ownsTransport || !transportId) throw new RequestError(String(error));
705
+ const originalError = error;
706
+ try {
707
+ nativeBinding.dropTransport(transportId);
708
+ } catch {}
709
+ throw new RequestError(String(originalError));
710
+ }
711
+ if (ownsTransport && transportId) try {
712
+ nativeBinding.dropTransport(transportId);
713
+ } catch (error) {
714
+ throw new RequestError(String(error));
715
+ }
716
+ }
836
717
  };
837
718
  function resolveSessionContext(config) {
838
- const requestedMode = config.cookieMode ?? "ephemeral";
839
- const sessionCandidate = config.session;
840
- const providedSessionId = typeof config.sessionId === "string" ? config.sessionId.trim() : void 0;
841
- if (sessionCandidate && providedSessionId) {
842
- throw new RequestError("Provide either `session` or `sessionId`, not both.");
843
- }
844
- if (sessionCandidate) {
845
- if (!(sessionCandidate instanceof Session)) {
846
- throw new RequestError("`session` must be created via createSession()");
847
- }
848
- if (sessionCandidate.closed) {
849
- throw new RequestError("Session has been closed");
850
- }
851
- return {
852
- sessionId: sessionCandidate.id,
853
- cookieMode: "session",
854
- dropAfterRequest: false,
855
- defaults: sessionCandidate._defaultsRef()
856
- };
857
- }
858
- if (providedSessionId) {
859
- if (!providedSessionId) {
860
- throw new RequestError("sessionId must not be empty");
861
- }
862
- if (requestedMode === "ephemeral") {
863
- throw new RequestError("cookieMode 'ephemeral' cannot be combined with sessionId");
864
- }
865
- return {
866
- sessionId: providedSessionId,
867
- cookieMode: "session",
868
- dropAfterRequest: false
869
- };
870
- }
871
- if (requestedMode === "session") {
872
- throw new RequestError("cookieMode 'session' requires a session or sessionId");
873
- }
874
- return {
875
- sessionId: generateEphemeralSessionId(),
876
- cookieMode: "ephemeral",
877
- dropAfterRequest: true
878
- };
719
+ const requestedMode = config.cookieMode ?? "ephemeral";
720
+ const sessionCandidate = config.session;
721
+ const providedSessionId = typeof config.sessionId === "string" ? config.sessionId.trim() : void 0;
722
+ if (sessionCandidate && providedSessionId) throw new RequestError("Provide either `session` or `sessionId`, not both.");
723
+ if (sessionCandidate) {
724
+ if (!(sessionCandidate instanceof Session)) throw new RequestError("`session` must be created via createSession()");
725
+ if (sessionCandidate.closed) throw new RequestError("Session has been closed");
726
+ return {
727
+ sessionId: sessionCandidate.id,
728
+ cookieMode: "session",
729
+ dropAfterRequest: false,
730
+ defaults: sessionCandidate._defaultsRef()
731
+ };
732
+ }
733
+ if (providedSessionId) {
734
+ if (!providedSessionId) throw new RequestError("sessionId must not be empty");
735
+ if (requestedMode === "ephemeral") throw new RequestError("cookieMode 'ephemeral' cannot be combined with sessionId");
736
+ return {
737
+ sessionId: providedSessionId,
738
+ cookieMode: "session",
739
+ dropAfterRequest: false
740
+ };
741
+ }
742
+ if (requestedMode === "session") throw new RequestError("cookieMode 'session' requires a session or sessionId");
743
+ return {
744
+ sessionId: generateEphemeralSessionId(),
745
+ cookieMode: "ephemeral",
746
+ dropAfterRequest: true
747
+ };
879
748
  }
880
749
  function resolveTransportContext(config, sessionDefaults) {
881
- if (config.transport !== void 0) {
882
- if (!(config.transport instanceof Transport)) {
883
- throw new RequestError("`transport` must be created via createTransport()");
884
- }
885
- if (config.transport.closed) {
886
- throw new RequestError("Transport has been closed");
887
- }
888
- const hasProxy = config.proxy !== void 0;
889
- if (config.browser !== void 0 || config.os !== void 0 || config.emulation !== void 0 || hasProxy || config.insecure !== void 0) {
890
- throw new RequestError("`transport` cannot be combined with browser/os/emulation/proxy/insecure options");
891
- }
892
- return { transportId: config.transport.id };
893
- }
894
- if (sessionDefaults?.transportId) {
895
- if (config.emulation !== void 0) {
896
- throw new RequestError("Session emulation cannot be changed after creation");
897
- }
898
- if (config.browser !== void 0) {
899
- validateBrowserProfile(config.browser);
900
- const lockedBrowser = sessionDefaults.transportMode.kind === "custom" ? void 0 : sessionDefaults.transportMode.browser;
901
- if (config.browser !== lockedBrowser) {
902
- throw new RequestError("Session browser cannot be changed after creation");
903
- }
904
- }
905
- if (config.os !== void 0) {
906
- validateOperatingSystem(config.os);
907
- const lockedOs = sessionDefaults.transportMode.kind === "custom" ? void 0 : sessionDefaults.transportMode.os;
908
- if (config.os !== lockedOs) {
909
- throw new RequestError("Session operating system cannot be changed after creation");
910
- }
911
- }
912
- const initHasProxy = Object.hasOwn(config, "proxy");
913
- const requestedProxy = initHasProxy ? config.proxy : void 0;
914
- if (initHasProxy && requestedProxy !== void 0 && (sessionDefaults.proxy ?? null) !== (requestedProxy ?? null)) {
915
- throw new RequestError("Session proxy cannot be changed after creation");
916
- }
917
- if (config.insecure !== void 0) {
918
- const lockedInsecure = sessionDefaults.insecure ?? false;
919
- if (config.insecure !== lockedInsecure) {
920
- throw new RequestError("Session insecure setting cannot be changed after creation");
921
- }
922
- }
923
- return { transportId: sessionDefaults.transportId };
924
- }
925
- const resolved = {
926
- mode: resolveEmulationMode(config.browser, config.os, config.emulation)
927
- };
928
- if (config.proxy !== void 0) {
929
- resolved.proxy = config.proxy;
930
- }
931
- if (config.insecure !== void 0) {
932
- resolved.insecure = config.insecure;
933
- }
934
- return resolved;
750
+ if (config.transport !== void 0) {
751
+ if (!(config.transport instanceof Transport)) throw new RequestError("`transport` must be created via createTransport()");
752
+ if (config.transport.closed) throw new RequestError("Transport has been closed");
753
+ const hasProxy = config.proxy !== void 0;
754
+ if (config.browser !== void 0 || config.os !== void 0 || config.emulation !== void 0 || hasProxy || config.insecure !== void 0 || config.trustStore !== void 0) throw new RequestError("`transport` cannot be combined with browser/os/emulation/proxy/insecure/trustStore options");
755
+ return {
756
+ transportId: config.transport.id,
757
+ ...config.captureDiagnostics !== void 0 && { captureDiagnostics: config.captureDiagnostics }
758
+ };
759
+ }
760
+ if (sessionDefaults?.transportId) {
761
+ if (config.emulation !== void 0) throw new RequestError("Session emulation cannot be changed after creation");
762
+ if (config.browser !== void 0) {
763
+ validateBrowserProfile(config.browser);
764
+ const lockedBrowser = sessionDefaults.transportMode.kind === "custom" ? void 0 : sessionDefaults.transportMode.browser;
765
+ if (config.browser !== lockedBrowser) throw new RequestError("Session browser cannot be changed after creation");
766
+ }
767
+ if (config.os !== void 0) {
768
+ validateOperatingSystem(config.os);
769
+ const lockedOs = sessionDefaults.transportMode.kind === "custom" ? void 0 : sessionDefaults.transportMode.os;
770
+ if (config.os !== lockedOs) throw new RequestError("Session operating system cannot be changed after creation");
771
+ }
772
+ const initHasProxy = Object.hasOwn(config, "proxy");
773
+ const requestedProxy = initHasProxy ? config.proxy : void 0;
774
+ if (initHasProxy && requestedProxy !== void 0 && (sessionDefaults.proxy ?? null) !== (requestedProxy ?? null)) throw new RequestError("Session proxy cannot be changed after creation");
775
+ if (config.insecure !== void 0) {
776
+ const lockedInsecure = sessionDefaults.insecure ?? false;
777
+ if (config.insecure !== lockedInsecure) throw new RequestError("Session insecure setting cannot be changed after creation");
778
+ }
779
+ if (config.trustStore !== void 0) {
780
+ const lockedTrustStore = sessionDefaults.trustStore ?? DEFAULT_TRUST_STORE;
781
+ if (config.trustStore !== lockedTrustStore) throw new RequestError("Session trustStore setting cannot be changed after creation");
782
+ }
783
+ const captureDiagnostics = config.captureDiagnostics ?? sessionDefaults.captureDiagnostics;
784
+ return {
785
+ transportId: sessionDefaults.transportId,
786
+ ...captureDiagnostics !== void 0 && { captureDiagnostics }
787
+ };
788
+ }
789
+ const resolved = { mode: resolveEmulationMode(config.browser, config.os, config.emulation) };
790
+ if (config.proxy !== void 0) resolved.proxy = config.proxy;
791
+ if (config.insecure !== void 0) resolved.insecure = config.insecure;
792
+ resolved.trustStore = config.trustStore ?? DEFAULT_TRUST_STORE;
793
+ if (config.captureDiagnostics !== void 0) resolved.captureDiagnostics = config.captureDiagnostics;
794
+ return resolved;
935
795
  }
936
796
  function createAbortError(reason) {
937
- const fallbackMessage = typeof reason === "string" ? reason : "The operation was aborted";
938
- if (typeof DOMException !== "undefined" && reason instanceof DOMException) {
939
- return reason.name === "AbortError" ? reason : new DOMException(reason.message || fallbackMessage, "AbortError");
940
- }
941
- if (reason instanceof Error) {
942
- const error2 = new Error(reason.message);
943
- error2.name = "AbortError";
944
- error2.cause = reason;
945
- return error2;
946
- }
947
- if (typeof DOMException !== "undefined") {
948
- return new DOMException(fallbackMessage, "AbortError");
949
- }
950
- const error = new Error(fallbackMessage);
951
- error.name = "AbortError";
952
- return error;
797
+ const fallbackMessage = typeof reason === "string" ? reason : "The operation was aborted";
798
+ if (typeof DOMException !== "undefined" && reason instanceof DOMException) return reason.name === "AbortError" ? reason : new DOMException(reason.message || fallbackMessage, "AbortError");
799
+ if (reason instanceof Error) {
800
+ const error = new Error(reason.message);
801
+ error.name = "AbortError";
802
+ error.cause = reason;
803
+ return error;
804
+ }
805
+ if (typeof DOMException !== "undefined") return new DOMException(fallbackMessage, "AbortError");
806
+ const error = new Error(fallbackMessage);
807
+ error.name = "AbortError";
808
+ return error;
953
809
  }
954
810
  function isAbortError(error) {
955
- return Boolean(error) && typeof error.name === "string" && error.name === "AbortError";
811
+ return Boolean(error) && typeof error.name === "string" && error.name === "AbortError";
956
812
  }
957
- var REQUEST_ID_MAX = 2 ** 48;
958
- var requestIdCounter = Math.trunc(Number(process.hrtime.bigint() % BigInt(REQUEST_ID_MAX - 1))) + 1;
813
+ const REQUEST_ID_MAX = 2 ** 48;
814
+ let requestIdCounter = Math.trunc(Number(process.hrtime.bigint() % BigInt(REQUEST_ID_MAX - 1))) + 1;
959
815
  function generateRequestId() {
960
- requestIdCounter += 1;
961
- if (requestIdCounter >= REQUEST_ID_MAX) {
962
- requestIdCounter = 1;
963
- }
964
- return requestIdCounter;
816
+ requestIdCounter += 1;
817
+ if (requestIdCounter >= REQUEST_ID_MAX) requestIdCounter = 1;
818
+ return requestIdCounter;
965
819
  }
966
820
  function setupAbort(signal, cancelNative) {
967
- if (!signal) {
968
- return null;
969
- }
970
- if (signal.aborted) {
971
- cancelNative();
972
- throw createAbortError(signal.reason);
973
- }
974
- let onAbortListener;
975
- const promise = new Promise((_, reject) => {
976
- onAbortListener = () => {
977
- cancelNative();
978
- reject(createAbortError(signal.reason));
979
- };
980
- signal.addEventListener("abort", onAbortListener, { once: true });
981
- });
982
- const cleanup = () => {
983
- if (onAbortListener) {
984
- signal.removeEventListener("abort", onAbortListener);
985
- onAbortListener = void 0;
986
- }
987
- };
988
- return { promise, cleanup };
821
+ if (!signal) return null;
822
+ if (signal.aborted) {
823
+ cancelNative();
824
+ throw createAbortError(signal.reason);
825
+ }
826
+ let onAbortListener;
827
+ const promise = new Promise((_, reject) => {
828
+ onAbortListener = () => {
829
+ cancelNative();
830
+ reject(createAbortError(signal.reason));
831
+ };
832
+ signal.addEventListener("abort", onAbortListener, { once: true });
833
+ });
834
+ const cleanup = () => {
835
+ if (onAbortListener) {
836
+ signal.removeEventListener("abort", onAbortListener);
837
+ onAbortListener = void 0;
838
+ }
839
+ };
840
+ return {
841
+ promise,
842
+ cleanup
843
+ };
989
844
  }
990
845
  function coerceUrlInput(input) {
991
- if (input instanceof URL) {
992
- return input.href;
993
- }
994
- if (input.length === 0) {
995
- throw new RequestError("URL is required");
996
- }
997
- if (input.charCodeAt(0) > 32 && input.charCodeAt(input.length - 1) > 32) {
998
- return input;
999
- }
1000
- const trimmed = input.trim();
1001
- if (trimmed.length === 0) {
1002
- throw new RequestError("URL is required");
1003
- }
1004
- return trimmed;
846
+ if (input instanceof URL) return input.href;
847
+ if (input.length === 0) throw new RequestError("URL is required");
848
+ if (input.charCodeAt(0) > 32 && input.charCodeAt(input.length - 1) > 32) return input;
849
+ const trimmed = input.trim();
850
+ if (trimmed.length === 0) throw new RequestError("URL is required");
851
+ return trimmed;
1005
852
  }
1006
853
  function isRequestLike(input) {
1007
- if (!input || typeof input !== "object") {
1008
- return false;
1009
- }
1010
- if (typeof Request !== "undefined" && input instanceof Request) {
1011
- return true;
1012
- }
1013
- const candidate = input;
1014
- return typeof candidate.url === "string" && typeof candidate.method === "string" && typeof candidate.arrayBuffer === "function" && typeof candidate.redirect === "string";
854
+ if (!input || typeof input !== "object") return false;
855
+ if (typeof Request !== "undefined" && input instanceof Request) return true;
856
+ const candidate = input;
857
+ return typeof candidate.url === "string" && typeof candidate.method === "string" && typeof candidate.arrayBuffer === "function" && typeof candidate.redirect === "string";
1015
858
  }
1016
859
  async function resolveFetchArgs(input, init) {
1017
- if (!isRequestLike(input)) {
1018
- return { url: coerceUrlInput(input), init: init ?? {} };
1019
- }
1020
- const mergedInit = init ? { ...init } : {};
1021
- if (mergedInit.method === void 0) {
1022
- mergedInit.method = input.method;
1023
- }
1024
- if (mergedInit.headers === void 0) {
1025
- mergedInit.headers = input.headers;
1026
- }
1027
- if (mergedInit.redirect === void 0 && (input.redirect === "follow" || input.redirect === "manual" || input.redirect === "error")) {
1028
- mergedInit.redirect = input.redirect;
1029
- }
1030
- if (mergedInit.signal === void 0) {
1031
- mergedInit.signal = input.signal;
1032
- }
1033
- if (mergedInit.body === void 0 && input.body !== null) {
1034
- if (input.bodyUsed) {
1035
- throw new TypeError("Request body is already used");
1036
- }
1037
- mergedInit.body = Buffer.from(await input.arrayBuffer());
1038
- }
1039
- return { url: coerceUrlInput(input.url), init: mergedInit };
860
+ if (!isRequestLike(input)) return {
861
+ url: coerceUrlInput(input),
862
+ init: init ?? {}
863
+ };
864
+ const mergedInit = init ? { ...init } : {};
865
+ if (mergedInit.method === void 0) mergedInit.method = input.method;
866
+ if (mergedInit.headers === void 0) mergedInit.headers = input.headers;
867
+ if (mergedInit.redirect === void 0 && (input.redirect === "follow" || input.redirect === "manual" || input.redirect === "error")) mergedInit.redirect = input.redirect;
868
+ if (mergedInit.signal === void 0) mergedInit.signal = input.signal;
869
+ if (mergedInit.body === void 0 && input.body !== null) {
870
+ if (input.bodyUsed) throw new TypeError("Request body is already used");
871
+ mergedInit.body = Buffer.from(await input.arrayBuffer());
872
+ }
873
+ return {
874
+ url: coerceUrlInput(input.url),
875
+ init: mergedInit
876
+ };
1040
877
  }
1041
878
  function normalizeUrlForComparison(value) {
1042
- try {
1043
- return new URL(value).toString();
1044
- } catch {
1045
- return null;
1046
- }
879
+ try {
880
+ return new URL(value).toString();
881
+ } catch {
882
+ return null;
883
+ }
1047
884
  }
1048
885
  function validateRedirectMode(mode) {
1049
- if (mode === void 0 || mode === "follow" || mode === "manual" || mode === "error") {
1050
- return;
1051
- }
1052
- throw new RequestError(`Redirect mode '${mode}' is not supported`);
886
+ if (mode === void 0 || mode === "follow" || mode === "manual" || mode === "error") return;
887
+ throw new RequestError(`Redirect mode '${mode}' is not supported`);
1053
888
  }
1054
889
  async function serializeBody(body) {
1055
- if (body === null || body === void 0) {
1056
- return {};
1057
- }
1058
- if (typeof body === "string") {
1059
- return { body: Buffer.from(body, "utf8") };
1060
- }
1061
- if (Buffer.isBuffer(body)) {
1062
- return { body };
1063
- }
1064
- if (body instanceof URLSearchParams) {
1065
- return {
1066
- body: Buffer.from(body.toString(), "utf8"),
1067
- contentType: "application/x-www-form-urlencoded;charset=UTF-8"
1068
- };
1069
- }
1070
- if (body instanceof ArrayBuffer) {
1071
- return { body: Buffer.from(body) };
1072
- }
1073
- if (ArrayBuffer.isView(body)) {
1074
- return { body: Buffer.from(body.buffer, body.byteOffset, body.byteLength) };
1075
- }
1076
- if (typeof Blob !== "undefined" && body instanceof Blob) {
1077
- const buffer = Buffer.from(await body.arrayBuffer());
1078
- return { body: buffer, ...body.type ? { contentType: body.type } : {} };
1079
- }
1080
- if (typeof FormData !== "undefined" && body instanceof FormData) {
1081
- const encoded = new globalThis.Response(body);
1082
- const contentType = encoded.headers.get("content-type") ?? void 0;
1083
- const buffer = Buffer.from(await encoded.arrayBuffer());
1084
- return { body: buffer, ...contentType ? { contentType } : {} };
1085
- }
1086
- throw new TypeError(
1087
- "Unsupported body type; expected string, Buffer, ArrayBuffer, ArrayBufferView, URLSearchParams, Blob, or FormData"
1088
- );
890
+ if (body === null || body === void 0) return {};
891
+ if (typeof body === "string") return { body: Buffer.from(body, "utf8") };
892
+ if (Buffer.isBuffer(body)) return { body };
893
+ if (body instanceof URLSearchParams) return {
894
+ body: Buffer.from(body.toString(), "utf8"),
895
+ contentType: "application/x-www-form-urlencoded;charset=UTF-8"
896
+ };
897
+ if (body instanceof ArrayBuffer) return { body: Buffer.from(body) };
898
+ if (ArrayBuffer.isView(body)) return { body: Buffer.from(body.buffer, body.byteOffset, body.byteLength) };
899
+ if (typeof Blob !== "undefined" && body instanceof Blob) return {
900
+ body: Buffer.from(await body.arrayBuffer()),
901
+ ...body.type ? { contentType: body.type } : {}
902
+ };
903
+ if (typeof FormData !== "undefined" && body instanceof FormData) {
904
+ const encoded = new globalThis.Response(body);
905
+ const contentType = encoded.headers.get("content-type") ?? void 0;
906
+ return {
907
+ body: Buffer.from(await encoded.arrayBuffer()),
908
+ ...contentType ? { contentType } : {}
909
+ };
910
+ }
911
+ throw new TypeError("Unsupported body type; expected string, Buffer, ArrayBuffer, ArrayBufferView, URLSearchParams, Blob, or FormData");
1089
912
  }
1090
913
  function ensureMethod(method) {
1091
- if (method === void 0 || method.length === 0) {
1092
- return "GET";
1093
- }
1094
- switch (method) {
1095
- case "GET":
1096
- case "POST":
1097
- case "PUT":
1098
- case "DELETE":
1099
- case "PATCH":
1100
- case "HEAD":
1101
- case "OPTIONS":
1102
- return method;
1103
- }
1104
- const normalized = method.trim().toUpperCase();
1105
- return normalized.length > 0 ? normalized : "GET";
914
+ if (method === void 0 || method.length === 0) return "GET";
915
+ switch (method) {
916
+ case "GET":
917
+ case "POST":
918
+ case "PUT":
919
+ case "DELETE":
920
+ case "PATCH":
921
+ case "HEAD":
922
+ case "OPTIONS": return method;
923
+ }
924
+ const normalized = method.trim().toUpperCase();
925
+ return normalized.length > 0 ? normalized : "GET";
1106
926
  }
1107
927
  function ensureBodyAllowed(method, body) {
1108
- if (body === void 0) {
1109
- return;
1110
- }
1111
- if (method === "GET" || method === "HEAD") {
1112
- throw new RequestError(`Request with ${method} method cannot have a body`);
1113
- }
928
+ if (body === void 0) return;
929
+ if (method === "GET" || method === "HEAD") throw new RequestError(`Request with ${method} method cannot have a body`);
1114
930
  }
1115
931
  function validateBrowserProfile(browser) {
1116
- if (browser === void 0) {
1117
- return;
1118
- }
1119
- if (typeof browser !== "string" || browser.trim().length === 0) {
1120
- throw new RequestError("Browser profile must not be empty");
1121
- }
1122
- if (!getProfileSet().has(browser)) {
1123
- throw new RequestError(`Invalid browser profile: ${browser}. Available profiles: ${getProfiles().join(", ")}`);
1124
- }
932
+ if (browser === void 0) return;
933
+ if (typeof browser !== "string" || browser.trim().length === 0) throw new RequestError("Browser profile must not be empty");
934
+ if (!getProfileSet().has(browser)) throw new RequestError(`Invalid browser profile: ${browser}. Available profiles: ${getProfiles().join(", ")}`);
1125
935
  }
1126
936
  function validateOperatingSystem(os) {
1127
- if (os === void 0) {
1128
- return;
1129
- }
1130
- if (typeof os !== "string" || os.trim().length === 0) {
1131
- throw new RequestError("Operating system must not be empty");
1132
- }
1133
- if (!getOperatingSystemSet().has(os)) {
1134
- throw new RequestError(`Invalid operating system: ${os}. Available options: ${getOperatingSystems().join(", ")}`);
1135
- }
937
+ if (os === void 0) return;
938
+ if (typeof os !== "string" || os.trim().length === 0) throw new RequestError("Operating system must not be empty");
939
+ if (!getOperatingSystemSet().has(os)) throw new RequestError(`Invalid operating system: ${os}. Available options: ${getOperatingSystems().join(", ")}`);
1136
940
  }
1137
941
  function validateTimeout(timeout) {
1138
- if (timeout === void 0) {
1139
- return;
1140
- }
1141
- if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
1142
- throw new RequestError("Timeout must be a finite number");
1143
- }
1144
- if (timeout < 0) {
1145
- throw new RequestError("Timeout must be 0 (no timeout) or a positive number");
1146
- }
942
+ if (timeout === void 0) return;
943
+ if (typeof timeout !== "number" || !Number.isFinite(timeout)) throw new RequestError("Timeout must be a finite number");
944
+ if (timeout < 0) throw new RequestError("Timeout must be 0 (no timeout) or a positive number");
945
+ }
946
+ function validateTrustStore(trustStore) {
947
+ if (trustStore === void 0) return;
948
+ if (trustStore !== "combined" && trustStore !== "mozilla" && trustStore !== "defaultPaths") throw new RequestError("trustStore must be one of: combined, mozilla, defaultPaths");
1147
949
  }
1148
950
  function validatePositiveNumber(value, label) {
1149
- if (typeof value !== "number" || !Number.isFinite(value)) {
1150
- throw new RequestError(`${label} must be a finite number`);
1151
- }
1152
- if (value <= 0) {
1153
- throw new RequestError(`${label} must be greater than 0`);
1154
- }
951
+ if (typeof value !== "number" || !Number.isFinite(value)) throw new RequestError(`${label} must be a finite number`);
952
+ if (value <= 0) throw new RequestError(`${label} must be greater than 0`);
1155
953
  }
1156
954
  function validateNonNegativeInteger(value, label) {
1157
- if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
1158
- throw new RequestError(`${label} must be an integer`);
1159
- }
1160
- if (value < 0) {
1161
- throw new RequestError(`${label} must be greater than or equal to 0`);
1162
- }
955
+ if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) throw new RequestError(`${label} must be an integer`);
956
+ if (value < 0) throw new RequestError(`${label} must be greater than or equal to 0`);
1163
957
  }
1164
958
  function validatePositiveInteger(value, label) {
1165
- if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
1166
- throw new RequestError(`${label} must be an integer`);
1167
- }
1168
- if (value <= 0) {
1169
- throw new RequestError(`${label} must be greater than 0`);
1170
- }
959
+ if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) throw new RequestError(`${label} must be an integer`);
960
+ if (value <= 0) throw new RequestError(`${label} must be greater than 0`);
1171
961
  }
1172
962
  function validateIntegerInRange(value, min, max, label) {
1173
- validateNonNegativeInteger(value, label);
1174
- if (value < min || value > max) {
1175
- throw new RequestError(`${label} must be between ${min} and ${max}`);
1176
- }
1177
- }
1178
- var SUPPORTED_ALPN_PROTOCOLS = /* @__PURE__ */ new Set(["HTTP1", "HTTP2", "HTTP3"]);
1179
- var SUPPORTED_ALPS_PROTOCOLS = /* @__PURE__ */ new Set(["HTTP1", "HTTP2", "HTTP3"]);
1180
- var SUPPORTED_CERTIFICATE_COMPRESSION_ALGORITHMS = /* @__PURE__ */ new Set(["zlib", "brotli", "zstd"]);
1181
- var HTTP2_SETTING_IDS = /* @__PURE__ */ new Set([
1182
- "HeaderTableSize",
1183
- "EnablePush",
1184
- "MaxConcurrentStreams",
1185
- "InitialWindowSize",
1186
- "MaxFrameSize",
1187
- "MaxHeaderListSize",
1188
- "EnableConnectProtocol",
1189
- "NoRfc7540Priorities"
963
+ validateNonNegativeInteger(value, label);
964
+ if (value < min || value > max) throw new RequestError(`${label} must be between ${min} and ${max}`);
965
+ }
966
+ const SUPPORTED_ALPN_PROTOCOLS = new Set([
967
+ "HTTP1",
968
+ "HTTP2",
969
+ "HTTP3"
970
+ ]);
971
+ const SUPPORTED_ALPS_PROTOCOLS = new Set([
972
+ "HTTP1",
973
+ "HTTP2",
974
+ "HTTP3"
975
+ ]);
976
+ const SUPPORTED_CERTIFICATE_COMPRESSION_ALGORITHMS = new Set([
977
+ "zlib",
978
+ "brotli",
979
+ "zstd"
980
+ ]);
981
+ const HTTP2_SETTING_IDS = new Set([
982
+ "HeaderTableSize",
983
+ "EnablePush",
984
+ "MaxConcurrentStreams",
985
+ "InitialWindowSize",
986
+ "MaxFrameSize",
987
+ "MaxHeaderListSize",
988
+ "EnableConnectProtocol",
989
+ "NoRfc7540Priorities"
1190
990
  ]);
1191
- var HTTP2_PSEUDO_HEADER_IDS = /* @__PURE__ */ new Set(["Method", "Scheme", "Authority", "Path", "Protocol"]);
1192
- var STANDARD_HTTP2_SETTING_ID_VALUES = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6, 8, 9]);
1193
- var MAX_HTTP2_EXPERIMENTAL_SETTING_ID = 15;
1194
- var TLS_VERSION_ALIASES = /* @__PURE__ */ new Map([
1195
- ["1.0", "1.0"],
1196
- ["1.1", "1.1"],
1197
- ["1.2", "1.2"],
1198
- ["1.3", "1.3"],
1199
- ["tls1.0", "1.0"],
1200
- ["tls1.1", "1.1"],
1201
- ["tls1.2", "1.2"],
1202
- ["tls1.3", "1.3"]
991
+ const HTTP2_PSEUDO_HEADER_IDS = new Set([
992
+ "Method",
993
+ "Scheme",
994
+ "Authority",
995
+ "Path",
996
+ "Protocol"
997
+ ]);
998
+ const STANDARD_HTTP2_SETTING_ID_VALUES = new Set([
999
+ 1,
1000
+ 2,
1001
+ 3,
1002
+ 4,
1003
+ 5,
1004
+ 6,
1005
+ 8,
1006
+ 9
1007
+ ]);
1008
+ const MAX_HTTP2_EXPERIMENTAL_SETTING_ID = 15;
1009
+ const TLS_VERSION_ALIASES = new Map([
1010
+ ["1.0", "1.0"],
1011
+ ["1.1", "1.1"],
1012
+ ["1.2", "1.2"],
1013
+ ["1.3", "1.3"],
1014
+ ["tls1.0", "1.0"],
1015
+ ["tls1.1", "1.1"],
1016
+ ["tls1.2", "1.2"],
1017
+ ["tls1.3", "1.3"]
1203
1018
  ]);
1204
1019
  function isNonEmpty(value) {
1205
- for (const _ in value) return true;
1206
- return false;
1020
+ for (const _ in value) return true;
1021
+ return false;
1207
1022
  }
1208
1023
  function normalizeProtocolList(value, label, allowed) {
1209
- if (value === void 0) {
1210
- return void 0;
1211
- }
1212
- if (!Array.isArray(value)) {
1213
- throw new RequestError(`${label} must be an array`);
1214
- }
1215
- for (const protocol of value) {
1216
- if (!allowed.has(protocol)) {
1217
- throw new RequestError(`${label} values must be one of: HTTP1, HTTP2, HTTP3`);
1218
- }
1219
- }
1220
- return [...value];
1024
+ if (value === void 0) return;
1025
+ if (!Array.isArray(value)) throw new RequestError(`${label} must be an array`);
1026
+ for (const protocol of value) if (!allowed.has(protocol)) throw new RequestError(`${label} values must be one of: HTTP1, HTTP2, HTTP3`);
1027
+ return [...value];
1221
1028
  }
1222
1029
  function normalizeTlsVersion(value, label) {
1223
- if (value === void 0) {
1224
- return void 0;
1225
- }
1226
- if (typeof value !== "string") {
1227
- throw new RequestError(`${label} must be a string`);
1228
- }
1229
- const normalized = TLS_VERSION_ALIASES.get(value.trim().toLowerCase());
1230
- if (!normalized) {
1231
- throw new RequestError(`${label} must be one of: 1.0, 1.1, 1.2, 1.3`);
1232
- }
1233
- return normalized;
1030
+ if (value === void 0) return;
1031
+ if (typeof value !== "string") throw new RequestError(`${label} must be a string`);
1032
+ const normalized = TLS_VERSION_ALIASES.get(value.trim().toLowerCase());
1033
+ if (!normalized) throw new RequestError(`${label} must be one of: 1.0, 1.1, 1.2, 1.3`);
1034
+ return normalized;
1234
1035
  }
1235
1036
  function normalizeOrigHeaders(origHeaders) {
1236
- if (origHeaders === void 0) {
1237
- return void 0;
1238
- }
1239
- if (!Array.isArray(origHeaders)) {
1240
- throw new RequestError("emulation.origHeaders must be an array of strings");
1241
- }
1242
- const normalized = [];
1243
- const seen = /* @__PURE__ */ new Set();
1244
- for (const entry of origHeaders) {
1245
- if (typeof entry !== "string" || entry.trim().length === 0) {
1246
- throw new RequestError("emulation.origHeaders entries must be non-empty strings");
1247
- }
1248
- const trimmed = entry.trim();
1249
- const duplicateKey = trimmed.toLowerCase();
1250
- if (seen.has(duplicateKey)) {
1251
- throw new RequestError(`Duplicate emulation.origHeaders entry: ${trimmed}`);
1252
- }
1253
- seen.add(duplicateKey);
1254
- normalized.push(trimmed);
1255
- }
1256
- return normalized.length > 0 ? normalized : void 0;
1037
+ if (origHeaders === void 0) return;
1038
+ if (!Array.isArray(origHeaders)) throw new RequestError("emulation.origHeaders must be an array of strings");
1039
+ const normalized = [];
1040
+ const seen = /* @__PURE__ */ new Set();
1041
+ for (const entry of origHeaders) {
1042
+ if (typeof entry !== "string" || entry.trim().length === 0) throw new RequestError("emulation.origHeaders entries must be non-empty strings");
1043
+ const trimmed = entry.trim();
1044
+ const duplicateKey = trimmed.toLowerCase();
1045
+ if (seen.has(duplicateKey)) throw new RequestError(`Duplicate emulation.origHeaders entry: ${trimmed}`);
1046
+ seen.add(duplicateKey);
1047
+ normalized.push(trimmed);
1048
+ }
1049
+ return normalized.length > 0 ? normalized : void 0;
1257
1050
  }
1258
1051
  function normalizeCustomTlsOptions(options) {
1259
- if (options === void 0) {
1260
- return void 0;
1261
- }
1262
- const normalized = {};
1263
- const alpnProtocols = normalizeProtocolList(
1264
- options.alpnProtocols,
1265
- "emulation.tlsOptions.alpnProtocols",
1266
- SUPPORTED_ALPN_PROTOCOLS
1267
- );
1268
- if (alpnProtocols !== void 0) {
1269
- normalized.alpnProtocols = alpnProtocols;
1270
- }
1271
- const alpsProtocols = normalizeProtocolList(
1272
- options.alpsProtocols,
1273
- "emulation.tlsOptions.alpsProtocols",
1274
- SUPPORTED_ALPS_PROTOCOLS
1275
- );
1276
- if (alpsProtocols !== void 0) {
1277
- normalized.alpsProtocols = alpsProtocols;
1278
- }
1279
- const minTlsVersion = normalizeTlsVersion(options.minTlsVersion, "emulation.tlsOptions.minTlsVersion");
1280
- if (minTlsVersion !== void 0) {
1281
- normalized.minTlsVersion = minTlsVersion;
1282
- }
1283
- const maxTlsVersion = normalizeTlsVersion(options.maxTlsVersion, "emulation.tlsOptions.maxTlsVersion");
1284
- if (maxTlsVersion !== void 0) {
1285
- normalized.maxTlsVersion = maxTlsVersion;
1286
- }
1287
- if (options.alpsUseNewCodepoint !== void 0) {
1288
- normalized.alpsUseNewCodepoint = options.alpsUseNewCodepoint;
1289
- }
1290
- if (options.sessionTicket !== void 0) {
1291
- normalized.sessionTicket = options.sessionTicket;
1292
- }
1293
- if (options.preSharedKey !== void 0) {
1294
- normalized.preSharedKey = options.preSharedKey;
1295
- }
1296
- if (options.enableEchGrease !== void 0) {
1297
- normalized.enableEchGrease = options.enableEchGrease;
1298
- }
1299
- if (options.permuteExtensions !== void 0) {
1300
- normalized.permuteExtensions = options.permuteExtensions;
1301
- }
1302
- if (options.greaseEnabled !== void 0) {
1303
- normalized.greaseEnabled = options.greaseEnabled;
1304
- }
1305
- if (options.enableOcspStapling !== void 0) {
1306
- normalized.enableOcspStapling = options.enableOcspStapling;
1307
- }
1308
- if (options.enableSignedCertTimestamps !== void 0) {
1309
- normalized.enableSignedCertTimestamps = options.enableSignedCertTimestamps;
1310
- }
1311
- if (options.pskSkipSessionTicket !== void 0) {
1312
- normalized.pskSkipSessionTicket = options.pskSkipSessionTicket;
1313
- }
1314
- if (options.pskDheKe !== void 0) {
1315
- normalized.pskDheKe = options.pskDheKe;
1316
- }
1317
- if (options.renegotiation !== void 0) {
1318
- normalized.renegotiation = options.renegotiation;
1319
- }
1320
- if (options.aesHwOverride !== void 0) {
1321
- normalized.aesHwOverride = options.aesHwOverride;
1322
- }
1323
- if (options.preserveTls13CipherList !== void 0) {
1324
- normalized.preserveTls13CipherList = options.preserveTls13CipherList;
1325
- }
1326
- if (options.randomAesHwOverride !== void 0) {
1327
- normalized.randomAesHwOverride = options.randomAesHwOverride;
1328
- }
1329
- if (options.delegatedCredentials !== void 0) {
1330
- normalized.delegatedCredentials = options.delegatedCredentials;
1331
- }
1332
- if (options.curvesList !== void 0) {
1333
- normalized.curvesList = options.curvesList;
1334
- }
1335
- if (options.cipherList !== void 0) {
1336
- normalized.cipherList = options.cipherList;
1337
- }
1338
- if (options.sigalgsList !== void 0) {
1339
- normalized.sigalgsList = options.sigalgsList;
1340
- }
1341
- if (options.recordSizeLimit !== void 0) {
1342
- validateIntegerInRange(options.recordSizeLimit, 0, 65535, "emulation.tlsOptions.recordSizeLimit");
1343
- normalized.recordSizeLimit = options.recordSizeLimit;
1344
- }
1345
- if (options.keySharesLimit !== void 0) {
1346
- validateIntegerInRange(options.keySharesLimit, 0, 255, "emulation.tlsOptions.keySharesLimit");
1347
- normalized.keySharesLimit = options.keySharesLimit;
1348
- }
1349
- if (options.certificateCompressionAlgorithms !== void 0) {
1350
- if (!Array.isArray(options.certificateCompressionAlgorithms)) {
1351
- throw new RequestError("emulation.tlsOptions.certificateCompressionAlgorithms must be an array");
1352
- }
1353
- const algorithms = [];
1354
- const seen = /* @__PURE__ */ new Set();
1355
- for (const algorithm of options.certificateCompressionAlgorithms) {
1356
- if (!SUPPORTED_CERTIFICATE_COMPRESSION_ALGORITHMS.has(algorithm)) {
1357
- throw new RequestError(
1358
- "emulation.tlsOptions.certificateCompressionAlgorithms values must be one of: zlib, brotli, zstd"
1359
- );
1360
- }
1361
- if (seen.has(algorithm)) {
1362
- throw new RequestError(`Duplicate emulation.tlsOptions.certificateCompressionAlgorithms entry: ${algorithm}`);
1363
- }
1364
- seen.add(algorithm);
1365
- algorithms.push(algorithm);
1366
- }
1367
- normalized.certificateCompressionAlgorithms = algorithms;
1368
- }
1369
- if (options.extensionPermutation !== void 0) {
1370
- if (!Array.isArray(options.extensionPermutation)) {
1371
- throw new RequestError("emulation.tlsOptions.extensionPermutation must be an array");
1372
- }
1373
- const permutation = [];
1374
- const seen = /* @__PURE__ */ new Set();
1375
- for (const extensionId of options.extensionPermutation) {
1376
- validateIntegerInRange(extensionId, 0, 65535, "emulation.tlsOptions.extensionPermutation");
1377
- if (seen.has(extensionId)) {
1378
- throw new RequestError(`Duplicate emulation.tlsOptions.extensionPermutation entry: ${extensionId}`);
1379
- }
1380
- seen.add(extensionId);
1381
- permutation.push(extensionId);
1382
- }
1383
- normalized.extensionPermutation = permutation;
1384
- }
1385
- return isNonEmpty(normalized) ? normalized : void 0;
1052
+ if (options === void 0) return;
1053
+ const normalized = {};
1054
+ const alpnProtocols = normalizeProtocolList(options.alpnProtocols, "emulation.tlsOptions.alpnProtocols", SUPPORTED_ALPN_PROTOCOLS);
1055
+ if (alpnProtocols !== void 0) normalized.alpnProtocols = alpnProtocols;
1056
+ const alpsProtocols = normalizeProtocolList(options.alpsProtocols, "emulation.tlsOptions.alpsProtocols", SUPPORTED_ALPS_PROTOCOLS);
1057
+ if (alpsProtocols !== void 0) normalized.alpsProtocols = alpsProtocols;
1058
+ const minTlsVersion = normalizeTlsVersion(options.minTlsVersion, "emulation.tlsOptions.minTlsVersion");
1059
+ if (minTlsVersion !== void 0) normalized.minTlsVersion = minTlsVersion;
1060
+ const maxTlsVersion = normalizeTlsVersion(options.maxTlsVersion, "emulation.tlsOptions.maxTlsVersion");
1061
+ if (maxTlsVersion !== void 0) normalized.maxTlsVersion = maxTlsVersion;
1062
+ if (options.alpsUseNewCodepoint !== void 0) normalized.alpsUseNewCodepoint = options.alpsUseNewCodepoint;
1063
+ if (options.sessionTicket !== void 0) normalized.sessionTicket = options.sessionTicket;
1064
+ if (options.preSharedKey !== void 0) normalized.preSharedKey = options.preSharedKey;
1065
+ if (options.enableEchGrease !== void 0) normalized.enableEchGrease = options.enableEchGrease;
1066
+ if (options.permuteExtensions !== void 0) normalized.permuteExtensions = options.permuteExtensions;
1067
+ if (options.greaseEnabled !== void 0) normalized.greaseEnabled = options.greaseEnabled;
1068
+ if (options.enableOcspStapling !== void 0) normalized.enableOcspStapling = options.enableOcspStapling;
1069
+ if (options.enableSignedCertTimestamps !== void 0) normalized.enableSignedCertTimestamps = options.enableSignedCertTimestamps;
1070
+ if (options.pskSkipSessionTicket !== void 0) normalized.pskSkipSessionTicket = options.pskSkipSessionTicket;
1071
+ if (options.pskDheKe !== void 0) normalized.pskDheKe = options.pskDheKe;
1072
+ if (options.renegotiation !== void 0) normalized.renegotiation = options.renegotiation;
1073
+ if (options.aesHwOverride !== void 0) normalized.aesHwOverride = options.aesHwOverride;
1074
+ if (options.preserveTls13CipherList !== void 0) normalized.preserveTls13CipherList = options.preserveTls13CipherList;
1075
+ if (options.randomAesHwOverride !== void 0) normalized.randomAesHwOverride = options.randomAesHwOverride;
1076
+ if (options.delegatedCredentials !== void 0) normalized.delegatedCredentials = options.delegatedCredentials;
1077
+ if (options.curvesList !== void 0) normalized.curvesList = options.curvesList;
1078
+ if (options.cipherList !== void 0) normalized.cipherList = options.cipherList;
1079
+ if (options.sigalgsList !== void 0) normalized.sigalgsList = options.sigalgsList;
1080
+ if (options.recordSizeLimit !== void 0) {
1081
+ validateIntegerInRange(options.recordSizeLimit, 0, 65535, "emulation.tlsOptions.recordSizeLimit");
1082
+ normalized.recordSizeLimit = options.recordSizeLimit;
1083
+ }
1084
+ if (options.keySharesLimit !== void 0) {
1085
+ validateIntegerInRange(options.keySharesLimit, 0, 255, "emulation.tlsOptions.keySharesLimit");
1086
+ normalized.keySharesLimit = options.keySharesLimit;
1087
+ }
1088
+ if (options.certificateCompressionAlgorithms !== void 0) {
1089
+ if (!Array.isArray(options.certificateCompressionAlgorithms)) throw new RequestError("emulation.tlsOptions.certificateCompressionAlgorithms must be an array");
1090
+ const algorithms = [];
1091
+ const seen = /* @__PURE__ */ new Set();
1092
+ for (const algorithm of options.certificateCompressionAlgorithms) {
1093
+ if (!SUPPORTED_CERTIFICATE_COMPRESSION_ALGORITHMS.has(algorithm)) throw new RequestError("emulation.tlsOptions.certificateCompressionAlgorithms values must be one of: zlib, brotli, zstd");
1094
+ if (seen.has(algorithm)) throw new RequestError(`Duplicate emulation.tlsOptions.certificateCompressionAlgorithms entry: ${algorithm}`);
1095
+ seen.add(algorithm);
1096
+ algorithms.push(algorithm);
1097
+ }
1098
+ normalized.certificateCompressionAlgorithms = algorithms;
1099
+ }
1100
+ if (options.extensionPermutation !== void 0) {
1101
+ if (!Array.isArray(options.extensionPermutation)) throw new RequestError("emulation.tlsOptions.extensionPermutation must be an array");
1102
+ const permutation = [];
1103
+ const seen = /* @__PURE__ */ new Set();
1104
+ for (const extensionId of options.extensionPermutation) {
1105
+ validateIntegerInRange(extensionId, 0, 65535, "emulation.tlsOptions.extensionPermutation");
1106
+ if (seen.has(extensionId)) throw new RequestError(`Duplicate emulation.tlsOptions.extensionPermutation entry: ${extensionId}`);
1107
+ seen.add(extensionId);
1108
+ permutation.push(extensionId);
1109
+ }
1110
+ normalized.extensionPermutation = permutation;
1111
+ }
1112
+ return isNonEmpty(normalized) ? normalized : void 0;
1386
1113
  }
1387
1114
  function normalizeCustomHttp1Options(options) {
1388
- if (options === void 0) {
1389
- return void 0;
1390
- }
1391
- const normalized = {};
1392
- if (options.http09Responses !== void 0) {
1393
- normalized.http09Responses = options.http09Responses;
1394
- }
1395
- if (options.writev !== void 0) {
1396
- normalized.writev = options.writev;
1397
- }
1398
- if (options.ignoreInvalidHeadersInResponses !== void 0) {
1399
- normalized.ignoreInvalidHeadersInResponses = options.ignoreInvalidHeadersInResponses;
1400
- }
1401
- if (options.allowSpacesAfterHeaderNameInResponses !== void 0) {
1402
- normalized.allowSpacesAfterHeaderNameInResponses = options.allowSpacesAfterHeaderNameInResponses;
1403
- }
1404
- if (options.allowObsoleteMultilineHeadersInResponses !== void 0) {
1405
- normalized.allowObsoleteMultilineHeadersInResponses = options.allowObsoleteMultilineHeadersInResponses;
1406
- }
1407
- if (options.maxHeaders !== void 0) {
1408
- validateNonNegativeInteger(options.maxHeaders, "emulation.http1Options.maxHeaders");
1409
- normalized.maxHeaders = options.maxHeaders;
1410
- }
1411
- if (options.readBufExactSize !== void 0) {
1412
- validateNonNegativeInteger(options.readBufExactSize, "emulation.http1Options.readBufExactSize");
1413
- normalized.readBufExactSize = options.readBufExactSize;
1414
- }
1415
- if (options.maxBufSize !== void 0) {
1416
- validateNonNegativeInteger(options.maxBufSize, "emulation.http1Options.maxBufSize");
1417
- if (options.maxBufSize < 8192) {
1418
- throw new RequestError("emulation.http1Options.maxBufSize must be greater than or equal to 8192");
1419
- }
1420
- normalized.maxBufSize = options.maxBufSize;
1421
- }
1422
- if (normalized.readBufExactSize !== void 0 && normalized.maxBufSize !== void 0) {
1423
- throw new RequestError("emulation.http1Options.readBufExactSize and maxBufSize cannot both be set");
1424
- }
1425
- return isNonEmpty(normalized) ? normalized : void 0;
1115
+ if (options === void 0) return;
1116
+ const normalized = {};
1117
+ if (options.http09Responses !== void 0) normalized.http09Responses = options.http09Responses;
1118
+ if (options.writev !== void 0) normalized.writev = options.writev;
1119
+ if (options.ignoreInvalidHeadersInResponses !== void 0) normalized.ignoreInvalidHeadersInResponses = options.ignoreInvalidHeadersInResponses;
1120
+ if (options.allowSpacesAfterHeaderNameInResponses !== void 0) normalized.allowSpacesAfterHeaderNameInResponses = options.allowSpacesAfterHeaderNameInResponses;
1121
+ if (options.allowObsoleteMultilineHeadersInResponses !== void 0) normalized.allowObsoleteMultilineHeadersInResponses = options.allowObsoleteMultilineHeadersInResponses;
1122
+ if (options.maxHeaders !== void 0) {
1123
+ validateNonNegativeInteger(options.maxHeaders, "emulation.http1Options.maxHeaders");
1124
+ normalized.maxHeaders = options.maxHeaders;
1125
+ }
1126
+ if (options.readBufExactSize !== void 0) {
1127
+ validateNonNegativeInteger(options.readBufExactSize, "emulation.http1Options.readBufExactSize");
1128
+ normalized.readBufExactSize = options.readBufExactSize;
1129
+ }
1130
+ if (options.maxBufSize !== void 0) {
1131
+ validateNonNegativeInteger(options.maxBufSize, "emulation.http1Options.maxBufSize");
1132
+ if (options.maxBufSize < 8192) throw new RequestError("emulation.http1Options.maxBufSize must be greater than or equal to 8192");
1133
+ normalized.maxBufSize = options.maxBufSize;
1134
+ }
1135
+ if (normalized.readBufExactSize !== void 0 && normalized.maxBufSize !== void 0) throw new RequestError("emulation.http1Options.readBufExactSize and maxBufSize cannot both be set");
1136
+ return isNonEmpty(normalized) ? normalized : void 0;
1426
1137
  }
1427
1138
  function normalizeHttp2StreamDependency(dependency, label) {
1428
- if (!isPlainObject(dependency)) {
1429
- throw new RequestError(`${label} must be an object`);
1430
- }
1431
- validateIntegerInRange(dependency.dependencyId, 0, 2147483647, `${label}.dependencyId`);
1432
- validateIntegerInRange(dependency.weight, 0, 255, `${label}.weight`);
1433
- const normalized = {
1434
- dependencyId: dependency.dependencyId,
1435
- weight: dependency.weight
1436
- };
1437
- if (dependency.exclusive !== void 0) {
1438
- normalized.exclusive = dependency.exclusive;
1439
- }
1440
- return normalized;
1139
+ if (!isPlainObject(dependency)) throw new RequestError(`${label} must be an object`);
1140
+ validateIntegerInRange(dependency.dependencyId, 0, 2147483647, `${label}.dependencyId`);
1141
+ validateIntegerInRange(dependency.weight, 0, 255, `${label}.weight`);
1142
+ const normalized = {
1143
+ dependencyId: dependency.dependencyId,
1144
+ weight: dependency.weight
1145
+ };
1146
+ if (dependency.exclusive !== void 0) normalized.exclusive = dependency.exclusive;
1147
+ return normalized;
1441
1148
  }
1442
1149
  function normalizeCustomHttp2Options(options) {
1443
- if (options === void 0) {
1444
- return void 0;
1445
- }
1446
- const normalized = {};
1447
- if (options.adaptiveWindow !== void 0) {
1448
- normalized.adaptiveWindow = options.adaptiveWindow;
1449
- }
1450
- if (options.keepAliveWhileIdle !== void 0) {
1451
- normalized.keepAliveWhileIdle = options.keepAliveWhileIdle;
1452
- }
1453
- if (options.enablePush !== void 0) {
1454
- normalized.enablePush = options.enablePush;
1455
- }
1456
- if (options.enableConnectProtocol !== void 0) {
1457
- normalized.enableConnectProtocol = options.enableConnectProtocol;
1458
- }
1459
- if (options.noRfc7540Priorities !== void 0) {
1460
- normalized.noRfc7540Priorities = options.noRfc7540Priorities;
1461
- }
1462
- if (options.initialStreamId !== void 0) {
1463
- validateNonNegativeInteger(options.initialStreamId, "emulation.http2Options.initialStreamId");
1464
- normalized.initialStreamId = options.initialStreamId;
1465
- }
1466
- if (options.initialConnectionWindowSize !== void 0) {
1467
- validateNonNegativeInteger(
1468
- options.initialConnectionWindowSize,
1469
- "emulation.http2Options.initialConnectionWindowSize"
1470
- );
1471
- normalized.initialConnectionWindowSize = options.initialConnectionWindowSize;
1472
- }
1473
- if (options.initialWindowSize !== void 0) {
1474
- validateNonNegativeInteger(options.initialWindowSize, "emulation.http2Options.initialWindowSize");
1475
- normalized.initialWindowSize = options.initialWindowSize;
1476
- }
1477
- if (options.initialMaxSendStreams !== void 0) {
1478
- validateNonNegativeInteger(options.initialMaxSendStreams, "emulation.http2Options.initialMaxSendStreams");
1479
- normalized.initialMaxSendStreams = options.initialMaxSendStreams;
1480
- }
1481
- if (options.maxFrameSize !== void 0) {
1482
- validateNonNegativeInteger(options.maxFrameSize, "emulation.http2Options.maxFrameSize");
1483
- normalized.maxFrameSize = options.maxFrameSize;
1484
- }
1485
- if (options.keepAliveInterval !== void 0) {
1486
- validateNonNegativeInteger(options.keepAliveInterval, "emulation.http2Options.keepAliveInterval");
1487
- normalized.keepAliveInterval = options.keepAliveInterval;
1488
- }
1489
- if (options.keepAliveTimeout !== void 0) {
1490
- validateNonNegativeInteger(options.keepAliveTimeout, "emulation.http2Options.keepAliveTimeout");
1491
- normalized.keepAliveTimeout = options.keepAliveTimeout;
1492
- }
1493
- if (options.maxConcurrentResetStreams !== void 0) {
1494
- validateNonNegativeInteger(options.maxConcurrentResetStreams, "emulation.http2Options.maxConcurrentResetStreams");
1495
- normalized.maxConcurrentResetStreams = options.maxConcurrentResetStreams;
1496
- }
1497
- if (options.maxSendBufferSize !== void 0) {
1498
- validateNonNegativeInteger(options.maxSendBufferSize, "emulation.http2Options.maxSendBufferSize");
1499
- normalized.maxSendBufferSize = options.maxSendBufferSize;
1500
- }
1501
- if (options.maxConcurrentStreams !== void 0) {
1502
- validateNonNegativeInteger(options.maxConcurrentStreams, "emulation.http2Options.maxConcurrentStreams");
1503
- normalized.maxConcurrentStreams = options.maxConcurrentStreams;
1504
- }
1505
- if (options.maxHeaderListSize !== void 0) {
1506
- validateNonNegativeInteger(options.maxHeaderListSize, "emulation.http2Options.maxHeaderListSize");
1507
- normalized.maxHeaderListSize = options.maxHeaderListSize;
1508
- }
1509
- if (options.maxPendingAcceptResetStreams !== void 0) {
1510
- validateNonNegativeInteger(
1511
- options.maxPendingAcceptResetStreams,
1512
- "emulation.http2Options.maxPendingAcceptResetStreams"
1513
- );
1514
- normalized.maxPendingAcceptResetStreams = options.maxPendingAcceptResetStreams;
1515
- }
1516
- if (options.headerTableSize !== void 0) {
1517
- validateNonNegativeInteger(options.headerTableSize, "emulation.http2Options.headerTableSize");
1518
- normalized.headerTableSize = options.headerTableSize;
1519
- }
1520
- if (options.settingsOrder !== void 0) {
1521
- if (!Array.isArray(options.settingsOrder)) {
1522
- throw new RequestError("emulation.http2Options.settingsOrder must be an array");
1523
- }
1524
- const settingsOrder = [];
1525
- const seen = /* @__PURE__ */ new Set();
1526
- for (const settingId of options.settingsOrder) {
1527
- if (!HTTP2_SETTING_IDS.has(settingId)) {
1528
- throw new RequestError("emulation.http2Options.settingsOrder contains an unsupported setting id");
1529
- }
1530
- if (seen.has(settingId)) {
1531
- throw new RequestError(`Duplicate emulation.http2Options.settingsOrder entry: ${settingId}`);
1532
- }
1533
- seen.add(settingId);
1534
- settingsOrder.push(settingId);
1535
- }
1536
- normalized.settingsOrder = settingsOrder;
1537
- }
1538
- if (options.headersPseudoOrder !== void 0) {
1539
- if (!Array.isArray(options.headersPseudoOrder)) {
1540
- throw new RequestError("emulation.http2Options.headersPseudoOrder must be an array");
1541
- }
1542
- const headersPseudoOrder = [];
1543
- const seenPseudo = /* @__PURE__ */ new Set();
1544
- for (const pseudoId of options.headersPseudoOrder) {
1545
- if (!HTTP2_PSEUDO_HEADER_IDS.has(pseudoId)) {
1546
- throw new RequestError("emulation.http2Options.headersPseudoOrder contains an unsupported pseudo-header id");
1547
- }
1548
- if (seenPseudo.has(pseudoId)) {
1549
- throw new RequestError(`Duplicate emulation.http2Options.headersPseudoOrder entry: ${pseudoId}`);
1550
- }
1551
- seenPseudo.add(pseudoId);
1552
- headersPseudoOrder.push(pseudoId);
1553
- }
1554
- normalized.headersPseudoOrder = headersPseudoOrder;
1555
- }
1556
- if (options.headersStreamDependency !== void 0) {
1557
- normalized.headersStreamDependency = normalizeHttp2StreamDependency(
1558
- options.headersStreamDependency,
1559
- "emulation.http2Options.headersStreamDependency"
1560
- );
1561
- }
1562
- if (options.priorities !== void 0) {
1563
- if (!Array.isArray(options.priorities)) {
1564
- throw new RequestError("emulation.http2Options.priorities must be an array");
1565
- }
1566
- const priorities = [];
1567
- const seenStreamIds = /* @__PURE__ */ new Set();
1568
- for (const [index, priority] of options.priorities.entries()) {
1569
- if (!isPlainObject(priority)) {
1570
- throw new RequestError(`emulation.http2Options.priorities[${index}] must be an object`);
1571
- }
1572
- validatePositiveInteger(priority.streamId, `emulation.http2Options.priorities[${index}].streamId`);
1573
- if (seenStreamIds.has(priority.streamId)) {
1574
- throw new RequestError(`Duplicate emulation.http2Options.priorities streamId: ${priority.streamId}`);
1575
- }
1576
- seenStreamIds.add(priority.streamId);
1577
- priorities.push({
1578
- streamId: priority.streamId,
1579
- dependency: normalizeHttp2StreamDependency(
1580
- priority.dependency,
1581
- `emulation.http2Options.priorities[${index}].dependency`
1582
- )
1583
- });
1584
- }
1585
- normalized.priorities = priorities;
1586
- }
1587
- if (options.experimentalSettings !== void 0) {
1588
- if (!Array.isArray(options.experimentalSettings)) {
1589
- throw new RequestError("emulation.http2Options.experimentalSettings must be an array");
1590
- }
1591
- const experimentalSettings = [];
1592
- const seenIds = /* @__PURE__ */ new Set();
1593
- for (const [index, setting] of options.experimentalSettings.entries()) {
1594
- if (!isPlainObject(setting)) {
1595
- throw new RequestError(`emulation.http2Options.experimentalSettings[${index}] must be an object`);
1596
- }
1597
- validateIntegerInRange(
1598
- setting.id,
1599
- 1,
1600
- MAX_HTTP2_EXPERIMENTAL_SETTING_ID,
1601
- `emulation.http2Options.experimentalSettings[${index}].id`
1602
- );
1603
- if (STANDARD_HTTP2_SETTING_ID_VALUES.has(setting.id)) {
1604
- throw new RequestError(
1605
- `emulation.http2Options.experimentalSettings[${index}].id must not be a standard HTTP/2 setting id`
1606
- );
1607
- }
1608
- if (seenIds.has(setting.id)) {
1609
- throw new RequestError(`Duplicate emulation.http2Options.experimentalSettings id: ${setting.id}`);
1610
- }
1611
- seenIds.add(setting.id);
1612
- validateIntegerInRange(
1613
- setting.value,
1614
- 0,
1615
- 4294967295,
1616
- `emulation.http2Options.experimentalSettings[${index}].value`
1617
- );
1618
- experimentalSettings.push({
1619
- id: setting.id,
1620
- value: setting.value
1621
- });
1622
- }
1623
- normalized.experimentalSettings = experimentalSettings;
1624
- }
1625
- return isNonEmpty(normalized) ? normalized : void 0;
1150
+ if (options === void 0) return;
1151
+ const normalized = {};
1152
+ if (options.adaptiveWindow !== void 0) normalized.adaptiveWindow = options.adaptiveWindow;
1153
+ if (options.keepAliveWhileIdle !== void 0) normalized.keepAliveWhileIdle = options.keepAliveWhileIdle;
1154
+ if (options.enablePush !== void 0) normalized.enablePush = options.enablePush;
1155
+ if (options.enableConnectProtocol !== void 0) normalized.enableConnectProtocol = options.enableConnectProtocol;
1156
+ if (options.noRfc7540Priorities !== void 0) normalized.noRfc7540Priorities = options.noRfc7540Priorities;
1157
+ if (options.initialStreamId !== void 0) {
1158
+ validateNonNegativeInteger(options.initialStreamId, "emulation.http2Options.initialStreamId");
1159
+ normalized.initialStreamId = options.initialStreamId;
1160
+ }
1161
+ if (options.initialConnectionWindowSize !== void 0) {
1162
+ validateNonNegativeInteger(options.initialConnectionWindowSize, "emulation.http2Options.initialConnectionWindowSize");
1163
+ normalized.initialConnectionWindowSize = options.initialConnectionWindowSize;
1164
+ }
1165
+ if (options.initialWindowSize !== void 0) {
1166
+ validateNonNegativeInteger(options.initialWindowSize, "emulation.http2Options.initialWindowSize");
1167
+ normalized.initialWindowSize = options.initialWindowSize;
1168
+ }
1169
+ if (options.initialMaxSendStreams !== void 0) {
1170
+ validateNonNegativeInteger(options.initialMaxSendStreams, "emulation.http2Options.initialMaxSendStreams");
1171
+ normalized.initialMaxSendStreams = options.initialMaxSendStreams;
1172
+ }
1173
+ if (options.maxFrameSize !== void 0) {
1174
+ validateNonNegativeInteger(options.maxFrameSize, "emulation.http2Options.maxFrameSize");
1175
+ normalized.maxFrameSize = options.maxFrameSize;
1176
+ }
1177
+ if (options.keepAliveInterval !== void 0) {
1178
+ validateNonNegativeInteger(options.keepAliveInterval, "emulation.http2Options.keepAliveInterval");
1179
+ normalized.keepAliveInterval = options.keepAliveInterval;
1180
+ }
1181
+ if (options.keepAliveTimeout !== void 0) {
1182
+ validateNonNegativeInteger(options.keepAliveTimeout, "emulation.http2Options.keepAliveTimeout");
1183
+ normalized.keepAliveTimeout = options.keepAliveTimeout;
1184
+ }
1185
+ if (options.maxConcurrentResetStreams !== void 0) {
1186
+ validateNonNegativeInteger(options.maxConcurrentResetStreams, "emulation.http2Options.maxConcurrentResetStreams");
1187
+ normalized.maxConcurrentResetStreams = options.maxConcurrentResetStreams;
1188
+ }
1189
+ if (options.maxSendBufferSize !== void 0) {
1190
+ validateNonNegativeInteger(options.maxSendBufferSize, "emulation.http2Options.maxSendBufferSize");
1191
+ normalized.maxSendBufferSize = options.maxSendBufferSize;
1192
+ }
1193
+ if (options.maxConcurrentStreams !== void 0) {
1194
+ validateNonNegativeInteger(options.maxConcurrentStreams, "emulation.http2Options.maxConcurrentStreams");
1195
+ normalized.maxConcurrentStreams = options.maxConcurrentStreams;
1196
+ }
1197
+ if (options.maxHeaderListSize !== void 0) {
1198
+ validateNonNegativeInteger(options.maxHeaderListSize, "emulation.http2Options.maxHeaderListSize");
1199
+ normalized.maxHeaderListSize = options.maxHeaderListSize;
1200
+ }
1201
+ if (options.maxPendingAcceptResetStreams !== void 0) {
1202
+ validateNonNegativeInteger(options.maxPendingAcceptResetStreams, "emulation.http2Options.maxPendingAcceptResetStreams");
1203
+ normalized.maxPendingAcceptResetStreams = options.maxPendingAcceptResetStreams;
1204
+ }
1205
+ if (options.headerTableSize !== void 0) {
1206
+ validateNonNegativeInteger(options.headerTableSize, "emulation.http2Options.headerTableSize");
1207
+ normalized.headerTableSize = options.headerTableSize;
1208
+ }
1209
+ if (options.settingsOrder !== void 0) {
1210
+ if (!Array.isArray(options.settingsOrder)) throw new RequestError("emulation.http2Options.settingsOrder must be an array");
1211
+ const settingsOrder = [];
1212
+ const seen = /* @__PURE__ */ new Set();
1213
+ for (const settingId of options.settingsOrder) {
1214
+ if (!HTTP2_SETTING_IDS.has(settingId)) throw new RequestError("emulation.http2Options.settingsOrder contains an unsupported setting id");
1215
+ if (seen.has(settingId)) throw new RequestError(`Duplicate emulation.http2Options.settingsOrder entry: ${settingId}`);
1216
+ seen.add(settingId);
1217
+ settingsOrder.push(settingId);
1218
+ }
1219
+ normalized.settingsOrder = settingsOrder;
1220
+ }
1221
+ if (options.headersPseudoOrder !== void 0) {
1222
+ if (!Array.isArray(options.headersPseudoOrder)) throw new RequestError("emulation.http2Options.headersPseudoOrder must be an array");
1223
+ const headersPseudoOrder = [];
1224
+ const seenPseudo = /* @__PURE__ */ new Set();
1225
+ for (const pseudoId of options.headersPseudoOrder) {
1226
+ if (!HTTP2_PSEUDO_HEADER_IDS.has(pseudoId)) throw new RequestError("emulation.http2Options.headersPseudoOrder contains an unsupported pseudo-header id");
1227
+ if (seenPseudo.has(pseudoId)) throw new RequestError(`Duplicate emulation.http2Options.headersPseudoOrder entry: ${pseudoId}`);
1228
+ seenPseudo.add(pseudoId);
1229
+ headersPseudoOrder.push(pseudoId);
1230
+ }
1231
+ normalized.headersPseudoOrder = headersPseudoOrder;
1232
+ }
1233
+ if (options.headersStreamDependency !== void 0) normalized.headersStreamDependency = normalizeHttp2StreamDependency(options.headersStreamDependency, "emulation.http2Options.headersStreamDependency");
1234
+ if (options.priorities !== void 0) {
1235
+ if (!Array.isArray(options.priorities)) throw new RequestError("emulation.http2Options.priorities must be an array");
1236
+ const priorities = [];
1237
+ const seenStreamIds = /* @__PURE__ */ new Set();
1238
+ for (const [index, priority] of options.priorities.entries()) {
1239
+ if (!isPlainObject(priority)) throw new RequestError(`emulation.http2Options.priorities[${index}] must be an object`);
1240
+ validatePositiveInteger(priority.streamId, `emulation.http2Options.priorities[${index}].streamId`);
1241
+ if (seenStreamIds.has(priority.streamId)) throw new RequestError(`Duplicate emulation.http2Options.priorities streamId: ${priority.streamId}`);
1242
+ seenStreamIds.add(priority.streamId);
1243
+ priorities.push({
1244
+ streamId: priority.streamId,
1245
+ dependency: normalizeHttp2StreamDependency(priority.dependency, `emulation.http2Options.priorities[${index}].dependency`)
1246
+ });
1247
+ }
1248
+ normalized.priorities = priorities;
1249
+ }
1250
+ if (options.experimentalSettings !== void 0) {
1251
+ if (!Array.isArray(options.experimentalSettings)) throw new RequestError("emulation.http2Options.experimentalSettings must be an array");
1252
+ const experimentalSettings = [];
1253
+ const seenIds = /* @__PURE__ */ new Set();
1254
+ for (const [index, setting] of options.experimentalSettings.entries()) {
1255
+ if (!isPlainObject(setting)) throw new RequestError(`emulation.http2Options.experimentalSettings[${index}] must be an object`);
1256
+ validateIntegerInRange(setting.id, 1, MAX_HTTP2_EXPERIMENTAL_SETTING_ID, `emulation.http2Options.experimentalSettings[${index}].id`);
1257
+ if (STANDARD_HTTP2_SETTING_ID_VALUES.has(setting.id)) throw new RequestError(`emulation.http2Options.experimentalSettings[${index}].id must not be a standard HTTP/2 setting id`);
1258
+ if (seenIds.has(setting.id)) throw new RequestError(`Duplicate emulation.http2Options.experimentalSettings id: ${setting.id}`);
1259
+ seenIds.add(setting.id);
1260
+ validateIntegerInRange(setting.value, 0, 4294967295, `emulation.http2Options.experimentalSettings[${index}].value`);
1261
+ experimentalSettings.push({
1262
+ id: setting.id,
1263
+ value: setting.value
1264
+ });
1265
+ }
1266
+ normalized.experimentalSettings = experimentalSettings;
1267
+ }
1268
+ return isNonEmpty(normalized) ? normalized : void 0;
1626
1269
  }
1627
1270
  function normalizeCustomEmulationOptions(emulation, allowEmpty) {
1628
- if (emulation === void 0) {
1629
- return void 0;
1630
- }
1631
- if (!isPlainObject(emulation)) {
1632
- throw new RequestError("emulation must be an object");
1633
- }
1634
- const source = emulation;
1635
- const normalized = {};
1636
- const tlsOptions = normalizeCustomTlsOptions(source.tlsOptions);
1637
- if (tlsOptions !== void 0) {
1638
- normalized.tlsOptions = tlsOptions;
1639
- }
1640
- const http1Options = normalizeCustomHttp1Options(source.http1Options);
1641
- if (http1Options !== void 0) {
1642
- normalized.http1Options = http1Options;
1643
- }
1644
- const http2Options = normalizeCustomHttp2Options(source.http2Options);
1645
- if (http2Options !== void 0) {
1646
- normalized.http2Options = http2Options;
1647
- }
1648
- if (source.headers !== void 0) {
1649
- const headers = headersToTuples(source.headers);
1650
- if (headers.length > 0) {
1651
- normalized.headers = headers;
1652
- }
1653
- }
1654
- const origHeaders = normalizeOrigHeaders(source.origHeaders);
1655
- if (origHeaders !== void 0) {
1656
- normalized.origHeaders = origHeaders;
1657
- }
1658
- if (!allowEmpty && !isNonEmpty(normalized)) {
1659
- throw new RequestError(
1660
- "Standalone custom emulation requires at least one of tlsOptions, http1Options, http2Options, headers, or origHeaders"
1661
- );
1662
- }
1663
- return isNonEmpty(normalized) ? normalized : void 0;
1271
+ if (emulation === void 0) return;
1272
+ if (!isPlainObject(emulation)) throw new RequestError("emulation must be an object");
1273
+ const source = emulation;
1274
+ const normalized = {};
1275
+ const tlsOptions = normalizeCustomTlsOptions(source.tlsOptions);
1276
+ if (tlsOptions !== void 0) normalized.tlsOptions = tlsOptions;
1277
+ const http1Options = normalizeCustomHttp1Options(source.http1Options);
1278
+ if (http1Options !== void 0) normalized.http1Options = http1Options;
1279
+ const http2Options = normalizeCustomHttp2Options(source.http2Options);
1280
+ if (http2Options !== void 0) normalized.http2Options = http2Options;
1281
+ if (source.headers !== void 0) {
1282
+ const headers = headersToTuples(source.headers);
1283
+ if (headers.length > 0) normalized.headers = headers;
1284
+ }
1285
+ const origHeaders = normalizeOrigHeaders(source.origHeaders);
1286
+ if (origHeaders !== void 0) normalized.origHeaders = origHeaders;
1287
+ if (!allowEmpty && !isNonEmpty(normalized)) throw new RequestError("Standalone custom emulation requires at least one of tlsOptions, http1Options, http2Options, headers, or origHeaders");
1288
+ return isNonEmpty(normalized) ? normalized : void 0;
1664
1289
  }
1665
1290
  function serializeCustomEmulationOptions(emulation, allowEmpty) {
1666
- const normalized = normalizeCustomEmulationOptions(emulation, allowEmpty);
1667
- return normalized ? JSON.stringify(normalized) : void 0;
1291
+ const normalized = normalizeCustomEmulationOptions(emulation, allowEmpty);
1292
+ return normalized ? JSON.stringify(normalized) : void 0;
1668
1293
  }
1669
1294
  function resolveEmulationMode(browser, os, emulation) {
1670
- if (browser !== void 0) {
1671
- validateBrowserProfile(browser);
1672
- if (os !== void 0) {
1673
- validateOperatingSystem(os);
1674
- }
1675
- const emulationJson = serializeCustomEmulationOptions(emulation, true);
1676
- return {
1677
- kind: "preset",
1678
- browser,
1679
- os: os ?? DEFAULT_OS,
1680
- ...emulationJson !== void 0 && { emulationJson }
1681
- };
1682
- }
1683
- if (os !== void 0) {
1684
- validateOperatingSystem(os);
1685
- const emulationJson = serializeCustomEmulationOptions(emulation, true);
1686
- return {
1687
- kind: "preset",
1688
- browser: DEFAULT_BROWSER,
1689
- os,
1690
- ...emulationJson !== void 0 && { emulationJson }
1691
- };
1692
- }
1693
- if (emulation !== void 0) {
1694
- const emulationJson = serializeCustomEmulationOptions(emulation, false);
1695
- if (emulationJson === void 0) {
1696
- throw new RequestError(
1697
- "Standalone custom emulation requires at least one of tlsOptions, http1Options, http2Options, headers, or origHeaders"
1698
- );
1699
- }
1700
- return { kind: "custom", emulationJson };
1701
- }
1702
- return {
1703
- kind: "preset",
1704
- browser: DEFAULT_BROWSER,
1705
- os: DEFAULT_OS
1706
- };
1295
+ if (browser !== void 0) {
1296
+ validateBrowserProfile(browser);
1297
+ if (os !== void 0) validateOperatingSystem(os);
1298
+ const emulationJson = serializeCustomEmulationOptions(emulation, true);
1299
+ return {
1300
+ kind: "preset",
1301
+ browser,
1302
+ os: os ?? DEFAULT_OS,
1303
+ ...emulationJson !== void 0 && { emulationJson }
1304
+ };
1305
+ }
1306
+ if (os !== void 0) {
1307
+ validateOperatingSystem(os);
1308
+ const emulationJson = serializeCustomEmulationOptions(emulation, true);
1309
+ return {
1310
+ kind: "preset",
1311
+ browser: DEFAULT_BROWSER,
1312
+ os,
1313
+ ...emulationJson !== void 0 && { emulationJson }
1314
+ };
1315
+ }
1316
+ if (emulation !== void 0) {
1317
+ const emulationJson = serializeCustomEmulationOptions(emulation, false);
1318
+ if (emulationJson === void 0) throw new RequestError("Standalone custom emulation requires at least one of tlsOptions, http1Options, http2Options, headers, or origHeaders");
1319
+ return {
1320
+ kind: "custom",
1321
+ emulationJson
1322
+ };
1323
+ }
1324
+ return {
1325
+ kind: "preset",
1326
+ browser: DEFAULT_BROWSER,
1327
+ os: DEFAULT_OS
1328
+ };
1707
1329
  }
1708
1330
  function applyNativeEmulationMode(target, mode) {
1709
- if (mode.kind === "custom") {
1710
- target.emulationJson = mode.emulationJson;
1711
- return;
1712
- }
1713
- target.browser = mode.browser;
1714
- target.os = mode.os;
1715
- if (mode.emulationJson !== void 0) {
1716
- target.emulationJson = mode.emulationJson;
1717
- }
1331
+ if (mode.kind === "custom") {
1332
+ target.emulationJson = mode.emulationJson;
1333
+ return;
1334
+ }
1335
+ target.browser = mode.browser;
1336
+ target.os = mode.os;
1337
+ if (mode.emulationJson !== void 0) target.emulationJson = mode.emulationJson;
1718
1338
  }
1719
1339
  async function dispatchRequest(options, requestUrl, signal) {
1720
- if (!signal) {
1721
- const requestId2 = generateRequestId();
1722
- let payload2;
1723
- try {
1724
- payload2 = await nativeBinding.request(options, requestId2, false);
1725
- } catch (error) {
1726
- if (error instanceof RequestError) {
1727
- throw error;
1728
- }
1729
- throw new RequestError(String(error));
1730
- }
1731
- return new Response(payload2, requestUrl);
1732
- }
1733
- const requestId = generateRequestId();
1734
- const cancelNative = () => {
1735
- try {
1736
- nativeBinding.cancelRequest(requestId);
1737
- } catch {
1738
- }
1739
- };
1740
- const abortHandler = setupAbort(signal, cancelNative);
1741
- const pending = Promise.race([nativeBinding.request(options, requestId, true), abortHandler.promise]);
1742
- let payload;
1743
- try {
1744
- payload = await pending;
1745
- } catch (error) {
1746
- if (isAbortError(error)) {
1747
- throw error;
1748
- }
1749
- if (error instanceof RequestError) {
1750
- throw error;
1751
- }
1752
- throw new RequestError(String(error));
1753
- } finally {
1754
- abortHandler.cleanup();
1755
- }
1756
- return new Response(payload, requestUrl);
1757
- }
1340
+ if (!signal) {
1341
+ const requestId = generateRequestId();
1342
+ let payload;
1343
+ try {
1344
+ payload = await nativeBinding.request(options, requestId, false);
1345
+ } catch (error) {
1346
+ if (error instanceof RequestError) throw error;
1347
+ throw new RequestError(String(error));
1348
+ }
1349
+ return new Response(payload, requestUrl);
1350
+ }
1351
+ const requestId = generateRequestId();
1352
+ const cancelNative = () => {
1353
+ try {
1354
+ nativeBinding.cancelRequest(requestId);
1355
+ } catch {}
1356
+ };
1357
+ const abortHandler = setupAbort(signal, cancelNative);
1358
+ const pending = Promise.race([nativeBinding.request(options, requestId, true), abortHandler.promise]);
1359
+ let payload;
1360
+ try {
1361
+ payload = await pending;
1362
+ } catch (error) {
1363
+ if (isAbortError(error)) throw error;
1364
+ if (error instanceof RequestError) throw error;
1365
+ throw new RequestError(String(error));
1366
+ } finally {
1367
+ abortHandler.cleanup();
1368
+ }
1369
+ return new Response(payload, requestUrl);
1370
+ }
1371
+ /**
1372
+ * Fetch-compatible entry point that adds browser impersonation controls.
1373
+ *
1374
+ * **Important:** The default fetch path is isolated and non-persistent by design.
1375
+ * Each call uses an isolated request context, so cookies are not shared across calls.
1376
+ * Connection and TLS reuse behavior is handled by the native layer.
1377
+ *
1378
+ * **Use {@link createSession} or {@link withSession} if you need:**
1379
+ * - Cookie persistence across requests
1380
+ * - Shared session defaults across requests
1381
+ * - A single session context for multi-step flows
1382
+ *
1383
+ * **Concurrency:** The core is unthrottled by design. Callers are expected to implement
1384
+ * their own concurrency control (e.g., p-limit) if needed. Built-in throttling would
1385
+ * reduce performance for high-throughput workloads.
1386
+ *
1387
+ * @param input - Request URL (string or URL) or a Request object
1388
+ * @param init - Fetch-compatible init options
1389
+ *
1390
+ * @example
1391
+ * ```typescript
1392
+ * // Isolated request (no state persistence)
1393
+ * const response = await fetch('https://example.com');
1394
+ *
1395
+ * // For persistent cookies and connection reuse, use a session:
1396
+ * await withSession(async (session) => {
1397
+ * await session.fetch('https://example.com/login', { method: 'POST', body: loginData });
1398
+ * await session.fetch('https://example.com/protected'); // Cookies from login are sent
1399
+ * });
1400
+ * ```
1401
+ */
1758
1402
  async function fetch(input, init) {
1759
- const resolved = await resolveFetchArgs(input, init);
1760
- const url = resolved.url;
1761
- const config = resolved.init;
1762
- const sessionContext = resolveSessionContext(config);
1763
- const sessionDefaults = sessionContext.defaults;
1764
- validateRedirectMode(config.redirect);
1765
- if (config.timeout !== void 0) {
1766
- validateTimeout(config.timeout);
1767
- }
1768
- const method = ensureMethod(config.method);
1769
- const serializedBody = await serializeBody(config.body ?? null);
1770
- const body = serializedBody.body;
1771
- ensureBodyAllowed(method, body);
1772
- let headerTuples = mergeHeaderTuples(sessionDefaults?.defaultHeaders, config.headers);
1773
- if (serializedBody.contentType && !hasHeaderName(headerTuples, "content-type")) {
1774
- if (!headerTuples) {
1775
- headerTuples = [];
1776
- }
1777
- headerTuples.push(["Content-Type", serializedBody.contentType]);
1778
- }
1779
- const transport = resolveTransportContext(config, sessionDefaults);
1780
- const timeout = config.timeout ?? sessionDefaults?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
1781
- const requestOptions = {
1782
- url,
1783
- method,
1784
- sessionId: sessionContext.sessionId,
1785
- ephemeral: sessionContext.dropAfterRequest
1786
- };
1787
- if (body !== void 0) {
1788
- requestOptions.body = body;
1789
- }
1790
- if (transport.transportId) {
1791
- requestOptions.transportId = transport.transportId;
1792
- } else {
1793
- if (transport.mode !== void 0) {
1794
- applyNativeEmulationMode(requestOptions, transport.mode);
1795
- }
1796
- if (transport.proxy !== void 0) {
1797
- requestOptions.proxy = transport.proxy;
1798
- }
1799
- if (transport.insecure !== void 0) {
1800
- requestOptions.insecure = transport.insecure;
1801
- }
1802
- }
1803
- requestOptions.timeout = timeout;
1804
- if (config.redirect !== void 0) {
1805
- requestOptions.redirect = config.redirect;
1806
- }
1807
- if (config.disableDefaultHeaders !== void 0) {
1808
- requestOptions.disableDefaultHeaders = config.disableDefaultHeaders;
1809
- }
1810
- if (config.compress !== void 0) {
1811
- requestOptions.compress = config.compress;
1812
- }
1813
- if (headerTuples && headerTuples.length > 0) {
1814
- requestOptions.headers = headerTuples;
1815
- }
1816
- return dispatchRequest(requestOptions, url, config.signal ?? null);
1403
+ const resolved = await resolveFetchArgs(input, init);
1404
+ const url = resolved.url;
1405
+ const config = resolved.init;
1406
+ const sessionContext = resolveSessionContext(config);
1407
+ const sessionDefaults = sessionContext.defaults;
1408
+ validateRedirectMode(config.redirect);
1409
+ if (config.timeout !== void 0) validateTimeout(config.timeout);
1410
+ validateTrustStore(config.trustStore);
1411
+ const method = ensureMethod(config.method);
1412
+ const serializedBody = await serializeBody(config.body ?? null);
1413
+ const body = serializedBody.body;
1414
+ ensureBodyAllowed(method, body);
1415
+ let headerTuples = mergeHeaderTuples(sessionDefaults?.defaultHeaders, config.headers);
1416
+ if (serializedBody.contentType && !hasHeaderName(headerTuples, "content-type")) {
1417
+ if (!headerTuples) headerTuples = [];
1418
+ headerTuples.push(["Content-Type", serializedBody.contentType]);
1419
+ }
1420
+ const transport = resolveTransportContext(config, sessionDefaults);
1421
+ const timeout = config.timeout ?? sessionDefaults?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
1422
+ const requestOptions = {
1423
+ url,
1424
+ method,
1425
+ sessionId: sessionContext.sessionId,
1426
+ ephemeral: sessionContext.dropAfterRequest
1427
+ };
1428
+ if (body !== void 0) requestOptions.body = body;
1429
+ if (transport.captureDiagnostics !== void 0) requestOptions.captureDiagnostics = transport.captureDiagnostics;
1430
+ if (config.onRequestEvent !== void 0) requestOptions.onRequestEvent = config.onRequestEvent;
1431
+ if (transport.transportId) requestOptions.transportId = transport.transportId;
1432
+ else {
1433
+ if (transport.mode !== void 0) applyNativeEmulationMode(requestOptions, transport.mode);
1434
+ if (transport.proxy !== void 0) requestOptions.proxy = transport.proxy;
1435
+ if (transport.insecure !== void 0) requestOptions.insecure = transport.insecure;
1436
+ if (transport.trustStore !== void 0) requestOptions.trustStore = transport.trustStore;
1437
+ }
1438
+ requestOptions.timeout = timeout;
1439
+ if (config.redirect !== void 0) requestOptions.redirect = config.redirect;
1440
+ if (config.disableDefaultHeaders !== void 0) requestOptions.disableDefaultHeaders = config.disableDefaultHeaders;
1441
+ if (config.compress !== void 0) requestOptions.compress = config.compress;
1442
+ if (headerTuples && headerTuples.length > 0) requestOptions.headers = headerTuples;
1443
+ return dispatchRequest(requestOptions, url, config.signal ?? null);
1817
1444
  }
1818
1445
  async function createTransport(options) {
1819
- const mode = resolveEmulationMode(options?.browser, options?.os, options?.emulation);
1820
- if (options?.poolIdleTimeout !== void 0) {
1821
- validatePositiveNumber(options.poolIdleTimeout, "poolIdleTimeout");
1822
- }
1823
- if (options?.poolMaxIdlePerHost !== void 0) {
1824
- validateNonNegativeInteger(options.poolMaxIdlePerHost, "poolMaxIdlePerHost");
1825
- }
1826
- if (options?.poolMaxSize !== void 0) {
1827
- validatePositiveInteger(options.poolMaxSize, "poolMaxSize");
1828
- }
1829
- if (options?.connectTimeout !== void 0) {
1830
- validatePositiveNumber(options.connectTimeout, "connectTimeout");
1831
- }
1832
- if (options?.readTimeout !== void 0) {
1833
- validatePositiveNumber(options.readTimeout, "readTimeout");
1834
- }
1835
- try {
1836
- const transportOptions = {
1837
- ...options?.proxy !== void 0 && { proxy: options.proxy },
1838
- ...options?.insecure !== void 0 && { insecure: options.insecure },
1839
- ...options?.poolIdleTimeout !== void 0 && { poolIdleTimeout: options.poolIdleTimeout },
1840
- ...options?.poolMaxIdlePerHost !== void 0 && { poolMaxIdlePerHost: options.poolMaxIdlePerHost },
1841
- ...options?.poolMaxSize !== void 0 && { poolMaxSize: options.poolMaxSize },
1842
- ...options?.connectTimeout !== void 0 && { connectTimeout: options.connectTimeout },
1843
- ...options?.readTimeout !== void 0 && { readTimeout: options.readTimeout }
1844
- };
1845
- applyNativeEmulationMode(transportOptions, mode);
1846
- const id = nativeBinding.createTransport(transportOptions);
1847
- return new Transport(id);
1848
- } catch (error) {
1849
- throw new RequestError(String(error));
1850
- }
1446
+ const mode = resolveEmulationMode(options?.browser, options?.os, options?.emulation);
1447
+ validateTrustStore(options?.trustStore);
1448
+ if (options?.poolIdleTimeout !== void 0) validatePositiveNumber(options.poolIdleTimeout, "poolIdleTimeout");
1449
+ if (options?.poolMaxIdlePerHost !== void 0) validateNonNegativeInteger(options.poolMaxIdlePerHost, "poolMaxIdlePerHost");
1450
+ if (options?.poolMaxSize !== void 0) validatePositiveInteger(options.poolMaxSize, "poolMaxSize");
1451
+ if (options?.connectTimeout !== void 0) validatePositiveNumber(options.connectTimeout, "connectTimeout");
1452
+ if (options?.readTimeout !== void 0) validatePositiveNumber(options.readTimeout, "readTimeout");
1453
+ try {
1454
+ const transportOptions = {
1455
+ ...options?.proxy !== void 0 && { proxy: options.proxy },
1456
+ ...options?.insecure !== void 0 && { insecure: options.insecure },
1457
+ trustStore: options?.trustStore ?? DEFAULT_TRUST_STORE,
1458
+ ...options?.poolIdleTimeout !== void 0 && { poolIdleTimeout: options.poolIdleTimeout },
1459
+ ...options?.poolMaxIdlePerHost !== void 0 && { poolMaxIdlePerHost: options.poolMaxIdlePerHost },
1460
+ ...options?.poolMaxSize !== void 0 && { poolMaxSize: options.poolMaxSize },
1461
+ ...options?.connectTimeout !== void 0 && { connectTimeout: options.connectTimeout },
1462
+ ...options?.readTimeout !== void 0 && { readTimeout: options.readTimeout },
1463
+ ...options?.captureDiagnostics !== void 0 && { captureDiagnostics: options.captureDiagnostics }
1464
+ };
1465
+ applyNativeEmulationMode(transportOptions, mode);
1466
+ return new Transport(nativeBinding.createTransport(transportOptions));
1467
+ } catch (error) {
1468
+ throw new RequestError(String(error));
1469
+ }
1851
1470
  }
1852
1471
  async function createSession(options) {
1853
- const { sessionId, defaults } = normalizeSessionOptions(options);
1854
- let createdId;
1855
- let transportId;
1856
- try {
1857
- const transportOptions = {
1858
- ...defaults.proxy !== void 0 && { proxy: defaults.proxy },
1859
- ...defaults.insecure !== void 0 && { insecure: defaults.insecure }
1860
- };
1861
- applyNativeEmulationMode(transportOptions, defaults.transportMode);
1862
- transportId = nativeBinding.createTransport(transportOptions);
1863
- } catch (error) {
1864
- throw new RequestError(String(error));
1865
- }
1866
- try {
1867
- createdId = nativeBinding.createSession({
1868
- sessionId
1869
- });
1870
- } catch (error) {
1871
- try {
1872
- nativeBinding.dropTransport(transportId);
1873
- } catch {
1874
- }
1875
- throw new RequestError(String(error));
1876
- }
1877
- defaults.transportId = transportId;
1878
- defaults.ownsTransport = true;
1879
- return new Session(createdId, defaults);
1472
+ const { sessionId, defaults } = normalizeSessionOptions(options);
1473
+ let createdId;
1474
+ let transportId;
1475
+ try {
1476
+ const transportOptions = {
1477
+ ...defaults.proxy !== void 0 && { proxy: defaults.proxy },
1478
+ ...defaults.insecure !== void 0 && { insecure: defaults.insecure },
1479
+ trustStore: defaults.trustStore ?? DEFAULT_TRUST_STORE,
1480
+ ...defaults.captureDiagnostics !== void 0 && { captureDiagnostics: defaults.captureDiagnostics }
1481
+ };
1482
+ applyNativeEmulationMode(transportOptions, defaults.transportMode);
1483
+ transportId = nativeBinding.createTransport(transportOptions);
1484
+ } catch (error) {
1485
+ throw new RequestError(String(error));
1486
+ }
1487
+ try {
1488
+ createdId = nativeBinding.createSession({ sessionId });
1489
+ } catch (error) {
1490
+ try {
1491
+ nativeBinding.dropTransport(transportId);
1492
+ } catch {}
1493
+ throw new RequestError(String(error));
1494
+ }
1495
+ defaults.transportId = transportId;
1496
+ defaults.ownsTransport = true;
1497
+ return new Session(createdId, defaults);
1880
1498
  }
1881
1499
  async function withSession(fn, options) {
1882
- const session = await createSession(options);
1883
- try {
1884
- return await fn(session);
1885
- } finally {
1886
- await session.close();
1887
- }
1888
- }
1500
+ const session = await createSession(options);
1501
+ try {
1502
+ return await fn(session);
1503
+ } finally {
1504
+ await session.close();
1505
+ }
1506
+ }
1507
+ /**
1508
+ * @deprecated Use {@link fetch} instead.
1509
+ */
1889
1510
  async function request(options) {
1890
- if (!options.url) {
1891
- throw new RequestError("URL is required");
1892
- }
1893
- const { url, ...rest } = options;
1894
- const init = {};
1895
- const legacy = rest;
1896
- if (rest.method !== void 0) {
1897
- init.method = rest.method;
1898
- }
1899
- if (rest.headers !== void 0) {
1900
- init.headers = rest.headers;
1901
- }
1902
- if (rest.body !== void 0) {
1903
- init.body = rest.body;
1904
- }
1905
- if (rest.browser !== void 0) {
1906
- init.browser = rest.browser;
1907
- }
1908
- if (rest.os !== void 0) {
1909
- init.os = rest.os;
1910
- }
1911
- if (rest.emulation !== void 0) {
1912
- init.emulation = rest.emulation;
1913
- }
1914
- if (rest.proxy !== void 0) {
1915
- init.proxy = rest.proxy;
1916
- }
1917
- if (rest.timeout !== void 0) {
1918
- init.timeout = rest.timeout;
1919
- }
1920
- if (rest.sessionId !== void 0) {
1921
- init.sessionId = rest.sessionId;
1922
- }
1923
- if (rest.transport !== void 0) {
1924
- init.transport = rest.transport;
1925
- }
1926
- if (rest.insecure !== void 0) {
1927
- init.insecure = rest.insecure;
1928
- }
1929
- if (rest.disableDefaultHeaders !== void 0) {
1930
- init.disableDefaultHeaders = rest.disableDefaultHeaders;
1931
- }
1932
- if (rest.redirect !== void 0) {
1933
- init.redirect = rest.redirect;
1934
- }
1935
- if (legacy.signal !== void 0) {
1936
- init.signal = legacy.signal;
1937
- }
1938
- if (legacy.session !== void 0) {
1939
- init.session = legacy.session;
1940
- }
1941
- if (legacy.cookieMode !== void 0) {
1942
- init.cookieMode = legacy.cookieMode;
1943
- } else if (legacy.ephemeral === true) {
1944
- init.cookieMode = "ephemeral";
1945
- }
1946
- return fetch(url, init);
1947
- }
1511
+ if (!options.url) throw new RequestError("URL is required");
1512
+ const { url, ...rest } = options;
1513
+ const init = {};
1514
+ const legacy = rest;
1515
+ if (rest.method !== void 0) init.method = rest.method;
1516
+ if (rest.headers !== void 0) init.headers = rest.headers;
1517
+ if (rest.body !== void 0) init.body = rest.body;
1518
+ if (rest.browser !== void 0) init.browser = rest.browser;
1519
+ if (rest.os !== void 0) init.os = rest.os;
1520
+ if (rest.emulation !== void 0) init.emulation = rest.emulation;
1521
+ if (rest.proxy !== void 0) init.proxy = rest.proxy;
1522
+ if (rest.timeout !== void 0) init.timeout = rest.timeout;
1523
+ if (rest.sessionId !== void 0) init.sessionId = rest.sessionId;
1524
+ if (rest.transport !== void 0) init.transport = rest.transport;
1525
+ if (rest.insecure !== void 0) init.insecure = rest.insecure;
1526
+ if (rest.trustStore !== void 0) init.trustStore = rest.trustStore;
1527
+ if (rest.disableDefaultHeaders !== void 0) init.disableDefaultHeaders = rest.disableDefaultHeaders;
1528
+ if (rest.redirect !== void 0) init.redirect = rest.redirect;
1529
+ if (legacy.signal !== void 0) init.signal = legacy.signal;
1530
+ if (legacy.session !== void 0) init.session = legacy.session;
1531
+ if (legacy.cookieMode !== void 0) init.cookieMode = legacy.cookieMode;
1532
+ else if (legacy.ephemeral === true) init.cookieMode = "ephemeral";
1533
+ if (legacy.onRequestEvent !== void 0) init.onRequestEvent = legacy.onRequestEvent;
1534
+ if (legacy.captureDiagnostics !== void 0) init.captureDiagnostics = legacy.captureDiagnostics;
1535
+ return fetch(url, init);
1536
+ }
1537
+ /**
1538
+ * Get list of available browser profiles
1539
+ *
1540
+ * @returns Array of browser profile names
1541
+ *
1542
+ * @example
1543
+ * ```typescript
1544
+ * import { getProfiles } from 'wreq-js';
1545
+ *
1546
+ * const profiles = getProfiles();
1547
+ * console.log(profiles); // ['chrome_131', 'chrome_142', 'firefox_135', 'safari_18', ...]
1548
+ * ```
1549
+ */
1948
1550
  function getProfiles() {
1949
- if (!cachedProfiles) {
1950
- cachedProfiles = nativeBinding.getProfiles();
1951
- }
1952
- return cachedProfiles;
1551
+ if (!cachedProfiles) cachedProfiles = nativeBinding.getProfiles();
1552
+ return cachedProfiles;
1953
1553
  }
1954
1554
  function getProfileSet() {
1955
- if (!cachedProfileSet) {
1956
- cachedProfileSet = new Set(getProfiles());
1957
- }
1958
- return cachedProfileSet;
1959
- }
1555
+ if (!cachedProfileSet) cachedProfileSet = new Set(getProfiles());
1556
+ return cachedProfileSet;
1557
+ }
1558
+ /**
1559
+ * Get list of supported operating systems for emulation.
1560
+ *
1561
+ * @returns Array of operating system identifiers
1562
+ */
1960
1563
  function getOperatingSystems() {
1961
- if (!cachedOperatingSystems) {
1962
- const fromNative = nativeBinding.getOperatingSystems?.();
1963
- cachedOperatingSystems = fromNative && fromNative.length > 0 ? fromNative : [...SUPPORTED_OSES];
1964
- }
1965
- return cachedOperatingSystems;
1564
+ if (!cachedOperatingSystems) {
1565
+ const fromNative = nativeBinding.getOperatingSystems?.();
1566
+ cachedOperatingSystems = fromNative && fromNative.length > 0 ? fromNative : [...SUPPORTED_OSES];
1567
+ }
1568
+ return cachedOperatingSystems;
1966
1569
  }
1967
1570
  function getOperatingSystemSet() {
1968
- if (!cachedOperatingSystemSet) {
1969
- cachedOperatingSystemSet = new Set(getOperatingSystems());
1970
- }
1971
- return cachedOperatingSystemSet;
1571
+ if (!cachedOperatingSystemSet) cachedOperatingSystemSet = new Set(getOperatingSystems());
1572
+ return cachedOperatingSystemSet;
1972
1573
  }
1574
+ /**
1575
+ * Convenience helper for GET requests using {@link fetch}.
1576
+ */
1973
1577
  async function get(url, init) {
1974
- const config = {};
1975
- if (init) {
1976
- Object.assign(config, init);
1977
- }
1978
- config.method = "GET";
1979
- return fetch(url, config);
1980
- }
1578
+ const config = {};
1579
+ if (init) Object.assign(config, init);
1580
+ config.method = "GET";
1581
+ return fetch(url, config);
1582
+ }
1583
+ /**
1584
+ * Convenience helper for POST requests using {@link fetch}.
1585
+ */
1981
1586
  async function post(url, body, init) {
1982
- const config = {};
1983
- if (init) {
1984
- Object.assign(config, init);
1985
- }
1986
- config.method = "POST";
1987
- if (body !== void 0) {
1988
- config.body = body;
1989
- }
1990
- return fetch(url, config);
1587
+ const config = {};
1588
+ if (init) Object.assign(config, init);
1589
+ config.method = "POST";
1590
+ if (body !== void 0) config.body = body;
1591
+ return fetch(url, config);
1991
1592
  }
1992
1593
  function normalizeWebSocketUrl(url) {
1993
- const normalized = String(url).trim();
1994
- if (!normalized) {
1995
- throw new RequestError("URL is required");
1996
- }
1997
- let parsed;
1998
- try {
1999
- parsed = new URL(normalized);
2000
- } catch (error) {
2001
- throw new RequestError(String(error));
2002
- }
2003
- if (parsed.hash) {
2004
- throw new RequestError("WebSocket URL must not include a hash fragment");
2005
- }
2006
- if (parsed.protocol === "http:") {
2007
- parsed.protocol = "ws:";
2008
- } else if (parsed.protocol === "https:") {
2009
- parsed.protocol = "wss:";
2010
- }
2011
- if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
2012
- throw new RequestError("expected a ws: or wss: url");
2013
- }
2014
- return parsed.toString();
1594
+ const normalized = String(url).trim();
1595
+ if (!normalized) throw new RequestError("URL is required");
1596
+ let parsed;
1597
+ try {
1598
+ parsed = new URL(normalized);
1599
+ } catch (error) {
1600
+ throw new RequestError(String(error));
1601
+ }
1602
+ if (parsed.hash) throw new RequestError("WebSocket URL must not include a hash fragment");
1603
+ if (parsed.protocol === "http:") parsed.protocol = "ws:";
1604
+ else if (parsed.protocol === "https:") parsed.protocol = "wss:";
1605
+ if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") throw new RequestError("expected a ws: or wss: url");
1606
+ return parsed.toString();
2015
1607
  }
2016
1608
  function validateWebSocketProtocols(protocols) {
2017
- if (protocols === void 0) {
2018
- return;
2019
- }
2020
- const protocolList = typeof protocols === "string" ? [protocols] : protocols;
2021
- const seen = /* @__PURE__ */ new Set();
2022
- const validToken = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
2023
- for (const protocol of protocolList) {
2024
- if (typeof protocol !== "string" || protocol.length === 0) {
2025
- throw new RequestError("WebSocket protocol values must be non-empty strings");
2026
- }
2027
- if (!validToken.test(protocol)) {
2028
- throw new RequestError(`Invalid WebSocket protocol value: ${protocol}`);
2029
- }
2030
- if (seen.has(protocol)) {
2031
- throw new RequestError(`Duplicate WebSocket protocol: ${protocol}`);
2032
- }
2033
- seen.add(protocol);
2034
- }
1609
+ if (protocols === void 0) return;
1610
+ const protocolList = typeof protocols === "string" ? [protocols] : protocols;
1611
+ const seen = /* @__PURE__ */ new Set();
1612
+ const validToken = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
1613
+ for (const protocol of protocolList) {
1614
+ if (typeof protocol !== "string" || protocol.length === 0) throw new RequestError("WebSocket protocol values must be non-empty strings");
1615
+ if (!validToken.test(protocol)) throw new RequestError(`Invalid WebSocket protocol value: ${protocol}`);
1616
+ if (seen.has(protocol)) throw new RequestError(`Duplicate WebSocket protocol: ${protocol}`);
1617
+ seen.add(protocol);
1618
+ }
1619
+ }
1620
+ function normalizeWebSocketSizeOption(value, label) {
1621
+ if (value === void 0) return;
1622
+ if (!Number.isSafeInteger(value) || value <= 0) throw new RequestError(`${label} must be a positive safe integer`);
1623
+ return value;
2035
1624
  }
2036
1625
  function normalizeStandaloneWebSocketOptions(options) {
2037
- const normalized = {};
2038
- if (!options) {
2039
- return normalized;
2040
- }
2041
- if (options.browser !== void 0) {
2042
- normalized.browser = options.browser;
2043
- }
2044
- if (options.os !== void 0) {
2045
- normalized.os = options.os;
2046
- }
2047
- if (options.emulation !== void 0) {
2048
- normalized.emulation = options.emulation;
2049
- }
2050
- if (options.headers !== void 0) {
2051
- normalized.headers = options.headers;
2052
- }
2053
- if (options.proxy !== void 0) {
2054
- normalized.proxy = options.proxy;
2055
- }
2056
- if (options.protocols !== void 0) {
2057
- normalized.protocols = options.protocols;
2058
- }
2059
- if (options.binaryType !== void 0) {
2060
- if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
2061
- throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
2062
- }
2063
- normalized.binaryType = options.binaryType;
2064
- }
2065
- return normalized;
1626
+ const normalized = {};
1627
+ if (!options) return normalized;
1628
+ if (options.browser !== void 0) normalized.browser = options.browser;
1629
+ if (options.os !== void 0) normalized.os = options.os;
1630
+ if (options.emulation !== void 0) normalized.emulation = options.emulation;
1631
+ if (options.headers !== void 0) normalized.headers = options.headers;
1632
+ if (options.proxy !== void 0) normalized.proxy = options.proxy;
1633
+ if (options.protocols !== void 0) normalized.protocols = options.protocols;
1634
+ if (options.maxFrameSize !== void 0) {
1635
+ const maxFrameSize = normalizeWebSocketSizeOption(options.maxFrameSize, "maxFrameSize");
1636
+ if (maxFrameSize !== void 0) normalized.maxFrameSize = maxFrameSize;
1637
+ }
1638
+ if (options.maxMessageSize !== void 0) {
1639
+ const maxMessageSize = normalizeWebSocketSizeOption(options.maxMessageSize, "maxMessageSize");
1640
+ if (maxMessageSize !== void 0) normalized.maxMessageSize = maxMessageSize;
1641
+ }
1642
+ if (options.binaryType !== void 0) {
1643
+ if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
1644
+ normalized.binaryType = options.binaryType;
1645
+ }
1646
+ return normalized;
2066
1647
  }
2067
1648
  function normalizeSessionWebSocketOptions(options) {
2068
- const normalized = {};
2069
- if (!options) {
2070
- return normalized;
2071
- }
2072
- const optionsWithOverrides = options;
2073
- if (optionsWithOverrides.browser !== void 0) {
2074
- throw new RequestError(
2075
- "`browser` is not supported in session.websocket(); the session controls browser emulation."
2076
- );
2077
- }
2078
- if (optionsWithOverrides.os !== void 0) {
2079
- throw new RequestError("`os` is not supported in session.websocket(); the session controls OS emulation.");
2080
- }
2081
- if (optionsWithOverrides.emulation !== void 0) {
2082
- throw new RequestError(
2083
- "`emulation` is not supported in session.websocket(); the session transport controls emulation."
2084
- );
2085
- }
2086
- if (optionsWithOverrides.proxy !== void 0) {
2087
- throw new RequestError("`proxy` is not supported in session.websocket(); the session transport controls proxying.");
2088
- }
2089
- if (options.headers !== void 0) {
2090
- normalized.headers = options.headers;
2091
- }
2092
- if (options.protocols !== void 0) {
2093
- normalized.protocols = options.protocols;
2094
- }
2095
- if (options.binaryType !== void 0) {
2096
- if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
2097
- throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
2098
- }
2099
- normalized.binaryType = options.binaryType;
2100
- }
2101
- return normalized;
1649
+ const normalized = {};
1650
+ if (!options) return normalized;
1651
+ const optionsWithOverrides = options;
1652
+ if (optionsWithOverrides.browser !== void 0) throw new RequestError("`browser` is not supported in session.websocket(); the session controls browser emulation.");
1653
+ if (optionsWithOverrides.os !== void 0) throw new RequestError("`os` is not supported in session.websocket(); the session controls OS emulation.");
1654
+ if (optionsWithOverrides.emulation !== void 0) throw new RequestError("`emulation` is not supported in session.websocket(); the session transport controls emulation.");
1655
+ if (optionsWithOverrides.proxy !== void 0) throw new RequestError("`proxy` is not supported in session.websocket(); the session transport controls proxying.");
1656
+ if (options.headers !== void 0) normalized.headers = options.headers;
1657
+ if (options.protocols !== void 0) normalized.protocols = options.protocols;
1658
+ if (options.maxFrameSize !== void 0) {
1659
+ const maxFrameSize = normalizeWebSocketSizeOption(options.maxFrameSize, "maxFrameSize");
1660
+ if (maxFrameSize !== void 0) normalized.maxFrameSize = maxFrameSize;
1661
+ }
1662
+ if (options.maxMessageSize !== void 0) {
1663
+ const maxMessageSize = normalizeWebSocketSizeOption(options.maxMessageSize, "maxMessageSize");
1664
+ if (maxMessageSize !== void 0) normalized.maxMessageSize = maxMessageSize;
1665
+ }
1666
+ if (options.binaryType !== void 0) {
1667
+ if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
1668
+ normalized.binaryType = options.binaryType;
1669
+ }
1670
+ return normalized;
2102
1671
  }
2103
1672
  function extractLegacyWebSocketCallbacks(options) {
2104
- if (!isPlainObject(options)) {
2105
- return void 0;
2106
- }
2107
- const maybeCallbacks = options;
2108
- const callbacks = {};
2109
- if (typeof maybeCallbacks.onMessage === "function") {
2110
- callbacks.onMessage = maybeCallbacks.onMessage;
2111
- }
2112
- if (typeof maybeCallbacks.onClose === "function") {
2113
- callbacks.onClose = maybeCallbacks.onClose;
2114
- }
2115
- if (typeof maybeCallbacks.onError === "function") {
2116
- callbacks.onError = maybeCallbacks.onError;
2117
- }
2118
- return Object.keys(callbacks).length > 0 ? callbacks : void 0;
1673
+ if (!isPlainObject(options)) return;
1674
+ const maybeCallbacks = options;
1675
+ const callbacks = {};
1676
+ if (typeof maybeCallbacks.onMessage === "function") callbacks.onMessage = maybeCallbacks.onMessage;
1677
+ if (typeof maybeCallbacks.onClose === "function") callbacks.onClose = maybeCallbacks.onClose;
1678
+ if (typeof maybeCallbacks.onError === "function") callbacks.onError = maybeCallbacks.onError;
1679
+ return Object.keys(callbacks).length > 0 ? callbacks : void 0;
2119
1680
  }
2120
1681
  function normalizeWebSocketCloseOptions(code, reason) {
2121
- if (code === void 0 && reason === void 0) {
2122
- return void 0;
2123
- }
2124
- if (code === void 0) {
2125
- throw new RequestError("A close code is required when providing a close reason");
2126
- }
2127
- if (!Number.isInteger(code)) {
2128
- throw new RequestError("Close code must be an integer");
2129
- }
2130
- if (code !== 1e3 && (code < 3e3 || code > 4999)) {
2131
- throw new RequestError("Close code must be 1000 or in range 3000-4999");
2132
- }
2133
- const normalizedReason = reason ?? "";
2134
- if (Buffer.byteLength(normalizedReason, "utf8") > 123) {
2135
- throw new RequestError("Close reason must be 123 bytes or fewer");
2136
- }
2137
- return {
2138
- code,
2139
- reason: normalizedReason
2140
- };
1682
+ if (code === void 0 && reason === void 0) return;
1683
+ if (code === void 0) throw new RequestError("A close code is required when providing a close reason");
1684
+ if (!Number.isInteger(code)) throw new RequestError("Close code must be an integer");
1685
+ if (code !== 1e3 && (code < 3e3 || code > 4999)) throw new RequestError("Close code must be 1000 or in range 3000-4999");
1686
+ const normalizedReason = reason ?? "";
1687
+ if (Buffer.byteLength(normalizedReason, "utf8") > 123) throw new RequestError("Close reason must be 123 bytes or fewer");
1688
+ return {
1689
+ code,
1690
+ reason: normalizedReason
1691
+ };
2141
1692
  }
2142
1693
  function isWebSocketListenerType(type) {
2143
- return type === "open" || type === "message" || type === "close" || type === "error";
2144
- }
2145
- var WebSocket = class _WebSocket {
2146
- static CONNECTING = 0;
2147
- static OPEN = 1;
2148
- static CLOSING = 2;
2149
- static CLOSED = 3;
2150
- url;
2151
- protocol = "";
2152
- extensions = "";
2153
- readyState = _WebSocket.CONNECTING;
2154
- _binaryType = "nodebuffer";
2155
- _bufferedAmount = 0;
2156
- _onopen = null;
2157
- _onmessage = null;
2158
- _onclose = null;
2159
- _onerror = null;
2160
- _onHandlerOrder = {
2161
- open: -1,
2162
- message: -1,
2163
- close: -1,
2164
- error: -1
2165
- };
2166
- _listenerOrderCounter = 0;
2167
- _listeners = {
2168
- open: /* @__PURE__ */ new Map(),
2169
- message: /* @__PURE__ */ new Map(),
2170
- close: /* @__PURE__ */ new Map(),
2171
- error: /* @__PURE__ */ new Map()
2172
- };
2173
- _legacyCallbacks;
2174
- _openDispatchMode;
2175
- _connection;
2176
- _connectPromise;
2177
- _closeOptions;
2178
- _finalizerToken;
2179
- _openEventDispatched = false;
2180
- _openEventQueued = false;
2181
- _closeEventDispatched = false;
2182
- _nativeCloseStarted = false;
2183
- _pendingMessages = [];
2184
- _sendChain = Promise.resolve();
2185
- constructor(urlOrInit, protocolsOrOptions, maybeOptions) {
2186
- let init;
2187
- if (isInternalWebSocketInit(urlOrInit)) {
2188
- init = urlOrInit;
2189
- } else {
2190
- init = _WebSocket.buildStandaloneInit(urlOrInit, protocolsOrOptions, maybeOptions);
2191
- }
2192
- this.url = init.url;
2193
- this.binaryType = init.options.binaryType ?? "nodebuffer";
2194
- this._legacyCallbacks = init.legacyCallbacks;
2195
- this._openDispatchMode = init.openDispatchMode;
2196
- this._connectPromise = this.connect(init.connect);
2197
- void this._connectPromise.catch(() => void 0);
2198
- }
2199
- get binaryType() {
2200
- return this._binaryType;
2201
- }
2202
- set binaryType(value) {
2203
- if (value === "arraybuffer" || value === "blob" || value === "nodebuffer") {
2204
- this._binaryType = value;
2205
- }
2206
- }
2207
- get bufferedAmount() {
2208
- return this._bufferedAmount;
2209
- }
2210
- get onopen() {
2211
- return this._onopen;
2212
- }
2213
- set onopen(listener) {
2214
- this._onopen = listener;
2215
- this._onHandlerOrder.open = listener ? ++this._listenerOrderCounter : -1;
2216
- }
2217
- get onmessage() {
2218
- return this._onmessage;
2219
- }
2220
- set onmessage(listener) {
2221
- this._onmessage = listener;
2222
- this._onHandlerOrder.message = listener ? ++this._listenerOrderCounter : -1;
2223
- }
2224
- get onclose() {
2225
- return this._onclose;
2226
- }
2227
- set onclose(listener) {
2228
- this._onclose = listener;
2229
- this._onHandlerOrder.close = listener ? ++this._listenerOrderCounter : -1;
2230
- }
2231
- get onerror() {
2232
- return this._onerror;
2233
- }
2234
- set onerror(listener) {
2235
- this._onerror = listener;
2236
- this._onHandlerOrder.error = listener ? ++this._listenerOrderCounter : -1;
2237
- }
2238
- static async _connectWithInit(init) {
2239
- const ws = new _WebSocket(init);
2240
- await ws._waitUntilConnected();
2241
- ws.scheduleOpenEventAfterAwait();
2242
- return ws;
2243
- }
2244
- static buildStandaloneInit(url, protocolsOrOptions, maybeOptions) {
2245
- const optionsCandidate = typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? maybeOptions : protocolsOrOptions ?? maybeOptions;
2246
- const normalizedOptions = normalizeStandaloneWebSocketOptions(optionsCandidate);
2247
- validateWebSocketProtocols(
2248
- typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
2249
- );
2250
- assertNoManualWebSocketProtocolHeader(normalizedOptions.headers);
2251
- const emulationMode = resolveEmulationMode(
2252
- normalizedOptions.browser,
2253
- normalizedOptions.os,
2254
- normalizedOptions.emulation
2255
- );
2256
- const protocols = normalizeWebSocketProtocolList(
2257
- typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
2258
- );
2259
- return {
2260
- _internal: true,
2261
- url: normalizeWebSocketUrl(url),
2262
- options: normalizedOptions,
2263
- openDispatchMode: "automatic",
2264
- connect: (callbacks) => {
2265
- const nativeOptions = {
2266
- url: normalizeWebSocketUrl(url),
2267
- headers: headersToTuples(normalizedOptions.headers ?? {}),
2268
- ...protocols && protocols.length > 0 && { protocols },
2269
- ...normalizedOptions.proxy !== void 0 && { proxy: normalizedOptions.proxy },
2270
- onMessage: callbacks.onMessage,
2271
- onClose: callbacks.onClose,
2272
- onError: callbacks.onError
2273
- };
2274
- applyNativeEmulationMode(nativeOptions, emulationMode);
2275
- return nativeBinding.websocketConnect(nativeOptions);
2276
- },
2277
- legacyCallbacks: extractLegacyWebSocketCallbacks(optionsCandidate)
2278
- };
2279
- }
2280
- async connect(connectFn) {
2281
- try {
2282
- const connection = await connectFn({
2283
- onMessage: (data) => {
2284
- this.handleNativeMessage(data);
2285
- },
2286
- onClose: (event) => {
2287
- this.handleNativeClose(event);
2288
- },
2289
- onError: (message) => {
2290
- this.handleNativeError(message);
2291
- }
2292
- });
2293
- this._connection = connection;
2294
- this.protocol = connection.protocol ?? "";
2295
- this.extensions = connection.extensions ?? "";
2296
- if (websocketFinalizer) {
2297
- this._finalizerToken = connection;
2298
- websocketFinalizer.register(this, connection, connection);
2299
- }
2300
- if (this.readyState === _WebSocket.CLOSING) {
2301
- this.startNativeClose();
2302
- return;
2303
- }
2304
- this.readyState = _WebSocket.OPEN;
2305
- if (this._openDispatchMode === "automatic") {
2306
- this.scheduleOpenEventAfterConnect();
2307
- }
2308
- } catch (error) {
2309
- this.handleNativeError(String(error));
2310
- this.finalizeClosed({ code: 1006, reason: "" }, false);
2311
- throw new RequestError(String(error));
2312
- }
2313
- }
2314
- _waitUntilConnected() {
2315
- return this._connectPromise;
2316
- }
2317
- scheduleOpenEventAfterConnect() {
2318
- this.scheduleOpenEventWithDepth(2);
2319
- }
2320
- scheduleOpenEventAfterAwait() {
2321
- this.scheduleOpenEventWithDepth(3);
2322
- }
2323
- scheduleOpenEventWithDepth(depth) {
2324
- if (this._openEventDispatched || this._openEventQueued || this.readyState !== _WebSocket.OPEN) {
2325
- return;
2326
- }
2327
- this._openEventQueued = true;
2328
- const queue = (remaining) => {
2329
- if (remaining === 0) {
2330
- this._openEventQueued = false;
2331
- if (this._openEventDispatched || this.readyState !== _WebSocket.OPEN) {
2332
- return;
2333
- }
2334
- this._openEventDispatched = true;
2335
- this.dispatchOpenEvent();
2336
- return;
2337
- }
2338
- queueMicrotask(() => {
2339
- queue(remaining - 1);
2340
- });
2341
- };
2342
- queue(depth);
2343
- }
2344
- releaseConnectionTracking() {
2345
- if (!this._finalizerToken || !websocketFinalizer) {
2346
- return;
2347
- }
2348
- websocketFinalizer.unregister(this._finalizerToken);
2349
- this._finalizerToken = void 0;
2350
- }
2351
- toMessageEventData(data) {
2352
- if (typeof data === "string") {
2353
- return data;
2354
- }
2355
- if (this._binaryType === "arraybuffer") {
2356
- const arrayBuffer = new ArrayBuffer(data.byteLength);
2357
- new Uint8Array(arrayBuffer).set(data);
2358
- return arrayBuffer;
2359
- }
2360
- if (this._binaryType === "blob") {
2361
- return new Blob([data]);
2362
- }
2363
- return data;
2364
- }
2365
- invokeListener(listener, event) {
2366
- try {
2367
- if (typeof listener === "function") {
2368
- listener.call(this, event);
2369
- } else {
2370
- listener.handleEvent(event);
2371
- }
2372
- } catch {
2373
- }
2374
- }
2375
- createBaseEvent(type) {
2376
- return {
2377
- type,
2378
- isTrusted: false,
2379
- timeStamp: Date.now(),
2380
- target: this,
2381
- currentTarget: this
2382
- };
2383
- }
2384
- getOnHandler(type) {
2385
- switch (type) {
2386
- case "open":
2387
- return this._onopen;
2388
- case "message":
2389
- return this._onmessage;
2390
- case "close":
2391
- return this._onclose;
2392
- case "error":
2393
- return this._onerror;
2394
- default:
2395
- return null;
2396
- }
2397
- }
2398
- getOnHandlerOrder(type) {
2399
- return this._onHandlerOrder[type];
2400
- }
2401
- getListenerMap(type) {
2402
- return this._listeners[type];
2403
- }
2404
- dispatchEvent(type, event) {
2405
- const listenerMap = this.getListenerMap(type);
2406
- const onHandler = this.getOnHandler(type);
2407
- if (listenerMap.size === 0 && !onHandler) {
2408
- return;
2409
- }
2410
- const ordered = [];
2411
- for (const descriptor of listenerMap.values()) {
2412
- ordered.push({
2413
- order: descriptor.order,
2414
- listener: descriptor.listener,
2415
- once: descriptor.once
2416
- });
2417
- }
2418
- if (onHandler) {
2419
- ordered.push({
2420
- order: this.getOnHandlerOrder(type),
2421
- listener: onHandler,
2422
- once: false
2423
- });
2424
- }
2425
- ordered.sort((a, b) => a.order - b.order);
2426
- for (const entry of ordered) {
2427
- if (entry.once) {
2428
- this.removeEventListener(type, entry.listener);
2429
- }
2430
- this.invokeListener(entry.listener, event);
2431
- }
2432
- }
2433
- dispatchOpenEvent() {
2434
- const event = this.createBaseEvent("open");
2435
- this.dispatchEvent("open", event);
2436
- if (!this._closeEventDispatched && this._pendingMessages.length > 0) {
2437
- const pending = this._pendingMessages;
2438
- this._pendingMessages = [];
2439
- for (const data of pending) {
2440
- this.dispatchMessageEvent(this.toMessageEventData(data));
2441
- }
2442
- }
2443
- }
2444
- dispatchMessageEvent(data) {
2445
- const event = {
2446
- ...this.createBaseEvent("message"),
2447
- data
2448
- };
2449
- this.dispatchEvent("message", event);
2450
- }
2451
- dispatchCloseEvent(event) {
2452
- this.dispatchEvent("close", event);
2453
- }
2454
- dispatchErrorEvent(message) {
2455
- const event = {
2456
- ...this.createBaseEvent("error"),
2457
- ...message !== void 0 && { message }
2458
- };
2459
- this.dispatchEvent("error", event);
2460
- }
2461
- handleNativeMessage(data) {
2462
- if (this._closeEventDispatched) {
2463
- return;
2464
- }
2465
- this._legacyCallbacks?.onMessage?.(data);
2466
- if (!this._openEventDispatched && this.readyState === _WebSocket.OPEN) {
2467
- this._pendingMessages.push(data);
2468
- return;
2469
- }
2470
- this.dispatchMessageEvent(this.toMessageEventData(data));
2471
- }
2472
- handleNativeError(message) {
2473
- this._legacyCallbacks?.onError?.(message);
2474
- this.dispatchErrorEvent(message);
2475
- }
2476
- handleNativeClose(event) {
2477
- const wasClean = this.readyState === _WebSocket.CLOSING || event.code === 1e3;
2478
- this.finalizeClosed(event, wasClean);
2479
- }
2480
- finalizeClosed(event, wasClean) {
2481
- if (this._closeEventDispatched) {
2482
- return;
2483
- }
2484
- this.readyState = _WebSocket.CLOSED;
2485
- this._closeEventDispatched = true;
2486
- this._pendingMessages = [];
2487
- this.releaseConnectionTracking();
2488
- const closeEvent = {
2489
- ...this.createBaseEvent("close"),
2490
- code: event.code,
2491
- reason: event.reason,
2492
- wasClean
2493
- };
2494
- this._legacyCallbacks?.onClose?.(closeEvent);
2495
- this.dispatchCloseEvent(closeEvent);
2496
- }
2497
- startNativeClose() {
2498
- if (this._nativeCloseStarted || !this._connection) {
2499
- return;
2500
- }
2501
- this._nativeCloseStarted = true;
2502
- const connection = this._connection;
2503
- const closeOptions = this._closeOptions;
2504
- void nativeBinding.websocketClose(connection, closeOptions).catch((error) => {
2505
- this.handleNativeError(String(error));
2506
- this.finalizeClosed({ code: 1006, reason: "" }, false);
2507
- });
2508
- }
2509
- addEventListener(type, listener, options) {
2510
- if (!listener || !isWebSocketListenerType(type)) {
2511
- return;
2512
- }
2513
- const normalizedListener = listener;
2514
- if (typeof normalizedListener !== "function" && (typeof normalizedListener !== "object" || normalizedListener === null || typeof normalizedListener.handleEvent !== "function")) {
2515
- return;
2516
- }
2517
- const listenerMap = this.getListenerMap(type);
2518
- if (listenerMap.has(normalizedListener)) {
2519
- return;
2520
- }
2521
- const parsedOptions = typeof options === "boolean" ? {} : options ?? {};
2522
- const once = parsedOptions.once === true;
2523
- const signal = parsedOptions.signal;
2524
- if (signal?.aborted) {
2525
- return;
2526
- }
2527
- const descriptor = {
2528
- listener: normalizedListener,
2529
- order: ++this._listenerOrderCounter,
2530
- once
2531
- };
2532
- if (signal) {
2533
- const onAbort = () => {
2534
- this.removeEventListener(type, normalizedListener);
2535
- };
2536
- descriptor.abortSignal = signal;
2537
- descriptor.abortHandler = onAbort;
2538
- signal.addEventListener("abort", onAbort, { once: true });
2539
- }
2540
- listenerMap.set(normalizedListener, descriptor);
2541
- }
2542
- removeEventListener(type, listener) {
2543
- if (!listener || !isWebSocketListenerType(type)) {
2544
- return;
2545
- }
2546
- const normalizedListener = listener;
2547
- if (typeof normalizedListener !== "function" && typeof normalizedListener !== "object") {
2548
- return;
2549
- }
2550
- const listenerMap = this.getListenerMap(type);
2551
- const descriptor = listenerMap.get(normalizedListener);
2552
- if (!descriptor) {
2553
- return;
2554
- }
2555
- if (descriptor.abortSignal && descriptor.abortHandler) {
2556
- descriptor.abortSignal.removeEventListener("abort", descriptor.abortHandler);
2557
- }
2558
- listenerMap.delete(normalizedListener);
2559
- }
2560
- getSendByteLength(data) {
2561
- if (typeof data === "string") {
2562
- return Buffer.byteLength(data);
2563
- }
2564
- if (Buffer.isBuffer(data)) {
2565
- return data.byteLength;
2566
- }
2567
- if (data instanceof ArrayBuffer) {
2568
- return data.byteLength;
2569
- }
2570
- if (ArrayBuffer.isView(data)) {
2571
- return data.byteLength;
2572
- }
2573
- if (typeof Blob !== "undefined" && data instanceof Blob) {
2574
- return data.size;
2575
- }
2576
- throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
2577
- }
2578
- async normalizeSendPayload(data) {
2579
- if (typeof data === "string") {
2580
- return data;
2581
- }
2582
- if (Buffer.isBuffer(data)) {
2583
- return data;
2584
- }
2585
- if (data instanceof ArrayBuffer) {
2586
- return Buffer.from(data);
2587
- }
2588
- if (ArrayBuffer.isView(data)) {
2589
- return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
2590
- }
2591
- if (typeof Blob !== "undefined" && data instanceof Blob) {
2592
- return Buffer.from(await data.arrayBuffer());
2593
- }
2594
- throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
2595
- }
2596
- send(data) {
2597
- if (this.readyState !== _WebSocket.OPEN || !this._connection) {
2598
- throw new RequestError("WebSocket is not open");
2599
- }
2600
- const queuedBytes = this.getSendByteLength(data);
2601
- const connection = this._connection;
2602
- this._bufferedAmount += queuedBytes;
2603
- const sendTask = async () => {
2604
- try {
2605
- const payload = await this.normalizeSendPayload(data);
2606
- await nativeBinding.websocketSend(connection, payload);
2607
- } catch (error) {
2608
- this.handleNativeError(String(error));
2609
- this.finalizeClosed({ code: 1006, reason: "" }, false);
2610
- } finally {
2611
- this._bufferedAmount = Math.max(0, this._bufferedAmount - queuedBytes);
2612
- }
2613
- };
2614
- this._sendChain = this._sendChain.then(sendTask, sendTask);
2615
- }
2616
- close(code, reason) {
2617
- if (this.readyState === _WebSocket.CLOSING || this.readyState === _WebSocket.CLOSED) {
2618
- return;
2619
- }
2620
- this._closeOptions = normalizeWebSocketCloseOptions(code, reason);
2621
- this.readyState = _WebSocket.CLOSING;
2622
- this.startNativeClose();
2623
- }
1694
+ return type === "open" || type === "message" || type === "close" || type === "error";
1695
+ }
1696
+ /**
1697
+ * WHATWG-style WebSocket API with async connection establishment.
1698
+ */
1699
+ var WebSocket = class WebSocket {
1700
+ static CONNECTING = 0;
1701
+ static OPEN = 1;
1702
+ static CLOSING = 2;
1703
+ static CLOSED = 3;
1704
+ url;
1705
+ protocol = "";
1706
+ extensions = "";
1707
+ readyState = WebSocket.CONNECTING;
1708
+ _binaryType = "nodebuffer";
1709
+ _bufferedAmount = 0;
1710
+ _onopen = null;
1711
+ _onmessage = null;
1712
+ _onclose = null;
1713
+ _onerror = null;
1714
+ _onHandlerOrder = {
1715
+ open: -1,
1716
+ message: -1,
1717
+ close: -1,
1718
+ error: -1
1719
+ };
1720
+ _listenerOrderCounter = 0;
1721
+ _listeners = {
1722
+ open: /* @__PURE__ */ new Map(),
1723
+ message: /* @__PURE__ */ new Map(),
1724
+ close: /* @__PURE__ */ new Map(),
1725
+ error: /* @__PURE__ */ new Map()
1726
+ };
1727
+ _legacyCallbacks;
1728
+ _openDispatchMode;
1729
+ _connection;
1730
+ _connectPromise;
1731
+ _closeOptions;
1732
+ _finalizerToken;
1733
+ _openEventDispatched = false;
1734
+ _openEventQueued = false;
1735
+ _closeEventDispatched = false;
1736
+ _nativeCloseStarted = false;
1737
+ _pendingMessages = [];
1738
+ _sendChain = Promise.resolve();
1739
+ constructor(urlOrInit, protocolsOrOptions, maybeOptions) {
1740
+ let init;
1741
+ if (isInternalWebSocketInit(urlOrInit)) init = urlOrInit;
1742
+ else init = WebSocket.buildStandaloneInit(urlOrInit, protocolsOrOptions, maybeOptions);
1743
+ this.url = init.url;
1744
+ this.binaryType = init.options.binaryType ?? "nodebuffer";
1745
+ this._legacyCallbacks = init.legacyCallbacks;
1746
+ this._openDispatchMode = init.openDispatchMode;
1747
+ this._connectPromise = this.connect(init.connect);
1748
+ this._connectPromise.catch(() => void 0);
1749
+ }
1750
+ get binaryType() {
1751
+ return this._binaryType;
1752
+ }
1753
+ set binaryType(value) {
1754
+ if (value === "arraybuffer" || value === "blob" || value === "nodebuffer") this._binaryType = value;
1755
+ }
1756
+ get bufferedAmount() {
1757
+ return this._bufferedAmount;
1758
+ }
1759
+ get onopen() {
1760
+ return this._onopen;
1761
+ }
1762
+ set onopen(listener) {
1763
+ this._onopen = listener;
1764
+ this._onHandlerOrder.open = listener ? ++this._listenerOrderCounter : -1;
1765
+ }
1766
+ get onmessage() {
1767
+ return this._onmessage;
1768
+ }
1769
+ set onmessage(listener) {
1770
+ this._onmessage = listener;
1771
+ this._onHandlerOrder.message = listener ? ++this._listenerOrderCounter : -1;
1772
+ }
1773
+ get onclose() {
1774
+ return this._onclose;
1775
+ }
1776
+ set onclose(listener) {
1777
+ this._onclose = listener;
1778
+ this._onHandlerOrder.close = listener ? ++this._listenerOrderCounter : -1;
1779
+ }
1780
+ get onerror() {
1781
+ return this._onerror;
1782
+ }
1783
+ set onerror(listener) {
1784
+ this._onerror = listener;
1785
+ this._onHandlerOrder.error = listener ? ++this._listenerOrderCounter : -1;
1786
+ }
1787
+ static async _connectWithInit(init) {
1788
+ const ws = new WebSocket(init);
1789
+ await ws._waitUntilConnected();
1790
+ ws.scheduleOpenEventAfterAwait();
1791
+ return ws;
1792
+ }
1793
+ static buildStandaloneInit(url, protocolsOrOptions, maybeOptions) {
1794
+ const optionsCandidate = typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? maybeOptions : protocolsOrOptions ?? maybeOptions;
1795
+ const normalizedOptions = normalizeStandaloneWebSocketOptions(optionsCandidate);
1796
+ validateWebSocketProtocols(typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols);
1797
+ assertNoManualWebSocketProtocolHeader(normalizedOptions.headers);
1798
+ const emulationMode = resolveEmulationMode(normalizedOptions.browser, normalizedOptions.os, normalizedOptions.emulation);
1799
+ const protocols = normalizeWebSocketProtocolList(typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols);
1800
+ return {
1801
+ _internal: true,
1802
+ url: normalizeWebSocketUrl(url),
1803
+ options: normalizedOptions,
1804
+ openDispatchMode: "automatic",
1805
+ connect: (callbacks) => {
1806
+ const nativeOptions = {
1807
+ url: normalizeWebSocketUrl(url),
1808
+ headers: headersToTuples(normalizedOptions.headers ?? {}),
1809
+ ...protocols && protocols.length > 0 && { protocols },
1810
+ ...normalizedOptions.proxy !== void 0 && { proxy: normalizedOptions.proxy },
1811
+ ...normalizedOptions.maxFrameSize !== void 0 && { maxFrameSize: normalizedOptions.maxFrameSize },
1812
+ ...normalizedOptions.maxMessageSize !== void 0 && { maxMessageSize: normalizedOptions.maxMessageSize },
1813
+ onMessage: callbacks.onMessage,
1814
+ onClose: callbacks.onClose,
1815
+ onError: callbacks.onError
1816
+ };
1817
+ applyNativeEmulationMode(nativeOptions, emulationMode);
1818
+ return nativeBinding.websocketConnect(nativeOptions);
1819
+ },
1820
+ legacyCallbacks: extractLegacyWebSocketCallbacks(optionsCandidate)
1821
+ };
1822
+ }
1823
+ async connect(connectFn) {
1824
+ try {
1825
+ const connection = await connectFn({
1826
+ onMessage: (data) => {
1827
+ this.handleNativeMessage(data);
1828
+ },
1829
+ onClose: (event) => {
1830
+ this.handleNativeClose(event);
1831
+ },
1832
+ onError: (message) => {
1833
+ this.handleNativeError(message);
1834
+ }
1835
+ });
1836
+ this._connection = connection;
1837
+ this.protocol = connection.protocol ?? "";
1838
+ this.extensions = connection.extensions ?? "";
1839
+ if (websocketFinalizer) {
1840
+ this._finalizerToken = connection;
1841
+ websocketFinalizer.register(this, connection, connection);
1842
+ }
1843
+ if (this.readyState === WebSocket.CLOSING) {
1844
+ this.startNativeClose();
1845
+ return;
1846
+ }
1847
+ this.readyState = WebSocket.OPEN;
1848
+ if (this._openDispatchMode === "automatic") this.scheduleOpenEventAfterConnect();
1849
+ } catch (error) {
1850
+ this.handleNativeError(String(error));
1851
+ this.finalizeClosed({
1852
+ code: 1006,
1853
+ reason: ""
1854
+ }, false);
1855
+ throw new RequestError(String(error));
1856
+ }
1857
+ }
1858
+ _waitUntilConnected() {
1859
+ return this._connectPromise;
1860
+ }
1861
+ scheduleOpenEventAfterConnect() {
1862
+ this.scheduleOpenEventWithDepth(2);
1863
+ }
1864
+ scheduleOpenEventAfterAwait() {
1865
+ this.scheduleOpenEventWithDepth(3);
1866
+ }
1867
+ scheduleOpenEventWithDepth(depth) {
1868
+ if (this._openEventDispatched || this._openEventQueued || this.readyState !== WebSocket.OPEN) return;
1869
+ this._openEventQueued = true;
1870
+ const queue = (remaining) => {
1871
+ if (remaining === 0) {
1872
+ this._openEventQueued = false;
1873
+ if (this._openEventDispatched || this.readyState !== WebSocket.OPEN) return;
1874
+ this._openEventDispatched = true;
1875
+ this.dispatchOpenEvent();
1876
+ return;
1877
+ }
1878
+ queueMicrotask(() => {
1879
+ queue(remaining - 1);
1880
+ });
1881
+ };
1882
+ queue(depth);
1883
+ }
1884
+ releaseConnectionTracking() {
1885
+ if (!this._finalizerToken || !websocketFinalizer) return;
1886
+ websocketFinalizer.unregister(this._finalizerToken);
1887
+ this._finalizerToken = void 0;
1888
+ }
1889
+ toMessageEventData(data) {
1890
+ if (typeof data === "string") return data;
1891
+ if (this._binaryType === "arraybuffer") {
1892
+ const arrayBuffer = new ArrayBuffer(data.byteLength);
1893
+ new Uint8Array(arrayBuffer).set(data);
1894
+ return arrayBuffer;
1895
+ }
1896
+ if (this._binaryType === "blob") return new Blob([data]);
1897
+ return data;
1898
+ }
1899
+ invokeListener(listener, event) {
1900
+ try {
1901
+ if (typeof listener === "function") listener.call(this, event);
1902
+ else listener.handleEvent(event);
1903
+ } catch {}
1904
+ }
1905
+ createBaseEvent(type) {
1906
+ return {
1907
+ type,
1908
+ isTrusted: false,
1909
+ timeStamp: Date.now(),
1910
+ target: this,
1911
+ currentTarget: this
1912
+ };
1913
+ }
1914
+ getOnHandler(type) {
1915
+ switch (type) {
1916
+ case "open": return this._onopen;
1917
+ case "message": return this._onmessage;
1918
+ case "close": return this._onclose;
1919
+ case "error": return this._onerror;
1920
+ default: return null;
1921
+ }
1922
+ }
1923
+ getOnHandlerOrder(type) {
1924
+ return this._onHandlerOrder[type];
1925
+ }
1926
+ getListenerMap(type) {
1927
+ return this._listeners[type];
1928
+ }
1929
+ dispatchEvent(type, event) {
1930
+ const listenerMap = this.getListenerMap(type);
1931
+ const onHandler = this.getOnHandler(type);
1932
+ if (listenerMap.size === 0 && !onHandler) return;
1933
+ const ordered = [];
1934
+ for (const descriptor of listenerMap.values()) ordered.push({
1935
+ order: descriptor.order,
1936
+ listener: descriptor.listener,
1937
+ once: descriptor.once
1938
+ });
1939
+ if (onHandler) ordered.push({
1940
+ order: this.getOnHandlerOrder(type),
1941
+ listener: onHandler,
1942
+ once: false
1943
+ });
1944
+ ordered.sort((a, b) => a.order - b.order);
1945
+ for (const entry of ordered) {
1946
+ if (entry.once) this.removeEventListener(type, entry.listener);
1947
+ this.invokeListener(entry.listener, event);
1948
+ }
1949
+ }
1950
+ dispatchOpenEvent() {
1951
+ const event = this.createBaseEvent("open");
1952
+ this.dispatchEvent("open", event);
1953
+ if (!this._closeEventDispatched && this._pendingMessages.length > 0) {
1954
+ const pending = this._pendingMessages;
1955
+ this._pendingMessages = [];
1956
+ for (const data of pending) this.dispatchMessageEvent(this.toMessageEventData(data));
1957
+ }
1958
+ }
1959
+ dispatchMessageEvent(data) {
1960
+ const event = {
1961
+ ...this.createBaseEvent("message"),
1962
+ data
1963
+ };
1964
+ this.dispatchEvent("message", event);
1965
+ }
1966
+ dispatchCloseEvent(event) {
1967
+ this.dispatchEvent("close", event);
1968
+ }
1969
+ dispatchErrorEvent(message) {
1970
+ const event = {
1971
+ ...this.createBaseEvent("error"),
1972
+ ...message !== void 0 && { message }
1973
+ };
1974
+ this.dispatchEvent("error", event);
1975
+ }
1976
+ handleNativeMessage(data) {
1977
+ if (this._closeEventDispatched) return;
1978
+ this._legacyCallbacks?.onMessage?.(data);
1979
+ if (!this._openEventDispatched && this.readyState === WebSocket.OPEN) {
1980
+ this._pendingMessages.push(data);
1981
+ return;
1982
+ }
1983
+ this.dispatchMessageEvent(this.toMessageEventData(data));
1984
+ }
1985
+ handleNativeError(message) {
1986
+ this._legacyCallbacks?.onError?.(message);
1987
+ this.dispatchErrorEvent(message);
1988
+ }
1989
+ handleNativeClose(event) {
1990
+ const wasClean = this.readyState === WebSocket.CLOSING || event.code === 1e3;
1991
+ this.finalizeClosed(event, wasClean);
1992
+ }
1993
+ finalizeClosed(event, wasClean) {
1994
+ if (this._closeEventDispatched) return;
1995
+ this.readyState = WebSocket.CLOSED;
1996
+ this._closeEventDispatched = true;
1997
+ this._pendingMessages = [];
1998
+ this.releaseConnectionTracking();
1999
+ const closeEvent = {
2000
+ ...this.createBaseEvent("close"),
2001
+ code: event.code,
2002
+ reason: event.reason,
2003
+ wasClean
2004
+ };
2005
+ this._legacyCallbacks?.onClose?.(closeEvent);
2006
+ this.dispatchCloseEvent(closeEvent);
2007
+ }
2008
+ startNativeClose() {
2009
+ if (this._nativeCloseStarted || !this._connection) return;
2010
+ this._nativeCloseStarted = true;
2011
+ const connection = this._connection;
2012
+ const closeOptions = this._closeOptions;
2013
+ nativeBinding.websocketClose(connection, closeOptions).catch((error) => {
2014
+ this.handleNativeError(String(error));
2015
+ this.finalizeClosed({
2016
+ code: 1006,
2017
+ reason: ""
2018
+ }, false);
2019
+ });
2020
+ }
2021
+ addEventListener(type, listener, options) {
2022
+ if (!listener || !isWebSocketListenerType(type)) return;
2023
+ const normalizedListener = listener;
2024
+ if (typeof normalizedListener !== "function" && (typeof normalizedListener !== "object" || normalizedListener === null || typeof normalizedListener.handleEvent !== "function")) return;
2025
+ const listenerMap = this.getListenerMap(type);
2026
+ if (listenerMap.has(normalizedListener)) return;
2027
+ const parsedOptions = typeof options === "boolean" ? {} : options ?? {};
2028
+ const once = parsedOptions.once === true;
2029
+ const signal = parsedOptions.signal;
2030
+ if (signal?.aborted) return;
2031
+ const descriptor = {
2032
+ listener: normalizedListener,
2033
+ order: ++this._listenerOrderCounter,
2034
+ once
2035
+ };
2036
+ if (signal) {
2037
+ const onAbort = () => {
2038
+ this.removeEventListener(type, normalizedListener);
2039
+ };
2040
+ descriptor.abortSignal = signal;
2041
+ descriptor.abortHandler = onAbort;
2042
+ signal.addEventListener("abort", onAbort, { once: true });
2043
+ }
2044
+ listenerMap.set(normalizedListener, descriptor);
2045
+ }
2046
+ removeEventListener(type, listener) {
2047
+ if (!listener || !isWebSocketListenerType(type)) return;
2048
+ const normalizedListener = listener;
2049
+ if (typeof normalizedListener !== "function" && typeof normalizedListener !== "object") return;
2050
+ const listenerMap = this.getListenerMap(type);
2051
+ const descriptor = listenerMap.get(normalizedListener);
2052
+ if (!descriptor) return;
2053
+ if (descriptor.abortSignal && descriptor.abortHandler) descriptor.abortSignal.removeEventListener("abort", descriptor.abortHandler);
2054
+ listenerMap.delete(normalizedListener);
2055
+ }
2056
+ getSendByteLength(data) {
2057
+ if (typeof data === "string") return Buffer.byteLength(data);
2058
+ if (Buffer.isBuffer(data)) return data.byteLength;
2059
+ if (data instanceof ArrayBuffer) return data.byteLength;
2060
+ if (ArrayBuffer.isView(data)) return data.byteLength;
2061
+ if (typeof Blob !== "undefined" && data instanceof Blob) return data.size;
2062
+ throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
2063
+ }
2064
+ async normalizeSendPayload(data) {
2065
+ if (typeof data === "string") return data;
2066
+ if (Buffer.isBuffer(data)) return data;
2067
+ if (data instanceof ArrayBuffer) return Buffer.from(data);
2068
+ if (ArrayBuffer.isView(data)) return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
2069
+ if (typeof Blob !== "undefined" && data instanceof Blob) return Buffer.from(await data.arrayBuffer());
2070
+ throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
2071
+ }
2072
+ send(data) {
2073
+ if (this.readyState !== WebSocket.OPEN || !this._connection) throw new RequestError("WebSocket is not open");
2074
+ const queuedBytes = this.getSendByteLength(data);
2075
+ const connection = this._connection;
2076
+ this._bufferedAmount += queuedBytes;
2077
+ const sendTask = async () => {
2078
+ try {
2079
+ const payload = await this.normalizeSendPayload(data);
2080
+ await nativeBinding.websocketSend(connection, payload);
2081
+ } catch (error) {
2082
+ this.handleNativeError(String(error));
2083
+ this.finalizeClosed({
2084
+ code: 1006,
2085
+ reason: ""
2086
+ }, false);
2087
+ } finally {
2088
+ this._bufferedAmount = Math.max(0, this._bufferedAmount - queuedBytes);
2089
+ }
2090
+ };
2091
+ this._sendChain = this._sendChain.then(sendTask, sendTask);
2092
+ }
2093
+ close(code, reason) {
2094
+ if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) return;
2095
+ this._closeOptions = normalizeWebSocketCloseOptions(code, reason);
2096
+ this.readyState = WebSocket.CLOSING;
2097
+ this.startNativeClose();
2098
+ }
2624
2099
  };
2625
2100
  function isInternalWebSocketInit(value) {
2626
- if (!isPlainObject(value)) {
2627
- return false;
2628
- }
2629
- const candidate = value;
2630
- return candidate._internal === true && typeof candidate.url === "string" && typeof candidate.connect === "function";
2101
+ if (!isPlainObject(value)) return false;
2102
+ const candidate = value;
2103
+ return candidate._internal === true && typeof candidate.url === "string" && typeof candidate.connect === "function";
2631
2104
  }
2632
2105
  function normalizeStandaloneWebSocketArgs(urlOrOptions, options) {
2633
- if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
2634
- const normalizedOptions2 = normalizeStandaloneWebSocketOptions(options);
2635
- return {
2636
- url: normalizeWebSocketUrl(urlOrOptions),
2637
- options: normalizedOptions2,
2638
- legacyCallbacks: extractLegacyWebSocketCallbacks(options)
2639
- };
2640
- }
2641
- const legacy = urlOrOptions;
2642
- const normalizedOptions = normalizeStandaloneWebSocketOptions(legacy);
2643
- return {
2644
- url: normalizeWebSocketUrl(legacy.url),
2645
- options: normalizedOptions,
2646
- legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
2647
- };
2106
+ if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
2107
+ const normalizedOptions = normalizeStandaloneWebSocketOptions(options);
2108
+ return {
2109
+ url: normalizeWebSocketUrl(urlOrOptions),
2110
+ options: normalizedOptions,
2111
+ legacyCallbacks: extractLegacyWebSocketCallbacks(options)
2112
+ };
2113
+ }
2114
+ const legacy = urlOrOptions;
2115
+ const normalizedOptions = normalizeStandaloneWebSocketOptions(legacy);
2116
+ return {
2117
+ url: normalizeWebSocketUrl(legacy.url),
2118
+ options: normalizedOptions,
2119
+ legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
2120
+ };
2648
2121
  }
2649
2122
  function normalizeSessionWebSocketArgs(urlOrOptions, options) {
2650
- if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
2651
- const normalizedOptions2 = normalizeSessionWebSocketOptions(options);
2652
- return {
2653
- url: normalizeWebSocketUrl(urlOrOptions),
2654
- options: normalizedOptions2,
2655
- legacyCallbacks: extractLegacyWebSocketCallbacks(options)
2656
- };
2657
- }
2658
- const legacy = urlOrOptions;
2659
- const normalizedOptions = normalizeSessionWebSocketOptions(legacy);
2660
- return {
2661
- url: normalizeWebSocketUrl(legacy.url),
2662
- options: normalizedOptions,
2663
- legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
2664
- };
2123
+ if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
2124
+ const normalizedOptions = normalizeSessionWebSocketOptions(options);
2125
+ return {
2126
+ url: normalizeWebSocketUrl(urlOrOptions),
2127
+ options: normalizedOptions,
2128
+ legacyCallbacks: extractLegacyWebSocketCallbacks(options)
2129
+ };
2130
+ }
2131
+ const legacy = urlOrOptions;
2132
+ const normalizedOptions = normalizeSessionWebSocketOptions(legacy);
2133
+ return {
2134
+ url: normalizeWebSocketUrl(legacy.url),
2135
+ options: normalizedOptions,
2136
+ legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
2137
+ };
2665
2138
  }
2666
2139
  async function websocket(urlOrOptions, options) {
2667
- const normalized = normalizeStandaloneWebSocketArgs(urlOrOptions, options);
2668
- validateWebSocketProtocols(normalized.options.protocols);
2669
- assertNoManualWebSocketProtocolHeader(normalized.options.headers);
2670
- const emulationMode = resolveEmulationMode(
2671
- normalized.options.browser,
2672
- normalized.options.os,
2673
- normalized.options.emulation
2674
- );
2675
- const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
2676
- return WebSocket._connectWithInit({
2677
- _internal: true,
2678
- url: normalized.url,
2679
- options: normalized.options,
2680
- openDispatchMode: "deferred",
2681
- connect: (callbacks) => {
2682
- const nativeOptions = {
2683
- url: normalized.url,
2684
- headers: headersToTuples(normalized.options.headers ?? {}),
2685
- ...protocols && protocols.length > 0 && { protocols },
2686
- ...normalized.options.proxy !== void 0 && { proxy: normalized.options.proxy },
2687
- onMessage: callbacks.onMessage,
2688
- onClose: callbacks.onClose,
2689
- onError: callbacks.onError
2690
- };
2691
- applyNativeEmulationMode(nativeOptions, emulationMode);
2692
- return nativeBinding.websocketConnect(nativeOptions);
2693
- },
2694
- legacyCallbacks: normalized.legacyCallbacks
2695
- });
2140
+ const normalized = normalizeStandaloneWebSocketArgs(urlOrOptions, options);
2141
+ validateWebSocketProtocols(normalized.options.protocols);
2142
+ assertNoManualWebSocketProtocolHeader(normalized.options.headers);
2143
+ const emulationMode = resolveEmulationMode(normalized.options.browser, normalized.options.os, normalized.options.emulation);
2144
+ const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
2145
+ return WebSocket._connectWithInit({
2146
+ _internal: true,
2147
+ url: normalized.url,
2148
+ options: normalized.options,
2149
+ openDispatchMode: "deferred",
2150
+ connect: (callbacks) => {
2151
+ const nativeOptions = {
2152
+ url: normalized.url,
2153
+ headers: headersToTuples(normalized.options.headers ?? {}),
2154
+ ...protocols && protocols.length > 0 && { protocols },
2155
+ ...normalized.options.proxy !== void 0 && { proxy: normalized.options.proxy },
2156
+ ...normalized.options.maxFrameSize !== void 0 && { maxFrameSize: normalized.options.maxFrameSize },
2157
+ ...normalized.options.maxMessageSize !== void 0 && { maxMessageSize: normalized.options.maxMessageSize },
2158
+ onMessage: callbacks.onMessage,
2159
+ onClose: callbacks.onClose,
2160
+ onError: callbacks.onError
2161
+ };
2162
+ applyNativeEmulationMode(nativeOptions, emulationMode);
2163
+ return nativeBinding.websocketConnect(nativeOptions);
2164
+ },
2165
+ legacyCallbacks: normalized.legacyCallbacks
2166
+ });
2696
2167
  }
2697
2168
  var wreq_js_default = {
2698
- fetch,
2699
- request,
2700
- get,
2701
- post,
2702
- getProfiles,
2703
- getOperatingSystems,
2704
- createTransport,
2705
- createSession,
2706
- withSession,
2707
- websocket,
2708
- WebSocket,
2709
- Headers,
2710
- Response,
2711
- Transport,
2712
- Session,
2713
- RequestError
2169
+ fetch,
2170
+ request,
2171
+ get,
2172
+ post,
2173
+ getProfiles,
2174
+ getOperatingSystems,
2175
+ createTransport,
2176
+ createSession,
2177
+ withSession,
2178
+ websocket,
2179
+ WebSocket,
2180
+ Headers,
2181
+ Response,
2182
+ Transport,
2183
+ Session,
2184
+ RequestError
2714
2185
  };
2715
- // Annotate the CommonJS export names for ESM import in node:
2716
- 0 && (module.exports = {
2717
- Headers,
2718
- RequestError,
2719
- Response,
2720
- Session,
2721
- Transport,
2722
- WebSocket,
2723
- createSession,
2724
- createTransport,
2725
- fetch,
2726
- get,
2727
- getOperatingSystems,
2728
- getProfiles,
2729
- post,
2730
- request,
2731
- websocket,
2732
- withSession
2733
- });
2186
+ //#endregion
2187
+ exports.Headers = Headers;
2188
+ exports.RequestError = RequestError;
2189
+ exports.Response = Response;
2190
+ exports.Session = Session;
2191
+ exports.Transport = Transport;
2192
+ exports.WebSocket = WebSocket;
2193
+ exports.createSession = createSession;
2194
+ exports.createTransport = createTransport;
2195
+ exports.default = wreq_js_default;
2196
+ exports.fetch = fetch;
2197
+ exports.get = get;
2198
+ exports.getOperatingSystems = getOperatingSystems;
2199
+ exports.getProfiles = getProfiles;
2200
+ exports.post = post;
2201
+ exports.request = request;
2202
+ exports.websocket = websocket;
2203
+ exports.withSession = withSession;
2204
+
2734
2205
  //# sourceMappingURL=wreq-js.cjs.map