snapreq 0.0.3 → 0.0.5
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 +12 -0
- package/{types → build}/capabilities.d.ts +1 -0
- package/build/capabilities.d.ts.map +1 -0
- package/{src → build}/capabilities.js +11 -12
- package/{types → build}/errors.d.ts +18 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +82 -0
- package/{types → build}/headers.d.ts +1 -0
- package/build/headers.d.ts.map +1 -0
- package/build/headers.js +89 -0
- package/{types → build}/request.d.ts +1 -0
- package/build/request.d.ts.map +1 -0
- package/build/request.js +89 -0
- package/{types → build}/response.d.ts +21 -1
- package/build/response.d.ts.map +1 -0
- package/build/response.js +171 -0
- package/{types → build}/retry.d.ts +1 -0
- package/build/retry.d.ts.map +1 -0
- package/build/retry.js +95 -0
- package/{types → build}/snap-req.d.ts +72 -1
- package/build/snap-req.d.ts.map +1 -0
- package/build/snap-req.js +349 -0
- package/{types → build}/transports/fetch-transport.d.ts +1 -0
- package/build/transports/fetch-transport.d.ts.map +1 -0
- package/build/transports/fetch-transport.js +116 -0
- package/build/transports/fetch.d.ts +2 -0
- package/build/transports/fetch.d.ts.map +1 -0
- package/build/transports/fetch.js +3 -0
- package/{types → build}/transports/node-transport.d.ts +1 -0
- package/build/transports/node-transport.d.ts.map +1 -0
- package/build/transports/node-transport.js +287 -0
- package/build/transports/proxy-bounce-transport.d.ts +27 -0
- package/build/transports/proxy-bounce-transport.d.ts.map +1 -0
- package/build/transports/proxy-bounce-transport.js +116 -0
- package/{types → build}/transports/select.d.ts +1 -0
- package/build/transports/select.d.ts.map +1 -0
- package/build/transports/select.js +69 -0
- package/{types → build}/transports/xhr-transport.d.ts +1 -0
- package/build/transports/xhr-transport.d.ts.map +1 -0
- package/build/transports/xhr-transport.js +93 -0
- package/build/transports/xhr.d.ts +2 -0
- package/build/transports/xhr.d.ts.map +1 -0
- package/build/transports/xhr.js +3 -0
- package/{types → build}/websocket/websocket-channel.d.ts +1 -0
- package/build/websocket/websocket-channel.d.ts.map +1 -0
- package/build/websocket/websocket-channel.js +162 -0
- package/{types → build}/websocket/websocket-client.d.ts +1 -0
- package/build/websocket/websocket-client.d.ts.map +1 -0
- package/build/websocket/websocket-client.js +920 -0
- package/{types → build}/websocket/websocket-connection.d.ts +1 -0
- package/build/websocket/websocket-connection.d.ts.map +1 -0
- package/build/websocket/websocket-connection.js +148 -0
- package/build/websocket.d.ts +3 -0
- package/build/websocket.d.ts.map +1 -0
- package/build/websocket.js +4 -0
- package/package.json +20 -23
- package/src/errors.js +0 -69
- package/src/headers.js +0 -92
- package/src/request.js +0 -104
- package/src/response.js +0 -156
- package/src/retry.js +0 -105
- package/src/snap-req.js +0 -248
- package/src/transports/fetch-transport.js +0 -128
- package/src/transports/node-transport.js +0 -323
- package/src/transports/select.js +0 -73
- package/src/transports/xhr-transport.js +0 -112
- package/src/websocket/websocket-channel.js +0 -176
- package/src/websocket/websocket-client.js +0 -1034
- package/src/websocket/websocket-connection.js +0 -154
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { buildCapabilities } from "../capabilities.js";
|
|
3
|
+
import { SnapReqAbortError, SnapReqUnsupportedFeatureError } from "../errors.js";
|
|
4
|
+
import SnapReqHeaders from "../headers.js";
|
|
5
|
+
import SnapReqResponse from "../response.js";
|
|
6
|
+
/**
|
|
7
|
+
* Transport backed by the `fetch` global. Works on web, Expo / React Native and
|
|
8
|
+
* Node 18+. It cannot open Unix sockets, present client certificates or
|
|
9
|
+
* compress request bodies — those raise `SnapReqUnsupportedFeatureError`.
|
|
10
|
+
* Response streaming uses `response.body` where available and otherwise buffers
|
|
11
|
+
* the body once, keeping the same stream interface everywhere.
|
|
12
|
+
*/
|
|
13
|
+
export default class FetchTransport {
|
|
14
|
+
/** @returns {string} - Transport name. */
|
|
15
|
+
static get transportName() {
|
|
16
|
+
return "fetch";
|
|
17
|
+
}
|
|
18
|
+
/** @returns {boolean} - Whether this transport can run in the current environment. */
|
|
19
|
+
static isAvailable() {
|
|
20
|
+
return typeof fetch === "function";
|
|
21
|
+
}
|
|
22
|
+
/** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
|
|
23
|
+
get capabilities() {
|
|
24
|
+
return buildCapabilities({
|
|
25
|
+
responseStreaming: true,
|
|
26
|
+
abort: true
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
|
|
31
|
+
* @returns {Promise<SnapReqResponse>} - The response.
|
|
32
|
+
*/
|
|
33
|
+
async performRequest(request) {
|
|
34
|
+
if (request.bodyCompression && request.bodyCompression !== "identity") {
|
|
35
|
+
throw new SnapReqUnsupportedFeatureError({ feature: "request body compression", transport: "fetch" });
|
|
36
|
+
}
|
|
37
|
+
/** @type {Record<string, any>} */
|
|
38
|
+
const init = {
|
|
39
|
+
method: request.method,
|
|
40
|
+
headers: request.headers.toObject()
|
|
41
|
+
};
|
|
42
|
+
if (request.signal)
|
|
43
|
+
init.signal = request.signal;
|
|
44
|
+
if (request.credentials)
|
|
45
|
+
init.credentials = request.credentials;
|
|
46
|
+
const body = request.body;
|
|
47
|
+
if (body.kind === "text") {
|
|
48
|
+
init.body = body.value;
|
|
49
|
+
}
|
|
50
|
+
else if (body.kind === "bytes") {
|
|
51
|
+
init.body = body.value;
|
|
52
|
+
}
|
|
53
|
+
else if (body.kind === "stream") {
|
|
54
|
+
throw new SnapReqUnsupportedFeatureError({ feature: "streamed request bodies", transport: "fetch" });
|
|
55
|
+
}
|
|
56
|
+
/** @type {Response} */
|
|
57
|
+
let fetchResponse;
|
|
58
|
+
try {
|
|
59
|
+
fetchResponse = await fetch(request.url, init);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof Error && error.name === "AbortError")
|
|
63
|
+
throw new SnapReqAbortError();
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
return new SnapReqResponse({
|
|
67
|
+
url: request.url,
|
|
68
|
+
method: request.method,
|
|
69
|
+
status: fetchResponse.status,
|
|
70
|
+
statusText: fetchResponse.statusText,
|
|
71
|
+
headers: this._responseHeaders(fetchResponse),
|
|
72
|
+
stream: this._responseStream(fetchResponse)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @param {Response} response - The fetch response.
|
|
77
|
+
* @returns {SnapReqHeaders} - The response headers.
|
|
78
|
+
*/
|
|
79
|
+
_responseHeaders(response) {
|
|
80
|
+
const headers = new SnapReqHeaders();
|
|
81
|
+
response.headers.forEach((value, name) => headers.set(name, value));
|
|
82
|
+
return headers;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Builds an async iterable of byte chunks over a fetch response. Uses the
|
|
86
|
+
* `ReadableStream` body for true streaming when present and otherwise buffers
|
|
87
|
+
* the whole body once so the stream interface stays identical everywhere.
|
|
88
|
+
* @param {Response} response - The fetch response.
|
|
89
|
+
* @returns {AsyncIterable<Uint8Array>} - The response body stream.
|
|
90
|
+
*/
|
|
91
|
+
_responseStream(response) {
|
|
92
|
+
const body = response.body;
|
|
93
|
+
if (body && typeof body.getReader === "function") {
|
|
94
|
+
return (async function* () {
|
|
95
|
+
const reader = body.getReader();
|
|
96
|
+
try {
|
|
97
|
+
while (true) {
|
|
98
|
+
const { done, value } = await reader.read();
|
|
99
|
+
if (done)
|
|
100
|
+
break;
|
|
101
|
+
if (value)
|
|
102
|
+
yield value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
reader.releaseLock?.();
|
|
107
|
+
}
|
|
108
|
+
})();
|
|
109
|
+
}
|
|
110
|
+
return (async function* () {
|
|
111
|
+
const buffer = await response.arrayBuffer();
|
|
112
|
+
yield new Uint8Array(buffer);
|
|
113
|
+
})();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2gtdHJhbnNwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zcG9ydHMvZmV0Y2gtdHJhbnNwb3J0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsOEJBQThCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDOUUsT0FBTyxjQUFjLE1BQU0sZUFBZSxDQUFBO0FBQzFDLE9BQU8sZUFBZSxNQUFNLGdCQUFnQixDQUFBO0FBRTVDOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sY0FBYztJQUNqQywwQ0FBMEM7SUFDMUMsTUFBTSxLQUFLLGFBQWE7UUFDdEIsT0FBTyxPQUFPLENBQUE7SUFDaEIsQ0FBQztJQUVELHNGQUFzRjtJQUN0RixNQUFNLENBQUMsV0FBVztRQUNoQixPQUFPLE9BQU8sS0FBSyxLQUFLLFVBQVUsQ0FBQTtJQUNwQyxDQUFDO0lBRUQsOEZBQThGO0lBQzlGLElBQUksWUFBWTtRQUNkLE9BQU8saUJBQWlCLENBQUM7WUFDdkIsaUJBQWlCLEVBQUUsSUFBSTtZQUN2QixLQUFLLEVBQUUsSUFBSTtTQUNaLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQU87UUFDMUIsSUFBSSxPQUFPLENBQUMsZUFBZSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDdEUsTUFBTSxJQUFJLDhCQUE4QixDQUFDLEVBQUMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFBO1FBQ3JHLENBQUM7UUFFRCxrQ0FBa0M7UUFDbEMsTUFBTSxJQUFJLEdBQUc7WUFDWCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDdEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFO1NBQ3BDLENBQUE7UUFFRCxJQUFJLE9BQU8sQ0FBQyxNQUFNO1lBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFBO1FBQ2hELElBQUksT0FBTyxDQUFDLFdBQVc7WUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUE7UUFFL0QsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQTtRQUV6QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1FBQ3hCLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1FBQ3hCLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLDhCQUE4QixDQUFDLEVBQUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFBO1FBQ3BHLENBQUM7UUFFRCx1QkFBdUI7UUFDdkIsSUFBSSxhQUFhLENBQUE7UUFFakIsSUFBSSxDQUFDO1lBQ0gsYUFBYSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFDaEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZO2dCQUFFLE1BQU0sSUFBSSxpQkFBaUIsRUFBRSxDQUFBO1lBRXhGLE1BQU0sS0FBSyxDQUFBO1FBQ2IsQ0FBQztRQUVELE9BQU8sSUFBSSxlQUFlLENBQUM7WUFDekIsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO1lBQ2hCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtZQUN0QixNQUFNLEVBQUUsYUFBYSxDQUFDLE1BQU07WUFDNUIsVUFBVSxFQUFFLGFBQWEsQ0FBQyxVQUFVO1lBQ3BDLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDO1lBQzdDLE1BQU0sRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQztTQUM1QyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZ0JBQWdCLENBQUMsUUFBUTtRQUN2QixNQUFNLE9BQU8sR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFBO1FBRXBDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQTtRQUVuRSxPQUFPLE9BQU8sQ0FBQTtJQUNoQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsZUFBZSxDQUFDLFFBQVE7UUFDdEIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQTtRQUUxQixJQUFJLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxTQUFTLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDakQsT0FBTyxDQUFDLEtBQUssU0FBUyxDQUFDO2dCQUNyQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUE7Z0JBRS9CLElBQUksQ0FBQztvQkFDSCxPQUFPLElBQUksRUFBRSxDQUFDO3dCQUNaLE1BQU0sRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7d0JBRXpDLElBQUksSUFBSTs0QkFBRSxNQUFLO3dCQUNmLElBQUksS0FBSzs0QkFBRSxNQUFNLEtBQUssWUFBWSxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUE7b0JBQzlFLENBQUM7Z0JBQ0gsQ0FBQzt3QkFBUyxDQUFDO29CQUNULE1BQU0sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFBO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUNOLENBQUM7UUFFRCxPQUFPLENBQUMsS0FBSyxTQUFTLENBQUM7WUFDckIsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUE7WUFFM0MsTUFBTSxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUM5QixDQUFDLENBQUMsRUFBRSxDQUFBO0lBQ04sQ0FBQztDQUNGIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/transports/fetch.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
export { default } from "./fetch-transport.js";
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhbnNwb3J0cy9mZXRjaC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLHNCQUFzQixDQUFBIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-transport.d.ts","sourceRoot":"","sources":["../../src/transports/node-transport.js"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH;IACE,0CAA0C;IAC1C,4BADc,MAAM,CAGnB;IAED,sFAAsF;IACtF,sBADc,OAAO,CAGpB;IAED;;;;;OAKG;IACH,6CAJG;QAAwB,UAAU,GAA1B,MAAM;QACuG,GAAG,GAAhH;YAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;SAAC;QAClF,SAAS,GAA1B,OAAO;KACjB,EAWA;IATC,mBAA4B;IAC5B;aALe,MAAM,GAAG,MAAM;eAAS,MAAM,GAAG,MAAM;cAAQ,MAAM,GAAG,MAAM;6BAAuB,OAAO;MAK7F;IACd,mBAA0B;IAC1B,qEAAqE;IACrE,UADW;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAC,GAAG,IAAI,CAC7C;IACpB,kBAAkB;IAClB,YADW,GAAG,CACQ;IACtB,kBAAkB;IAClB,aADW,GAAG,CACS;IAGzB,8FAA8F;IAC9F,oBADc,OAAO,oBAAoB,EAAE,qBAAqB,CAW/D;IAED,wGAAwG;IACxG,SADc,OAAO,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAC,CAAC,CAcrE;IAED;;;OAGG;IACH,eAHW,OAAO,GACL,GAAG,CAoBf;IAED;;;;;OAKG;IACH,wBAHW,OAAO,gBAAgB,EAAE,iBAAiB,GACxC,OAAO,CAAC,eAAe,CAAC,CA2FpC;IAED;;;;;OAKG;IACH,6BALW,OAAO,gBAAgB,EAAE,iBAAiB,WAC1C,cAAc,oBACd;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAC,GACtB;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,OAAO,aAAa,EAAE,QAAQ,GAAG,IAAI,CAAA;KAAC,CA8ClF;IAED;;;;OAIG;IACH,6BAJW,MAAM,QACN,GAAG,GACD,OAAO,aAAa,EAAE,SAAS,CAS3C;IAED;;;;OAIG;IACH,gCAJW,OAAO,WAAW,EAAE,eAAe,QACnC,GAAG,GACD,OAAO,aAAa,EAAE,QAAQ,CAkB1C;IAED;;;;OAIG;IACH,2BAJW,MAAM,QACN,GAAG,GACD,OAAO,aAAa,EAAE,SAAS,CAS3C;IAED;;;OAGG;IACH,2BAHW,OAAO,WAAW,EAAE,eAAe,GACjC,cAAc,CAY1B;IAED;;;OAGG;IACH,SAFa,IAAI,CAOhB;CACF;4BA7T2B,gBAAgB;2BADjB,eAAe"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { buildCapabilities } from "../capabilities.js";
|
|
3
|
+
import { SnapReqAbortError, SnapReqUnsupportedFeatureError } from "../errors.js";
|
|
4
|
+
import SnapReqHeaders from "../headers.js";
|
|
5
|
+
import SnapReqResponse from "../response.js";
|
|
6
|
+
/**
|
|
7
|
+
* Full-featured transport backed by Node's `http`/`https` modules. Supports
|
|
8
|
+
* Unix sockets, client TLS, keep-alive, request-body compression, response
|
|
9
|
+
* decompression and streaming. The `node:*` modules are loaded with a dynamic
|
|
10
|
+
* `import()` so this file never has to be bundled by web/Expo bundlers — the
|
|
11
|
+
* transport selector only imports it when running on Node.
|
|
12
|
+
*/
|
|
13
|
+
export default class NodeTransport {
|
|
14
|
+
/** @returns {string} - Transport name. */
|
|
15
|
+
static get transportName() {
|
|
16
|
+
return "node";
|
|
17
|
+
}
|
|
18
|
+
/** @returns {boolean} - Whether this transport can run in the current environment. */
|
|
19
|
+
static isAvailable() {
|
|
20
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @param {object} [config] - Transport configuration.
|
|
24
|
+
* @param {string} [config.socketPath] - Unix domain socket path.
|
|
25
|
+
* @param {{ca?: string | Buffer, cert?: string | Buffer, key?: string | Buffer, rejectUnauthorized?: boolean}} [config.tls] - TLS material for HTTPS connections.
|
|
26
|
+
* @param {boolean} [config.keepAlive] - Reuse connections across requests. Defaults to true.
|
|
27
|
+
*/
|
|
28
|
+
constructor({ socketPath, tls, keepAlive = true } = {}) {
|
|
29
|
+
this.socketPath = socketPath;
|
|
30
|
+
this.tls = tls;
|
|
31
|
+
this.keepAlive = keepAlive;
|
|
32
|
+
/** @type {{http: any, https: any, zlib: any, stream: any} | null} */
|
|
33
|
+
this._modules = null;
|
|
34
|
+
/** @type {any} */
|
|
35
|
+
this._httpAgent = null;
|
|
36
|
+
/** @type {any} */
|
|
37
|
+
this._httpsAgent = null;
|
|
38
|
+
}
|
|
39
|
+
/** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
|
|
40
|
+
get capabilities() {
|
|
41
|
+
return buildCapabilities({
|
|
42
|
+
unixSocket: true,
|
|
43
|
+
tlsClientCert: true,
|
|
44
|
+
requestCompression: true,
|
|
45
|
+
responseStreaming: true,
|
|
46
|
+
requestStreaming: true,
|
|
47
|
+
keepAlive: true,
|
|
48
|
+
abort: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** @returns {Promise<{http: any, https: any, zlib: any, stream: any}>} - Lazily-loaded Node modules. */
|
|
52
|
+
async _load() {
|
|
53
|
+
if (!this._modules) {
|
|
54
|
+
const [http, https, zlib, stream] = await Promise.all([
|
|
55
|
+
import("node:http"),
|
|
56
|
+
import("node:https"),
|
|
57
|
+
import("node:zlib"),
|
|
58
|
+
import("node:stream")
|
|
59
|
+
]);
|
|
60
|
+
this._modules = { http, https, zlib, stream };
|
|
61
|
+
}
|
|
62
|
+
return this._modules;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* @param {boolean} useTls - Whether the request uses TLS.
|
|
66
|
+
* @returns {any} - The keep-alive agent for the protocol.
|
|
67
|
+
*/
|
|
68
|
+
_agent(useTls) {
|
|
69
|
+
const { http, https } = /** @type {{http: any, https: any}} */ (this._modules);
|
|
70
|
+
if (useTls) {
|
|
71
|
+
this._httpsAgent || (this._httpsAgent = new https.Agent({
|
|
72
|
+
keepAlive: this.keepAlive,
|
|
73
|
+
...(this.tls?.ca !== undefined ? { ca: this.tls.ca } : {}),
|
|
74
|
+
...(this.tls?.cert !== undefined ? { cert: this.tls.cert } : {}),
|
|
75
|
+
...(this.tls?.key !== undefined ? { key: this.tls.key } : {}),
|
|
76
|
+
...(this.tls?.rejectUnauthorized !== undefined ? { rejectUnauthorized: this.tls.rejectUnauthorized } : {})
|
|
77
|
+
}));
|
|
78
|
+
return this._httpsAgent;
|
|
79
|
+
}
|
|
80
|
+
this._httpAgent || (this._httpAgent = new http.Agent({ keepAlive: this.keepAlive }));
|
|
81
|
+
return this._httpAgent;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Performs a single request and resolves once the response headers arrive,
|
|
85
|
+
* exposing the (decoded) body as a stream so callers can buffer or stream it.
|
|
86
|
+
* @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
|
|
87
|
+
* @returns {Promise<SnapReqResponse>} - The response.
|
|
88
|
+
*/
|
|
89
|
+
async performRequest(request) {
|
|
90
|
+
const modules = await this._load();
|
|
91
|
+
const { zlib, stream } = modules;
|
|
92
|
+
const parsedUrl = new URL(request.url);
|
|
93
|
+
const useTls = Boolean(this.tls) || parsedUrl.protocol === "https:";
|
|
94
|
+
const httpModule = useTls ? modules.https : modules.http;
|
|
95
|
+
const headers = new SnapReqHeaders(request.headers);
|
|
96
|
+
const requestBody = this._prepareRequestBody(request, headers, { zlib, stream });
|
|
97
|
+
/** @type {Record<string, any>} */
|
|
98
|
+
const requestOptions = {
|
|
99
|
+
method: request.method,
|
|
100
|
+
path: `${parsedUrl.pathname}${parsedUrl.search}`,
|
|
101
|
+
headers: headers.toObject(),
|
|
102
|
+
agent: this._agent(useTls)
|
|
103
|
+
};
|
|
104
|
+
if (this.socketPath) {
|
|
105
|
+
requestOptions.socketPath = this.socketPath;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
requestOptions.hostname = parsedUrl.hostname;
|
|
109
|
+
requestOptions.port = parsedUrl.port || (useTls ? 443 : 80);
|
|
110
|
+
}
|
|
111
|
+
return await new Promise((resolve, reject) => {
|
|
112
|
+
if (request.signal?.aborted) {
|
|
113
|
+
reject(new SnapReqAbortError());
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
let settled = false;
|
|
117
|
+
const abort = () => req.destroy(new SnapReqAbortError());
|
|
118
|
+
const removeAbortListener = () => request.signal?.removeEventListener("abort", abort);
|
|
119
|
+
const req = httpModule.request(requestOptions, (res) => {
|
|
120
|
+
/** @type {import("node:stream").Readable} */
|
|
121
|
+
let responseStream;
|
|
122
|
+
try {
|
|
123
|
+
responseStream = this._decodeResponseStream(res, zlib);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (!settled) {
|
|
127
|
+
settled = true;
|
|
128
|
+
removeAbortListener();
|
|
129
|
+
reject(error);
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Re-point the abort listener at the response stream so aborting after
|
|
134
|
+
// headers arrive tears down the body stream rather than the request.
|
|
135
|
+
removeAbortListener();
|
|
136
|
+
const abortStream = () => responseStream.destroy(new SnapReqAbortError());
|
|
137
|
+
request.signal?.addEventListener("abort", abortStream, { once: true });
|
|
138
|
+
responseStream.on("close", () => request.signal?.removeEventListener("abort", abortStream));
|
|
139
|
+
settled = true;
|
|
140
|
+
resolve(new SnapReqResponse({
|
|
141
|
+
url: request.url,
|
|
142
|
+
method: request.method,
|
|
143
|
+
status: res.statusCode,
|
|
144
|
+
statusText: res.statusMessage || "",
|
|
145
|
+
headers: this._responseHeaders(res),
|
|
146
|
+
stream: responseStream,
|
|
147
|
+
nodeStream: responseStream
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
request.signal?.addEventListener("abort", abort, { once: true });
|
|
151
|
+
req.on("error", (/** @type {unknown} */ error) => {
|
|
152
|
+
removeAbortListener();
|
|
153
|
+
if (!settled) {
|
|
154
|
+
settled = true;
|
|
155
|
+
reject(error);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (requestBody.stream) {
|
|
159
|
+
requestBody.stream.pipe(req);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
if (requestBody.buffer)
|
|
163
|
+
req.write(requestBody.buffer);
|
|
164
|
+
req.end();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
|
|
170
|
+
* @param {SnapReqHeaders} headers - Headers, mutated with Content-Length / Content-Encoding.
|
|
171
|
+
* @param {{zlib: any, stream: any}} modules - Node modules.
|
|
172
|
+
* @returns {{buffer: Buffer | null, stream: import("node:stream").Readable | null}} - Prepared body.
|
|
173
|
+
*/
|
|
174
|
+
_prepareRequestBody(request, headers, { zlib, stream }) {
|
|
175
|
+
const compression = request.bodyCompression || "identity";
|
|
176
|
+
const body = request.body;
|
|
177
|
+
if (body.kind === "none")
|
|
178
|
+
return { buffer: null, stream: null };
|
|
179
|
+
/** @type {Buffer | null} */
|
|
180
|
+
let buffer = null;
|
|
181
|
+
/** @type {import("node:stream").Readable | null} */
|
|
182
|
+
let bodyStream = null;
|
|
183
|
+
if (body.kind === "stream") {
|
|
184
|
+
const value = /** @type {any} */ (body.value);
|
|
185
|
+
bodyStream = typeof value.pipe === "function" ? value : stream.Readable.from(value);
|
|
186
|
+
}
|
|
187
|
+
else if (body.kind === "bytes") {
|
|
188
|
+
buffer = Buffer.from(/** @type {Uint8Array} */ (body.value));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
buffer = Buffer.from(/** @type {string} */ (body.value));
|
|
192
|
+
}
|
|
193
|
+
if (compression === "identity") {
|
|
194
|
+
if (buffer)
|
|
195
|
+
headers.set("Content-Length", String(buffer.length));
|
|
196
|
+
return { buffer, stream: bodyStream };
|
|
197
|
+
}
|
|
198
|
+
if (headers.has("content-encoding")) {
|
|
199
|
+
throw new SnapReqUnsupportedFeatureError({
|
|
200
|
+
feature: "bodyCompression",
|
|
201
|
+
transport: "node",
|
|
202
|
+
detail: "cannot combine bodyCompression with an explicit Content-Encoding header"
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
headers.set("Content-Encoding", compression);
|
|
206
|
+
const compressor = this._requestCompressor(compression, zlib);
|
|
207
|
+
const source = bodyStream || stream.Readable.from(/** @type {Buffer} */ (buffer));
|
|
208
|
+
source.on("error", (/** @type {Error} */ error) => compressor.destroy(error));
|
|
209
|
+
source.pipe(compressor);
|
|
210
|
+
return { buffer: null, stream: compressor };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* @param {string} encoding - Compression encoding.
|
|
214
|
+
* @param {any} zlib - The zlib module.
|
|
215
|
+
* @returns {import("node:stream").Transform} - A compressor transform.
|
|
216
|
+
*/
|
|
217
|
+
_requestCompressor(encoding, zlib) {
|
|
218
|
+
if (encoding === "gzip")
|
|
219
|
+
return zlib.createGzip();
|
|
220
|
+
if (encoding === "deflate")
|
|
221
|
+
return zlib.createDeflate();
|
|
222
|
+
if (encoding === "br")
|
|
223
|
+
return zlib.createBrotliCompress();
|
|
224
|
+
if (encoding === "zstd" && typeof zlib.createZstdCompress === "function")
|
|
225
|
+
return zlib.createZstdCompress();
|
|
226
|
+
throw new SnapReqUnsupportedFeatureError({ feature: `bodyCompression "${encoding}"`, transport: "node" });
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* @param {import("node:http").IncomingMessage} response - The raw response.
|
|
230
|
+
* @param {any} zlib - The zlib module.
|
|
231
|
+
* @returns {import("node:stream").Readable} - The decoded response body stream.
|
|
232
|
+
*/
|
|
233
|
+
_decodeResponseStream(response, zlib) {
|
|
234
|
+
const header = response.headers["content-encoding"];
|
|
235
|
+
const headerValue = Array.isArray(header) ? header.join(",") : header;
|
|
236
|
+
const encodings = (headerValue || "")
|
|
237
|
+
.split(",")
|
|
238
|
+
.map((encoding) => encoding.trim().toLowerCase())
|
|
239
|
+
.filter((encoding) => encoding && encoding !== "identity");
|
|
240
|
+
/** @type {import("node:stream").Readable} */
|
|
241
|
+
let decoded = response;
|
|
242
|
+
for (let index = encodings.length - 1; index >= 0; index -= 1) {
|
|
243
|
+
decoded = decoded.pipe(this._responseDecoder(encodings[index], zlib));
|
|
244
|
+
}
|
|
245
|
+
return decoded;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* @param {string} encoding - Content encoding.
|
|
249
|
+
* @param {any} zlib - The zlib module.
|
|
250
|
+
* @returns {import("node:stream").Transform} - A decompressor transform.
|
|
251
|
+
*/
|
|
252
|
+
_responseDecoder(encoding, zlib) {
|
|
253
|
+
if (encoding === "gzip" || encoding === "x-gzip")
|
|
254
|
+
return zlib.createGunzip();
|
|
255
|
+
if (encoding === "deflate")
|
|
256
|
+
return zlib.createInflate();
|
|
257
|
+
if (encoding === "br")
|
|
258
|
+
return zlib.createBrotliDecompress();
|
|
259
|
+
if (encoding === "zstd" && typeof zlib.createZstdDecompress === "function")
|
|
260
|
+
return zlib.createZstdDecompress();
|
|
261
|
+
throw new SnapReqUnsupportedFeatureError({ feature: `response content-encoding "${encoding}"`, transport: "node" });
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* @param {import("node:http").IncomingMessage} response - The raw response.
|
|
265
|
+
* @returns {SnapReqHeaders} - The response headers.
|
|
266
|
+
*/
|
|
267
|
+
_responseHeaders(response) {
|
|
268
|
+
const headers = new SnapReqHeaders();
|
|
269
|
+
for (const [name, value] of Object.entries(response.headers)) {
|
|
270
|
+
if (value === undefined)
|
|
271
|
+
continue;
|
|
272
|
+
headers.set(name, Array.isArray(value) ? value.join(", ") : value);
|
|
273
|
+
}
|
|
274
|
+
return headers;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Destroys the keep-alive agents, closing all persistent connections.
|
|
278
|
+
* @returns {void}
|
|
279
|
+
*/
|
|
280
|
+
close() {
|
|
281
|
+
this._httpAgent?.destroy();
|
|
282
|
+
this._httpsAgent?.destroy();
|
|
283
|
+
this._httpAgent = null;
|
|
284
|
+
this._httpsAgent = null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS10cmFuc3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhbnNwb3J0cy9ub2RlLXRyYW5zcG9ydC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUE7QUFDcEQsT0FBTyxFQUFDLGlCQUFpQixFQUFFLDhCQUE4QixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQzlFLE9BQU8sY0FBYyxNQUFNLGVBQWUsQ0FBQTtBQUMxQyxPQUFPLGVBQWUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLGFBQWE7SUFDaEMsMENBQTBDO0lBQzFDLE1BQU0sS0FBSyxhQUFhO1FBQ3RCLE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQUVELHNGQUFzRjtJQUN0RixNQUFNLENBQUMsV0FBVztRQUNoQixPQUFPLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUMxRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxZQUFZLEVBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEdBQUcsSUFBSSxFQUFDLEdBQUcsRUFBRTtRQUNsRCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQTtRQUNkLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFBO1FBQzFCLHFFQUFxRTtRQUNyRSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtRQUNwQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUE7UUFDdEIsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFBO0lBQ3pCLENBQUM7SUFFRCw4RkFBOEY7SUFD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
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport that bounces every request through a same-origin proxy endpoint.
|
|
3
|
+
* Used when the real target is a different origin and CORS would block direct
|
|
4
|
+
* browser `fetch` calls. The proxy backend makes the outbound request
|
|
5
|
+
* server-side where CORS does not apply.
|
|
6
|
+
*/
|
|
7
|
+
export default class ProxyBounceTransport {
|
|
8
|
+
/** @returns {string} - Transport name. */
|
|
9
|
+
static get transportName(): string;
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} config - Transport configuration.
|
|
12
|
+
* @param {string} config.proxyUrl - Absolute URL of the proxy endpoint.
|
|
13
|
+
*/
|
|
14
|
+
constructor({ proxyUrl }: {
|
|
15
|
+
proxyUrl: string;
|
|
16
|
+
});
|
|
17
|
+
proxyUrl: string;
|
|
18
|
+
/** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
|
|
19
|
+
get capabilities(): import("../capabilities.js").TransportCapabilities;
|
|
20
|
+
/**
|
|
21
|
+
* @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
|
|
22
|
+
* @returns {Promise<SnapReqResponse>} - The response.
|
|
23
|
+
*/
|
|
24
|
+
performRequest(request: import("../snap-req.js").NormalizedRequest): Promise<SnapReqResponse>;
|
|
25
|
+
}
|
|
26
|
+
import SnapReqResponse from "../response.js";
|
|
27
|
+
//# sourceMappingURL=proxy-bounce-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-bounce-transport.d.ts","sourceRoot":"","sources":["../../src/transports/proxy-bounce-transport.js"],"names":[],"mappings":"AAgCA;;;;;GAKG;AACH;IASE,0CAA0C;IAC1C,4BADc,MAAM,CAGnB;IAXD;;;OAGG;IACH,0BAFG;QAAuB,QAAQ,EAAvB,MAAM;KAChB,EAGA;IADC,iBAAwB;IAQ1B,8FAA8F;IAC9F,oBADc,OAAO,oBAAoB,EAAE,qBAAqB,CAG/D;IAED;;;OAGG;IACH,wBAHW,OAAO,gBAAgB,EAAE,iBAAiB,GACxC,OAAO,CAAC,eAAe,CAAC,CA2EpC;CACF;4BAlI2B,gBAAgB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { buildCapabilities } from "../capabilities.js";
|
|
3
|
+
import { SnapReqUnsupportedFeatureError } from "../errors.js";
|
|
4
|
+
import SnapReqHeaders from "../headers.js";
|
|
5
|
+
import SnapReqResponse from "../response.js";
|
|
6
|
+
/**
|
|
7
|
+
* @param {Uint8Array} bytes - Bytes to encode.
|
|
8
|
+
* @returns {string} - Base64 string.
|
|
9
|
+
*/
|
|
10
|
+
function base64Encode(bytes) {
|
|
11
|
+
const binary = Array.from(bytes, (b) => String.fromCharCode(b)).join("");
|
|
12
|
+
return btoa(binary);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @param {string} base64 - Base64-encoded string.
|
|
16
|
+
* @returns {Uint8Array} - Decoded bytes.
|
|
17
|
+
*/
|
|
18
|
+
function base64Decode(base64) {
|
|
19
|
+
const binary = atob(base64);
|
|
20
|
+
const bytes = new Uint8Array(binary.length);
|
|
21
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
22
|
+
bytes[i] = binary.charCodeAt(i);
|
|
23
|
+
}
|
|
24
|
+
return bytes;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Transport that bounces every request through a same-origin proxy endpoint.
|
|
28
|
+
* Used when the real target is a different origin and CORS would block direct
|
|
29
|
+
* browser `fetch` calls. The proxy backend makes the outbound request
|
|
30
|
+
* server-side where CORS does not apply.
|
|
31
|
+
*/
|
|
32
|
+
export default class ProxyBounceTransport {
|
|
33
|
+
/**
|
|
34
|
+
* @param {object} config - Transport configuration.
|
|
35
|
+
* @param {string} config.proxyUrl - Absolute URL of the proxy endpoint.
|
|
36
|
+
*/
|
|
37
|
+
constructor({ proxyUrl }) {
|
|
38
|
+
this.proxyUrl = proxyUrl;
|
|
39
|
+
}
|
|
40
|
+
/** @returns {string} - Transport name. */
|
|
41
|
+
static get transportName() {
|
|
42
|
+
return "proxy-bounce";
|
|
43
|
+
}
|
|
44
|
+
/** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
|
|
45
|
+
get capabilities() {
|
|
46
|
+
return buildCapabilities({ abort: true });
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
|
|
50
|
+
* @returns {Promise<SnapReqResponse>} - The response.
|
|
51
|
+
*/
|
|
52
|
+
async performRequest(request) {
|
|
53
|
+
const requestBody = request.body;
|
|
54
|
+
/** @type {string | null} */
|
|
55
|
+
let serializedBody = null;
|
|
56
|
+
/** @type {string | undefined} */
|
|
57
|
+
let bodyEncoding;
|
|
58
|
+
if (requestBody.kind === "text") {
|
|
59
|
+
serializedBody = /** @type {string} */ (requestBody.value);
|
|
60
|
+
}
|
|
61
|
+
else if (requestBody.kind === "bytes") {
|
|
62
|
+
serializedBody = base64Encode(/** @type {Uint8Array} */ (requestBody.value));
|
|
63
|
+
bodyEncoding = "base64";
|
|
64
|
+
}
|
|
65
|
+
else if (requestBody.kind === "stream") {
|
|
66
|
+
throw new SnapReqUnsupportedFeatureError({ feature: "streamed request bodies", transport: "proxy-bounce" });
|
|
67
|
+
}
|
|
68
|
+
/** @type {Record<string, any>} */
|
|
69
|
+
const proxyPayload = {
|
|
70
|
+
body: serializedBody,
|
|
71
|
+
headers: request.headers.toObject(),
|
|
72
|
+
method: request.method,
|
|
73
|
+
url: request.url
|
|
74
|
+
};
|
|
75
|
+
if (bodyEncoding) {
|
|
76
|
+
proxyPayload.bodyEncoding = bodyEncoding;
|
|
77
|
+
}
|
|
78
|
+
/** @type {Response} */
|
|
79
|
+
let proxyResponse;
|
|
80
|
+
try {
|
|
81
|
+
proxyResponse = await fetch(this.proxyUrl, {
|
|
82
|
+
body: JSON.stringify(proxyPayload),
|
|
83
|
+
headers: { "Content-Type": "application/json" },
|
|
84
|
+
method: "POST",
|
|
85
|
+
signal: request.signal || undefined
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
const payload = await proxyResponse.json();
|
|
95
|
+
const responseHeaders = new SnapReqHeaders();
|
|
96
|
+
if (payload.headers) {
|
|
97
|
+
for (const [name, value] of Object.entries(payload.headers)) {
|
|
98
|
+
responseHeaders.set(name, String(value));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** @type {Uint8Array} */
|
|
102
|
+
let bodyBytes = new Uint8Array(0);
|
|
103
|
+
if (payload.body) {
|
|
104
|
+
bodyBytes = base64Decode(payload.body);
|
|
105
|
+
}
|
|
106
|
+
return new SnapReqResponse({
|
|
107
|
+
bytes: bodyBytes,
|
|
108
|
+
headers: responseHeaders,
|
|
109
|
+
method: request.method,
|
|
110
|
+
status: payload.status,
|
|
111
|
+
statusText: payload.statusText || "",
|
|
112
|
+
url: request.url
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHktYm91bmNlLXRyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90cmFuc3BvcnRzL3Byb3h5LWJvdW5jZS10cmFuc3BvcnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBQ3BELE9BQU8sRUFBQyw4QkFBOEIsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUMzRCxPQUFPLGNBQWMsTUFBTSxlQUFlLENBQUE7QUFDMUMsT0FBTyxlQUFlLE1BQU0sZ0JBQWdCLENBQUE7QUFFNUM7OztHQUdHO0FBQ0gsU0FBUyxZQUFZLENBQUMsS0FBSztJQUN6QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUV4RSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUNyQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxZQUFZLENBQUMsTUFBTTtJQUMxQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDM0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRTNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFN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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/transports/select.js"],"names":[],"mappings":"AAMA;;GAEG;AAEH;;;;;GAKG;AAEH;;;GAGG;AACH,iCAFa,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAU3D;AAYD;;;;;;;GAOG;AACH,4CAJW,aAAa,GAAG,SAAS,GAAG,SAAS,cACrC,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAyB9B;4BAjEY,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK;;;;;kBAKhC,OAAO,oBAAoB,EAAE,qBAAqB;;;;oBAClD,CAAC,OAAO,EAAE,OAAO,gBAAgB,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,gBAAgB,EAAE,OAAO,CAAC;;;;YAClG,MAAM,IAAI"}
|