@whatwg-node/node-fetch 0.7.25-alpha-20250729225623-2377d384db01c30592dffc1bb6248bc3baa4502c → 0.7.25-alpha-20250730124646-a1e5ae5dfafa7af8bcc74e671579aea5eb5e4349

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.
@@ -20,133 +20,131 @@ function getRequestFnForProtocol(url) {
20
20
  throw new Error(`Unsupported protocol: ${url.split(':')[0] || url}`);
21
21
  }
22
22
  function fetchNodeHttp(fetchRequest) {
23
- return new Promise((resolve, reject) => {
24
- try {
25
- const requestFn = getRequestFnForProtocol(fetchRequest.parsedUrl?.protocol || fetchRequest.url);
26
- const headersSerializer = fetchRequest.headersSerializer || utils_js_1.getHeadersObj;
27
- const nodeHeaders = headersSerializer(fetchRequest.headers);
28
- if (nodeHeaders['accept-encoding'] == null) {
29
- nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
30
- }
31
- let signal;
32
- if (fetchRequest._signal == null) {
33
- signal = undefined;
34
- }
35
- else if (fetchRequest._signal) {
36
- signal = fetchRequest._signal;
37
- }
38
- let nodeRequest;
39
- // If it is our ponyfilled Request, it should have `parsedUrl` which is a `URL` object
40
- if (fetchRequest.parsedUrl) {
41
- nodeRequest = requestFn(fetchRequest.parsedUrl, {
42
- method: fetchRequest.method,
43
- headers: nodeHeaders,
44
- signal,
45
- agent: fetchRequest.agent,
46
- });
47
- }
48
- else {
49
- nodeRequest = requestFn(fetchRequest.url, {
50
- method: fetchRequest.method,
51
- headers: nodeHeaders,
52
- signal,
53
- agent: fetchRequest.agent,
54
- });
23
+ const deferred = (0, promise_helpers_1.createDeferredPromise)();
24
+ try {
25
+ const requestFn = getRequestFnForProtocol(fetchRequest.parsedUrl?.protocol || fetchRequest.url);
26
+ const headersSerializer = fetchRequest.headersSerializer || utils_js_1.getHeadersObj;
27
+ const nodeHeaders = headersSerializer(fetchRequest.headers);
28
+ if (nodeHeaders['accept-encoding'] == null) {
29
+ nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
30
+ }
31
+ let signal;
32
+ if (fetchRequest._signal == null) {
33
+ signal = undefined;
34
+ }
35
+ else if (fetchRequest._signal) {
36
+ signal = fetchRequest._signal;
37
+ }
38
+ let nodeRequest;
39
+ // If it is our ponyfilled Request, it should have `parsedUrl` which is a `URL` object
40
+ if (fetchRequest.parsedUrl) {
41
+ nodeRequest = requestFn(fetchRequest.parsedUrl, {
42
+ method: fetchRequest.method,
43
+ headers: nodeHeaders,
44
+ signal,
45
+ agent: fetchRequest.agent,
46
+ });
47
+ }
48
+ else {
49
+ nodeRequest = requestFn(fetchRequest.url, {
50
+ method: fetchRequest.method,
51
+ headers: nodeHeaders,
52
+ signal,
53
+ agent: fetchRequest.agent,
54
+ });
55
+ }
56
+ nodeRequest.once('error', e => deferred.reject(e));
57
+ nodeRequest.once('response', nodeResponse => {
58
+ let outputStream;
59
+ const contentEncoding = nodeResponse.headers['content-encoding'];
60
+ switch (contentEncoding) {
61
+ case 'x-gzip':
62
+ case 'gzip':
63
+ outputStream = (0, node_zlib_1.createGunzip)();
64
+ break;
65
+ case 'x-deflate':
66
+ case 'deflate':
67
+ outputStream = (0, node_zlib_1.createInflate)();
68
+ break;
69
+ case 'x-deflate-raw':
70
+ case 'deflate-raw':
71
+ outputStream = (0, node_zlib_1.createInflateRaw)();
72
+ break;
73
+ case 'br':
74
+ outputStream = (0, node_zlib_1.createBrotliDecompress)();
75
+ break;
55
76
  }
56
- nodeRequest.once('error', reject);
57
- nodeRequest.once('response', nodeResponse => {
58
- let outputStream;
59
- const contentEncoding = nodeResponse.headers['content-encoding'];
60
- switch (contentEncoding) {
61
- case 'x-gzip':
62
- case 'gzip':
63
- outputStream = (0, node_zlib_1.createGunzip)();
64
- break;
65
- case 'x-deflate':
66
- case 'deflate':
67
- outputStream = (0, node_zlib_1.createInflate)();
68
- break;
69
- case 'x-deflate-raw':
70
- case 'deflate-raw':
71
- outputStream = (0, node_zlib_1.createInflateRaw)();
72
- break;
73
- case 'br':
74
- outputStream = (0, node_zlib_1.createBrotliDecompress)();
75
- break;
77
+ if (nodeResponse.headers.location && (0, utils_js_1.shouldRedirect)(nodeResponse.statusCode)) {
78
+ if (fetchRequest.redirect === 'error') {
79
+ const redirectError = new Error('Redirects are not allowed');
80
+ deferred.reject(redirectError);
81
+ nodeResponse.resume();
82
+ return;
76
83
  }
77
- if (nodeResponse.headers.location && (0, utils_js_1.shouldRedirect)(nodeResponse.statusCode)) {
78
- if (fetchRequest.redirect === 'error') {
79
- const redirectError = new Error('Redirects are not allowed');
80
- reject(redirectError);
81
- nodeResponse.resume();
82
- return;
83
- }
84
- if (fetchRequest.redirect === 'follow') {
85
- const redirectedUrl = new URL_js_1.PonyfillURL(nodeResponse.headers.location, fetchRequest.parsedUrl || fetchRequest.url);
86
- const redirectResponse$ = fetchNodeHttp(new Request_js_1.PonyfillRequest(redirectedUrl, fetchRequest));
87
- resolve(redirectResponse$.then(redirectResponse => {
88
- redirectResponse.redirected = true;
89
- return redirectResponse;
90
- }));
91
- nodeResponse.resume();
92
- return;
93
- }
94
- }
95
- if (outputStream) {
96
- (0, utils_js_1.pipeThrough)({
97
- src: nodeResponse,
98
- dest: outputStream,
99
- signal,
100
- onError: e => {
101
- if (!nodeResponse.destroyed) {
102
- nodeResponse.destroy(e);
103
- }
104
- if (!outputStream.destroyed) {
105
- outputStream.destroy(e);
106
- }
107
- reject(e);
108
- },
84
+ if (fetchRequest.redirect === 'follow') {
85
+ const redirectedUrl = new URL_js_1.PonyfillURL(nodeResponse.headers.location, fetchRequest.parsedUrl || fetchRequest.url);
86
+ const redirectResponse$ = fetchNodeHttp(new Request_js_1.PonyfillRequest(redirectedUrl, fetchRequest));
87
+ redirectResponse$
88
+ .then(redirectResponse => {
89
+ redirectResponse.redirected = true;
90
+ deferred.resolve(redirectResponse);
91
+ })
92
+ .catch(e => {
93
+ deferred.reject(e);
109
94
  });
95
+ nodeResponse.resume();
96
+ return;
110
97
  }
111
- const statusCode = nodeResponse.statusCode || 200;
112
- let statusText = nodeResponse.statusMessage || node_http_1.STATUS_CODES[statusCode];
113
- if (statusText == null) {
114
- statusText = '';
115
- }
116
- const ponyfillResponse = new Response_js_1.PonyfillResponse(outputStream || nodeResponse, {
117
- status: statusCode,
118
- statusText,
119
- headers: nodeResponse.headers,
120
- url: fetchRequest.url,
98
+ }
99
+ if (outputStream) {
100
+ (0, utils_js_1.pipeThrough)({
101
+ src: nodeResponse,
102
+ dest: outputStream,
121
103
  signal,
104
+ onError: e => {
105
+ if (!nodeResponse.destroyed) {
106
+ nodeResponse.destroy(e);
107
+ }
108
+ if (!outputStream.destroyed) {
109
+ outputStream.destroy(e);
110
+ }
111
+ deferred.reject(e);
112
+ },
122
113
  });
123
- finalizationRegistry.register(ponyfillResponse, nodeResponse);
124
- resolve(ponyfillResponse);
114
+ }
115
+ const statusCode = nodeResponse.statusCode || 200;
116
+ let statusText = nodeResponse.statusMessage || node_http_1.STATUS_CODES[statusCode];
117
+ if (statusText == null) {
118
+ statusText = '';
119
+ }
120
+ const ponyfillResponse = new Response_js_1.PonyfillResponse(outputStream || nodeResponse, {
121
+ status: statusCode,
122
+ statusText,
123
+ headers: nodeResponse.headers,
124
+ url: fetchRequest.url,
125
+ signal,
125
126
  });
126
- if (fetchRequest['_buffer'] != null) {
127
- (0, promise_helpers_1.handleMaybePromise)(() => (0, utils_js_1.safeWrite)(fetchRequest['_buffer'], nodeRequest), () => (0, utils_js_1.endStream)(nodeRequest), reject);
127
+ deferred.resolve(ponyfillResponse);
128
+ });
129
+ if (fetchRequest['_buffer'] != null) {
130
+ (0, promise_helpers_1.handleMaybePromise)(() => (0, utils_js_1.safeWrite)(fetchRequest['_buffer'], nodeRequest), () => (0, utils_js_1.endStream)(nodeRequest), e => deferred.reject(e));
131
+ }
132
+ else {
133
+ const nodeReadable = (fetchRequest.body != null
134
+ ? (0, utils_js_1.isNodeReadable)(fetchRequest.body)
135
+ ? fetchRequest.body
136
+ : node_stream_1.Readable.from(fetchRequest.body)
137
+ : null);
138
+ if (nodeReadable) {
139
+ nodeReadable.pipe(nodeRequest);
128
140
  }
129
141
  else {
130
- const nodeReadable = (fetchRequest.body != null
131
- ? (0, utils_js_1.isNodeReadable)(fetchRequest.body)
132
- ? fetchRequest.body
133
- : node_stream_1.Readable.from(fetchRequest.body)
134
- : null);
135
- if (nodeReadable) {
136
- nodeReadable.pipe(nodeRequest);
137
- }
138
- else {
139
- (0, utils_js_1.endStream)(nodeRequest);
140
- }
142
+ (0, utils_js_1.endStream)(nodeRequest);
141
143
  }
142
144
  }
143
- catch (e) {
144
- reject(e);
145
- }
146
- });
147
- }
148
- const finalizationRegistry = new FinalizationRegistry(incomingMessage => {
149
- if (!incomingMessage.destroyed) {
150
- incomingMessage.destroy();
151
145
  }
152
- });
146
+ catch (e) {
147
+ deferred.reject(e);
148
+ }
149
+ return deferred.promise;
150
+ }
package/cjs/utils.js CHANGED
@@ -10,7 +10,6 @@ exports.shouldRedirect = shouldRedirect;
10
10
  exports.pipeThrough = pipeThrough;
11
11
  exports.endStream = endStream;
12
12
  exports.safeWrite = safeWrite;
13
- const node_events_1 = require("node:events");
14
13
  function isHeadersInstance(obj) {
15
14
  return obj?.forEach != null;
16
15
  }
@@ -99,7 +98,9 @@ function endStream(stream) {
99
98
  function safeWrite(chunk, stream) {
100
99
  const result = stream.write(chunk);
101
100
  if (!result) {
102
- return (0, node_events_1.once)(stream, 'drain');
101
+ return new Promise(resolve => {
102
+ stream.once('drain', resolve);
103
+ });
103
104
  }
104
105
  }
105
106
  // https://github.com/nodejs/node/blob/f692878dec6354c0a82241f224906981861bc840/lib/internal/errors.js#L961-L973
@@ -2,7 +2,7 @@ import { request as httpRequest, STATUS_CODES } from 'node:http';
2
2
  import { request as httpsRequest } from 'node:https';
3
3
  import { Readable } from 'node:stream';
4
4
  import { createBrotliDecompress, createGunzip, createInflate, createInflateRaw } from 'node:zlib';
5
- import { handleMaybePromise } from '@whatwg-node/promise-helpers';
5
+ import { createDeferredPromise, handleMaybePromise } from '@whatwg-node/promise-helpers';
6
6
  import { PonyfillRequest } from './Request.js';
7
7
  import { PonyfillResponse } from './Response.js';
8
8
  import { PonyfillURL } from './URL.js';
@@ -17,133 +17,131 @@ function getRequestFnForProtocol(url) {
17
17
  throw new Error(`Unsupported protocol: ${url.split(':')[0] || url}`);
18
18
  }
19
19
  export function fetchNodeHttp(fetchRequest) {
20
- return new Promise((resolve, reject) => {
21
- try {
22
- const requestFn = getRequestFnForProtocol(fetchRequest.parsedUrl?.protocol || fetchRequest.url);
23
- const headersSerializer = fetchRequest.headersSerializer || getHeadersObj;
24
- const nodeHeaders = headersSerializer(fetchRequest.headers);
25
- if (nodeHeaders['accept-encoding'] == null) {
26
- nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
27
- }
28
- let signal;
29
- if (fetchRequest._signal == null) {
30
- signal = undefined;
31
- }
32
- else if (fetchRequest._signal) {
33
- signal = fetchRequest._signal;
34
- }
35
- let nodeRequest;
36
- // If it is our ponyfilled Request, it should have `parsedUrl` which is a `URL` object
37
- if (fetchRequest.parsedUrl) {
38
- nodeRequest = requestFn(fetchRequest.parsedUrl, {
39
- method: fetchRequest.method,
40
- headers: nodeHeaders,
41
- signal,
42
- agent: fetchRequest.agent,
43
- });
44
- }
45
- else {
46
- nodeRequest = requestFn(fetchRequest.url, {
47
- method: fetchRequest.method,
48
- headers: nodeHeaders,
49
- signal,
50
- agent: fetchRequest.agent,
51
- });
20
+ const deferred = createDeferredPromise();
21
+ try {
22
+ const requestFn = getRequestFnForProtocol(fetchRequest.parsedUrl?.protocol || fetchRequest.url);
23
+ const headersSerializer = fetchRequest.headersSerializer || getHeadersObj;
24
+ const nodeHeaders = headersSerializer(fetchRequest.headers);
25
+ if (nodeHeaders['accept-encoding'] == null) {
26
+ nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
27
+ }
28
+ let signal;
29
+ if (fetchRequest._signal == null) {
30
+ signal = undefined;
31
+ }
32
+ else if (fetchRequest._signal) {
33
+ signal = fetchRequest._signal;
34
+ }
35
+ let nodeRequest;
36
+ // If it is our ponyfilled Request, it should have `parsedUrl` which is a `URL` object
37
+ if (fetchRequest.parsedUrl) {
38
+ nodeRequest = requestFn(fetchRequest.parsedUrl, {
39
+ method: fetchRequest.method,
40
+ headers: nodeHeaders,
41
+ signal,
42
+ agent: fetchRequest.agent,
43
+ });
44
+ }
45
+ else {
46
+ nodeRequest = requestFn(fetchRequest.url, {
47
+ method: fetchRequest.method,
48
+ headers: nodeHeaders,
49
+ signal,
50
+ agent: fetchRequest.agent,
51
+ });
52
+ }
53
+ nodeRequest.once('error', e => deferred.reject(e));
54
+ nodeRequest.once('response', nodeResponse => {
55
+ let outputStream;
56
+ const contentEncoding = nodeResponse.headers['content-encoding'];
57
+ switch (contentEncoding) {
58
+ case 'x-gzip':
59
+ case 'gzip':
60
+ outputStream = createGunzip();
61
+ break;
62
+ case 'x-deflate':
63
+ case 'deflate':
64
+ outputStream = createInflate();
65
+ break;
66
+ case 'x-deflate-raw':
67
+ case 'deflate-raw':
68
+ outputStream = createInflateRaw();
69
+ break;
70
+ case 'br':
71
+ outputStream = createBrotliDecompress();
72
+ break;
52
73
  }
53
- nodeRequest.once('error', reject);
54
- nodeRequest.once('response', nodeResponse => {
55
- let outputStream;
56
- const contentEncoding = nodeResponse.headers['content-encoding'];
57
- switch (contentEncoding) {
58
- case 'x-gzip':
59
- case 'gzip':
60
- outputStream = createGunzip();
61
- break;
62
- case 'x-deflate':
63
- case 'deflate':
64
- outputStream = createInflate();
65
- break;
66
- case 'x-deflate-raw':
67
- case 'deflate-raw':
68
- outputStream = createInflateRaw();
69
- break;
70
- case 'br':
71
- outputStream = createBrotliDecompress();
72
- break;
74
+ if (nodeResponse.headers.location && shouldRedirect(nodeResponse.statusCode)) {
75
+ if (fetchRequest.redirect === 'error') {
76
+ const redirectError = new Error('Redirects are not allowed');
77
+ deferred.reject(redirectError);
78
+ nodeResponse.resume();
79
+ return;
73
80
  }
74
- if (nodeResponse.headers.location && shouldRedirect(nodeResponse.statusCode)) {
75
- if (fetchRequest.redirect === 'error') {
76
- const redirectError = new Error('Redirects are not allowed');
77
- reject(redirectError);
78
- nodeResponse.resume();
79
- return;
80
- }
81
- if (fetchRequest.redirect === 'follow') {
82
- const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, fetchRequest.parsedUrl || fetchRequest.url);
83
- const redirectResponse$ = fetchNodeHttp(new PonyfillRequest(redirectedUrl, fetchRequest));
84
- resolve(redirectResponse$.then(redirectResponse => {
85
- redirectResponse.redirected = true;
86
- return redirectResponse;
87
- }));
88
- nodeResponse.resume();
89
- return;
90
- }
91
- }
92
- if (outputStream) {
93
- pipeThrough({
94
- src: nodeResponse,
95
- dest: outputStream,
96
- signal,
97
- onError: e => {
98
- if (!nodeResponse.destroyed) {
99
- nodeResponse.destroy(e);
100
- }
101
- if (!outputStream.destroyed) {
102
- outputStream.destroy(e);
103
- }
104
- reject(e);
105
- },
81
+ if (fetchRequest.redirect === 'follow') {
82
+ const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, fetchRequest.parsedUrl || fetchRequest.url);
83
+ const redirectResponse$ = fetchNodeHttp(new PonyfillRequest(redirectedUrl, fetchRequest));
84
+ redirectResponse$
85
+ .then(redirectResponse => {
86
+ redirectResponse.redirected = true;
87
+ deferred.resolve(redirectResponse);
88
+ })
89
+ .catch(e => {
90
+ deferred.reject(e);
106
91
  });
92
+ nodeResponse.resume();
93
+ return;
107
94
  }
108
- const statusCode = nodeResponse.statusCode || 200;
109
- let statusText = nodeResponse.statusMessage || STATUS_CODES[statusCode];
110
- if (statusText == null) {
111
- statusText = '';
112
- }
113
- const ponyfillResponse = new PonyfillResponse(outputStream || nodeResponse, {
114
- status: statusCode,
115
- statusText,
116
- headers: nodeResponse.headers,
117
- url: fetchRequest.url,
95
+ }
96
+ if (outputStream) {
97
+ pipeThrough({
98
+ src: nodeResponse,
99
+ dest: outputStream,
118
100
  signal,
101
+ onError: e => {
102
+ if (!nodeResponse.destroyed) {
103
+ nodeResponse.destroy(e);
104
+ }
105
+ if (!outputStream.destroyed) {
106
+ outputStream.destroy(e);
107
+ }
108
+ deferred.reject(e);
109
+ },
119
110
  });
120
- finalizationRegistry.register(ponyfillResponse, nodeResponse);
121
- resolve(ponyfillResponse);
111
+ }
112
+ const statusCode = nodeResponse.statusCode || 200;
113
+ let statusText = nodeResponse.statusMessage || STATUS_CODES[statusCode];
114
+ if (statusText == null) {
115
+ statusText = '';
116
+ }
117
+ const ponyfillResponse = new PonyfillResponse(outputStream || nodeResponse, {
118
+ status: statusCode,
119
+ statusText,
120
+ headers: nodeResponse.headers,
121
+ url: fetchRequest.url,
122
+ signal,
122
123
  });
123
- if (fetchRequest['_buffer'] != null) {
124
- handleMaybePromise(() => safeWrite(fetchRequest['_buffer'], nodeRequest), () => endStream(nodeRequest), reject);
124
+ deferred.resolve(ponyfillResponse);
125
+ });
126
+ if (fetchRequest['_buffer'] != null) {
127
+ handleMaybePromise(() => safeWrite(fetchRequest['_buffer'], nodeRequest), () => endStream(nodeRequest), e => deferred.reject(e));
128
+ }
129
+ else {
130
+ const nodeReadable = (fetchRequest.body != null
131
+ ? isNodeReadable(fetchRequest.body)
132
+ ? fetchRequest.body
133
+ : Readable.from(fetchRequest.body)
134
+ : null);
135
+ if (nodeReadable) {
136
+ nodeReadable.pipe(nodeRequest);
125
137
  }
126
138
  else {
127
- const nodeReadable = (fetchRequest.body != null
128
- ? isNodeReadable(fetchRequest.body)
129
- ? fetchRequest.body
130
- : Readable.from(fetchRequest.body)
131
- : null);
132
- if (nodeReadable) {
133
- nodeReadable.pipe(nodeRequest);
134
- }
135
- else {
136
- endStream(nodeRequest);
137
- }
139
+ endStream(nodeRequest);
138
140
  }
139
141
  }
140
- catch (e) {
141
- reject(e);
142
- }
143
- });
144
- }
145
- const finalizationRegistry = new FinalizationRegistry(incomingMessage => {
146
- if (!incomingMessage.destroyed) {
147
- incomingMessage.destroy();
148
142
  }
149
- });
143
+ catch (e) {
144
+ deferred.reject(e);
145
+ }
146
+ return deferred.promise;
147
+ }
package/esm/utils.js CHANGED
@@ -1,4 +1,3 @@
1
- import { once } from 'node:events';
2
1
  function isHeadersInstance(obj) {
3
2
  return obj?.forEach != null;
4
3
  }
@@ -86,7 +85,9 @@ export function endStream(stream) {
86
85
  export function safeWrite(chunk, stream) {
87
86
  const result = stream.write(chunk);
88
87
  if (!result) {
89
- return once(stream, 'drain');
88
+ return new Promise(resolve => {
89
+ stream.once('drain', resolve);
90
+ });
90
91
  }
91
92
  }
92
93
  // https://github.com/nodejs/node/blob/f692878dec6354c0a82241f224906981861bc840/lib/internal/errors.js#L961-L973
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/node-fetch",
3
- "version": "0.7.25-alpha-20250729225623-2377d384db01c30592dffc1bb6248bc3baa4502c",
3
+ "version": "0.7.25-alpha-20250730124646-a1e5ae5dfafa7af8bcc74e671579aea5eb5e4349",
4
4
  "description": "Fetch API implementation for Node",
5
5
  "sideEffects": false,
6
6
  "dependencies": {
@@ -15,4 +15,4 @@ export declare function pipeThrough({ src, dest, signal, onError, }: {
15
15
  export declare function endStream(stream: {
16
16
  end: () => void;
17
17
  }): void;
18
- export declare function safeWrite(chunk: any, stream: Writable): Promise<any[]> | undefined;
18
+ export declare function safeWrite(chunk: any, stream: Writable): Promise<void> | undefined;
@@ -15,4 +15,4 @@ export declare function pipeThrough({ src, dest, signal, onError, }: {
15
15
  export declare function endStream(stream: {
16
16
  end: () => void;
17
17
  }): void;
18
- export declare function safeWrite(chunk: any, stream: Writable): Promise<any[]> | undefined;
18
+ export declare function safeWrite(chunk: any, stream: Writable): Promise<void> | undefined;