{"version":3,"sources":["util.ts"],"names":["createHash","cryptoCreateHash","fse","arrayFilterAsync","list","filter","r","entry","push","arrayMapAsync","map","streamEndError","obj","end","Promise","resolve","reject","done","err","on","promiseCatch","p","d","lstatExists","path","lstat","readDir","dotfile","readdir","charAt","sort","hashFile","algorithm","encoding","hasher","reader","createReadStream","data","update","digest","hashNormalize","hash","toLowerCase","fileHash","hashes","hashers","forEach","hashed","fileHashVerify","all","hashedV","expectedV","Error","fileSizeVerify","size","stat","fSize","dependSort","deps","m","Map","set","Set","a","b","aDeps","get","has","bDeps","streamVerify","source","endEvent","onData","streamSize","length","emit","streamRequest","onResponse","response","abort","streamRequestDownload","write","createWriteStream","written","pipe","zipEntryExtract","sizeD","stream"],"mappings":"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","sourcesContent":["import {createHash as cryptoCreateHash} from 'crypto';\nimport {EventEmitter} from 'events';\nimport {Readable} from 'stream';\n\nimport fse from 'fs-extra';\n\nimport {\n\tHashEncoding,\n\tIHash,\n\tIRequestStream,\n\tIZipItterEntry,\n\tOnData,\n\tOnResponse\n} from './types';\n\n/**\n * Like array filter method, but with asyncronous callback.\n *\n * @param list The array to filter.\n * @param filter Filter function.\n * @returns Filtered array.\n */\nexport async function arrayFilterAsync<T>(\n\tlist: T[],\n\tfilter: (entry: T) => Promise<any>\n) {\n\tconst r: T[] = [];\n\tfor (const entry of list) {\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tif (await filter(entry)) {\n\t\t\tr.push(entry);\n\t\t}\n\t}\n\treturn r;\n}\n\n/**\n * Like array map method, but with asyncronous callback.\n *\n * @param list The array to map.\n * @param map Map function.\n * @returns Mapped array.\n */\nexport async function arrayMapAsync<T, U>(\n\tlist: T[],\n\tmap: (entry: T) => Promise<U>\n) {\n\tconst r: U[] = [];\n\tfor (const entry of list) {\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tr.push(await map(entry));\n\t}\n\treturn r;\n}\n\n/**\n * Promise for event emitter object to end successfully or in an error.\n *\n * @param obj Event emitter.\n * @param end The end event name.\n */\nexport async function streamEndError(obj: EventEmitter, end: string) {\n\tawait new Promise((resolve, reject) => {\n\t\tconst done = (err: Error | null) => {\n\t\t\tif (err) {\n\t\t\t\treject(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve();\n\t\t};\n\t\tobj.on(end, () => {\n\t\t\tdone(null);\n\t\t});\n\t\tobj.on('error', err => {\n\t\t\tdone(err);\n\t\t});\n\t});\n}\n\n/**\n * Catch promise on error and return default value.\n *\n * @param p Promise object.\n * @param d Default value.\n * @returns Resulting value.\n */\nexport async function promiseCatch<T, U>(p: Promise<T>, d: U) {\n\tlet r: T | U = d;\n\ttry {\n\t\tr = await p;\n\t}\n\tcatch (err) {\n\t\t// Do nothing.\n\t}\n\treturn r;\n}\n\n/**\n * Promise for lstating a path, null on error.\n *\n * @param path File path.\n * @returns Stat object or null.\n */\nexport async function lstatExists(path: string) {\n\treturn promiseCatch(fse.lstat(path), null);\n}\n\n/**\n * Read directory, optional skip dot files, sorted order.\n *\n * @param path Path to the directory to list.\n * @param dotfile Include dot files in the list or not.\n * @returns Directory list, sorted order.\n */\nexport async function readDir(path: string, dotfile = true) {\n\tconst list = await fse.readdir(path);\n\tconst r: string[] = [];\n\tfor (const entry of list) {\n\t\t// Skip any dot files.\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with\n\t\tif (!dotfile && entry.charAt(0) === '.') {\n\t\t\tcontinue;\n\t\t}\n\t\tr.push(entry);\n\t}\n\tr.sort();\n\treturn r;\n}\n\n/**\n * Hash file using the specified algoithm.\n *\n * @param path File path.\n * @param algorithm Hash algorithm.\n * @param encoding Digest encoding.\n * @returns Hash digest.\n */\nexport async function hashFile(\n\tpath: string,\n\talgorithm: string,\n\tencoding: HashEncoding\n) {\n\tconst hasher = cryptoCreateHash(algorithm);\n\tconst reader = fse.createReadStream(path);\n\treader.on('data', data => {\n\t\thasher.update(data);\n\t});\n\tawait streamEndError(reader, 'close');\n\tconst digest = hasher.digest(encoding);\n\treturn hashNormalize(digest, encoding);\n}\n\n/**\n * Normalize a hash string based on the encoding.\n *\n * @param hash Hash value.\n * @param encoding Hash encoding.\n * @returns Normalized hash.\n */\nexport function hashNormalize(hash: string, encoding: HashEncoding) {\n\treturn encoding === 'hex' ? hash.toLowerCase() : hash;\n}\n\n/**\n * Hash file using the specified algoithms.\n *\n * @param path File path.\n * @param hashes Hash list.\n */\nexport async function fileHash(path: string, hashes: IHash[]) {\n\tconst hashers = hashes.map(hash => ({\n\t\thash,\n\t\thasher: cryptoCreateHash(hash.algorithm)\n\t}));\n\n\tconst reader = fse.createReadStream(path);\n\treader.on('data', data => {\n\t\t// Update hashers.\n\t\thashers.forEach(entry => entry.hasher.update(data));\n\t});\n\n\tawait streamEndError(reader, 'close');\n\n\t// Verify hashes.\n\tfor (const {hash, hasher} of hashers) {\n\t\tconst {encoding} = hash;\n\t\tconst hashed = hasher.digest(encoding);\n\t\thash.digest = hashNormalize(hashed, encoding);\n\t}\n}\n\n/**\n * Verify file hash list using the specified algoithms.\n *\n * @param path File path.\n * @param hashes Hash list.\n */\nexport async function fileHashVerify(path: string, hashes: IHash[]) {\n\tconst all = hashes.map(hash => {\n\t\tconst hashed: IHash = {\n\t\t\talgorithm: hash.algorithm,\n\t\t\tencoding: hash.encoding,\n\t\t\tdigest: hash.digest\n\t\t};\n\t\treturn {\n\t\t\thash,\n\t\t\thashed\n\t\t};\n\t});\n\n\tawait fileHash(path, all.map(entry => entry.hashed));\n\n\tfor (const {hash, hashed} of all) {\n\t\tconst {encoding, algorithm} = hash;\n\t\tconst hashedV = hashNormalize(hashed.digest, encoding);\n\t\tconst expectedV = hashNormalize(hash.digest, encoding);\n\t\tif (hashedV === expectedV) {\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Invalid ${algorithm} hash: ${hashedV} expected: ${expectedV}`\n\t\t);\n\t}\n}\n\n/**\n * Verify file size or throw error.\n *\n * @param path File path.\n * @param size Expected size.\n */\nexport async function fileSizeVerify(path: string, size: number) {\n\tconst stat = await fse.lstat(path);\n\tconst fSize = stat.size;\n\tif (fSize !== size) {\n\t\tthrow new Error(`Invalid file size: ${fSize} expected: ${size}`);\n\t}\n}\n\n/**\n * Sort entries on dependencies listed for each entry.\n * Sorts the array in-place.\n *\n * @param list The array to sort.\n * @param deps Get the list of dependencies for each entry.\n * @returns Sorted array.\n */\nexport function dependSort<T>(list: T[], deps: (entry: T) => T[]) {\n\tconst m = new Map<T, Set<T>>();\n\tfor (const entry of list) {\n\t\tm.set(entry, new Set(deps(entry)));\n\t}\n\treturn list.sort((a, b) => {\n\t\tconst aDeps = m.get(a) as Set<T>;\n\t\tif (aDeps.has(b)) {\n\t\t\treturn 1;\n\t\t}\n\t\tconst bDeps = m.get(b) as Set<T>;\n\t\tif (bDeps.has(a)) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t});\n}\n\n/**\n * Stream verifier.\n *\n * @param source Request stream.\n * @param endEvent The end event name.\n * @param size Expected size.\n * @param hashes Expected hashes.\n * @param onData Data event handler, can throw to cancel download.\n */\nexport async function streamVerify(\n\tsource: Readable,\n\tendEvent: string,\n\tsize: number | null = null,\n\thashes: IHash[] | null = null,\n\tonData: OnData | null = null\n) {\n\tconst hashers = (hashes || []).map(hash => ({\n\t\thash,\n\t\thasher: cryptoCreateHash(hash.algorithm)\n\t}));\n\n\tlet streamSize = 0;\n\tsource.on('data', data => {\n\t\t// Update size, check no over read.\n\t\tstreamSize += data.length;\n\t\tif (size !== null && streamSize > size) {\n\t\t\tsource.emit('error', new Error(\n\t\t\t\t`Read size too large: ${streamSize}`\n\t\t\t));\n\t\t}\n\n\t\t// Update hashers.\n\t\thashers.forEach(entry => entry.hasher.update(data));\n\n\t\tif (!onData) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tonData(data);\n\t\t}\n\t\tcatch (err) {\n\t\t\tsource.emit('error', err);\n\t\t}\n\t});\n\n\tawait streamEndError(source, 'end');\n\n\t// Verify size is not too small (too large is checked on data).\n\tif (size !== null && streamSize < size) {\n\t\tthrow new Error(`Read size too small: ${streamSize}`);\n\t}\n\n\tfor (const {hash, hasher} of hashers) {\n\t\tconst {algorithm, encoding, digest} = hash;\n\t\tconst expectedV = hashNormalize(digest, encoding);\n\t\tconst hashed = hasher.digest(encoding);\n\t\tconst hashedV = hashNormalize(hashed, encoding);\n\t\tif (hashedV === expectedV) {\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Invalid ${algorithm} hash: ${hashedV} expected: ${expectedV}`\n\t\t);\n\t}\n}\n\n/**\n * Stream a request stream to a specified directory.\n *\n * @param source Request stream.\n * @param size Expected size.\n * @param hashes Expected hashes.\n * @param onResponse Response event handler, can throw to cancel download.\n * @param onData Data event handler, can throw to cancel download.\n */\nexport async function streamRequest(\n\tsource: IRequestStream,\n\tsize: number | null = null,\n\thashes: IHash[] | null = null,\n\tonResponse: OnResponse | null = null,\n\tonData: OnData | null = null\n) {\n\tsource.on('response', response => {\n\t\ttry {\n\t\t\tif (onResponse) {\n\t\t\t\tonResponse(response);\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tsource.emit('error', err);\n\t\t\treturn;\n\t\t}\n\t});\n\tsource.on('error', () => {\n\t\tsource.abort();\n\t});\n\n\tawait streamVerify(\n\t\t(source as any) as Readable,\n\t\t'end',\n\t\tsize,\n\t\thashes,\n\t\tonData\n\t);\n}\n\n/**\n * Write a request stream to a specified file.\n *\n * @param source Request stream.\n * @param path File path.\n * @param size Expected size.\n * @param hashes Expected hashes.\n * @param onResponse Response event handler, can throw to cancel download.\n * @param onData Data event handler, can throw to cancel download.\n */\nexport async function streamRequestDownload(\n\tsource: IRequestStream,\n\tpath: string,\n\tsize: number | null = null,\n\thashes: IHash[] | null = null,\n\tonResponse: OnResponse | null = null,\n\tonData: OnData | null = null\n) {\n\tconst write = fse.createWriteStream(path, {\n\t\tencoding: 'binary'\n\t});\n\tconst written = streamEndError(write, 'close');\n\tsource.pipe(write);\n\n\tawait streamRequest(source, size, hashes, onResponse, onData);\n\tawait written;\n}\n\n/**\n * Write a ZIP entry to a specified file.\n *\n * @param entry ZIP entry.\n * @param path File path.\n * @param size Expected size.\n * @param hashes Expected hashes.\n * @param onData Data event handler, can throw to cancel download.\n */\nexport async function zipEntryExtract(\n\tentry: IZipItterEntry,\n\tpath: string,\n\tsize: number | null = null,\n\thashes: IHash[] | null = null,\n\tonData: OnData | null = null\n) {\n\tconst {sizeD} = entry;\n\tif (size === null) {\n\t\tsize = sizeD;\n\t}\n\telse if (sizeD !== size) {\n\t\tthrow new Error(`Unexpected extract size: ${sizeD}`);\n\t}\n\n\tconst source = await entry.stream();\n\tconst write = fse.createWriteStream(path, {\n\t\tencoding: 'binary'\n\t});\n\tconst written = streamEndError(write, 'close');\n\tsource.pipe(write);\n\n\tawait streamVerify(source, 'end', size, hashes, onData);\n\tawait written;\n}\n"],"file":"util.mjs","sourceRoot":"../src"}