#!/usr/bin/env node import { access, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { createStaticArchive } from './archive.mjs'; import { sha256File } from './artifact.mjs'; import { assertSafeRemovalTarget, canonicalExistingPath, canonicalPathsOverlap, } from './path-safety.mjs'; import { publishStagedTargets } from './publication.mjs'; function argument(name, fallback) { const index = process.argv.indexOf(name); return index >= 0 ? process.argv[index + 1] : fallback; } const input = await canonicalExistingPath( argument('--input', 'build/toolbox'), 'Static archive input' ); const output = await assertSafeRemovalTarget( argument('--output', 'artifacts/add-ideas-toolbox-static.zip') ); const checksumOutput = await assertSafeRemovalTarget(`${output}.sha256`); const force = process.argv.includes('--force'); if (path.extname(output).toLocaleLowerCase() !== '.zip') throw new Error('Archive output must use a .zip extension.'); if (canonicalPathsOverlap(output, input)) throw new Error('Archive output and input directory must not overlap.'); const outputExists = await access(output).then( () => true, () => false ); const checksumExists = await access(checksumOutput).then( () => true, () => false ); if (outputExists && !force) throw new Error( `Archive already exists (use --force to replace it): ${output}` ); if (checksumExists && !force) throw new Error( `Checksum already exists (use --force to replace it): ${checksumOutput}` ); await mkdir(path.dirname(output), { recursive: true }); const staging = await mkdtemp( path.join(path.dirname(output), '.toolbox-package-') ); const stagedArchive = path.join(staging, path.basename(output)); const stagedChecksum = `${stagedArchive}.sha256`; try { await createStaticArchive(input, stagedArchive); const checksum = await sha256File(stagedArchive); await writeFile(stagedChecksum, `${checksum} ${path.basename(output)}\n`, { flag: 'wx', }); await publishStagedTargets( [ { staged: stagedArchive, target: output }, { staged: stagedChecksum, target: checksumOutput }, ], { force } ); } finally { await rm(staging, { recursive: true, force: true }); } process.stdout.write(`Created ${output}\nChecksum: ${checksumOutput}\n`);