// Auto-generated by scripts/gen_parity_tests.py from docs/runtime-parity.md.
// Module: node:fs
// This file is a byte-for-byte parity test against `node --experimental-strip-types`.
// Edit the TODO lines below to exercise each API; rerun
// `./run_parity_tests.sh --filter test_parity_fs` to verify.

import * as fs from "node:fs";

// ────────────────────────────────────────────────────────────────
// Setup — deterministic fixture files under /tmp.
// ────────────────────────────────────────────────────────────────
const BASE = "/tmp/perry_fs_parity";
try {
  fs.rmSync(BASE, { recursive: true, force: true });
} catch (e) {
  console.log("setup rmSync ERROR:", (e as Error).message);
}
try {
  fs.mkdirSync(BASE, { recursive: true });
  fs.writeFileSync(BASE + "/seed.txt", "hello world");
  fs.writeFileSync(BASE + "/a.txt", "alpha");
  fs.writeFileSync(BASE + "/b.txt", "bravo");
  fs.mkdirSync(BASE + "/sub", { recursive: true });
  fs.writeFileSync(BASE + "/sub/c.txt", "charlie");
} catch (e) {
  console.log("setup ERROR:", (e as Error).message);
}

// ── Functions (Callback API) ──
// We mostly probe typeof to keep output deterministic; a few are exercised
// with explicit promise wrapping where the result is stable.

console.log("typeof fs.access:", typeof fs.access);
console.log("typeof fs.appendFile:", typeof fs.appendFile);
console.log("typeof fs.chmod:", typeof fs.chmod);
console.log("typeof fs.chown:", typeof fs.chown);
console.log("typeof fs.close:", typeof fs.close);
console.log("typeof fs.copyFile:", typeof fs.copyFile);
console.log("typeof fs.cp:", typeof fs.cp);
console.log("typeof fs.createReadStream:", typeof fs.createReadStream);
console.log("typeof fs.createWriteStream:", typeof fs.createWriteStream);
console.log("typeof fs.exists:", typeof fs.exists);
console.log("typeof fs.fchmod:", typeof fs.fchmod);
console.log("typeof fs.fchown:", typeof fs.fchown);
console.log("typeof fs.fdatasync:", typeof fs.fdatasync);
console.log("typeof fs.fstat:", typeof fs.fstat);
console.log("typeof fs.fsync:", typeof fs.fsync);
console.log("typeof fs.ftruncate:", typeof fs.ftruncate);
console.log("typeof fs.futimes:", typeof fs.futimes);
console.log("typeof fs.glob:", typeof fs.glob);
console.log("typeof fs.lchmod:", typeof fs.lchmod);
console.log("typeof fs.lchown:", typeof fs.lchown);
console.log("typeof fs.link:", typeof fs.link);
console.log("typeof fs.lstat:", typeof fs.lstat);
console.log("typeof fs.lutimes:", typeof fs.lutimes);
console.log("typeof fs.mkdir:", typeof fs.mkdir);
console.log("typeof fs.mkdtemp:", typeof fs.mkdtemp);
console.log("typeof fs.open:", typeof fs.open);
console.log("typeof fs.openAsBlob:", typeof fs.openAsBlob);
console.log("typeof fs.opendir:", typeof fs.opendir);
console.log("typeof fs.read:", typeof fs.read);
console.log("typeof fs.readdir:", typeof fs.readdir);
console.log("typeof fs.readFile:", typeof fs.readFile);
console.log("typeof fs.readlink:", typeof fs.readlink);
console.log("typeof fs.readv:", typeof fs.readv);
console.log("typeof fs.realpath:", typeof fs.realpath);
console.log("typeof fs.realpath.native:", typeof (fs.realpath as any)?.native);
console.log("typeof fs.rename:", typeof fs.rename);
console.log("typeof fs.rm:", typeof fs.rm);
console.log("typeof fs.rmdir:", typeof fs.rmdir);
console.log("typeof fs.stat:", typeof fs.stat);
console.log("typeof fs.statfs:", typeof fs.statfs);
console.log("typeof fs.symlink:", typeof fs.symlink);
console.log("typeof fs.truncate:", typeof fs.truncate);
console.log("typeof fs.unlink:", typeof fs.unlink);
// SKIP: fs.unwatchFile(filename[, listener]) — Counterpart to watchFile.
console.log("typeof fs.utimes:", typeof fs.utimes);
// SKIP: fs.watch(filename[, options][, listener]) — Filesystem-event timing is non-deterministic; not parity-testable.
// SKIP: fs.watchFile(filename[, options], listener) — Polling-based watch; non-deterministic event timing.
console.log("typeof fs.write:", typeof fs.write);
console.log("typeof fs.writeFile:", typeof fs.writeFile);
console.log("typeof fs.writev:", typeof fs.writev);

// Exercise a few callback APIs via promise wrappers to confirm behavior.
try {
  await new Promise<void>((resolve) => {
    fs.readFile(BASE + "/seed.txt", "utf8", (err, data) => {
      if (err) {
        console.log("fs.readFile cb ERROR:", err.message);
      } else {
        console.log("fs.readFile cb:", data);
      }
      resolve();
    });
  });
} catch (e) {
  console.log("readFile cb section ERROR:", (e as Error).message);
}

try {
  await new Promise<void>((resolve) => {
    fs.access(BASE + "/seed.txt", fs.constants.F_OK, (err) => {
      console.log("fs.access cb err:", err === null);
      resolve();
    });
  });
} catch (e) {
  console.log("access cb section ERROR:", (e as Error).message);
}

try {
  await new Promise<void>((resolve) => {
    fs.stat(BASE + "/seed.txt", (err, st) => {
      if (err) {
        console.log("fs.stat cb ERROR:", err.message);
      } else {
        console.log("fs.stat cb size:", st.size, "isFile:", st.isFile());
      }
      resolve();
    });
  });
} catch (e) {
  console.log("stat cb section ERROR:", (e as Error).message);
}

try {
  await new Promise<void>((resolve) => {
    fs.readdir(BASE, (err, entries) => {
      if (err) {
        console.log("fs.readdir cb ERROR:", err.message);
      } else {
        console.log("fs.readdir cb:", entries.slice().sort());
      }
      resolve();
    });
  });
} catch (e) {
  console.log("readdir cb section ERROR:", (e as Error).message);
}

// ── Functions (Sync API) ──
try {
  fs.accessSync(BASE + "/seed.txt", fs.constants.F_OK);
  console.log("fs.accessSync: ok");
} catch (e) {
  console.log("fs.accessSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/append.txt";
  fs.writeFileSync(p, "hi");
  fs.appendFileSync(p, " there");
  console.log("fs.appendFileSync:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("appendFileSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/chmod.txt";
  fs.writeFileSync(p, "x");
  fs.chmodSync(p, 0o644);
  const st = fs.statSync(p);
  console.log("fs.chmodSync mode:", (st.mode & 0o777).toString(8));
} catch (e) {
  console.log("chmodSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/chown.txt";
  fs.writeFileSync(p, "x");
  const st = fs.statSync(p);
  fs.chownSync(p, st.uid, st.gid);
  console.log("fs.chownSync: ok");
} catch (e) {
  console.log("chownSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/close.txt", "w");
  fs.closeSync(fd);
  console.log("fs.closeSync: ok");
} catch (e) {
  console.log("closeSync ERROR:", (e as Error).message);
}

try {
  fs.writeFileSync(BASE + "/cp_src.txt", "copyme");
  fs.copyFileSync(BASE + "/cp_src.txt", BASE + "/cp_dst.txt");
  console.log("fs.copyFileSync:", fs.readFileSync(BASE + "/cp_dst.txt", "utf8"));
} catch (e) {
  console.log("copyFileSync ERROR:", (e as Error).message);
}

try {
  fs.mkdirSync(BASE + "/cp_dir_src", { recursive: true });
  fs.writeFileSync(BASE + "/cp_dir_src/file.txt", "tree");
  fs.cpSync(BASE + "/cp_dir_src", BASE + "/cp_dir_dst", { recursive: true });
  console.log("fs.cpSync:", fs.readFileSync(BASE + "/cp_dir_dst/file.txt", "utf8"));
} catch (e) {
  console.log("cpSync ERROR:", (e as Error).message);
}

try {
  console.log("fs.existsSync hit:", fs.existsSync(BASE + "/seed.txt"));
  console.log("fs.existsSync miss:", fs.existsSync(BASE + "/no-such-file"));
} catch (e) {
  console.log("existsSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  fs.fchmodSync(fd, 0o644);
  fs.closeSync(fd);
  console.log("fs.fchmodSync: ok");
} catch (e) {
  console.log("fchmodSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  const st = fs.fstatSync(fd);
  fs.fchownSync(fd, st.uid, st.gid);
  fs.closeSync(fd);
  console.log("fs.fchownSync: ok");
} catch (e) {
  console.log("fchownSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/fdatasync.txt", "w");
  fs.writeSync(fd, "x");
  fs.fdatasyncSync(fd);
  fs.closeSync(fd);
  console.log("fs.fdatasyncSync: ok");
} catch (e) {
  console.log("fdatasyncSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  const st = fs.fstatSync(fd);
  console.log("fs.fstatSync size:", st.size, "isFile:", st.isFile());
  fs.closeSync(fd);
} catch (e) {
  console.log("fstatSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/fsync.txt", "w");
  fs.writeSync(fd, "x");
  fs.fsyncSync(fd);
  fs.closeSync(fd);
  console.log("fs.fsyncSync: ok");
} catch (e) {
  console.log("fsyncSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/ftrunc.txt";
  fs.writeFileSync(p, "abcdefghij");
  const fd = fs.openSync(p, "r+");
  fs.ftruncateSync(fd, 4);
  fs.closeSync(fd);
  console.log("fs.ftruncateSync:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("ftruncateSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/futimes.txt";
  fs.writeFileSync(p, "x");
  const fd = fs.openSync(p, "r+");
  fs.futimesSync(fd, 1700000000, 1700000000);
  fs.closeSync(fd);
  const st = fs.statSync(p);
  console.log("fs.futimesSync mtimeMs:", st.mtimeMs);
} catch (e) {
  console.log("futimesSync ERROR:", (e as Error).message);
}

try {
  const results = fs.globSync(BASE + "/*.txt");
  console.log("fs.globSync count:", results.length, "type:", typeof results);
} catch (e) {
  console.log("globSync ERROR:", (e as Error).message);
}

try {
  // lchmod is deprecated and unsupported on most Linux platforms; just probe.
  console.log("typeof fs.lchmodSync:", typeof fs.lchmodSync);
} catch (e) {
  console.log("lchmodSync ERROR:", (e as Error).message);
}

try {
  // lchown is mostly used for symlinks; probe type for portability.
  console.log("typeof fs.lchownSync:", typeof fs.lchownSync);
} catch (e) {
  console.log("lchownSync ERROR:", (e as Error).message);
}

try {
  const p1 = BASE + "/link_src.txt";
  const p2 = BASE + "/link_dst.txt";
  fs.writeFileSync(p1, "linkme");
  fs.linkSync(p1, p2);
  console.log("fs.linkSync:", fs.readFileSync(p2, "utf8"));
} catch (e) {
  console.log("linkSync ERROR:", (e as Error).message);
}

try {
  const st = fs.lstatSync(BASE + "/seed.txt");
  console.log("fs.lstatSync size:", st.size, "isFile:", st.isFile());
} catch (e) {
  console.log("lstatSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/lutimes.txt";
  fs.writeFileSync(p, "x");
  fs.lutimesSync(p, 1700000000, 1700000000);
  console.log("fs.lutimesSync: ok");
} catch (e) {
  console.log("lutimesSync ERROR:", (e as Error).message);
}

try {
  fs.mkdirSync(BASE + "/mkd/a/b/c", { recursive: true });
  console.log("fs.mkdirSync recursive:", fs.existsSync(BASE + "/mkd/a/b/c"));
} catch (e) {
  console.log("mkdirSync ERROR:", (e as Error).message);
}

try {
  const dir = fs.mkdtempSync(BASE + "/tmpdir-");
  console.log("fs.mkdtempSync prefix-ok:", dir.startsWith(BASE + "/tmpdir-"));
} catch (e) {
  console.log("mkdtempSync ERROR:", (e as Error).message);
}

try {
  // Node v22+; may be undefined on older nodes.
  console.log("typeof fs.mkdtempDisposableSync:", typeof (fs as any).mkdtempDisposableSync);
} catch (e) {
  console.log("mkdtempDisposableSync ERROR:", (e as Error).message);
}

try {
  const d = fs.opendirSync(BASE);
  console.log("fs.opendirSync path:", d.path);
  d.closeSync();
} catch (e) {
  console.log("opendirSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  console.log("fs.openSync fd-is-number:", typeof fd === "number");
  fs.closeSync(fd);
} catch (e) {
  console.log("openSync ERROR:", (e as Error).message);
}

try {
  const entries = fs.readdirSync(BASE);
  console.log("fs.readdirSync count >= 4:", entries.length >= 4);
} catch (e) {
  console.log("readdirSync ERROR:", (e as Error).message);
}

try {
  console.log("fs.readFileSync utf8:", fs.readFileSync(BASE + "/seed.txt", "utf8"));
  const buf = fs.readFileSync(BASE + "/seed.txt");
  console.log("fs.readFileSync buf hex:", buf.toString("hex"));
} catch (e) {
  console.log("readFileSync ERROR:", (e as Error).message);
}

try {
  const target = BASE + "/seed.txt";
  const linkPath = BASE + "/seed-link";
  try { fs.unlinkSync(linkPath); } catch {}
  fs.symlinkSync(target, linkPath);
  console.log("fs.readlinkSync:", fs.readlinkSync(linkPath));
} catch (e) {
  console.log("readlinkSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  const buf = Buffer.alloc(5);
  const n = fs.readSync(fd, buf, 0, 5, 0);
  console.log("fs.readSync n:", n, "data:", buf.toString("utf8"));
  fs.closeSync(fd);
} catch (e) {
  console.log("readSync ERROR:", (e as Error).message);
}

try {
  const fd = fs.openSync(BASE + "/seed.txt", "r");
  const b1 = Buffer.alloc(5);
  const b2 = Buffer.alloc(6);
  const n = fs.readvSync(fd, [b1, b2], 0);
  console.log("fs.readvSync n:", n, "b1:", b1.toString("utf8"), "b2:", b2.toString("utf8"));
  fs.closeSync(fd);
} catch (e) {
  console.log("readvSync ERROR:", (e as Error).message);
}

try {
  const rp = fs.realpathSync(BASE + "/seed.txt");
  console.log("fs.realpathSync ends-with seed.txt:", rp.endsWith("/seed.txt"));
} catch (e) {
  console.log("realpathSync ERROR:", (e as Error).message);
}

try {
  const nat = (fs.realpathSync as any)?.native;
  if (typeof nat === "function") {
    const rp = nat(BASE + "/seed.txt");
    console.log("fs.realpathSync.native ends-with seed.txt:", rp.endsWith("/seed.txt"));
  } else {
    console.log("fs.realpathSync.native: not-a-function");
  }
} catch (e) {
  console.log("realpathSync.native ERROR:", (e as Error).message);
}

try {
  const a = BASE + "/rename_a.txt";
  const b = BASE + "/rename_b.txt";
  fs.writeFileSync(a, "renameme");
  fs.renameSync(a, b);
  console.log("fs.renameSync:", fs.readFileSync(b, "utf8"));
} catch (e) {
  console.log("renameSync ERROR:", (e as Error).message);
}

try {
  fs.mkdirSync(BASE + "/rmdir-target", { recursive: true });
  fs.rmdirSync(BASE + "/rmdir-target");
  console.log("fs.rmdirSync ok-gone:", !fs.existsSync(BASE + "/rmdir-target"));
} catch (e) {
  console.log("rmdirSync ERROR:", (e as Error).message);
}

try {
  fs.mkdirSync(BASE + "/rm-target/x", { recursive: true });
  fs.writeFileSync(BASE + "/rm-target/x/y.txt", "y");
  fs.rmSync(BASE + "/rm-target", { recursive: true, force: true });
  console.log("fs.rmSync ok-gone:", !fs.existsSync(BASE + "/rm-target"));
} catch (e) {
  console.log("rmSync ERROR:", (e as Error).message);
}

try {
  const st = fs.statSync(BASE + "/seed.txt");
  console.log("fs.statSync size:", st.size, "isFile:", st.isFile(), "isDirectory:", st.isDirectory());
} catch (e) {
  console.log("statSync ERROR:", (e as Error).message);
}

try {
  const sf = fs.statfsSync(BASE);
  console.log("fs.statfsSync bsize-is-number:", typeof sf.bsize === "number");
} catch (e) {
  console.log("statfsSync ERROR:", (e as Error).message);
}

try {
  const target = BASE + "/seed.txt";
  const linkPath = BASE + "/seed-sym";
  try { fs.unlinkSync(linkPath); } catch {}
  fs.symlinkSync(target, linkPath);
  console.log("fs.symlinkSync:", fs.readlinkSync(linkPath));
} catch (e) {
  console.log("symlinkSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/trunc.txt";
  fs.writeFileSync(p, "abcdefghij");
  fs.truncateSync(p, 3);
  console.log("fs.truncateSync:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("truncateSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/unlink.txt";
  fs.writeFileSync(p, "bye");
  fs.unlinkSync(p);
  console.log("fs.unlinkSync ok-gone:", !fs.existsSync(p));
} catch (e) {
  console.log("unlinkSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/utimes.txt";
  fs.writeFileSync(p, "x");
  fs.utimesSync(p, 1700000000, 1700000000);
  const st = fs.statSync(p);
  console.log("fs.utimesSync mtimeMs:", st.mtimeMs);
} catch (e) {
  console.log("utimesSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/writeFile.txt";
  fs.writeFileSync(p, "perry-write");
  console.log("fs.writeFileSync:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("writeFileSync ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/writeSync.txt";
  const fd = fs.openSync(p, "w");
  const n = fs.writeSync(fd, "abc-buf");
  fs.closeSync(fd);
  console.log("fs.writeSync n:", n, "data:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("writeSync(string) ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/writeSyncBuf.txt";
  const fd = fs.openSync(p, "w");
  const buf = Buffer.from("buf-data");
  const n = fs.writeSync(fd, buf, 0, buf.length, 0);
  fs.closeSync(fd);
  console.log("fs.writeSync(buf) n:", n, "data:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("writeSync(buf) ERROR:", (e as Error).message);
}

try {
  const p = BASE + "/writev.txt";
  const fd = fs.openSync(p, "w");
  const b1 = Buffer.from("foo-");
  const b2 = Buffer.from("bar");
  const n = fs.writevSync(fd, [b1, b2], 0);
  fs.closeSync(fd);
  console.log("fs.writevSync n:", n, "data:", fs.readFileSync(p, "utf8"));
} catch (e) {
  console.log("writevSync ERROR:", (e as Error).message);
}

// ── Streams ──
// We synchronously probe shape immediately after create then destroy. When the
// underlying fs.createReadStream / createWriteStream is missing (returns
// undefined), the shape reads return undefined; when present, properties like
// `path`, `pending`, and `bytesRead`/`bytesWritten` should match Node.
// PERRY-SKIP: awaiting the 'open' / 'close' events hangs Perry's event loop;
// uncomment the awaited form below when createReadStream/createWriteStream are
// wired with proper event emission.
try {
  const rs = (fs as any).createReadStream
    ? (fs as any).createReadStream(BASE + "/seed.txt")
    : undefined;
  if (rs) {
    console.log("fs.createReadStream path:", rs.path);
    console.log("fs.createReadStream pending:", rs.pending);
    console.log("fs.createReadStream bytesRead is number:", typeof rs.bytesRead === "number");
    rs.on?.("error", () => {});
    rs.destroy?.();
  } else {
    console.log("fs.createReadStream: missing");
  }
} catch (e) {
  console.log("createReadStream ERROR:", (e as Error).message);
}

try {
  const ws = (fs as any).createWriteStream
    ? (fs as any).createWriteStream(BASE + "/ws.txt")
    : undefined;
  if (ws) {
    console.log("fs.createWriteStream path:", ws.path);
    console.log("fs.createWriteStream pending:", ws.pending);
    console.log("fs.createWriteStream bytesWritten is number:", typeof ws.bytesWritten === "number");
    ws.on?.("error", () => {});
    ws.destroy?.();
  } else {
    console.log("fs.createWriteStream: missing");
  }
} catch (e) {
  console.log("createWriteStream ERROR:", (e as Error).message);
}

// ── Classes ──
try {
  const d = fs.opendirSync(BASE);
  console.log("class fs.Dir path:", d.path);
  let count = 0;
  // Walk via repeated readSync to keep output deterministic.
  while (true) {
    const e = d.readSync();
    if (e === null) break;
    count++;
  }
  console.log("class fs.Dir entries-found:", count >= 4);
  d.closeSync();
} catch (e) {
  console.log("class fs.Dir ERROR:", (e as Error).message);
}

try {
  // Dirent surface — exercised through readdirSync withFileTypes.
  const ents = fs.readdirSync(BASE, { withFileTypes: true }).slice().sort((a, b) => a.name.localeCompare(b.name));
  let seed: fs.Dirent | undefined;
  for (const ent of ents) {
    if (ent.name === "seed.txt") { seed = ent; break; }
  }
  if (!seed) {
    console.log("Dirent seed.txt: not-found");
  } else {
    try { console.log("Dirent seed.txt name:", seed.name); } catch (e) { console.log("Dirent name ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isFile:", seed.isFile()); } catch (e) { console.log("Dirent isFile ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isDirectory:", seed.isDirectory()); } catch (e) { console.log("Dirent isDirectory ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isBlockDevice:", seed.isBlockDevice()); } catch (e) { console.log("Dirent isBlockDevice ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isCharacterDevice:", seed.isCharacterDevice()); } catch (e) { console.log("Dirent isCharacterDevice ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isFIFO:", seed.isFIFO()); } catch (e) { console.log("Dirent isFIFO ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isSocket:", seed.isSocket()); } catch (e) { console.log("Dirent isSocket ERROR:", (e as Error).message); }
    try { console.log("Dirent seed.txt isSymbolicLink:", seed.isSymbolicLink()); } catch (e) { console.log("Dirent isSymbolicLink ERROR:", (e as Error).message); }
  }
} catch (e) {
  console.log("Dirent ERROR:", (e as Error).message);
}

// ── Constants ──
console.log("fs.constants.F_OK:", fs.constants.F_OK);
console.log("fs.constants.R_OK:", fs.constants.R_OK);
console.log("fs.constants.W_OK:", fs.constants.W_OK);
console.log("fs.constants.X_OK:", fs.constants.X_OK);
console.log("fs.constants.O_RDONLY:", fs.constants.O_RDONLY);
console.log("fs.constants.O_WRONLY:", fs.constants.O_WRONLY);
console.log("fs.constants.O_RDWR:", fs.constants.O_RDWR);
console.log("fs.constants.O_CREAT:", fs.constants.O_CREAT);
console.log("fs.constants.O_EXCL:", fs.constants.O_EXCL);
console.log("fs.constants.O_TRUNC:", fs.constants.O_TRUNC);
console.log("fs.constants.O_APPEND:", fs.constants.O_APPEND);
console.log("fs.constants.O_DIRECTORY:", fs.constants.O_DIRECTORY);
console.log("fs.constants.O_NOATIME:", fs.constants.O_NOATIME);
console.log("fs.constants.O_NOFOLLOW:", fs.constants.O_NOFOLLOW);
console.log("fs.constants.O_SYNC:", fs.constants.O_SYNC);
console.log("fs.constants.O_DSYNC:", fs.constants.O_DSYNC);
console.log("fs.constants.O_SYMLINK:", fs.constants.O_SYMLINK);
console.log("fs.constants.O_DIRECT:", fs.constants.O_DIRECT);
console.log("fs.constants.O_NONBLOCK:", fs.constants.O_NONBLOCK);
console.log("fs.constants.S_IFMT:", fs.constants.S_IFMT);
console.log("fs.constants.S_IFREG:", fs.constants.S_IFREG);
console.log("fs.constants.S_IFDIR:", fs.constants.S_IFDIR);
console.log("fs.constants.S_IFCHR:", fs.constants.S_IFCHR);
console.log("fs.constants.S_IFBLK:", fs.constants.S_IFBLK);
console.log("fs.constants.S_IFIFO:", fs.constants.S_IFIFO);
console.log("fs.constants.S_IFLNK:", fs.constants.S_IFLNK);
console.log("fs.constants.S_IFSOCK:", fs.constants.S_IFSOCK);

// ── Cleanup ──
try {
  fs.rmSync(BASE, { recursive: true, force: true });
  console.log("cleanup: ok");
} catch (e) {
  console.log("cleanup ERROR:", (e as Error).message);
}
