@whatwg-node/node-fetch 0.8.0-alpha-20241212160430-140b66f028923f44368e67598b6b66f47f690454 → 0.8.0-alpha-20250917012053-36c9ccdc3e94ee8d0961f17398a9053fa55df37b

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 (73) hide show
  1. package/cjs/AbortError.js +10 -3
  2. package/cjs/Blob.js +21 -19
  3. package/cjs/Body.js +146 -76
  4. package/cjs/FormData.js +54 -41
  5. package/cjs/Headers.js +54 -15
  6. package/cjs/ReadableStream.js +62 -26
  7. package/cjs/Request.js +9 -16
  8. package/cjs/Response.js +56 -10
  9. package/cjs/TextEncoderDecoder.js +6 -5
  10. package/cjs/TextEncoderDecoderStream.js +2 -6
  11. package/cjs/TransformStream.js +2 -1
  12. package/cjs/URL.js +10 -66
  13. package/cjs/URLSearchParams.js +1 -117
  14. package/cjs/WritableStream.js +35 -111
  15. package/cjs/fetch.js +37 -8
  16. package/cjs/fetchCurl.js +30 -61
  17. package/cjs/fetchNodeHttp.js +60 -64
  18. package/cjs/index.js +1 -7
  19. package/cjs/utils.js +76 -55
  20. package/esm/AbortError.js +10 -3
  21. package/esm/Blob.js +6 -4
  22. package/esm/Body.js +134 -63
  23. package/esm/FormData.js +54 -41
  24. package/esm/Headers.js +54 -15
  25. package/esm/ReadableStream.js +57 -21
  26. package/esm/Request.js +7 -14
  27. package/esm/Response.js +55 -9
  28. package/esm/TextEncoderDecoder.js +1 -0
  29. package/esm/TextEncoderDecoderStream.js +2 -6
  30. package/esm/TransformStream.js +2 -1
  31. package/esm/URL.js +9 -64
  32. package/esm/URLSearchParams.js +1 -115
  33. package/esm/WritableStream.js +33 -109
  34. package/esm/fetch.js +35 -6
  35. package/esm/fetchCurl.js +28 -59
  36. package/esm/fetchNodeHttp.js +55 -59
  37. package/esm/index.js +0 -3
  38. package/esm/utils.js +70 -53
  39. package/package.json +4 -5
  40. package/typings/AbortError.d.cts +2 -2
  41. package/typings/AbortError.d.ts +2 -2
  42. package/typings/Blob.d.cts +5 -4
  43. package/typings/Blob.d.ts +5 -4
  44. package/typings/Body.d.cts +11 -6
  45. package/typings/Body.d.ts +11 -6
  46. package/typings/Headers.d.cts +1 -1
  47. package/typings/Headers.d.ts +1 -1
  48. package/typings/ReadableStream.d.cts +8 -2
  49. package/typings/ReadableStream.d.ts +8 -2
  50. package/typings/Request.d.cts +9 -10
  51. package/typings/Request.d.ts +9 -10
  52. package/typings/Response.d.cts +6 -5
  53. package/typings/Response.d.ts +6 -5
  54. package/typings/TextEncoderDecoder.d.cts +2 -1
  55. package/typings/TextEncoderDecoder.d.ts +2 -1
  56. package/typings/URL.d.cts +12 -16
  57. package/typings/URL.d.ts +12 -16
  58. package/typings/URLSearchParams.d.cts +4 -21
  59. package/typings/URLSearchParams.d.ts +4 -21
  60. package/typings/WritableStream.d.cts +1 -1
  61. package/typings/WritableStream.d.ts +1 -1
  62. package/typings/index.d.cts +0 -3
  63. package/typings/index.d.ts +0 -3
  64. package/typings/utils.d.cts +13 -8
  65. package/typings/utils.d.ts +13 -8
  66. package/cjs/AbortController.js +0 -18
  67. package/cjs/AbortSignal.js +0 -92
  68. package/esm/AbortController.js +0 -14
  69. package/esm/AbortSignal.js +0 -88
  70. package/typings/AbortController.d.cts +0 -8
  71. package/typings/AbortController.d.ts +0 -8
  72. package/typings/AbortSignal.d.cts +0 -15
  73. package/typings/AbortSignal.d.ts +0 -15
@@ -1,4 +1,8 @@
1
- import { Readable } from 'stream';
1
+ import { Buffer } from 'node:buffer';
2
+ import { once } from 'node:events';
3
+ import { Readable } from 'node:stream';
4
+ import { pipeline } from 'node:stream/promises';
5
+ import { handleMaybePromise } from '@whatwg-node/promise-helpers';
2
6
  import { fakePromise } from './utils.js';
3
7
  function createController(desiredSize, readable) {
4
8
  let chunks = [];
@@ -62,20 +66,31 @@ export class PonyfillReadableStream {
62
66
  else {
63
67
  let started = false;
64
68
  let ongoing = false;
65
- const readImpl = async (desiredSize) => {
69
+ const handleStart = (desiredSize) => {
66
70
  if (!started) {
67
71
  const controller = createController(desiredSize, this.readable);
68
72
  started = true;
69
- await underlyingSource?.start?.(controller);
70
- controller._flush();
71
- if (controller._closed) {
73
+ return handleMaybePromise(() => underlyingSource?.start?.(controller), () => {
74
+ controller._flush();
75
+ if (controller._closed) {
76
+ return false;
77
+ }
78
+ return true;
79
+ });
80
+ }
81
+ return true;
82
+ };
83
+ const readImpl = (desiredSize) => {
84
+ return handleMaybePromise(() => handleStart(desiredSize), shouldContinue => {
85
+ if (!shouldContinue) {
72
86
  return;
73
87
  }
74
- }
75
- const controller = createController(desiredSize, this.readable);
76
- await underlyingSource?.pull?.(controller);
77
- controller._flush();
78
- ongoing = false;
88
+ const controller = createController(desiredSize, this.readable);
89
+ return handleMaybePromise(() => underlyingSource?.pull?.(controller), () => {
90
+ controller._flush();
91
+ ongoing = false;
92
+ });
93
+ });
79
94
  };
80
95
  this.readable = new Readable({
81
96
  read(desiredSize) {
@@ -109,12 +124,14 @@ export class PonyfillReadableStream {
109
124
  }
110
125
  cancel(reason) {
111
126
  this.readable.destroy(reason);
112
- return new Promise(resolve => this.readable.once('end', resolve));
127
+ // @ts-expect-error - we know it is void
128
+ return once(this.readable, 'close');
113
129
  }
114
130
  locked = false;
115
131
  getReader(_options) {
116
132
  const iterator = this.readable[Symbol.asyncIterator]();
117
133
  this.locked = true;
134
+ const thisReadable = this.readable;
118
135
  return {
119
136
  read() {
120
137
  return iterator.next();
@@ -141,16 +158,36 @@ export class PonyfillReadableStream {
141
158
  }
142
159
  }
143
160
  this.locked = false;
144
- return fakePromise(undefined);
161
+ return fakePromise();
162
+ },
163
+ get closed() {
164
+ return Promise.race([
165
+ once(thisReadable, 'end'),
166
+ once(thisReadable, 'error').then(err => Promise.reject(err)),
167
+ ]);
145
168
  },
146
- closed: new Promise((resolve, reject) => {
147
- this.readable.once('end', resolve);
148
- this.readable.once('error', reject);
149
- }),
150
169
  };
151
170
  }
152
171
  [Symbol.asyncIterator]() {
153
- return this.readable[Symbol.asyncIterator]();
172
+ const iterator = this.readable[Symbol.asyncIterator]();
173
+ return {
174
+ [Symbol.asyncIterator]() {
175
+ return this;
176
+ },
177
+ next: () => iterator.next(),
178
+ return: () => {
179
+ if (!this.readable.destroyed) {
180
+ this.readable.destroy();
181
+ }
182
+ return iterator.return?.() || fakePromise({ done: true, value: undefined });
183
+ },
184
+ throw: (err) => {
185
+ if (!this.readable.destroyed) {
186
+ this.readable.destroy(err);
187
+ }
188
+ return iterator.throw?.(err) || fakePromise({ done: true, value: undefined });
189
+ },
190
+ };
154
191
  }
155
192
  tee() {
156
193
  throw new Error('Not implemented');
@@ -168,10 +205,8 @@ export class PonyfillReadableStream {
168
205
  }
169
206
  pipeTo(destination) {
170
207
  if (isPonyfillWritableStream(destination)) {
171
- return new Promise((resolve, reject) => {
172
- this.readable.pipe(destination.writable);
173
- destination.writable.once('finish', resolve);
174
- destination.writable.once('error', reject);
208
+ return pipeline(this.readable, destination.writable, {
209
+ end: true,
175
210
  });
176
211
  }
177
212
  else {
@@ -196,6 +231,7 @@ export class PonyfillReadableStream {
196
231
  static from(iterable) {
197
232
  return new PonyfillReadableStream(Readable.from(iterable));
198
233
  }
234
+ [Symbol.toStringTag] = 'ReadableStream';
199
235
  }
200
236
  function isPonyfillReadableStream(obj) {
201
237
  return obj?.readable != null;
package/esm/Request.js CHANGED
@@ -1,6 +1,5 @@
1
- import { Agent as HTTPAgent } from 'http';
2
- import { Agent as HTTPSAgent } from 'https';
3
- import { PonyfillAbortController } from './AbortController.js';
1
+ import { Agent as HTTPAgent } from 'node:http';
2
+ import { Agent as HTTPSAgent } from 'node:https';
4
3
  import { PonyfillBody } from './Body.js';
5
4
  import { isHeadersLike, PonyfillHeaders } from './Headers.js';
6
5
  import { PonyfillURL } from './URL.js';
@@ -39,7 +38,7 @@ export class PonyfillRequest extends PonyfillBody {
39
38
  bodyInit = options.body || null;
40
39
  requestInit = options;
41
40
  }
42
- super(bodyInit, options);
41
+ super(bodyInit, requestInit);
43
42
  this._url = _url;
44
43
  this._parsedUrl = _parsedUrl;
45
44
  this.cache = requestInit?.cache || 'default';
@@ -55,7 +54,6 @@ export class PonyfillRequest extends PonyfillBody {
55
54
  this.redirect = requestInit?.redirect || 'follow';
56
55
  this.referrer = requestInit?.referrer || 'about:client';
57
56
  this.referrerPolicy = requestInit?.referrerPolicy || 'no-referrer';
58
- this._signal = requestInit?.signal;
59
57
  this.headersSerializer = requestInit?.headersSerializer;
60
58
  this.duplex = requestInit?.duplex || 'half';
61
59
  this.destination = 'document';
@@ -90,6 +88,10 @@ export class PonyfillRequest extends PonyfillBody {
90
88
  referrer;
91
89
  referrerPolicy;
92
90
  _url;
91
+ get signal() {
92
+ this._signal ||= new AbortController().signal;
93
+ return this._signal;
94
+ }
93
95
  get url() {
94
96
  if (this._url == null) {
95
97
  if (this._parsedUrl) {
@@ -115,15 +117,6 @@ export class PonyfillRequest extends PonyfillBody {
115
117
  }
116
118
  duplex;
117
119
  agent;
118
- _signal;
119
- get signal() {
120
- // Create a new signal only if needed
121
- // Because the creation of signal is expensive
122
- if (!this._signal) {
123
- this._signal = new PonyfillAbortController().signal;
124
- }
125
- return this._signal;
126
- }
127
120
  clone() {
128
121
  return this;
129
122
  }
package/esm/Response.js CHANGED
@@ -1,4 +1,4 @@
1
- import { STATUS_CODES } from 'http';
1
+ import { STATUS_CODES } from 'node:http';
2
2
  import { PonyfillBody } from './Body.js';
3
3
  import { isHeadersLike, PonyfillHeaders } from './Headers.js';
4
4
  const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
@@ -45,14 +45,60 @@ export class PonyfillResponse extends PonyfillBody {
45
45
  status,
46
46
  });
47
47
  }
48
- static json(data, init = {}) {
49
- init.headers =
50
- init?.headers && isHeadersLike(init.headers)
51
- ? init.headers
52
- : new PonyfillHeaders(init?.headers);
53
- if (!init.headers.has('content-type')) {
54
- init.headers.set('content-type', JSON_CONTENT_TYPE);
48
+ static json(data, init) {
49
+ const bodyInit = JSON.stringify(data);
50
+ if (!init) {
51
+ init = {
52
+ headers: {
53
+ 'content-type': JSON_CONTENT_TYPE,
54
+ 'content-length': Buffer.byteLength(bodyInit).toString(),
55
+ },
56
+ };
57
+ }
58
+ else if (!init.headers) {
59
+ init.headers = {
60
+ 'content-type': JSON_CONTENT_TYPE,
61
+ 'content-length': Buffer.byteLength(bodyInit).toString(),
62
+ };
63
+ }
64
+ else if (isHeadersLike(init.headers)) {
65
+ if (!init.headers.has('content-type')) {
66
+ init.headers.set('content-type', JSON_CONTENT_TYPE);
67
+ }
68
+ if (!init.headers.has('content-length')) {
69
+ init.headers.set('content-length', Buffer.byteLength(bodyInit).toString());
70
+ }
71
+ }
72
+ else if (Array.isArray(init.headers)) {
73
+ let contentTypeExists = false;
74
+ let contentLengthExists = false;
75
+ for (const [key] of init.headers) {
76
+ if (contentLengthExists && contentTypeExists) {
77
+ break;
78
+ }
79
+ if (!contentTypeExists && key.toLowerCase() === 'content-type') {
80
+ contentTypeExists = true;
81
+ }
82
+ else if (!contentLengthExists && key.toLowerCase() === 'content-length') {
83
+ contentLengthExists = true;
84
+ }
85
+ }
86
+ if (!contentTypeExists) {
87
+ init.headers.push(['content-type', JSON_CONTENT_TYPE]);
88
+ }
89
+ if (!contentLengthExists) {
90
+ init.headers.push(['content-length', Buffer.byteLength(bodyInit).toString()]);
91
+ }
92
+ }
93
+ else if (typeof init.headers === 'object') {
94
+ if (init.headers?.['content-type'] == null) {
95
+ init.headers['content-type'] = JSON_CONTENT_TYPE;
96
+ }
97
+ if (init.headers?.['content-length'] == null) {
98
+ init.headers['content-length'] = Buffer.byteLength(bodyInit).toString();
99
+ }
55
100
  }
56
- return new PonyfillResponse(JSON.stringify(data), init);
101
+ return new PonyfillResponse(bodyInit, init);
57
102
  }
103
+ [Symbol.toStringTag] = 'Response';
58
104
  }
@@ -1,3 +1,4 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  import { isArrayBufferView } from './utils.js';
2
3
  export class PonyfillTextEncoder {
3
4
  encoding;
@@ -4,9 +4,7 @@ export class PonyfillTextDecoderStream extends PonyfillTransformStream {
4
4
  textDecoder;
5
5
  constructor(encoding, options) {
6
6
  super({
7
- transform: (chunk, controller) => {
8
- controller.enqueue(this.textDecoder.decode(chunk, { stream: true }));
9
- },
7
+ transform: (chunk, controller) => controller.enqueue(this.textDecoder.decode(chunk, { stream: true })),
10
8
  });
11
9
  this.textDecoder = new PonyfillTextDecoder(encoding, options);
12
10
  }
@@ -24,9 +22,7 @@ export class PonyfillTextEncoderStream extends PonyfillTransformStream {
24
22
  textEncoder;
25
23
  constructor(encoding) {
26
24
  super({
27
- transform: (chunk, controller) => {
28
- controller.enqueue(this.textEncoder.encode(chunk));
29
- },
25
+ transform: (chunk, controller) => controller.enqueue(this.textEncoder.encode(chunk)),
30
26
  });
31
27
  this.textEncoder = new PonyfillTextEncoder(encoding);
32
28
  }
@@ -1,5 +1,6 @@
1
1
  import { Transform } from 'node:stream';
2
2
  import { PonyfillReadableStream } from './ReadableStream.js';
3
+ import { endStream } from './utils.js';
3
4
  import { PonyfillWritableStream } from './WritableStream.js';
4
5
  export class PonyfillTransformStream {
5
6
  transform;
@@ -18,7 +19,7 @@ export class PonyfillTransformStream {
18
19
  transform.destroy(reason);
19
20
  },
20
21
  terminate() {
21
- transform.end();
22
+ endStream(transform);
22
23
  },
23
24
  get desiredSize() {
24
25
  return transform.writableLength;
package/esm/URL.js CHANGED
@@ -1,79 +1,24 @@
1
- import { resolveObjectURL } from 'buffer';
2
- import { randomUUID } from 'crypto';
3
- import FastQuerystring from 'fast-querystring';
4
- import FastUrl from '@kamilkisiela/fast-url-parser';
5
- import { PonyfillURLSearchParams } from './URLSearchParams.js';
6
- FastUrl.queryString = FastQuerystring;
7
- const IPV6_REGEX = /^(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)(?:\/(?:0?0?[0-9]|0?[1-9][0-9]|1[01][0-9]|12[0-8]))?)$/;
8
- export class PonyfillURL extends FastUrl {
9
- constructor(url, base) {
10
- super();
11
- if (url.startsWith('data:')) {
12
- this.protocol = 'data:';
13
- this.pathname = url.slice('data:'.length);
14
- return;
15
- }
16
- this.parse(url, false);
17
- // `fast-url-parser` cannot handle ipv6 hosts correctly
18
- if ((url.startsWith('http://[') || url.startsWith('https://[')) &&
19
- IPV6_REGEX.test(this.hostname)) {
20
- this.hostname = `[${this.hostname}]`;
21
- }
22
- if (base) {
23
- const baseParsed = typeof base === 'string' ? new PonyfillURL(base) : base;
24
- this.protocol ||= baseParsed.protocol;
25
- this.host ||= baseParsed.host;
26
- this.pathname ||= baseParsed.pathname;
27
- this.port ||= baseParsed.port;
28
- }
29
- }
30
- get origin() {
31
- return `${this.protocol}//${this.host}${this.port ? `:${this.port}` : ''}`;
32
- }
33
- _searchParams;
34
- get searchParams() {
35
- if (!this._searchParams) {
36
- this._searchParams = new PonyfillURLSearchParams(this.query);
37
- }
38
- return this._searchParams;
39
- }
40
- get username() {
41
- return this.auth?.split(':')[0] || '';
42
- }
43
- set username(value) {
44
- this.auth = `${value}:${this.password}`;
45
- }
46
- get password() {
47
- return this.auth?.split(':')[1] || '';
48
- }
49
- set password(value) {
50
- this.auth = `${this.username}:${value}`;
51
- }
52
- toString() {
53
- if (this._searchParams) {
54
- this.search = this._searchParams.toString();
55
- }
56
- return this.format();
57
- }
58
- toJSON() {
59
- return this.toString();
60
- }
1
+ import NodeBuffer from 'node:buffer';
2
+ import { randomUUID } from 'node:crypto';
3
+ const NativeURL = globalThis.URL;
4
+ class URL extends NativeURL {
5
+ // This part is only needed to handle `PonyfillBlob` objects
61
6
  static blobRegistry = new Map();
62
7
  static createObjectURL(blob) {
63
8
  const blobUrl = `blob:whatwgnode:${randomUUID()}`;
64
9
  this.blobRegistry.set(blobUrl, blob);
65
10
  return blobUrl;
66
11
  }
67
- static resolveObjectURL(url) {
12
+ static revokeObjectURL(url) {
68
13
  if (!this.blobRegistry.has(url)) {
69
- URL.revokeObjectURL(url);
14
+ NativeURL.revokeObjectURL(url);
70
15
  }
71
16
  else {
72
17
  this.blobRegistry.delete(url);
73
18
  }
74
19
  }
75
20
  static getBlobFromURL(url) {
76
- return (this.blobRegistry.get(url) || resolveObjectURL(url));
21
+ return (this.blobRegistry.get(url) || NodeBuffer?.resolveObjectURL?.(url));
77
22
  }
78
- [Symbol.toStringTag] = 'URL';
79
23
  }
24
+ export { URL as PonyfillURL };
@@ -1,115 +1 @@
1
- import FastQuerystring from 'fast-querystring';
2
- import { PonyfillIteratorObject } from './IteratorObject.js';
3
- function isURLSearchParams(value) {
4
- return value?.entries != null;
5
- }
6
- export class PonyfillURLSearchParams {
7
- params;
8
- constructor(init) {
9
- if (init) {
10
- if (typeof init === 'string') {
11
- this.params = FastQuerystring.parse(init);
12
- }
13
- else if (Array.isArray(init)) {
14
- this.params = {};
15
- for (const [key, value] of init) {
16
- this.params[key] = value;
17
- }
18
- }
19
- else if (isURLSearchParams(init)) {
20
- this.params = {};
21
- for (const [key, value] of init.entries()) {
22
- this.params[key] = value;
23
- }
24
- }
25
- else {
26
- this.params = init;
27
- }
28
- }
29
- else {
30
- this.params = {};
31
- }
32
- }
33
- append(name, value) {
34
- const existingValue = this.params[name];
35
- const finalValue = existingValue ? `${existingValue},${value}` : value;
36
- this.params[name] = finalValue;
37
- }
38
- delete(name) {
39
- delete this.params[name];
40
- }
41
- get(name) {
42
- const value = this.params[name];
43
- if (Array.isArray(value)) {
44
- return value[0] || null;
45
- }
46
- return value || null;
47
- }
48
- getAll(name) {
49
- const value = this.params[name];
50
- if (!Array.isArray(value)) {
51
- return value ? [value] : [];
52
- }
53
- return value;
54
- }
55
- has(name) {
56
- return name in this.params;
57
- }
58
- set(name, value) {
59
- this.params[name] = value;
60
- }
61
- sort() {
62
- const sortedKeys = Object.keys(this.params).sort();
63
- const sortedParams = {};
64
- for (const key of sortedKeys) {
65
- sortedParams[key] = this.params[key];
66
- }
67
- this.params = sortedParams;
68
- }
69
- toString() {
70
- return FastQuerystring.stringify(this.params);
71
- }
72
- *_keys() {
73
- for (const key in this.params) {
74
- yield key;
75
- }
76
- }
77
- keys() {
78
- return new PonyfillIteratorObject(this._keys(), 'URLSearchParamsIterator');
79
- }
80
- *_entries() {
81
- for (const key of this.keys()) {
82
- const value = this.params[key];
83
- if (Array.isArray(value)) {
84
- for (const item of value) {
85
- yield [key, item];
86
- }
87
- }
88
- else {
89
- yield [key, value];
90
- }
91
- }
92
- }
93
- entries() {
94
- return new PonyfillIteratorObject(this._entries(), 'URLSearchParamsIterator');
95
- }
96
- *_values() {
97
- for (const [, value] of this) {
98
- yield value;
99
- }
100
- }
101
- values() {
102
- return new PonyfillIteratorObject(this._values(), 'URLSearchParamsIterator');
103
- }
104
- [Symbol.iterator]() {
105
- return this.entries();
106
- }
107
- forEach(callback) {
108
- for (const [key, value] of this) {
109
- callback(value, key, this);
110
- }
111
- }
112
- get size() {
113
- return Object.keys(this.params).length;
114
- }
115
- }
1
+ export const PonyfillURLSearchParams = globalThis.URLSearchParams;