@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.
Files changed (142) hide show
  1. package/README.md +143 -50
  2. package/bun.lock +68 -0
  3. package/examples/custom-proxy-client.ts +32 -0
  4. package/examples/http-client.ts +47 -0
  5. package/examples/proxy.ts +16 -0
  6. package/examples/simple.ts +15 -0
  7. package/package.json +25 -30
  8. package/src/_internal/consts.ts +3 -0
  9. package/{_internal/decode-stream-error.d.cts → src/_internal/decode-stream-error.ts} +7 -2
  10. package/src/_internal/error-mapping.ts +160 -0
  11. package/src/_internal/guards.ts +78 -0
  12. package/src/_internal/net.ts +173 -0
  13. package/src/_internal/promises.ts +22 -0
  14. package/src/_internal/streams.ts +52 -0
  15. package/src/_internal/symbols.ts +1 -0
  16. package/src/agent-pool.ts +157 -0
  17. package/src/agent.ts +408 -0
  18. package/src/body.ts +179 -0
  19. package/src/dialers/index.ts +3 -0
  20. package/src/dialers/proxy.ts +102 -0
  21. package/src/dialers/tcp.ts +162 -0
  22. package/src/encoding.ts +222 -0
  23. package/src/errors.ts +357 -0
  24. package/src/fetch.ts +626 -0
  25. package/src/http-client.ts +111 -0
  26. package/src/index.ts +14 -0
  27. package/src/io/_utils.ts +82 -0
  28. package/src/io/buf-writer.ts +183 -0
  29. package/src/io/io.ts +322 -0
  30. package/src/io/readers.ts +576 -0
  31. package/src/io/writers.ts +331 -0
  32. package/{types/agent.d.cts → src/types/agent.ts} +47 -21
  33. package/{types/dialer.d.cts → src/types/dialer.ts} +19 -9
  34. package/src/types/index.ts +2 -0
  35. package/tests/agent-pool.test.ts +111 -0
  36. package/tests/agent.test.ts +134 -0
  37. package/tests/body.test.ts +228 -0
  38. package/tests/errors.test.ts +152 -0
  39. package/tests/fetch.test.ts +421 -0
  40. package/tests/io-options.test.ts +127 -0
  41. package/tests/multipart.test.ts +348 -0
  42. package/tests/test-utils.ts +335 -0
  43. package/tsconfig.json +15 -0
  44. package/LICENSE +0 -21
  45. package/_internal/consts.cjs +0 -4
  46. package/_internal/consts.d.cts +0 -3
  47. package/_internal/consts.d.ts +0 -3
  48. package/_internal/consts.js +0 -4
  49. package/_internal/decode-stream-error.cjs +0 -18
  50. package/_internal/decode-stream-error.d.ts +0 -11
  51. package/_internal/decode-stream-error.js +0 -18
  52. package/_internal/error-mapping.cjs +0 -44
  53. package/_internal/error-mapping.d.cts +0 -15
  54. package/_internal/error-mapping.d.ts +0 -15
  55. package/_internal/error-mapping.js +0 -41
  56. package/_internal/guards.cjs +0 -23
  57. package/_internal/guards.d.cts +0 -15
  58. package/_internal/guards.d.ts +0 -15
  59. package/_internal/guards.js +0 -15
  60. package/_internal/net.cjs +0 -95
  61. package/_internal/net.d.cts +0 -11
  62. package/_internal/net.d.ts +0 -11
  63. package/_internal/net.js +0 -92
  64. package/_internal/promises.cjs +0 -18
  65. package/_internal/promises.d.cts +0 -1
  66. package/_internal/promises.d.ts +0 -1
  67. package/_internal/promises.js +0 -18
  68. package/_internal/streams.cjs +0 -37
  69. package/_internal/streams.d.cts +0 -21
  70. package/_internal/streams.d.ts +0 -21
  71. package/_internal/streams.js +0 -36
  72. package/_internal/symbols.cjs +0 -4
  73. package/_internal/symbols.d.cts +0 -1
  74. package/_internal/symbols.d.ts +0 -1
  75. package/_internal/symbols.js +0 -4
  76. package/_virtual/_rolldown/runtime.cjs +0 -23
  77. package/agent-pool.cjs +0 -96
  78. package/agent-pool.d.cts +0 -2
  79. package/agent-pool.d.ts +0 -2
  80. package/agent-pool.js +0 -95
  81. package/agent.cjs +0 -260
  82. package/agent.d.cts +0 -3
  83. package/agent.d.ts +0 -3
  84. package/agent.js +0 -259
  85. package/body.cjs +0 -105
  86. package/body.d.cts +0 -12
  87. package/body.d.ts +0 -12
  88. package/body.js +0 -102
  89. package/dialers/index.d.cts +0 -3
  90. package/dialers/index.d.ts +0 -3
  91. package/dialers/proxy.cjs +0 -56
  92. package/dialers/proxy.d.cts +0 -27
  93. package/dialers/proxy.d.ts +0 -27
  94. package/dialers/proxy.js +0 -55
  95. package/dialers/tcp.cjs +0 -92
  96. package/dialers/tcp.d.cts +0 -57
  97. package/dialers/tcp.d.ts +0 -57
  98. package/dialers/tcp.js +0 -89
  99. package/encoding.cjs +0 -114
  100. package/encoding.d.cts +0 -35
  101. package/encoding.d.ts +0 -35
  102. package/encoding.js +0 -110
  103. package/errors.cjs +0 -275
  104. package/errors.d.cts +0 -110
  105. package/errors.d.ts +0 -110
  106. package/errors.js +0 -259
  107. package/fetch.cjs +0 -353
  108. package/fetch.d.cts +0 -58
  109. package/fetch.d.ts +0 -58
  110. package/fetch.js +0 -350
  111. package/http-client.cjs +0 -75
  112. package/http-client.d.cts +0 -39
  113. package/http-client.d.ts +0 -39
  114. package/http-client.js +0 -75
  115. package/index.cjs +0 -49
  116. package/index.d.cts +0 -14
  117. package/index.d.ts +0 -14
  118. package/index.js +0 -11
  119. package/io/_utils.cjs +0 -56
  120. package/io/_utils.d.cts +0 -10
  121. package/io/_utils.d.ts +0 -10
  122. package/io/_utils.js +0 -51
  123. package/io/buf-writer.cjs +0 -149
  124. package/io/buf-writer.d.cts +0 -13
  125. package/io/buf-writer.d.ts +0 -13
  126. package/io/buf-writer.js +0 -148
  127. package/io/io.cjs +0 -199
  128. package/io/io.d.cts +0 -5
  129. package/io/io.d.ts +0 -5
  130. package/io/io.js +0 -198
  131. package/io/readers.cjs +0 -337
  132. package/io/readers.d.cts +0 -69
  133. package/io/readers.d.ts +0 -69
  134. package/io/readers.js +0 -333
  135. package/io/writers.cjs +0 -196
  136. package/io/writers.d.cts +0 -22
  137. package/io/writers.d.ts +0 -22
  138. package/io/writers.js +0 -195
  139. package/types/agent.d.ts +0 -72
  140. package/types/dialer.d.ts +0 -30
  141. package/types/index.d.cts +0 -2
  142. package/types/index.d.ts +0 -2
package/io/io.cjs DELETED
@@ -1,199 +0,0 @@
1
- const require_streams = require("../_internal/streams.cjs");
2
- const require_encoding = require("../encoding.cjs");
3
- const require__utils = require("./_utils.cjs");
4
- const require_readers = require("./readers.cjs");
5
- const require_writers = require("./writers.cjs");
6
- //#region src/io/io.ts
7
- function parseStatusLine(line) {
8
- const m = /^HTTP\/(\d+)\.(\d+)\s+(\d{3})(?:\s+(.*))?$/.exec(line);
9
- if (!m) throw new Error(`Invalid HTTP status line: ${line}`);
10
- const major = Number(m[1]);
11
- const minor = Number(m[2]);
12
- const status = Number(m[3]);
13
- if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(status)) throw new Error(`Invalid HTTP status line: ${line}`);
14
- return {
15
- major,
16
- minor,
17
- status,
18
- statusText: m[4] ?? ""
19
- };
20
- }
21
- function toArrayBufferBytes(bytes) {
22
- if (bytes.buffer instanceof ArrayBuffer) return bytes;
23
- return new Uint8Array(bytes);
24
- }
25
- function wrapStreamErrors(source, mapError) {
26
- const reader = source.getReader();
27
- let pending = null;
28
- return new ReadableStream({
29
- type: "bytes",
30
- async pull(controller) {
31
- try {
32
- const byob = controller.byobRequest;
33
- if (byob?.view) {
34
- const target = new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength);
35
- if (target.byteLength === 0) {
36
- byob.respond(0);
37
- return;
38
- }
39
- let written = 0;
40
- if (pending && pending.byteLength > 0) {
41
- const n = Math.min(target.byteLength, pending.byteLength);
42
- target.set(pending.subarray(0, n), written);
43
- written += n;
44
- pending = n === pending.byteLength ? null : pending.subarray(n);
45
- }
46
- while (written === 0) {
47
- const { done, value } = await reader.read();
48
- if (done) {
49
- byob.respond(0);
50
- controller.close();
51
- return;
52
- }
53
- if (!value || value.byteLength === 0) continue;
54
- const n = Math.min(target.byteLength - written, value.byteLength);
55
- target.set(value.subarray(0, n), written);
56
- written += n;
57
- if (n < value.byteLength) pending = value.subarray(n);
58
- }
59
- byob.respond(written);
60
- return;
61
- }
62
- if (pending && pending.byteLength > 0) {
63
- const chunk = pending;
64
- pending = null;
65
- controller.enqueue(toArrayBufferBytes(chunk));
66
- return;
67
- }
68
- const { done, value } = await reader.read();
69
- if (done) {
70
- controller.close();
71
- return;
72
- }
73
- if (value && value.byteLength > 0) controller.enqueue(toArrayBufferBytes(value));
74
- } catch (error) {
75
- controller.error(mapError(error));
76
- }
77
- },
78
- async cancel(reason) {
79
- pending = null;
80
- await reader.cancel(reason);
81
- }
82
- });
83
- }
84
- async function readResponse(conn, options = {}, shouldIgnoreBody, onDone, mapBodyError) {
85
- const lr = new require_readers.LineReader(conn, options);
86
- const finalize = (() => {
87
- let called = false;
88
- return (reusable) => {
89
- if (called) return;
90
- called = true;
91
- queueMicrotask(() => onDone?.(reusable));
92
- };
93
- })();
94
- let statusLine;
95
- let headers;
96
- for (;;) {
97
- const line = await lr.readLine();
98
- if (line === null) throw new Error("Unexpected EOF while reading status line");
99
- const parsed = parseStatusLine(line);
100
- const hdrs = await lr.readHeaders(options);
101
- if (parsed.status >= 100 && parsed.status < 200) {
102
- if (parsed.status === 101) throw new Error("HTTP/1.1 protocol upgrades not supported");
103
- continue;
104
- }
105
- statusLine = parsed;
106
- headers = hdrs;
107
- break;
108
- }
109
- const { major, minor, status, statusText } = statusLine;
110
- const connectionTokens = require__utils.splitTokens(headers.get("connection"));
111
- const hasClose = connectionTokens.includes("close");
112
- const hasKeepAlive = connectionTokens.includes("keep-alive");
113
- const keepAliveOk = !(major === 1 && minor === 0) || hasKeepAlive;
114
- const ignoreBody = shouldIgnoreBody(status);
115
- const te = require__utils.parseTransferEncoding(headers);
116
- let chunked = false;
117
- let contentLength = null;
118
- if (!ignoreBody) if (te.has) {
119
- chunked = te.chunked;
120
- contentLength = null;
121
- headers.delete("content-length");
122
- } else {
123
- chunked = false;
124
- contentLength = require__utils.parseContentLength(headers);
125
- }
126
- const reusable = keepAliveOk && !hasClose && (ignoreBody || chunked || contentLength != null);
127
- if (ignoreBody) {
128
- finalize(reusable);
129
- return new Response(null, {
130
- status,
131
- statusText,
132
- headers
133
- });
134
- }
135
- if (chunked) headers.delete("content-length");
136
- const reader = chunked ? new require_readers.ChunkedBodyReader(lr, options) : new require_readers.BodyReader(lr, contentLength, options);
137
- let body = new ReadableStream({
138
- type: "bytes",
139
- async pull(controller) {
140
- const byob = controller.byobRequest;
141
- const view = byob?.view ? new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength) : new Uint8Array(new ArrayBuffer(options.readChunkSize ?? 16 * 1024));
142
- try {
143
- const n = await reader.read(view);
144
- if (n === 0) {
145
- byob?.respond(0);
146
- controller.close();
147
- finalize(reusable);
148
- return;
149
- }
150
- if (byob) byob.respond(n);
151
- else controller.enqueue(view.subarray(0, n));
152
- } catch (err) {
153
- controller.error(err);
154
- finalize(false);
155
- }
156
- },
157
- cancel() {
158
- finalize(false);
159
- }
160
- });
161
- try {
162
- if (te.has && te.codings.length > 0) {
163
- const decodedTe = require_encoding.decodeStream(body, te.codings);
164
- if (decodedTe !== body) {
165
- if (te.chunked) headers.set("transfer-encoding", "chunked");
166
- else headers.delete("transfer-encoding");
167
- headers.delete("content-length");
168
- }
169
- body = decodedTe;
170
- }
171
- const decompress = options.decompress !== false;
172
- const contentEncoding = headers.get("content-encoding") ?? void 0;
173
- if (decompress && contentEncoding) {
174
- const decodedCe = require_encoding.decodeStream(body, contentEncoding);
175
- if (decodedCe !== body) {
176
- headers.delete("content-encoding");
177
- headers.delete("content-length");
178
- }
179
- body = decodedCe;
180
- }
181
- const maxDecoded = require__utils.parseMaxBytes(options.maxDecodedBodySize);
182
- if (maxDecoded != null) body = body.pipeThrough(new require_streams.MaxBytesTransformStream(maxDecoded));
183
- if (mapBodyError != null) body = wrapStreamErrors(body, mapBodyError);
184
- } catch (err) {
185
- finalize(false);
186
- throw err;
187
- }
188
- return new Response(body, {
189
- status,
190
- statusText,
191
- headers
192
- });
193
- }
194
- async function writeRequest(conn, req, options = {}) {
195
- await require_writers.createRequestWriter(conn, options).write(req);
196
- }
197
- //#endregion
198
- exports.readResponse = readResponse;
199
- exports.writeRequest = writeRequest;
package/io/io.d.cts DELETED
@@ -1,5 +0,0 @@
1
- import { IConnection } from '@fuman/net';
2
- import { LineReader, Readers } from './readers';
3
- import { Writers } from './writers';
4
- export declare function readResponse(conn: IConnection<unknown>, options: (Readers.Options & LineReader.ReadHeadersOptions) | undefined, shouldIgnoreBody: (status: number) => boolean, onDone?: (reusable: boolean) => void, mapBodyError?: (err: unknown) => unknown): Promise<Response>;
5
- export declare function writeRequest(conn: IConnection<unknown>, req: Writers.Request, options?: Writers.Options): Promise<void>;
package/io/io.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { IConnection } from '@fuman/net';
2
- import { LineReader, Readers } from './readers';
3
- import { Writers } from './writers';
4
- export declare function readResponse(conn: IConnection<unknown>, options: (Readers.Options & LineReader.ReadHeadersOptions) | undefined, shouldIgnoreBody: (status: number) => boolean, onDone?: (reusable: boolean) => void, mapBodyError?: (err: unknown) => unknown): Promise<Response>;
5
- export declare function writeRequest(conn: IConnection<unknown>, req: Writers.Request, options?: Writers.Options): Promise<void>;
package/io/io.js DELETED
@@ -1,198 +0,0 @@
1
- import { MaxBytesTransformStream } from "../_internal/streams.js";
2
- import { decodeStream } from "../encoding.js";
3
- import { parseContentLength, parseMaxBytes, parseTransferEncoding, splitTokens } from "./_utils.js";
4
- import { BodyReader, ChunkedBodyReader, LineReader } from "./readers.js";
5
- import { createRequestWriter } from "./writers.js";
6
- //#region src/io/io.ts
7
- function parseStatusLine(line) {
8
- const m = /^HTTP\/(\d+)\.(\d+)\s+(\d{3})(?:\s+(.*))?$/.exec(line);
9
- if (!m) throw new Error(`Invalid HTTP status line: ${line}`);
10
- const major = Number(m[1]);
11
- const minor = Number(m[2]);
12
- const status = Number(m[3]);
13
- if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(status)) throw new Error(`Invalid HTTP status line: ${line}`);
14
- return {
15
- major,
16
- minor,
17
- status,
18
- statusText: m[4] ?? ""
19
- };
20
- }
21
- function toArrayBufferBytes(bytes) {
22
- if (bytes.buffer instanceof ArrayBuffer) return bytes;
23
- return new Uint8Array(bytes);
24
- }
25
- function wrapStreamErrors(source, mapError) {
26
- const reader = source.getReader();
27
- let pending = null;
28
- return new ReadableStream({
29
- type: "bytes",
30
- async pull(controller) {
31
- try {
32
- const byob = controller.byobRequest;
33
- if (byob?.view) {
34
- const target = new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength);
35
- if (target.byteLength === 0) {
36
- byob.respond(0);
37
- return;
38
- }
39
- let written = 0;
40
- if (pending && pending.byteLength > 0) {
41
- const n = Math.min(target.byteLength, pending.byteLength);
42
- target.set(pending.subarray(0, n), written);
43
- written += n;
44
- pending = n === pending.byteLength ? null : pending.subarray(n);
45
- }
46
- while (written === 0) {
47
- const { done, value } = await reader.read();
48
- if (done) {
49
- byob.respond(0);
50
- controller.close();
51
- return;
52
- }
53
- if (!value || value.byteLength === 0) continue;
54
- const n = Math.min(target.byteLength - written, value.byteLength);
55
- target.set(value.subarray(0, n), written);
56
- written += n;
57
- if (n < value.byteLength) pending = value.subarray(n);
58
- }
59
- byob.respond(written);
60
- return;
61
- }
62
- if (pending && pending.byteLength > 0) {
63
- const chunk = pending;
64
- pending = null;
65
- controller.enqueue(toArrayBufferBytes(chunk));
66
- return;
67
- }
68
- const { done, value } = await reader.read();
69
- if (done) {
70
- controller.close();
71
- return;
72
- }
73
- if (value && value.byteLength > 0) controller.enqueue(toArrayBufferBytes(value));
74
- } catch (error) {
75
- controller.error(mapError(error));
76
- }
77
- },
78
- async cancel(reason) {
79
- pending = null;
80
- await reader.cancel(reason);
81
- }
82
- });
83
- }
84
- async function readResponse(conn, options = {}, shouldIgnoreBody, onDone, mapBodyError) {
85
- const lr = new LineReader(conn, options);
86
- const finalize = (() => {
87
- let called = false;
88
- return (reusable) => {
89
- if (called) return;
90
- called = true;
91
- queueMicrotask(() => onDone?.(reusable));
92
- };
93
- })();
94
- let statusLine;
95
- let headers;
96
- for (;;) {
97
- const line = await lr.readLine();
98
- if (line === null) throw new Error("Unexpected EOF while reading status line");
99
- const parsed = parseStatusLine(line);
100
- const hdrs = await lr.readHeaders(options);
101
- if (parsed.status >= 100 && parsed.status < 200) {
102
- if (parsed.status === 101) throw new Error("HTTP/1.1 protocol upgrades not supported");
103
- continue;
104
- }
105
- statusLine = parsed;
106
- headers = hdrs;
107
- break;
108
- }
109
- const { major, minor, status, statusText } = statusLine;
110
- const connectionTokens = splitTokens(headers.get("connection"));
111
- const hasClose = connectionTokens.includes("close");
112
- const hasKeepAlive = connectionTokens.includes("keep-alive");
113
- const keepAliveOk = !(major === 1 && minor === 0) || hasKeepAlive;
114
- const ignoreBody = shouldIgnoreBody(status);
115
- const te = parseTransferEncoding(headers);
116
- let chunked = false;
117
- let contentLength = null;
118
- if (!ignoreBody) if (te.has) {
119
- chunked = te.chunked;
120
- contentLength = null;
121
- headers.delete("content-length");
122
- } else {
123
- chunked = false;
124
- contentLength = parseContentLength(headers);
125
- }
126
- const reusable = keepAliveOk && !hasClose && (ignoreBody || chunked || contentLength != null);
127
- if (ignoreBody) {
128
- finalize(reusable);
129
- return new Response(null, {
130
- status,
131
- statusText,
132
- headers
133
- });
134
- }
135
- if (chunked) headers.delete("content-length");
136
- const reader = chunked ? new ChunkedBodyReader(lr, options) : new BodyReader(lr, contentLength, options);
137
- let body = new ReadableStream({
138
- type: "bytes",
139
- async pull(controller) {
140
- const byob = controller.byobRequest;
141
- const view = byob?.view ? new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength) : new Uint8Array(new ArrayBuffer(options.readChunkSize ?? 16 * 1024));
142
- try {
143
- const n = await reader.read(view);
144
- if (n === 0) {
145
- byob?.respond(0);
146
- controller.close();
147
- finalize(reusable);
148
- return;
149
- }
150
- if (byob) byob.respond(n);
151
- else controller.enqueue(view.subarray(0, n));
152
- } catch (err) {
153
- controller.error(err);
154
- finalize(false);
155
- }
156
- },
157
- cancel() {
158
- finalize(false);
159
- }
160
- });
161
- try {
162
- if (te.has && te.codings.length > 0) {
163
- const decodedTe = decodeStream(body, te.codings);
164
- if (decodedTe !== body) {
165
- if (te.chunked) headers.set("transfer-encoding", "chunked");
166
- else headers.delete("transfer-encoding");
167
- headers.delete("content-length");
168
- }
169
- body = decodedTe;
170
- }
171
- const decompress = options.decompress !== false;
172
- const contentEncoding = headers.get("content-encoding") ?? void 0;
173
- if (decompress && contentEncoding) {
174
- const decodedCe = decodeStream(body, contentEncoding);
175
- if (decodedCe !== body) {
176
- headers.delete("content-encoding");
177
- headers.delete("content-length");
178
- }
179
- body = decodedCe;
180
- }
181
- const maxDecoded = parseMaxBytes(options.maxDecodedBodySize);
182
- if (maxDecoded != null) body = body.pipeThrough(new MaxBytesTransformStream(maxDecoded));
183
- if (mapBodyError != null) body = wrapStreamErrors(body, mapBodyError);
184
- } catch (err) {
185
- finalize(false);
186
- throw err;
187
- }
188
- return new Response(body, {
189
- status,
190
- statusText,
191
- headers
192
- });
193
- }
194
- async function writeRequest(conn, req, options = {}) {
195
- await createRequestWriter(conn, options).write(req);
196
- }
197
- //#endregion
198
- export { readResponse, writeRequest };