cacache 11.0.3 → 11.3.1

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 CHANGED
@@ -2,6 +2,46 @@
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
+ <a name="11.3.1"></a>
6
+ ## [11.3.1](https://github.com/zkat/cacache/compare/v11.3.0...v11.3.1) (2018-11-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **get:** export hasContent.sync properly ([d76c920](https://github.com/zkat/cacache/commit/d76c920))
12
+
13
+
14
+
15
+ <a name="11.3.0"></a>
16
+ # [11.3.0](https://github.com/zkat/cacache/compare/v11.2.0...v11.3.0) (2018-11-05)
17
+
18
+
19
+ ### Features
20
+
21
+ * **get:** add sync API for reading ([db1e094](https://github.com/zkat/cacache/commit/db1e094))
22
+
23
+
24
+
25
+ <a name="11.2.0"></a>
26
+ # [11.2.0](https://github.com/zkat/cacache/compare/v11.1.0...v11.2.0) (2018-08-08)
27
+
28
+
29
+ ### Features
30
+
31
+ * **read:** add sync support to other internal read.js fns ([fe638b6](https://github.com/zkat/cacache/commit/fe638b6))
32
+
33
+
34
+
35
+ <a name="11.1.0"></a>
36
+ # [11.1.0](https://github.com/zkat/cacache/compare/v11.0.3...v11.1.0) (2018-08-01)
37
+
38
+
39
+ ### Features
40
+
41
+ * **read:** add sync support for low-level content read ([b43af83](https://github.com/zkat/cacache/commit/b43af83))
42
+
43
+
44
+
5
45
  <a name="11.0.3"></a>
6
46
  ## [11.0.3](https://github.com/zkat/cacache/compare/v11.0.2...v11.0.3) (2018-08-01)
7
47
 
package/get.js CHANGED
@@ -63,6 +63,55 @@ function getData (byDigest, cache, key, opts) {
63
63
  })
64
64
  }
65
65
 
66
+ module.exports.sync = function get (cache, key, opts) {
67
+ return getDataSync(false, cache, key, opts)
68
+ }
69
+ module.exports.sync.byDigest = function getByDigest (cache, digest, opts) {
70
+ return getDataSync(true, cache, digest, opts)
71
+ }
72
+ function getDataSync (byDigest, cache, key, opts) {
73
+ opts = GetOpts(opts)
74
+ const memoized = (
75
+ byDigest
76
+ ? memo.get.byDigest(cache, key, opts)
77
+ : memo.get(cache, key, opts)
78
+ )
79
+ if (memoized && opts.memoize !== false) {
80
+ return byDigest ? memoized : {
81
+ metadata: memoized.entry.metadata,
82
+ data: memoized.data,
83
+ integrity: memoized.entry.integrity,
84
+ size: memoized.entry.size
85
+ }
86
+ }
87
+ const entry = !byDigest && index.find.sync(cache, key, opts)
88
+ if (!entry && !byDigest) {
89
+ throw new index.NotFoundError(cache, key)
90
+ }
91
+ const data = read.sync(
92
+ cache,
93
+ byDigest ? key : entry.integrity,
94
+ {
95
+ integrity: opts.integrity,
96
+ size: opts.size
97
+ }
98
+ )
99
+ const res = byDigest
100
+ ? data
101
+ : {
102
+ metadata: entry.metadata,
103
+ data: data,
104
+ size: entry.size,
105
+ integrity: entry.integrity
106
+ }
107
+ if (opts.memoize && byDigest) {
108
+ memo.put.byDigest(cache, key, res, opts)
109
+ } else if (opts.memoize) {
110
+ memo.put(cache, entry, res.data, opts)
111
+ }
112
+ return res
113
+ }
114
+
66
115
  module.exports.stream = getStream
67
116
  function getStream (cache, key, opts) {
68
117
  opts = GetOpts(opts)
@@ -33,6 +33,21 @@ function read (cache, integrity, opts) {
33
33
  })
34
34
  }
35
35
 
36
+ module.exports.sync = readSync
37
+ function readSync (cache, integrity, opts) {
38
+ opts = ReadOpts(opts)
39
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
40
+ const data = fs.readFileSync(cpath)
41
+ if (typeof opts.size === 'number' && opts.size !== data.length) {
42
+ throw sizeError(opts.size, data.length)
43
+ } else if (ssri.checkData(data, sri)) {
44
+ return data
45
+ } else {
46
+ throw integrityError(sri, cpath)
47
+ }
48
+ })
49
+ }
50
+
36
51
  module.exports.stream = readStream
37
52
  module.exports.readStream = readStream
38
53
  function readStream (cache, integrity, opts) {
@@ -58,8 +73,10 @@ function readStream (cache, integrity, opts) {
58
73
  let copyFileAsync
59
74
  if (fs.copyFile) {
60
75
  module.exports.copy = copy
76
+ module.exports.copy.sync = copySync
61
77
  copyFileAsync = BB.promisify(fs.copyFile)
62
78
  }
79
+
63
80
  function copy (cache, integrity, dest, opts) {
64
81
  opts = ReadOpts(opts)
65
82
  return withContentSri(cache, integrity, (cpath, sri) => {
@@ -67,11 +84,18 @@ function copy (cache, integrity, dest, opts) {
67
84
  })
68
85
  }
69
86
 
87
+ function copySync (cache, integrity, dest, opts) {
88
+ opts = ReadOpts(opts)
89
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
90
+ return fs.copyFileSync(cpath, dest)
91
+ })
92
+ }
93
+
70
94
  module.exports.hasContent = hasContent
71
95
  function hasContent (cache, integrity) {
72
96
  if (!integrity) { return BB.resolve(false) }
73
97
  return withContentSri(cache, integrity, (cpath, sri) => {
74
- return lstatAsync(cpath).then(stat => ({size: stat.size, sri}))
98
+ return lstatAsync(cpath).then(stat => ({size: stat.size, sri, stat}))
75
99
  }).catch(err => {
76
100
  if (err.code === 'ENOENT') { return false }
77
101
  if (err.code === 'EPERM') {
@@ -84,6 +108,26 @@ function hasContent (cache, integrity) {
84
108
  })
85
109
  }
86
110
 
111
+ module.exports.hasContent.sync = hasContentSync
112
+ function hasContentSync (cache, integrity) {
113
+ if (!integrity) { return false }
114
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
115
+ try {
116
+ const stat = fs.lstatSync(cpath)
117
+ return {size: stat.size, sri, stat}
118
+ } catch (err) {
119
+ if (err.code === 'ENOENT') { return false }
120
+ if (err.code === 'EPERM') {
121
+ if (process.platform !== 'win32') {
122
+ throw err
123
+ } else {
124
+ return false
125
+ }
126
+ }
127
+ }
128
+ })
129
+ }
130
+
87
131
  function withContentSri (cache, integrity, fn) {
88
132
  return BB.try(() => {
89
133
  const sri = ssri.parse(integrity)
@@ -112,6 +156,28 @@ function withContentSri (cache, integrity, fn) {
112
156
  })
113
157
  }
114
158
 
159
+ function withContentSriSync (cache, integrity, fn) {
160
+ const sri = ssri.parse(integrity)
161
+ // If `integrity` has multiple entries, pick the first digest
162
+ // with available local data.
163
+ const algo = sri.pickAlgorithm()
164
+ const digests = sri[algo]
165
+ if (digests.length <= 1) {
166
+ const cpath = contentPath(cache, digests[0])
167
+ return fn(cpath, digests[0])
168
+ } else {
169
+ let lastErr = null
170
+ for (const meta of sri[sri.pickAlgorithm()]) {
171
+ try {
172
+ return withContentSriSync(cache, meta, fn)
173
+ } catch (err) {
174
+ lastErr = err
175
+ }
176
+ }
177
+ if (lastErr) { throw lastErr }
178
+ }
179
+ }
180
+
115
181
  function sizeError (expected, found) {
116
182
  var err = new Error(Y`Bad data size: expected inserted data to be ${expected} bytes, but got ${found} instead`)
117
183
  err.expected = expected
@@ -75,10 +75,36 @@ function insert (cache, key, integrity, opts) {
75
75
  })
76
76
  }
77
77
 
78
+ module.exports.insert.sync = insertSync
79
+ function insertSync (cache, key, integrity, opts) {
80
+ opts = IndexOpts(opts)
81
+ const bucket = bucketPath(cache, key)
82
+ const entry = {
83
+ key,
84
+ integrity: integrity && ssri.stringify(integrity),
85
+ time: Date.now(),
86
+ size: opts.size,
87
+ metadata: opts.metadata
88
+ }
89
+ fixOwner.mkdirfix.sync(path.dirname(bucket), opts.uid, opts.gid)
90
+ const stringified = JSON.stringify(entry)
91
+ fs.appendFileSync(
92
+ bucket, `\n${hashEntry(stringified)}\t${stringified}`
93
+ )
94
+ try {
95
+ fixOwner.chownr.sync(bucket, opts.uid, opts.gid)
96
+ } catch (err) {
97
+ if (err.code !== 'ENOENT') {
98
+ throw err
99
+ }
100
+ }
101
+ return formatEntry(cache, entry)
102
+ }
103
+
78
104
  module.exports.find = find
79
105
  function find (cache, key) {
80
106
  const bucket = bucketPath(cache, key)
81
- return bucketEntries(cache, bucket).then(entries => {
107
+ return bucketEntries(bucket).then(entries => {
82
108
  return entries.reduce((latest, next) => {
83
109
  if (next && next.key === key) {
84
110
  return formatEntry(cache, next)
@@ -95,11 +121,36 @@ function find (cache, key) {
95
121
  })
96
122
  }
97
123
 
124
+ module.exports.find.sync = findSync
125
+ function findSync (cache, key) {
126
+ const bucket = bucketPath(cache, key)
127
+ try {
128
+ return bucketEntriesSync(bucket).reduce((latest, next) => {
129
+ if (next && next.key === key) {
130
+ return formatEntry(cache, next)
131
+ } else {
132
+ return latest
133
+ }
134
+ }, null)
135
+ } catch (err) {
136
+ if (err.code === 'ENOENT') {
137
+ return null
138
+ } else {
139
+ throw err
140
+ }
141
+ }
142
+ }
143
+
98
144
  module.exports.delete = del
99
145
  function del (cache, key, opts) {
100
146
  return insert(cache, key, null, opts)
101
147
  }
102
148
 
149
+ module.exports.delete.sync = delSync
150
+ function delSync (cache, key, opts) {
151
+ return insertSync(cache, key, null, opts)
152
+ }
153
+
103
154
  module.exports.lsStream = lsStream
104
155
  function lsStream (cache) {
105
156
  const indexDir = bucketDir(cache)
@@ -116,7 +167,6 @@ function lsStream (cache) {
116
167
  // "/cachename/<bucket 0xFF>/<bucket 0xFF>/*"
117
168
  return readdirOrEmpty(subbucketPath).map(entry => {
118
169
  const getKeyToEntry = bucketEntries(
119
- cache,
120
170
  path.join(subbucketPath, entry)
121
171
  ).reduce((acc, entry) => {
122
172
  acc.set(entry.key, entry)
@@ -152,32 +202,39 @@ function ls (cache) {
152
202
  })
153
203
  }
154
204
 
155
- function bucketEntries (cache, bucket, filter) {
205
+ function bucketEntries (bucket, filter) {
156
206
  return readFileAsync(
157
207
  bucket, 'utf8'
158
- ).then(data => {
159
- let entries = []
160
- data.split('\n').forEach(entry => {
161
- if (!entry) { return }
162
- const pieces = entry.split('\t')
163
- if (!pieces[1] || hashEntry(pieces[1]) !== pieces[0]) {
164
- // Hash is no good! Corruption or malice? Doesn't matter!
165
- // EJECT EJECT
166
- return
167
- }
168
- let obj
169
- try {
170
- obj = JSON.parse(pieces[1])
171
- } catch (e) {
172
- // Entry is corrupted!
173
- return
174
- }
175
- if (obj) {
176
- entries.push(obj)
177
- }
178
- })
179
- return entries
208
+ ).then(data => _bucketEntries(data, filter))
209
+ }
210
+
211
+ function bucketEntriesSync (bucket, filter) {
212
+ const data = fs.readFileSync(bucket, 'utf8')
213
+ return _bucketEntries(data, filter)
214
+ }
215
+
216
+ function _bucketEntries (data, filter) {
217
+ let entries = []
218
+ data.split('\n').forEach(entry => {
219
+ if (!entry) { return }
220
+ const pieces = entry.split('\t')
221
+ if (!pieces[1] || hashEntry(pieces[1]) !== pieces[0]) {
222
+ // Hash is no good! Corruption or malice? Doesn't matter!
223
+ // EJECT EJECT
224
+ return
225
+ }
226
+ let obj
227
+ try {
228
+ obj = JSON.parse(pieces[1])
229
+ } catch (e) {
230
+ // Entry is corrupted!
231
+ return
232
+ }
233
+ if (obj) {
234
+ entries.push(obj)
235
+ }
180
236
  })
237
+ return entries
181
238
  }
182
239
 
183
240
  module.exports._bucketDir = bucketDir
@@ -31,6 +31,34 @@ function fixOwner (filepath, uid, gid) {
31
31
  )
32
32
  }
33
33
 
34
+ module.exports.chownr.sync = fixOwnerSync
35
+ function fixOwnerSync (filepath, uid, gid) {
36
+ if (!process.getuid) {
37
+ // This platform doesn't need ownership fixing
38
+ return
39
+ }
40
+ if (typeof uid !== 'number' && typeof gid !== 'number') {
41
+ // There's no permissions override. Nothing to do here.
42
+ return
43
+ }
44
+ if ((typeof uid === 'number' && process.getuid() === uid) &&
45
+ (typeof gid === 'number' && process.getgid() === gid)) {
46
+ // No need to override if it's already what we used.
47
+ return
48
+ }
49
+ try {
50
+ chownr.sync(
51
+ filepath,
52
+ typeof uid === 'number' ? uid : process.getuid(),
53
+ typeof gid === 'number' ? gid : process.getgid()
54
+ )
55
+ } catch (err) {
56
+ if (err.code === 'ENOENT') {
57
+ return null
58
+ }
59
+ }
60
+ }
61
+
34
62
  module.exports.mkdirfix = mkdirfix
35
63
  function mkdirfix (p, uid, gid, cb) {
36
64
  return mkdirp(p).then(made => {
@@ -42,3 +70,21 @@ function mkdirfix (p, uid, gid, cb) {
42
70
  return fixOwner(p, uid, gid).then(() => null)
43
71
  })
44
72
  }
73
+
74
+ module.exports.mkdirfix.sync = mkdirfixSync
75
+ function mkdirfixSync (p, uid, gid) {
76
+ try {
77
+ const made = mkdirp.sync(p)
78
+ if (made) {
79
+ fixOwnerSync(made, uid, gid)
80
+ return made
81
+ }
82
+ } catch (err) {
83
+ if (err.code === 'EEXIST') {
84
+ fixOwnerSync(p, uid, gid)
85
+ return null
86
+ } else {
87
+ throw err
88
+ }
89
+ }
90
+ }
package/locales/en.js CHANGED
@@ -18,12 +18,15 @@ x.ls.stream = cache => ls.stream(cache)
18
18
 
19
19
  x.get = (cache, key, opts) => get(cache, key, opts)
20
20
  x.get.byDigest = (cache, hash, opts) => get.byDigest(cache, hash, opts)
21
+ x.get.sync = (cache, key, opts) => get.sync(cache, key, opts)
22
+ x.get.sync.byDigest = (cache, key, opts) => get.sync.byDigest(cache, key, opts)
21
23
  x.get.stream = (cache, key, opts) => get.stream(cache, key, opts)
22
24
  x.get.stream.byDigest = (cache, hash, opts) => get.stream.byDigest(cache, hash, opts)
23
25
  x.get.copy = (cache, key, dest, opts) => get.copy(cache, key, dest, opts)
24
26
  x.get.copy.byDigest = (cache, hash, dest, opts) => get.copy.byDigest(cache, hash, dest, opts)
25
27
  x.get.info = (cache, key) => get.info(cache, key)
26
28
  x.get.hasContent = (cache, hash) => get.hasContent(cache, hash)
29
+ x.get.hasContent.sync = (cache, hash) => get.hasContent.sync(cache, hash)
27
30
 
28
31
  x.put = (cache, key, data, opts) => put(cache, key, data, opts)
29
32
  x.put.stream = (cache, key, opts) => put.stream(cache, key, opts)
package/locales/es.js CHANGED
@@ -18,12 +18,15 @@ x.ls.flujo = cache => ls.stream(cache)
18
18
 
19
19
  x.saca = (cache, clave, ops) => get(cache, clave, ops)
20
20
  x.saca.porHacheo = (cache, hacheo, ops) => get.byDigest(cache, hacheo, ops)
21
+ x.saca.sinc = (cache, clave, ops) => get.sync(cache, clave, ops)
22
+ x.saca.sinc.porHacheo = (cache, hacheo, ops) => get.sync.byDigest(cache, hacheo, ops)
21
23
  x.saca.flujo = (cache, clave, ops) => get.stream(cache, clave, ops)
22
24
  x.saca.flujo.porHacheo = (cache, hacheo, ops) => get.stream.byDigest(cache, hacheo, ops)
23
25
  x.sava.copia = (cache, clave, destino, opts) => get.copy(cache, clave, destino, opts)
24
26
  x.sava.copia.porHacheo = (cache, hacheo, destino, opts) => get.copy.byDigest(cache, hacheo, destino, opts)
25
27
  x.saca.info = (cache, clave) => get.info(cache, clave)
26
28
  x.saca.tieneDatos = (cache, hacheo) => get.hasContent(cache, hacheo)
29
+ x.saca.tieneDatos.sinc = (cache, hacheo) => get.hasContent.sync(cache, hacheo)
27
30
 
28
31
  x.mete = (cache, clave, datos, ops) => put(cache, clave, datos, ops)
29
32
  x.mete.flujo = (cache, clave, ops) => put.stream(cache, clave, ops)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cacache",
3
- "version": "11.0.3",
3
+ "version": "11.3.1",
4
4
  "cache-version": {
5
5
  "content": "2",
6
6
  "index": "5"