pacote 12.0.2 → 13.0.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 +5 -4
- package/lib/bin.js +17 -13
- package/lib/dir.js +8 -9
- package/lib/fetcher.js +60 -41
- package/lib/file.js +22 -19
- package/lib/git.js +50 -37
- package/lib/registry.js +24 -15
- package/lib/remote.js +4 -4
- package/lib/util/cache-dir.js +1 -1
- package/lib/util/is-package-bin.js +4 -3
- package/lib/util/npm.js +0 -1
- package/lib/util/tar-create-options.js +3 -2
- package/lib/util/trailing-slashes.js +10 -0
- package/package.json +29 -16
- package/lib/util/proc-log.js +0 -21
package/README.md
CHANGED
|
@@ -146,10 +146,6 @@ resolved, and other properties, as they are determined.
|
|
|
146
146
|
`0o666`. See "Extracted File Modes" below.
|
|
147
147
|
* `dmode` Minimum permission mode for extracted directories. Defaults to
|
|
148
148
|
`0o777`. See "Extracted File Modes" below.
|
|
149
|
-
* `log` A logger object with methods for various log levels. Typically,
|
|
150
|
-
this will be [`npmlog`](http://npm.im/npmlog) in the npm CLI use case,
|
|
151
|
-
but if not specified, the default is a logger that emits `'log'` events
|
|
152
|
-
on the `process` object.
|
|
153
149
|
* `preferOnline` Prefer to revalidate cache entries, even when it would not
|
|
154
150
|
be strictly necessary. Default `false`.
|
|
155
151
|
* `before` When picking a manifest from a packument, only consider
|
|
@@ -162,11 +158,16 @@ resolved, and other properties, as they are determined.
|
|
|
162
158
|
including information not strictly required for installation (author,
|
|
163
159
|
description, etc.) Defaults to `true` when `before` is set, since the
|
|
164
160
|
version publish time is part of the extended packument metadata.
|
|
161
|
+
* `fullReadJson` Use the slower `read-package-json` package insted of
|
|
162
|
+
`read-package-json-fast` in order to include extra fields like "readme" in
|
|
163
|
+
the manifest. Defaults to `false`.
|
|
165
164
|
* `packumentCache` For registry packuments only, you may provide a `Map`
|
|
166
165
|
object which will be used to cache packument requests between pacote
|
|
167
166
|
calls. This allows you to easily avoid hitting the registry multiple
|
|
168
167
|
times (even just to validate the cache) for a given packument, since it
|
|
169
168
|
is unlikely to change in the span of a single command.
|
|
169
|
+
* `silent` A boolean that determines whether the banner is displayed
|
|
170
|
+
when calling `@npmcli/run-script`.
|
|
170
171
|
|
|
171
172
|
|
|
172
173
|
### Advanced API
|
package/lib/bin.js
CHANGED
|
@@ -4,26 +4,28 @@ const run = conf => {
|
|
|
4
4
|
const pacote = require('../')
|
|
5
5
|
switch (conf._[0]) {
|
|
6
6
|
case 'resolve':
|
|
7
|
-
|
|
7
|
+
case 'manifest':
|
|
8
|
+
case 'packument':
|
|
9
|
+
if (conf._[0] === 'resolve' && conf.long) {
|
|
8
10
|
return pacote.manifest(conf._[1], conf).then(mani => ({
|
|
9
11
|
resolved: mani._resolved,
|
|
10
12
|
integrity: mani._integrity,
|
|
11
13
|
from: mani._from,
|
|
12
14
|
}))
|
|
13
|
-
|
|
14
|
-
case 'packument':
|
|
15
|
+
}
|
|
15
16
|
return pacote[conf._[0]](conf._[1], conf)
|
|
16
17
|
|
|
17
18
|
case 'tarball':
|
|
18
19
|
if (!conf._[2] || conf._[2] === '-') {
|
|
19
20
|
return pacote.tarball.stream(conf._[1], stream => {
|
|
20
21
|
stream.pipe(conf.testStdout ||
|
|
21
|
-
|
|
22
|
+
/* istanbul ignore next */ process.stdout)
|
|
22
23
|
// make sure it resolves something falsey
|
|
23
24
|
return stream.promise().then(() => {})
|
|
24
25
|
}, conf)
|
|
25
|
-
} else
|
|
26
|
+
} else {
|
|
26
27
|
return pacote.tarball.file(conf._[1], conf._[2], conf)
|
|
28
|
+
}
|
|
27
29
|
|
|
28
30
|
case 'extract':
|
|
29
31
|
return pacote.extract(conf._[1], conf._[2], conf)
|
|
@@ -81,8 +83,9 @@ const pretty = (conf, result) =>
|
|
|
81
83
|
let addedLogListener = false
|
|
82
84
|
const main = args => {
|
|
83
85
|
const conf = parse(args)
|
|
84
|
-
if (conf.help || conf.h)
|
|
86
|
+
if (conf.help || conf.h) {
|
|
85
87
|
return console.log(usage())
|
|
88
|
+
}
|
|
86
89
|
|
|
87
90
|
if (!addedLogListener) {
|
|
88
91
|
process.on('log', console.error)
|
|
@@ -121,14 +124,14 @@ const parse = args => {
|
|
|
121
124
|
}
|
|
122
125
|
let dashdash = false
|
|
123
126
|
args.forEach(arg => {
|
|
124
|
-
if (dashdash)
|
|
127
|
+
if (dashdash) {
|
|
125
128
|
conf._.push(arg)
|
|
126
|
-
else if (arg === '--')
|
|
129
|
+
} else if (arg === '--') {
|
|
127
130
|
dashdash = true
|
|
128
|
-
else if (arg === '-h')
|
|
131
|
+
} else if (arg === '-h') {
|
|
129
132
|
conf.help = true
|
|
130
|
-
else if (/^--/.test(arg)) {
|
|
131
|
-
const {key, value} = parseArg(arg)
|
|
133
|
+
} else if (/^--/.test(arg)) {
|
|
134
|
+
const { key, value } = parseArg(arg)
|
|
132
135
|
conf[key] = value
|
|
133
136
|
} else {
|
|
134
137
|
conf._.push(arg)
|
|
@@ -137,9 +140,9 @@ const parse = args => {
|
|
|
137
140
|
return conf
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
if (module === require.main)
|
|
143
|
+
if (module === require.main) {
|
|
141
144
|
main(process.argv.slice(2))
|
|
142
|
-
else
|
|
145
|
+
} else {
|
|
143
146
|
module.exports = {
|
|
144
147
|
main,
|
|
145
148
|
run,
|
|
@@ -147,3 +150,4 @@ else
|
|
|
147
150
|
parseArg,
|
|
148
151
|
parse,
|
|
149
152
|
}
|
|
153
|
+
}
|
package/lib/dir.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
const Fetcher = require('./fetcher.js')
|
|
2
2
|
const FileFetcher = require('./file.js')
|
|
3
|
-
const cacache = require('cacache')
|
|
4
3
|
const Minipass = require('minipass')
|
|
5
|
-
const { promisify } = require('util')
|
|
6
|
-
const readPackageJson = require('read-package-json-fast')
|
|
7
4
|
const tarCreateOptions = require('./util/tar-create-options.js')
|
|
8
5
|
const packlist = require('npm-packlist')
|
|
9
6
|
const tar = require('tar')
|
|
10
7
|
const _prepareDir = Symbol('_prepareDir')
|
|
11
8
|
const { resolve } = require('path')
|
|
9
|
+
const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson')
|
|
12
10
|
|
|
13
11
|
const runScript = require('@npmcli/run-script')
|
|
14
12
|
|
|
@@ -31,18 +29,18 @@ class DirFetcher extends Fetcher {
|
|
|
31
29
|
|
|
32
30
|
[_prepareDir] () {
|
|
33
31
|
return this.manifest().then(mani => {
|
|
34
|
-
if (!mani.scripts || !mani.scripts.prepare)
|
|
32
|
+
if (!mani.scripts || !mani.scripts.prepare) {
|
|
35
33
|
return
|
|
34
|
+
}
|
|
36
35
|
|
|
37
36
|
// we *only* run prepare.
|
|
38
37
|
// pre/post-pack is run by the npm CLI for publish and pack,
|
|
39
38
|
// but this function is *also* run when installing git deps
|
|
40
39
|
const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe'
|
|
41
40
|
|
|
42
|
-
// hide the banner if
|
|
41
|
+
// hide the banner if silent opt is passed in, or if prepare running
|
|
43
42
|
// in the background.
|
|
44
|
-
const banner = this.opts.
|
|
45
|
-
: stdio === 'inherit'
|
|
43
|
+
const banner = this.opts.silent ? false : stdio === 'inherit'
|
|
46
44
|
|
|
47
45
|
return runScript({
|
|
48
46
|
pkg: mani,
|
|
@@ -76,10 +74,11 @@ class DirFetcher extends Fetcher {
|
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
manifest () {
|
|
79
|
-
if (this.package)
|
|
77
|
+
if (this.package) {
|
|
80
78
|
return Promise.resolve(this.package)
|
|
79
|
+
}
|
|
81
80
|
|
|
82
|
-
return
|
|
81
|
+
return this[_readPackageJson](this.resolved + '/package.json')
|
|
83
82
|
.then(mani => this.package = {
|
|
84
83
|
...mani,
|
|
85
84
|
_integrity: this.integrity && String(this.integrity),
|
package/lib/fetcher.js
CHANGED
|
@@ -9,12 +9,15 @@ const { promisify } = require('util')
|
|
|
9
9
|
const { basename, dirname } = require('path')
|
|
10
10
|
const rimraf = promisify(require('rimraf'))
|
|
11
11
|
const tar = require('tar')
|
|
12
|
-
const
|
|
12
|
+
const log = require('proc-log')
|
|
13
13
|
const retry = require('promise-retry')
|
|
14
14
|
const fsm = require('fs-minipass')
|
|
15
15
|
const cacache = require('cacache')
|
|
16
16
|
const isPackageBin = require('./util/is-package-bin.js')
|
|
17
|
+
const removeTrailingSlashes = require('./util/trailing-slashes.js')
|
|
17
18
|
const getContents = require('@npmcli/installed-package-contents')
|
|
19
|
+
const readPackageJsonFast = require('read-package-json-fast')
|
|
20
|
+
const readPackageJson = promisify(require('read-package-json'))
|
|
18
21
|
|
|
19
22
|
// we only change ownership on unix platforms, and only if uid is 0
|
|
20
23
|
const selfOwner = process.getuid && process.getuid() === 0 ? {
|
|
@@ -41,11 +44,13 @@ const _assertType = Symbol('_assertType')
|
|
|
41
44
|
const _tarballFromCache = Symbol('_tarballFromCache')
|
|
42
45
|
const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
|
|
43
46
|
const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches')
|
|
47
|
+
const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson')
|
|
44
48
|
|
|
45
49
|
class FetcherBase {
|
|
46
50
|
constructor (spec, opts) {
|
|
47
|
-
if (!opts || typeof opts !== 'object')
|
|
51
|
+
if (!opts || typeof opts !== 'object') {
|
|
48
52
|
throw new TypeError('options object is required')
|
|
53
|
+
}
|
|
49
54
|
this.spec = npa(spec, opts.where)
|
|
50
55
|
|
|
51
56
|
this.allowGitIgnore = !!opts.allowGitIgnore
|
|
@@ -62,7 +67,7 @@ class FetcherBase {
|
|
|
62
67
|
this[_assertType]()
|
|
63
68
|
// clone the opts object so that others aren't upset when we mutate it
|
|
64
69
|
// by adding/modifying the integrity value.
|
|
65
|
-
this.opts = {...opts}
|
|
70
|
+
this.opts = { ...opts }
|
|
66
71
|
|
|
67
72
|
this.cache = opts.cache || cacheDir()
|
|
68
73
|
this.resolved = opts.resolved || null
|
|
@@ -72,8 +77,9 @@ class FetcherBase {
|
|
|
72
77
|
// is no longer strong enough.
|
|
73
78
|
this.defaultIntegrityAlgorithm = opts.defaultIntegrityAlgorithm || 'sha512'
|
|
74
79
|
|
|
75
|
-
if (typeof opts.integrity === 'string')
|
|
80
|
+
if (typeof opts.integrity === 'string') {
|
|
76
81
|
this.opts.integrity = ssri.parse(opts.integrity)
|
|
82
|
+
}
|
|
77
83
|
|
|
78
84
|
this.package = null
|
|
79
85
|
this.type = this.constructor.name
|
|
@@ -85,7 +91,6 @@ class FetcherBase {
|
|
|
85
91
|
// the process's umask setting do its job. but if configured, we do
|
|
86
92
|
// respect it.
|
|
87
93
|
this.umask = opts.umask || 0
|
|
88
|
-
this.log = opts.log || procLog
|
|
89
94
|
|
|
90
95
|
this.preferOnline = !!opts.preferOnline
|
|
91
96
|
this.preferOffline = !!opts.preferOffline
|
|
@@ -93,10 +98,15 @@ class FetcherBase {
|
|
|
93
98
|
|
|
94
99
|
this.before = opts.before
|
|
95
100
|
this.fullMetadata = this.before ? true : !!opts.fullMetadata
|
|
101
|
+
this.fullReadJson = !!opts.fullReadJson
|
|
102
|
+
if (this.fullReadJson) {
|
|
103
|
+
this[_readPackageJson] = readPackageJson
|
|
104
|
+
} else {
|
|
105
|
+
this[_readPackageJson] = readPackageJsonFast
|
|
106
|
+
}
|
|
96
107
|
|
|
97
108
|
this.defaultTag = opts.defaultTag || 'latest'
|
|
98
|
-
this.registry = (opts.registry || 'https://registry.npmjs.org')
|
|
99
|
-
.replace(/\/+$/, '')
|
|
109
|
+
this.registry = removeTrailingSlashes(opts.registry || 'https://registry.npmjs.org')
|
|
100
110
|
|
|
101
111
|
// command to run 'prepare' scripts on directories and git dirs
|
|
102
112
|
// To use pacote with yarn, for example, set npmBin to 'yarn'
|
|
@@ -104,7 +114,7 @@ class FetcherBase {
|
|
|
104
114
|
this.npmBin = opts.npmBin || 'npm'
|
|
105
115
|
|
|
106
116
|
// command to install deps for preparing
|
|
107
|
-
this.npmInstallCmd = opts.npmInstallCmd || [
|
|
117
|
+
this.npmInstallCmd = opts.npmInstallCmd || ['install', '--force']
|
|
108
118
|
|
|
109
119
|
// XXX fill more of this in based on what we know from this.opts
|
|
110
120
|
// we explicitly DO NOT fill in --tag, though, since we are often
|
|
@@ -132,19 +142,22 @@ class FetcherBase {
|
|
|
132
142
|
get integrity () {
|
|
133
143
|
return this.opts.integrity || null
|
|
134
144
|
}
|
|
145
|
+
|
|
135
146
|
set integrity (i) {
|
|
136
|
-
if (!i)
|
|
147
|
+
if (!i) {
|
|
137
148
|
return
|
|
149
|
+
}
|
|
138
150
|
|
|
139
151
|
i = ssri.parse(i)
|
|
140
152
|
const current = this.opts.integrity
|
|
141
153
|
|
|
142
154
|
// do not ever update an existing hash value, but do
|
|
143
155
|
// merge in NEW algos and hashes that we don't already have.
|
|
144
|
-
if (current)
|
|
156
|
+
if (current) {
|
|
145
157
|
current.merge(i)
|
|
146
|
-
else
|
|
158
|
+
} else {
|
|
147
159
|
this.opts.integrity = i
|
|
160
|
+
}
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
get notImplementedError () {
|
|
@@ -212,8 +225,9 @@ class FetcherBase {
|
|
|
212
225
|
stream.on('error', er => istream.emit('error', er))
|
|
213
226
|
|
|
214
227
|
// if not caching this, just pipe through to the istream and return it
|
|
215
|
-
if (!this.opts.cache || !this[_cacheFetches])
|
|
228
|
+
if (!this.opts.cache || !this[_cacheFetches]) {
|
|
216
229
|
return stream.pipe(istream)
|
|
230
|
+
}
|
|
217
231
|
|
|
218
232
|
// we have to return a stream that gets ALL the data, and proxies errors,
|
|
219
233
|
// but then pipe from the original tarball stream into the cache as well.
|
|
@@ -288,39 +302,42 @@ class FetcherBase {
|
|
|
288
302
|
this.integrity &&
|
|
289
303
|
this.resolved
|
|
290
304
|
) ? streamHandler(this[_tarballFromCache]()).catch(er => {
|
|
291
|
-
|
|
292
|
-
|
|
305
|
+
if (this.isDataCorruptionError(er)) {
|
|
306
|
+
log.warn('tarball', `cached data for ${
|
|
293
307
|
this.spec
|
|
294
308
|
} (${this.integrity}) seems to be corrupted. Refreshing cache.`)
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
309
|
+
return this.cleanupCached().then(() => {
|
|
310
|
+
throw er
|
|
311
|
+
})
|
|
312
|
+
} else {
|
|
313
|
+
throw er
|
|
314
|
+
}
|
|
315
|
+
}) : null
|
|
300
316
|
|
|
301
317
|
const fromResolved = er => {
|
|
302
318
|
if (er) {
|
|
303
|
-
if (!this.isRetriableError(er))
|
|
319
|
+
if (!this.isRetriableError(er)) {
|
|
304
320
|
throw er
|
|
305
|
-
|
|
321
|
+
}
|
|
322
|
+
log.silly('tarball', `no local data for ${
|
|
306
323
|
this.spec
|
|
307
324
|
}. Extracting by manifest.`)
|
|
308
325
|
}
|
|
309
326
|
return this.resolve().then(() => retry(tryAgain =>
|
|
310
327
|
streamHandler(this[_istream](this[_tarballFromResolved]()))
|
|
311
|
-
|
|
328
|
+
.catch(er => {
|
|
312
329
|
// Most likely data integrity. A cache ENOENT error is unlikely
|
|
313
330
|
// here, since we're definitely not reading from the cache, but it
|
|
314
331
|
// IS possible that the fetch subsystem accessed the cache, and the
|
|
315
332
|
// entry got blown away or something. Try one more time to be sure.
|
|
316
|
-
|
|
317
|
-
|
|
333
|
+
if (this.isRetriableError(er)) {
|
|
334
|
+
log.warn('tarball', `tarball data for ${
|
|
318
335
|
this.spec
|
|
319
336
|
} (${this.integrity}) seems to be corrupted. Trying again.`)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
337
|
+
return this.cleanupCached().then(() => tryAgain(er))
|
|
338
|
+
}
|
|
339
|
+
throw er
|
|
340
|
+
}), { retries: 1, minTimeout: 0, maxTimeout: 0 }))
|
|
324
341
|
}
|
|
325
342
|
|
|
326
343
|
return fromCache ? fromCache.catch(fromResolved) : fromResolved()
|
|
@@ -337,7 +354,7 @@ class FetcherBase {
|
|
|
337
354
|
}
|
|
338
355
|
|
|
339
356
|
[_empty] (path) {
|
|
340
|
-
return getContents({path, depth: 1}).then(contents => Promise.all(
|
|
357
|
+
return getContents({ path, depth: 1 }).then(contents => Promise.all(
|
|
341
358
|
contents.map(entry => rimraf(entry))))
|
|
342
359
|
}
|
|
343
360
|
|
|
@@ -350,7 +367,7 @@ class FetcherBase {
|
|
|
350
367
|
// parent folder (rare, but probably happens sometimes).
|
|
351
368
|
return !inferOwner
|
|
352
369
|
? this[_empty](dest).then(() => mkdirp(dest)).then(() => ({}))
|
|
353
|
-
: inferOwner(dest).then(({uid, gid}) =>
|
|
370
|
+
: inferOwner(dest).then(({ uid, gid }) =>
|
|
354
371
|
this[_empty](dest)
|
|
355
372
|
.then(() => mkdirp(dest))
|
|
356
373
|
.then(made => {
|
|
@@ -360,13 +377,13 @@ class FetcherBase {
|
|
|
360
377
|
const dir = made || /* istanbul ignore next */ dest
|
|
361
378
|
return this[_chown](dir, uid, gid)
|
|
362
379
|
})
|
|
363
|
-
.then(() => ({uid, gid})))
|
|
380
|
+
.then(() => ({ uid, gid })))
|
|
364
381
|
}
|
|
365
382
|
|
|
366
383
|
// extraction is always the same. the only difference is where
|
|
367
384
|
// the tarball comes from.
|
|
368
385
|
extract (dest) {
|
|
369
|
-
return this[_mkdir](dest).then(({uid, gid}) =>
|
|
386
|
+
return this[_mkdir](dest).then(({ uid, gid }) =>
|
|
370
387
|
this.tarballStream(tarball => this[_extract](dest, tarball, uid, gid)))
|
|
371
388
|
}
|
|
372
389
|
|
|
@@ -389,7 +406,7 @@ class FetcherBase {
|
|
|
389
406
|
const dir = dirname(dest)
|
|
390
407
|
return !inferOwner
|
|
391
408
|
? mkdirp(dir).then(() => this[_toFile](dest))
|
|
392
|
-
: inferOwner(dest).then(({uid, gid}) =>
|
|
409
|
+
: inferOwner(dest).then(({ uid, gid }) =>
|
|
393
410
|
mkdirp(dir).then(made => this[_toFile](dest)
|
|
394
411
|
.then(res => this[_chown](made || dir, uid, gid)
|
|
395
412
|
.then(() => res))))
|
|
@@ -407,8 +424,8 @@ class FetcherBase {
|
|
|
407
424
|
})
|
|
408
425
|
|
|
409
426
|
extractor.on('error', er => {
|
|
410
|
-
|
|
411
|
-
|
|
427
|
+
log.warn('tar', er.message)
|
|
428
|
+
log.silly('tar', er)
|
|
412
429
|
reject(er)
|
|
413
430
|
})
|
|
414
431
|
|
|
@@ -439,21 +456,23 @@ class FetcherBase {
|
|
|
439
456
|
noChmod: true,
|
|
440
457
|
noMtime: true,
|
|
441
458
|
filter: (name, entry) => {
|
|
442
|
-
if (/Link$/.test(entry.type))
|
|
459
|
+
if (/Link$/.test(entry.type)) {
|
|
443
460
|
return false
|
|
461
|
+
}
|
|
444
462
|
entry.mode = this[_entryMode](entry.path, entry.mode, entry.type)
|
|
445
463
|
// this replicates the npm pack behavior where .gitignore files
|
|
446
464
|
// are treated like .npmignore files, but only if a .npmignore
|
|
447
465
|
// file is not present.
|
|
448
466
|
if (/File$/.test(entry.type)) {
|
|
449
467
|
const base = basename(entry.path)
|
|
450
|
-
if (base === '.npmignore')
|
|
468
|
+
if (base === '.npmignore') {
|
|
451
469
|
sawIgnores.add(entry.path)
|
|
452
|
-
else if (base === '.gitignore' && !this.allowGitIgnore) {
|
|
470
|
+
} else if (base === '.gitignore' && !this.allowGitIgnore) {
|
|
453
471
|
// rename, but only if there's not already a .npmignore
|
|
454
472
|
const ni = entry.path.replace(/\.gitignore$/, '.npmignore')
|
|
455
|
-
if (sawIgnores.has(ni))
|
|
473
|
+
if (sawIgnores.has(ni)) {
|
|
456
474
|
return false
|
|
475
|
+
}
|
|
457
476
|
entry.path = ni
|
|
458
477
|
}
|
|
459
478
|
return true
|
|
@@ -462,8 +481,8 @@ class FetcherBase {
|
|
|
462
481
|
strip: 1,
|
|
463
482
|
onwarn: /* istanbul ignore next - we can trust that tar logs */
|
|
464
483
|
(code, msg, data) => {
|
|
465
|
-
|
|
466
|
-
|
|
484
|
+
log.warn('tar', code, msg)
|
|
485
|
+
log.silly('tar', code, msg, data)
|
|
467
486
|
},
|
|
468
487
|
uid,
|
|
469
488
|
gid,
|
package/lib/file.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
const Fetcher = require('./fetcher.js')
|
|
2
2
|
const fsm = require('fs-minipass')
|
|
3
3
|
const cacache = require('cacache')
|
|
4
|
-
const { promisify } = require('util')
|
|
5
|
-
const readPackageJson = require('read-package-json-fast')
|
|
6
4
|
const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
|
|
7
5
|
const _exeBins = Symbol('_exeBins')
|
|
8
6
|
const { resolve } = require('path')
|
|
9
7
|
const fs = require('fs')
|
|
8
|
+
const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson')
|
|
10
9
|
|
|
11
10
|
class FileFetcher extends Fetcher {
|
|
12
11
|
constructor (spec, opts) {
|
|
@@ -20,24 +19,26 @@ class FileFetcher extends Fetcher {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
manifest () {
|
|
23
|
-
if (this.package)
|
|
22
|
+
if (this.package) {
|
|
24
23
|
return Promise.resolve(this.package)
|
|
24
|
+
}
|
|
25
25
|
|
|
26
26
|
// have to unpack the tarball for this.
|
|
27
27
|
return cacache.tmp.withTmp(this.cache, this.opts, dir =>
|
|
28
28
|
this.extract(dir)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
.then(() => this[_readPackageJson](dir + '/package.json'))
|
|
30
|
+
.then(mani => this.package = {
|
|
31
|
+
...mani,
|
|
32
|
+
_integrity: this.integrity && String(this.integrity),
|
|
33
|
+
_resolved: this.resolved,
|
|
34
|
+
_from: this.from,
|
|
35
|
+
}))
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
[_exeBins] (pkg, dest) {
|
|
39
|
-
if (!pkg.bin)
|
|
39
|
+
if (!pkg.bin) {
|
|
40
40
|
return Promise.resolve()
|
|
41
|
+
}
|
|
41
42
|
|
|
42
43
|
return Promise.all(Object.keys(pkg.bin).map(k => new Promise(res => {
|
|
43
44
|
const script = resolve(dest, pkg.bin[k])
|
|
@@ -46,11 +47,13 @@ class FileFetcher extends Fetcher {
|
|
|
46
47
|
// something, we just leave it for a later stage to trip over
|
|
47
48
|
// when we can provide a more useful contextual error.
|
|
48
49
|
fs.stat(script, (er, st) => {
|
|
49
|
-
if (er)
|
|
50
|
+
if (er) {
|
|
50
51
|
return res()
|
|
52
|
+
}
|
|
51
53
|
const mode = st.mode | 0o111
|
|
52
|
-
if (mode === st.mode)
|
|
54
|
+
if (mode === st.mode) {
|
|
53
55
|
return res()
|
|
56
|
+
}
|
|
54
57
|
fs.chmod(script, mode, res)
|
|
55
58
|
})
|
|
56
59
|
})))
|
|
@@ -61,8 +64,8 @@ class FileFetcher extends Fetcher {
|
|
|
61
64
|
// but if not, read the unpacked manifest and chmod properly.
|
|
62
65
|
return super.extract(dest)
|
|
63
66
|
.then(result => this.package ? result
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
: this[_readPackageJson](dest + '/package.json').then(pkg =>
|
|
68
|
+
this[_exeBins](pkg, dest)).then(() => result))
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
[_tarballFromResolved] () {
|
|
@@ -75,7 +78,7 @@ class FileFetcher extends Fetcher {
|
|
|
75
78
|
return this.manifest().then(mani => ({
|
|
76
79
|
name: mani.name,
|
|
77
80
|
'dist-tags': {
|
|
78
|
-
[this.defaultTag]: mani.version
|
|
81
|
+
[this.defaultTag]: mani.version,
|
|
79
82
|
},
|
|
80
83
|
versions: {
|
|
81
84
|
[mani.version]: {
|
|
@@ -83,9 +86,9 @@ class FileFetcher extends Fetcher {
|
|
|
83
86
|
dist: {
|
|
84
87
|
tarball: `file:${this.resolved}`,
|
|
85
88
|
integrity: this.integrity && String(this.integrity),
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
89
92
|
}))
|
|
90
93
|
}
|
|
91
94
|
}
|
package/lib/git.js
CHANGED
|
@@ -6,11 +6,9 @@ const hashre = /^[a-f0-9]{40}$/
|
|
|
6
6
|
const git = require('@npmcli/git')
|
|
7
7
|
const pickManifest = require('npm-pick-manifest')
|
|
8
8
|
const npa = require('npm-package-arg')
|
|
9
|
-
const url = require('url')
|
|
10
9
|
const Minipass = require('minipass')
|
|
11
10
|
const cacache = require('cacache')
|
|
12
|
-
const
|
|
13
|
-
const readPackageJson = require('read-package-json-fast')
|
|
11
|
+
const log = require('proc-log')
|
|
14
12
|
const npm = require('./util/npm.js')
|
|
15
13
|
|
|
16
14
|
const _resolvedFromRepo = Symbol('_resolvedFromRepo')
|
|
@@ -24,6 +22,7 @@ const _cloneHosted = Symbol('_cloneHosted')
|
|
|
24
22
|
const _cloneRepo = Symbol('_cloneRepo')
|
|
25
23
|
const _setResolvedWithSha = Symbol('_setResolvedWithSha')
|
|
26
24
|
const _prepareDir = Symbol('_prepareDir')
|
|
25
|
+
const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson')
|
|
27
26
|
|
|
28
27
|
// get the repository url.
|
|
29
28
|
// prefer https if there's auth, since ssh will drop that.
|
|
@@ -40,8 +39,9 @@ class GitFetcher extends Fetcher {
|
|
|
40
39
|
constructor (spec, opts) {
|
|
41
40
|
super(spec, opts)
|
|
42
41
|
this.resolvedRef = null
|
|
43
|
-
if (this.spec.hosted)
|
|
42
|
+
if (this.spec.hosted) {
|
|
44
43
|
this.from = this.spec.hosted.shortcut({ noCommittish: false })
|
|
44
|
+
}
|
|
45
45
|
|
|
46
46
|
// shortcut: avoid full clone when we can go straight to the tgz
|
|
47
47
|
// if we have the full sha and it's a hosted git platform
|
|
@@ -51,8 +51,9 @@ class GitFetcher extends Fetcher {
|
|
|
51
51
|
this.resolved = this.spec.hosted
|
|
52
52
|
? repoUrl(this.spec.hosted, { noCommittish: false })
|
|
53
53
|
: this.spec.rawSpec
|
|
54
|
-
} else
|
|
54
|
+
} else {
|
|
55
55
|
this.resolvedSha = ''
|
|
56
|
+
}
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
// just exposed to make it easier to test all the combinations
|
|
@@ -67,8 +68,9 @@ class GitFetcher extends Fetcher {
|
|
|
67
68
|
resolve () {
|
|
68
69
|
// likely a hosted git repo with a sha, so get the tarball url
|
|
69
70
|
// but in general, no reason to resolve() more than necessary!
|
|
70
|
-
if (this.resolved)
|
|
71
|
+
if (this.resolved) {
|
|
71
72
|
return super.resolve()
|
|
73
|
+
}
|
|
72
74
|
|
|
73
75
|
// fetch the git repo and then look at the current hash
|
|
74
76
|
const h = this.spec.hosted
|
|
@@ -86,37 +88,41 @@ class GitFetcher extends Fetcher {
|
|
|
86
88
|
return this[_resolvedFromRepo](hosted.https && hosted.https())
|
|
87
89
|
.catch(er => {
|
|
88
90
|
// Throw early since we know pathspec errors will fail again if retried
|
|
89
|
-
if (er instanceof git.errors.GitPathspecError)
|
|
91
|
+
if (er instanceof git.errors.GitPathspecError) {
|
|
90
92
|
throw er
|
|
93
|
+
}
|
|
91
94
|
const ssh = hosted.sshurl && hosted.sshurl()
|
|
92
95
|
// no fallthrough if we can't fall through or have https auth
|
|
93
|
-
if (!ssh || hosted.auth)
|
|
96
|
+
if (!ssh || hosted.auth) {
|
|
94
97
|
throw er
|
|
98
|
+
}
|
|
95
99
|
return this[_resolvedFromRepo](ssh)
|
|
96
100
|
})
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
[_resolvedFromRepo] (gitRemote) {
|
|
100
104
|
// XXX make this a custom error class
|
|
101
|
-
if (!gitRemote)
|
|
105
|
+
if (!gitRemote) {
|
|
102
106
|
return Promise.reject(new Error(`No git url for ${this.spec}`))
|
|
107
|
+
}
|
|
103
108
|
const gitRange = this.spec.gitRange
|
|
104
109
|
const name = this.spec.name
|
|
105
110
|
return git.revs(gitRemote, this.opts).then(remoteRefs => {
|
|
106
111
|
return gitRange ? pickManifest({
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
versions: remoteRefs.versions,
|
|
113
|
+
'dist-tags': remoteRefs['dist-tags'],
|
|
114
|
+
name,
|
|
115
|
+
}, gitRange, this.opts)
|
|
111
116
|
: this.spec.gitCommittish ?
|
|
112
117
|
remoteRefs.refs[this.spec.gitCommittish] ||
|
|
113
118
|
remoteRefs.refs[remoteRefs.shas[this.spec.gitCommittish]]
|
|
114
|
-
|
|
119
|
+
: remoteRefs.refs.HEAD // no git committish, get default head
|
|
115
120
|
}).then(revDoc => {
|
|
116
121
|
// the committish provided isn't in the rev list
|
|
117
122
|
// things like HEAD~3 or @yesterday can land here.
|
|
118
|
-
if (!revDoc || !revDoc.sha)
|
|
123
|
+
if (!revDoc || !revDoc.sha) {
|
|
119
124
|
return this[_resolvedFromClone]()
|
|
125
|
+
}
|
|
120
126
|
|
|
121
127
|
this.resolvedRef = revDoc
|
|
122
128
|
this.resolvedSha = revDoc.sha
|
|
@@ -145,16 +151,18 @@ class GitFetcher extends Fetcher {
|
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
[_prepareDir] (dir) {
|
|
148
|
-
return
|
|
154
|
+
return this[_readPackageJson](dir + '/package.json').then(mani => {
|
|
149
155
|
// no need if we aren't going to do any preparation.
|
|
150
156
|
const scripts = mani.scripts
|
|
151
|
-
if (!scripts || !(
|
|
152
|
-
|
|
157
|
+
if (!mani.workspaces && (!scripts || !(
|
|
158
|
+
scripts.postinstall ||
|
|
153
159
|
scripts.build ||
|
|
154
160
|
scripts.preinstall ||
|
|
155
161
|
scripts.install ||
|
|
156
|
-
scripts.
|
|
162
|
+
scripts.prepack ||
|
|
163
|
+
scripts.prepare))) {
|
|
157
164
|
return
|
|
165
|
+
}
|
|
158
166
|
|
|
159
167
|
// to avoid cases where we have an cycle of git deps that depend
|
|
160
168
|
// on one another, we only ever do preparation for one instance
|
|
@@ -166,7 +174,7 @@ class GitFetcher extends Fetcher {
|
|
|
166
174
|
const noPrepare = !process.env._PACOTE_NO_PREPARE_ ? []
|
|
167
175
|
: process.env._PACOTE_NO_PREPARE_.split('\n')
|
|
168
176
|
if (noPrepare.includes(this.resolved)) {
|
|
169
|
-
|
|
177
|
+
log.info('prepare', 'skip prepare, already seen', this.resolved)
|
|
170
178
|
return
|
|
171
179
|
}
|
|
172
180
|
noPrepare.push(this.resolved)
|
|
@@ -202,9 +210,9 @@ class GitFetcher extends Fetcher {
|
|
|
202
210
|
dirStream.on('end', res)
|
|
203
211
|
dirStream.pipe(stream)
|
|
204
212
|
}))).catch(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
/* istanbul ignore next: very unlikely and hard to test */
|
|
214
|
+
er => stream.emit('error', er)
|
|
215
|
+
)
|
|
208
216
|
return stream
|
|
209
217
|
}
|
|
210
218
|
|
|
@@ -237,10 +245,11 @@ class GitFetcher extends Fetcher {
|
|
|
237
245
|
integrity: null, // it'll always be different, if we have one
|
|
238
246
|
}).extract(tmp).then(() => handler(tmp), er => {
|
|
239
247
|
// fall back to ssh download if tarball fails
|
|
240
|
-
if (er.constructor.name.match(/^Http/))
|
|
248
|
+
if (er.constructor.name.match(/^Http/)) {
|
|
241
249
|
return this[_clone](handler, false)
|
|
242
|
-
else
|
|
250
|
+
} else {
|
|
243
251
|
throw er
|
|
252
|
+
}
|
|
244
253
|
})
|
|
245
254
|
}
|
|
246
255
|
|
|
@@ -249,10 +258,11 @@ class GitFetcher extends Fetcher {
|
|
|
249
258
|
: this[_cloneRepo](this.spec.fetchSpec, ref, tmp)
|
|
250
259
|
).then(sha => {
|
|
251
260
|
this.resolvedSha = sha
|
|
252
|
-
if (!this.resolved)
|
|
261
|
+
if (!this.resolved) {
|
|
253
262
|
this[_addGitSha](sha)
|
|
263
|
+
}
|
|
254
264
|
})
|
|
255
|
-
|
|
265
|
+
.then(() => handler(tmp))
|
|
256
266
|
})
|
|
257
267
|
}
|
|
258
268
|
|
|
@@ -266,12 +276,14 @@ class GitFetcher extends Fetcher {
|
|
|
266
276
|
return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp)
|
|
267
277
|
.catch(er => {
|
|
268
278
|
// Throw early since we know pathspec errors will fail again if retried
|
|
269
|
-
if (er instanceof git.errors.GitPathspecError)
|
|
279
|
+
if (er instanceof git.errors.GitPathspecError) {
|
|
270
280
|
throw er
|
|
281
|
+
}
|
|
271
282
|
const ssh = hosted.sshurl && hosted.sshurl({ noCommittish: true })
|
|
272
283
|
// no fallthrough if we can't fall through or have https auth
|
|
273
|
-
if (!ssh || hosted.auth)
|
|
284
|
+
if (!ssh || hosted.auth) {
|
|
274
285
|
throw er
|
|
286
|
+
}
|
|
275
287
|
return this[_cloneRepo](ssh, ref, tmp)
|
|
276
288
|
})
|
|
277
289
|
}
|
|
@@ -282,19 +294,20 @@ class GitFetcher extends Fetcher {
|
|
|
282
294
|
}
|
|
283
295
|
|
|
284
296
|
manifest () {
|
|
285
|
-
if (this.package)
|
|
297
|
+
if (this.package) {
|
|
286
298
|
return Promise.resolve(this.package)
|
|
299
|
+
}
|
|
287
300
|
|
|
288
301
|
return this.spec.hosted && this.resolved
|
|
289
302
|
? FileFetcher.prototype.manifest.apply(this)
|
|
290
303
|
: this[_clone](dir =>
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
304
|
+
this[_readPackageJson](dir + '/package.json')
|
|
305
|
+
.then(mani => this.package = {
|
|
306
|
+
...mani,
|
|
307
|
+
_integrity: this.integrity && String(this.integrity),
|
|
308
|
+
_resolved: this.resolved,
|
|
309
|
+
_from: this.from,
|
|
310
|
+
}))
|
|
298
311
|
}
|
|
299
312
|
|
|
300
313
|
packument () {
|
package/lib/registry.js
CHANGED
|
@@ -2,11 +2,11 @@ const Fetcher = require('./fetcher.js')
|
|
|
2
2
|
const RemoteFetcher = require('./remote.js')
|
|
3
3
|
const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
|
|
4
4
|
const pacoteVersion = require('../package.json').version
|
|
5
|
+
const removeTrailingSlashes = require('./util/trailing-slashes.js')
|
|
5
6
|
const npa = require('npm-package-arg')
|
|
6
7
|
const rpj = require('read-package-json-fast')
|
|
7
8
|
const pickManifest = require('npm-pick-manifest')
|
|
8
9
|
const ssri = require('ssri')
|
|
9
|
-
const Minipass = require('minipass')
|
|
10
10
|
|
|
11
11
|
// Corgis are cute. 🐕🐶
|
|
12
12
|
const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*'
|
|
@@ -32,10 +32,11 @@ class RegistryFetcher extends Fetcher {
|
|
|
32
32
|
// handle case when npm-package-arg guesses wrong.
|
|
33
33
|
if (this.spec.type === 'tag' &&
|
|
34
34
|
this.spec.rawSpec === '' &&
|
|
35
|
-
this.defaultTag !== 'latest')
|
|
35
|
+
this.defaultTag !== 'latest') {
|
|
36
36
|
this.spec = npa(`${this.spec.name}@${this.defaultTag}`)
|
|
37
|
+
}
|
|
37
38
|
this.registry = fetch.pickRegistry(spec, opts)
|
|
38
|
-
this.packumentUrl = this.registry
|
|
39
|
+
this.packumentUrl = removeTrailingSlashes(this.registry) + '/' +
|
|
39
40
|
this.spec.escapedName
|
|
40
41
|
|
|
41
42
|
// XXX pacote <=9 has some logic to ignore opts.resolved if
|
|
@@ -45,13 +46,15 @@ class RegistryFetcher extends Fetcher {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
resolve () {
|
|
48
|
-
if (this.resolved)
|
|
49
|
+
if (this.resolved) {
|
|
49
50
|
return Promise.resolve(this.resolved)
|
|
51
|
+
}
|
|
50
52
|
|
|
51
53
|
// fetching the manifest sets resolved and (usually) integrity
|
|
52
54
|
return this.manifest().then(() => {
|
|
53
|
-
if (this.resolved)
|
|
55
|
+
if (this.resolved) {
|
|
54
56
|
return this.resolved
|
|
57
|
+
}
|
|
55
58
|
|
|
56
59
|
throw Object.assign(
|
|
57
60
|
new Error('Invalid package manifest: no `dist.tarball` field'),
|
|
@@ -77,8 +80,9 @@ class RegistryFetcher extends Fetcher {
|
|
|
77
80
|
// note this might be either an in-flight promise for a request,
|
|
78
81
|
// or the actual packument, but we never want to make more than
|
|
79
82
|
// one request at a time for the same thing regardless.
|
|
80
|
-
if (this.packumentCache && this.packumentCache.has(this.packumentUrl))
|
|
83
|
+
if (this.packumentCache && this.packumentCache.has(this.packumentUrl)) {
|
|
81
84
|
return this.packumentCache.get(this.packumentUrl)
|
|
85
|
+
}
|
|
82
86
|
|
|
83
87
|
// npm-registry-fetch the packument
|
|
84
88
|
// set the appropriate header for corgis if fullMetadata isn't set
|
|
@@ -92,12 +96,14 @@ class RegistryFetcher extends Fetcher {
|
|
|
92
96
|
}).then(res => res.json().then(packument => {
|
|
93
97
|
packument._cached = res.headers.has('x-local-cache')
|
|
94
98
|
packument._contentLength = +res.headers.get('content-length')
|
|
95
|
-
if (this.packumentCache)
|
|
99
|
+
if (this.packumentCache) {
|
|
96
100
|
this.packumentCache.set(this.packumentUrl, packument)
|
|
101
|
+
}
|
|
97
102
|
return packument
|
|
98
103
|
})).catch(er => {
|
|
99
|
-
if (this.packumentCache)
|
|
104
|
+
if (this.packumentCache) {
|
|
100
105
|
this.packumentCache.delete(this.packumentUrl)
|
|
106
|
+
}
|
|
101
107
|
if (er.code === 'E404' && !this.fullMetadata) {
|
|
102
108
|
// possible that corgis are not supported by this registry
|
|
103
109
|
this.fullMetadata = true
|
|
@@ -105,14 +111,16 @@ class RegistryFetcher extends Fetcher {
|
|
|
105
111
|
}
|
|
106
112
|
throw er
|
|
107
113
|
})
|
|
108
|
-
if (this.packumentCache)
|
|
114
|
+
if (this.packumentCache) {
|
|
109
115
|
this.packumentCache.set(this.packumentUrl, p)
|
|
116
|
+
}
|
|
110
117
|
return p
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
manifest () {
|
|
114
|
-
if (this.package)
|
|
121
|
+
if (this.package) {
|
|
115
122
|
return Promise.resolve(this.package)
|
|
123
|
+
}
|
|
116
124
|
|
|
117
125
|
return this.packument()
|
|
118
126
|
.then(packument => pickManifest(packument, this.spec.fetchSpec, {
|
|
@@ -127,12 +135,12 @@ class RegistryFetcher extends Fetcher {
|
|
|
127
135
|
this.resolved = mani._resolved = dist.tarball
|
|
128
136
|
mani._from = this.from
|
|
129
137
|
const distIntegrity = dist.integrity ? ssri.parse(dist.integrity)
|
|
130
|
-
: dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', {...this.opts})
|
|
138
|
+
: dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts })
|
|
131
139
|
: null
|
|
132
140
|
if (distIntegrity) {
|
|
133
|
-
if (!this.integrity)
|
|
141
|
+
if (!this.integrity) {
|
|
134
142
|
this.integrity = distIntegrity
|
|
135
|
-
else if (!this.integrity.match(distIntegrity)) {
|
|
143
|
+
} else if (!this.integrity.match(distIntegrity)) {
|
|
136
144
|
// only bork if they have algos in common.
|
|
137
145
|
// otherwise we end up breaking if we have saved a sha512
|
|
138
146
|
// previously for the tarball, but the manifest only
|
|
@@ -143,7 +151,7 @@ class RegistryFetcher extends Fetcher {
|
|
|
143
151
|
for (const algo of Object.keys(this.integrity)) {
|
|
144
152
|
if (distIntegrity[algo]) {
|
|
145
153
|
throw Object.assign(new Error(
|
|
146
|
-
`Integrity checksum failed when using ${algo}:
|
|
154
|
+
`Integrity checksum failed when using ${algo}: ` +
|
|
147
155
|
`wanted ${this.integrity} but got ${distIntegrity}.`
|
|
148
156
|
), { code: 'EINTEGRITY' })
|
|
149
157
|
}
|
|
@@ -155,8 +163,9 @@ class RegistryFetcher extends Fetcher {
|
|
|
155
163
|
}
|
|
156
164
|
}
|
|
157
165
|
}
|
|
158
|
-
if (this.integrity)
|
|
166
|
+
if (this.integrity) {
|
|
159
167
|
mani._integrity = String(this.integrity)
|
|
168
|
+
}
|
|
160
169
|
this.package = rpj.normalize(mani)
|
|
161
170
|
return this.package
|
|
162
171
|
})
|
package/lib/remote.js
CHANGED
|
@@ -3,7 +3,6 @@ const FileFetcher = require('./file.js')
|
|
|
3
3
|
const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
|
|
4
4
|
const pacoteVersion = require('../package.json').version
|
|
5
5
|
const fetch = require('npm-registry-fetch')
|
|
6
|
-
const ssri = require('ssri')
|
|
7
6
|
const Minipass = require('minipass')
|
|
8
7
|
// The default registry URL is a string of great magic.
|
|
9
8
|
const magic = /^https?:\/\/registry\.npmjs\.org\//
|
|
@@ -14,8 +13,9 @@ class RemoteFetcher extends Fetcher {
|
|
|
14
13
|
constructor (spec, opts) {
|
|
15
14
|
super(spec, opts)
|
|
16
15
|
this.resolved = this.spec.fetchSpec
|
|
17
|
-
if (magic.test(this.resolved) && !magic.test(this.registry + '/'))
|
|
16
|
+
if (magic.test(this.resolved) && !magic.test(this.registry + '/')) {
|
|
18
17
|
this.resolved = this.resolved.replace(magic, this.registry + '/')
|
|
18
|
+
}
|
|
19
19
|
|
|
20
20
|
// nam is a fermented pork sausage that is good to eat
|
|
21
21
|
const nameat = this.spec.name ? `${this.spec.name}@` : ''
|
|
@@ -35,7 +35,7 @@ class RemoteFetcher extends Fetcher {
|
|
|
35
35
|
headers: this[_headers](),
|
|
36
36
|
spec: this.spec,
|
|
37
37
|
integrity: this.integrity,
|
|
38
|
-
algorithms: [
|
|
38
|
+
algorithms: [this.pickIntegrityAlgorithm()],
|
|
39
39
|
}
|
|
40
40
|
fetch(this.resolved, fetchOpts).then(res => {
|
|
41
41
|
const hash = res.headers.get('x-local-cache-hash')
|
|
@@ -62,7 +62,7 @@ class RemoteFetcher extends Fetcher {
|
|
|
62
62
|
'pacote-req-type': 'tarball',
|
|
63
63
|
'pacote-pkg-id': this.pkgid,
|
|
64
64
|
...(this.integrity ? { 'pacote-integrity': String(this.integrity) }
|
|
65
|
-
|
|
65
|
+
: {}),
|
|
66
66
|
...(this.opts.headers || {}),
|
|
67
67
|
}
|
|
68
68
|
}
|
package/lib/util/cache-dir.js
CHANGED
|
@@ -12,10 +12,11 @@ const binObj = (name, bin) =>
|
|
|
12
12
|
|
|
13
13
|
const hasBin = (pkg, path) => {
|
|
14
14
|
const bin = binObj(pkg.name, pkg.bin)
|
|
15
|
-
const p = path.replace(/^[
|
|
16
|
-
for (const
|
|
17
|
-
if (
|
|
15
|
+
const p = path.replace(/^[^\\/]*\//, '')
|
|
16
|
+
for (const kv of Object.entries(bin)) {
|
|
17
|
+
if (kv[1] === p) {
|
|
18
18
|
return true
|
|
19
|
+
}
|
|
19
20
|
}
|
|
20
21
|
return false
|
|
21
22
|
}
|
package/lib/util/npm.js
CHANGED
|
@@ -9,7 +9,7 @@ const tarCreateOptions = manifest => ({
|
|
|
9
9
|
// platform specific optimizations that cause
|
|
10
10
|
// integrity mismatch errors due to differing
|
|
11
11
|
// end results after compression
|
|
12
|
-
level: 9
|
|
12
|
+
level: 9,
|
|
13
13
|
},
|
|
14
14
|
|
|
15
15
|
// ensure that package bins are always executable
|
|
@@ -17,8 +17,9 @@ const tarCreateOptions = manifest => ({
|
|
|
17
17
|
// anything that is not a regular file, ignored by
|
|
18
18
|
// .npmignore or package.json "files", etc.
|
|
19
19
|
filter: (path, stat) => {
|
|
20
|
-
if (isPackageBin(manifest, path))
|
|
20
|
+
if (isPackageBin(manifest, path)) {
|
|
21
21
|
stat.mode |= 0o111
|
|
22
|
+
}
|
|
22
23
|
return true
|
|
23
24
|
},
|
|
24
25
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pacote",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.2",
|
|
4
4
|
"description": "JavaScript package downloader",
|
|
5
|
-
"author": "
|
|
5
|
+
"author": "GitHub Inc.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"pacote": "lib/bin.js"
|
|
8
8
|
},
|
|
@@ -13,19 +13,26 @@
|
|
|
13
13
|
"snap": "tap",
|
|
14
14
|
"preversion": "npm test",
|
|
15
15
|
"postversion": "npm publish",
|
|
16
|
-
"prepublishOnly": "git push origin --follow-tags"
|
|
16
|
+
"prepublishOnly": "git push origin --follow-tags",
|
|
17
|
+
"lint": "eslint '**/*.js'",
|
|
18
|
+
"postlint": "npm-template-check",
|
|
19
|
+
"lintfix": "npm run lint -- --fix",
|
|
20
|
+
"posttest": "npm run lint",
|
|
21
|
+
"template-copy": "npm-template-copy --force"
|
|
17
22
|
},
|
|
18
23
|
"tap": {
|
|
19
24
|
"timeout": 300,
|
|
20
25
|
"coverage-map": "map.js"
|
|
21
26
|
},
|
|
22
27
|
"devDependencies": {
|
|
28
|
+
"@npmcli/template-oss": "^2.7.1",
|
|
23
29
|
"mutate-fs": "^2.1.1",
|
|
24
30
|
"npm-registry-mock": "^1.3.1",
|
|
25
|
-
"tap": "^15.
|
|
31
|
+
"tap": "^15.1.6"
|
|
26
32
|
},
|
|
27
33
|
"files": [
|
|
28
|
-
"
|
|
34
|
+
"bin",
|
|
35
|
+
"lib"
|
|
29
36
|
],
|
|
30
37
|
"keywords": [
|
|
31
38
|
"packages",
|
|
@@ -33,28 +40,34 @@
|
|
|
33
40
|
"git"
|
|
34
41
|
],
|
|
35
42
|
"dependencies": {
|
|
36
|
-
"@npmcli/git": "^
|
|
37
|
-
"@npmcli/installed-package-contents": "^1.0.
|
|
43
|
+
"@npmcli/git": "^3.0.0",
|
|
44
|
+
"@npmcli/installed-package-contents": "^1.0.7",
|
|
38
45
|
"@npmcli/promise-spawn": "^1.2.0",
|
|
39
46
|
"@npmcli/run-script": "^2.0.0",
|
|
40
|
-
"cacache": "^15.0
|
|
47
|
+
"cacache": "^15.3.0",
|
|
41
48
|
"chownr": "^2.0.0",
|
|
42
49
|
"fs-minipass": "^2.1.0",
|
|
43
50
|
"infer-owner": "^1.0.4",
|
|
44
|
-
"minipass": "^3.1.
|
|
45
|
-
"mkdirp": "^1.0.
|
|
46
|
-
"npm-package-arg": "^
|
|
51
|
+
"minipass": "^3.1.6",
|
|
52
|
+
"mkdirp": "^1.0.4",
|
|
53
|
+
"npm-package-arg": "^9.0.0",
|
|
47
54
|
"npm-packlist": "^3.0.0",
|
|
48
|
-
"npm-pick-manifest": "^
|
|
49
|
-
"npm-registry-fetch": "^
|
|
55
|
+
"npm-pick-manifest": "^7.0.0",
|
|
56
|
+
"npm-registry-fetch": "^13.0.0",
|
|
57
|
+
"proc-log": "^2.0.0",
|
|
50
58
|
"promise-retry": "^2.0.1",
|
|
51
|
-
"read-package-json
|
|
59
|
+
"read-package-json": "^4.1.1",
|
|
60
|
+
"read-package-json-fast": "^2.0.3",
|
|
52
61
|
"rimraf": "^3.0.2",
|
|
53
62
|
"ssri": "^8.0.1",
|
|
54
|
-
"tar": "^6.1.
|
|
63
|
+
"tar": "^6.1.11"
|
|
55
64
|
},
|
|
56
65
|
"engines": {
|
|
57
66
|
"node": "^12.13.0 || ^14.15.0 || >=16"
|
|
58
67
|
},
|
|
59
|
-
"repository": "git@github.com:npm/pacote"
|
|
68
|
+
"repository": "git@github.com:npm/pacote",
|
|
69
|
+
"templateOSS": {
|
|
70
|
+
"version": "2.7.1",
|
|
71
|
+
"windowsCI": false
|
|
72
|
+
}
|
|
60
73
|
}
|
package/lib/util/proc-log.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// default logger.
|
|
2
|
-
// emits 'log' events on the process
|
|
3
|
-
const LEVELS = [
|
|
4
|
-
'notice',
|
|
5
|
-
'error',
|
|
6
|
-
'warn',
|
|
7
|
-
'info',
|
|
8
|
-
'verbose',
|
|
9
|
-
'http',
|
|
10
|
-
'silly',
|
|
11
|
-
'pause',
|
|
12
|
-
'resume'
|
|
13
|
-
]
|
|
14
|
-
|
|
15
|
-
const log = level => (...args) => process.emit('log', level, ...args)
|
|
16
|
-
|
|
17
|
-
const logger = {}
|
|
18
|
-
for (const level of LEVELS) {
|
|
19
|
-
logger[level] = log(level)
|
|
20
|
-
}
|
|
21
|
-
module.exports = logger
|