| 14 | } from '../src/library.js'; |
| 15 | |
| 16 | async function withLibraryRoot(fn: (root: string, home: string) => Promise<void>): Promise<void> { |
| 17 | const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ft-library-')); |
| 18 | const root = path.join(tmp, 'library'); |
| 19 | const home = path.join(tmp, 'home'); |
| 20 | const previous = { |
| 21 | FT_LIBRARY_DIR: process.env.FT_LIBRARY_DIR, |
| 22 | HOME: process.env.HOME, |
| 23 | }; |
| 24 | process.env.FT_LIBRARY_DIR = root; |
| 25 | process.env.HOME = home; |
| 26 | try { |
| 27 | await fn(root, home); |
| 28 | } finally { |
| 29 | if (previous.FT_LIBRARY_DIR === undefined) delete process.env.FT_LIBRARY_DIR; |
| 30 | else process.env.FT_LIBRARY_DIR = previous.FT_LIBRARY_DIR; |
| 31 | if (previous.HOME === undefined) delete process.env.HOME; |
| 32 | else process.env.HOME = previous.HOME; |
| 33 | fs.rmSync(tmp, { recursive: true, force: true }); |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | test('library CRUD stays under canonical library root and uses conflict guards', async () => { |
| 38 | await withLibraryRoot(async (root, home) => { |