cacache 15.0.5 → 15.3.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
@@ -36,6 +36,8 @@ just as easily be used on its own.
36
36
  * [`rm.all`](#rm-all)
37
37
  * [`rm.entry`](#rm-entry)
38
38
  * [`rm.content`](#rm-content)
39
+ * [`index.compact`](#index-compact)
40
+ * [`index.insert`](#index-insert)
39
41
  * Utilities
40
42
  * [`clearMemoized`](#clear-memoized)
41
43
  * [`tmp.mkdir`](#tmp-mkdir)
@@ -456,13 +458,17 @@ cacache.rm.all(cachePath).then(() => {
456
458
  })
457
459
  ```
458
460
 
459
- #### <a name="rm-entry"></a> `> cacache.rm.entry(cache, key) -> Promise`
461
+ #### <a name="rm-entry"></a> `> cacache.rm.entry(cache, key, [opts]) -> Promise`
460
462
 
461
463
  Alias: `cacache.rm`
462
464
 
463
465
  Removes the index entry for `key`. Content will still be accessible if
464
466
  requested directly by content address ([`get.stream.byDigest`](#get-stream)).
465
467
 
468
+ By default, this appends a new entry to the index with an integrity of `null`.
469
+ If `opts.removeFully` is set to `true` then the index file itself will be
470
+ physically deleted rather than appending a `null`.
471
+
466
472
  To remove the content itself (which might still be used by other entries), use
467
473
  [`rm.content`](#rm-content). Or, to safely vacuum any unused content, use
468
474
  [`verify`](#verify).
@@ -489,6 +495,34 @@ cacache.rm.content(cachePath, 'sha512-SoMeDIGest/IN+BaSE64==').then(() => {
489
495
  })
490
496
  ```
491
497
 
498
+ #### <a name="index-compact"></a> `> cacache.index.compact(cache, key, matchFn, [opts]) -> Promise`
499
+
500
+ Uses `matchFn`, which must be a synchronous function that accepts two entries
501
+ and returns a boolean indicating whether or not the two entries match, to
502
+ deduplicate all entries in the cache for the given `key`.
503
+
504
+ If `opts.validateEntry` is provided, it will be called as a function with the
505
+ only parameter being a single index entry. The function must return a Boolean,
506
+ if it returns `true` the entry is considered valid and will be kept in the index,
507
+ if it returns `false` the entry will be removed from the index.
508
+
509
+ If `opts.validateEntry` is not provided, however, every entry in the index will
510
+ be deduplicated and kept until the first `null` integrity is reached, removing
511
+ all entries that were written before the `null`.
512
+
513
+ The deduplicated list of entries is both written to the index, replacing the
514
+ existing content, and returned in the Promise.
515
+
516
+ #### <a name="index-insert"></a> `> cacache.index.insert(cache, key, integrity, opts) -> Promise`
517
+
518
+ Writes an index entry to the cache for the given `key` without writing content.
519
+
520
+ It is assumed if you are using this method, you have already stored the content
521
+ some other way and you only wish to add a new index to that content. The `metadata`
522
+ and `size` properties are read from `opts` and used as part of the index entry.
523
+
524
+ Returns a Promise resolving to the newly added entry.
525
+
492
526
  #### <a name="clear-memoized"></a> `> cacache.clearMemoized()`
493
527
 
494
528
  Completely resets the in-memory entry cache.
package/get.js CHANGED
@@ -1,119 +1,112 @@
1
1
  'use strict'
2
2
 
3
- const util = require('util')
3
+ const Collect = require('minipass-collect')
4
+ const Minipass = require('minipass')
5
+ const Pipeline = require('minipass-pipeline')
4
6
  const fs = require('fs')
7
+ const util = require('util')
8
+
5
9
  const index = require('./lib/entry-index')
6
10
  const memo = require('./lib/memoization')
7
11
  const read = require('./lib/content/read')
8
12
 
9
- const Minipass = require('minipass')
10
- const Collect = require('minipass-collect')
11
- const Pipeline = require('minipass-pipeline')
12
-
13
13
  const writeFile = util.promisify(fs.writeFile)
14
14
 
15
- module.exports = function get (cache, key, opts) {
16
- return getData(false, cache, key, opts)
17
- }
18
- module.exports.byDigest = function getByDigest (cache, digest, opts) {
19
- return getData(true, cache, digest, opts)
20
- }
21
-
22
- function getData (byDigest, cache, key, opts = {}) {
15
+ function getData (cache, key, opts = {}) {
23
16
  const { integrity, memoize, size } = opts
24
- const memoized = byDigest
25
- ? memo.get.byDigest(cache, key, opts)
26
- : memo.get(cache, key, opts)
17
+ const memoized = memo.get(cache, key, opts)
27
18
  if (memoized && memoize !== false) {
28
- return Promise.resolve(
29
- byDigest
30
- ? memoized
31
- : {
32
- metadata: memoized.entry.metadata,
33
- data: memoized.data,
34
- integrity: memoized.entry.integrity,
35
- size: memoized.entry.size
36
- }
37
- )
19
+ return Promise.resolve({
20
+ metadata: memoized.entry.metadata,
21
+ data: memoized.data,
22
+ integrity: memoized.entry.integrity,
23
+ size: memoized.entry.size,
24
+ })
38
25
  }
39
- return (byDigest ? Promise.resolve(null) : index.find(cache, key, opts)).then(
40
- (entry) => {
41
- if (!entry && !byDigest) {
42
- throw new index.NotFoundError(cache, key)
26
+
27
+ return index.find(cache, key, opts).then((entry) => {
28
+ if (!entry)
29
+ throw new index.NotFoundError(cache, key)
30
+
31
+ return read(cache, entry.integrity, { integrity, size }).then((data) => {
32
+ if (memoize)
33
+ memo.put(cache, entry, data, opts)
34
+
35
+ return {
36
+ data,
37
+ metadata: entry.metadata,
38
+ size: entry.size,
39
+ integrity: entry.integrity,
43
40
  }
44
- return read(cache, byDigest ? key : entry.integrity, {
45
- integrity,
46
- size
47
- })
48
- .then((data) =>
49
- byDigest
50
- ? data
51
- : {
52
- data,
53
- metadata: entry.metadata,
54
- size: entry.size,
55
- integrity: entry.integrity
56
- }
57
- )
58
- .then((res) => {
59
- if (memoize && byDigest) {
60
- memo.put.byDigest(cache, key, res, opts)
61
- } else if (memoize) {
62
- memo.put(cache, entry, res.data, opts)
63
- }
64
- return res
65
- })
66
- }
67
- )
41
+ })
42
+ })
68
43
  }
44
+ module.exports = getData
69
45
 
70
- module.exports.sync = function get (cache, key, opts) {
71
- return getDataSync(false, cache, key, opts)
72
- }
73
- module.exports.sync.byDigest = function getByDigest (cache, digest, opts) {
74
- return getDataSync(true, cache, digest, opts)
46
+ function getDataByDigest (cache, key, opts = {}) {
47
+ const { integrity, memoize, size } = opts
48
+ const memoized = memo.get.byDigest(cache, key, opts)
49
+ if (memoized && memoize !== false)
50
+ return Promise.resolve(memoized)
51
+
52
+ return read(cache, key, { integrity, size }).then((res) => {
53
+ if (memoize)
54
+ memo.put.byDigest(cache, key, res, opts)
55
+ return res
56
+ })
75
57
  }
58
+ module.exports.byDigest = getDataByDigest
76
59
 
77
- function getDataSync (byDigest, cache, key, opts = {}) {
60
+ function getDataSync (cache, key, opts = {}) {
78
61
  const { integrity, memoize, size } = opts
79
- const memoized = byDigest
80
- ? memo.get.byDigest(cache, key, opts)
81
- : memo.get(cache, key, opts)
62
+ const memoized = memo.get(cache, key, opts)
63
+
82
64
  if (memoized && memoize !== false) {
83
- return byDigest
84
- ? memoized
85
- : {
86
- metadata: memoized.entry.metadata,
87
- data: memoized.data,
88
- integrity: memoized.entry.integrity,
89
- size: memoized.entry.size
90
- }
65
+ return {
66
+ metadata: memoized.entry.metadata,
67
+ data: memoized.data,
68
+ integrity: memoized.entry.integrity,
69
+ size: memoized.entry.size,
70
+ }
91
71
  }
92
- const entry = !byDigest && index.find.sync(cache, key, opts)
93
- if (!entry && !byDigest) {
72
+ const entry = index.find.sync(cache, key, opts)
73
+ if (!entry)
94
74
  throw new index.NotFoundError(cache, key)
95
- }
96
- const data = read.sync(cache, byDigest ? key : entry.integrity, {
75
+ const data = read.sync(cache, entry.integrity, {
97
76
  integrity: integrity,
98
- size: size
77
+ size: size,
99
78
  })
100
- const res = byDigest
101
- ? data
102
- : {
103
- metadata: entry.metadata,
104
- data: data,
105
- size: entry.size,
106
- integrity: entry.integrity
107
- }
108
- if (memoize && byDigest) {
109
- memo.put.byDigest(cache, key, res, opts)
110
- } else if (memoize) {
111
- memo.put(cache, entry, res.data, opts)
79
+ const res = {
80
+ metadata: entry.metadata,
81
+ data: data,
82
+ size: entry.size,
83
+ integrity: entry.integrity,
112
84
  }
85
+ if (memoize)
86
+ memo.put(cache, entry, res.data, opts)
87
+
113
88
  return res
114
89
  }
115
90
 
116
- module.exports.stream = getStream
91
+ module.exports.sync = getDataSync
92
+
93
+ function getDataByDigestSync (cache, digest, opts = {}) {
94
+ const { integrity, memoize, size } = opts
95
+ const memoized = memo.get.byDigest(cache, digest, opts)
96
+
97
+ if (memoized && memoize !== false)
98
+ return memoized
99
+
100
+ const res = read.sync(cache, digest, {
101
+ integrity: integrity,
102
+ size: size,
103
+ })
104
+ if (memoize)
105
+ memo.put.byDigest(cache, digest, res, opts)
106
+
107
+ return res
108
+ }
109
+ module.exports.sync.byDigest = getDataByDigestSync
117
110
 
118
111
  const getMemoizedStream = (memoized) => {
119
112
  const stream = new Minipass()
@@ -129,17 +122,16 @@ const getMemoizedStream = (memoized) => {
129
122
  function getStream (cache, key, opts = {}) {
130
123
  const { memoize, size } = opts
131
124
  const memoized = memo.get(cache, key, opts)
132
- if (memoized && memoize !== false) {
125
+ if (memoized && memoize !== false)
133
126
  return getMemoizedStream(memoized)
134
- }
135
127
 
136
128
  const stream = new Pipeline()
137
129
  index
138
130
  .find(cache, key)
139
131
  .then((entry) => {
140
- if (!entry) {
132
+ if (!entry)
141
133
  throw new index.NotFoundError(cache, key)
142
- }
134
+
143
135
  stream.emit('metadata', entry.metadata)
144
136
  stream.emit('integrity', entry.integrity)
145
137
  stream.emit('size', entry.size)
@@ -167,7 +159,7 @@ function getStream (cache, key, opts = {}) {
167
159
  return stream
168
160
  }
169
161
 
170
- module.exports.stream.byDigest = getStreamDigest
162
+ module.exports.stream = getStream
171
163
 
172
164
  function getStreamDigest (cache, integrity, opts = {}) {
173
165
  const { memoize } = opts
@@ -178,9 +170,9 @@ function getStreamDigest (cache, integrity, opts = {}) {
178
170
  return stream
179
171
  } else {
180
172
  const stream = read.readStream(cache, integrity, opts)
181
- if (!memoize) {
173
+ if (!memoize)
182
174
  return stream
183
- }
175
+
184
176
  const memoStream = new Collect.PassThrough()
185
177
  memoStream.on('collect', data => memo.put.byDigest(
186
178
  cache,
@@ -192,64 +184,54 @@ function getStreamDigest (cache, integrity, opts = {}) {
192
184
  }
193
185
  }
194
186
 
195
- module.exports.info = info
187
+ module.exports.stream.byDigest = getStreamDigest
196
188
 
197
189
  function info (cache, key, opts = {}) {
198
190
  const { memoize } = opts
199
191
  const memoized = memo.get(cache, key, opts)
200
- if (memoized && memoize !== false) {
192
+ if (memoized && memoize !== false)
201
193
  return Promise.resolve(memoized.entry)
202
- } else {
194
+ else
203
195
  return index.find(cache, key)
204
- }
205
- }
206
-
207
- module.exports.hasContent = read.hasContent
208
-
209
- function cp (cache, key, dest, opts) {
210
- return copy(false, cache, key, dest, opts)
211
196
  }
197
+ module.exports.info = info
212
198
 
213
- module.exports.copy = cp
214
-
215
- function cpDigest (cache, digest, dest, opts) {
216
- return copy(true, cache, digest, dest, opts)
217
- }
218
-
219
- module.exports.copy.byDigest = cpDigest
220
-
221
- function copy (byDigest, cache, key, dest, opts = {}) {
199
+ function copy (cache, key, dest, opts = {}) {
222
200
  if (read.copy) {
223
- return (byDigest
224
- ? Promise.resolve(null)
225
- : index.find(cache, key, opts)
226
- ).then((entry) => {
227
- if (!entry && !byDigest) {
201
+ return index.find(cache, key, opts).then((entry) => {
202
+ if (!entry)
228
203
  throw new index.NotFoundError(cache, key)
229
- }
230
- return read
231
- .copy(cache, byDigest ? key : entry.integrity, dest, opts)
204
+ return read.copy(cache, entry.integrity, dest, opts)
232
205
  .then(() => {
233
- return byDigest
234
- ? key
235
- : {
236
- metadata: entry.metadata,
237
- size: entry.size,
238
- integrity: entry.integrity
239
- }
206
+ return {
207
+ metadata: entry.metadata,
208
+ size: entry.size,
209
+ integrity: entry.integrity,
210
+ }
240
211
  })
241
212
  })
242
213
  }
243
214
 
244
- return getData(byDigest, cache, key, opts).then((res) => {
245
- return writeFile(dest, byDigest ? res : res.data).then(() => {
246
- return byDigest
247
- ? key
248
- : {
249
- metadata: res.metadata,
250
- size: res.size,
251
- integrity: res.integrity
252
- }
215
+ return getData(cache, key, opts).then((res) => {
216
+ return writeFile(dest, res.data).then(() => {
217
+ return {
218
+ metadata: res.metadata,
219
+ size: res.size,
220
+ integrity: res.integrity,
221
+ }
253
222
  })
254
223
  })
255
224
  }
225
+ module.exports.copy = copy
226
+
227
+ function copyByDigest (cache, key, dest, opts = {}) {
228
+ if (read.copy)
229
+ return read.copy(cache, key, dest, opts).then(() => key)
230
+
231
+ return getDataByDigest(cache, key, opts).then((res) => {
232
+ return writeFile(dest, res).then(() => key)
233
+ })
234
+ }
235
+ module.exports.copy.byDigest = copyByDigest
236
+
237
+ module.exports.hasContent = read.hasContent
package/index.js CHANGED
@@ -7,6 +7,11 @@ const rm = require('./rm.js')
7
7
  const verify = require('./verify.js')
8
8
  const { clearMemoized } = require('./lib/memoization.js')
9
9
  const tmp = require('./lib/util/tmp.js')
10
+ const index = require('./lib/entry-index.js')
11
+
12
+ module.exports.index = {}
13
+ module.exports.index.compact = index.compact
14
+ module.exports.index.insert = index.insert
10
15
 
11
16
  module.exports.ls = ls
12
17
  module.exports.ls.stream = ls.stream
@@ -20,17 +20,16 @@ function read (cache, integrity, opts = {}) {
20
20
  // get size
21
21
  return lstat(cpath).then(stat => ({ stat, cpath, sri }))
22
22
  }).then(({ stat, cpath, sri }) => {
23
- if (typeof size === 'number' && stat.size !== size) {
23
+ if (typeof size === 'number' && stat.size !== size)
24
24
  throw sizeError(size, stat.size)
25
- }
26
- if (stat.size > MAX_SINGLE_READ_SIZE) {
25
+
26
+ if (stat.size > MAX_SINGLE_READ_SIZE)
27
27
  return readPipeline(cpath, stat.size, sri, new Pipeline()).concat()
28
- }
29
28
 
30
29
  return readFile(cpath, null).then((data) => {
31
- if (!ssri.checkData(data, sri)) {
30
+ if (!ssri.checkData(data, sri))
32
31
  throw integrityError(sri, cpath)
33
- }
32
+
34
33
  return data
35
34
  })
36
35
  })
@@ -40,11 +39,11 @@ const readPipeline = (cpath, size, sri, stream) => {
40
39
  stream.push(
41
40
  new fsm.ReadStream(cpath, {
42
41
  size,
43
- readSize: MAX_SINGLE_READ_SIZE
42
+ readSize: MAX_SINGLE_READ_SIZE,
44
43
  }),
45
44
  ssri.integrityStream({
46
45
  integrity: sri,
47
- size
46
+ size,
48
47
  })
49
48
  )
50
49
  return stream
@@ -56,13 +55,11 @@ function readSync (cache, integrity, opts = {}) {
56
55
  const { size } = opts
57
56
  return withContentSriSync(cache, integrity, (cpath, sri) => {
58
57
  const data = fs.readFileSync(cpath)
59
- if (typeof size === 'number' && size !== data.length) {
58
+ if (typeof size === 'number' && size !== data.length)
60
59
  throw sizeError(size, data.length)
61
- }
62
60
 
63
- if (ssri.checkData(data, sri)) {
61
+ if (ssri.checkData(data, sri))
64
62
  return data
65
- }
66
63
 
67
64
  throw integrityError(sri, cpath)
68
65
  })
@@ -78,9 +75,9 @@ function readStream (cache, integrity, opts = {}) {
78
75
  // just lstat to ensure it exists
79
76
  return lstat(cpath).then((stat) => ({ stat, cpath, sri }))
80
77
  }).then(({ stat, cpath, sri }) => {
81
- if (typeof size === 'number' && size !== stat.size) {
78
+ if (typeof size === 'number' && size !== stat.size)
82
79
  return stream.emit('error', sizeError(size, stat.size))
83
- }
80
+
84
81
  readPipeline(cpath, stat.size, sri, stream)
85
82
  }, er => stream.emit('error', er))
86
83
 
@@ -109,22 +106,21 @@ function copySync (cache, integrity, dest) {
109
106
  module.exports.hasContent = hasContent
110
107
 
111
108
  function hasContent (cache, integrity) {
112
- if (!integrity) {
109
+ if (!integrity)
113
110
  return Promise.resolve(false)
114
- }
111
+
115
112
  return withContentSri(cache, integrity, (cpath, sri) => {
116
113
  return lstat(cpath).then((stat) => ({ size: stat.size, sri, stat }))
117
114
  }).catch((err) => {
118
- if (err.code === 'ENOENT') {
115
+ if (err.code === 'ENOENT')
119
116
  return false
120
- }
117
+
121
118
  if (err.code === 'EPERM') {
122
119
  /* istanbul ignore else */
123
- if (process.platform !== 'win32') {
120
+ if (process.platform !== 'win32')
124
121
  throw err
125
- } else {
122
+ else
126
123
  return false
127
- }
128
124
  }
129
125
  })
130
126
  }
@@ -132,24 +128,23 @@ function hasContent (cache, integrity) {
132
128
  module.exports.hasContent.sync = hasContentSync
133
129
 
134
130
  function hasContentSync (cache, integrity) {
135
- if (!integrity) {
131
+ if (!integrity)
136
132
  return false
137
- }
133
+
138
134
  return withContentSriSync(cache, integrity, (cpath, sri) => {
139
135
  try {
140
136
  const stat = fs.lstatSync(cpath)
141
137
  return { size: stat.size, sri, stat }
142
138
  } catch (err) {
143
- if (err.code === 'ENOENT') {
139
+ if (err.code === 'ENOENT')
144
140
  return false
145
- }
141
+
146
142
  if (err.code === 'EPERM') {
147
143
  /* istanbul ignore else */
148
- if (process.platform !== 'win32') {
144
+ if (process.platform !== 'win32')
149
145
  throw err
150
- } else {
146
+ else
151
147
  return false
152
- }
153
148
  }
154
149
  }
155
150
  })
@@ -167,7 +162,8 @@ function withContentSri (cache, integrity, fn) {
167
162
  const cpath = contentPath(cache, digests[0])
168
163
  return fn(cpath, digests[0])
169
164
  } else {
170
- // Can't use race here because a generic error can happen before a ENOENT error, and can happen before a valid result
165
+ // Can't use race here because a generic error can happen before
166
+ // a ENOENT error, and can happen before a valid result
171
167
  return Promise
172
168
  .all(digests.map((meta) => {
173
169
  return withContentSri(cache, meta, fn)
@@ -184,15 +180,13 @@ function withContentSri (cache, integrity, fn) {
184
180
  .then((results) => {
185
181
  // Return the first non error if it is found
186
182
  const result = results.find((r) => !(r instanceof Error))
187
- if (result) {
183
+ if (result)
188
184
  return result
189
- }
190
185
 
191
186
  // Throw the No matching content found error
192
187
  const enoentError = results.find((r) => r.code === 'ENOENT')
193
- if (enoentError) {
188
+ if (enoentError)
194
189
  throw enoentError
195
- }
196
190
 
197
191
  // Throw generic error
198
192
  throw results.find((r) => r instanceof Error)
package/lib/content/rm.js CHANGED
@@ -11,10 +11,9 @@ module.exports = rm
11
11
  function rm (cache, integrity) {
12
12
  return hasContent(cache, integrity).then((content) => {
13
13
  // ~pretty~ sure we can't end up with a content lacking sri, but be safe
14
- if (content && content.sri) {
14
+ if (content && content.sri)
15
15
  return rimraf(contentPath(cache, content.sri)).then(() => true)
16
- } else {
16
+ else
17
17
  return false
18
- }
19
18
  })
20
19
  }
@@ -22,16 +22,15 @@ module.exports = write
22
22
 
23
23
  function write (cache, data, opts = {}) {
24
24
  const { algorithms, size, integrity } = opts
25
- if (algorithms && algorithms.length > 1) {
25
+ if (algorithms && algorithms.length > 1)
26
26
  throw new Error('opts.algorithms only supports a single algorithm for now')
27
- }
28
- if (typeof size === 'number' && data.length !== size) {
27
+
28
+ if (typeof size === 'number' && data.length !== size)
29
29
  return Promise.reject(sizeError(size, data.length))
30
- }
30
+
31
31
  const sri = ssri.fromData(data, algorithms ? { algorithms } : {})
32
- if (integrity && !ssri.checkData(data, integrity, opts)) {
32
+ if (integrity && !ssri.checkData(data, integrity, opts))
33
33
  return Promise.reject(checksumError(integrity, sri))
34
- }
35
34
 
36
35
  return disposer(makeTmp(cache, opts), makeTmpDisposer,
37
36
  (tmp) => {
@@ -112,13 +111,17 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts) {
112
111
  const hashStream = ssri.integrityStream({
113
112
  integrity: opts.integrity,
114
113
  algorithms: opts.algorithms,
115
- size: opts.size
114
+ size: opts.size,
115
+ })
116
+ hashStream.on('integrity', i => {
117
+ integrity = i
118
+ })
119
+ hashStream.on('size', s => {
120
+ size = s
116
121
  })
117
- hashStream.on('integrity', i => { integrity = i })
118
- hashStream.on('size', s => { size = s })
119
122
 
120
123
  const outStream = new fsm.WriteStream(tmpTarget, {
121
- flags: 'wx'
124
+ flags: 'wx',
122
125
  })
123
126
 
124
127
  // NB: this can throw if the hashStream has a problem with
@@ -132,21 +135,23 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts) {
132
135
 
133
136
  return pipeline.promise()
134
137
  .then(() => ({ integrity, size }))
135
- .catch(er => rimraf(tmpTarget).then(() => { throw er }))
138
+ .catch(er => rimraf(tmpTarget).then(() => {
139
+ throw er
140
+ }))
136
141
  }
137
142
 
138
143
  function makeTmp (cache, opts) {
139
144
  const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
140
145
  return fixOwner.mkdirfix(cache, path.dirname(tmpTarget)).then(() => ({
141
146
  target: tmpTarget,
142
- moved: false
147
+ moved: false,
143
148
  }))
144
149
  }
145
150
 
146
151
  function makeTmpDisposer (tmp) {
147
- if (tmp.moved) {
152
+ if (tmp.moved)
148
153
  return Promise.resolve()
149
- }
154
+
150
155
  return rimraf(tmp.target)
151
156
  }
152
157