-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
69 lines (59 loc) · 1.38 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
const { createHash } = require('node:crypto');
const { createReadStream } = require('node:fs');
/**
* @callback hashCallback
* @param {*} err
* @param {string=} digest
* @return {*}
*/
/**
* @typedef {object} hashOptions
* @property {string} file
* @property {string=} hash
* @property {boolean=} prefix
*/
/**
* Creates a SRI hash of the given file
*
* @param {(string|hashOptions)} file Accepts either a filename or a dictionary of options
* @param {hashCallback=} cb Optional callback
* @return {Promise<string>|void} Returns a promise if no callback has been provided
*/
function hash(file, cb)
{
let options = {
hash: 'sha256',
prefix: true
};
if (typeof file === 'object') {
options = { ...options, ...file };
}
else {
options.file = file;
}
if (!options.file) {
throw new TypeError('No file specified');
}
const p = new Promise((resolve, reject) => {
const input = createReadStream(options.file);
const hash = createHash(options.hash);
hash.setEncoding('base64');
input.on('end', () => {
hash.end();
/** @type string */
const digest = hash.read();
resolve(options.prefix ? `${options.hash}-${digest}` : digest);
});
input.on('error', (e) => reject(e));
input.pipe(hash);
});
if (typeof cb === 'function') {
p.then(digest => cb(null, digest)).catch(cb);
}
else {
return p;
}
}
module.exports = {
hash
};