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 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. prefer ssh, fall back to git://
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 = (hosted, opts) =>
30
- hosted.sshurl && addGitPlus(hosted.sshurl(opts)) ||
31
- hosted.https && addGitPlus(hosted.https(opts))
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
- const addGitPlus = url => url && `git+${url}`
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. Fall back to SSH to support private repos.
73
- // NB: we always store the SSH url in the 'resolved' field.
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 (!ssh)
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[_setResolvedWithSha](
125
- this.spec.hosted.shortcut({ noCommittish: true }) + '#' + sha
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
- /* istanbul ignore if - should be covered by the resolve() call */
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
- return fetch(this.packumentUrl, {
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.1.14",
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
- "postpublish": "git push origin --follow-tags"
16
+ "prepublishOnly": "git push origin --follow-tags"
17
17
  },
18
18
  "tap": {
19
19
  "timeout": 300,