pacote 11.1.14 → 11.2.3
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 +5 -0
- package/lib/fetcher.js +4 -1
- package/lib/git.js +32 -13
- package/lib/registry.js +23 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -162,6 +162,11 @@ resolved, and other properties, as they are determined.
|
|
|
162
162
|
including information not strictly required for installation (author,
|
|
163
163
|
description, etc.) Defaults to `true` when `before` is set, since the
|
|
164
164
|
version publish time is part of the extended packument metadata.
|
|
165
|
+
* `packumentCache` For registry packuments only, you may provide a `Map`
|
|
166
|
+
object which will be used to cache packument requests between pacote
|
|
167
|
+
calls. This allows you to easily avoid hitting the registry multiple
|
|
168
|
+
times (even just to validate the cache) for a given packument, since it
|
|
169
|
+
is unlikely to change in the span of a single command.
|
|
165
170
|
|
|
166
171
|
## Extracted File Modes
|
|
167
172
|
|
package/lib/fetcher.js
CHANGED
|
@@ -47,6 +47,8 @@ class FetcherBase {
|
|
|
47
47
|
throw new TypeError('options object is required')
|
|
48
48
|
this.spec = npa(spec, opts.where)
|
|
49
49
|
|
|
50
|
+
this.allowGitIgnore = !!opts.allowGitIgnore
|
|
51
|
+
|
|
50
52
|
// a bit redundant because presumably the caller already knows this,
|
|
51
53
|
// but it makes it easier to not have to keep track of the requested
|
|
52
54
|
// spec when we're dispatching thousands of these at once, and normalizing
|
|
@@ -60,6 +62,7 @@ class FetcherBase {
|
|
|
60
62
|
// clone the opts object so that others aren't upset when we mutate it
|
|
61
63
|
// by adding/modifying the integrity value.
|
|
62
64
|
this.opts = {...opts}
|
|
65
|
+
|
|
63
66
|
this.cache = opts.cache || cacheDir()
|
|
64
67
|
this.resolved = opts.resolved || null
|
|
65
68
|
|
|
@@ -413,7 +416,7 @@ class FetcherBase {
|
|
|
413
416
|
const base = basename(entry.path)
|
|
414
417
|
if (base === '.npmignore')
|
|
415
418
|
sawIgnores.add(entry.path)
|
|
416
|
-
else if (base === '.gitignore') {
|
|
419
|
+
else if (base === '.gitignore' && !this.allowGitIgnore) {
|
|
417
420
|
// rename, but only if there's not already a .npmignore
|
|
418
421
|
const ni = entry.path.replace(/\.gitignore$/, '.npmignore')
|
|
419
422
|
if (sawIgnores.has(ni))
|
package/lib/git.js
CHANGED
|
@@ -24,13 +24,16 @@ const _cloneRepo = Symbol('_cloneRepo')
|
|
|
24
24
|
const _setResolvedWithSha = Symbol('_setResolvedWithSha')
|
|
25
25
|
const _prepareDir = Symbol('_prepareDir')
|
|
26
26
|
|
|
27
|
-
// get the repository url.
|
|
27
|
+
// get the repository url.
|
|
28
|
+
// prefer https if there's auth, since ssh will drop that.
|
|
29
|
+
// otherwise, prefer ssh if available (more secure).
|
|
28
30
|
// We have to add the git+ back because npa suppresses it.
|
|
29
|
-
const repoUrl = (
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const repoUrl = (h, opts) =>
|
|
32
|
+
h.sshurl && !(h.https && h.auth) && addGitPlus(h.sshurl(opts)) ||
|
|
33
|
+
h.https && addGitPlus(h.https(opts))
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
// add git+ to the url, but only one time.
|
|
36
|
+
const addGitPlus = url => url && `git+${url}`.replace(/^(git\+)+/, 'git+')
|
|
34
37
|
|
|
35
38
|
class GitFetcher extends Fetcher {
|
|
36
39
|
constructor (spec, opts) {
|
|
@@ -51,6 +54,11 @@ class GitFetcher extends Fetcher {
|
|
|
51
54
|
this.resolvedSha = ''
|
|
52
55
|
}
|
|
53
56
|
|
|
57
|
+
// just exposed to make it easier to test all the combinations
|
|
58
|
+
static repoUrl (hosted, opts) {
|
|
59
|
+
return repoUrl(hosted, opts)
|
|
60
|
+
}
|
|
61
|
+
|
|
54
62
|
get types () {
|
|
55
63
|
return ['git']
|
|
56
64
|
}
|
|
@@ -69,13 +77,16 @@ class GitFetcher extends Fetcher {
|
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
// first try https, since that's faster and passphrase-less for
|
|
72
|
-
// public repos
|
|
73
|
-
//
|
|
80
|
+
// public repos, and supports private repos when auth is provided.
|
|
81
|
+
// Fall back to SSH to support private repos
|
|
82
|
+
// NB: we always store the https url in resolved field if auth
|
|
83
|
+
// is present, otherwise ssh if the hosted type provides it
|
|
74
84
|
[_resolvedFromHosted] (hosted) {
|
|
75
85
|
return this[_resolvedFromRepo](hosted.https && hosted.https())
|
|
76
86
|
.catch(er => {
|
|
77
87
|
const ssh = hosted.sshurl && hosted.sshurl()
|
|
78
|
-
if
|
|
88
|
+
// no fallthrough if we can't fall through or have https auth
|
|
89
|
+
if (!ssh || hosted.auth)
|
|
79
90
|
throw er
|
|
80
91
|
return this[_resolvedFromRepo](ssh)
|
|
81
92
|
})
|
|
@@ -121,9 +132,11 @@ class GitFetcher extends Fetcher {
|
|
|
121
132
|
// either a git url with a hash, or a tarball download URL
|
|
122
133
|
[_addGitSha] (sha) {
|
|
123
134
|
if (this.spec.hosted) {
|
|
124
|
-
this
|
|
125
|
-
|
|
126
|
-
)
|
|
135
|
+
const h = this.spec.hosted
|
|
136
|
+
const opt = { noCommittish: true }
|
|
137
|
+
const base = h.https && h.auth ? h.https(opt) : h.shortcut(opt)
|
|
138
|
+
|
|
139
|
+
this[_setResolvedWithSha](`${base}#${sha}`)
|
|
127
140
|
} else {
|
|
128
141
|
const u = url.format(new url.URL(`#${sha}`, this.spec.rawSpec))
|
|
129
142
|
this[_setResolvedWithSha](url.format(u))
|
|
@@ -207,6 +220,7 @@ class GitFetcher extends Fetcher {
|
|
|
207
220
|
const nameat = this.spec.name ? `${this.spec.name}@` : ''
|
|
208
221
|
return new RemoteFetcher(h.tarball({ noCommittish: false }), {
|
|
209
222
|
...this.opts,
|
|
223
|
+
allowGitIgnore: true,
|
|
210
224
|
pkgid: `git:${nameat}${this.resolved}`,
|
|
211
225
|
resolved: this.resolved,
|
|
212
226
|
integrity: null, // it'll always be different, if we have one
|
|
@@ -231,14 +245,19 @@ class GitFetcher extends Fetcher {
|
|
|
231
245
|
})
|
|
232
246
|
}
|
|
233
247
|
|
|
248
|
+
// first try https, since that's faster and passphrase-less for
|
|
249
|
+
// public repos, and supports private repos when auth is provided.
|
|
250
|
+
// Fall back to SSH to support private repos
|
|
251
|
+
// NB: we always store the https url in resolved field if auth
|
|
252
|
+
// is present, otherwise ssh if the hosted type provides it
|
|
234
253
|
[_cloneHosted] (ref, tmp) {
|
|
235
254
|
const hosted = this.spec.hosted
|
|
236
255
|
const https = hosted.https()
|
|
237
256
|
return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp)
|
|
238
257
|
.catch(er => {
|
|
239
258
|
const ssh = hosted.sshurl && hosted.sshurl({ noCommittish: true })
|
|
240
|
-
|
|
241
|
-
if (!ssh)
|
|
259
|
+
// no fallthrough if we can't fall through or have https auth
|
|
260
|
+
if (!ssh || hosted.auth)
|
|
242
261
|
throw er
|
|
243
262
|
return this[_cloneRepo](ssh, ref, tmp)
|
|
244
263
|
})
|
package/lib/registry.js
CHANGED
|
@@ -20,6 +20,14 @@ class RegistryFetcher extends Fetcher {
|
|
|
20
20
|
constructor (spec, opts) {
|
|
21
21
|
super(spec, opts)
|
|
22
22
|
|
|
23
|
+
// you usually don't want to fetch the same packument multiple times in
|
|
24
|
+
// the span of a given script or command, no matter how many pacote calls
|
|
25
|
+
// are made, so this lets us avoid doing that. It's only relevant for
|
|
26
|
+
// registry fetchers, because other types simulate their packument from
|
|
27
|
+
// the manifest, which they memoize on this.package, so it's very cheap
|
|
28
|
+
// already.
|
|
29
|
+
this.packumentCache = this.opts.packumentCache || null
|
|
30
|
+
|
|
23
31
|
// handle case when npm-package-arg guesses wrong.
|
|
24
32
|
if (this.spec.type === 'tag' &&
|
|
25
33
|
this.spec.rawSpec === '' &&
|
|
@@ -64,11 +72,17 @@ class RegistryFetcher extends Fetcher {
|
|
|
64
72
|
}
|
|
65
73
|
}
|
|
66
74
|
|
|
67
|
-
packument () {
|
|
75
|
+
async packument () {
|
|
76
|
+
// note this might be either an in-flight promise for a request,
|
|
77
|
+
// or the actual packument, but we never want to make more than
|
|
78
|
+
// one request at a time for the same thing regardless.
|
|
79
|
+
if (this.packumentCache && this.packumentCache.has(this.packumentUrl))
|
|
80
|
+
return this.packumentCache.get(this.packumentUrl)
|
|
81
|
+
|
|
68
82
|
// npm-registry-fetch the packument
|
|
69
83
|
// set the appropriate header for corgis if fullMetadata isn't set
|
|
70
84
|
// return the res.json() promise
|
|
71
|
-
|
|
85
|
+
const p = fetch(this.packumentUrl, {
|
|
72
86
|
...this.opts,
|
|
73
87
|
headers: this[_headers](),
|
|
74
88
|
spec: this.spec,
|
|
@@ -77,8 +91,12 @@ class RegistryFetcher extends Fetcher {
|
|
|
77
91
|
}).then(res => res.json().then(packument => {
|
|
78
92
|
packument._cached = res.headers.has('x-local-cache')
|
|
79
93
|
packument._contentLength = +res.headers.get('content-length')
|
|
94
|
+
if (this.packumentCache)
|
|
95
|
+
this.packumentCache.set(this.packumentUrl, packument)
|
|
80
96
|
return packument
|
|
81
97
|
})).catch(er => {
|
|
98
|
+
if (this.packumentCache)
|
|
99
|
+
this.packumentCache.delete(this.packumentUrl)
|
|
82
100
|
if (er.code === 'E404' && !this.fullMetadata) {
|
|
83
101
|
// possible that corgis are not supported by this registry
|
|
84
102
|
this.fullMetadata = true
|
|
@@ -86,6 +104,9 @@ class RegistryFetcher extends Fetcher {
|
|
|
86
104
|
}
|
|
87
105
|
throw er
|
|
88
106
|
})
|
|
107
|
+
if (this.packumentCache)
|
|
108
|
+
this.packumentCache.set(this.packumentUrl, p)
|
|
109
|
+
return p
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
manifest () {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pacote",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.2.3",
|
|
4
4
|
"description": "JavaScript package downloader",
|
|
5
5
|
"author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"snap": "tap",
|
|
14
14
|
"preversion": "npm test",
|
|
15
15
|
"postversion": "npm publish",
|
|
16
|
-
"
|
|
16
|
+
"prepublishOnly": "git push origin --follow-tags"
|
|
17
17
|
},
|
|
18
18
|
"tap": {
|
|
19
19
|
"timeout": 300,
|