Files
Krunker-Civilian-Client-Test/scripts/build-asar.js
T

97 lines
3.3 KiB
JavaScript

/**
* Build a standalone app.asar + checksums.sha256 for minor (patch) updates.
*
* Replicates what electron-builder packs into the asar (dist/ + package.json +
* required node_modules) without running the full installer build.
*
* Usage:
* npm run build:asar # default (github) update source
* UPDATE_SOURCE=gitea npm run build:asar # gitea update source
*/
const { execSync } = require('child_process');
const { cpSync, mkdirSync, rmSync, readFileSync, writeFileSync, createReadStream } = require('fs');
const { join } = require('path');
const { createHash } = require('crypto');
const asar = require('@electron/asar');
const ROOT = join(__dirname, '..');
const STAGING = join(ROOT, 'out', 'asar-staging');
const OUTPUT = join(ROOT, 'out', 'asar');
// Same node_modules list as electron-builder.yml
const NODE_MODULES = [
'electron-store', 'conf', 'dot-prop', 'type-fest', 'pkg-up',
'find-up', 'locate-path', 'p-locate', 'p-limit', 'yocto-queue',
'path-exists', 'env-paths', 'json-schema-typed', 'ajv', 'ajv-formats',
'atomically', 'debounce-fn', 'mimic-fn', 'semver', 'onetime',
];
function shouldExclude(src) {
return src.endsWith('.ts') || src.endsWith('.map');
}
async function main() {
// 1. Run Vite build (pass UPDATE_SOURCE through env)
const env = { ...process.env };
if (env.UPDATE_SOURCE) {
console.log(`Building with UPDATE_SOURCE=${env.UPDATE_SOURCE}`);
}
execSync('npm run build', { cwd: ROOT, stdio: 'inherit', env });
// 2. Prepare staging directory
rmSync(STAGING, { recursive: true, force: true });
mkdirSync(STAGING, { recursive: true });
// Copy dist/
cpSync(join(ROOT, 'dist'), join(STAGING, 'dist'), { recursive: true });
// Copy package.json (Electron reads "main" from it)
cpSync(join(ROOT, 'package.json'), join(STAGING, 'package.json'));
// Copy required node_modules (excluding .ts and .map files)
for (const mod of NODE_MODULES) {
const src = join(ROOT, 'node_modules', mod);
const dest = join(STAGING, 'node_modules', mod);
cpSync(src, dest, {
recursive: true,
filter: (s) => !shouldExclude(s),
});
}
// 3. Pack into asar
mkdirSync(OUTPUT, { recursive: true });
const asarPath = join(OUTPUT, 'app.asar');
await asar.createPackage(STAGING, asarPath);
console.log('Created:', asarPath);
// 4. Generate checksums.sha256
const hex = await fileHash(asarPath);
const checksumsPath = join(OUTPUT, 'checksums.sha256');
writeFileSync(checksumsPath, `${hex} app.asar\n`);
console.log(`SHA-256: ${hex}`);
console.log('Created:', checksumsPath);
// 5. Cleanup staging
rmSync(STAGING, { recursive: true, force: true });
// Print size
const size = readFileSync(asarPath).length;
console.log(`\napp.asar size: ${(size / 1024).toFixed(1)} KB`);
}
function fileHash(filePath) {
return new Promise((resolve, reject) => {
const hash = createHash('sha256');
const stream = createReadStream(filePath);
stream.on('data', (chunk) => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', reject);
});
}
main().catch((err) => {
console.error('build-asar failed:', err);
process.exit(1);
});