121 lines
3.6 KiB
JavaScript
121 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Download the published npm tarball and verify that the bundled host-platform
|
|
* native binary reports the expected package version.
|
|
*/
|
|
|
|
import { createWriteStream, existsSync, mkdtempSync, readFileSync, rmSync, unlinkSync } from 'fs';
|
|
import { tmpdir } from 'os';
|
|
import { dirname, join } from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { execFileSync } from 'child_process';
|
|
import { get } from 'https';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const rootDir = join(__dirname, '..');
|
|
|
|
const pkg = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf8'));
|
|
const packageName = process.env.PACKAGE_NAME || pkg.name || 'agent-browser-stealth';
|
|
const expectedVersion = process.env.EXPECTED_VERSION || pkg.version;
|
|
|
|
if (!expectedVersion) {
|
|
console.error('Error: expected version is empty');
|
|
process.exit(1);
|
|
}
|
|
|
|
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
const hostBinaryName = `agent-browser-${process.platform}-${process.arch}${ext}`;
|
|
|
|
function downloadFile(url, dest) {
|
|
return new Promise((resolve, reject) => {
|
|
const file = createWriteStream(dest);
|
|
|
|
const request = (currentUrl) => {
|
|
get(currentUrl, (response) => {
|
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
request(response.headers.location);
|
|
return;
|
|
}
|
|
|
|
if (response.statusCode !== 200) {
|
|
reject(new Error(`Failed to download tarball: HTTP ${response.statusCode}`));
|
|
return;
|
|
}
|
|
|
|
response.pipe(file);
|
|
file.on('finish', () => {
|
|
file.close();
|
|
resolve();
|
|
});
|
|
}).on('error', (err) => {
|
|
reject(err);
|
|
});
|
|
};
|
|
|
|
request(url);
|
|
});
|
|
}
|
|
|
|
let tempDir = '';
|
|
let tarballPath = '';
|
|
|
|
try {
|
|
const tarballUrl = execFileSync(
|
|
'npm',
|
|
['view', `${packageName}@${expectedVersion}`, 'dist.tarball'],
|
|
{
|
|
cwd: rootDir,
|
|
encoding: 'utf8',
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
}
|
|
).trim();
|
|
|
|
if (!tarballUrl) {
|
|
throw new Error(`could not resolve dist.tarball for ${packageName}@${expectedVersion}`);
|
|
}
|
|
|
|
tempDir = mkdtempSync(join(tmpdir(), 'ab-registry-verify-'));
|
|
tarballPath = join(tempDir, 'package.tgz');
|
|
await downloadFile(tarballUrl, tarballPath);
|
|
|
|
execFileSync('tar', ['-xzf', tarballPath, '-C', tempDir], {
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
|
|
const packedRoot = join(tempDir, 'package');
|
|
const packedPkg = JSON.parse(readFileSync(join(packedRoot, 'package.json'), 'utf8'));
|
|
if (String(packedPkg.version || '').trim() !== expectedVersion) {
|
|
throw new Error(
|
|
`registry package.json version mismatch: expected ${expectedVersion}, got ${packedPkg.version}`
|
|
);
|
|
}
|
|
|
|
const packedBinary = join(packedRoot, 'bin', hostBinaryName);
|
|
if (!existsSync(packedBinary)) {
|
|
throw new Error(`host binary missing in registry tarball: bin/${hostBinaryName}`);
|
|
}
|
|
|
|
const binaryVersion = execFileSync(packedBinary, ['--version'], {
|
|
encoding: 'utf8',
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
}).trim();
|
|
|
|
if (!binaryVersion.includes(expectedVersion)) {
|
|
throw new Error(
|
|
`registry host binary version mismatch: expected ${expectedVersion}, got "${binaryVersion}"`
|
|
);
|
|
}
|
|
|
|
console.log(
|
|
`✓ Registry tarball host binary matches package.json (${packageName}@${expectedVersion})`
|
|
);
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
console.error(`Error: ${message}`);
|
|
process.exitCode = 1;
|
|
} finally {
|
|
if (tarballPath && existsSync(tarballPath)) unlinkSync(tarballPath);
|
|
if (tempDir) rmSync(tempDir, { recursive: true, force: true });
|
|
}
|