summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/cacache/lib/content/read.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/cacache/lib/content/read.js')
-rw-r--r--deps/npm/node_modules/cacache/lib/content/read.js139
1 files changed, 102 insertions, 37 deletions
diff --git a/deps/npm/node_modules/cacache/lib/content/read.js b/deps/npm/node_modules/cacache/lib/content/read.js
index 5c1a6f2f29..8f1acc06d8 100644
--- a/deps/npm/node_modules/cacache/lib/content/read.js
+++ b/deps/npm/node_modules/cacache/lib/content/read.js
@@ -10,7 +10,8 @@ const pipe = BB.promisify(require('mississippi').pipe)
const ssri = require('ssri')
const Y = require('../util/y.js')
-BB.promisifyAll(fs)
+const lstatAsync = BB.promisify(fs.lstat)
+const readFileAsync = BB.promisify(fs.readFile)
const ReadOpts = figgyPudding({
size: {}
@@ -19,10 +20,8 @@ const ReadOpts = figgyPudding({
module.exports = read
function read (cache, integrity, opts) {
opts = ReadOpts(opts)
- return pickContentSri(cache, integrity).then(content => {
- const sri = content.sri
- const cpath = contentPath(cache, sri)
- return fs.readFileAsync(cpath, null).then(data => {
+ return withContentSri(cache, integrity, (cpath, sri) => {
+ return readFileAsync(cpath, null).then(data => {
if (typeof opts.size === 'number' && opts.size !== data.length) {
throw sizeError(opts.size, data.length)
} else if (ssri.checkData(data, sri)) {
@@ -34,17 +33,31 @@ function read (cache, integrity, opts) {
})
}
+module.exports.sync = readSync
+function readSync (cache, integrity, opts) {
+ opts = ReadOpts(opts)
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
+ const data = fs.readFileSync(cpath)
+ if (typeof opts.size === 'number' && opts.size !== data.length) {
+ throw sizeError(opts.size, data.length)
+ } else if (ssri.checkData(data, sri)) {
+ return data
+ } else {
+ throw integrityError(sri, cpath)
+ }
+ })
+}
+
module.exports.stream = readStream
module.exports.readStream = readStream
function readStream (cache, integrity, opts) {
opts = ReadOpts(opts)
const stream = new PassThrough()
- pickContentSri(
- cache, integrity
- ).then(content => {
- const sri = content.sri
+ withContentSri(cache, integrity, (cpath, sri) => {
+ return lstatAsync(cpath).then(stat => ({cpath, sri, stat}))
+ }).then(({cpath, sri, stat}) => {
return pipe(
- fs.createReadStream(contentPath(cache, sri)),
+ fs.createReadStream(cpath),
ssri.integrityStream({
integrity: sri,
size: opts.size
@@ -57,37 +70,93 @@ function readStream (cache, integrity, opts) {
return stream
}
+let copyFileAsync
if (fs.copyFile) {
module.exports.copy = copy
+ module.exports.copy.sync = copySync
+ copyFileAsync = BB.promisify(fs.copyFile)
}
+
function copy (cache, integrity, dest, opts) {
opts = ReadOpts(opts)
- return pickContentSri(cache, integrity).then(content => {
- const sri = content.sri
- const cpath = contentPath(cache, sri)
- return fs.copyFileAsync(cpath, dest).then(() => content.size)
+ return withContentSri(cache, integrity, (cpath, sri) => {
+ return copyFileAsync(cpath, dest)
+ })
+}
+
+function copySync (cache, integrity, dest, opts) {
+ opts = ReadOpts(opts)
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
+ return fs.copyFileSync(cpath, dest)
})
}
module.exports.hasContent = hasContent
function hasContent (cache, integrity) {
if (!integrity) { return BB.resolve(false) }
- return pickContentSri(cache, integrity)
- .catch({code: 'ENOENT'}, () => false)
- .catch({code: 'EPERM'}, err => {
+ return withContentSri(cache, integrity, (cpath, sri) => {
+ return lstatAsync(cpath).then(stat => ({size: stat.size, sri, stat}))
+ }).catch(err => {
+ if (err.code === 'ENOENT') { return false }
+ if (err.code === 'EPERM') {
if (process.platform !== 'win32') {
throw err
} else {
return false
}
- }).then(content => {
- if (!content.sri) return false
- return ({ sri: content.sri, size: content.stat.size })
- })
+ }
+ })
}
-module.exports._pickContentSri = pickContentSri
-function pickContentSri (cache, integrity) {
+module.exports.hasContent.sync = hasContentSync
+function hasContentSync (cache, integrity) {
+ if (!integrity) { return false }
+ return withContentSriSync(cache, integrity, (cpath, sri) => {
+ try {
+ const stat = fs.lstatSync(cpath)
+ return {size: stat.size, sri, stat}
+ } catch (err) {
+ if (err.code === 'ENOENT') { return false }
+ if (err.code === 'EPERM') {
+ if (process.platform !== 'win32') {
+ throw err
+ } else {
+ return false
+ }
+ }
+ }
+ })
+}
+
+function withContentSri (cache, integrity, fn) {
+ return BB.try(() => {
+ const sri = ssri.parse(integrity)
+ // If `integrity` has multiple entries, pick the first digest
+ // with available local data.
+ const algo = sri.pickAlgorithm()
+ const digests = sri[algo]
+ if (digests.length <= 1) {
+ const cpath = contentPath(cache, digests[0])
+ return fn(cpath, digests[0])
+ } else {
+ return BB.any(sri[sri.pickAlgorithm()].map(meta => {
+ return withContentSri(cache, meta, fn)
+ }, {concurrency: 1}))
+ .catch(err => {
+ if ([].some.call(err, e => e.code === 'ENOENT')) {
+ throw Object.assign(
+ new Error('No matching content found for ' + sri.toString()),
+ {code: 'ENOENT'}
+ )
+ } else {
+ throw err[0]
+ }
+ })
+ }
+ })
+}
+
+function withContentSriSync (cache, integrity, fn) {
const sri = ssri.parse(integrity)
// If `integrity` has multiple entries, pick the first digest
// with available local data.
@@ -95,21 +164,17 @@ function pickContentSri (cache, integrity) {
const digests = sri[algo]
if (digests.length <= 1) {
const cpath = contentPath(cache, digests[0])
- return fs.lstatAsync(cpath).then(stat => ({ sri: digests[0], stat }))
+ return fn(cpath, digests[0])
} else {
- return BB.any(sri[sri.pickAlgorithm()].map(meta => {
- return pickContentSri(cache, meta)
- }))
- .catch(err => {
- if ([].some.call(err, e => e.code === 'ENOENT')) {
- throw Object.assign(
- new Error('No matching content found for ' + sri.toString()),
- {code: 'ENOENT'}
- )
- } else {
- throw err[0]
- }
- })
+ let lastErr = null
+ for (const meta of sri[sri.pickAlgorithm()]) {
+ try {
+ return withContentSriSync(cache, meta, fn)
+ } catch (err) {
+ lastErr = err
+ }
+ }
+ if (lastErr) { throw lastErr }
}
}