$
This commit is contained in:
150
node_modules/hasha/index.js
generated
vendored
Normal file
150
node_modules/hasha/index.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const isStream = require('is-stream');
|
||||
|
||||
const {Worker} = (() => {
|
||||
try {
|
||||
return require('worker_threads');
|
||||
} catch (_) {
|
||||
return {};
|
||||
}
|
||||
})();
|
||||
|
||||
let worker; // Lazy
|
||||
let taskIdCounter = 0;
|
||||
const tasks = new Map();
|
||||
|
||||
const recreateWorkerError = sourceError => {
|
||||
const error = new Error(sourceError.message);
|
||||
|
||||
for (const [key, value] of Object.entries(sourceError)) {
|
||||
if (key !== 'message') {
|
||||
error[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
const createWorker = () => {
|
||||
worker = new Worker(path.join(__dirname, 'thread.js'));
|
||||
|
||||
worker.on('message', message => {
|
||||
const task = tasks.get(message.id);
|
||||
tasks.delete(message.id);
|
||||
|
||||
if (tasks.size === 0) {
|
||||
worker.unref();
|
||||
}
|
||||
|
||||
if (message.error === undefined) {
|
||||
task.resolve(message.value);
|
||||
} else {
|
||||
task.reject(recreateWorkerError(message.error));
|
||||
}
|
||||
});
|
||||
|
||||
worker.on('error', error => {
|
||||
// Any error here is effectively an equivalent of segfault, and have no scope, so we just throw it on callback level
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
const taskWorker = (method, args, transferList) => new Promise((resolve, reject) => {
|
||||
const id = taskIdCounter++;
|
||||
tasks.set(id, {resolve, reject});
|
||||
|
||||
if (worker === undefined) {
|
||||
createWorker();
|
||||
}
|
||||
|
||||
worker.ref();
|
||||
worker.postMessage({id, method, args}, transferList);
|
||||
});
|
||||
|
||||
const hasha = (input, options = {}) => {
|
||||
let outputEncoding = options.encoding || 'hex';
|
||||
|
||||
if (outputEncoding === 'buffer') {
|
||||
outputEncoding = undefined;
|
||||
}
|
||||
|
||||
const hash = crypto.createHash(options.algorithm || 'sha512');
|
||||
|
||||
const update = buffer => {
|
||||
const inputEncoding = typeof buffer === 'string' ? 'utf8' : undefined;
|
||||
hash.update(buffer, inputEncoding);
|
||||
};
|
||||
|
||||
if (Array.isArray(input)) {
|
||||
input.forEach(update);
|
||||
} else {
|
||||
update(input);
|
||||
}
|
||||
|
||||
return hash.digest(outputEncoding);
|
||||
};
|
||||
|
||||
hasha.stream = (options = {}) => {
|
||||
let outputEncoding = options.encoding || 'hex';
|
||||
|
||||
if (outputEncoding === 'buffer') {
|
||||
outputEncoding = undefined;
|
||||
}
|
||||
|
||||
const stream = crypto.createHash(options.algorithm || 'sha512');
|
||||
stream.setEncoding(outputEncoding);
|
||||
return stream;
|
||||
};
|
||||
|
||||
hasha.fromStream = async (stream, options = {}) => {
|
||||
if (!isStream(stream)) {
|
||||
throw new TypeError('Expected a stream');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// TODO: Use `stream.pipeline` and `stream.finished` when targeting Node.js 10
|
||||
stream
|
||||
.on('error', reject)
|
||||
.pipe(hasha.stream(options))
|
||||
.on('error', reject)
|
||||
.on('finish', function () {
|
||||
resolve(this.read());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (Worker === undefined) {
|
||||
hasha.fromFile = async (filePath, options) => hasha.fromStream(fs.createReadStream(filePath), options);
|
||||
hasha.async = async (input, options) => hasha(input, options);
|
||||
} else {
|
||||
hasha.fromFile = async (filePath, {algorithm = 'sha512', encoding = 'hex'} = {}) => {
|
||||
const hash = await taskWorker('hashFile', [algorithm, filePath]);
|
||||
|
||||
if (encoding === 'buffer') {
|
||||
return Buffer.from(hash);
|
||||
}
|
||||
|
||||
return Buffer.from(hash).toString(encoding);
|
||||
};
|
||||
|
||||
hasha.async = async (input, {algorithm = 'sha512', encoding = 'hex'} = {}) => {
|
||||
if (encoding === 'buffer') {
|
||||
encoding = undefined;
|
||||
}
|
||||
|
||||
const hash = await taskWorker('hash', [algorithm, input]);
|
||||
|
||||
if (encoding === undefined) {
|
||||
return Buffer.from(hash);
|
||||
}
|
||||
|
||||
return Buffer.from(hash).toString(encoding);
|
||||
};
|
||||
}
|
||||
|
||||
hasha.fromFileSync = (filePath, options) => hasha(fs.readFileSync(filePath), options);
|
||||
|
||||
module.exports = hasha;
|
Reference in New Issue
Block a user