#!/usr/bin/env node 'use strict'; const { spawnSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const EXPECTED_NAME = 'ecc-universal'; const EXPECTED_BIN = 'scripts/ecc.js'; const CHILD_PROCESS_TIMEOUT_MS = 5 * 60 * 1000; const REQUIRED_FILES = Object.freeze([ 'scripts/ecc.js', 'manifests/install-components.json', 'manifests/install-modules.json', 'manifests/install-profiles.json', ]); function fail(message) { throw new Error(message); } function isWithin(root, candidate) { const relative = path.relative(root, candidate); return relative === '' || ( relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative) ); } function requireRegularFile(packageRoot, relativePath) { const resolvedPath = path.resolve(packageRoot, relativePath); if (!isWithin(packageRoot, resolvedPath)) { fail(`Package path escapes the extracted root: ${relativePath}`); } let file; try { file = fs.lstatSync(resolvedPath); } catch { fail(`Packed package is missing ${relativePath}.`); } if (!file.isFile() || file.isSymbolicLink()) { fail(`Packed package path is not a regular file: ${relativePath}`); } return resolvedPath; } function validatePackedPackage(packageRoot) { const resolvedRoot = path.resolve(packageRoot); const packageJsonPath = requireRegularFile(resolvedRoot, 'package.json'); const manifest = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); if (manifest.name !== EXPECTED_NAME) { fail(`Unexpected packed package name: ${manifest.name || ''}.`); } if (typeof manifest.version !== 'string' || manifest.version.length === 0) { fail('Packed package version is missing.'); } if (!manifest.bin || manifest.bin.ecc !== EXPECTED_BIN) { fail(`Packed package bin.ecc must map to ${EXPECTED_BIN}.`); } for (const requiredFile of REQUIRED_FILES) { requireRegularFile(resolvedRoot, requiredFile); } const binTarget = path.resolve(resolvedRoot, manifest.bin.ecc); if (!isWithin(resolvedRoot, binTarget)) { fail('Packed package bin.ecc escapes the extracted package root.'); } if (process.platform !== 'win32') { fs.accessSync(binTarget, fs.constants.X_OK); } return binTarget; } function run(executable, argv, options = {}) { const result = spawnSync(executable, argv, { ...options, encoding: 'utf8', shell: false, timeout: CHILD_PROCESS_TIMEOUT_MS, }); if (result.error) { fail(`Unable to run ${executable}: ${result.error.message}`); } if (result.status !== 0) { const detail = (result.stderr || result.stdout || '').trim(); fail(`${executable} exited with status ${result.status}${detail ? `: ${detail}` : ''}`); } return result; } function preparePackedCli(sourceRoot, outputRoot) { const resolvedSource = path.resolve(sourceRoot); const resolvedOutput = path.resolve(outputRoot); if (resolvedSource !== '/ecc') { fail('Package source must be the read-only /ecc checkout.'); } if (resolvedOutput !== '/tmp' && !resolvedOutput.startsWith('/tmp/')) { fail('Packed CLI output must remain under /tmp.'); } fs.mkdirSync(resolvedOutput, { recursive: true, mode: 0o700 }); const workRoot = fs.mkdtempSync(path.join(resolvedOutput, 'artifact-')); const childEnv = { ...process.env, NPM_CONFIG_CACHE: '/tmp/npm-cache', npm_config_audit: 'false', npm_config_fund: 'false', npm_config_ignore_scripts: 'true', npm_config_offline: 'true', }; const packed = run('npm', [ 'pack', resolvedSource, '--ignore-scripts', '--pack-destination', workRoot, '--json', ], { env: childEnv }); let metadata; try { metadata = JSON.parse(packed.stdout); } catch (error) { fail(`npm pack returned invalid JSON: ${error.message}`); } const filename = metadata?.[0]?.filename; if ( typeof filename !== 'string' || path.basename(filename) !== filename || !filename.endsWith('.tgz') ) { fail('npm pack did not return a confined tarball filename.'); } const archivePath = path.resolve(workRoot, filename); if (!isWithin(workRoot, archivePath)) { fail('npm pack tarball escaped the artifact directory.'); } const extractRoot = path.join(workRoot, 'extracted'); fs.mkdirSync(extractRoot, { mode: 0o700 }); run('tar', ['-xzf', archivePath, '-C', extractRoot]); const binTarget = validatePackedPackage(path.join(extractRoot, 'package')); const binRoot = path.join(workRoot, 'bin'); fs.mkdirSync(binRoot, { mode: 0o700 }); const publicBin = path.join(binRoot, 'ecc'); fs.symlinkSync(binTarget, publicBin); return publicBin; } function main() { try { const publicBin = preparePackedCli(process.argv[2], process.argv[3]); process.stdout.write(`${publicBin}\n`); } catch (error) { process.stderr.write(`Error: ${error.message}\n`); process.exitCode = 1; } } if (require.main === module) main(); module.exports = { isWithin, preparePackedCli, validatePackedPackage };