import { afterEach, beforeEach, describe, expect, test } from 'bun:test'; import { execSync } from 'node:child_process'; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { buildPackument, computeIntegrity, highestVersion, indexTarballs, loadTarball, loadTarballsFromDir, readPackageJsonFromTarball, } from './packument'; let tmp: string; beforeEach(() => { tmp = mkdtempSync(join(tmpdir(), 'npm-sim-test-')); }); afterEach(() => { rmSync(tmp, { recursive: true, force: true }); }); function packFixture(name: string, version: string): string { const slug = `${name.replace(/[@/]/g, '_')}-${version}`; const pkgDir = join(tmp, 'pkg', slug); mkdirSync(pkgDir, { recursive: true }); writeFileSync(join(pkgDir, 'package.json'), JSON.stringify({ name, version, main: 'index.js' })); writeFileSync(join(pkgDir, 'index.js'), `module.exports = '${name}@${version}';\n`); const stagingDir = join(tmp, 'staging', slug); mkdirSync(stagingDir, { recursive: true }); execSync(`bun pm pack --destination=${stagingDir}`, { cwd: pkgDir, stdio: 'pipe' }); const filename = execSync(`ls ${stagingDir}`, { encoding: 'utf-8' }) .split('\n') .find((f) => f.endsWith('.tgz')); if (!filename) throw new Error(`bun pm pack produced no tarball in ${stagingDir}`); return join(stagingDir, filename); } describe('packument', () => { test('readPackageJsonFromTarball extracts the package.json', () => { const tgz = packFixture('@testorg/foo', '1.2.3'); const { pkg } = readPackageJsonFromTarball(tgz); expect(pkg.name).toBe('@testorg/foo'); expect(pkg.version).toBe('1.2.3'); }); test('computeIntegrity yields stable sha1 + sha512', () => { const buf = Buffer.from('hello'); const a = computeIntegrity(buf); const b = computeIntegrity(buf); expect(a).toEqual(b); expect(a.shasum).toMatch(/^[0-9a-f]{40}$/); expect(a.integrity).toMatch(/^sha512-/); }); test('highestVersion picks the largest semver-ish version', () => { expect(highestVersion(['1.0.0', '1.10.0', '1.2.0'])).toBe('1.10.0'); expect(highestVersion(['0.7.7'])).toBe('0.7.7'); }); test('loadTarball populates path, filename, integrity, pkg', () => { const tgz = packFixture('@testorg/foo', '1.2.3'); const filename = tgz.split('/').pop() as string; const meta = loadTarball(tgz, filename); expect(meta.pkg.name).toBe('@testorg/foo'); expect(meta.filename).toBe(filename); expect(meta.integrity).toMatch(/^sha512-/); }); test('loadTarballsFromDir + indexTarballs groups by name', () => { const tgz1 = packFixture('@testorg/foo', '1.0.0'); const tgz2 = packFixture('@testorg/foo', '2.0.0'); const dir = join(tmp, 'all'); mkdirSync(dir); execSync(`cp ${tgz1} ${tgz2} ${dir}/`); const tarballs = loadTarballsFromDir(dir); expect(tarballs).toHaveLength(2); const byName = indexTarballs(tarballs); expect(byName.get('@testorg/foo')).toHaveLength(2); }); test('buildPackument emits dist-tags.latest and full version map', () => { const tgz = packFixture('@testorg/foo', '1.2.3'); const filename = tgz.split('/').pop() as string; const meta = loadTarball(tgz, filename); const packument = buildPackument('@testorg/foo', [meta], { registryUrl: 'http://npm-registry.lab', }) as { name: string; 'dist-tags': { latest: string; alpha: string }; versions: Record; }; expect(packument.name).toBe('@testorg/foo'); expect(packument['dist-tags'].latest).toBe('1.2.3'); // alpha resolves to the same single build so `@pkg@alpha` installs work in // the install-sh / bootstrap-apt e2e tests (the install paths track @alpha). expect(packument['dist-tags'].alpha).toBe('1.2.3'); expect(packument.versions['1.2.3'].dist.tarball).toBe( `http://npm-registry.lab/@testorg/foo/-/${filename}`, ); expect(packument.versions['1.2.3'].dist.integrity).toMatch(/^sha512-/); }); });