overleaf/services/history-v1/storage/lib/blob_hash.js

82 lines
2 KiB
JavaScript
Raw Normal View History

/** @module */
'use strict'
const BPromise = require('bluebird')
const fs = BPromise.promisifyAll(require('fs'))
const crypto = require('crypto')
const { pipeline } = require('stream')
const assert = require('./assert')
function getGitBlobHeader(byteLength) {
return 'blob ' + byteLength + '\x00'
}
function getBlobHash(byteLength) {
const hash = crypto.createHash('sha1')
hash.setEncoding('hex')
hash.update(getGitBlobHeader(byteLength))
return hash
}
/**
* Compute the git blob hash for a blob from a readable stream of its content.
*
* @function
* @param {number} byteLength
* @param {stream.Readable} stream
* @return {Promise.<string>} hexadecimal SHA-1 hash
*/
exports.fromStream = BPromise.method(function blobHashFromStream(
byteLength,
stream
) {
assert.integer(byteLength, 'blobHash: bad byteLength')
assert.object(stream, 'blobHash: bad stream')
const hash = getBlobHash(byteLength)
return new BPromise(function (resolve, reject) {
pipeline(stream, hash, function (err) {
if (err) {
reject(err)
} else {
hash.end()
resolve(hash.read())
}
})
})
})
/**
* Compute the git blob hash for a blob with the given string content.
*
* @param {string} string
* @return {string} hexadecimal SHA-1 hash
*/
exports.fromString = function blobHashFromString(string) {
assert.string(string, 'blobHash: bad string')
const hash = getBlobHash(Buffer.byteLength(string))
hash.update(string, 'utf8')
hash.end()
return hash.read()
}
/**
* Compute the git blob hash for the content of a file
*
* @param {string} filePath
* @return {string} hexadecimal SHA-1 hash
*/
exports.fromFile = function blobHashFromFile(pathname) {
assert.string(pathname, 'blobHash: bad pathname')
function getByteLengthOfFile() {
return fs.statAsync(pathname).then(stat => stat.size)
}
const fromStream = this.fromStream
return getByteLengthOfFile(pathname).then(function (byteLength) {
const stream = fs.createReadStream(pathname)
return fromStream(byteLength, stream)
})
}