undici 7.0.0-alpha.3 → 7.0.0-alpha.4
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 +2 -1
- package/docs/docs/api/BalancedPool.md +1 -1
- package/docs/docs/api/CacheStore.md +16 -32
- package/docs/docs/api/Dispatcher.md +22 -2
- package/docs/docs/api/MockClient.md +1 -1
- package/docs/docs/api/Pool.md +1 -1
- package/docs/docs/api/api-lifecycle.md +2 -2
- package/docs/docs/best-practices/mocking-request.md +2 -2
- package/docs/docs/best-practices/proxy.md +1 -1
- package/index.d.ts +1 -1
- package/index.js +2 -1
- package/lib/api/api-request.js +1 -1
- package/lib/cache/memory-cache-store.js +108 -200
- package/lib/core/connect.js +5 -0
- package/lib/core/request.js +2 -2
- package/lib/core/util.js +13 -40
- package/lib/dispatcher/client-h2.js +53 -33
- package/lib/handler/cache-handler.js +112 -82
- package/lib/handler/cache-revalidation-handler.js +45 -13
- package/lib/handler/redirect-handler.js +5 -3
- package/lib/handler/retry-handler.js +3 -3
- package/lib/interceptor/cache.js +115 -94
- package/lib/interceptor/dns.js +71 -48
- package/lib/util/cache.js +38 -13
- package/lib/web/cookies/index.js +12 -1
- package/lib/web/cookies/parse.js +6 -1
- package/lib/web/fetch/body.js +1 -5
- package/lib/web/fetch/formdata-parser.js +70 -43
- package/lib/web/fetch/headers.js +1 -1
- package/lib/web/fetch/index.js +4 -6
- package/lib/web/fetch/webidl.js +12 -4
- package/package.json +2 -3
- package/types/cache-interceptor.d.ts +36 -32
- package/types/cookies.d.ts +2 -0
- package/types/dispatcher.d.ts +1 -1
- package/types/index.d.ts +0 -1
- package/types/interceptors.d.ts +0 -1
|
@@ -11,7 +11,7 @@ const { File: NodeFile } = require('node:buffer')
|
|
|
11
11
|
const File = globalThis.File ?? NodeFile
|
|
12
12
|
|
|
13
13
|
const formDataNameBuffer = Buffer.from('form-data; name="')
|
|
14
|
-
const filenameBuffer = Buffer.from('
|
|
14
|
+
const filenameBuffer = Buffer.from('filename')
|
|
15
15
|
const dd = Buffer.from('--')
|
|
16
16
|
const ddcrlf = Buffer.from('--\r\n')
|
|
17
17
|
|
|
@@ -75,7 +75,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
75
75
|
// Otherwise, let boundary be the result of UTF-8 decoding mimeType’s
|
|
76
76
|
// parameters["boundary"].
|
|
77
77
|
if (boundaryString === undefined) {
|
|
78
|
-
|
|
78
|
+
throw parsingError('missing boundary in content-type header')
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const boundary = Buffer.from(`--${boundaryString}`, 'utf8')
|
|
@@ -111,7 +111,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
111
111
|
if (input.subarray(position.position, position.position + boundary.length).equals(boundary)) {
|
|
112
112
|
position.position += boundary.length
|
|
113
113
|
} else {
|
|
114
|
-
|
|
114
|
+
throw parsingError('expected a value starting with -- and the boundary')
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
// 5.2. If position points to the sequence of bytes 0x2D 0x2D 0x0D 0x0A
|
|
@@ -127,7 +127,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
127
127
|
// 5.3. If position does not point to a sequence of bytes starting with 0x0D
|
|
128
128
|
// 0x0A (CR LF), return failure.
|
|
129
129
|
if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) {
|
|
130
|
-
|
|
130
|
+
throw parsingError('expected CRLF')
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
// 5.4. Advance position by 2. (This skips past the newline.)
|
|
@@ -138,10 +138,6 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
138
138
|
// is not failure. Otherwise, return failure.
|
|
139
139
|
const result = parseMultipartFormDataHeaders(input, position)
|
|
140
140
|
|
|
141
|
-
if (result === 'failure') {
|
|
142
|
-
return 'failure'
|
|
143
|
-
}
|
|
144
|
-
|
|
145
141
|
let { name, filename, contentType, encoding } = result
|
|
146
142
|
|
|
147
143
|
// 5.6. Advance position by 2. (This skips past the empty line that marks
|
|
@@ -157,7 +153,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
157
153
|
const boundaryIndex = input.indexOf(boundary.subarray(2), position.position)
|
|
158
154
|
|
|
159
155
|
if (boundaryIndex === -1) {
|
|
160
|
-
|
|
156
|
+
throw parsingError('expected boundary after body')
|
|
161
157
|
}
|
|
162
158
|
|
|
163
159
|
body = input.subarray(position.position, boundaryIndex - 4)
|
|
@@ -174,7 +170,7 @@ function multipartFormDataParser (input, mimeType) {
|
|
|
174
170
|
// 5.9. If position does not point to a sequence of bytes starting with
|
|
175
171
|
// 0x0D 0x0A (CR LF), return failure. Otherwise, advance position by 2.
|
|
176
172
|
if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) {
|
|
177
|
-
|
|
173
|
+
throw parsingError('expected CRLF')
|
|
178
174
|
} else {
|
|
179
175
|
position.position += 2
|
|
180
176
|
}
|
|
@@ -230,7 +226,7 @@ function parseMultipartFormDataHeaders (input, position) {
|
|
|
230
226
|
if (input[position.position] === 0x0d && input[position.position + 1] === 0x0a) {
|
|
231
227
|
// 2.1.1. If name is null, return failure.
|
|
232
228
|
if (name === null) {
|
|
233
|
-
|
|
229
|
+
throw parsingError('header name is null')
|
|
234
230
|
}
|
|
235
231
|
|
|
236
232
|
// 2.1.2. Return name, filename and contentType.
|
|
@@ -250,12 +246,12 @@ function parseMultipartFormDataHeaders (input, position) {
|
|
|
250
246
|
|
|
251
247
|
// 2.4. If header name does not match the field-name token production, return failure.
|
|
252
248
|
if (!HTTP_TOKEN_CODEPOINTS.test(headerName.toString())) {
|
|
253
|
-
|
|
249
|
+
throw parsingError('header name does not match the field-name token production')
|
|
254
250
|
}
|
|
255
251
|
|
|
256
252
|
// 2.5. If the byte at position is not 0x3A (:), return failure.
|
|
257
253
|
if (input[position.position] !== 0x3a) {
|
|
258
|
-
|
|
254
|
+
throw parsingError('expected :')
|
|
259
255
|
}
|
|
260
256
|
|
|
261
257
|
// 2.6. Advance position by 1.
|
|
@@ -278,7 +274,7 @@ function parseMultipartFormDataHeaders (input, position) {
|
|
|
278
274
|
// 2. If position does not point to a sequence of bytes starting with
|
|
279
275
|
// `form-data; name="`, return failure.
|
|
280
276
|
if (!bufferStartsWith(input, formDataNameBuffer, position)) {
|
|
281
|
-
|
|
277
|
+
throw parsingError('expected form-data; name=" for content-disposition header')
|
|
282
278
|
}
|
|
283
279
|
|
|
284
280
|
// 3. Advance position so it points at the byte after the next 0x22 (")
|
|
@@ -290,34 +286,61 @@ function parseMultipartFormDataHeaders (input, position) {
|
|
|
290
286
|
// failure.
|
|
291
287
|
name = parseMultipartFormDataName(input, position)
|
|
292
288
|
|
|
293
|
-
if (name === null) {
|
|
294
|
-
return 'failure'
|
|
295
|
-
}
|
|
296
|
-
|
|
297
289
|
// 5. If position points to a sequence of bytes starting with `; filename="`:
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
290
|
+
if (input[position.position] === 0x3b /* ; */ && input[position.position + 1] === 0x20 /* ' ' */) {
|
|
291
|
+
const at = { position: position.position + 2 }
|
|
292
|
+
|
|
293
|
+
if (bufferStartsWith(input, filenameBuffer, at)) {
|
|
294
|
+
if (input[at.position + 8] === 0x2a /* '*' */) {
|
|
295
|
+
at.position += 10 // skip past filename*=
|
|
296
|
+
|
|
297
|
+
// Remove leading http tab and spaces. See RFC for examples.
|
|
298
|
+
// https://datatracker.ietf.org/doc/html/rfc6266#section-5
|
|
299
|
+
collectASequenceOfBytes(
|
|
300
|
+
(char) => char === 0x20 || char === 0x09,
|
|
301
|
+
input,
|
|
302
|
+
at
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
const headerValue = collectASequenceOfBytes(
|
|
306
|
+
(char) => char !== 0x20 && char !== 0x0d && char !== 0x0a, // ' ' or CRLF
|
|
307
|
+
input,
|
|
308
|
+
at
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
if (
|
|
312
|
+
(headerValue[0] !== 0x75 && headerValue[0] !== 0x55) || // u or U
|
|
313
|
+
(headerValue[1] !== 0x74 && headerValue[1] !== 0x54) || // t or T
|
|
314
|
+
(headerValue[2] !== 0x66 && headerValue[2] !== 0x46) || // f or F
|
|
315
|
+
headerValue[3] !== 0x2d || // -
|
|
316
|
+
headerValue[4] !== 0x38 // 8
|
|
317
|
+
) {
|
|
318
|
+
throw parsingError('unknown encoding, expected utf-8\'\'')
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// skip utf-8''
|
|
322
|
+
filename = decodeURIComponent(new TextDecoder().decode(headerValue.subarray(7)))
|
|
323
|
+
|
|
324
|
+
position.position = at.position
|
|
325
|
+
} else {
|
|
326
|
+
// 1. Advance position so it points at the byte after the next 0x22 (") byte
|
|
327
|
+
// (the one in the sequence of bytes matched above).
|
|
328
|
+
position.position += 11
|
|
329
|
+
|
|
330
|
+
// Remove leading http tab and spaces. See RFC for examples.
|
|
331
|
+
// https://datatracker.ietf.org/doc/html/rfc6266#section-5
|
|
332
|
+
collectASequenceOfBytes(
|
|
333
|
+
(char) => char === 0x20 || char === 0x09,
|
|
334
|
+
input,
|
|
335
|
+
position
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
position.position++ // skip past " after removing whitespace
|
|
339
|
+
|
|
340
|
+
// 2. Set filename to the result of parsing a multipart/form-data name given
|
|
341
|
+
// input and position, if the result is not failure. Otherwise, return failure.
|
|
342
|
+
filename = parseMultipartFormDataName(input, position)
|
|
343
|
+
}
|
|
321
344
|
}
|
|
322
345
|
}
|
|
323
346
|
|
|
@@ -367,7 +390,7 @@ function parseMultipartFormDataHeaders (input, position) {
|
|
|
367
390
|
// 2.9. If position does not point to a sequence of bytes starting with 0x0D 0x0A
|
|
368
391
|
// (CR LF), return failure. Otherwise, advance position by 2 (past the newline).
|
|
369
392
|
if (input[position.position] !== 0x0d && input[position.position + 1] !== 0x0a) {
|
|
370
|
-
|
|
393
|
+
throw parsingError('expected CRLF')
|
|
371
394
|
} else {
|
|
372
395
|
position.position += 2
|
|
373
396
|
}
|
|
@@ -393,7 +416,7 @@ function parseMultipartFormDataName (input, position) {
|
|
|
393
416
|
|
|
394
417
|
// 3. If the byte at position is not 0x22 ("), return failure. Otherwise, advance position by 1.
|
|
395
418
|
if (input[position.position] !== 0x22) {
|
|
396
|
-
|
|
419
|
+
throw parsingError('expected "')
|
|
397
420
|
} else {
|
|
398
421
|
position.position++
|
|
399
422
|
}
|
|
@@ -468,6 +491,10 @@ function bufferStartsWith (buffer, start, position) {
|
|
|
468
491
|
return true
|
|
469
492
|
}
|
|
470
493
|
|
|
494
|
+
function parsingError (cause) {
|
|
495
|
+
return new TypeError('Failed to parse body as FormData.', { cause: new TypeError(cause) })
|
|
496
|
+
}
|
|
497
|
+
|
|
471
498
|
module.exports = {
|
|
472
499
|
multipartFormDataParser,
|
|
473
500
|
validateBoundary
|
package/lib/web/fetch/headers.js
CHANGED
|
@@ -451,7 +451,7 @@ class Headers {
|
|
|
451
451
|
|
|
452
452
|
// 2. If init is given, then fill this with init.
|
|
453
453
|
if (init !== undefined) {
|
|
454
|
-
init = webidl.converters.HeadersInit(init, 'Headers
|
|
454
|
+
init = webidl.converters.HeadersInit(init, 'Headers constructor', 'init')
|
|
455
455
|
fill(this, init)
|
|
456
456
|
}
|
|
457
457
|
}
|
package/lib/web/fetch/index.js
CHANGED
|
@@ -1943,8 +1943,10 @@ async function httpNetworkFetch (
|
|
|
1943
1943
|
// 19. Run these steps in parallel:
|
|
1944
1944
|
|
|
1945
1945
|
// 1. Run these steps, but abort when fetchParams is canceled:
|
|
1946
|
-
fetchParams.controller.
|
|
1947
|
-
|
|
1946
|
+
if (!fetchParams.controller.resume) {
|
|
1947
|
+
fetchParams.controller.on('terminated', onAborted)
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1948
1950
|
fetchParams.controller.resume = async () => {
|
|
1949
1951
|
// 1. While true
|
|
1950
1952
|
while (true) {
|
|
@@ -2205,10 +2207,6 @@ async function httpNetworkFetch (
|
|
|
2205
2207
|
fetchParams.controller.off('terminated', this.abort)
|
|
2206
2208
|
}
|
|
2207
2209
|
|
|
2208
|
-
if (fetchParams.controller.onAborted) {
|
|
2209
|
-
fetchParams.controller.off('terminated', fetchParams.controller.onAborted)
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
2210
|
fetchParams.controller.ended = true
|
|
2213
2211
|
|
|
2214
2212
|
this.body.push(null)
|
package/lib/web/fetch/webidl.js
CHANGED
|
@@ -345,12 +345,14 @@ webidl.recordConverter = function (keyConverter, valueConverter) {
|
|
|
345
345
|
const keys = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]
|
|
346
346
|
|
|
347
347
|
for (const key of keys) {
|
|
348
|
+
const keyName = webidl.util.Stringify(key)
|
|
349
|
+
|
|
348
350
|
// 1. Let typedKey be key converted to an IDL value of type K.
|
|
349
|
-
const typedKey = keyConverter(key, prefix, argument)
|
|
351
|
+
const typedKey = keyConverter(key, prefix, `Key ${keyName} in ${argument}`)
|
|
350
352
|
|
|
351
353
|
// 2. Let value be ? Get(O, key).
|
|
352
354
|
// 3. Let typedValue be value converted to an IDL value of type V.
|
|
353
|
-
const typedValue = valueConverter(O[key], prefix, argument)
|
|
355
|
+
const typedValue = valueConverter(O[key], prefix, `${argument}[${keyName}]`)
|
|
354
356
|
|
|
355
357
|
// 4. Set result[typedKey] to typedValue.
|
|
356
358
|
result[typedKey] = typedValue
|
|
@@ -501,8 +503,14 @@ webidl.converters.DOMString = function (V, prefix, argument, opts) {
|
|
|
501
503
|
// https://webidl.spec.whatwg.org/#es-ByteString
|
|
502
504
|
webidl.converters.ByteString = function (V, prefix, argument) {
|
|
503
505
|
// 1. Let x be ? ToString(V).
|
|
504
|
-
|
|
505
|
-
|
|
506
|
+
if (typeof V === 'symbol') {
|
|
507
|
+
throw webidl.errors.exception({
|
|
508
|
+
header: prefix,
|
|
509
|
+
message: `${argument} is a symbol, which cannot be converted to a ByteString.`
|
|
510
|
+
})
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const x = String(V)
|
|
506
514
|
|
|
507
515
|
// 2. If the value of any element of x is greater than
|
|
508
516
|
// 255, then throw a TypeError.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "undici",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.4",
|
|
4
4
|
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
|
5
5
|
"homepage": "https://undici.nodejs.org",
|
|
6
6
|
"bugs": {
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"types": "index.d.ts",
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build:node": "esbuild index-fetch.js --bundle --platform=node --outfile=undici-fetch.js --define:esbuildDetection=1 --keep-names && node scripts/strip-comments.js",
|
|
66
|
-
"prebuild:wasm": "node build/wasm.js --prebuild",
|
|
67
66
|
"build:wasm": "node build/wasm.js --docker",
|
|
68
67
|
"generate-pem": "node scripts/generate-pem.js",
|
|
69
68
|
"lint": "eslint --cache",
|
|
@@ -108,7 +107,7 @@
|
|
|
108
107
|
"devDependencies": {
|
|
109
108
|
"@fastify/busboy": "3.0.0",
|
|
110
109
|
"@matteo.collina/tspl": "^0.1.1",
|
|
111
|
-
"@sinonjs/fake-timers": "^
|
|
110
|
+
"@sinonjs/fake-timers": "^12.0.0",
|
|
112
111
|
"@types/node": "^18.19.50",
|
|
113
112
|
"abort-controller": "^3.0.0",
|
|
114
113
|
"borp": "^0.18.0",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Readable, Writable } from 'node:stream'
|
|
2
|
-
import Dispatcher from './dispatcher'
|
|
3
2
|
|
|
4
3
|
export default CacheHandler
|
|
5
4
|
|
|
@@ -19,6 +18,21 @@ declare namespace CacheHandler {
|
|
|
19
18
|
methods?: CacheMethods[]
|
|
20
19
|
}
|
|
21
20
|
|
|
21
|
+
export interface CacheKey {
|
|
22
|
+
origin: string
|
|
23
|
+
method: string
|
|
24
|
+
path: string
|
|
25
|
+
headers?: Record<string, string | string[]>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface DeleteByUri {
|
|
29
|
+
origin: string
|
|
30
|
+
method: string
|
|
31
|
+
path: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type GetResult = CachedResponse & { body: null | Readable | Iterable<Buffer> | Buffer | Iterable<string> | string }
|
|
35
|
+
|
|
22
36
|
/**
|
|
23
37
|
* Underlying storage provider for cached responses
|
|
24
38
|
*/
|
|
@@ -26,72 +40,62 @@ declare namespace CacheHandler {
|
|
|
26
40
|
/**
|
|
27
41
|
* Whether or not the cache is full and can not store any more responses
|
|
28
42
|
*/
|
|
29
|
-
get isFull(): boolean
|
|
43
|
+
get isFull(): boolean | undefined
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
get(key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
|
|
32
46
|
|
|
33
|
-
createWriteStream(
|
|
47
|
+
createWriteStream(key: CacheKey, value: CachedResponse): Writable | undefined
|
|
34
48
|
|
|
35
|
-
|
|
36
|
-
* Delete all of the cached responses from a certain origin (host)
|
|
37
|
-
*/
|
|
38
|
-
deleteByOrigin(origin: string): void | Promise<void>
|
|
49
|
+
delete(key: CacheKey): void | Promise<void>
|
|
39
50
|
}
|
|
40
51
|
|
|
41
|
-
export interface
|
|
42
|
-
get value(): CacheStoreValue
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface CacheStoreWriteable extends Writable {
|
|
46
|
-
set rawTrailers(rawTrailers: string[] | undefined)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface CacheStoreValue {
|
|
52
|
+
export interface CachedResponse {
|
|
50
53
|
statusCode: number;
|
|
51
54
|
statusMessage: string;
|
|
52
|
-
rawHeaders:
|
|
53
|
-
rawTrailers?: string[];
|
|
55
|
+
rawHeaders: Buffer[];
|
|
54
56
|
/**
|
|
55
57
|
* Headers defined by the Vary header and their respective values for
|
|
56
58
|
* later comparison
|
|
57
59
|
*/
|
|
58
|
-
vary?: Record<string, string
|
|
60
|
+
vary?: Record<string, string | string[]>
|
|
59
61
|
/**
|
|
60
62
|
* Time in millis that this value was cached
|
|
61
63
|
*/
|
|
62
|
-
cachedAt: number
|
|
64
|
+
cachedAt: number
|
|
63
65
|
/**
|
|
64
66
|
* Time in millis that this value is considered stale
|
|
65
67
|
*/
|
|
66
|
-
staleAt: number
|
|
68
|
+
staleAt: number
|
|
67
69
|
/**
|
|
68
70
|
* Time in millis that this value is to be deleted from the cache. This is
|
|
69
71
|
* either the same as staleAt or the `max-stale` caching directive.
|
|
70
72
|
*/
|
|
71
|
-
deleteAt: number
|
|
73
|
+
deleteAt: number
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
export interface MemoryCacheStoreOpts {
|
|
75
77
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
* @default Infinity
|
|
79
|
+
*/
|
|
80
|
+
maxCount?: number
|
|
81
|
+
|
|
79
82
|
/**
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
* @default Infinity
|
|
84
|
+
*/
|
|
82
85
|
maxEntrySize?: number
|
|
86
|
+
|
|
83
87
|
errorCallback?: (err: Error) => void
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
export class MemoryCacheStore implements CacheStore {
|
|
87
91
|
constructor (opts?: MemoryCacheStoreOpts)
|
|
88
92
|
|
|
89
|
-
get isFull (): boolean
|
|
93
|
+
get isFull (): boolean | undefined
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
get (key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
|
|
92
96
|
|
|
93
|
-
createWriteStream (
|
|
97
|
+
createWriteStream (key: CacheKey, value: CachedResponse): Writable | undefined
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
delete (key: CacheKey): void | Promise<void>
|
|
96
100
|
}
|
|
97
101
|
}
|
package/types/cookies.d.ts
CHANGED
|
@@ -26,3 +26,5 @@ export function getCookies (headers: Headers): Record<string, string>
|
|
|
26
26
|
export function getSetCookies (headers: Headers): Cookie[]
|
|
27
27
|
|
|
28
28
|
export function setCookie (headers: Headers, cookie: Cookie): void
|
|
29
|
+
|
|
30
|
+
export function parseCookie (cookie: string): Cookie | null
|
package/types/dispatcher.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ declare namespace Dispatcher {
|
|
|
108
108
|
query?: Record<string, any>;
|
|
109
109
|
/** Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline have completed. Default: `true` if `method` is `HEAD` or `GET`. */
|
|
110
110
|
idempotent?: boolean;
|
|
111
|
-
/** Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. */
|
|
111
|
+
/** Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. Defaults to `method !== 'HEAD'`. */
|
|
112
112
|
blocking?: boolean;
|
|
113
113
|
/** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */
|
|
114
114
|
upgrade?: boolean | string | null;
|
package/types/index.d.ts
CHANGED
|
@@ -40,7 +40,6 @@ declare namespace Undici {
|
|
|
40
40
|
const RedirectHandler: typeof import ('./handlers').RedirectHandler
|
|
41
41
|
const DecoratorHandler: typeof import ('./handlers').DecoratorHandler
|
|
42
42
|
const RetryHandler: typeof import ('./retry-handler').default
|
|
43
|
-
const createRedirectInterceptor: typeof import ('./interceptors').default.createRedirectInterceptor
|
|
44
43
|
const BalancedPool: typeof import('./balanced-pool').default
|
|
45
44
|
const Client: typeof import('./client').default
|
|
46
45
|
const buildConnector: typeof import('./connector').default
|
package/types/interceptors.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ declare namespace Interceptors {
|
|
|
25
25
|
affinity?: 4 | 6
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function createRedirectInterceptor (opts: RedirectInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
|
|
29
28
|
export function dump (opts?: DumpInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
|
|
30
29
|
export function retry (opts?: RetryInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
|
|
31
30
|
export function redirect (opts?: RedirectInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
|