pnpm 7.9.1 → 7.9.2
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 +22 -7
- package/bin/pnpm.cjs +3 -0
- package/bin/pnpx.cjs +1 -15
- package/dist/node_modules/.modules.yaml +3 -3
- package/dist/node_modules/.pnpm/lock.yaml +76 -42
- package/dist/node_modules/@npmcli/fs/lib/common/owner-sync.js +96 -0
- package/dist/node_modules/@npmcli/fs/lib/common/owner.js +8 -4
- package/dist/node_modules/@npmcli/fs/lib/copy-file.js +3 -9
- package/dist/node_modules/@npmcli/fs/lib/fs.js +9 -3
- package/dist/node_modules/@npmcli/fs/lib/index.js +3 -1
- package/dist/node_modules/@npmcli/fs/lib/mkdir.js +19 -0
- package/dist/node_modules/@npmcli/fs/lib/mkdtemp.js +3 -8
- package/dist/node_modules/@npmcli/fs/lib/with-owner-sync.js +21 -0
- package/dist/node_modules/@npmcli/fs/lib/with-owner.js +21 -0
- package/dist/node_modules/@npmcli/fs/lib/with-temp-dir.js +4 -2
- package/dist/node_modules/@npmcli/fs/lib/write-file.js +3 -8
- package/dist/node_modules/@npmcli/fs/package.json +21 -9
- package/dist/node_modules/@npmcli/move-file/{index.js → lib/index.js} +50 -27
- package/dist/node_modules/@npmcli/move-file/package.json +20 -7
- package/dist/node_modules/@tootallnate/once/LICENSE +21 -0
- package/dist/node_modules/@tootallnate/once/dist/index.js +21 -36
- package/dist/node_modules/@tootallnate/once/dist/index.js.map +1 -1
- package/dist/node_modules/@tootallnate/once/dist/overloaded-parameters.js +3 -0
- package/dist/node_modules/@tootallnate/once/dist/overloaded-parameters.js.map +1 -0
- package/dist/node_modules/@tootallnate/once/dist/types.js +3 -0
- package/dist/node_modules/@tootallnate/once/dist/types.js.map +1 -0
- package/dist/node_modules/@tootallnate/once/package.json +22 -15
- package/dist/node_modules/cacache/lib/content/read.js +99 -102
- package/dist/node_modules/cacache/lib/content/rm.js +9 -8
- package/dist/node_modules/cacache/lib/content/write.js +67 -67
- package/dist/node_modules/cacache/lib/entry-index.js +128 -118
- package/dist/node_modules/cacache/{get.js → lib/get.js} +88 -100
- package/dist/node_modules/cacache/{index.js → lib/index.js} +5 -6
- package/dist/node_modules/cacache/lib/memoization.js +10 -11
- package/dist/node_modules/cacache/{put.js → lib/put.js} +23 -26
- package/dist/node_modules/cacache/{rm.js → lib/rm.js} +3 -3
- package/dist/node_modules/cacache/lib/util/fix-owner.js +41 -38
- package/dist/node_modules/cacache/lib/util/move-file.js +36 -47
- package/dist/node_modules/cacache/lib/util/tmp.js +5 -7
- package/dist/node_modules/cacache/lib/verify.js +160 -190
- package/dist/node_modules/cacache/node_modules/brace-expansion/.github/FUNDING.yml +2 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/LICENSE +21 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/index.js +203 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/package.json +46 -0
- package/dist/node_modules/cacache/node_modules/glob/LICENSE +15 -0
- package/dist/node_modules/cacache/node_modules/glob/common.js +240 -0
- package/dist/node_modules/cacache/node_modules/glob/glob.js +790 -0
- package/dist/node_modules/cacache/node_modules/glob/package.json +55 -0
- package/dist/node_modules/cacache/node_modules/glob/sync.js +486 -0
- package/dist/node_modules/cacache/node_modules/minimatch/LICENSE +15 -0
- package/dist/node_modules/cacache/node_modules/minimatch/lib/path.js +4 -0
- package/dist/node_modules/cacache/node_modules/minimatch/minimatch.js +906 -0
- package/dist/node_modules/cacache/node_modules/minimatch/package.json +32 -0
- package/dist/node_modules/cacache/package.json +34 -30
- package/dist/node_modules/http-proxy-agent/dist/agent.js +3 -3
- package/dist/node_modules/http-proxy-agent/dist/agent.js.map +1 -1
- package/dist/node_modules/http-proxy-agent/package.json +4 -4
- package/dist/node_modules/lru-cache/LICENSE +1 -1
- package/dist/node_modules/lru-cache/index.js +921 -247
- package/dist/node_modules/lru-cache/package.json +49 -9
- package/dist/node_modules/make-fetch-happen/LICENSE +1 -1
- package/dist/node_modules/make-fetch-happen/lib/agent.js +34 -14
- package/dist/node_modules/make-fetch-happen/lib/cache/entry.js +90 -106
- package/dist/node_modules/make-fetch-happen/lib/cache/errors.js +1 -0
- package/dist/node_modules/make-fetch-happen/lib/cache/index.js +10 -6
- package/dist/node_modules/make-fetch-happen/lib/cache/policy.js +21 -21
- package/dist/node_modules/make-fetch-happen/lib/dns.js +49 -0
- package/dist/node_modules/make-fetch-happen/lib/fetch.js +40 -22
- package/dist/node_modules/make-fetch-happen/lib/index.js +4 -3
- package/dist/node_modules/make-fetch-happen/lib/options.js +17 -9
- package/dist/node_modules/make-fetch-happen/lib/pipeline.js +41 -0
- package/dist/node_modules/make-fetch-happen/lib/remote.js +28 -9
- package/dist/node_modules/make-fetch-happen/package.json +36 -33
- package/dist/node_modules/minipass-fetch/lib/blob.js +4 -4
- package/dist/node_modules/minipass-fetch/lib/body.js +63 -49
- package/dist/node_modules/minipass-fetch/lib/fetch-error.js +2 -1
- package/dist/node_modules/minipass-fetch/lib/headers.js +38 -21
- package/dist/node_modules/minipass-fetch/lib/index.js +130 -106
- package/dist/node_modules/minipass-fetch/lib/request.js +46 -28
- package/dist/node_modules/minipass-fetch/lib/response.js +3 -2
- package/dist/node_modules/minipass-fetch/package.json +27 -14
- package/dist/node_modules/node-gyp/.github/workflows/release-please.yml +1 -1
- package/dist/node_modules/node-gyp/.github/workflows/tests.yml +16 -9
- package/dist/node_modules/node-gyp/.github/workflows/visual-studio.yml +16 -8
- package/dist/node_modules/node-gyp/lib/build.js +7 -0
- package/dist/node_modules/node-gyp/lib/configure.js +26 -1
- package/dist/node_modules/node-gyp/lib/create-config-gypi.js +2 -1
- package/dist/node_modules/node-gyp/lib/find-visualstudio.js +9 -8
- package/dist/node_modules/node-gyp/lib/node-gyp.js +4 -0
- package/dist/node_modules/node-gyp/package.json +4 -4
- package/dist/node_modules/semver/node_modules/lru-cache/LICENSE +15 -0
- package/dist/node_modules/semver/node_modules/lru-cache/index.js +334 -0
- package/dist/node_modules/semver/node_modules/lru-cache/package.json +34 -0
- package/dist/node_modules/socks-proxy-agent/dist/index.js +3 -3
- package/dist/node_modules/socks-proxy-agent/dist/index.js.map +1 -1
- package/dist/node_modules/socks-proxy-agent/package.json +2 -2
- package/dist/node_modules/ssri/{index.js → lib/index.js} +78 -24
- package/dist/node_modules/ssri/package.json +27 -16
- package/dist/pnpm.cjs +67042 -65886
- package/package.json +6 -6
- package/dist/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js +0 -17
- package/dist/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js +0 -121
- package/dist/node_modules/@npmcli/fs/lib/mkdir/index.js +0 -32
- package/dist/node_modules/@npmcli/fs/lib/mkdir/polyfill.js +0 -81
- package/dist/node_modules/cacache/lib/util/disposer.js +0 -30
- package/dist/node_modules/cacache/ls.js +0 -6
- package/dist/node_modules/cacache/verify.js +0 -3
- package/dist/node_modules/minipass-fetch/index.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const
|
|
2
|
+
const { URL } = require('url')
|
|
3
3
|
const http = require('http')
|
|
4
4
|
const https = require('https')
|
|
5
5
|
const zlib = require('minizlib')
|
|
@@ -15,25 +15,41 @@ const { getNodeRequestOptions } = Request
|
|
|
15
15
|
const FetchError = require('./fetch-error.js')
|
|
16
16
|
const AbortError = require('./abort-error.js')
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const fetch = (url, opts) => {
|
|
18
|
+
// XXX this should really be split up and unit-ized for easier testing
|
|
19
|
+
// and better DRY implementation of data/http request aborting
|
|
20
|
+
const fetch = async (url, opts) => {
|
|
21
21
|
if (/^data:/.test(url)) {
|
|
22
22
|
const request = new Request(url, opts)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'
|
|
23
|
+
// delay 1 promise tick so that the consumer can abort right away
|
|
24
|
+
return Promise.resolve().then(() => new Promise((resolve, reject) => {
|
|
25
|
+
let type, data
|
|
26
|
+
try {
|
|
27
|
+
const { pathname, search } = new URL(url)
|
|
28
|
+
const split = pathname.split(',')
|
|
29
|
+
if (split.length < 2) {
|
|
30
|
+
throw new Error('invalid data: URI')
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const mime = split.shift()
|
|
33
|
+
const base64 = /;base64$/.test(mime)
|
|
34
|
+
type = base64 ? mime.slice(0, -1 * ';base64'.length) : mime
|
|
35
|
+
const rawData = decodeURIComponent(split.join(',') + search)
|
|
36
|
+
data = base64 ? Buffer.from(rawData, 'base64') : Buffer.from(rawData)
|
|
37
|
+
} catch (er) {
|
|
38
|
+
return reject(new FetchError(`[${request.method}] ${
|
|
39
|
+
request.url} invalid URL, ${er.message}`, 'system', er))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const { signal } = request
|
|
43
|
+
if (signal && signal.aborted) {
|
|
44
|
+
return reject(new AbortError('The user aborted a request.'))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const headers = { 'Content-Length': data.length }
|
|
48
|
+
if (type) {
|
|
49
|
+
headers['Content-Type'] = type
|
|
50
|
+
}
|
|
51
|
+
return resolve(new Response(data, { headers }))
|
|
52
|
+
}))
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
return new Promise((resolve, reject) => {
|
|
@@ -61,8 +77,9 @@ const fetch = (url, opts) => {
|
|
|
61
77
|
}
|
|
62
78
|
}
|
|
63
79
|
|
|
64
|
-
if (signal && signal.aborted)
|
|
80
|
+
if (signal && signal.aborted) {
|
|
65
81
|
return abort()
|
|
82
|
+
}
|
|
66
83
|
|
|
67
84
|
const abortAndFinalize = () => {
|
|
68
85
|
abort()
|
|
@@ -71,16 +88,18 @@ const fetch = (url, opts) => {
|
|
|
71
88
|
|
|
72
89
|
const finalize = () => {
|
|
73
90
|
req.abort()
|
|
74
|
-
if (signal)
|
|
91
|
+
if (signal) {
|
|
75
92
|
signal.removeEventListener('abort', abortAndFinalize)
|
|
93
|
+
}
|
|
76
94
|
clearTimeout(reqTimeout)
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
// send request
|
|
80
98
|
const req = send(options)
|
|
81
99
|
|
|
82
|
-
if (signal)
|
|
100
|
+
if (signal) {
|
|
83
101
|
signal.addEventListener('abort', abortAndFinalize)
|
|
102
|
+
}
|
|
84
103
|
|
|
85
104
|
let reqTimeout = null
|
|
86
105
|
if (request.timeout) {
|
|
@@ -105,8 +124,9 @@ const fetch = (url, opts) => {
|
|
|
105
124
|
// exits without warning.
|
|
106
125
|
// coverage skipped here due to the difficulty in testing
|
|
107
126
|
// istanbul ignore next
|
|
108
|
-
if (req.res)
|
|
127
|
+
if (req.res) {
|
|
109
128
|
req.res.emit('error', er)
|
|
129
|
+
}
|
|
110
130
|
reject(new FetchError(`request to ${request.url} failed, reason: ${
|
|
111
131
|
er.message}`, 'system', er))
|
|
112
132
|
finalize()
|
|
@@ -124,98 +144,103 @@ const fetch = (url, opts) => {
|
|
|
124
144
|
|
|
125
145
|
// HTTP fetch step 5.3
|
|
126
146
|
const locationURL = location === null ? null
|
|
127
|
-
:
|
|
147
|
+
: (new URL(location, request.url)).toString()
|
|
128
148
|
|
|
129
149
|
// HTTP fetch step 5.5
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
if (request.redirect === 'error') {
|
|
151
|
+
reject(new FetchError('uri requested responds with a redirect, ' +
|
|
152
|
+
`redirect mode is set to error: ${request.url}`, 'no-redirect'))
|
|
153
|
+
finalize()
|
|
154
|
+
return
|
|
155
|
+
} else if (request.redirect === 'manual') {
|
|
156
|
+
// node-fetch-specific step: make manual redirect a bit easier to
|
|
157
|
+
// use by setting the Location header value to the resolved URL.
|
|
158
|
+
if (locationURL !== null) {
|
|
159
|
+
// handle corrupted header
|
|
160
|
+
try {
|
|
161
|
+
headers.set('Location', locationURL)
|
|
162
|
+
} catch (err) {
|
|
163
|
+
/* istanbul ignore next: nodejs server prevent invalid
|
|
164
|
+
response headers, we can't test this through normal
|
|
165
|
+
request */
|
|
166
|
+
reject(err)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} else if (request.redirect === 'follow' && locationURL !== null) {
|
|
170
|
+
// HTTP-redirect fetch step 5
|
|
171
|
+
if (request.counter >= request.follow) {
|
|
172
|
+
reject(new FetchError(`maximum redirect reached at: ${
|
|
173
|
+
request.url}`, 'max-redirect'))
|
|
134
174
|
finalize()
|
|
135
175
|
return
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
response headers, we can't test this through normal
|
|
147
|
-
request */
|
|
148
|
-
reject(err)
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
break
|
|
152
|
-
|
|
153
|
-
case 'follow':
|
|
154
|
-
// HTTP-redirect fetch step 2
|
|
155
|
-
if (locationURL === null) {
|
|
156
|
-
break
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// HTTP-redirect fetch step 5
|
|
160
|
-
if (request.counter >= request.follow) {
|
|
161
|
-
reject(new FetchError(`maximum redirect reached at: ${
|
|
162
|
-
request.url}`, 'max-redirect'))
|
|
163
|
-
finalize()
|
|
164
|
-
return
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// HTTP-redirect fetch step 9
|
|
168
|
-
if (res.statusCode !== 303 &&
|
|
169
|
-
request.body &&
|
|
170
|
-
getTotalBytes(request) === null) {
|
|
171
|
-
reject(new FetchError(
|
|
172
|
-
'Cannot follow redirect with body being a readable stream',
|
|
173
|
-
'unsupported-redirect'
|
|
174
|
-
))
|
|
175
|
-
finalize()
|
|
176
|
-
return
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Update host due to redirection
|
|
180
|
-
request.headers.set('host', Url.parse(locationURL).host)
|
|
181
|
-
|
|
182
|
-
// HTTP-redirect fetch step 6 (counter increment)
|
|
183
|
-
// Create a new Request object.
|
|
184
|
-
const requestOpts = {
|
|
185
|
-
headers: new Headers(request.headers),
|
|
186
|
-
follow: request.follow,
|
|
187
|
-
counter: request.counter + 1,
|
|
188
|
-
agent: request.agent,
|
|
189
|
-
compress: request.compress,
|
|
190
|
-
method: request.method,
|
|
191
|
-
body: request.body,
|
|
192
|
-
signal: request.signal,
|
|
193
|
-
timeout: request.timeout,
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// HTTP-redirect fetch step 11
|
|
197
|
-
if (res.statusCode === 303 || (
|
|
198
|
-
(res.statusCode === 301 || res.statusCode === 302) &&
|
|
199
|
-
request.method === 'POST'
|
|
200
|
-
)) {
|
|
201
|
-
requestOpts.method = 'GET'
|
|
202
|
-
requestOpts.body = undefined
|
|
203
|
-
requestOpts.headers.delete('content-length')
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// HTTP-redirect fetch step 15
|
|
207
|
-
resolve(fetch(new Request(locationURL, requestOpts)))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// HTTP-redirect fetch step 9
|
|
179
|
+
if (res.statusCode !== 303 &&
|
|
180
|
+
request.body &&
|
|
181
|
+
getTotalBytes(request) === null) {
|
|
182
|
+
reject(new FetchError(
|
|
183
|
+
'Cannot follow redirect with body being a readable stream',
|
|
184
|
+
'unsupported-redirect'
|
|
185
|
+
))
|
|
208
186
|
finalize()
|
|
209
187
|
return
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Update host due to redirection
|
|
191
|
+
request.headers.set('host', (new URL(locationURL)).host)
|
|
192
|
+
|
|
193
|
+
// HTTP-redirect fetch step 6 (counter increment)
|
|
194
|
+
// Create a new Request object.
|
|
195
|
+
const requestOpts = {
|
|
196
|
+
headers: new Headers(request.headers),
|
|
197
|
+
follow: request.follow,
|
|
198
|
+
counter: request.counter + 1,
|
|
199
|
+
agent: request.agent,
|
|
200
|
+
compress: request.compress,
|
|
201
|
+
method: request.method,
|
|
202
|
+
body: request.body,
|
|
203
|
+
signal: request.signal,
|
|
204
|
+
timeout: request.timeout,
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// if the redirect is to a new hostname, strip the authorization and cookie headers
|
|
208
|
+
const parsedOriginal = new URL(request.url)
|
|
209
|
+
const parsedRedirect = new URL(locationURL)
|
|
210
|
+
if (parsedOriginal.hostname !== parsedRedirect.hostname) {
|
|
211
|
+
requestOpts.headers.delete('authorization')
|
|
212
|
+
requestOpts.headers.delete('cookie')
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// HTTP-redirect fetch step 11
|
|
216
|
+
if (res.statusCode === 303 || (
|
|
217
|
+
(res.statusCode === 301 || res.statusCode === 302) &&
|
|
218
|
+
request.method === 'POST'
|
|
219
|
+
)) {
|
|
220
|
+
requestOpts.method = 'GET'
|
|
221
|
+
requestOpts.body = undefined
|
|
222
|
+
requestOpts.headers.delete('content-length')
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// HTTP-redirect fetch step 15
|
|
226
|
+
resolve(fetch(new Request(locationURL, requestOpts)))
|
|
227
|
+
finalize()
|
|
228
|
+
return
|
|
210
229
|
}
|
|
211
230
|
} // end if(isRedirect)
|
|
212
231
|
|
|
213
|
-
|
|
214
232
|
// prepare response
|
|
215
233
|
res.once('end', () =>
|
|
216
234
|
signal && signal.removeEventListener('abort', abortAndFinalize))
|
|
217
235
|
|
|
218
236
|
const body = new Minipass()
|
|
237
|
+
// if an error occurs, either on the response stream itself, on one of the
|
|
238
|
+
// decoder streams, or a response length timeout from the Body class, we
|
|
239
|
+
// forward the error through to our internal body stream. If we see an
|
|
240
|
+
// error event on that, we call finalize to abort the request and ensure
|
|
241
|
+
// we don't leave a socket believing a request is in flight.
|
|
242
|
+
// this is difficult to test, so lacks specific coverage.
|
|
243
|
+
body.on('error', finalize)
|
|
219
244
|
// exceedingly rare that the stream would have an error,
|
|
220
245
|
// but just in case we proxy it to the stream in use.
|
|
221
246
|
res.on('error', /* istanbul ignore next */ er => body.emit('error', er))
|
|
@@ -230,8 +255,8 @@ const fetch = (url, opts) => {
|
|
|
230
255
|
size: request.size,
|
|
231
256
|
timeout: request.timeout,
|
|
232
257
|
counter: request.counter,
|
|
233
|
-
trailer: new Promise(
|
|
234
|
-
res.on('end', () =>
|
|
258
|
+
trailer: new Promise(resolveTrailer =>
|
|
259
|
+
res.on('end', () => resolveTrailer(createHeadersLenient(res.trailers)))),
|
|
235
260
|
}
|
|
236
261
|
|
|
237
262
|
// HTTP-network fetch step 12.1.1.3
|
|
@@ -255,7 +280,6 @@ const fetch = (url, opts) => {
|
|
|
255
280
|
return
|
|
256
281
|
}
|
|
257
282
|
|
|
258
|
-
|
|
259
283
|
// Be less strict when decoding compressed responses, since sometimes
|
|
260
284
|
// servers send slightly invalid responses that are still accepted
|
|
261
285
|
// by common browsers.
|
|
@@ -266,7 +290,7 @@ const fetch = (url, opts) => {
|
|
|
266
290
|
}
|
|
267
291
|
|
|
268
292
|
// for gzip
|
|
269
|
-
if (codings
|
|
293
|
+
if (codings === 'gzip' || codings === 'x-gzip') {
|
|
270
294
|
const unzip = new zlib.Gunzip(zlibOptions)
|
|
271
295
|
response = new Response(
|
|
272
296
|
// exceedingly rare that the stream would have an error,
|
|
@@ -279,7 +303,7 @@ const fetch = (url, opts) => {
|
|
|
279
303
|
}
|
|
280
304
|
|
|
281
305
|
// for deflate
|
|
282
|
-
if (codings
|
|
306
|
+
if (codings === 'deflate' || codings === 'x-deflate') {
|
|
283
307
|
// handle the infamous raw deflate response from old servers
|
|
284
308
|
// a hack for old IIS and Apache servers
|
|
285
309
|
const raw = res.pipe(new Minipass())
|
|
@@ -297,9 +321,8 @@ const fetch = (url, opts) => {
|
|
|
297
321
|
return
|
|
298
322
|
}
|
|
299
323
|
|
|
300
|
-
|
|
301
324
|
// for br
|
|
302
|
-
if (codings
|
|
325
|
+
if (codings === 'br') {
|
|
303
326
|
// ignoring coverage so tests don't have to fake support (or lack of) for brotli
|
|
304
327
|
// istanbul ignore next
|
|
305
328
|
try {
|
|
@@ -339,3 +362,4 @@ fetch.Headers = Headers
|
|
|
339
362
|
fetch.Request = Request
|
|
340
363
|
fetch.Response = Response
|
|
341
364
|
fetch.FetchError = FetchError
|
|
365
|
+
fetch.AbortError = AbortError
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const
|
|
2
|
+
const { URL } = require('url')
|
|
3
3
|
const Minipass = require('minipass')
|
|
4
4
|
const Headers = require('./headers.js')
|
|
5
5
|
const { exportNodeCompatibleHeaders } = Headers
|
|
@@ -12,8 +12,6 @@ const defaultUserAgent =
|
|
|
12
12
|
|
|
13
13
|
const INTERNALS = Symbol('Request internals')
|
|
14
14
|
|
|
15
|
-
const { parse: parseUrl, format: formatUrl } = Url
|
|
16
|
-
|
|
17
15
|
const isRequest = input =>
|
|
18
16
|
typeof input === 'object' && typeof input[INTERNALS] === 'object'
|
|
19
17
|
|
|
@@ -28,21 +26,23 @@ const isAbortSignal = signal => {
|
|
|
28
26
|
|
|
29
27
|
class Request extends Body {
|
|
30
28
|
constructor (input, init = {}) {
|
|
31
|
-
const parsedURL = isRequest(input) ?
|
|
32
|
-
: input && input.href ?
|
|
33
|
-
:
|
|
29
|
+
const parsedURL = isRequest(input) ? new URL(input.url)
|
|
30
|
+
: input && input.href ? new URL(input.href)
|
|
31
|
+
: new URL(`${input}`)
|
|
34
32
|
|
|
35
|
-
if (isRequest(input))
|
|
33
|
+
if (isRequest(input)) {
|
|
36
34
|
init = { ...input[INTERNALS], ...init }
|
|
37
|
-
else if (!input || typeof input === 'string')
|
|
35
|
+
} else if (!input || typeof input === 'string') {
|
|
38
36
|
input = {}
|
|
37
|
+
}
|
|
39
38
|
|
|
40
39
|
const method = (init.method || input.method || 'GET').toUpperCase()
|
|
41
40
|
const isGETHEAD = method === 'GET' || method === 'HEAD'
|
|
42
41
|
|
|
43
42
|
if ((init.body !== null && init.body !== undefined ||
|
|
44
|
-
isRequest(input) && input.body !== null) && isGETHEAD)
|
|
43
|
+
isRequest(input) && input.body !== null) && isGETHEAD) {
|
|
45
44
|
throw new TypeError('Request with GET/HEAD method cannot have body')
|
|
45
|
+
}
|
|
46
46
|
|
|
47
47
|
const inputBody = init.body !== null && init.body !== undefined ? init.body
|
|
48
48
|
: isRequest(input) && input.body !== null ? clone(input)
|
|
@@ -58,15 +58,17 @@ class Request extends Body {
|
|
|
58
58
|
if (inputBody !== null && inputBody !== undefined &&
|
|
59
59
|
!headers.has('Content-Type')) {
|
|
60
60
|
const contentType = extractContentType(inputBody)
|
|
61
|
-
if (contentType)
|
|
61
|
+
if (contentType) {
|
|
62
62
|
headers.append('Content-Type', contentType)
|
|
63
|
+
}
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
const signal = 'signal' in init ? init.signal
|
|
66
67
|
: null
|
|
67
68
|
|
|
68
|
-
if (signal !== null && signal !== undefined && !isAbortSignal(signal))
|
|
69
|
+
if (signal !== null && signal !== undefined && !isAbortSignal(signal)) {
|
|
69
70
|
throw new TypeError('Expected signal must be an instanceof AbortSignal')
|
|
71
|
+
}
|
|
70
72
|
|
|
71
73
|
// TLS specific options that are handled by node
|
|
72
74
|
const {
|
|
@@ -125,23 +127,23 @@ class Request extends Body {
|
|
|
125
127
|
this.agent = init.agent || input.agent
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
get method() {
|
|
130
|
+
get method () {
|
|
129
131
|
return this[INTERNALS].method
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
get url() {
|
|
133
|
-
return
|
|
134
|
+
get url () {
|
|
135
|
+
return this[INTERNALS].parsedURL.toString()
|
|
134
136
|
}
|
|
135
137
|
|
|
136
|
-
get headers() {
|
|
138
|
+
get headers () {
|
|
137
139
|
return this[INTERNALS].headers
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
get redirect() {
|
|
142
|
+
get redirect () {
|
|
141
143
|
return this[INTERNALS].redirect
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
get signal() {
|
|
146
|
+
get signal () {
|
|
145
147
|
return this[INTERNALS].signal
|
|
146
148
|
}
|
|
147
149
|
|
|
@@ -158,15 +160,14 @@ class Request extends Body {
|
|
|
158
160
|
const headers = new Headers(request[INTERNALS].headers)
|
|
159
161
|
|
|
160
162
|
// fetch step 1.3
|
|
161
|
-
if (!headers.has('Accept'))
|
|
163
|
+
if (!headers.has('Accept')) {
|
|
162
164
|
headers.set('Accept', '*/*')
|
|
165
|
+
}
|
|
163
166
|
|
|
164
167
|
// Basic fetch
|
|
165
|
-
if (
|
|
166
|
-
throw new TypeError('Only absolute URLs are supported')
|
|
167
|
-
|
|
168
|
-
if (!/^https?:$/.test(parsedURL.protocol))
|
|
168
|
+
if (!/^https?:$/.test(parsedURL.protocol)) {
|
|
169
169
|
throw new TypeError('Only HTTP(S) protocols are supported')
|
|
170
|
+
}
|
|
170
171
|
|
|
171
172
|
if (request.signal &&
|
|
172
173
|
Minipass.isStream(request.body) &&
|
|
@@ -181,25 +182,29 @@ class Request extends Body {
|
|
|
181
182
|
/^(POST|PUT)$/i.test(request.method) ? '0'
|
|
182
183
|
: request.body !== null && request.body !== undefined
|
|
183
184
|
? getTotalBytes(request)
|
|
184
|
-
|
|
185
|
+
: null
|
|
185
186
|
|
|
186
|
-
if (contentLengthValue)
|
|
187
|
+
if (contentLengthValue) {
|
|
187
188
|
headers.set('Content-Length', contentLengthValue + '')
|
|
189
|
+
}
|
|
188
190
|
|
|
189
191
|
// HTTP-network-or-cache fetch step 2.11
|
|
190
|
-
if (!headers.has('User-Agent'))
|
|
192
|
+
if (!headers.has('User-Agent')) {
|
|
191
193
|
headers.set('User-Agent', defaultUserAgent)
|
|
194
|
+
}
|
|
192
195
|
|
|
193
196
|
// HTTP-network-or-cache fetch step 2.15
|
|
194
|
-
if (request.compress && !headers.has('Accept-Encoding'))
|
|
197
|
+
if (request.compress && !headers.has('Accept-Encoding')) {
|
|
195
198
|
headers.set('Accept-Encoding', 'gzip,deflate')
|
|
199
|
+
}
|
|
196
200
|
|
|
197
201
|
const agent = typeof request.agent === 'function'
|
|
198
202
|
? request.agent(parsedURL)
|
|
199
203
|
: request.agent
|
|
200
204
|
|
|
201
|
-
if (!headers.has('Connection') && !agent)
|
|
205
|
+
if (!headers.has('Connection') && !agent) {
|
|
202
206
|
headers.set('Connection', 'close')
|
|
207
|
+
}
|
|
203
208
|
|
|
204
209
|
// TLS specific options that are handled by node
|
|
205
210
|
const {
|
|
@@ -225,8 +230,21 @@ class Request extends Body {
|
|
|
225
230
|
// HTTP-network fetch step 4.2
|
|
226
231
|
// chunked encoding is handled by Node.js
|
|
227
232
|
|
|
233
|
+
// we cannot spread parsedURL directly, so we have to read each property one-by-one
|
|
234
|
+
// and map them to the equivalent https?.request() method options
|
|
235
|
+
const urlProps = {
|
|
236
|
+
auth: parsedURL.username || parsedURL.password
|
|
237
|
+
? `${parsedURL.username}:${parsedURL.password}`
|
|
238
|
+
: '',
|
|
239
|
+
host: parsedURL.host,
|
|
240
|
+
hostname: parsedURL.hostname,
|
|
241
|
+
path: `${parsedURL.pathname}${parsedURL.search}`,
|
|
242
|
+
port: parsedURL.port,
|
|
243
|
+
protocol: parsedURL.protocol,
|
|
244
|
+
}
|
|
245
|
+
|
|
228
246
|
return {
|
|
229
|
-
...
|
|
247
|
+
...urlProps,
|
|
230
248
|
method: request.method,
|
|
231
249
|
headers: exportNodeCompatibleHeaders(headers),
|
|
232
250
|
agent,
|
|
@@ -17,8 +17,9 @@ class Response extends Body {
|
|
|
17
17
|
|
|
18
18
|
if (body !== null && body !== undefined && !headers.has('Content-Type')) {
|
|
19
19
|
const contentType = extractContentType(body)
|
|
20
|
-
if (contentType)
|
|
20
|
+
if (contentType) {
|
|
21
21
|
headers.append('Content-Type', contentType)
|
|
22
|
+
}
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
this[INTERNALS] = {
|
|
@@ -43,7 +44,7 @@ class Response extends Body {
|
|
|
43
44
|
return this[INTERNALS].status
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
get ok ()
|
|
47
|
+
get ok () {
|
|
47
48
|
return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minipass-fetch",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "An implementation of window.fetch in Node.js using Minipass streams",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -9,33 +9,41 @@
|
|
|
9
9
|
"snap": "tap",
|
|
10
10
|
"preversion": "npm test",
|
|
11
11
|
"postversion": "npm publish",
|
|
12
|
-
"postpublish": "git push origin --follow-tags"
|
|
12
|
+
"postpublish": "git push origin --follow-tags",
|
|
13
|
+
"lint": "eslint \"**/*.js\"",
|
|
14
|
+
"postlint": "template-oss-check",
|
|
15
|
+
"lintfix": "npm run lint -- --fix",
|
|
16
|
+
"prepublishOnly": "git push origin --follow-tags",
|
|
17
|
+
"posttest": "npm run lint",
|
|
18
|
+
"template-oss-apply": "template-oss-apply --force"
|
|
13
19
|
},
|
|
14
20
|
"tap": {
|
|
15
21
|
"coverage-map": "map.js",
|
|
16
22
|
"check-coverage": true
|
|
17
23
|
},
|
|
18
24
|
"devDependencies": {
|
|
19
|
-
"@
|
|
25
|
+
"@npmcli/eslint-config": "^3.0.1",
|
|
26
|
+
"@npmcli/template-oss": "3.1.2",
|
|
27
|
+
"@ungap/url-search-params": "^0.2.2",
|
|
20
28
|
"abort-controller": "^3.0.0",
|
|
21
|
-
"abortcontroller-polyfill": "~1.3
|
|
22
|
-
"form-data": "^
|
|
29
|
+
"abortcontroller-polyfill": "~1.7.3",
|
|
30
|
+
"form-data": "^4.0.0",
|
|
31
|
+
"nock": "^13.2.4",
|
|
23
32
|
"parted": "^0.1.1",
|
|
24
33
|
"string-to-arraybuffer": "^1.0.2",
|
|
25
|
-
"tap": "^
|
|
26
|
-
"whatwg-url": "^7.0.0"
|
|
34
|
+
"tap": "^16.0.0"
|
|
27
35
|
},
|
|
28
36
|
"dependencies": {
|
|
29
|
-
"minipass": "^3.1.
|
|
37
|
+
"minipass": "^3.1.6",
|
|
30
38
|
"minipass-sized": "^1.0.3",
|
|
31
|
-
"minizlib": "^2.
|
|
39
|
+
"minizlib": "^2.1.2"
|
|
32
40
|
},
|
|
33
41
|
"optionalDependencies": {
|
|
34
|
-
"encoding": "^0.1.
|
|
42
|
+
"encoding": "^0.1.13"
|
|
35
43
|
},
|
|
36
44
|
"repository": {
|
|
37
45
|
"type": "git",
|
|
38
|
-
"url": "
|
|
46
|
+
"url": "https://github.com/npm/minipass-fetch.git"
|
|
39
47
|
},
|
|
40
48
|
"keywords": [
|
|
41
49
|
"fetch",
|
|
@@ -44,10 +52,15 @@
|
|
|
44
52
|
"window.fetch"
|
|
45
53
|
],
|
|
46
54
|
"files": [
|
|
47
|
-
"
|
|
48
|
-
"lib
|
|
55
|
+
"bin/",
|
|
56
|
+
"lib/"
|
|
49
57
|
],
|
|
50
58
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
59
|
+
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
|
60
|
+
},
|
|
61
|
+
"author": "GitHub Inc.",
|
|
62
|
+
"templateOSS": {
|
|
63
|
+
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
64
|
+
"version": "3.1.2"
|
|
52
65
|
}
|
|
53
66
|
}
|
|
@@ -1,45 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
|
2
|
+
# TODO: Line 48, enable pytest --doctest-modules
|
|
2
3
|
|
|
3
4
|
name: Tests
|
|
4
|
-
on:
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [ main ]
|
|
5
10
|
jobs:
|
|
6
11
|
Tests:
|
|
7
12
|
strategy:
|
|
8
13
|
fail-fast: false
|
|
9
14
|
max-parallel: 15
|
|
10
15
|
matrix:
|
|
11
|
-
node: [
|
|
16
|
+
node: [14.x, 16.x, 18.x]
|
|
12
17
|
python: ["3.6", "3.8", "3.10"]
|
|
13
18
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
|
14
19
|
runs-on: ${{ matrix.os }}
|
|
15
20
|
steps:
|
|
16
21
|
- name: Checkout Repository
|
|
17
|
-
uses: actions/checkout@
|
|
22
|
+
uses: actions/checkout@v3
|
|
18
23
|
- name: Use Node.js ${{ matrix.node }}
|
|
19
|
-
uses: actions/setup-node@
|
|
24
|
+
uses: actions/setup-node@v3
|
|
20
25
|
with:
|
|
21
26
|
node-version: ${{ matrix.node }}
|
|
22
27
|
- name: Use Python ${{ matrix.python }}
|
|
23
|
-
uses: actions/setup-python@
|
|
28
|
+
uses: actions/setup-python@v4
|
|
24
29
|
with:
|
|
25
30
|
python-version: ${{ matrix.python }}
|
|
26
31
|
env:
|
|
27
|
-
PYTHON_VERSION: ${{ matrix.python }}
|
|
32
|
+
PYTHON_VERSION: ${{ matrix.python }} # Why do this?
|
|
28
33
|
- name: Install Dependencies
|
|
29
34
|
run: |
|
|
30
35
|
npm install --no-progress
|
|
31
36
|
pip install flake8 pytest
|
|
32
37
|
- name: Set Windows environment
|
|
33
|
-
if: matrix.os
|
|
38
|
+
if: startsWith(matrix.os, 'windows')
|
|
34
39
|
run: |
|
|
35
40
|
echo 'GYP_MSVS_VERSION=2015' >> $Env:GITHUB_ENV
|
|
36
41
|
echo 'GYP_MSVS_OVERRIDE_PATH=C:\\Dummy' >> $Env:GITHUB_ENV
|
|
37
42
|
- name: Lint Python
|
|
38
|
-
if: matrix.os
|
|
43
|
+
if: startsWith(matrix.os, 'ubuntu')
|
|
39
44
|
run: flake8 . --ignore=E203,W503 --max-complexity=101 --max-line-length=88 --show-source --statistics
|
|
40
45
|
- name: Run Python tests
|
|
41
46
|
run: python -m pytest
|
|
42
47
|
# - name: Run doctests with pytest
|
|
43
48
|
# run: python -m pytest --doctest-modules
|
|
49
|
+
- name: Environment Information
|
|
50
|
+
run: npx envinfo
|
|
44
51
|
- name: Run Node tests
|
|
45
52
|
run: npm test
|