cacache 17.0.6 → 17.1.0

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
@@ -101,7 +101,7 @@ cacache.get.byDigest(cachePath, integrityHash).then(data => {
101
101
 
102
102
  ### Contributing
103
103
 
104
- The cacache team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! The [Contributor Guide](CONTRIBUTING.md) has all the information you need for everything from reporting bugs to contributing entire new features. Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.
104
+ The cacache team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.
105
105
 
106
106
  All participants and maintainers in this project are expected to follow [Code of Conduct](CODE_OF_CONDUCT.md), and just generally be excellent to each other.
107
107
 
@@ -4,7 +4,7 @@ const events = require('events')
4
4
 
5
5
  const contentPath = require('./path')
6
6
  const fs = require('fs/promises')
7
- const moveFile = require('../util/move-file')
7
+ const { moveFile } = require('@npmcli/fs')
8
8
  const { Minipass } = require('minipass')
9
9
  const Pipeline = require('minipass-pipeline')
10
10
  const Flush = require('minipass-flush')
@@ -17,9 +17,6 @@ module.exports = write
17
17
 
18
18
  async function write (cache, data, opts = {}) {
19
19
  const { algorithms, size, integrity } = opts
20
- if (algorithms && algorithms.length > 1) {
21
- throw new Error('opts.algorithms only supports a single algorithm for now')
22
- }
23
20
 
24
21
  if (typeof size === 'number' && data.length !== size) {
25
22
  throw sizeError(size, data.length)
@@ -30,16 +27,19 @@ async function write (cache, data, opts = {}) {
30
27
  throw checksumError(integrity, sri)
31
28
  }
32
29
 
33
- const tmp = await makeTmp(cache, opts)
34
- try {
35
- await fs.writeFile(tmp.target, data, { flag: 'wx' })
36
- await moveToDestination(tmp, cache, sri, opts)
37
- return { integrity: sri, size: data.length }
38
- } finally {
39
- if (!tmp.moved) {
40
- await fs.rm(tmp.target, { recursive: true, force: true })
30
+ for (const algo in sri) {
31
+ const tmp = await makeTmp(cache, opts)
32
+ const hash = sri[algo].toString()
33
+ try {
34
+ await fs.writeFile(tmp.target, data, { flag: 'wx' })
35
+ await moveToDestination(tmp, cache, hash, opts)
36
+ } finally {
37
+ if (!tmp.moved) {
38
+ await fs.rm(tmp.target, { recursive: true, force: true })
39
+ }
41
40
  }
42
41
  }
42
+ return { integrity: sri, size: data.length }
43
43
  }
44
44
 
45
45
  module.exports.stream = writeStream
@@ -161,8 +161,14 @@ async function moveToDestination (tmp, cache, sri, opts) {
161
161
  const destDir = path.dirname(destination)
162
162
 
163
163
  await fs.mkdir(destDir, { recursive: true })
164
- await moveFile(tmp.target, destination)
165
- tmp.moved = true
164
+ try {
165
+ await moveFile(tmp.target, destination, { overwrite: false })
166
+ tmp.moved = true
167
+ } catch (err) {
168
+ if (!err.message.startsWith('The destination file exists')) {
169
+ throw Object.assign(err, { code: 'EEXIST' })
170
+ }
171
+ }
166
172
  }
167
173
 
168
174
  function sizeError (expected, found) {
@@ -109,12 +109,12 @@ async function compact (cache, key, matchFn, opts = {}) {
109
109
  module.exports.insert = insert
110
110
 
111
111
  async function insert (cache, key, integrity, opts = {}) {
112
- const { metadata, size } = opts
112
+ const { metadata, size, time } = opts
113
113
  const bucket = bucketPath(cache, key)
114
114
  const entry = {
115
115
  key,
116
116
  integrity: integrity && ssri.stringify(integrity),
117
- time: Date.now(),
117
+ time: time || Date.now(),
118
118
  size,
119
119
  metadata,
120
120
  }
package/lib/verify.js CHANGED
@@ -100,7 +100,11 @@ async function garbageCollect (cache, opts) {
100
100
  return
101
101
  }
102
102
 
103
- liveContent.add(entry.integrity.toString())
103
+ // integrity is stringified, re-parse it so we can get each hash
104
+ const integrity = ssri.parse(entry.integrity)
105
+ for (const algo in integrity) {
106
+ liveContent.add(integrity[algo].toString())
107
+ }
104
108
  })
105
109
  await new Promise((resolve, reject) => {
106
110
  indexStream.on('end', resolve).on('error', reject)
@@ -220,6 +224,7 @@ async function rebuildBucket (cache, bucket, stats, opts) {
220
224
  await index.insert(cache, entry.key, entry.integrity, {
221
225
  metadata: entry.metadata,
222
226
  size: entry.size,
227
+ time: entry.time,
223
228
  })
224
229
  stats.totalEntries++
225
230
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cacache",
3
- "version": "17.0.6",
3
+ "version": "17.1.0",
4
4
  "cache-version": {
5
5
  "content": "2",
6
6
  "index": "5"
@@ -54,7 +54,6 @@
54
54
  "minipass-flush": "^1.0.5",
55
55
  "minipass-pipeline": "^1.2.4",
56
56
  "p-map": "^4.0.0",
57
- "promise-inflight": "^1.0.1",
58
57
  "ssri": "^10.0.0",
59
58
  "tar": "^6.1.11",
60
59
  "unique-filename": "^3.0.0"
@@ -1,56 +0,0 @@
1
- 'use strict'
2
-
3
- const fs = require('fs/promises')
4
- const { moveFile: move } = require('@npmcli/fs')
5
- const pinflight = require('promise-inflight')
6
-
7
- module.exports = moveFile
8
-
9
- async function moveFile (src, dest) {
10
- const isWindows = process.platform === 'win32'
11
-
12
- // This isn't quite an fs.rename -- the assumption is that
13
- // if `dest` already exists, and we get certain errors while
14
- // trying to move it, we should just not bother.
15
- //
16
- // In the case of cache corruption, users will receive an
17
- // EINTEGRITY error elsewhere, and can remove the offending
18
- // content their own way.
19
- //
20
- // Note that, as the name suggests, this strictly only supports file moves.
21
- try {
22
- await fs.link(src, dest)
23
- } catch (err) {
24
- if (isWindows && err.code === 'EPERM') {
25
- // XXX This is a really weird way to handle this situation, as it
26
- // results in the src file being deleted even though the dest
27
- // might not exist. Since we pretty much always write files to
28
- // deterministic locations based on content hash, this is likely
29
- // ok (or at worst, just ends in a future cache miss). But it would
30
- // be worth investigating at some time in the future if this is
31
- // really what we want to do here.
32
- } else if (err.code === 'EEXIST' || err.code === 'EBUSY') {
33
- // file already exists, so whatever
34
- } else {
35
- throw err
36
- }
37
- }
38
- try {
39
- await Promise.all([
40
- fs.unlink(src),
41
- !isWindows && fs.chmod(dest, '0444'),
42
- ])
43
- } catch (e) {
44
- return pinflight('cacache-move-file:' + dest, async () => {
45
- await fs.stat(dest).catch((err) => {
46
- if (err.code !== 'ENOENT') {
47
- // Something else is wrong here. Bail bail bail
48
- throw err
49
- }
50
- })
51
- // file doesn't already exist! let's try a rename -> copy fallback
52
- // only delete if it successfully copies
53
- return move(src, dest)
54
- })
55
- }
56
- }