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 +35 -1
- package/get.js +121 -139
- package/index.js +5 -0
- package/lib/content/read.js +27 -33
- package/lib/content/rm.js +2 -3
- package/lib/content/write.js +19 -14
- package/lib/entry-index.js +127 -38
- package/lib/memoization.js +5 -6
- package/lib/util/disposer.js +2 -2
- package/lib/util/fix-owner.js +9 -12
- package/lib/util/move-file.js +3 -5
- package/lib/util/tmp.js +9 -9
- package/lib/verify.js +17 -17
- package/package.json +14 -29
- package/put.js +9 -10
- package/rm.js +2 -2
- package/CHANGELOG.md +0 -794
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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 (
|
|
60
|
+
function getDataSync (cache, key, opts = {}) {
|
|
78
61
|
const { integrity, memoize, size } = opts
|
|
79
|
-
const memoized =
|
|
80
|
-
|
|
81
|
-
: memo.get(cache, key, opts)
|
|
62
|
+
const memoized = memo.get(cache, key, opts)
|
|
63
|
+
|
|
82
64
|
if (memoized && memoize !== false) {
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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 =
|
|
93
|
-
if (!entry
|
|
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 =
|
|
101
|
-
|
|
102
|
-
:
|
|
103
|
-
|
|
104
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
224
|
-
|
|
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
|
|
234
|
-
|
|
235
|
-
:
|
|
236
|
-
|
|
237
|
-
|
|
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(
|
|
245
|
-
return writeFile(dest,
|
|
246
|
-
return
|
|
247
|
-
|
|
248
|
-
:
|
|
249
|
-
|
|
250
|
-
|
|
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
|
package/lib/content/read.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16
|
+
else
|
|
17
17
|
return false
|
|
18
|
-
}
|
|
19
18
|
})
|
|
20
19
|
}
|
package/lib/content/write.js
CHANGED
|
@@ -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(() => {
|
|
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
|
|