@nxtedition/lib 14.1.13 → 14.1.15

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 (4) hide show
  1. package/http.js +17 -0
  2. package/package.json +1 -1
  3. package/stream.js +12 -0
  4. package/undici.js +32 -24
package/http.js CHANGED
@@ -349,3 +349,20 @@ module.exports.retry = async function _retry(fn, options) {
349
349
  }
350
350
  }
351
351
  }
352
+
353
+ module.exports.parseHeaders = function parseHeaders(rawHeaders, obj = {}) {
354
+ for (let i = 0; i < rawHeaders.length; i += 2) {
355
+ const key = rawHeaders[i].toString().toLowerCase()
356
+ let val = obj[key]
357
+ if (!val) {
358
+ obj[key] = rawHeaders[i + 1].toString()
359
+ } else {
360
+ if (!Array.isArray(val)) {
361
+ val = [val]
362
+ obj[key] = val
363
+ }
364
+ val.push(rawHeaders[i + 1].toString())
365
+ }
366
+ }
367
+ return obj
368
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "14.1.13",
3
+ "version": "14.1.15",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "files": [
package/stream.js CHANGED
@@ -17,7 +17,19 @@ function isStream(obj) {
17
17
  )
18
18
  }
19
19
 
20
+ function readableStreamLength(stream) {
21
+ if (!isReadableNodeStream(stream)) {
22
+ return null
23
+ }
24
+
25
+ stream.read(0)
26
+
27
+ const state = stream._readableState
28
+ return state && state.ended === true && Number.isFinite(state.length) ? state.length : null
29
+ }
30
+
20
31
  module.exports = {
21
32
  isStream,
22
33
  isReadableNodeStream,
34
+ readableStreamLength,
23
35
  }
package/undici.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const assert = require('assert')
2
2
  const tp = require('timers/promises')
3
3
  const xuid = require('xuid')
4
- const { isReadableNodeStream } = require('./stream')
4
+ const { isReadableNodeStream, readableStreamLength } = require('./stream')
5
5
  const undici = require('undici')
6
6
  const stream = require('stream')
7
7
  const omitEmpty = require('omit-empty')
@@ -13,6 +13,7 @@ module.exports.request = async function request(
13
13
  id = xuid(),
14
14
  retry,
15
15
  maxRedirections: _maxRedirections,
16
+ idempotent,
16
17
  redirect,
17
18
  dispatcher,
18
19
  signal,
@@ -38,7 +39,27 @@ module.exports.request = async function request(
38
39
  }
39
40
 
40
41
  const { count: maxRedirections = _maxRedirections ?? 3 } = redirect ?? {}
41
- const { count: maxRetries = 8, status = [] } = retry ?? {}
42
+ const {
43
+ count: maxRetries = 8,
44
+ method: retryMethod = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'PATCH'],
45
+ status: retryStatus = [420, 429, 502, 503, 504],
46
+ code: retryCode = [
47
+ 'ECONNRESET',
48
+ 'ECONNREFUSED',
49
+ 'ENOTFOUND',
50
+ 'ENETDOWN',
51
+ 'ENETUNREACH',
52
+ 'EHOSTDOWN',
53
+ 'EHOSTUNREACH',
54
+ 'EPIPE',
55
+ ],
56
+ message: retryMessage = ['other side closed'],
57
+ } = retry ?? {}
58
+
59
+ if (readableStreamLength(body) === 0) {
60
+ body.on('error', () => {})
61
+ body = null
62
+ }
42
63
 
43
64
  const ureq = {
44
65
  url,
@@ -98,28 +119,15 @@ module.exports.request = async function request(
98
119
  throw err
99
120
  }
100
121
 
101
- if (method === 'HEAD' || method === 'GET') {
102
- if (
103
- err.code !== 'ECONNRESET' &&
104
- err.code !== 'ECONNREFUSED' &&
105
- err.code !== 'ENOTFOUND' &&
106
- err.code !== 'ENETDOWN' &&
107
- err.code !== 'ENETUNREACH' &&
108
- err.code !== 'EHOSTDOWN' &&
109
- err.code !== 'EHOSTUNREACH' &&
110
- err.code !== 'EPIPE' &&
111
- err.message !== 'other side closed' &&
112
- err.statusCode !== 420 &&
113
- err.statusCode !== 429 &&
114
- err.statusCode !== 502 &&
115
- err.statusCode !== 503 &&
116
- err.statusCode !== 504 &&
117
- !status.includes(err.statusCode)
118
- ) {
119
- throw err
120
- }
121
- } else {
122
- // TODO (fix): What to do?
122
+ if (!retryMethod.includes(method) && !idempotent) {
123
+ throw err
124
+ }
125
+
126
+ if (
127
+ !retryCode.includes(err.code) &&
128
+ !retryMessage.includes(err.message) &&
129
+ !retryStatus.includes(err.statusCode)
130
+ ) {
123
131
  throw err
124
132
  }
125
133