// A scratch tree per test: a copy of this package's src/ under // /packages/plugins, plus fixture modules. The loader finds modules // from its own location, so each tree's copy loads only that tree's modules. import { cpSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; export const SRC = resolve(dirname(fileURLToPath(import.meta.url)), "..", "src"); export const USAGE = name => `export const interfaceVersion = 1; export function readTurn() { return ${JSON.stringify(name)}; } `; export const LIMIT = name => `export const interfaceVersion = 2; export function mayLaunch() { return ${JSON.stringify(name)}; } export function mustStop() { return false; } export function report() { return []; } `; // A version 1 limit check (before row 125): the loader refuses it. export const LIMIT_V1 = name => `export const interfaceVersion = 1; export function mayLaunch() { return ${JSON.stringify(name)}; } export function mustStop() { return false; } `; export function tree(t) { const root = mkdtempSync(join(tmpdir(), "mosaic-plugins-")); t.after(() => rmSync(root, { recursive: true, force: true })); const pkg = join(root, "packages", "plugins"); cpSync(SRC, join(pkg, "src"), { recursive: true }); const write = (kind, name, body) => { const dir = join(pkg, kind, name); mkdirSync(dir, { recursive: true }); writeFileSync(join(dir, "index.mjs"), body); return dir; }; const loaderUrl = pathToFileURL(join(pkg, "src", "loader.mjs")).href; async function loader(options = {}) { const { createLoader } = await import(loaderUrl); const logged = []; const instance = createLoader({ log: entry => logged.push(entry), ...options }); return { ...instance, logged }; } return { root, pkg, write, loader, loaderUrl }; }