Files
iptvnator/tools/embedded-mpv/download-pinned-source.mjs
T

64 lines
1.8 KiB
JavaScript

import crypto from 'node:crypto';
import fs from 'node:fs';
function sha256File(filePath) {
const hash = crypto.createHash('sha256');
hash.update(fs.readFileSync(filePath));
return hash.digest('hex');
}
function checksumFailure(expectedSha256, actualSha256) {
return `SHA-256 mismatch: expected ${expectedSha256}, received ${actualSha256}`;
}
export function downloadPinnedSource({
archivePath,
download,
expectedSha256,
urls,
}) {
const partialPath = `${archivePath}.partial`;
const failures = [];
const sourceUrls = [...urls];
if (fs.existsSync(archivePath)) {
const actualSha256 = sha256File(archivePath);
if (actualSha256 === expectedSha256) {
return {
sourceSha256: actualSha256,
sourceUrl: null,
sourceUrls,
};
}
failures.push(
`cached archive: ${checksumFailure(
expectedSha256,
actualSha256
)}`
);
fs.rmSync(archivePath, { force: true });
}
for (const url of sourceUrls) {
fs.rmSync(partialPath, { force: true });
try {
download({ destinationPath: partialPath, url });
const actualSha256 = sha256File(partialPath);
if (actualSha256 !== expectedSha256) {
throw new Error(
checksumFailure(expectedSha256, actualSha256)
);
}
fs.renameSync(partialPath, archivePath);
return { sourceSha256: actualSha256, sourceUrl: url, sourceUrls };
} catch (error) {
failures.push(`${url}: ${error.message}`);
fs.rmSync(partialPath, { force: true });
}
}
throw new Error(
`Unable to download a verified source archive:\n${failures.join('\n')}`
);
}