wreq-js 1.6.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -17
- package/dist/wreq-js.cjs +923 -121
- package/dist/wreq-js.cjs.map +1 -1
- package/dist/wreq-js.d.cts +264 -103
- package/dist/wreq-js.d.ts +264 -103
- package/dist/wreq-js.js +923 -121
- package/dist/wreq-js.js.map +1 -1
- package/package.json +31 -18
- package/rust/wreq-js.darwin-arm64.node +0 -0
- package/rust/wreq-js.darwin-x64.node +0 -0
- package/rust/wreq-js.linux-arm64-gnu.node +0 -0
- package/rust/wreq-js.linux-x64-gnu.node +0 -0
- package/rust/wreq-js.linux-x64-musl.node +0 -0
- package/rust/wreq-js.win32-x64-msvc.node +0 -0
package/dist/wreq-js.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createRequire } from "module";
|
|
|
5
5
|
import { ReadableStream } from "stream/web";
|
|
6
6
|
|
|
7
7
|
// src/types.ts
|
|
8
|
-
var RequestError = class extends
|
|
8
|
+
var RequestError = class extends TypeError {
|
|
9
9
|
constructor(message) {
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = "RequestError";
|
|
@@ -15,7 +15,9 @@ var RequestError = class extends Error {
|
|
|
15
15
|
// src/wreq-js.ts
|
|
16
16
|
var nativeBinding;
|
|
17
17
|
var cachedProfiles;
|
|
18
|
+
var cachedProfileSet;
|
|
18
19
|
var cachedOperatingSystems;
|
|
20
|
+
var cachedOperatingSystemSet;
|
|
19
21
|
function detectLibc() {
|
|
20
22
|
if (process.platform !== "linux") {
|
|
21
23
|
return void 0;
|
|
@@ -84,8 +86,13 @@ var bodyHandleFinalizer = typeof FinalizationRegistry === "function" ? new Final
|
|
|
84
86
|
}) : void 0;
|
|
85
87
|
var DEFAULT_BROWSER = "chrome_142";
|
|
86
88
|
var DEFAULT_OS = "macos";
|
|
89
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
87
90
|
var SUPPORTED_OSES = ["windows", "macos", "linux", "android", "ios"];
|
|
88
91
|
var UTF8_DECODER = new TextDecoder("utf-8");
|
|
92
|
+
var ephemeralIdCounter = 0;
|
|
93
|
+
function generateEphemeralSessionId() {
|
|
94
|
+
return `_e${++ephemeralIdCounter}`;
|
|
95
|
+
}
|
|
89
96
|
function generateSessionId() {
|
|
90
97
|
return randomUUID();
|
|
91
98
|
}
|
|
@@ -248,37 +255,37 @@ var Headers = class _Headers {
|
|
|
248
255
|
}
|
|
249
256
|
};
|
|
250
257
|
function headersToTuples(init) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (
|
|
255
|
-
return
|
|
258
|
+
return new Headers(init).toTuples();
|
|
259
|
+
}
|
|
260
|
+
function hasHeaderName(tuples, name) {
|
|
261
|
+
if (!tuples) {
|
|
262
|
+
return false;
|
|
256
263
|
}
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
const value = init[name];
|
|
264
|
-
if (value === void 0 || value === null) {
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
out.push([name, String(value)]);
|
|
264
|
+
const target = name.toLowerCase();
|
|
265
|
+
for (const [headerName] of tuples) {
|
|
266
|
+
if (headerName.toLowerCase() === target) {
|
|
267
|
+
return true;
|
|
268
268
|
}
|
|
269
|
-
return out;
|
|
270
269
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
function hasWebSocketProtocolHeader(headers) {
|
|
273
|
+
const protocolHeaderName = "Sec-WebSocket-Protocol";
|
|
274
|
+
if (!headers) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
return hasHeaderName(headersToTuples(headers), protocolHeaderName);
|
|
278
|
+
}
|
|
279
|
+
function assertNoManualWebSocketProtocolHeader(headers) {
|
|
280
|
+
if (hasWebSocketProtocolHeader(headers)) {
|
|
281
|
+
throw new RequestError("Do not set `Sec-WebSocket-Protocol` header manually; use the `protocols` option instead.");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function normalizeWebSocketProtocolList(protocols) {
|
|
285
|
+
if (protocols === void 0) {
|
|
286
|
+
return void 0;
|
|
280
287
|
}
|
|
281
|
-
return
|
|
288
|
+
return typeof protocols === "string" ? [protocols] : [...protocols];
|
|
282
289
|
}
|
|
283
290
|
function mergeHeaderTuples(defaults, overrides) {
|
|
284
291
|
if (!defaults) {
|
|
@@ -291,9 +298,19 @@ function mergeHeaderTuples(defaults, overrides) {
|
|
|
291
298
|
if (overrideTuples.length === 0) {
|
|
292
299
|
return defaults;
|
|
293
300
|
}
|
|
294
|
-
const overrideKeys = new Set(
|
|
295
|
-
const
|
|
296
|
-
|
|
301
|
+
const overrideKeys = /* @__PURE__ */ new Set();
|
|
302
|
+
for (const tuple of overrideTuples) {
|
|
303
|
+
overrideKeys.add(tuple[0].toLowerCase());
|
|
304
|
+
}
|
|
305
|
+
const merged = [];
|
|
306
|
+
for (const tuple of defaults) {
|
|
307
|
+
if (!overrideKeys.has(tuple[0].toLowerCase())) {
|
|
308
|
+
merged.push(tuple);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
for (const tuple of overrideTuples) {
|
|
312
|
+
merged.push(tuple);
|
|
313
|
+
}
|
|
297
314
|
return merged;
|
|
298
315
|
}
|
|
299
316
|
function cloneNativeResponse(payload) {
|
|
@@ -350,13 +367,16 @@ function createNativeBodyStream(handle) {
|
|
|
350
367
|
}
|
|
351
368
|
function wrapBodyStream(source, onFirstUse) {
|
|
352
369
|
let started = false;
|
|
353
|
-
|
|
370
|
+
let reader = null;
|
|
354
371
|
return new ReadableStream({
|
|
355
372
|
async pull(controller) {
|
|
356
373
|
if (!started) {
|
|
357
374
|
started = true;
|
|
358
375
|
onFirstUse();
|
|
359
376
|
}
|
|
377
|
+
if (!reader) {
|
|
378
|
+
reader = source.getReader();
|
|
379
|
+
}
|
|
360
380
|
try {
|
|
361
381
|
const { done, value } = await reader.read();
|
|
362
382
|
if (done) {
|
|
@@ -369,6 +389,9 @@ function wrapBodyStream(source, onFirstUse) {
|
|
|
369
389
|
}
|
|
370
390
|
},
|
|
371
391
|
cancel(reason) {
|
|
392
|
+
if (!reader) {
|
|
393
|
+
return source.cancel(reason);
|
|
394
|
+
}
|
|
372
395
|
return reader.cancel(reason);
|
|
373
396
|
}
|
|
374
397
|
});
|
|
@@ -502,6 +525,9 @@ var Response = class _Response {
|
|
|
502
525
|
const bytes = await this.consumeBody();
|
|
503
526
|
const { buffer, byteOffset, byteLength } = bytes;
|
|
504
527
|
if (buffer instanceof ArrayBuffer) {
|
|
528
|
+
if (byteOffset === 0 && byteLength === buffer.byteLength) {
|
|
529
|
+
return buffer;
|
|
530
|
+
}
|
|
505
531
|
return buffer.slice(byteOffset, byteOffset + byteLength);
|
|
506
532
|
}
|
|
507
533
|
const view = new Uint8Array(byteLength);
|
|
@@ -512,8 +538,22 @@ var Response = class _Response {
|
|
|
512
538
|
const bytes = await this.consumeBody();
|
|
513
539
|
return UTF8_DECODER.decode(bytes);
|
|
514
540
|
}
|
|
541
|
+
async blob() {
|
|
542
|
+
const bytes = await this.consumeBody();
|
|
543
|
+
const contentType = this.headers.get("content-type") ?? "";
|
|
544
|
+
return new Blob([bytes], contentType ? { type: contentType } : void 0);
|
|
545
|
+
}
|
|
546
|
+
async formData() {
|
|
547
|
+
const bytes = await this.consumeBody();
|
|
548
|
+
const contentType = this.headers.get("content-type");
|
|
549
|
+
const response = new globalThis.Response(
|
|
550
|
+
bytes,
|
|
551
|
+
contentType ? { headers: { "content-type": contentType } } : void 0
|
|
552
|
+
);
|
|
553
|
+
return response.formData();
|
|
554
|
+
}
|
|
515
555
|
clone() {
|
|
516
|
-
if (this.bodyUsed
|
|
556
|
+
if (this.bodyUsed) {
|
|
517
557
|
throw new TypeError("Cannot clone a Response whose body is already used");
|
|
518
558
|
}
|
|
519
559
|
if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
|
|
@@ -551,7 +591,7 @@ var Response = class _Response {
|
|
|
551
591
|
try {
|
|
552
592
|
return await nativeBinding.readBodyAll(this.payload.bodyHandle);
|
|
553
593
|
} catch (error) {
|
|
554
|
-
if (String(error).includes("not found")) {
|
|
594
|
+
if (String(error).includes("Body handle") && String(error).includes("not found")) {
|
|
555
595
|
return Buffer.alloc(0);
|
|
556
596
|
}
|
|
557
597
|
throw error;
|
|
@@ -648,6 +688,36 @@ var Session = class {
|
|
|
648
688
|
throw new RequestError(String(error));
|
|
649
689
|
}
|
|
650
690
|
}
|
|
691
|
+
async websocket(urlOrOptions, options) {
|
|
692
|
+
this.ensureActive();
|
|
693
|
+
const normalized = normalizeSessionWebSocketArgs(urlOrOptions, options);
|
|
694
|
+
validateWebSocketProtocols(normalized.options.protocols);
|
|
695
|
+
assertNoManualWebSocketProtocolHeader(normalized.options.headers);
|
|
696
|
+
const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
|
|
697
|
+
const transportId = this.defaults.transportId;
|
|
698
|
+
if (!transportId) {
|
|
699
|
+
throw new RequestError(
|
|
700
|
+
"Session has no transport. Create the session with browser/os options or pass a transport to use session.websocket()."
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
return WebSocket._connectWithInit({
|
|
704
|
+
_internal: true,
|
|
705
|
+
url: normalized.url,
|
|
706
|
+
options: normalized.options,
|
|
707
|
+
openDispatchMode: "deferred",
|
|
708
|
+
connect: (callbacks) => nativeBinding.websocketConnectSession({
|
|
709
|
+
url: normalized.url,
|
|
710
|
+
sessionId: this.id,
|
|
711
|
+
transportId,
|
|
712
|
+
headers: headersToTuples(normalized.options.headers ?? {}),
|
|
713
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
714
|
+
onMessage: callbacks.onMessage,
|
|
715
|
+
onClose: callbacks.onClose,
|
|
716
|
+
onError: callbacks.onError
|
|
717
|
+
}),
|
|
718
|
+
legacyCallbacks: normalized.legacyCallbacks
|
|
719
|
+
});
|
|
720
|
+
}
|
|
651
721
|
async close() {
|
|
652
722
|
if (this.disposed) {
|
|
653
723
|
return;
|
|
@@ -715,7 +785,7 @@ function resolveSessionContext(config) {
|
|
|
715
785
|
throw new RequestError("cookieMode 'session' requires a session or sessionId");
|
|
716
786
|
}
|
|
717
787
|
return {
|
|
718
|
-
sessionId:
|
|
788
|
+
sessionId: generateEphemeralSessionId(),
|
|
719
789
|
cookieMode: "ephemeral",
|
|
720
790
|
dropAfterRequest: true
|
|
721
791
|
};
|
|
@@ -728,7 +798,7 @@ function resolveTransportContext(config, sessionDefaults) {
|
|
|
728
798
|
if (config.transport.closed) {
|
|
729
799
|
throw new RequestError("Transport has been closed");
|
|
730
800
|
}
|
|
731
|
-
const hasProxy =
|
|
801
|
+
const hasProxy = config.proxy !== void 0;
|
|
732
802
|
if (config.browser !== void 0 || config.os !== void 0 || hasProxy || config.insecure !== void 0) {
|
|
733
803
|
throw new RequestError("`transport` cannot be combined with browser/os/proxy/insecure options");
|
|
734
804
|
}
|
|
@@ -779,8 +849,10 @@ function createAbortError(reason) {
|
|
|
779
849
|
return reason.name === "AbortError" ? reason : new DOMException(reason.message || fallbackMessage, "AbortError");
|
|
780
850
|
}
|
|
781
851
|
if (reason instanceof Error) {
|
|
782
|
-
|
|
783
|
-
|
|
852
|
+
const error2 = new Error(reason.message);
|
|
853
|
+
error2.name = "AbortError";
|
|
854
|
+
error2.cause = reason;
|
|
855
|
+
return error2;
|
|
784
856
|
}
|
|
785
857
|
if (typeof DOMException !== "undefined") {
|
|
786
858
|
return new DOMException(fallbackMessage, "AbortError");
|
|
@@ -826,11 +898,55 @@ function setupAbort(signal, cancelNative) {
|
|
|
826
898
|
return { promise, cleanup };
|
|
827
899
|
}
|
|
828
900
|
function coerceUrlInput(input) {
|
|
829
|
-
|
|
830
|
-
|
|
901
|
+
if (input instanceof URL) {
|
|
902
|
+
return input.href;
|
|
903
|
+
}
|
|
904
|
+
if (input.length === 0) {
|
|
831
905
|
throw new RequestError("URL is required");
|
|
832
906
|
}
|
|
833
|
-
|
|
907
|
+
if (input.charCodeAt(0) > 32 && input.charCodeAt(input.length - 1) > 32) {
|
|
908
|
+
return input;
|
|
909
|
+
}
|
|
910
|
+
const trimmed = input.trim();
|
|
911
|
+
if (trimmed.length === 0) {
|
|
912
|
+
throw new RequestError("URL is required");
|
|
913
|
+
}
|
|
914
|
+
return trimmed;
|
|
915
|
+
}
|
|
916
|
+
function isRequestLike(input) {
|
|
917
|
+
if (!input || typeof input !== "object") {
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
if (typeof Request !== "undefined" && input instanceof Request) {
|
|
921
|
+
return true;
|
|
922
|
+
}
|
|
923
|
+
const candidate = input;
|
|
924
|
+
return typeof candidate.url === "string" && typeof candidate.method === "string" && typeof candidate.arrayBuffer === "function" && typeof candidate.redirect === "string";
|
|
925
|
+
}
|
|
926
|
+
async function resolveFetchArgs(input, init) {
|
|
927
|
+
if (!isRequestLike(input)) {
|
|
928
|
+
return { url: coerceUrlInput(input), init: init ?? {} };
|
|
929
|
+
}
|
|
930
|
+
const mergedInit = init ? { ...init } : {};
|
|
931
|
+
if (mergedInit.method === void 0) {
|
|
932
|
+
mergedInit.method = input.method;
|
|
933
|
+
}
|
|
934
|
+
if (mergedInit.headers === void 0) {
|
|
935
|
+
mergedInit.headers = input.headers;
|
|
936
|
+
}
|
|
937
|
+
if (mergedInit.redirect === void 0 && (input.redirect === "follow" || input.redirect === "manual" || input.redirect === "error")) {
|
|
938
|
+
mergedInit.redirect = input.redirect;
|
|
939
|
+
}
|
|
940
|
+
if (mergedInit.signal === void 0) {
|
|
941
|
+
mergedInit.signal = input.signal;
|
|
942
|
+
}
|
|
943
|
+
if (mergedInit.body === void 0 && input.body !== null) {
|
|
944
|
+
if (input.bodyUsed) {
|
|
945
|
+
throw new TypeError("Request body is already used");
|
|
946
|
+
}
|
|
947
|
+
mergedInit.body = Buffer.from(await input.arrayBuffer());
|
|
948
|
+
}
|
|
949
|
+
return { url: coerceUrlInput(input.url), init: mergedInit };
|
|
834
950
|
}
|
|
835
951
|
function normalizeUrlForComparison(value) {
|
|
836
952
|
try {
|
|
@@ -845,30 +961,58 @@ function validateRedirectMode(mode) {
|
|
|
845
961
|
}
|
|
846
962
|
throw new RequestError(`Redirect mode '${mode}' is not supported`);
|
|
847
963
|
}
|
|
848
|
-
function serializeBody(body) {
|
|
964
|
+
async function serializeBody(body) {
|
|
849
965
|
if (body === null || body === void 0) {
|
|
850
|
-
return
|
|
966
|
+
return {};
|
|
851
967
|
}
|
|
852
968
|
if (typeof body === "string") {
|
|
853
|
-
return Buffer.from(body, "utf8");
|
|
969
|
+
return { body: Buffer.from(body, "utf8") };
|
|
854
970
|
}
|
|
855
971
|
if (Buffer.isBuffer(body)) {
|
|
856
|
-
return body;
|
|
972
|
+
return { body };
|
|
857
973
|
}
|
|
858
974
|
if (body instanceof URLSearchParams) {
|
|
859
|
-
return
|
|
975
|
+
return {
|
|
976
|
+
body: Buffer.from(body.toString(), "utf8"),
|
|
977
|
+
contentType: "application/x-www-form-urlencoded;charset=UTF-8"
|
|
978
|
+
};
|
|
860
979
|
}
|
|
861
980
|
if (body instanceof ArrayBuffer) {
|
|
862
|
-
return Buffer.from(body);
|
|
981
|
+
return { body: Buffer.from(body) };
|
|
863
982
|
}
|
|
864
983
|
if (ArrayBuffer.isView(body)) {
|
|
865
|
-
return Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
|
984
|
+
return { body: Buffer.from(body.buffer, body.byteOffset, body.byteLength) };
|
|
985
|
+
}
|
|
986
|
+
if (typeof Blob !== "undefined" && body instanceof Blob) {
|
|
987
|
+
const buffer = Buffer.from(await body.arrayBuffer());
|
|
988
|
+
return { body: buffer, ...body.type ? { contentType: body.type } : {} };
|
|
989
|
+
}
|
|
990
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
991
|
+
const encoded = new globalThis.Response(body);
|
|
992
|
+
const contentType = encoded.headers.get("content-type") ?? void 0;
|
|
993
|
+
const buffer = Buffer.from(await encoded.arrayBuffer());
|
|
994
|
+
return { body: buffer, ...contentType ? { contentType } : {} };
|
|
866
995
|
}
|
|
867
|
-
throw new TypeError(
|
|
996
|
+
throw new TypeError(
|
|
997
|
+
"Unsupported body type; expected string, Buffer, ArrayBuffer, ArrayBufferView, URLSearchParams, Blob, or FormData"
|
|
998
|
+
);
|
|
868
999
|
}
|
|
869
1000
|
function ensureMethod(method) {
|
|
870
|
-
|
|
871
|
-
|
|
1001
|
+
if (method === void 0 || method.length === 0) {
|
|
1002
|
+
return "GET";
|
|
1003
|
+
}
|
|
1004
|
+
switch (method) {
|
|
1005
|
+
case "GET":
|
|
1006
|
+
case "POST":
|
|
1007
|
+
case "PUT":
|
|
1008
|
+
case "DELETE":
|
|
1009
|
+
case "PATCH":
|
|
1010
|
+
case "HEAD":
|
|
1011
|
+
case "OPTIONS":
|
|
1012
|
+
return method;
|
|
1013
|
+
}
|
|
1014
|
+
const normalized = method.trim().toUpperCase();
|
|
1015
|
+
return normalized.length > 0 ? normalized : "GET";
|
|
872
1016
|
}
|
|
873
1017
|
function ensureBodyAllowed(method, body) {
|
|
874
1018
|
if (body === void 0) {
|
|
@@ -879,21 +1023,25 @@ function ensureBodyAllowed(method, body) {
|
|
|
879
1023
|
}
|
|
880
1024
|
}
|
|
881
1025
|
function validateBrowserProfile(browser) {
|
|
882
|
-
if (
|
|
1026
|
+
if (browser === void 0) {
|
|
883
1027
|
return;
|
|
884
1028
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
1029
|
+
if (typeof browser !== "string" || browser.trim().length === 0) {
|
|
1030
|
+
throw new RequestError("Browser profile must not be empty");
|
|
1031
|
+
}
|
|
1032
|
+
if (!getProfileSet().has(browser)) {
|
|
1033
|
+
throw new RequestError(`Invalid browser profile: ${browser}. Available profiles: ${getProfiles().join(", ")}`);
|
|
888
1034
|
}
|
|
889
1035
|
}
|
|
890
1036
|
function validateOperatingSystem(os) {
|
|
891
|
-
if (
|
|
1037
|
+
if (os === void 0) {
|
|
892
1038
|
return;
|
|
893
1039
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1040
|
+
if (typeof os !== "string" || os.trim().length === 0) {
|
|
1041
|
+
throw new RequestError("Operating system must not be empty");
|
|
1042
|
+
}
|
|
1043
|
+
if (!getOperatingSystemSet().has(os)) {
|
|
1044
|
+
throw new RequestError(`Invalid operating system: ${os}. Available options: ${getOperatingSystems().join(", ")}`);
|
|
897
1045
|
}
|
|
898
1046
|
}
|
|
899
1047
|
function validateTimeout(timeout) {
|
|
@@ -903,8 +1051,8 @@ function validateTimeout(timeout) {
|
|
|
903
1051
|
if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
|
|
904
1052
|
throw new RequestError("Timeout must be a finite number");
|
|
905
1053
|
}
|
|
906
|
-
if (timeout
|
|
907
|
-
throw new RequestError("Timeout must be
|
|
1054
|
+
if (timeout < 0) {
|
|
1055
|
+
throw new RequestError("Timeout must be 0 (no timeout) or a positive number");
|
|
908
1056
|
}
|
|
909
1057
|
}
|
|
910
1058
|
function validatePositiveNumber(value, label) {
|
|
@@ -953,10 +1101,6 @@ async function dispatchRequest(options, requestUrl, signal) {
|
|
|
953
1101
|
}
|
|
954
1102
|
};
|
|
955
1103
|
const abortHandler = setupAbort(signal, cancelNative);
|
|
956
|
-
if (!abortHandler) {
|
|
957
|
-
cancelNative();
|
|
958
|
-
throw createAbortError(signal.reason);
|
|
959
|
-
}
|
|
960
1104
|
const pending = Promise.race([nativeBinding.request(options, requestId, true), abortHandler.promise]);
|
|
961
1105
|
let payload;
|
|
962
1106
|
try {
|
|
@@ -975,8 +1119,9 @@ async function dispatchRequest(options, requestUrl, signal) {
|
|
|
975
1119
|
return new Response(payload, requestUrl);
|
|
976
1120
|
}
|
|
977
1121
|
async function fetch(input, init) {
|
|
978
|
-
const
|
|
979
|
-
const
|
|
1122
|
+
const resolved = await resolveFetchArgs(input, init);
|
|
1123
|
+
const url = resolved.url;
|
|
1124
|
+
const config = resolved.init;
|
|
980
1125
|
const sessionContext = resolveSessionContext(config);
|
|
981
1126
|
const sessionDefaults = sessionContext.defaults;
|
|
982
1127
|
validateRedirectMode(config.redirect);
|
|
@@ -984,11 +1129,18 @@ async function fetch(input, init) {
|
|
|
984
1129
|
validateTimeout(config.timeout);
|
|
985
1130
|
}
|
|
986
1131
|
const method = ensureMethod(config.method);
|
|
987
|
-
const
|
|
1132
|
+
const serializedBody = await serializeBody(config.body ?? null);
|
|
1133
|
+
const body = serializedBody.body;
|
|
988
1134
|
ensureBodyAllowed(method, body);
|
|
989
|
-
|
|
1135
|
+
let headerTuples = mergeHeaderTuples(sessionDefaults?.defaultHeaders, config.headers);
|
|
1136
|
+
if (serializedBody.contentType && !hasHeaderName(headerTuples, "content-type")) {
|
|
1137
|
+
if (!headerTuples) {
|
|
1138
|
+
headerTuples = [];
|
|
1139
|
+
}
|
|
1140
|
+
headerTuples.push(["Content-Type", serializedBody.contentType]);
|
|
1141
|
+
}
|
|
990
1142
|
const transport = resolveTransportContext(config, sessionDefaults);
|
|
991
|
-
const timeout = config.timeout ?? sessionDefaults?.timeout;
|
|
1143
|
+
const timeout = config.timeout ?? sessionDefaults?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
992
1144
|
const requestOptions = {
|
|
993
1145
|
url,
|
|
994
1146
|
method,
|
|
@@ -1010,9 +1162,7 @@ async function fetch(input, init) {
|
|
|
1010
1162
|
requestOptions.insecure = transport.insecure;
|
|
1011
1163
|
}
|
|
1012
1164
|
}
|
|
1013
|
-
|
|
1014
|
-
requestOptions.timeout = timeout;
|
|
1015
|
-
}
|
|
1165
|
+
requestOptions.timeout = timeout;
|
|
1016
1166
|
if (config.redirect !== void 0) {
|
|
1017
1167
|
requestOptions.redirect = config.redirect;
|
|
1018
1168
|
}
|
|
@@ -1106,6 +1256,7 @@ async function request(options) {
|
|
|
1106
1256
|
}
|
|
1107
1257
|
const { url, ...rest } = options;
|
|
1108
1258
|
const init = {};
|
|
1259
|
+
const legacy = rest;
|
|
1109
1260
|
if (rest.method !== void 0) {
|
|
1110
1261
|
init.method = rest.method;
|
|
1111
1262
|
}
|
|
@@ -1133,12 +1284,26 @@ async function request(options) {
|
|
|
1133
1284
|
if (rest.transport !== void 0) {
|
|
1134
1285
|
init.transport = rest.transport;
|
|
1135
1286
|
}
|
|
1287
|
+
if (rest.insecure !== void 0) {
|
|
1288
|
+
init.insecure = rest.insecure;
|
|
1289
|
+
}
|
|
1136
1290
|
if (rest.disableDefaultHeaders !== void 0) {
|
|
1137
1291
|
init.disableDefaultHeaders = rest.disableDefaultHeaders;
|
|
1138
1292
|
}
|
|
1139
1293
|
if (rest.redirect !== void 0) {
|
|
1140
1294
|
init.redirect = rest.redirect;
|
|
1141
1295
|
}
|
|
1296
|
+
if (legacy.signal !== void 0) {
|
|
1297
|
+
init.signal = legacy.signal;
|
|
1298
|
+
}
|
|
1299
|
+
if (legacy.session !== void 0) {
|
|
1300
|
+
init.session = legacy.session;
|
|
1301
|
+
}
|
|
1302
|
+
if (legacy.cookieMode !== void 0) {
|
|
1303
|
+
init.cookieMode = legacy.cookieMode;
|
|
1304
|
+
} else if (legacy.ephemeral === true) {
|
|
1305
|
+
init.cookieMode = "ephemeral";
|
|
1306
|
+
}
|
|
1142
1307
|
return fetch(url, init);
|
|
1143
1308
|
}
|
|
1144
1309
|
function getProfiles() {
|
|
@@ -1147,6 +1312,12 @@ function getProfiles() {
|
|
|
1147
1312
|
}
|
|
1148
1313
|
return cachedProfiles;
|
|
1149
1314
|
}
|
|
1315
|
+
function getProfileSet() {
|
|
1316
|
+
if (!cachedProfileSet) {
|
|
1317
|
+
cachedProfileSet = new Set(getProfiles());
|
|
1318
|
+
}
|
|
1319
|
+
return cachedProfileSet;
|
|
1320
|
+
}
|
|
1150
1321
|
function getOperatingSystems() {
|
|
1151
1322
|
if (!cachedOperatingSystems) {
|
|
1152
1323
|
const fromNative = nativeBinding.getOperatingSystems?.();
|
|
@@ -1154,6 +1325,12 @@ function getOperatingSystems() {
|
|
|
1154
1325
|
}
|
|
1155
1326
|
return cachedOperatingSystems;
|
|
1156
1327
|
}
|
|
1328
|
+
function getOperatingSystemSet() {
|
|
1329
|
+
if (!cachedOperatingSystemSet) {
|
|
1330
|
+
cachedOperatingSystemSet = new Set(getOperatingSystems());
|
|
1331
|
+
}
|
|
1332
|
+
return cachedOperatingSystemSet;
|
|
1333
|
+
}
|
|
1157
1334
|
async function get(url, init) {
|
|
1158
1335
|
const config = {};
|
|
1159
1336
|
if (init) {
|
|
@@ -1173,72 +1350,696 @@ async function post(url, body, init) {
|
|
|
1173
1350
|
}
|
|
1174
1351
|
return fetch(url, config);
|
|
1175
1352
|
}
|
|
1176
|
-
|
|
1353
|
+
function normalizeWebSocketUrl(url) {
|
|
1354
|
+
const normalized = String(url).trim();
|
|
1355
|
+
if (!normalized) {
|
|
1356
|
+
throw new RequestError("URL is required");
|
|
1357
|
+
}
|
|
1358
|
+
let parsed;
|
|
1359
|
+
try {
|
|
1360
|
+
parsed = new URL(normalized);
|
|
1361
|
+
} catch (error) {
|
|
1362
|
+
throw new RequestError(String(error));
|
|
1363
|
+
}
|
|
1364
|
+
if (parsed.hash) {
|
|
1365
|
+
throw new RequestError("WebSocket URL must not include a hash fragment");
|
|
1366
|
+
}
|
|
1367
|
+
if (parsed.protocol === "http:") {
|
|
1368
|
+
parsed.protocol = "ws:";
|
|
1369
|
+
} else if (parsed.protocol === "https:") {
|
|
1370
|
+
parsed.protocol = "wss:";
|
|
1371
|
+
}
|
|
1372
|
+
if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
|
|
1373
|
+
throw new RequestError("expected a ws: or wss: url");
|
|
1374
|
+
}
|
|
1375
|
+
return parsed.toString();
|
|
1376
|
+
}
|
|
1377
|
+
function validateWebSocketProtocols(protocols) {
|
|
1378
|
+
if (protocols === void 0) {
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
const protocolList = typeof protocols === "string" ? [protocols] : protocols;
|
|
1382
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1383
|
+
const validToken = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
1384
|
+
for (const protocol of protocolList) {
|
|
1385
|
+
if (typeof protocol !== "string" || protocol.length === 0) {
|
|
1386
|
+
throw new RequestError("WebSocket protocol values must be non-empty strings");
|
|
1387
|
+
}
|
|
1388
|
+
if (!validToken.test(protocol)) {
|
|
1389
|
+
throw new RequestError(`Invalid WebSocket protocol value: ${protocol}`);
|
|
1390
|
+
}
|
|
1391
|
+
if (seen.has(protocol)) {
|
|
1392
|
+
throw new RequestError(`Duplicate WebSocket protocol: ${protocol}`);
|
|
1393
|
+
}
|
|
1394
|
+
seen.add(protocol);
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
function normalizeStandaloneWebSocketOptions(options) {
|
|
1398
|
+
const normalized = {};
|
|
1399
|
+
if (!options) {
|
|
1400
|
+
return normalized;
|
|
1401
|
+
}
|
|
1402
|
+
if (options.browser !== void 0) {
|
|
1403
|
+
normalized.browser = options.browser;
|
|
1404
|
+
}
|
|
1405
|
+
if (options.os !== void 0) {
|
|
1406
|
+
normalized.os = options.os;
|
|
1407
|
+
}
|
|
1408
|
+
if (options.headers !== void 0) {
|
|
1409
|
+
normalized.headers = options.headers;
|
|
1410
|
+
}
|
|
1411
|
+
if (options.proxy !== void 0) {
|
|
1412
|
+
normalized.proxy = options.proxy;
|
|
1413
|
+
}
|
|
1414
|
+
if (options.protocols !== void 0) {
|
|
1415
|
+
normalized.protocols = options.protocols;
|
|
1416
|
+
}
|
|
1417
|
+
if (options.binaryType !== void 0) {
|
|
1418
|
+
if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
|
|
1419
|
+
throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
|
|
1420
|
+
}
|
|
1421
|
+
normalized.binaryType = options.binaryType;
|
|
1422
|
+
}
|
|
1423
|
+
return normalized;
|
|
1424
|
+
}
|
|
1425
|
+
function normalizeSessionWebSocketOptions(options) {
|
|
1426
|
+
const normalized = {};
|
|
1427
|
+
if (!options) {
|
|
1428
|
+
return normalized;
|
|
1429
|
+
}
|
|
1430
|
+
const optionsWithOverrides = options;
|
|
1431
|
+
if (optionsWithOverrides.browser !== void 0) {
|
|
1432
|
+
throw new RequestError(
|
|
1433
|
+
"`browser` is not supported in session.websocket(); the session controls browser emulation."
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
if (optionsWithOverrides.os !== void 0) {
|
|
1437
|
+
throw new RequestError("`os` is not supported in session.websocket(); the session controls OS emulation.");
|
|
1438
|
+
}
|
|
1439
|
+
if (optionsWithOverrides.proxy !== void 0) {
|
|
1440
|
+
throw new RequestError("`proxy` is not supported in session.websocket(); the session transport controls proxying.");
|
|
1441
|
+
}
|
|
1442
|
+
if (options.headers !== void 0) {
|
|
1443
|
+
normalized.headers = options.headers;
|
|
1444
|
+
}
|
|
1445
|
+
if (options.protocols !== void 0) {
|
|
1446
|
+
normalized.protocols = options.protocols;
|
|
1447
|
+
}
|
|
1448
|
+
if (options.binaryType !== void 0) {
|
|
1449
|
+
if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
|
|
1450
|
+
throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
|
|
1451
|
+
}
|
|
1452
|
+
normalized.binaryType = options.binaryType;
|
|
1453
|
+
}
|
|
1454
|
+
return normalized;
|
|
1455
|
+
}
|
|
1456
|
+
function extractLegacyWebSocketCallbacks(options) {
|
|
1457
|
+
if (!isPlainObject(options)) {
|
|
1458
|
+
return void 0;
|
|
1459
|
+
}
|
|
1460
|
+
const maybeCallbacks = options;
|
|
1461
|
+
const callbacks = {};
|
|
1462
|
+
if (typeof maybeCallbacks.onMessage === "function") {
|
|
1463
|
+
callbacks.onMessage = maybeCallbacks.onMessage;
|
|
1464
|
+
}
|
|
1465
|
+
if (typeof maybeCallbacks.onClose === "function") {
|
|
1466
|
+
callbacks.onClose = maybeCallbacks.onClose;
|
|
1467
|
+
}
|
|
1468
|
+
if (typeof maybeCallbacks.onError === "function") {
|
|
1469
|
+
callbacks.onError = maybeCallbacks.onError;
|
|
1470
|
+
}
|
|
1471
|
+
return Object.keys(callbacks).length > 0 ? callbacks : void 0;
|
|
1472
|
+
}
|
|
1473
|
+
function normalizeWebSocketCloseOptions(code, reason) {
|
|
1474
|
+
if (code === void 0 && reason === void 0) {
|
|
1475
|
+
return void 0;
|
|
1476
|
+
}
|
|
1477
|
+
if (code === void 0) {
|
|
1478
|
+
throw new RequestError("A close code is required when providing a close reason");
|
|
1479
|
+
}
|
|
1480
|
+
if (!Number.isInteger(code)) {
|
|
1481
|
+
throw new RequestError("Close code must be an integer");
|
|
1482
|
+
}
|
|
1483
|
+
if (code !== 1e3 && (code < 3e3 || code > 4999)) {
|
|
1484
|
+
throw new RequestError("Close code must be 1000 or in range 3000-4999");
|
|
1485
|
+
}
|
|
1486
|
+
const normalizedReason = reason ?? "";
|
|
1487
|
+
if (Buffer.byteLength(normalizedReason, "utf8") > 123) {
|
|
1488
|
+
throw new RequestError("Close reason must be 123 bytes or fewer");
|
|
1489
|
+
}
|
|
1490
|
+
return {
|
|
1491
|
+
code,
|
|
1492
|
+
reason: normalizedReason
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
function isWebSocketListenerType(type) {
|
|
1496
|
+
return type === "open" || type === "message" || type === "close" || type === "error";
|
|
1497
|
+
}
|
|
1498
|
+
var WebSocket = class _WebSocket {
|
|
1499
|
+
static CONNECTING = 0;
|
|
1500
|
+
static OPEN = 1;
|
|
1501
|
+
static CLOSING = 2;
|
|
1502
|
+
static CLOSED = 3;
|
|
1503
|
+
url;
|
|
1504
|
+
protocol = "";
|
|
1505
|
+
extensions = "";
|
|
1506
|
+
readyState = _WebSocket.CONNECTING;
|
|
1507
|
+
_binaryType = "nodebuffer";
|
|
1508
|
+
_bufferedAmount = 0;
|
|
1509
|
+
_onopen = null;
|
|
1510
|
+
_onmessage = null;
|
|
1511
|
+
_onclose = null;
|
|
1512
|
+
_onerror = null;
|
|
1513
|
+
_onHandlerOrder = {
|
|
1514
|
+
open: -1,
|
|
1515
|
+
message: -1,
|
|
1516
|
+
close: -1,
|
|
1517
|
+
error: -1
|
|
1518
|
+
};
|
|
1519
|
+
_listenerOrderCounter = 0;
|
|
1520
|
+
_listeners = {
|
|
1521
|
+
open: /* @__PURE__ */ new Map(),
|
|
1522
|
+
message: /* @__PURE__ */ new Map(),
|
|
1523
|
+
close: /* @__PURE__ */ new Map(),
|
|
1524
|
+
error: /* @__PURE__ */ new Map()
|
|
1525
|
+
};
|
|
1526
|
+
_legacyCallbacks;
|
|
1527
|
+
_openDispatchMode;
|
|
1177
1528
|
_connection;
|
|
1529
|
+
_connectPromise;
|
|
1530
|
+
_closeOptions;
|
|
1178
1531
|
_finalizerToken;
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1532
|
+
_openEventDispatched = false;
|
|
1533
|
+
_openEventQueued = false;
|
|
1534
|
+
_closeEventDispatched = false;
|
|
1535
|
+
_nativeCloseStarted = false;
|
|
1536
|
+
_pendingMessages = [];
|
|
1537
|
+
_sendChain = Promise.resolve();
|
|
1538
|
+
constructor(urlOrInit, protocolsOrOptions, maybeOptions) {
|
|
1539
|
+
let init;
|
|
1540
|
+
if (isInternalWebSocketInit(urlOrInit)) {
|
|
1541
|
+
init = urlOrInit;
|
|
1542
|
+
} else {
|
|
1543
|
+
init = _WebSocket.buildStandaloneInit(urlOrInit, protocolsOrOptions, maybeOptions);
|
|
1544
|
+
}
|
|
1545
|
+
this.url = init.url;
|
|
1546
|
+
this.binaryType = init.options.binaryType ?? "nodebuffer";
|
|
1547
|
+
this._legacyCallbacks = init.legacyCallbacks;
|
|
1548
|
+
this._openDispatchMode = init.openDispatchMode;
|
|
1549
|
+
this._connectPromise = this.connect(init.connect);
|
|
1550
|
+
void this._connectPromise.catch(() => void 0);
|
|
1551
|
+
}
|
|
1552
|
+
get binaryType() {
|
|
1553
|
+
return this._binaryType;
|
|
1554
|
+
}
|
|
1555
|
+
set binaryType(value) {
|
|
1556
|
+
if (value === "arraybuffer" || value === "blob" || value === "nodebuffer") {
|
|
1557
|
+
this._binaryType = value;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
get bufferedAmount() {
|
|
1561
|
+
return this._bufferedAmount;
|
|
1562
|
+
}
|
|
1563
|
+
get onopen() {
|
|
1564
|
+
return this._onopen;
|
|
1565
|
+
}
|
|
1566
|
+
set onopen(listener) {
|
|
1567
|
+
this._onopen = listener;
|
|
1568
|
+
this._onHandlerOrder.open = listener ? ++this._listenerOrderCounter : -1;
|
|
1569
|
+
}
|
|
1570
|
+
get onmessage() {
|
|
1571
|
+
return this._onmessage;
|
|
1572
|
+
}
|
|
1573
|
+
set onmessage(listener) {
|
|
1574
|
+
this._onmessage = listener;
|
|
1575
|
+
this._onHandlerOrder.message = listener ? ++this._listenerOrderCounter : -1;
|
|
1576
|
+
}
|
|
1577
|
+
get onclose() {
|
|
1578
|
+
return this._onclose;
|
|
1579
|
+
}
|
|
1580
|
+
set onclose(listener) {
|
|
1581
|
+
this._onclose = listener;
|
|
1582
|
+
this._onHandlerOrder.close = listener ? ++this._listenerOrderCounter : -1;
|
|
1583
|
+
}
|
|
1584
|
+
get onerror() {
|
|
1585
|
+
return this._onerror;
|
|
1586
|
+
}
|
|
1587
|
+
set onerror(listener) {
|
|
1588
|
+
this._onerror = listener;
|
|
1589
|
+
this._onHandlerOrder.error = listener ? ++this._listenerOrderCounter : -1;
|
|
1590
|
+
}
|
|
1591
|
+
static async _connectWithInit(init) {
|
|
1592
|
+
const ws = new _WebSocket(init);
|
|
1593
|
+
await ws._waitUntilConnected();
|
|
1594
|
+
ws.scheduleOpenEventAfterAwait();
|
|
1595
|
+
return ws;
|
|
1596
|
+
}
|
|
1597
|
+
static buildStandaloneInit(url, protocolsOrOptions, maybeOptions) {
|
|
1598
|
+
const optionsCandidate = typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? maybeOptions : protocolsOrOptions ?? maybeOptions;
|
|
1599
|
+
const normalizedOptions = normalizeStandaloneWebSocketOptions(optionsCandidate);
|
|
1600
|
+
validateWebSocketProtocols(
|
|
1601
|
+
typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
|
|
1602
|
+
);
|
|
1603
|
+
assertNoManualWebSocketProtocolHeader(normalizedOptions.headers);
|
|
1604
|
+
validateBrowserProfile(normalizedOptions.browser);
|
|
1605
|
+
const os = normalizedOptions.os ?? DEFAULT_OS;
|
|
1606
|
+
validateOperatingSystem(os);
|
|
1607
|
+
const browser = normalizedOptions.browser ?? DEFAULT_BROWSER;
|
|
1608
|
+
const protocols = normalizeWebSocketProtocolList(
|
|
1609
|
+
typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
|
|
1610
|
+
);
|
|
1611
|
+
return {
|
|
1612
|
+
_internal: true,
|
|
1613
|
+
url: normalizeWebSocketUrl(url),
|
|
1614
|
+
options: normalizedOptions,
|
|
1615
|
+
openDispatchMode: "automatic",
|
|
1616
|
+
connect: (callbacks) => nativeBinding.websocketConnect({
|
|
1617
|
+
url: normalizeWebSocketUrl(url),
|
|
1618
|
+
browser,
|
|
1619
|
+
os,
|
|
1620
|
+
headers: headersToTuples(normalizedOptions.headers ?? {}),
|
|
1621
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
1622
|
+
...normalizedOptions.proxy !== void 0 && { proxy: normalizedOptions.proxy },
|
|
1623
|
+
onMessage: callbacks.onMessage,
|
|
1624
|
+
onClose: callbacks.onClose,
|
|
1625
|
+
onError: callbacks.onError
|
|
1626
|
+
}),
|
|
1627
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(optionsCandidate)
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
async connect(connectFn) {
|
|
1191
1631
|
try {
|
|
1192
|
-
await
|
|
1632
|
+
const connection = await connectFn({
|
|
1633
|
+
onMessage: (data) => {
|
|
1634
|
+
this.handleNativeMessage(data);
|
|
1635
|
+
},
|
|
1636
|
+
onClose: (event) => {
|
|
1637
|
+
this.handleNativeClose(event);
|
|
1638
|
+
},
|
|
1639
|
+
onError: (message) => {
|
|
1640
|
+
this.handleNativeError(message);
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
this._connection = connection;
|
|
1644
|
+
this.protocol = connection.protocol ?? "";
|
|
1645
|
+
this.extensions = connection.extensions ?? "";
|
|
1646
|
+
if (websocketFinalizer) {
|
|
1647
|
+
this._finalizerToken = connection;
|
|
1648
|
+
websocketFinalizer.register(this, connection, connection);
|
|
1649
|
+
}
|
|
1650
|
+
if (this.readyState === _WebSocket.CLOSING) {
|
|
1651
|
+
this.startNativeClose();
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
this.readyState = _WebSocket.OPEN;
|
|
1655
|
+
if (this._openDispatchMode === "automatic") {
|
|
1656
|
+
this.scheduleOpenEventAfterConnect();
|
|
1657
|
+
}
|
|
1193
1658
|
} catch (error) {
|
|
1659
|
+
this.handleNativeError(String(error));
|
|
1660
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1194
1661
|
throw new RequestError(String(error));
|
|
1195
1662
|
}
|
|
1196
1663
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1664
|
+
_waitUntilConnected() {
|
|
1665
|
+
return this._connectPromise;
|
|
1666
|
+
}
|
|
1667
|
+
scheduleOpenEventAfterConnect() {
|
|
1668
|
+
this.scheduleOpenEventWithDepth(2);
|
|
1669
|
+
}
|
|
1670
|
+
scheduleOpenEventAfterAwait() {
|
|
1671
|
+
this.scheduleOpenEventWithDepth(3);
|
|
1672
|
+
}
|
|
1673
|
+
scheduleOpenEventWithDepth(depth) {
|
|
1674
|
+
if (this._openEventDispatched || this._openEventQueued || this.readyState !== _WebSocket.OPEN) {
|
|
1202
1675
|
return;
|
|
1203
1676
|
}
|
|
1204
|
-
this.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1677
|
+
this._openEventQueued = true;
|
|
1678
|
+
const queue = (remaining) => {
|
|
1679
|
+
if (remaining === 0) {
|
|
1680
|
+
this._openEventQueued = false;
|
|
1681
|
+
if (this._openEventDispatched || this.readyState !== _WebSocket.OPEN) {
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
this._openEventDispatched = true;
|
|
1685
|
+
this.dispatchOpenEvent();
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
queueMicrotask(() => {
|
|
1689
|
+
queue(remaining - 1);
|
|
1690
|
+
});
|
|
1691
|
+
};
|
|
1692
|
+
queue(depth);
|
|
1693
|
+
}
|
|
1694
|
+
releaseConnectionTracking() {
|
|
1695
|
+
if (!this._finalizerToken || !websocketFinalizer) {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
websocketFinalizer.unregister(this._finalizerToken);
|
|
1699
|
+
this._finalizerToken = void 0;
|
|
1700
|
+
}
|
|
1701
|
+
toMessageEventData(data) {
|
|
1702
|
+
if (typeof data === "string") {
|
|
1703
|
+
return data;
|
|
1208
1704
|
}
|
|
1705
|
+
if (this._binaryType === "arraybuffer") {
|
|
1706
|
+
const arrayBuffer = new ArrayBuffer(data.byteLength);
|
|
1707
|
+
new Uint8Array(arrayBuffer).set(data);
|
|
1708
|
+
return arrayBuffer;
|
|
1709
|
+
}
|
|
1710
|
+
if (this._binaryType === "blob") {
|
|
1711
|
+
return new Blob([data]);
|
|
1712
|
+
}
|
|
1713
|
+
return data;
|
|
1714
|
+
}
|
|
1715
|
+
invokeListener(listener, event) {
|
|
1209
1716
|
try {
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1717
|
+
if (typeof listener === "function") {
|
|
1718
|
+
listener.call(this, event);
|
|
1719
|
+
} else {
|
|
1720
|
+
listener.handleEvent(event);
|
|
1721
|
+
}
|
|
1722
|
+
} catch {
|
|
1213
1723
|
}
|
|
1214
1724
|
}
|
|
1725
|
+
createBaseEvent(type) {
|
|
1726
|
+
return {
|
|
1727
|
+
type,
|
|
1728
|
+
isTrusted: false,
|
|
1729
|
+
timeStamp: Date.now(),
|
|
1730
|
+
target: this,
|
|
1731
|
+
currentTarget: this
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
getOnHandler(type) {
|
|
1735
|
+
switch (type) {
|
|
1736
|
+
case "open":
|
|
1737
|
+
return this._onopen;
|
|
1738
|
+
case "message":
|
|
1739
|
+
return this._onmessage;
|
|
1740
|
+
case "close":
|
|
1741
|
+
return this._onclose;
|
|
1742
|
+
case "error":
|
|
1743
|
+
return this._onerror;
|
|
1744
|
+
default:
|
|
1745
|
+
return null;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
getOnHandlerOrder(type) {
|
|
1749
|
+
return this._onHandlerOrder[type];
|
|
1750
|
+
}
|
|
1751
|
+
getListenerMap(type) {
|
|
1752
|
+
return this._listeners[type];
|
|
1753
|
+
}
|
|
1754
|
+
dispatchEvent(type, event) {
|
|
1755
|
+
const listenerMap = this.getListenerMap(type);
|
|
1756
|
+
const onHandler = this.getOnHandler(type);
|
|
1757
|
+
if (listenerMap.size === 0 && !onHandler) {
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
const ordered = [];
|
|
1761
|
+
for (const descriptor of listenerMap.values()) {
|
|
1762
|
+
ordered.push({
|
|
1763
|
+
order: descriptor.order,
|
|
1764
|
+
listener: descriptor.listener,
|
|
1765
|
+
once: descriptor.once
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
if (onHandler) {
|
|
1769
|
+
ordered.push({
|
|
1770
|
+
order: this.getOnHandlerOrder(type),
|
|
1771
|
+
listener: onHandler,
|
|
1772
|
+
once: false
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
ordered.sort((a, b) => a.order - b.order);
|
|
1776
|
+
for (const entry of ordered) {
|
|
1777
|
+
if (entry.once) {
|
|
1778
|
+
this.removeEventListener(type, entry.listener);
|
|
1779
|
+
}
|
|
1780
|
+
this.invokeListener(entry.listener, event);
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
dispatchOpenEvent() {
|
|
1784
|
+
const event = this.createBaseEvent("open");
|
|
1785
|
+
this.dispatchEvent("open", event);
|
|
1786
|
+
if (!this._closeEventDispatched && this._pendingMessages.length > 0) {
|
|
1787
|
+
const pending = this._pendingMessages;
|
|
1788
|
+
this._pendingMessages = [];
|
|
1789
|
+
for (const data of pending) {
|
|
1790
|
+
this.dispatchMessageEvent(this.toMessageEventData(data));
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
dispatchMessageEvent(data) {
|
|
1795
|
+
const event = {
|
|
1796
|
+
...this.createBaseEvent("message"),
|
|
1797
|
+
data
|
|
1798
|
+
};
|
|
1799
|
+
this.dispatchEvent("message", event);
|
|
1800
|
+
}
|
|
1801
|
+
dispatchCloseEvent(event) {
|
|
1802
|
+
this.dispatchEvent("close", event);
|
|
1803
|
+
}
|
|
1804
|
+
dispatchErrorEvent(message) {
|
|
1805
|
+
const event = {
|
|
1806
|
+
...this.createBaseEvent("error"),
|
|
1807
|
+
...message !== void 0 && { message }
|
|
1808
|
+
};
|
|
1809
|
+
this.dispatchEvent("error", event);
|
|
1810
|
+
}
|
|
1811
|
+
handleNativeMessage(data) {
|
|
1812
|
+
if (this._closeEventDispatched) {
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
this._legacyCallbacks?.onMessage?.(data);
|
|
1816
|
+
if (!this._openEventDispatched && this.readyState === _WebSocket.OPEN) {
|
|
1817
|
+
this._pendingMessages.push(data);
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
this.dispatchMessageEvent(this.toMessageEventData(data));
|
|
1821
|
+
}
|
|
1822
|
+
handleNativeError(message) {
|
|
1823
|
+
this._legacyCallbacks?.onError?.(message);
|
|
1824
|
+
this.dispatchErrorEvent(message);
|
|
1825
|
+
}
|
|
1826
|
+
handleNativeClose(event) {
|
|
1827
|
+
const wasClean = this.readyState === _WebSocket.CLOSING || event.code === 1e3;
|
|
1828
|
+
this.finalizeClosed(event, wasClean);
|
|
1829
|
+
}
|
|
1830
|
+
finalizeClosed(event, wasClean) {
|
|
1831
|
+
if (this._closeEventDispatched) {
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
this.readyState = _WebSocket.CLOSED;
|
|
1835
|
+
this._closeEventDispatched = true;
|
|
1836
|
+
this._pendingMessages = [];
|
|
1837
|
+
this.releaseConnectionTracking();
|
|
1838
|
+
const closeEvent = {
|
|
1839
|
+
...this.createBaseEvent("close"),
|
|
1840
|
+
code: event.code,
|
|
1841
|
+
reason: event.reason,
|
|
1842
|
+
wasClean
|
|
1843
|
+
};
|
|
1844
|
+
this._legacyCallbacks?.onClose?.(closeEvent);
|
|
1845
|
+
this.dispatchCloseEvent(closeEvent);
|
|
1846
|
+
}
|
|
1847
|
+
startNativeClose() {
|
|
1848
|
+
if (this._nativeCloseStarted || !this._connection) {
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
this._nativeCloseStarted = true;
|
|
1852
|
+
const connection = this._connection;
|
|
1853
|
+
const closeOptions = this._closeOptions;
|
|
1854
|
+
void nativeBinding.websocketClose(connection, closeOptions).catch((error) => {
|
|
1855
|
+
this.handleNativeError(String(error));
|
|
1856
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
addEventListener(type, listener, options) {
|
|
1860
|
+
if (!listener || !isWebSocketListenerType(type)) {
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1863
|
+
const normalizedListener = listener;
|
|
1864
|
+
if (typeof normalizedListener !== "function" && (typeof normalizedListener !== "object" || normalizedListener === null || typeof normalizedListener.handleEvent !== "function")) {
|
|
1865
|
+
return;
|
|
1866
|
+
}
|
|
1867
|
+
const listenerMap = this.getListenerMap(type);
|
|
1868
|
+
if (listenerMap.has(normalizedListener)) {
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const parsedOptions = typeof options === "boolean" ? {} : options ?? {};
|
|
1872
|
+
const once = parsedOptions.once === true;
|
|
1873
|
+
const signal = parsedOptions.signal;
|
|
1874
|
+
if (signal?.aborted) {
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
const descriptor = {
|
|
1878
|
+
listener: normalizedListener,
|
|
1879
|
+
order: ++this._listenerOrderCounter,
|
|
1880
|
+
once
|
|
1881
|
+
};
|
|
1882
|
+
if (signal) {
|
|
1883
|
+
const onAbort = () => {
|
|
1884
|
+
this.removeEventListener(type, normalizedListener);
|
|
1885
|
+
};
|
|
1886
|
+
descriptor.abortSignal = signal;
|
|
1887
|
+
descriptor.abortHandler = onAbort;
|
|
1888
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1889
|
+
}
|
|
1890
|
+
listenerMap.set(normalizedListener, descriptor);
|
|
1891
|
+
}
|
|
1892
|
+
removeEventListener(type, listener) {
|
|
1893
|
+
if (!listener || !isWebSocketListenerType(type)) {
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
const normalizedListener = listener;
|
|
1897
|
+
if (typeof normalizedListener !== "function" && typeof normalizedListener !== "object") {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
const listenerMap = this.getListenerMap(type);
|
|
1901
|
+
const descriptor = listenerMap.get(normalizedListener);
|
|
1902
|
+
if (!descriptor) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
if (descriptor.abortSignal && descriptor.abortHandler) {
|
|
1906
|
+
descriptor.abortSignal.removeEventListener("abort", descriptor.abortHandler);
|
|
1907
|
+
}
|
|
1908
|
+
listenerMap.delete(normalizedListener);
|
|
1909
|
+
}
|
|
1910
|
+
getSendByteLength(data) {
|
|
1911
|
+
if (typeof data === "string") {
|
|
1912
|
+
return Buffer.byteLength(data);
|
|
1913
|
+
}
|
|
1914
|
+
if (Buffer.isBuffer(data)) {
|
|
1915
|
+
return data.byteLength;
|
|
1916
|
+
}
|
|
1917
|
+
if (data instanceof ArrayBuffer) {
|
|
1918
|
+
return data.byteLength;
|
|
1919
|
+
}
|
|
1920
|
+
if (ArrayBuffer.isView(data)) {
|
|
1921
|
+
return data.byteLength;
|
|
1922
|
+
}
|
|
1923
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
1924
|
+
return data.size;
|
|
1925
|
+
}
|
|
1926
|
+
throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
|
|
1927
|
+
}
|
|
1928
|
+
async normalizeSendPayload(data) {
|
|
1929
|
+
if (typeof data === "string") {
|
|
1930
|
+
return data;
|
|
1931
|
+
}
|
|
1932
|
+
if (Buffer.isBuffer(data)) {
|
|
1933
|
+
return data;
|
|
1934
|
+
}
|
|
1935
|
+
if (data instanceof ArrayBuffer) {
|
|
1936
|
+
return Buffer.from(data);
|
|
1937
|
+
}
|
|
1938
|
+
if (ArrayBuffer.isView(data)) {
|
|
1939
|
+
return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
1940
|
+
}
|
|
1941
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
1942
|
+
return Buffer.from(await data.arrayBuffer());
|
|
1943
|
+
}
|
|
1944
|
+
throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
|
|
1945
|
+
}
|
|
1946
|
+
send(data) {
|
|
1947
|
+
if (this.readyState !== _WebSocket.OPEN || !this._connection) {
|
|
1948
|
+
throw new RequestError("WebSocket is not open");
|
|
1949
|
+
}
|
|
1950
|
+
const queuedBytes = this.getSendByteLength(data);
|
|
1951
|
+
const connection = this._connection;
|
|
1952
|
+
this._bufferedAmount += queuedBytes;
|
|
1953
|
+
const sendTask = async () => {
|
|
1954
|
+
try {
|
|
1955
|
+
const payload = await this.normalizeSendPayload(data);
|
|
1956
|
+
await nativeBinding.websocketSend(connection, payload);
|
|
1957
|
+
} catch (error) {
|
|
1958
|
+
this.handleNativeError(String(error));
|
|
1959
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1960
|
+
} finally {
|
|
1961
|
+
this._bufferedAmount = Math.max(0, this._bufferedAmount - queuedBytes);
|
|
1962
|
+
}
|
|
1963
|
+
};
|
|
1964
|
+
this._sendChain = this._sendChain.then(sendTask, sendTask);
|
|
1965
|
+
}
|
|
1966
|
+
close(code, reason) {
|
|
1967
|
+
if (this.readyState === _WebSocket.CLOSING || this.readyState === _WebSocket.CLOSED) {
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
this._closeOptions = normalizeWebSocketCloseOptions(code, reason);
|
|
1971
|
+
this.readyState = _WebSocket.CLOSING;
|
|
1972
|
+
this.startNativeClose();
|
|
1973
|
+
}
|
|
1215
1974
|
};
|
|
1216
|
-
|
|
1217
|
-
if (!
|
|
1218
|
-
|
|
1975
|
+
function isInternalWebSocketInit(value) {
|
|
1976
|
+
if (!isPlainObject(value)) {
|
|
1977
|
+
return false;
|
|
1219
1978
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1979
|
+
const candidate = value;
|
|
1980
|
+
return candidate._internal === true && typeof candidate.url === "string" && typeof candidate.connect === "function";
|
|
1981
|
+
}
|
|
1982
|
+
function normalizeStandaloneWebSocketArgs(urlOrOptions, options) {
|
|
1983
|
+
if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
|
|
1984
|
+
const normalizedOptions2 = normalizeStandaloneWebSocketOptions(options);
|
|
1985
|
+
return {
|
|
1986
|
+
url: normalizeWebSocketUrl(urlOrOptions),
|
|
1987
|
+
options: normalizedOptions2,
|
|
1988
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(options)
|
|
1989
|
+
};
|
|
1222
1990
|
}
|
|
1223
|
-
|
|
1224
|
-
const
|
|
1991
|
+
const legacy = urlOrOptions;
|
|
1992
|
+
const normalizedOptions = normalizeStandaloneWebSocketOptions(legacy);
|
|
1993
|
+
return {
|
|
1994
|
+
url: normalizeWebSocketUrl(legacy.url),
|
|
1995
|
+
options: normalizedOptions,
|
|
1996
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
function normalizeSessionWebSocketArgs(urlOrOptions, options) {
|
|
2000
|
+
if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
|
|
2001
|
+
const normalizedOptions2 = normalizeSessionWebSocketOptions(options);
|
|
2002
|
+
return {
|
|
2003
|
+
url: normalizeWebSocketUrl(urlOrOptions),
|
|
2004
|
+
options: normalizedOptions2,
|
|
2005
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(options)
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
const legacy = urlOrOptions;
|
|
2009
|
+
const normalizedOptions = normalizeSessionWebSocketOptions(legacy);
|
|
2010
|
+
return {
|
|
2011
|
+
url: normalizeWebSocketUrl(legacy.url),
|
|
2012
|
+
options: normalizedOptions,
|
|
2013
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
async function websocket(urlOrOptions, options) {
|
|
2017
|
+
const normalized = normalizeStandaloneWebSocketArgs(urlOrOptions, options);
|
|
2018
|
+
validateWebSocketProtocols(normalized.options.protocols);
|
|
2019
|
+
assertNoManualWebSocketProtocolHeader(normalized.options.headers);
|
|
2020
|
+
validateBrowserProfile(normalized.options.browser);
|
|
2021
|
+
const os = normalized.options.os ?? DEFAULT_OS;
|
|
1225
2022
|
validateOperatingSystem(os);
|
|
1226
|
-
const browser = options.browser ?? DEFAULT_BROWSER;
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
2023
|
+
const browser = normalized.options.browser ?? DEFAULT_BROWSER;
|
|
2024
|
+
const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
|
|
2025
|
+
return WebSocket._connectWithInit({
|
|
2026
|
+
_internal: true,
|
|
2027
|
+
url: normalized.url,
|
|
2028
|
+
options: normalized.options,
|
|
2029
|
+
openDispatchMode: "deferred",
|
|
2030
|
+
connect: (callbacks) => nativeBinding.websocketConnect({
|
|
2031
|
+
url: normalized.url,
|
|
1230
2032
|
browser,
|
|
1231
2033
|
os,
|
|
1232
|
-
headers: options.headers ?? {},
|
|
1233
|
-
...
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
}
|
|
2034
|
+
headers: headersToTuples(normalized.options.headers ?? {}),
|
|
2035
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
2036
|
+
...normalized.options.proxy !== void 0 && { proxy: normalized.options.proxy },
|
|
2037
|
+
onMessage: callbacks.onMessage,
|
|
2038
|
+
onClose: callbacks.onClose,
|
|
2039
|
+
onError: callbacks.onError
|
|
2040
|
+
}),
|
|
2041
|
+
legacyCallbacks: normalized.legacyCallbacks
|
|
2042
|
+
});
|
|
1242
2043
|
}
|
|
1243
2044
|
var wreq_js_default = {
|
|
1244
2045
|
fetch,
|
|
@@ -1255,7 +2056,8 @@ var wreq_js_default = {
|
|
|
1255
2056
|
Headers,
|
|
1256
2057
|
Response,
|
|
1257
2058
|
Transport,
|
|
1258
|
-
Session
|
|
2059
|
+
Session,
|
|
2060
|
+
RequestError
|
|
1259
2061
|
};
|
|
1260
2062
|
export {
|
|
1261
2063
|
Headers,
|