cacache 12.0.3 → 14.0.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/CHANGELOG.md +100 -1
- package/README.md +3 -29
- package/get.js +158 -139
- package/index.js +39 -1
- package/lib/content/path.js +7 -4
- package/lib/content/read.js +118 -55
- package/lib/content/rm.js +8 -9
- package/lib/content/write.js +120 -97
- package/lib/entry-index.js +135 -112
- package/lib/memoization.js +15 -10
- package/lib/util/disposer.js +30 -0
- package/lib/util/fix-owner.js +36 -19
- package/lib/util/hash-to-segments.js +1 -5
- package/lib/util/move-file.js +44 -27
- package/lib/util/tmp.js +8 -3
- package/lib/verify.js +162 -97
- package/ls.js +1 -1
- package/package.json +25 -23
- package/put.js +56 -48
- package/rm.js +5 -2
- package/README.es.md +0 -628
- package/en.js +0 -3
- package/es.js +0 -3
- package/lib/util/y.js +0 -25
- package/locales/en.js +0 -47
- package/locales/en.json +0 -7
- package/locales/es.js +0 -49
- package/locales/es.json +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,105 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [14.0.0](https://github.com/npm/cacache/compare/v13.0.1...v14.0.0) (2020-01-28)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* **deps:** bumps engines to >= 10
|
|
11
|
+
|
|
12
|
+
* **deps:** tar v6 and mkdirp v1 ([5a66e7a](https://github.com/npm/cacache/commit/5a66e7a))
|
|
13
|
+
|
|
14
|
+
### [13.0.1](https://github.com/npm/cacache/compare/v13.0.0...v13.0.1) (2019-09-30)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **fix-owner:** chownr.sync quits on non-root uid ([08801be](https://github.com/npm/cacache/commit/08801be))
|
|
20
|
+
|
|
21
|
+
## [13.0.0](https://github.com/npm/cacache/compare/v12.0.3...v13.0.0) (2019-09-25)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### ⚠ BREAKING CHANGES
|
|
25
|
+
|
|
26
|
+
* This subtly changes the streaming interface of
|
|
27
|
+
everything in cacache that streams, which is, well, everything in
|
|
28
|
+
cacache. Most users will probably not notice, but any code that
|
|
29
|
+
depended on stream behavior always being deferred until next tick will
|
|
30
|
+
need to adjust.
|
|
31
|
+
|
|
32
|
+
The mississippi methods 'to', 'from', 'through', and so on, have been
|
|
33
|
+
replaced with their Minipass counterparts, and streaming interaction
|
|
34
|
+
with the file system is done via fs-minipass.
|
|
35
|
+
|
|
36
|
+
The following modules are of interest here:
|
|
37
|
+
|
|
38
|
+
- [minipass](http://npm.im/minipass) The core stream library.
|
|
39
|
+
|
|
40
|
+
- [fs-minipass](http://npm.im/fs-minipass) Note that the 'WriteStream'
|
|
41
|
+
class from fs-minipass is _not_ a Minipass stream, but rather a plain
|
|
42
|
+
old EventEmitter that duck types as a Writable.
|
|
43
|
+
|
|
44
|
+
- [minipass-collect](http://npm.im/minipass-collect) Gather up all the
|
|
45
|
+
data from a stream. Cacache only uses Collect.PassThrough, which is a
|
|
46
|
+
basic Minipass passthrough stream which emits a 'collect' event with
|
|
47
|
+
the completed data just before the 'end' event.
|
|
48
|
+
|
|
49
|
+
- [minipass-pipeline](http://npm.im/minipass-pipeline) Connect one or
|
|
50
|
+
more streams into a pipe chain. Errors anywhere in the pipeline are
|
|
51
|
+
proxied down the chain and then up to the Pipeline object itself.
|
|
52
|
+
Writes go into the head, reads go to the tail. Used in place of
|
|
53
|
+
pump() and pumpify().
|
|
54
|
+
|
|
55
|
+
- [minipass-flush](http://npm.im/minipass-flush) A Minipass passthrough
|
|
56
|
+
stream that defers its 'end' event until after a flush() method has
|
|
57
|
+
completed (either calling the supplied callback, or returning a
|
|
58
|
+
promise.) Use in place of flush-write-stream (aka mississippi.to).
|
|
59
|
+
|
|
60
|
+
Streams from through2, concat-stream, and the behavior provided by
|
|
61
|
+
end-of-stream are all implemented in Minipass itself.
|
|
62
|
+
|
|
63
|
+
Features of interest to cacache, which make Minipass a particularly good
|
|
64
|
+
fit:
|
|
65
|
+
|
|
66
|
+
- All of the 'endish' events are normalized, so we can just listen on
|
|
67
|
+
'end' and know that finish, prefinish, and close will be handled as
|
|
68
|
+
well.
|
|
69
|
+
- Minipass doesn't waste time [containing
|
|
70
|
+
zalgo](https://blog.izs.me/2013/08/designing-apis-for-asynchrony).
|
|
71
|
+
- Minipass has built-in support for promises that indicate the end or
|
|
72
|
+
error: stream.promise(), stream.collect(), and stream.concat().
|
|
73
|
+
- With reliable and consistent timing guarantees, much less
|
|
74
|
+
error-checking logic is required. We can be more confident that an
|
|
75
|
+
error is being thrown or emitted in the correct place, rather than in
|
|
76
|
+
a callback which is deferred, resulting in a hung promise or
|
|
77
|
+
uncaughtException.
|
|
78
|
+
|
|
79
|
+
The biggest downside of Minipass is that it lacks some of the internal
|
|
80
|
+
characteristics of node-core streams, which many community modules use
|
|
81
|
+
to identify streams. They have no _writableState or _readableState
|
|
82
|
+
objects, or _read or _write methods. As a result, the is-stream module
|
|
83
|
+
(at least, at the time of this commit) doesn't recognize Minipass
|
|
84
|
+
streams as readable or writable streams.
|
|
85
|
+
|
|
86
|
+
All in all, the changes required of downstream users should be minimal,
|
|
87
|
+
but are unlikely to be zero. Hence the semver major change.
|
|
88
|
+
|
|
89
|
+
### Features
|
|
90
|
+
|
|
91
|
+
* replace all streams with Minipass streams ([f4c0962](https://github.com/npm/cacache/commit/f4c0962))
|
|
92
|
+
* **deps:** Add minipass and minipass-pipeline ([a6545a9](https://github.com/npm/cacache/commit/a6545a9))
|
|
93
|
+
* **promise:** converted .resolve to native promise, converted .map and .reduce to native ([220c56d](https://github.com/npm/cacache/commit/220c56d))
|
|
94
|
+
* **promise:** individually promisifing functions as needed ([74b939e](https://github.com/npm/cacache/commit/74b939e))
|
|
95
|
+
* **promise:** moved .reject from bluebird to native promise ([1d56da1](https://github.com/npm/cacache/commit/1d56da1))
|
|
96
|
+
* **promise:** removed .fromNode, removed .join ([9c457a0](https://github.com/npm/cacache/commit/9c457a0))
|
|
97
|
+
* **promise:** removed .map, replaced with p-map. removed .try ([cc3ee05](https://github.com/npm/cacache/commit/cc3ee05))
|
|
98
|
+
* **promise:** removed .tap ([0260f12](https://github.com/npm/cacache/commit/0260f12))
|
|
99
|
+
* **promise:** removed .using/.disposer ([5d832f3](https://github.com/npm/cacache/commit/5d832f3))
|
|
100
|
+
* **promise:** removed bluebird ([c21298c](https://github.com/npm/cacache/commit/c21298c))
|
|
101
|
+
* **promise:** removed bluebird specific .catch calls ([28aeeac](https://github.com/npm/cacache/commit/28aeeac))
|
|
102
|
+
* **promise:** replaced .reduce and .mapSeries ([478f5cb](https://github.com/npm/cacache/commit/478f5cb))
|
|
103
|
+
|
|
5
104
|
### [12.0.3](https://github.com/npm/cacache/compare/v12.0.2...v12.0.3) (2019-08-19)
|
|
6
105
|
|
|
7
106
|
|
|
@@ -65,7 +164,7 @@ chown everything to root.
|
|
|
65
164
|
The solution is for the user to create a folder, make it user-owned, and
|
|
66
165
|
use that, rather than relying on cacache to create the root cache folder.
|
|
67
166
|
|
|
68
|
-
If we decide to restore the uid/gid opts, and use ownership
|
|
167
|
+
If we decide to restore the uid/gid opts, and use ownership inference
|
|
69
168
|
only when uid/gid are unset, then take care to also make rm take an
|
|
70
169
|
option object, and pass it through to entry-index.js.
|
|
71
170
|
|
package/README.md
CHANGED
|
@@ -12,8 +12,6 @@ when running as `root`.
|
|
|
12
12
|
It was written to be used as [npm](https://npm.im)'s local cache, but can
|
|
13
13
|
just as easily be used on its own.
|
|
14
14
|
|
|
15
|
-
_Translations: [español](README.es.md)_
|
|
16
|
-
|
|
17
15
|
## Install
|
|
18
16
|
|
|
19
17
|
`$ npm install --save cacache`
|
|
@@ -40,7 +38,6 @@ _Translations: [español](README.es.md)_
|
|
|
40
38
|
* [`rm.entry`](#rm-entry)
|
|
41
39
|
* [`rm.content`](#rm-content)
|
|
42
40
|
* Utilities
|
|
43
|
-
* [`setLocale`](#set-locale)
|
|
44
41
|
* [`clearMemoized`](#clear-memoized)
|
|
45
42
|
* [`tmp.mkdir`](#tmp-mkdir)
|
|
46
43
|
* [`tmp.withTmp`](#with-tmp)
|
|
@@ -52,7 +49,7 @@ _Translations: [español](README.es.md)_
|
|
|
52
49
|
### Example
|
|
53
50
|
|
|
54
51
|
```javascript
|
|
55
|
-
const cacache = require('cacache
|
|
52
|
+
const cacache = require('cacache')
|
|
56
53
|
const fs = require('fs')
|
|
57
54
|
|
|
58
55
|
const tarball = '/path/to/mytar.tgz'
|
|
@@ -113,21 +110,6 @@ Happy hacking!
|
|
|
113
110
|
|
|
114
111
|
### API
|
|
115
112
|
|
|
116
|
-
#### <a name="localized-api"></a> Using localized APIs
|
|
117
|
-
|
|
118
|
-
cacache includes a complete API in English, with the same features as other
|
|
119
|
-
translations. To use the English API as documented in this README, use
|
|
120
|
-
`require('cacache/en')`. This is also currently the default if you do
|
|
121
|
-
`require('cacache')`, but may change in the future.
|
|
122
|
-
|
|
123
|
-
cacache also supports other languages! You can find the list of currently
|
|
124
|
-
supported ones by looking in `./locales` in the source directory. You can use
|
|
125
|
-
the API in that language with `require('cacache/<lang>')`.
|
|
126
|
-
|
|
127
|
-
Want to add support for a new language? Please go ahead! You should be able to
|
|
128
|
-
copy `./locales/en.js` and `./locales/en.json` and fill them in. Translating the
|
|
129
|
-
`README.md` is a bit more work, but also appreciated if you get around to it. 👍🏼
|
|
130
|
-
|
|
131
113
|
#### <a name="ls"></a> `> cacache.ls(cache) -> Promise<Object>`
|
|
132
114
|
|
|
133
115
|
Lists info for all entries currently in the cache as a single large object. Each
|
|
@@ -478,14 +460,6 @@ cacache.rm.content(cachePath, 'sha512-SoMeDIGest/IN+BaSE64==').then(() => {
|
|
|
478
460
|
})
|
|
479
461
|
```
|
|
480
462
|
|
|
481
|
-
#### <a name="set-locale"></a> `> cacache.setLocale(locale)`
|
|
482
|
-
|
|
483
|
-
Configure the language/locale used for messages and errors coming from cacache.
|
|
484
|
-
The list of available locales is in the `./locales` directory in the project
|
|
485
|
-
root.
|
|
486
|
-
|
|
487
|
-
_Interested in contributing more languages! [Submit a PR](CONTRIBUTING.md)!_
|
|
488
|
-
|
|
489
463
|
#### <a name="clear-memoized"></a> `> cacache.clearMemoized()`
|
|
490
464
|
|
|
491
465
|
Completely resets the in-memory entry cache.
|
|
@@ -537,8 +511,8 @@ cacache.tmp.mkdir(cache).then(dir => {
|
|
|
537
511
|
|
|
538
512
|
Creates a temporary directory with [`tmp.mkdir()`](#tmp-mkdir) and calls `cb`
|
|
539
513
|
with it. The created temporary directory will be removed when the return value
|
|
540
|
-
of `cb()` resolves
|
|
541
|
-
|
|
514
|
+
of `cb()` resolves, the tmp directory will be automatically deleted once that
|
|
515
|
+
promise completes.
|
|
542
516
|
|
|
543
517
|
The same caveats apply when it comes to managing permissions for the tmp dir's
|
|
544
518
|
contents.
|
package/get.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const util = require('util')
|
|
4
4
|
|
|
5
5
|
const figgyPudding = require('figgy-pudding')
|
|
6
6
|
const fs = require('fs')
|
|
7
7
|
const index = require('./lib/entry-index')
|
|
8
8
|
const memo = require('./lib/memoization')
|
|
9
|
-
const pipe = require('mississippi').pipe
|
|
10
|
-
const pipeline = require('mississippi').pipeline
|
|
11
9
|
const read = require('./lib/content/read')
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
const Minipass = require('minipass')
|
|
12
|
+
const Collect = require('minipass-collect')
|
|
13
|
+
const Pipeline = require('minipass-pipeline')
|
|
14
|
+
|
|
15
|
+
const writeFile = util.promisify(fs.writeFile)
|
|
13
16
|
|
|
14
17
|
const GetOpts = figgyPudding({
|
|
15
18
|
integrity: {},
|
|
@@ -23,44 +26,53 @@ module.exports = function get (cache, key, opts) {
|
|
|
23
26
|
module.exports.byDigest = function getByDigest (cache, digest, opts) {
|
|
24
27
|
return getData(true, cache, digest, opts)
|
|
25
28
|
}
|
|
29
|
+
|
|
26
30
|
function getData (byDigest, cache, key, opts) {
|
|
27
31
|
opts = GetOpts(opts)
|
|
28
|
-
const memoized =
|
|
29
|
-
byDigest
|
|
30
|
-
|
|
31
|
-
: memo.get(cache, key, opts)
|
|
32
|
-
)
|
|
32
|
+
const memoized = byDigest
|
|
33
|
+
? memo.get.byDigest(cache, key, opts)
|
|
34
|
+
: memo.get(cache, key, opts)
|
|
33
35
|
if (memoized && opts.memoize !== false) {
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
return Promise.resolve(
|
|
37
|
+
byDigest
|
|
38
|
+
? memoized
|
|
39
|
+
: {
|
|
40
|
+
metadata: memoized.entry.metadata,
|
|
41
|
+
data: memoized.data,
|
|
42
|
+
integrity: memoized.entry.integrity,
|
|
43
|
+
size: memoized.entry.size
|
|
44
|
+
}
|
|
45
|
+
)
|
|
40
46
|
}
|
|
41
|
-
return (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
throw new index.NotFoundError(cache, key)
|
|
46
|
-
}
|
|
47
|
-
return read(cache, byDigest ? key : entry.integrity, {
|
|
48
|
-
integrity: opts.integrity,
|
|
49
|
-
size: opts.size
|
|
50
|
-
}).then(data => byDigest ? data : {
|
|
51
|
-
metadata: entry.metadata,
|
|
52
|
-
data: data,
|
|
53
|
-
size: entry.size,
|
|
54
|
-
integrity: entry.integrity
|
|
55
|
-
}).then(res => {
|
|
56
|
-
if (opts.memoize && byDigest) {
|
|
57
|
-
memo.put.byDigest(cache, key, res, opts)
|
|
58
|
-
} else if (opts.memoize) {
|
|
59
|
-
memo.put(cache, entry, res.data, opts)
|
|
47
|
+
return (byDigest ? Promise.resolve(null) : index.find(cache, key, opts)).then(
|
|
48
|
+
(entry) => {
|
|
49
|
+
if (!entry && !byDigest) {
|
|
50
|
+
throw new index.NotFoundError(cache, key)
|
|
60
51
|
}
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
return read(cache, byDigest ? key : entry.integrity, {
|
|
53
|
+
integrity: opts.integrity,
|
|
54
|
+
size: opts.size
|
|
55
|
+
})
|
|
56
|
+
.then((data) =>
|
|
57
|
+
byDigest
|
|
58
|
+
? data
|
|
59
|
+
: {
|
|
60
|
+
metadata: entry.metadata,
|
|
61
|
+
data: data,
|
|
62
|
+
size: entry.size,
|
|
63
|
+
integrity: entry.integrity
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
.then((res) => {
|
|
67
|
+
if (opts.memoize && byDigest) {
|
|
68
|
+
memo.put.byDigest(cache, key, res, opts)
|
|
69
|
+
} else if (opts.memoize) {
|
|
70
|
+
memo.put(cache, entry, res.data, opts)
|
|
71
|
+
}
|
|
72
|
+
return res
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
)
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
module.exports.sync = function get (cache, key, opts) {
|
|
@@ -69,33 +81,30 @@ module.exports.sync = function get (cache, key, opts) {
|
|
|
69
81
|
module.exports.sync.byDigest = function getByDigest (cache, digest, opts) {
|
|
70
82
|
return getDataSync(true, cache, digest, opts)
|
|
71
83
|
}
|
|
84
|
+
|
|
72
85
|
function getDataSync (byDigest, cache, key, opts) {
|
|
73
86
|
opts = GetOpts(opts)
|
|
74
|
-
const memoized =
|
|
75
|
-
byDigest
|
|
76
|
-
|
|
77
|
-
: memo.get(cache, key, opts)
|
|
78
|
-
)
|
|
87
|
+
const memoized = byDigest
|
|
88
|
+
? memo.get.byDigest(cache, key, opts)
|
|
89
|
+
: memo.get(cache, key, opts)
|
|
79
90
|
if (memoized && opts.memoize !== false) {
|
|
80
|
-
return byDigest
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
return byDigest
|
|
92
|
+
? memoized
|
|
93
|
+
: {
|
|
94
|
+
metadata: memoized.entry.metadata,
|
|
95
|
+
data: memoized.data,
|
|
96
|
+
integrity: memoized.entry.integrity,
|
|
97
|
+
size: memoized.entry.size
|
|
98
|
+
}
|
|
86
99
|
}
|
|
87
100
|
const entry = !byDigest && index.find.sync(cache, key, opts)
|
|
88
101
|
if (!entry && !byDigest) {
|
|
89
102
|
throw new index.NotFoundError(cache, key)
|
|
90
103
|
}
|
|
91
|
-
const data = read.sync(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
integrity: opts.integrity,
|
|
96
|
-
size: opts.size
|
|
97
|
-
}
|
|
98
|
-
)
|
|
104
|
+
const data = read.sync(cache, byDigest ? key : entry.integrity, {
|
|
105
|
+
integrity: opts.integrity,
|
|
106
|
+
size: opts.size
|
|
107
|
+
})
|
|
99
108
|
const res = byDigest
|
|
100
109
|
? data
|
|
101
110
|
: {
|
|
@@ -113,97 +122,93 @@ function getDataSync (byDigest, cache, key, opts) {
|
|
|
113
122
|
}
|
|
114
123
|
|
|
115
124
|
module.exports.stream = getStream
|
|
125
|
+
|
|
126
|
+
const getMemoizedStream = (memoized) => {
|
|
127
|
+
const stream = new Minipass()
|
|
128
|
+
stream.on('newListener', function (ev, cb) {
|
|
129
|
+
ev === 'metadata' && cb(memoized.entry.metadata)
|
|
130
|
+
ev === 'integrity' && cb(memoized.entry.integrity)
|
|
131
|
+
ev === 'size' && cb(memoized.entry.size)
|
|
132
|
+
})
|
|
133
|
+
stream.end(memoized.data)
|
|
134
|
+
return stream
|
|
135
|
+
}
|
|
136
|
+
|
|
116
137
|
function getStream (cache, key, opts) {
|
|
117
138
|
opts = GetOpts(opts)
|
|
118
|
-
let stream = through()
|
|
119
139
|
const memoized = memo.get(cache, key, opts)
|
|
120
140
|
if (memoized && opts.memoize !== false) {
|
|
121
|
-
|
|
122
|
-
ev === 'metadata' && cb(memoized.entry.metadata)
|
|
123
|
-
ev === 'integrity' && cb(memoized.entry.integrity)
|
|
124
|
-
ev === 'size' && cb(memoized.entry.size)
|
|
125
|
-
})
|
|
126
|
-
stream.write(memoized.data, () => stream.end())
|
|
127
|
-
return stream
|
|
141
|
+
return getMemoizedStream(memoized)
|
|
128
142
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
cb(
|
|
143
|
-
|
|
144
|
-
memoData && memo.put(cache, entry, Buffer.concat(memoData, memoLength), opts)
|
|
145
|
-
cb()
|
|
143
|
+
|
|
144
|
+
const stream = new Pipeline()
|
|
145
|
+
index
|
|
146
|
+
.find(cache, key)
|
|
147
|
+
.then((entry) => {
|
|
148
|
+
if (!entry) {
|
|
149
|
+
throw new index.NotFoundError(cache, key)
|
|
150
|
+
}
|
|
151
|
+
stream.emit('metadata', entry.metadata)
|
|
152
|
+
stream.emit('integrity', entry.integrity)
|
|
153
|
+
stream.emit('size', entry.size)
|
|
154
|
+
stream.on('newListener', function (ev, cb) {
|
|
155
|
+
ev === 'metadata' && cb(entry.metadata)
|
|
156
|
+
ev === 'integrity' && cb(entry.integrity)
|
|
157
|
+
ev === 'size' && cb(entry.size)
|
|
146
158
|
})
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
|
|
160
|
+
const src = read.readStream(
|
|
161
|
+
cache,
|
|
162
|
+
entry.integrity,
|
|
163
|
+
opts.concat({
|
|
164
|
+
size: opts.size == null ? entry.size : opts.size
|
|
165
|
+
})
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
if (opts.memoize) {
|
|
169
|
+
const memoStream = new Collect.PassThrough()
|
|
170
|
+
memoStream.on('collect', data => memo.put(cache, entry, data, opts))
|
|
171
|
+
stream.unshift(memoStream)
|
|
172
|
+
}
|
|
173
|
+
stream.unshift(src)
|
|
157
174
|
})
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
size: opts.size == null ? entry.size : opts.size
|
|
161
|
-
})),
|
|
162
|
-
memoStream,
|
|
163
|
-
stream
|
|
164
|
-
)
|
|
165
|
-
}).catch(err => stream.emit('error', err))
|
|
175
|
+
.catch((err) => stream.emit('error', err))
|
|
176
|
+
|
|
166
177
|
return stream
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
module.exports.stream.byDigest = getStreamDigest
|
|
181
|
+
|
|
170
182
|
function getStreamDigest (cache, integrity, opts) {
|
|
171
183
|
opts = GetOpts(opts)
|
|
172
184
|
const memoized = memo.get.byDigest(cache, integrity, opts)
|
|
173
185
|
if (memoized && opts.memoize !== false) {
|
|
174
|
-
const stream =
|
|
175
|
-
stream.
|
|
186
|
+
const stream = new Minipass()
|
|
187
|
+
stream.end(memoized)
|
|
176
188
|
return stream
|
|
177
189
|
} else {
|
|
178
|
-
|
|
179
|
-
if (opts.memoize) {
|
|
180
|
-
|
|
181
|
-
let memoLength = 0
|
|
182
|
-
const memoStream = through((c, en, cb) => {
|
|
183
|
-
memoData && memoData.push(c)
|
|
184
|
-
memoLength += c.length
|
|
185
|
-
cb(null, c, en)
|
|
186
|
-
}, cb => {
|
|
187
|
-
memoData && memo.put.byDigest(
|
|
188
|
-
cache,
|
|
189
|
-
integrity,
|
|
190
|
-
Buffer.concat(memoData, memoLength),
|
|
191
|
-
opts
|
|
192
|
-
)
|
|
193
|
-
cb()
|
|
194
|
-
})
|
|
195
|
-
stream = pipeline(stream, memoStream)
|
|
190
|
+
const stream = read.readStream(cache, integrity, opts)
|
|
191
|
+
if (!opts.memoize) {
|
|
192
|
+
return stream
|
|
196
193
|
}
|
|
197
|
-
|
|
194
|
+
const memoStream = new Collect.PassThrough()
|
|
195
|
+
memoStream.on('collect', data => memo.put.byDigest(
|
|
196
|
+
cache,
|
|
197
|
+
integrity,
|
|
198
|
+
data,
|
|
199
|
+
opts
|
|
200
|
+
))
|
|
201
|
+
return new Pipeline(stream, memoStream)
|
|
198
202
|
}
|
|
199
203
|
}
|
|
200
204
|
|
|
201
205
|
module.exports.info = info
|
|
206
|
+
|
|
202
207
|
function info (cache, key, opts) {
|
|
203
208
|
opts = GetOpts(opts)
|
|
204
209
|
const memoized = memo.get(cache, key, opts)
|
|
205
210
|
if (memoized && opts.memoize !== false) {
|
|
206
|
-
return
|
|
211
|
+
return Promise.resolve(memoized.entry)
|
|
207
212
|
} else {
|
|
208
213
|
return index.find(cache, key)
|
|
209
214
|
}
|
|
@@ -211,37 +216,51 @@ function info (cache, key, opts) {
|
|
|
211
216
|
|
|
212
217
|
module.exports.hasContent = read.hasContent
|
|
213
218
|
|
|
214
|
-
|
|
219
|
+
function cp (cache, key, dest, opts) {
|
|
215
220
|
return copy(false, cache, key, dest, opts)
|
|
216
221
|
}
|
|
217
|
-
|
|
222
|
+
|
|
223
|
+
module.exports.copy = cp
|
|
224
|
+
|
|
225
|
+
function cpDigest (cache, digest, dest, opts) {
|
|
218
226
|
return copy(true, cache, digest, dest, opts)
|
|
219
227
|
}
|
|
228
|
+
|
|
229
|
+
module.exports.copy.byDigest = cpDigest
|
|
230
|
+
|
|
220
231
|
function copy (byDigest, cache, key, dest, opts) {
|
|
221
232
|
opts = GetOpts(opts)
|
|
222
233
|
if (read.copy) {
|
|
223
|
-
return (
|
|
224
|
-
|
|
225
|
-
|
|
234
|
+
return (byDigest
|
|
235
|
+
? Promise.resolve(null)
|
|
236
|
+
: index.find(cache, key, opts)
|
|
237
|
+
).then((entry) => {
|
|
226
238
|
if (!entry && !byDigest) {
|
|
227
239
|
throw new index.NotFoundError(cache, key)
|
|
228
240
|
}
|
|
229
|
-
return read
|
|
230
|
-
cache, byDigest ? key : entry.integrity, dest, opts
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
241
|
+
return read
|
|
242
|
+
.copy(cache, byDigest ? key : entry.integrity, dest, opts)
|
|
243
|
+
.then(() => {
|
|
244
|
+
return byDigest
|
|
245
|
+
? key
|
|
246
|
+
: {
|
|
247
|
+
metadata: entry.metadata,
|
|
248
|
+
size: entry.size,
|
|
249
|
+
integrity: entry.integrity
|
|
250
|
+
}
|
|
251
|
+
})
|
|
236
252
|
})
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return getData(byDigest, cache, key, opts).then((res) => {
|
|
256
|
+
return writeFile(dest, byDigest ? res : res.data).then(() => {
|
|
257
|
+
return byDigest
|
|
258
|
+
? key
|
|
259
|
+
: {
|
|
241
260
|
metadata: res.metadata,
|
|
242
261
|
size: res.size,
|
|
243
262
|
integrity: res.integrity
|
|
244
|
-
}
|
|
263
|
+
}
|
|
245
264
|
})
|
|
246
|
-
}
|
|
265
|
+
})
|
|
247
266
|
}
|
package/index.js
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const ls = require('./ls.js')
|
|
4
|
+
const get = require('./get.js')
|
|
5
|
+
const put = require('./put.js')
|
|
6
|
+
const rm = require('./rm.js')
|
|
7
|
+
const verify = require('./verify.js')
|
|
8
|
+
const { clearMemoized } = require('./lib/memoization.js')
|
|
9
|
+
const tmp = require('./lib/util/tmp.js')
|
|
10
|
+
|
|
11
|
+
module.exports.ls = ls
|
|
12
|
+
module.exports.ls.stream = ls.stream
|
|
13
|
+
|
|
14
|
+
module.exports.get = get
|
|
15
|
+
module.exports.get.byDigest = get.byDigest
|
|
16
|
+
module.exports.get.sync = get.sync
|
|
17
|
+
module.exports.get.sync.byDigest = get.sync.byDigest
|
|
18
|
+
module.exports.get.stream = get.stream
|
|
19
|
+
module.exports.get.stream.byDigest = get.stream.byDigest
|
|
20
|
+
module.exports.get.copy = get.copy
|
|
21
|
+
module.exports.get.copy.byDigest = get.copy.byDigest
|
|
22
|
+
module.exports.get.info = get.info
|
|
23
|
+
module.exports.get.hasContent = get.hasContent
|
|
24
|
+
module.exports.get.hasContent.sync = get.hasContent.sync
|
|
25
|
+
|
|
26
|
+
module.exports.put = put
|
|
27
|
+
module.exports.put.stream = put.stream
|
|
28
|
+
|
|
29
|
+
module.exports.rm = rm.entry
|
|
30
|
+
module.exports.rm.all = rm.all
|
|
31
|
+
module.exports.rm.entry = module.exports.rm
|
|
32
|
+
module.exports.rm.content = rm.content
|
|
33
|
+
|
|
34
|
+
module.exports.clearMemoized = clearMemoized
|
|
35
|
+
|
|
36
|
+
module.exports.tmp = {}
|
|
37
|
+
module.exports.tmp.mkdir = tmp.mkdir
|
|
38
|
+
module.exports.tmp.withTmp = tmp.withTmp
|
|
39
|
+
|
|
40
|
+
module.exports.verify = verify
|
|
41
|
+
module.exports.verify.lastRun = verify.lastRun
|
package/lib/content/path.js
CHANGED
|
@@ -11,16 +11,19 @@ const ssri = require('ssri')
|
|
|
11
11
|
// ~/.my-cache/content-v2/sha512/ba/da/55deadbeefc0ffee
|
|
12
12
|
//
|
|
13
13
|
module.exports = contentPath
|
|
14
|
+
|
|
14
15
|
function contentPath (cache, integrity) {
|
|
15
16
|
const sri = ssri.parse(integrity, { single: true })
|
|
16
17
|
// contentPath is the *strongest* algo given
|
|
17
|
-
return path.join
|
|
18
|
+
return path.join(
|
|
18
19
|
contentDir(cache),
|
|
19
|
-
sri.algorithm
|
|
20
|
-
|
|
20
|
+
sri.algorithm,
|
|
21
|
+
...hashToSegments(sri.hexDigest())
|
|
22
|
+
)
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
module.exports.
|
|
25
|
+
module.exports.contentDir = contentDir
|
|
26
|
+
|
|
24
27
|
function contentDir (cache) {
|
|
25
28
|
return path.join(cache, `content-v${contentVer}`)
|
|
26
29
|
}
|