@nxtedition/nxt-undici 1.4.4 → 2.0.1
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/lib/index.js +30 -24
- package/lib/interceptor/abort.js +2 -2
- package/lib/interceptor/cache.js +4 -4
- package/lib/interceptor/catch.js +1 -1
- package/lib/interceptor/log.js +6 -6
- package/lib/interceptor/proxy.js +3 -3
- package/lib/interceptor/redirect.js +3 -3
- package/lib/interceptor/request-body-factory.js +1 -1
- package/lib/interceptor/request-body.js +2 -2
- package/lib/interceptor/request-content.js +2 -2
- package/lib/interceptor/request-id.js +1 -1
- package/lib/interceptor/response-body-retry.js +3 -3
- package/lib/interceptor/response-content.js +3 -3
- package/lib/interceptor/response-retry.js +2 -2
- package/lib/interceptor/response-status-retry.js +3 -3
- package/lib/interceptor/signal.js +1 -1
- package/lib/utils.js +13 -28
- package/package.json +3 -1
package/lib/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import stream from 'node:stream'
|
|
3
|
+
import createError from 'http-errors'
|
|
4
|
+
import undici from 'undici'
|
|
5
|
+
import { parseHeaders, AbortError } from './utils.js'
|
|
6
|
+
import CacheableLookup from 'cacheable-lookup'
|
|
6
7
|
|
|
7
8
|
const dispatcherCache = new WeakMap()
|
|
8
9
|
|
|
@@ -126,24 +127,31 @@ class Readable extends stream.Readable {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
const dispatchers = {
|
|
129
|
-
requestBody:
|
|
130
|
-
requestBodyFactory:
|
|
131
|
-
abort:
|
|
132
|
-
catch:
|
|
133
|
-
responseContent:
|
|
134
|
-
requestContent:
|
|
135
|
-
log:
|
|
136
|
-
redirect:
|
|
137
|
-
responseBodyRetry:
|
|
138
|
-
responseStatusRetry:
|
|
139
|
-
responseRetry:
|
|
140
|
-
signal:
|
|
141
|
-
proxy:
|
|
142
|
-
cache:
|
|
143
|
-
requestId:
|
|
130
|
+
requestBody: (await import('./interceptor/request-body.js')).default,
|
|
131
|
+
requestBodyFactory: (await import('./interceptor/request-body-factory.js')).default,
|
|
132
|
+
abort: (await import('./interceptor/abort.js')).default,
|
|
133
|
+
catch: (await import('./interceptor/catch.js')).default,
|
|
134
|
+
responseContent: (await import('./interceptor/response-content.js')).default,
|
|
135
|
+
requestContent: (await import('./interceptor/request-content.js')).default,
|
|
136
|
+
log: (await import('./interceptor/log.js')).default,
|
|
137
|
+
redirect: (await import('./interceptor/redirect.js')).default,
|
|
138
|
+
responseBodyRetry: (await import('./interceptor/response-body-retry.js')).default,
|
|
139
|
+
responseStatusRetry: (await import('./interceptor/response-status-retry.js')).default,
|
|
140
|
+
responseRetry: (await import('./interceptor/response-retry.js')).default,
|
|
141
|
+
signal: (await import('./interceptor/signal.js')).default,
|
|
142
|
+
proxy: (await import('./interceptor/proxy.js')).default,
|
|
143
|
+
cache: (await import('./interceptor/cache.js')).default,
|
|
144
|
+
requestId: (await import('./interceptor/request-id.js')).default,
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
|
|
147
|
+
const dnsCache = new CacheableLookup()
|
|
148
|
+
const defaultDispatcher = new undici.Agent({
|
|
149
|
+
connect: {
|
|
150
|
+
lookup: dnsCache.lookup,
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
export async function request(url, opts) {
|
|
147
155
|
// TODO (fix): More argument validation...
|
|
148
156
|
|
|
149
157
|
if (typeof url === 'string') {
|
|
@@ -211,7 +219,7 @@ async function request(url, opts) {
|
|
|
211
219
|
delete headers['content-length']
|
|
212
220
|
}
|
|
213
221
|
|
|
214
|
-
const dispatcher = opts.dispatcher ??
|
|
222
|
+
const dispatcher = opts.dispatcher ?? defaultDispatcher
|
|
215
223
|
|
|
216
224
|
let dispatch = dispatcherCache.get(dispatcher)
|
|
217
225
|
if (dispatch == null) {
|
|
@@ -325,5 +333,3 @@ async function request(url, opts) {
|
|
|
325
333
|
),
|
|
326
334
|
)
|
|
327
335
|
}
|
|
328
|
-
|
|
329
|
-
module.exports = { request }
|
package/lib/interceptor/abort.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { AbortError } from '../utils.js'
|
|
2
2
|
|
|
3
3
|
class Handler {
|
|
4
4
|
constructor(opts, { handler }) {
|
|
@@ -69,4 +69,4 @@ class Handler {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
export default (dispatch) => (opts, handler) => dispatch(opts, new Handler(opts, { handler }))
|
package/lib/interceptor/cache.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { LRUCache } from 'lru-cache'
|
|
3
|
+
import cacheControlParser from 'cache-control-parser'
|
|
4
4
|
|
|
5
5
|
class CacheHandler {
|
|
6
6
|
constructor({ key, handler, store }) {
|
|
@@ -128,7 +128,7 @@ function makeKey(opts) {
|
|
|
128
128
|
|
|
129
129
|
const DEFAULT_CACHE_STORE = new CacheStore({ maxSize: 128 * 1024, maxEntrySize: 1024 })
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
export default (dispatch) => (opts, handler) => {
|
|
132
132
|
if (!opts.cache || opts.upgrade) {
|
|
133
133
|
return dispatch(opts, handler)
|
|
134
134
|
}
|
package/lib/interceptor/catch.js
CHANGED
package/lib/interceptor/log.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { performance } from 'node:perf_hooks'
|
|
2
|
+
import { parseHeaders } from '../utils.js'
|
|
3
3
|
|
|
4
4
|
class Handler {
|
|
5
5
|
constructor(opts, { handler }) {
|
|
@@ -67,7 +67,7 @@ class Handler {
|
|
|
67
67
|
|
|
68
68
|
onData(chunk) {
|
|
69
69
|
if (this.stats.firstBodyReceived === -1) {
|
|
70
|
-
this.stats.firstBodyReceived = this.stats.start
|
|
70
|
+
this.stats.firstBodyReceived = performance.now() - this.stats.start
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
this.pos += chunk.length
|
|
@@ -75,7 +75,7 @@ class Handler {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
onComplete(rawTrailers) {
|
|
78
|
-
this.stats.lastBodyReceived = this.stats.start
|
|
78
|
+
this.stats.lastBodyReceived = performance.now() - this.stats.start
|
|
79
79
|
this.stats.end = this.stats.lastBodyReceived
|
|
80
80
|
|
|
81
81
|
this.logger.debug(
|
|
@@ -86,7 +86,7 @@ class Handler {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
onError(err) {
|
|
89
|
-
this.stats.end = this.stats.start
|
|
89
|
+
this.stats.end = performance.now() - this.stats.start
|
|
90
90
|
|
|
91
91
|
if (this.aborted) {
|
|
92
92
|
this.logger.debug(
|
|
@@ -103,5 +103,5 @@ class Handler {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
export default (dispatch) => (opts, handler) =>
|
|
107
107
|
opts.logger ? dispatch(opts, new Handler(opts, { handler })) : dispatch(opts, handler)
|
package/lib/interceptor/proxy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import net from 'node:net'
|
|
2
|
+
import createError from 'http-errors'
|
|
3
3
|
|
|
4
4
|
class Handler {
|
|
5
5
|
constructor(opts, { handler }) {
|
|
@@ -73,7 +73,7 @@ class Handler {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
export default (dispatch) => (opts, handler) => {
|
|
77
77
|
if (!opts.proxy) {
|
|
78
78
|
return dispatch(opts, handler)
|
|
79
79
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { findHeader, isDisturbed, parseURL } from '../utils.js'
|
|
3
3
|
|
|
4
4
|
const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
|
|
5
5
|
|
|
@@ -176,7 +176,7 @@ function cleanRequestHeaders(headers, removeContent, unknownOrigin) {
|
|
|
176
176
|
return ret
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
export default (dispatch) => (opts, handler) =>
|
|
180
180
|
opts.follow != null
|
|
181
181
|
? dispatch(opts, new Handler(opts, { handler, dispatch }))
|
|
182
182
|
: dispatch(opts, handler)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { isStream } from '../utils.js'
|
|
2
2
|
|
|
3
3
|
class Handler {
|
|
4
4
|
constructor(opts, { handler }) {
|
|
@@ -58,7 +58,7 @@ class Handler {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
export default (dispatch) => (opts, handler) => {
|
|
62
62
|
if (isStream(opts.body)) {
|
|
63
63
|
if (opts.method === 'GET' || opts.method === 'HEAD') {
|
|
64
64
|
opts.body.resume() // dump
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import crypto from 'node:crypto'
|
|
2
2
|
|
|
3
3
|
class Handler {
|
|
4
4
|
constructor(opts, { handler, md5, length }) {
|
|
@@ -61,7 +61,7 @@ class Handler {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
export default (dispatch) => (opts, handler) => {
|
|
65
65
|
if (opts.upgrade) {
|
|
66
66
|
return dispatch(opts, handler)
|
|
67
67
|
}
|
|
@@ -11,7 +11,7 @@ function genReqId() {
|
|
|
11
11
|
return `req-${nextReqId.toString(36)}`
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export default (dispatch) => (opts, handler) => {
|
|
15
15
|
let id = opts.id ?? opts.headers?.['request-id'] ?? opts.headers?.['Request-Id']
|
|
16
16
|
id = id ? `${id},${genReqId()}` : genReqId()
|
|
17
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { parseContentRange, isDisturbed, findHeader, retry as retryFn } from '../utils.js'
|
|
3
3
|
|
|
4
4
|
class Handler {
|
|
5
5
|
constructor(opts, { dispatch, handler }) {
|
|
@@ -155,7 +155,7 @@ class Handler {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
export default (dispatch) => (opts, handler) => {
|
|
159
159
|
return opts.idempotent && opts.retry && opts.method === 'GET' && !opts.upgrade
|
|
160
160
|
? dispatch(opts, new Handler(opts, { handler, dispatch }))
|
|
161
161
|
: dispatch(opts, handler)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import crypto from 'node:crypto'
|
|
2
|
+
import { findHeader } from '../utils.js'
|
|
3
3
|
|
|
4
4
|
class Handler {
|
|
5
5
|
constructor(opts, { handler }) {
|
|
@@ -65,5 +65,5 @@ class Handler {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
export default (dispatch) => (opts, handler) =>
|
|
69
69
|
!opts.upgrade ? dispatch(opts, new Handler(opts, { handler })) : dispatch(opts, handler)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { isDisturbed, retry as retryFn } from '../utils.js'
|
|
2
2
|
|
|
3
3
|
class Handler {
|
|
4
4
|
constructor(opts, { dispatch, handler }) {
|
|
@@ -86,7 +86,7 @@ class Handler {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
export default (dispatch) => (opts, handler) =>
|
|
90
90
|
opts.idempotent && opts.retry && !opts.upgrade
|
|
91
91
|
? dispatch(opts, new Handler(opts, { handler, dispatch }))
|
|
92
92
|
: dispatch(opts, handler)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { parseHeaders, isDisturbed, retry as retryFn } from '../utils.js'
|
|
2
|
+
import createError from 'http-errors'
|
|
3
3
|
|
|
4
4
|
class Handler {
|
|
5
5
|
constructor(opts, { dispatch, handler }) {
|
|
@@ -98,7 +98,7 @@ class Handler {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
export default (dispatch) => (opts, handler) =>
|
|
102
102
|
opts.idempotent && opts.retry
|
|
103
103
|
? dispatch(opts, new Handler(opts, { handler, dispatch }))
|
|
104
104
|
: dispatch(opts, handler)
|
package/lib/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import tp from 'node:timers/promises'
|
|
2
2
|
|
|
3
|
-
function isDisturbed(body) {
|
|
3
|
+
export function isDisturbed(body) {
|
|
4
4
|
if (
|
|
5
5
|
body == null ||
|
|
6
6
|
typeof body === 'string' ||
|
|
@@ -17,7 +17,7 @@ function isDisturbed(body) {
|
|
|
17
17
|
return true
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function parseContentRange(range) {
|
|
20
|
+
export function parseContentRange(range) {
|
|
21
21
|
if (typeof range !== 'string') {
|
|
22
22
|
return null
|
|
23
23
|
}
|
|
@@ -45,7 +45,7 @@ function parseContentRange(range) {
|
|
|
45
45
|
return { start, end: end ? end + 1 : size, size }
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function findHeader(rawHeaders, name) {
|
|
48
|
+
export function findHeader(rawHeaders, name) {
|
|
49
49
|
const len = name.length
|
|
50
50
|
|
|
51
51
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
@@ -57,7 +57,7 @@ function findHeader(rawHeaders, name) {
|
|
|
57
57
|
return null
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
function retry(err, retryCount, opts) {
|
|
60
|
+
export function retry(err, retryCount, opts) {
|
|
61
61
|
if (opts.retry === null || opts.retry === false) {
|
|
62
62
|
return null
|
|
63
63
|
}
|
|
@@ -105,7 +105,7 @@ function retry(err, retryCount, opts) {
|
|
|
105
105
|
return null
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
function parseURL(url) {
|
|
108
|
+
export function parseURL(url) {
|
|
109
109
|
if (typeof url === 'string') {
|
|
110
110
|
url = new URL(url)
|
|
111
111
|
|
|
@@ -168,7 +168,7 @@ function parseURL(url) {
|
|
|
168
168
|
return url
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
function parseOrigin(url) {
|
|
171
|
+
export function parseOrigin(url) {
|
|
172
172
|
url = module.exports.parseURL(url)
|
|
173
173
|
|
|
174
174
|
if (url.pathname !== '/' || url.search || url.hash) {
|
|
@@ -178,7 +178,7 @@ function parseOrigin(url) {
|
|
|
178
178
|
return url
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
function parseHeaders(rawHeaders, obj = {}) {
|
|
181
|
+
export function parseHeaders(rawHeaders, obj = {}) {
|
|
182
182
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
183
183
|
const key = rawHeaders[i].toString().toLowerCase()
|
|
184
184
|
let val = obj[key]
|
|
@@ -195,7 +195,7 @@ function parseHeaders(rawHeaders, obj = {}) {
|
|
|
195
195
|
return obj
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
class AbortError extends Error {
|
|
198
|
+
export class AbortError extends Error {
|
|
199
199
|
constructor(message) {
|
|
200
200
|
super(message ?? 'The operation was aborted')
|
|
201
201
|
this.code = 'ABORT_ERR'
|
|
@@ -203,14 +203,14 @@ class AbortError extends Error {
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
function isStream(obj) {
|
|
206
|
+
export function isStream(obj) {
|
|
207
207
|
return (
|
|
208
208
|
obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function'
|
|
209
209
|
)
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License)
|
|
213
|
-
function isBlobLike(object) {
|
|
213
|
+
export function isBlobLike(object) {
|
|
214
214
|
return (
|
|
215
215
|
(Blob && object instanceof Blob) ||
|
|
216
216
|
(object &&
|
|
@@ -220,12 +220,12 @@ function isBlobLike(object) {
|
|
|
220
220
|
)
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
function isBuffer(buffer) {
|
|
223
|
+
export function isBuffer(buffer) {
|
|
224
224
|
// See, https://github.com/mcollina/undici/pull/319
|
|
225
225
|
return buffer instanceof Uint8Array || Buffer.isBuffer(buffer)
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
function bodyLength(body) {
|
|
228
|
+
export function bodyLength(body) {
|
|
229
229
|
if (body == null) {
|
|
230
230
|
return 0
|
|
231
231
|
} else if (isStream(body)) {
|
|
@@ -239,18 +239,3 @@ function bodyLength(body) {
|
|
|
239
239
|
|
|
240
240
|
return null
|
|
241
241
|
}
|
|
242
|
-
|
|
243
|
-
module.exports = {
|
|
244
|
-
isStream,
|
|
245
|
-
isBuffer,
|
|
246
|
-
isBlobLike,
|
|
247
|
-
AbortError,
|
|
248
|
-
bodyLength,
|
|
249
|
-
parseHeaders,
|
|
250
|
-
isDisturbed,
|
|
251
|
-
parseContentRange,
|
|
252
|
-
findHeader,
|
|
253
|
-
retry,
|
|
254
|
-
parseURL,
|
|
255
|
-
parseOrigin,
|
|
256
|
-
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/nxt-undici",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"files": [
|
|
8
9
|
"lib/*"
|
|
9
10
|
],
|
|
10
11
|
"dependencies": {
|
|
11
12
|
"cache-control-parser": "^2.0.4",
|
|
13
|
+
"cacheable-lookup": "^7.0.0",
|
|
12
14
|
"http-errors": "^2.0.0",
|
|
13
15
|
"lru-cache": "^10.0.1",
|
|
14
16
|
"undici": "^5.27.0"
|