// Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { tmpdir } from 'node:os'; import { mkdtemp, rm, rename, stat, writeFile } from 'node:fs/promises'; import { createReadStream } from 'node:fs'; import { pipeline } from 'node:stream/promises'; import { createHash } from 'node:crypto'; import path from 'node:path'; import type { ArtifactCreated } from 'electron-builder'; import { BlockMap } from 'better-blockmap'; export async function artifactBuildCompleted({ target, file, packager, updateInfo, }: ArtifactCreated): Promise { if (packager.platform.name === 'linux' && file.endsWith('.AppImage')) { const blockMapPath = `${file}.blockmap`; console.log(`Generating blockmap ${blockMapPath}`); const blockMapGenerator = new BlockMap({ detectZipBoundary: true }); await pipeline(createReadStream(file), blockMapGenerator); await writeFile(blockMapPath, blockMapGenerator.compress()); } if (packager.platform.name !== 'mac') { return; } if (target?.name !== 'zip') { return; } if (!file.endsWith('.zip')) { return; } // ESM module const { optimize } = await import('@indutny/rezip-electron'); const tmpFolder = await mkdtemp(path.join(tmpdir(), 'rezip')); const optimizedPath = path.join(tmpFolder, path.basename(file)); try { console.log(`Optimizing ${file} => ${optimizedPath}`); await optimize({ inputPath: file, outputPath: optimizedPath, blockMapPath: `${file}.blockmap`, }); console.log(`Replacing ${file}`); await rename(optimizedPath, file); } finally { await rm(tmpFolder, { recursive: true }); } console.log('Updating hash and size'); const sha512 = createHash('sha512'); await pipeline(createReadStream(file), sha512); // eslint-disable-next-line no-param-reassign updateInfo.sha512 = sha512.digest('base64'); const { size } = await stat(file); // eslint-disable-next-line no-param-reassign updateInfo.size = size; }