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
|
@@ -2,19 +2,6 @@ const CacheSemantics = require('http-cache-semantics')
|
|
|
2
2
|
const Negotiator = require('negotiator')
|
|
3
3
|
const ssri = require('ssri')
|
|
4
4
|
|
|
5
|
-
// HACK: negotiator lazy loads several of its own modules
|
|
6
|
-
// as a micro optimization. we need to be sure that they're
|
|
7
|
-
// in memory as soon as possible at startup so that we do
|
|
8
|
-
// not try to lazy load them after the directory has been
|
|
9
|
-
// retired during a self update of the npm CLI, we do this
|
|
10
|
-
// by calling all of the methods that trigger a lazy load
|
|
11
|
-
// on a fake instance.
|
|
12
|
-
const preloadNegotiator = new Negotiator({ headers: {} })
|
|
13
|
-
preloadNegotiator.charsets()
|
|
14
|
-
preloadNegotiator.encodings()
|
|
15
|
-
preloadNegotiator.languages()
|
|
16
|
-
preloadNegotiator.mediaTypes()
|
|
17
|
-
|
|
18
5
|
// options passed to http-cache-semantics constructor
|
|
19
6
|
const policyOptions = {
|
|
20
7
|
shared: false,
|
|
@@ -31,6 +18,7 @@ const requestObject = (request) => {
|
|
|
31
18
|
method: request.method,
|
|
32
19
|
url: request.url,
|
|
33
20
|
headers: {},
|
|
21
|
+
compress: request.compress,
|
|
34
22
|
}
|
|
35
23
|
|
|
36
24
|
request.headers.forEach((value, key) => {
|
|
@@ -74,16 +62,19 @@ class CachePolicy {
|
|
|
74
62
|
// static method to quickly determine if a request alone is storable
|
|
75
63
|
static storable (request, options) {
|
|
76
64
|
// no cachePath means no caching
|
|
77
|
-
if (!options.cachePath)
|
|
65
|
+
if (!options.cachePath) {
|
|
78
66
|
return false
|
|
67
|
+
}
|
|
79
68
|
|
|
80
69
|
// user explicitly asked not to cache
|
|
81
|
-
if (options.cache === 'no-store')
|
|
70
|
+
if (options.cache === 'no-store') {
|
|
82
71
|
return false
|
|
72
|
+
}
|
|
83
73
|
|
|
84
74
|
// we only cache GET and HEAD requests
|
|
85
|
-
if (!['GET', 'HEAD'].includes(request.method))
|
|
75
|
+
if (!['GET', 'HEAD'].includes(request.method)) {
|
|
86
76
|
return false
|
|
77
|
+
}
|
|
87
78
|
|
|
88
79
|
// otherwise, let http-cache-semantics make the decision
|
|
89
80
|
// based on the request's headers
|
|
@@ -94,23 +85,32 @@ class CachePolicy {
|
|
|
94
85
|
// returns true if the policy satisfies the request
|
|
95
86
|
satisfies (request) {
|
|
96
87
|
const _req = requestObject(request)
|
|
97
|
-
if (this.request.headers.host !== _req.headers.host)
|
|
88
|
+
if (this.request.headers.host !== _req.headers.host) {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.request.compress !== _req.compress) {
|
|
98
93
|
return false
|
|
94
|
+
}
|
|
99
95
|
|
|
100
96
|
const negotiatorA = new Negotiator(this.request)
|
|
101
97
|
const negotiatorB = new Negotiator(_req)
|
|
102
98
|
|
|
103
|
-
if (JSON.stringify(negotiatorA.mediaTypes()) !== JSON.stringify(negotiatorB.mediaTypes()))
|
|
99
|
+
if (JSON.stringify(negotiatorA.mediaTypes()) !== JSON.stringify(negotiatorB.mediaTypes())) {
|
|
104
100
|
return false
|
|
101
|
+
}
|
|
105
102
|
|
|
106
|
-
if (JSON.stringify(negotiatorA.languages()) !== JSON.stringify(negotiatorB.languages()))
|
|
103
|
+
if (JSON.stringify(negotiatorA.languages()) !== JSON.stringify(negotiatorB.languages())) {
|
|
107
104
|
return false
|
|
105
|
+
}
|
|
108
106
|
|
|
109
|
-
if (JSON.stringify(negotiatorA.encodings()) !== JSON.stringify(negotiatorB.encodings()))
|
|
107
|
+
if (JSON.stringify(negotiatorA.encodings()) !== JSON.stringify(negotiatorB.encodings())) {
|
|
110
108
|
return false
|
|
109
|
+
}
|
|
111
110
|
|
|
112
|
-
if (this.options.integrity)
|
|
111
|
+
if (this.options.integrity) {
|
|
113
112
|
return ssri.parse(this.options.integrity).match(this.entry.integrity)
|
|
113
|
+
}
|
|
114
114
|
|
|
115
115
|
return true
|
|
116
116
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const LRUCache = require('lru-cache')
|
|
2
|
+
const dns = require('dns')
|
|
3
|
+
|
|
4
|
+
const defaultOptions = exports.defaultOptions = {
|
|
5
|
+
family: undefined,
|
|
6
|
+
hints: dns.ADDRCONFIG,
|
|
7
|
+
all: false,
|
|
8
|
+
verbatim: undefined,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const lookupCache = exports.lookupCache = new LRUCache({ max: 50 })
|
|
12
|
+
|
|
13
|
+
// this is a factory so that each request can have its own opts (i.e. ttl)
|
|
14
|
+
// while still sharing the cache across all requests
|
|
15
|
+
exports.getLookup = (dnsOptions) => {
|
|
16
|
+
return (hostname, options, callback) => {
|
|
17
|
+
if (typeof options === 'function') {
|
|
18
|
+
callback = options
|
|
19
|
+
options = null
|
|
20
|
+
} else if (typeof options === 'number') {
|
|
21
|
+
options = { family: options }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
options = { ...defaultOptions, ...options }
|
|
25
|
+
|
|
26
|
+
const key = JSON.stringify({
|
|
27
|
+
hostname,
|
|
28
|
+
family: options.family,
|
|
29
|
+
hints: options.hints,
|
|
30
|
+
all: options.all,
|
|
31
|
+
verbatim: options.verbatim,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
if (lookupCache.has(key)) {
|
|
35
|
+
const [address, family] = lookupCache.get(key)
|
|
36
|
+
process.nextTick(callback, null, address, family)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
dnsOptions.lookup(hostname, options, (err, address, family) => {
|
|
41
|
+
if (err) {
|
|
42
|
+
return callback(err)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
lookupCache.set(key, [address, family], { ttl: dnsOptions.ttl })
|
|
46
|
+
return callback(null, address, family)
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -13,20 +13,28 @@ const remote = require('./remote.js')
|
|
|
13
13
|
// in the fetch being rejected if the redirect is
|
|
14
14
|
// possible but invalid for some reason
|
|
15
15
|
const canFollowRedirect = (request, response, options) => {
|
|
16
|
-
if (!isRedirect(response.status))
|
|
16
|
+
if (!isRedirect(response.status)) {
|
|
17
17
|
return false
|
|
18
|
+
}
|
|
18
19
|
|
|
19
|
-
if (options.redirect === 'manual')
|
|
20
|
+
if (options.redirect === 'manual') {
|
|
20
21
|
return false
|
|
22
|
+
}
|
|
21
23
|
|
|
22
|
-
if (options.redirect === 'error')
|
|
23
|
-
throw new FetchError(`redirect mode is set to error: ${request.url}`,
|
|
24
|
+
if (options.redirect === 'error') {
|
|
25
|
+
throw new FetchError(`redirect mode is set to error: ${request.url}`,
|
|
26
|
+
'no-redirect', { code: 'ENOREDIRECT' })
|
|
27
|
+
}
|
|
24
28
|
|
|
25
|
-
if (!response.headers.has('location'))
|
|
26
|
-
throw new FetchError(`redirect location header missing for: ${request.url}`,
|
|
29
|
+
if (!response.headers.has('location')) {
|
|
30
|
+
throw new FetchError(`redirect location header missing for: ${request.url}`,
|
|
31
|
+
'no-location', { code: 'EINVALIDREDIRECT' })
|
|
32
|
+
}
|
|
27
33
|
|
|
28
|
-
if (request.counter >= request.follow)
|
|
29
|
-
throw new FetchError(`maximum redirect reached at: ${request.url}`,
|
|
34
|
+
if (request.counter >= request.follow) {
|
|
35
|
+
throw new FetchError(`maximum redirect reached at: ${request.url}`,
|
|
36
|
+
'max-redirect', { code: 'EMAXREDIRECT' })
|
|
37
|
+
}
|
|
30
38
|
|
|
31
39
|
return true
|
|
32
40
|
}
|
|
@@ -39,26 +47,34 @@ const getRedirect = (request, response, options) => {
|
|
|
39
47
|
const location = response.headers.get('location')
|
|
40
48
|
const redirectUrl = new url.URL(location, /^https?:/.test(location) ? undefined : request.url)
|
|
41
49
|
// Comment below is used under the following license:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @license
|
|
52
|
+
* Copyright (c) 2010-2012 Mikeal Rogers
|
|
53
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
54
|
+
* you may not use this file except in compliance with the License.
|
|
55
|
+
* You may obtain a copy of the License at
|
|
56
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
57
|
+
* Unless required by applicable law or agreed to in writing,
|
|
58
|
+
* software distributed under the License is distributed on an "AS
|
|
59
|
+
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
|
60
|
+
* express or implied. See the License for the specific language
|
|
61
|
+
* governing permissions and limitations under the License.
|
|
62
|
+
*/
|
|
52
63
|
|
|
53
64
|
// Remove authorization if changing hostnames (but not if just
|
|
54
65
|
// changing ports or protocols). This matches the behavior of request:
|
|
55
66
|
// https://github.com/request/request/blob/b12a6245/lib/redirect.js#L134-L138
|
|
56
|
-
if (new url.URL(request.url).hostname !== redirectUrl.hostname)
|
|
67
|
+
if (new url.URL(request.url).hostname !== redirectUrl.hostname) {
|
|
57
68
|
request.headers.delete('authorization')
|
|
69
|
+
request.headers.delete('cookie')
|
|
70
|
+
}
|
|
58
71
|
|
|
59
72
|
// for POST request with 301/302 response, or any request with 303 response,
|
|
60
73
|
// use GET when following redirect
|
|
61
|
-
if (
|
|
74
|
+
if (
|
|
75
|
+
response.status === 303 ||
|
|
76
|
+
(request.method === 'POST' && [301, 302].includes(response.status))
|
|
77
|
+
) {
|
|
62
78
|
_opts.method = 'GET'
|
|
63
79
|
_opts.body = null
|
|
64
80
|
request.headers.delete('content-length')
|
|
@@ -87,11 +103,13 @@ const fetch = async (request, options) => {
|
|
|
87
103
|
// request url
|
|
88
104
|
if (!['GET', 'HEAD'].includes(request.method) &&
|
|
89
105
|
response.status >= 200 &&
|
|
90
|
-
response.status <= 399)
|
|
106
|
+
response.status <= 399) {
|
|
91
107
|
await cache.invalidate(request, options)
|
|
108
|
+
}
|
|
92
109
|
|
|
93
|
-
if (!canFollowRedirect(request, response, options))
|
|
110
|
+
if (!canFollowRedirect(request, response, options)) {
|
|
94
111
|
return response
|
|
112
|
+
}
|
|
95
113
|
|
|
96
114
|
const redirect = getRedirect(request, response, options)
|
|
97
115
|
return fetch(redirect.request, redirect.options)
|
|
@@ -10,7 +10,7 @@ const makeFetchHappen = (url, opts) => {
|
|
|
10
10
|
return fetch(request, options)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
makeFetchHappen.defaults = (defaultUrl, defaultOptions = {}) => {
|
|
13
|
+
makeFetchHappen.defaults = (defaultUrl, defaultOptions = {}, wrappedFetch = makeFetchHappen) => {
|
|
14
14
|
if (typeof defaultUrl === 'object') {
|
|
15
15
|
defaultOptions = defaultUrl
|
|
16
16
|
defaultUrl = null
|
|
@@ -26,10 +26,11 @@ makeFetchHappen.defaults = (defaultUrl, defaultOptions = {}) => {
|
|
|
26
26
|
...options.headers,
|
|
27
27
|
},
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return wrappedFetch(finalUrl, finalOptions)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
defaultedFetch.defaults =
|
|
32
|
+
defaultedFetch.defaults = (defaultUrl1, defaultOptions1 = {}) =>
|
|
33
|
+
makeFetchHappen.defaults(defaultUrl1, defaultOptions1, defaultedFetch)
|
|
33
34
|
return defaultedFetch
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const dns = require('dns')
|
|
2
|
+
|
|
1
3
|
const conditionalHeaders = [
|
|
2
4
|
'if-modified-since',
|
|
3
5
|
'if-none-match',
|
|
@@ -7,36 +9,42 @@ const conditionalHeaders = [
|
|
|
7
9
|
]
|
|
8
10
|
|
|
9
11
|
const configureOptions = (opts) => {
|
|
10
|
-
const {strictSSL, ...options} = { ...opts }
|
|
12
|
+
const { strictSSL, ...options } = { ...opts }
|
|
11
13
|
options.method = options.method ? options.method.toUpperCase() : 'GET'
|
|
12
14
|
options.rejectUnauthorized = strictSSL !== false
|
|
13
15
|
|
|
14
|
-
if (!options.retry)
|
|
16
|
+
if (!options.retry) {
|
|
15
17
|
options.retry = { retries: 0 }
|
|
16
|
-
else if (typeof options.retry === 'string') {
|
|
18
|
+
} else if (typeof options.retry === 'string') {
|
|
17
19
|
const retries = parseInt(options.retry, 10)
|
|
18
|
-
if (isFinite(retries))
|
|
20
|
+
if (isFinite(retries)) {
|
|
19
21
|
options.retry = { retries }
|
|
20
|
-
else
|
|
22
|
+
} else {
|
|
21
23
|
options.retry = { retries: 0 }
|
|
22
|
-
|
|
24
|
+
}
|
|
25
|
+
} else if (typeof options.retry === 'number') {
|
|
23
26
|
options.retry = { retries: options.retry }
|
|
24
|
-
else
|
|
27
|
+
} else {
|
|
25
28
|
options.retry = { retries: 0, ...options.retry }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
options.dns = { ttl: 5 * 60 * 1000, lookup: dns.lookup, ...options.dns }
|
|
26
32
|
|
|
27
33
|
options.cache = options.cache || 'default'
|
|
28
34
|
if (options.cache === 'default') {
|
|
29
35
|
const hasConditionalHeader = Object.keys(options.headers || {}).some((name) => {
|
|
30
36
|
return conditionalHeaders.includes(name.toLowerCase())
|
|
31
37
|
})
|
|
32
|
-
if (hasConditionalHeader)
|
|
38
|
+
if (hasConditionalHeader) {
|
|
33
39
|
options.cache = 'no-store'
|
|
40
|
+
}
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
// cacheManager is deprecated, but if it's set and
|
|
37
44
|
// cachePath is not we should copy it to the new field
|
|
38
|
-
if (options.cacheManager && !options.cachePath)
|
|
45
|
+
if (options.cacheManager && !options.cachePath) {
|
|
39
46
|
options.cachePath = options.cacheManager
|
|
47
|
+
}
|
|
40
48
|
|
|
41
49
|
return options
|
|
42
50
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const MinipassPipeline = require('minipass-pipeline')
|
|
4
|
+
|
|
5
|
+
class CachingMinipassPipeline extends MinipassPipeline {
|
|
6
|
+
#events = []
|
|
7
|
+
#data = new Map()
|
|
8
|
+
|
|
9
|
+
constructor (opts, ...streams) {
|
|
10
|
+
// CRITICAL: do NOT pass the streams to the call to super(), this will start
|
|
11
|
+
// the flow of data and potentially cause the events we need to catch to emit
|
|
12
|
+
// before we've finished our own setup. instead we call super() with no args,
|
|
13
|
+
// finish our setup, and then push the streams into ourselves to start the
|
|
14
|
+
// data flow
|
|
15
|
+
super()
|
|
16
|
+
this.#events = opts.events
|
|
17
|
+
|
|
18
|
+
/* istanbul ignore next - coverage disabled because this is pointless to test here */
|
|
19
|
+
if (streams.length) {
|
|
20
|
+
this.push(...streams)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
on (event, handler) {
|
|
25
|
+
if (this.#events.includes(event) && this.#data.has(event)) {
|
|
26
|
+
return handler(...this.#data.get(event))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return super.on(event, handler)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
emit (event, ...data) {
|
|
33
|
+
if (this.#events.includes(event)) {
|
|
34
|
+
this.#data.set(event, data)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return super.emit(event, ...data)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = CachingMinipassPipeline
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const Minipass = require('minipass')
|
|
2
|
-
const MinipassPipeline = require('minipass-pipeline')
|
|
3
2
|
const fetch = require('minipass-fetch')
|
|
4
3
|
const promiseRetry = require('promise-retry')
|
|
5
4
|
const ssri = require('ssri')
|
|
6
5
|
|
|
6
|
+
const CachingMinipassPipeline = require('./pipeline.js')
|
|
7
7
|
const getAgent = require('./agent.js')
|
|
8
8
|
const pkg = require('../package.json')
|
|
9
9
|
|
|
@@ -29,11 +29,13 @@ const RETRY_TYPES = [
|
|
|
29
29
|
// and verifying response integrity
|
|
30
30
|
const remoteFetch = (request, options) => {
|
|
31
31
|
const agent = getAgent(request.url, options)
|
|
32
|
-
if (!request.headers.has('connection'))
|
|
32
|
+
if (!request.headers.has('connection')) {
|
|
33
33
|
request.headers.set('connection', agent ? 'keep-alive' : 'close')
|
|
34
|
+
}
|
|
34
35
|
|
|
35
|
-
if (!request.headers.has('user-agent'))
|
|
36
|
+
if (!request.headers.has('user-agent')) {
|
|
36
37
|
request.headers.set('user-agent', USER_AGENT)
|
|
38
|
+
}
|
|
37
39
|
|
|
38
40
|
// keep our own options since we're overriding the agent
|
|
39
41
|
// and the redirect mode
|
|
@@ -50,8 +52,21 @@ const remoteFetch = (request, options) => {
|
|
|
50
52
|
if (_opts.integrity && res.status === 200) {
|
|
51
53
|
// we got a 200 response and the user has specified an expected
|
|
52
54
|
// integrity value, so wrap the response in an ssri stream to verify it
|
|
53
|
-
const integrityStream = ssri.integrityStream({
|
|
54
|
-
|
|
55
|
+
const integrityStream = ssri.integrityStream({
|
|
56
|
+
algorithms: _opts.algorithms,
|
|
57
|
+
integrity: _opts.integrity,
|
|
58
|
+
size: _opts.size,
|
|
59
|
+
})
|
|
60
|
+
const pipeline = new CachingMinipassPipeline({
|
|
61
|
+
events: ['integrity', 'size'],
|
|
62
|
+
}, res.body, integrityStream)
|
|
63
|
+
// we also propagate the integrity and size events out to the pipeline so we can use
|
|
64
|
+
// this new response body as an integrityEmitter for cacache
|
|
65
|
+
integrityStream.on('integrity', i => pipeline.emit('integrity', i))
|
|
66
|
+
integrityStream.on('size', s => pipeline.emit('size', s))
|
|
67
|
+
res = new fetch.Response(pipeline, res)
|
|
68
|
+
// set an explicit flag so we know if our response body will emit integrity and size
|
|
69
|
+
res.body.hasIntegrityEmitter = true
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
res.headers.set('x-fetch-attempts', attemptNum)
|
|
@@ -64,8 +79,9 @@ const remoteFetch = (request, options) => {
|
|
|
64
79
|
([408, 420, 429].includes(res.status) || res.status >= 500)
|
|
65
80
|
|
|
66
81
|
if (isRetriable) {
|
|
67
|
-
if (typeof options.onRetry === 'function')
|
|
82
|
+
if (typeof options.onRetry === 'function') {
|
|
68
83
|
options.onRetry(res)
|
|
84
|
+
}
|
|
69
85
|
|
|
70
86
|
return retryHandler(res)
|
|
71
87
|
}
|
|
@@ -82,18 +98,21 @@ const remoteFetch = (request, options) => {
|
|
|
82
98
|
const isRetryError = err.retried instanceof fetch.Response ||
|
|
83
99
|
(RETRY_ERRORS.includes(code) && RETRY_TYPES.includes(err.type))
|
|
84
100
|
|
|
85
|
-
if (req.method === 'POST' || isRetryError)
|
|
101
|
+
if (req.method === 'POST' || isRetryError) {
|
|
86
102
|
throw err
|
|
103
|
+
}
|
|
87
104
|
|
|
88
|
-
if (typeof options.onRetry === 'function')
|
|
105
|
+
if (typeof options.onRetry === 'function') {
|
|
89
106
|
options.onRetry(err)
|
|
107
|
+
}
|
|
90
108
|
|
|
91
109
|
return retryHandler(err)
|
|
92
110
|
}
|
|
93
111
|
}, options.retry).catch((err) => {
|
|
94
112
|
// don't reject for http errors, just return them
|
|
95
|
-
if (err.status >= 400 && err.type !== 'system')
|
|
113
|
+
if (err.status >= 400 && err.type !== 'system') {
|
|
96
114
|
return err
|
|
115
|
+
}
|
|
97
116
|
|
|
98
117
|
throw err
|
|
99
118
|
})
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "make-fetch-happen",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.2.1",
|
|
4
4
|
"description": "Opinionated, caching, retrying fetch client",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
7
|
-
"
|
|
7
|
+
"bin/",
|
|
8
|
+
"lib/"
|
|
8
9
|
],
|
|
9
10
|
"scripts": {
|
|
10
|
-
"preversion": "npm
|
|
11
|
+
"preversion": "npm test",
|
|
11
12
|
"postversion": "npm publish",
|
|
12
|
-
"prepublishOnly": "git push --follow-tags",
|
|
13
|
+
"prepublishOnly": "git push origin --follow-tags",
|
|
13
14
|
"test": "tap",
|
|
14
15
|
"posttest": "npm run lint",
|
|
15
16
|
"eslint": "eslint",
|
|
16
|
-
"lint": "
|
|
17
|
-
"lintfix": "npm run lint -- --fix"
|
|
17
|
+
"lint": "eslint \"**/*.js\"",
|
|
18
|
+
"lintfix": "npm run lint -- --fix",
|
|
19
|
+
"postlint": "template-oss-check",
|
|
20
|
+
"snap": "tap",
|
|
21
|
+
"template-oss-apply": "template-oss-apply --force"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/npm/make-fetch-happen.git"
|
|
18
26
|
},
|
|
19
|
-
"repository": "https://github.com/npm/make-fetch-happen",
|
|
20
27
|
"keywords": [
|
|
21
28
|
"http",
|
|
22
29
|
"request",
|
|
@@ -26,51 +33,47 @@
|
|
|
26
33
|
"cache",
|
|
27
34
|
"subresource integrity"
|
|
28
35
|
],
|
|
29
|
-
"author":
|
|
30
|
-
"name": "Kat Marchán",
|
|
31
|
-
"email": "kzm@zkat.tech",
|
|
32
|
-
"twitter": "maybekatz"
|
|
33
|
-
},
|
|
36
|
+
"author": "GitHub Inc.",
|
|
34
37
|
"license": "ISC",
|
|
35
38
|
"dependencies": {
|
|
36
|
-
"agentkeepalive": "^4.1
|
|
37
|
-
"cacache": "^
|
|
39
|
+
"agentkeepalive": "^4.2.1",
|
|
40
|
+
"cacache": "^16.1.0",
|
|
38
41
|
"http-cache-semantics": "^4.1.0",
|
|
39
|
-
"http-proxy-agent": "^
|
|
42
|
+
"http-proxy-agent": "^5.0.0",
|
|
40
43
|
"https-proxy-agent": "^5.0.0",
|
|
41
44
|
"is-lambda": "^1.0.1",
|
|
42
|
-
"lru-cache": "^
|
|
43
|
-
"minipass": "^3.1.
|
|
45
|
+
"lru-cache": "^7.7.1",
|
|
46
|
+
"minipass": "^3.1.6",
|
|
44
47
|
"minipass-collect": "^1.0.2",
|
|
45
|
-
"minipass-fetch": "^
|
|
48
|
+
"minipass-fetch": "^2.0.3",
|
|
46
49
|
"minipass-flush": "^1.0.5",
|
|
47
50
|
"minipass-pipeline": "^1.2.4",
|
|
48
|
-
"negotiator": "^0.6.
|
|
51
|
+
"negotiator": "^0.6.3",
|
|
49
52
|
"promise-retry": "^2.0.1",
|
|
50
|
-
"socks-proxy-agent": "^
|
|
51
|
-
"ssri": "^
|
|
53
|
+
"socks-proxy-agent": "^7.0.0",
|
|
54
|
+
"ssri": "^9.0.0"
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
54
|
-
"eslint": "^
|
|
55
|
-
"
|
|
56
|
-
"eslint-plugin-node": "^11.1.0",
|
|
57
|
-
"eslint-plugin-promise": "^5.1.0",
|
|
58
|
-
"eslint-plugin-standard": "^5.0.0",
|
|
57
|
+
"@npmcli/eslint-config": "^3.0.1",
|
|
58
|
+
"@npmcli/template-oss": "3.5.0",
|
|
59
59
|
"mkdirp": "^1.0.4",
|
|
60
|
-
"nock": "^13.
|
|
61
|
-
"npmlog": "^5.0.0",
|
|
62
|
-
"require-inject": "^1.4.2",
|
|
60
|
+
"nock": "^13.2.4",
|
|
63
61
|
"rimraf": "^3.0.2",
|
|
64
62
|
"safe-buffer": "^5.2.1",
|
|
65
|
-
"standard-version": "^9.3.
|
|
66
|
-
"tap": "^
|
|
63
|
+
"standard-version": "^9.3.2",
|
|
64
|
+
"tap": "^16.0.0"
|
|
67
65
|
},
|
|
68
66
|
"engines": {
|
|
69
|
-
"node": ">=
|
|
67
|
+
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
|
70
68
|
},
|
|
71
69
|
"tap": {
|
|
72
70
|
"color": 1,
|
|
73
71
|
"files": "test/*.js",
|
|
74
|
-
"check-coverage": true
|
|
72
|
+
"check-coverage": true,
|
|
73
|
+
"timeout": 60
|
|
74
|
+
},
|
|
75
|
+
"templateOSS": {
|
|
76
|
+
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
77
|
+
"version": "3.5.0"
|
|
75
78
|
}
|
|
76
79
|
}
|
|
@@ -18,10 +18,10 @@ class Blob {
|
|
|
18
18
|
const buffer = element instanceof Buffer ? element
|
|
19
19
|
: ArrayBuffer.isView(element)
|
|
20
20
|
? Buffer.from(element.buffer, element.byteOffset, element.byteLength)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
: element instanceof ArrayBuffer ? Buffer.from(element)
|
|
22
|
+
: element instanceof Blob ? element[BUFFER]
|
|
23
|
+
: typeof element === 'string' ? Buffer.from(element)
|
|
24
|
+
: Buffer.from(String(element))
|
|
25
25
|
size += buffer.length
|
|
26
26
|
buffers.push(buffer)
|
|
27
27
|
}
|