@npy/fetch 0.1.2 → 0.1.3
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 +143 -50
- package/bun.lock +68 -0
- package/examples/custom-proxy-client.ts +32 -0
- package/examples/http-client.ts +47 -0
- package/examples/proxy.ts +16 -0
- package/examples/simple.ts +15 -0
- package/package.json +25 -30
- package/src/_internal/consts.ts +3 -0
- package/{_internal/decode-stream-error.d.cts → src/_internal/decode-stream-error.ts} +7 -2
- package/src/_internal/error-mapping.ts +160 -0
- package/src/_internal/guards.ts +78 -0
- package/src/_internal/net.ts +173 -0
- package/src/_internal/promises.ts +22 -0
- package/src/_internal/streams.ts +52 -0
- package/src/_internal/symbols.ts +1 -0
- package/src/agent-pool.ts +157 -0
- package/src/agent.ts +408 -0
- package/src/body.ts +179 -0
- package/src/dialers/index.ts +3 -0
- package/src/dialers/proxy.ts +102 -0
- package/src/dialers/tcp.ts +162 -0
- package/src/encoding.ts +222 -0
- package/src/errors.ts +357 -0
- package/src/fetch.ts +626 -0
- package/src/http-client.ts +111 -0
- package/src/index.ts +14 -0
- package/src/io/_utils.ts +82 -0
- package/src/io/buf-writer.ts +183 -0
- package/src/io/io.ts +322 -0
- package/src/io/readers.ts +576 -0
- package/src/io/writers.ts +331 -0
- package/{types/agent.d.cts → src/types/agent.ts} +47 -21
- package/{types/dialer.d.cts → src/types/dialer.ts} +19 -9
- package/src/types/index.ts +2 -0
- package/tests/agent-pool.test.ts +111 -0
- package/tests/agent.test.ts +134 -0
- package/tests/body.test.ts +228 -0
- package/tests/errors.test.ts +152 -0
- package/tests/fetch.test.ts +421 -0
- package/tests/io-options.test.ts +127 -0
- package/tests/multipart.test.ts +348 -0
- package/tests/test-utils.ts +335 -0
- package/tsconfig.json +15 -0
- package/LICENSE +0 -21
- package/_internal/consts.cjs +0 -4
- package/_internal/consts.d.cts +0 -3
- package/_internal/consts.d.ts +0 -3
- package/_internal/consts.js +0 -4
- package/_internal/decode-stream-error.cjs +0 -18
- package/_internal/decode-stream-error.d.ts +0 -11
- package/_internal/decode-stream-error.js +0 -18
- package/_internal/error-mapping.cjs +0 -44
- package/_internal/error-mapping.d.cts +0 -15
- package/_internal/error-mapping.d.ts +0 -15
- package/_internal/error-mapping.js +0 -41
- package/_internal/guards.cjs +0 -23
- package/_internal/guards.d.cts +0 -15
- package/_internal/guards.d.ts +0 -15
- package/_internal/guards.js +0 -15
- package/_internal/net.cjs +0 -95
- package/_internal/net.d.cts +0 -11
- package/_internal/net.d.ts +0 -11
- package/_internal/net.js +0 -92
- package/_internal/promises.cjs +0 -18
- package/_internal/promises.d.cts +0 -1
- package/_internal/promises.d.ts +0 -1
- package/_internal/promises.js +0 -18
- package/_internal/streams.cjs +0 -37
- package/_internal/streams.d.cts +0 -21
- package/_internal/streams.d.ts +0 -21
- package/_internal/streams.js +0 -36
- package/_internal/symbols.cjs +0 -4
- package/_internal/symbols.d.cts +0 -1
- package/_internal/symbols.d.ts +0 -1
- package/_internal/symbols.js +0 -4
- package/_virtual/_rolldown/runtime.cjs +0 -23
- package/agent-pool.cjs +0 -96
- package/agent-pool.d.cts +0 -2
- package/agent-pool.d.ts +0 -2
- package/agent-pool.js +0 -95
- package/agent.cjs +0 -260
- package/agent.d.cts +0 -3
- package/agent.d.ts +0 -3
- package/agent.js +0 -259
- package/body.cjs +0 -105
- package/body.d.cts +0 -12
- package/body.d.ts +0 -12
- package/body.js +0 -102
- package/dialers/index.d.cts +0 -3
- package/dialers/index.d.ts +0 -3
- package/dialers/proxy.cjs +0 -56
- package/dialers/proxy.d.cts +0 -27
- package/dialers/proxy.d.ts +0 -27
- package/dialers/proxy.js +0 -55
- package/dialers/tcp.cjs +0 -92
- package/dialers/tcp.d.cts +0 -57
- package/dialers/tcp.d.ts +0 -57
- package/dialers/tcp.js +0 -89
- package/encoding.cjs +0 -114
- package/encoding.d.cts +0 -35
- package/encoding.d.ts +0 -35
- package/encoding.js +0 -110
- package/errors.cjs +0 -275
- package/errors.d.cts +0 -110
- package/errors.d.ts +0 -110
- package/errors.js +0 -259
- package/fetch.cjs +0 -353
- package/fetch.d.cts +0 -58
- package/fetch.d.ts +0 -58
- package/fetch.js +0 -350
- package/http-client.cjs +0 -75
- package/http-client.d.cts +0 -39
- package/http-client.d.ts +0 -39
- package/http-client.js +0 -75
- package/index.cjs +0 -49
- package/index.d.cts +0 -14
- package/index.d.ts +0 -14
- package/index.js +0 -11
- package/io/_utils.cjs +0 -56
- package/io/_utils.d.cts +0 -10
- package/io/_utils.d.ts +0 -10
- package/io/_utils.js +0 -51
- package/io/buf-writer.cjs +0 -149
- package/io/buf-writer.d.cts +0 -13
- package/io/buf-writer.d.ts +0 -13
- package/io/buf-writer.js +0 -148
- package/io/io.cjs +0 -199
- package/io/io.d.cts +0 -5
- package/io/io.d.ts +0 -5
- package/io/io.js +0 -198
- package/io/readers.cjs +0 -337
- package/io/readers.d.cts +0 -69
- package/io/readers.d.ts +0 -69
- package/io/readers.js +0 -333
- package/io/writers.cjs +0 -196
- package/io/writers.d.cts +0 -22
- package/io/writers.d.ts +0 -22
- package/io/writers.js +0 -195
- package/types/agent.d.ts +0 -72
- package/types/dialer.d.ts +0 -30
- package/types/index.d.cts +0 -2
- package/types/index.d.ts +0 -2
package/dialers/tcp.cjs
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const require_net = require("../_internal/net.cjs");
|
|
2
|
-
//#region src/dialers/tcp.ts
|
|
3
|
-
var DEFAULT_TCP_PORT = 80;
|
|
4
|
-
var DEFAULT_TLS_PORT = 443;
|
|
5
|
-
var DEFAULT_HTTP_ALPN_PROTOCOLS = ["http/1.1"];
|
|
6
|
-
function parsePort(value) {
|
|
7
|
-
if (typeof value === "number") {
|
|
8
|
-
if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new TypeError(`Invalid port: ${String(value)}`);
|
|
9
|
-
return value;
|
|
10
|
-
}
|
|
11
|
-
if (!/^\d+$/.test(value)) throw new TypeError(`Invalid port: ${JSON.stringify(value)}`);
|
|
12
|
-
const parsed = Number.parseInt(value, 10);
|
|
13
|
-
if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) throw new TypeError(`Invalid port: ${JSON.stringify(value)}`);
|
|
14
|
-
return parsed;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Resolves the effective network address and port for a URL or dial target.
|
|
18
|
-
*
|
|
19
|
-
* @remarks
|
|
20
|
-
* When the input does not include an explicit port, the provided default port is used.
|
|
21
|
-
*/
|
|
22
|
-
function resolveHostPort(target, defaultPort) {
|
|
23
|
-
const address = target instanceof URL ? target.hostname : target.address;
|
|
24
|
-
if (!address) throw new TypeError("Target address is required");
|
|
25
|
-
return {
|
|
26
|
-
address,
|
|
27
|
-
port: target instanceof URL ? parsePort(target.port || String(defaultPort)) : parsePort(target.port || defaultPort)
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Dialer for plain TCP targets.
|
|
32
|
-
*
|
|
33
|
-
* @remarks
|
|
34
|
-
* This dialer rejects secure targets and is intended for HTTP over raw TCP.
|
|
35
|
-
*/
|
|
36
|
-
var TcpDialer = class {
|
|
37
|
-
async dial(target, options = {}) {
|
|
38
|
-
if (target.secure) throw new Error("TcpDialer cannot dial a secure target");
|
|
39
|
-
return require_net.connectTcp({
|
|
40
|
-
...resolveHostPort(target, DEFAULT_TCP_PORT),
|
|
41
|
-
signal: options.signal
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Dialer for TLS targets.
|
|
47
|
-
*
|
|
48
|
-
* @remarks
|
|
49
|
-
* This dialer rejects insecure targets and applies TLS-specific options such as
|
|
50
|
-
* CA certificates, SNI and ALPN.
|
|
51
|
-
*/
|
|
52
|
-
var TlsDialer = class {
|
|
53
|
-
#options;
|
|
54
|
-
constructor(options = {}) {
|
|
55
|
-
this.#options = { ...options };
|
|
56
|
-
}
|
|
57
|
-
async dial(target, options = {}) {
|
|
58
|
-
if (!target.secure) throw new Error("TlsDialer cannot dial an insecure target");
|
|
59
|
-
const endpoint = resolveHostPort(target, DEFAULT_TLS_PORT);
|
|
60
|
-
const extraOptions = this.#options.extraOptions || target.extraOptions ? {
|
|
61
|
-
...this.#options.extraOptions,
|
|
62
|
-
...target.extraOptions
|
|
63
|
-
} : void 0;
|
|
64
|
-
return require_net.connectTls({
|
|
65
|
-
...endpoint,
|
|
66
|
-
signal: options.signal,
|
|
67
|
-
caCerts: this.#options.caCerts,
|
|
68
|
-
sni: target.sni ?? this.#options.sni ?? endpoint.address,
|
|
69
|
-
alpnProtocols: target.alpnProtocols ?? this.#options.alpnProtocols ?? [...DEFAULT_HTTP_ALPN_PROTOCOLS],
|
|
70
|
-
extraOptions
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Selects {@link TcpDialer} or {@link TlsDialer} based on the target security mode.
|
|
76
|
-
*/
|
|
77
|
-
var AutoDialer = class {
|
|
78
|
-
tcpDialer;
|
|
79
|
-
tlsDialer;
|
|
80
|
-
constructor(options = {}) {
|
|
81
|
-
this.tcpDialer = options.tcp ?? new TcpDialer();
|
|
82
|
-
this.tlsDialer = options.tls ?? new TlsDialer();
|
|
83
|
-
}
|
|
84
|
-
dial(target, options = {}) {
|
|
85
|
-
return target.secure ? this.tlsDialer.dial(target, options) : this.tcpDialer.dial(target, options);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
//#endregion
|
|
89
|
-
exports.AutoDialer = AutoDialer;
|
|
90
|
-
exports.TcpDialer = TcpDialer;
|
|
91
|
-
exports.TlsDialer = TlsDialer;
|
|
92
|
-
exports.resolveHostPort = resolveHostPort;
|
package/dialers/tcp.d.cts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { NodeTlsConnectOptions } from '@fuman/node';
|
|
2
|
-
import { Dialer } from '../types/dialer';
|
|
3
|
-
export type HostPort = {
|
|
4
|
-
address: string;
|
|
5
|
-
port: number;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Resolves the effective network address and port for a URL or dial target.
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* When the input does not include an explicit port, the provided default port is used.
|
|
12
|
-
*/
|
|
13
|
-
export declare function resolveHostPort(target: URL | Dialer.Target, defaultPort: number): HostPort;
|
|
14
|
-
/**
|
|
15
|
-
* Dialer for plain TCP targets.
|
|
16
|
-
*
|
|
17
|
-
* @remarks
|
|
18
|
-
* This dialer rejects secure targets and is intended for HTTP over raw TCP.
|
|
19
|
-
*/
|
|
20
|
-
export declare class TcpDialer implements Dialer {
|
|
21
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Dialer for TLS targets.
|
|
25
|
-
*
|
|
26
|
-
* @remarks
|
|
27
|
-
* This dialer rejects insecure targets and applies TLS-specific options such as
|
|
28
|
-
* CA certificates, SNI and ALPN.
|
|
29
|
-
*/
|
|
30
|
-
export declare class TlsDialer implements Dialer {
|
|
31
|
-
#private;
|
|
32
|
-
constructor(options?: TlsDialer.Options);
|
|
33
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
34
|
-
}
|
|
35
|
-
export declare namespace TlsDialer {
|
|
36
|
-
interface Options {
|
|
37
|
-
caCerts?: string[];
|
|
38
|
-
sni?: string;
|
|
39
|
-
alpnProtocols?: string[];
|
|
40
|
-
extraOptions?: NodeTlsConnectOptions["extraOptions"];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Selects {@link TcpDialer} or {@link TlsDialer} based on the target security mode.
|
|
45
|
-
*/
|
|
46
|
-
export declare class AutoDialer implements Dialer {
|
|
47
|
-
readonly tcpDialer: TcpDialer;
|
|
48
|
-
readonly tlsDialer: TlsDialer;
|
|
49
|
-
constructor(options?: AutoDialer.Options);
|
|
50
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
51
|
-
}
|
|
52
|
-
export declare namespace AutoDialer {
|
|
53
|
-
interface Options {
|
|
54
|
-
tcp?: TcpDialer;
|
|
55
|
-
tls?: TlsDialer;
|
|
56
|
-
}
|
|
57
|
-
}
|
package/dialers/tcp.d.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { NodeTlsConnectOptions } from '@fuman/node';
|
|
2
|
-
import { Dialer } from '../types/dialer';
|
|
3
|
-
export type HostPort = {
|
|
4
|
-
address: string;
|
|
5
|
-
port: number;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Resolves the effective network address and port for a URL or dial target.
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* When the input does not include an explicit port, the provided default port is used.
|
|
12
|
-
*/
|
|
13
|
-
export declare function resolveHostPort(target: URL | Dialer.Target, defaultPort: number): HostPort;
|
|
14
|
-
/**
|
|
15
|
-
* Dialer for plain TCP targets.
|
|
16
|
-
*
|
|
17
|
-
* @remarks
|
|
18
|
-
* This dialer rejects secure targets and is intended for HTTP over raw TCP.
|
|
19
|
-
*/
|
|
20
|
-
export declare class TcpDialer implements Dialer {
|
|
21
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Dialer for TLS targets.
|
|
25
|
-
*
|
|
26
|
-
* @remarks
|
|
27
|
-
* This dialer rejects insecure targets and applies TLS-specific options such as
|
|
28
|
-
* CA certificates, SNI and ALPN.
|
|
29
|
-
*/
|
|
30
|
-
export declare class TlsDialer implements Dialer {
|
|
31
|
-
#private;
|
|
32
|
-
constructor(options?: TlsDialer.Options);
|
|
33
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
34
|
-
}
|
|
35
|
-
export declare namespace TlsDialer {
|
|
36
|
-
interface Options {
|
|
37
|
-
caCerts?: string[];
|
|
38
|
-
sni?: string;
|
|
39
|
-
alpnProtocols?: string[];
|
|
40
|
-
extraOptions?: NodeTlsConnectOptions["extraOptions"];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Selects {@link TcpDialer} or {@link TlsDialer} based on the target security mode.
|
|
45
|
-
*/
|
|
46
|
-
export declare class AutoDialer implements Dialer {
|
|
47
|
-
readonly tcpDialer: TcpDialer;
|
|
48
|
-
readonly tlsDialer: TlsDialer;
|
|
49
|
-
constructor(options?: AutoDialer.Options);
|
|
50
|
-
dial(target: Dialer.Target, options?: Dialer.Options): Promise<Dialer.ConnectionLike>;
|
|
51
|
-
}
|
|
52
|
-
export declare namespace AutoDialer {
|
|
53
|
-
interface Options {
|
|
54
|
-
tcp?: TcpDialer;
|
|
55
|
-
tls?: TlsDialer;
|
|
56
|
-
}
|
|
57
|
-
}
|
package/dialers/tcp.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { connectTcp, connectTls } from "../_internal/net.js";
|
|
2
|
-
//#region src/dialers/tcp.ts
|
|
3
|
-
var DEFAULT_TCP_PORT = 80;
|
|
4
|
-
var DEFAULT_TLS_PORT = 443;
|
|
5
|
-
var DEFAULT_HTTP_ALPN_PROTOCOLS = ["http/1.1"];
|
|
6
|
-
function parsePort(value) {
|
|
7
|
-
if (typeof value === "number") {
|
|
8
|
-
if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new TypeError(`Invalid port: ${String(value)}`);
|
|
9
|
-
return value;
|
|
10
|
-
}
|
|
11
|
-
if (!/^\d+$/.test(value)) throw new TypeError(`Invalid port: ${JSON.stringify(value)}`);
|
|
12
|
-
const parsed = Number.parseInt(value, 10);
|
|
13
|
-
if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) throw new TypeError(`Invalid port: ${JSON.stringify(value)}`);
|
|
14
|
-
return parsed;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Resolves the effective network address and port for a URL or dial target.
|
|
18
|
-
*
|
|
19
|
-
* @remarks
|
|
20
|
-
* When the input does not include an explicit port, the provided default port is used.
|
|
21
|
-
*/
|
|
22
|
-
function resolveHostPort(target, defaultPort) {
|
|
23
|
-
const address = target instanceof URL ? target.hostname : target.address;
|
|
24
|
-
if (!address) throw new TypeError("Target address is required");
|
|
25
|
-
return {
|
|
26
|
-
address,
|
|
27
|
-
port: target instanceof URL ? parsePort(target.port || String(defaultPort)) : parsePort(target.port || defaultPort)
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Dialer for plain TCP targets.
|
|
32
|
-
*
|
|
33
|
-
* @remarks
|
|
34
|
-
* This dialer rejects secure targets and is intended for HTTP over raw TCP.
|
|
35
|
-
*/
|
|
36
|
-
var TcpDialer = class {
|
|
37
|
-
async dial(target, options = {}) {
|
|
38
|
-
if (target.secure) throw new Error("TcpDialer cannot dial a secure target");
|
|
39
|
-
return connectTcp({
|
|
40
|
-
...resolveHostPort(target, DEFAULT_TCP_PORT),
|
|
41
|
-
signal: options.signal
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Dialer for TLS targets.
|
|
47
|
-
*
|
|
48
|
-
* @remarks
|
|
49
|
-
* This dialer rejects insecure targets and applies TLS-specific options such as
|
|
50
|
-
* CA certificates, SNI and ALPN.
|
|
51
|
-
*/
|
|
52
|
-
var TlsDialer = class {
|
|
53
|
-
#options;
|
|
54
|
-
constructor(options = {}) {
|
|
55
|
-
this.#options = { ...options };
|
|
56
|
-
}
|
|
57
|
-
async dial(target, options = {}) {
|
|
58
|
-
if (!target.secure) throw new Error("TlsDialer cannot dial an insecure target");
|
|
59
|
-
const endpoint = resolveHostPort(target, DEFAULT_TLS_PORT);
|
|
60
|
-
const extraOptions = this.#options.extraOptions || target.extraOptions ? {
|
|
61
|
-
...this.#options.extraOptions,
|
|
62
|
-
...target.extraOptions
|
|
63
|
-
} : void 0;
|
|
64
|
-
return connectTls({
|
|
65
|
-
...endpoint,
|
|
66
|
-
signal: options.signal,
|
|
67
|
-
caCerts: this.#options.caCerts,
|
|
68
|
-
sni: target.sni ?? this.#options.sni ?? endpoint.address,
|
|
69
|
-
alpnProtocols: target.alpnProtocols ?? this.#options.alpnProtocols ?? [...DEFAULT_HTTP_ALPN_PROTOCOLS],
|
|
70
|
-
extraOptions
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Selects {@link TcpDialer} or {@link TlsDialer} based on the target security mode.
|
|
76
|
-
*/
|
|
77
|
-
var AutoDialer = class {
|
|
78
|
-
tcpDialer;
|
|
79
|
-
tlsDialer;
|
|
80
|
-
constructor(options = {}) {
|
|
81
|
-
this.tcpDialer = options.tcp ?? new TcpDialer();
|
|
82
|
-
this.tlsDialer = options.tls ?? new TlsDialer();
|
|
83
|
-
}
|
|
84
|
-
dial(target, options = {}) {
|
|
85
|
-
return target.secure ? this.tlsDialer.dial(target, options) : this.tcpDialer.dial(target, options);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
//#endregion
|
|
89
|
-
export { AutoDialer, TcpDialer, TlsDialer, resolveHostPort };
|
package/encoding.cjs
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
require("./_virtual/_rolldown/runtime.cjs");
|
|
2
|
-
const require_decode_stream_error = require("./_internal/decode-stream-error.cjs");
|
|
3
|
-
let _fuman_node = require("@fuman/node");
|
|
4
|
-
let node_stream = require("node:stream");
|
|
5
|
-
//#region src/encoding.ts
|
|
6
|
-
function applyTransforms(stream, contentEncoding, factory) {
|
|
7
|
-
const transforms = factory(contentEncoding);
|
|
8
|
-
if (transforms.length === 0) return stream;
|
|
9
|
-
let result;
|
|
10
|
-
if (stream instanceof ReadableStream) result = stream;
|
|
11
|
-
else result = (0, _fuman_node.nodeReadableToWeb)(node_stream.Readable.from(stream));
|
|
12
|
-
for (const t of transforms) result = result.pipeThrough(t);
|
|
13
|
-
return result;
|
|
14
|
-
}
|
|
15
|
-
function decodeStream(stream, contentEncoding) {
|
|
16
|
-
return applyTransforms(stream, contentEncoding, createDecoders);
|
|
17
|
-
}
|
|
18
|
-
function encodeStream(stream, contentEncoding) {
|
|
19
|
-
return applyTransforms(stream, contentEncoding, createEncoders);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Creates the decoder pipeline for a Content-Encoding or transfer-coding list.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* Decoding is applied in reverse order of encoding, as required by HTTP semantics.
|
|
26
|
-
* The special value `identity` is ignored.
|
|
27
|
-
*/
|
|
28
|
-
function createDecoders(contentEncoding) {
|
|
29
|
-
const decoders = [];
|
|
30
|
-
if (contentEncoding?.length) {
|
|
31
|
-
const encodings = Array.isArray(contentEncoding) ? contentEncoding.flatMap(commaSplit) : contentEncoding.split(",");
|
|
32
|
-
for (const encoding of encodings) {
|
|
33
|
-
const normalizedEncoding = normalizeEncoding(encoding);
|
|
34
|
-
if (normalizedEncoding === "identity") continue;
|
|
35
|
-
decoders.push(createDecoder(normalizedEncoding));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return decoders.reverse();
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Creates the encoder pipeline for a Content-Encoding or transfer-coding list.
|
|
42
|
-
*
|
|
43
|
-
* @remarks
|
|
44
|
-
* Encoders are returned in the declared order. The special value `identity` is ignored.
|
|
45
|
-
*/
|
|
46
|
-
function createEncoders(contentEncoding) {
|
|
47
|
-
const encoders = [];
|
|
48
|
-
if (contentEncoding?.length) {
|
|
49
|
-
const encodings = Array.isArray(contentEncoding) ? contentEncoding.flatMap(commaSplit) : contentEncoding.split(",");
|
|
50
|
-
for (const encoding of encodings) {
|
|
51
|
-
const normalizedEncoding = normalizeEncoding(encoding);
|
|
52
|
-
if (normalizedEncoding === "identity") continue;
|
|
53
|
-
encoders.push(createEncoder(normalizedEncoding));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return encoders;
|
|
57
|
-
}
|
|
58
|
-
function commaSplit(header) {
|
|
59
|
-
return header.split(",");
|
|
60
|
-
}
|
|
61
|
-
function normalizeEncoding(encoding) {
|
|
62
|
-
return encoding.trim().toLowerCase();
|
|
63
|
-
}
|
|
64
|
-
function tagDecodeErrors(native) {
|
|
65
|
-
const reader = native.readable.getReader();
|
|
66
|
-
const tagged = new ReadableStream({
|
|
67
|
-
pull(controller) {
|
|
68
|
-
return reader.read().then(({ done, value }) => {
|
|
69
|
-
if (done) controller.close();
|
|
70
|
-
else if (value) controller.enqueue(value);
|
|
71
|
-
}, (err) => {
|
|
72
|
-
controller.error(new require_decode_stream_error.DecodeStreamError(err));
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
|
-
cancel(reason) {
|
|
76
|
-
return reader.cancel(reason);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
return {
|
|
80
|
-
writable: native.writable,
|
|
81
|
-
readable: tagged
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function createDecoder(normalizedEncoding) {
|
|
85
|
-
switch (normalizedEncoding) {
|
|
86
|
-
case "gzip":
|
|
87
|
-
case "x-gzip": return tagDecodeErrors(new DecompressionStream("gzip"));
|
|
88
|
-
case "deflate":
|
|
89
|
-
case "x-deflate": return tagDecodeErrors(new DecompressionStream("deflate"));
|
|
90
|
-
case "zstd":
|
|
91
|
-
case "x-zstd": return tagDecodeErrors(new DecompressionStream("zstd"));
|
|
92
|
-
case "br": return tagDecodeErrors(new DecompressionStream("brotli"));
|
|
93
|
-
case "identity": return new TransformStream();
|
|
94
|
-
default: throw new TypeError(`Unsupported content-encoding: "${normalizedEncoding}"`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function createEncoder(normalizedEncoding) {
|
|
98
|
-
switch (normalizedEncoding) {
|
|
99
|
-
case "gzip":
|
|
100
|
-
case "x-gzip": return new CompressionStream("gzip");
|
|
101
|
-
case "deflate":
|
|
102
|
-
case "x-deflate": return new CompressionStream("deflate");
|
|
103
|
-
case "zstd":
|
|
104
|
-
case "x-zstd": return new CompressionStream("zstd");
|
|
105
|
-
case "br": return new CompressionStream("brotli");
|
|
106
|
-
case "identity": return new TransformStream();
|
|
107
|
-
default: throw new TypeError(`Unsupported content-encoding: "${normalizedEncoding}"`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
//#endregion
|
|
111
|
-
exports.createDecoders = createDecoders;
|
|
112
|
-
exports.createEncoders = createEncoders;
|
|
113
|
-
exports.decodeStream = decodeStream;
|
|
114
|
-
exports.encodeStream = encodeStream;
|
package/encoding.d.cts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export type ByteStream = ReadableStream<Uint8Array>;
|
|
2
|
-
export type ByteTransform = TransformStream<Uint8Array, Uint8Array>;
|
|
3
|
-
/**
|
|
4
|
-
* Applies decoding transforms for the given content-encoding list.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* If no supported encodings are provided, the original source is returned unchanged.
|
|
8
|
-
* Async iterables are converted to Web Streams only when transforms are required.
|
|
9
|
-
*/
|
|
10
|
-
export declare function decodeStream(stream: ByteStream, contentEncoding?: string | string[]): ByteStream;
|
|
11
|
-
export declare function decodeStream(stream: AsyncIterable<Uint8Array>, contentEncoding?: string | string[]): AsyncIterable<Uint8Array> | ByteStream;
|
|
12
|
-
/**
|
|
13
|
-
* Applies encoding transforms for the given content-encoding list.
|
|
14
|
-
*
|
|
15
|
-
* @remarks
|
|
16
|
-
* If no supported encodings are provided, the original source is returned unchanged.
|
|
17
|
-
* Async iterables are converted to Web Streams only when transforms are required.
|
|
18
|
-
*/
|
|
19
|
-
export declare function encodeStream(stream: ByteStream, contentEncoding?: string | string[]): ByteStream;
|
|
20
|
-
export declare function encodeStream(stream: AsyncIterable<Uint8Array>, contentEncoding?: string | string[]): AsyncIterable<Uint8Array> | ByteStream;
|
|
21
|
-
/**
|
|
22
|
-
* Creates the decoder pipeline for a Content-Encoding or transfer-coding list.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* Decoding is applied in reverse order of encoding, as required by HTTP semantics.
|
|
26
|
-
* The special value `identity` is ignored.
|
|
27
|
-
*/
|
|
28
|
-
export declare function createDecoders(contentEncoding?: string | string[]): ByteTransform[];
|
|
29
|
-
/**
|
|
30
|
-
* Creates the encoder pipeline for a Content-Encoding or transfer-coding list.
|
|
31
|
-
*
|
|
32
|
-
* @remarks
|
|
33
|
-
* Encoders are returned in the declared order. The special value `identity` is ignored.
|
|
34
|
-
*/
|
|
35
|
-
export declare function createEncoders(contentEncoding?: string | string[]): ByteTransform[];
|
package/encoding.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export type ByteStream = ReadableStream<Uint8Array>;
|
|
2
|
-
export type ByteTransform = TransformStream<Uint8Array, Uint8Array>;
|
|
3
|
-
/**
|
|
4
|
-
* Applies decoding transforms for the given content-encoding list.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* If no supported encodings are provided, the original source is returned unchanged.
|
|
8
|
-
* Async iterables are converted to Web Streams only when transforms are required.
|
|
9
|
-
*/
|
|
10
|
-
export declare function decodeStream(stream: ByteStream, contentEncoding?: string | string[]): ByteStream;
|
|
11
|
-
export declare function decodeStream(stream: AsyncIterable<Uint8Array>, contentEncoding?: string | string[]): AsyncIterable<Uint8Array> | ByteStream;
|
|
12
|
-
/**
|
|
13
|
-
* Applies encoding transforms for the given content-encoding list.
|
|
14
|
-
*
|
|
15
|
-
* @remarks
|
|
16
|
-
* If no supported encodings are provided, the original source is returned unchanged.
|
|
17
|
-
* Async iterables are converted to Web Streams only when transforms are required.
|
|
18
|
-
*/
|
|
19
|
-
export declare function encodeStream(stream: ByteStream, contentEncoding?: string | string[]): ByteStream;
|
|
20
|
-
export declare function encodeStream(stream: AsyncIterable<Uint8Array>, contentEncoding?: string | string[]): AsyncIterable<Uint8Array> | ByteStream;
|
|
21
|
-
/**
|
|
22
|
-
* Creates the decoder pipeline for a Content-Encoding or transfer-coding list.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* Decoding is applied in reverse order of encoding, as required by HTTP semantics.
|
|
26
|
-
* The special value `identity` is ignored.
|
|
27
|
-
*/
|
|
28
|
-
export declare function createDecoders(contentEncoding?: string | string[]): ByteTransform[];
|
|
29
|
-
/**
|
|
30
|
-
* Creates the encoder pipeline for a Content-Encoding or transfer-coding list.
|
|
31
|
-
*
|
|
32
|
-
* @remarks
|
|
33
|
-
* Encoders are returned in the declared order. The special value `identity` is ignored.
|
|
34
|
-
*/
|
|
35
|
-
export declare function createEncoders(contentEncoding?: string | string[]): ByteTransform[];
|
package/encoding.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { DecodeStreamError } from "./_internal/decode-stream-error.js";
|
|
2
|
-
import { nodeReadableToWeb } from "@fuman/node";
|
|
3
|
-
import { Readable } from "node:stream";
|
|
4
|
-
//#region src/encoding.ts
|
|
5
|
-
function applyTransforms(stream, contentEncoding, factory) {
|
|
6
|
-
const transforms = factory(contentEncoding);
|
|
7
|
-
if (transforms.length === 0) return stream;
|
|
8
|
-
let result;
|
|
9
|
-
if (stream instanceof ReadableStream) result = stream;
|
|
10
|
-
else result = nodeReadableToWeb(Readable.from(stream));
|
|
11
|
-
for (const t of transforms) result = result.pipeThrough(t);
|
|
12
|
-
return result;
|
|
13
|
-
}
|
|
14
|
-
function decodeStream(stream, contentEncoding) {
|
|
15
|
-
return applyTransforms(stream, contentEncoding, createDecoders);
|
|
16
|
-
}
|
|
17
|
-
function encodeStream(stream, contentEncoding) {
|
|
18
|
-
return applyTransforms(stream, contentEncoding, createEncoders);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Creates the decoder pipeline for a Content-Encoding or transfer-coding list.
|
|
22
|
-
*
|
|
23
|
-
* @remarks
|
|
24
|
-
* Decoding is applied in reverse order of encoding, as required by HTTP semantics.
|
|
25
|
-
* The special value `identity` is ignored.
|
|
26
|
-
*/
|
|
27
|
-
function createDecoders(contentEncoding) {
|
|
28
|
-
const decoders = [];
|
|
29
|
-
if (contentEncoding?.length) {
|
|
30
|
-
const encodings = Array.isArray(contentEncoding) ? contentEncoding.flatMap(commaSplit) : contentEncoding.split(",");
|
|
31
|
-
for (const encoding of encodings) {
|
|
32
|
-
const normalizedEncoding = normalizeEncoding(encoding);
|
|
33
|
-
if (normalizedEncoding === "identity") continue;
|
|
34
|
-
decoders.push(createDecoder(normalizedEncoding));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return decoders.reverse();
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Creates the encoder pipeline for a Content-Encoding or transfer-coding list.
|
|
41
|
-
*
|
|
42
|
-
* @remarks
|
|
43
|
-
* Encoders are returned in the declared order. The special value `identity` is ignored.
|
|
44
|
-
*/
|
|
45
|
-
function createEncoders(contentEncoding) {
|
|
46
|
-
const encoders = [];
|
|
47
|
-
if (contentEncoding?.length) {
|
|
48
|
-
const encodings = Array.isArray(contentEncoding) ? contentEncoding.flatMap(commaSplit) : contentEncoding.split(",");
|
|
49
|
-
for (const encoding of encodings) {
|
|
50
|
-
const normalizedEncoding = normalizeEncoding(encoding);
|
|
51
|
-
if (normalizedEncoding === "identity") continue;
|
|
52
|
-
encoders.push(createEncoder(normalizedEncoding));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return encoders;
|
|
56
|
-
}
|
|
57
|
-
function commaSplit(header) {
|
|
58
|
-
return header.split(",");
|
|
59
|
-
}
|
|
60
|
-
function normalizeEncoding(encoding) {
|
|
61
|
-
return encoding.trim().toLowerCase();
|
|
62
|
-
}
|
|
63
|
-
function tagDecodeErrors(native) {
|
|
64
|
-
const reader = native.readable.getReader();
|
|
65
|
-
const tagged = new ReadableStream({
|
|
66
|
-
pull(controller) {
|
|
67
|
-
return reader.read().then(({ done, value }) => {
|
|
68
|
-
if (done) controller.close();
|
|
69
|
-
else if (value) controller.enqueue(value);
|
|
70
|
-
}, (err) => {
|
|
71
|
-
controller.error(new DecodeStreamError(err));
|
|
72
|
-
});
|
|
73
|
-
},
|
|
74
|
-
cancel(reason) {
|
|
75
|
-
return reader.cancel(reason);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
writable: native.writable,
|
|
80
|
-
readable: tagged
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function createDecoder(normalizedEncoding) {
|
|
84
|
-
switch (normalizedEncoding) {
|
|
85
|
-
case "gzip":
|
|
86
|
-
case "x-gzip": return tagDecodeErrors(new DecompressionStream("gzip"));
|
|
87
|
-
case "deflate":
|
|
88
|
-
case "x-deflate": return tagDecodeErrors(new DecompressionStream("deflate"));
|
|
89
|
-
case "zstd":
|
|
90
|
-
case "x-zstd": return tagDecodeErrors(new DecompressionStream("zstd"));
|
|
91
|
-
case "br": return tagDecodeErrors(new DecompressionStream("brotli"));
|
|
92
|
-
case "identity": return new TransformStream();
|
|
93
|
-
default: throw new TypeError(`Unsupported content-encoding: "${normalizedEncoding}"`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function createEncoder(normalizedEncoding) {
|
|
97
|
-
switch (normalizedEncoding) {
|
|
98
|
-
case "gzip":
|
|
99
|
-
case "x-gzip": return new CompressionStream("gzip");
|
|
100
|
-
case "deflate":
|
|
101
|
-
case "x-deflate": return new CompressionStream("deflate");
|
|
102
|
-
case "zstd":
|
|
103
|
-
case "x-zstd": return new CompressionStream("zstd");
|
|
104
|
-
case "br": return new CompressionStream("brotli");
|
|
105
|
-
case "identity": return new TransformStream();
|
|
106
|
-
default: throw new TypeError(`Unsupported content-encoding: "${normalizedEncoding}"`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
export { createDecoders, createEncoders, decodeStream, encodeStream };
|