35 lines
2.1 KiB
JavaScript
35 lines
2.1 KiB
JavaScript
import {test} from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {mkdtemp,mkdir,writeFile,readFile,rm,symlink,realpath,lstat} from 'node:fs/promises';
|
|
import {join} from 'node:path';
|
|
import {tmpdir} from 'node:os';
|
|
import {copyReleaseTree} from '../scripts/copy-release-tree.mjs';
|
|
|
|
test('copyReleaseTree rewrites absolute in-tree links into relocatable relative links',async t=>{
|
|
const root=await mkdtemp(join(tmpdir(),'91-copy-tree-'));t.after(()=>rm(root,{recursive:true,force:true}));
|
|
const source=join(root,'standalone'),dest=join(root,'release');
|
|
await mkdir(join(source,'.pnpm/pkg@1/node_modules/pkg'),{recursive:true});
|
|
await writeFile(join(source,'.pnpm/pkg@1/node_modules/pkg/index.js'),'module.exports=1;');
|
|
await mkdir(join(source,'node_modules'),{recursive:true});
|
|
// Absolute link back into the standalone tree (what Node cp would preserve).
|
|
await symlink(join(source,'.pnpm/pkg@1/node_modules/pkg'),join(source,'node_modules/pkg'));
|
|
await copyReleaseTree(source,dest,{root});
|
|
const link=join(dest,'node_modules/pkg');
|
|
assert.ok((await lstat(link)).isSymbolicLink());
|
|
assert.equal(await readFile(join(link,'index.js'),'utf8'),'module.exports=1;');
|
|
const resolved=await realpath(link),releaseRoot=await realpath(dest);
|
|
assert.ok(resolved===releaseRoot||resolved.startsWith(releaseRoot+'/'));
|
|
assert.equal(await readFile(join(resolved,'index.js'),'utf8'),'module.exports=1;');
|
|
});
|
|
|
|
test('copyReleaseTree rejects symlinks that escape the project root',async t=>{
|
|
const root=await mkdtemp(join(tmpdir(),'91-copy-escape-'));t.after(()=>rm(root,{recursive:true,force:true}));
|
|
const outside=await mkdtemp(join(tmpdir(),'91-outside-'));t.after(()=>rm(outside,{recursive:true,force:true}));
|
|
await writeFile(join(outside,'secret'),'nope');
|
|
const source=join(root,'standalone'),dest=join(root,'release');
|
|
await mkdir(join(source,'node_modules'),{recursive:true});
|
|
await writeFile(join(source,'ok.js'),'1');
|
|
await symlink(join(outside,'secret'),join(source,'node_modules/escape'));
|
|
await assert.rejects(copyReleaseTree(source,dest,{root}),/Release source contains a symbolic link/);
|
|
});
|