@ai-ecoverse/slicc-jsh 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.mjs CHANGED
@@ -1539,7 +1539,7 @@ ${e3}`;
1539
1539
  // package.json
1540
1540
  var package_default = {
1541
1541
  name: "@ai-ecoverse/slicc-jsh",
1542
- version: "0.3.7",
1542
+ version: "0.3.8",
1543
1543
  description: "Node.js-compatible runtime for slicc-kernel: the node and jsh commands (abi: js)",
1544
1544
  type: "module",
1545
1545
  license: "Apache-2.0",
@@ -1609,7 +1609,7 @@ var package_default = {
1609
1609
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
1610
1610
  },
1611
1611
  devDependencies: {
1612
- "@ai-ecoverse/slicc-kernel": "1.63.0",
1612
+ "@ai-ecoverse/slicc-kernel": "1.64.0",
1613
1613
  "@ai-ecoverse/wasi-pnpm": "12.9.1-8",
1614
1614
  "abort-controller": "3.0.0",
1615
1615
  acorn: "8.19.0",
@@ -1751,10 +1751,21 @@ function joinChild(dir, name) {
1751
1751
  if (dir === "/") return `/${name}`;
1752
1752
  return `${dir}/${name}`;
1753
1753
  }
1754
+ function skillRootOf(dir) {
1755
+ if (!dir) return dir;
1756
+ const absolute = dir.startsWith("/");
1757
+ const parts = dir.split("/").filter(Boolean);
1758
+ const at2 = parts.lastIndexOf("scripts");
1759
+ if (at2 < 0) return dir;
1760
+ const rootParts = parts.slice(0, at2);
1761
+ if (rootParts.length === 0) return absolute ? "/" : "";
1762
+ return (absolute ? "/" : "") + rootParts.join("/");
1763
+ }
1754
1764
  function createSkill({ argv, fs, exec }) {
1755
1765
  const dir = dirnameOf(argv[1] ?? "");
1756
- const refs = joinChild(dir, "references");
1757
- const assets = joinChild(dir, "assets");
1766
+ const root = skillRootOf(dir);
1767
+ const refs = joinChild(root, "references");
1768
+ const assets = joinChild(root, "assets");
1758
1769
  const configPath = joinChild(dir, ".config");
1759
1770
  async function readConfig() {
1760
1771
  let text;
@@ -1796,7 +1807,7 @@ function createSkill({ argv, fs, exec }) {
1796
1807
  }
1797
1808
  return stdout.replace(/\r?\n+$/, "");
1798
1809
  }
1799
- return Object.freeze({ dir, refs, assets, config, token });
1810
+ return Object.freeze({ dir, root, refs, assets, config, token });
1800
1811
  }
1801
1812
 
1802
1813
  // src/jsh/sliccy/http.mjs
@@ -10761,6 +10772,27 @@ function createEvents() {
10761
10772
  }
10762
10773
 
10763
10774
  // src/runtime/builtins/child-process.mjs
10775
+ var PROMISIFY_CUSTOM2 = /* @__PURE__ */ Symbol.for("nodejs.util.promisify.custom");
10776
+ function customPromiseExecFunction(orig) {
10777
+ return function(...args) {
10778
+ let resolve2;
10779
+ let reject;
10780
+ const promise = new Promise((res, rej) => {
10781
+ resolve2 = res;
10782
+ reject = rej;
10783
+ });
10784
+ promise.child = orig(...args, (err, stdout, stderr) => {
10785
+ if (err != null) {
10786
+ err.stdout = stdout;
10787
+ err.stderr = stderr;
10788
+ reject(err);
10789
+ } else {
10790
+ resolve2({ stdout, stderr });
10791
+ }
10792
+ });
10793
+ return promise;
10794
+ };
10795
+ }
10764
10796
  var SIGNAL_NAMES = {
10765
10797
  1: "SIGHUP",
10766
10798
  2: "SIGINT",
@@ -11250,6 +11282,14 @@ function createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles,
11250
11282
  const cmd = String(command);
11251
11283
  return execFile(shell, ["-c", cmd], { ...opts, shell: false, _execCmd: cmd }, cb);
11252
11284
  }
11285
+ Object.defineProperty(exec, PROMISIFY_CUSTOM2, {
11286
+ enumerable: false,
11287
+ value: customPromiseExecFunction(exec)
11288
+ });
11289
+ Object.defineProperty(execFile, PROMISIFY_CUSTOM2, {
11290
+ enumerable: false,
11291
+ value: customPromiseExecFunction(execFile)
11292
+ });
11253
11293
  return {
11254
11294
  spawn,
11255
11295
  execFile,
@@ -11273,10 +11313,404 @@ function createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles,
11273
11313
  };
11274
11314
  }
11275
11315
 
11316
+ // src/runtime/builtins/fs-cp.mjs
11317
+ var ERRNO = { EEXIST: 17, ENOTDIR: 20, EISDIR: 21, EINVAL: 22 };
11318
+ var SYSTEM_ERROR_PREFIX = {
11319
+ ERR_FS_CP_DIR_TO_NON_DIR: "Cannot overwrite non-directory with directory",
11320
+ ERR_FS_CP_EEXIST: "Target already exists",
11321
+ ERR_FS_CP_EINVAL: "Invalid src or dest",
11322
+ ERR_FS_CP_NON_DIR_TO_DIR: "Cannot overwrite directory with non-directory",
11323
+ ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY: "Cannot overwrite symlink in subdirectory of self",
11324
+ ERR_FS_EISDIR: "Path is a directory"
11325
+ };
11326
+ function systemError(key, { message, path, code }) {
11327
+ const err = new Error(
11328
+ `${SYSTEM_ERROR_PREFIX[key]}: cp returned ${code} (${message})${path === void 0 ? "" : ` ${path}`}`
11329
+ );
11330
+ err.name = "SystemError";
11331
+ err.code = key;
11332
+ err.errno = ERRNO[code];
11333
+ err.syscall = "cp";
11334
+ if (path !== void 0) err.path = path;
11335
+ err.info = { code, message, path, syscall: "cp", errno: ERRNO[code] };
11336
+ return err;
11337
+ }
11338
+ function nativeError(code, message) {
11339
+ const err = new Error(message);
11340
+ err.code = code;
11341
+ return err;
11342
+ }
11343
+ function invalidFilterReturn() {
11344
+ const err = new TypeError(
11345
+ 'Expected boolean to be returned from the "filter" function but got an instance of Promise.'
11346
+ );
11347
+ err.code = "ERR_INVALID_RETURN_VALUE";
11348
+ return err;
11349
+ }
11350
+ var isPromise = (v) => v != null && typeof v.then === "function";
11351
+ function createCp({ path, ops, abs, fsError, copyFileSync, mkdirpSync }) {
11352
+ const tryCall = (fn) => {
11353
+ try {
11354
+ return fn();
11355
+ } catch {
11356
+ return null;
11357
+ }
11358
+ };
11359
+ const call = (fn, syscall, pathArg, dest) => {
11360
+ try {
11361
+ return fn();
11362
+ } catch (err) {
11363
+ if (err?.syscall) throw err;
11364
+ throw fsError(err?.code || "EIO", syscall, pathArg, err, dest);
11365
+ }
11366
+ };
11367
+ const lstat = (p) => call(() => ops.lstat(abs(p)), "lstat", p);
11368
+ const stat = (p) => call(() => ops.stat(abs(p)), "stat", p);
11369
+ const readlink = (p) => call(() => ops.readlink(abs(p)), "readlink", p);
11370
+ const symlink = (target, p) => call(() => ops.symlink(target, abs(p)), "symlink", target, p);
11371
+ const unlink = (p) => call(() => ops.unlink(abs(p)), "unlink", p);
11372
+ const readdir = (p) => call(() => ops.readdir(abs(p)), "scandir", p);
11373
+ const exists = (p) => !!tryCall(() => ops.stat(abs(p)));
11374
+ const MAX_LINKS = 40;
11375
+ function realpathSync(p) {
11376
+ let resolved = path.resolve(String(p));
11377
+ const knownHard = /* @__PURE__ */ new Set();
11378
+ let hops = 0;
11379
+ let current2 = "/";
11380
+ let pos = 1;
11381
+ while (pos < resolved.length) {
11382
+ const next = resolved.indexOf("/", pos);
11383
+ const part = next === -1 ? resolved.slice(pos) : resolved.slice(pos, next);
11384
+ pos = next === -1 ? resolved.length : next + 1;
11385
+ if (!part) continue;
11386
+ const previous = current2;
11387
+ const base = current2 === "/" ? `/${part}` : `${current2}/${part}`;
11388
+ current2 = base;
11389
+ if (knownHard.has(base)) continue;
11390
+ const st = call(() => ops.lstat(base), "lstat", base);
11391
+ if (!st.isSymbolicLink) {
11392
+ knownHard.add(base);
11393
+ continue;
11394
+ }
11395
+ if (++hops > MAX_LINKS) throw fsError("ELOOP", "stat", base);
11396
+ call(() => ops.stat(base), "stat", base);
11397
+ const target = call(() => ops.readlink(base), "readlink", base);
11398
+ resolved = path.resolve(previous, target, resolved.slice(pos));
11399
+ current2 = "/";
11400
+ pos = 1;
11401
+ }
11402
+ return resolved;
11403
+ }
11404
+ function weaklyCanonical(p) {
11405
+ const parts = path.resolve(p).split("/").filter(Boolean);
11406
+ for (let i2 = parts.length; i2 > 0; i2--) {
11407
+ const prefix = `/${parts.slice(0, i2).join("/")}`;
11408
+ if (!exists(prefix)) continue;
11409
+ const real = tryCall(() => realpathSync(prefix)) ?? prefix;
11410
+ return path.join(real, ...parts.slice(i2));
11411
+ }
11412
+ return path.resolve(p);
11413
+ }
11414
+ const equivalent = (a, b) => {
11415
+ if (!exists(a) || !exists(b)) return false;
11416
+ return tryCall(() => realpathSync(a)) === tryCall(() => realpathSync(b));
11417
+ };
11418
+ const normalizeArray2 = (p) => path.resolve(p).split("/").filter(Boolean);
11419
+ const isSrcSubdir = (src, dest) => {
11420
+ const s = normalizeArray2(src);
11421
+ const d = normalizeArray2(dest);
11422
+ return s.every((cur, i2) => d[i2] === cur);
11423
+ };
11424
+ const withDefaults = (options = {}) => ({
11425
+ dereference: false,
11426
+ errorOnExist: false,
11427
+ force: true,
11428
+ preserveTimestamps: false,
11429
+ recursive: false,
11430
+ verbatimSymlinks: false,
11431
+ mode: 0,
11432
+ ...options
11433
+ });
11434
+ function checkPathsSync(src, dest, dereference, recursive) {
11435
+ const srcSt = call(() => dereference ? ops.lstat(abs(src)) : ops.stat(abs(src)), dereference ? "stat" : "lstat", src);
11436
+ const destSt = tryCall(() => dereference ? ops.stat(abs(dest)) : ops.lstat(abs(dest)));
11437
+ const srcIsDir = !!srcSt.isDirectory || dereference && !!srcSt.isSymbolicLink;
11438
+ if (destSt) {
11439
+ if (equivalent(src, dest)) throw nativeError("ERR_FS_CP_EINVAL", `src and dest cannot be the same ${dest}`);
11440
+ const destIsDir = !!destSt.isDirectory;
11441
+ if (srcIsDir && !destIsDir) {
11442
+ throw nativeError("ERR_FS_CP_DIR_TO_NON_DIR", `Cannot overwrite non-directory ${dest} with directory ${src}`);
11443
+ }
11444
+ if (!srcIsDir && destIsDir) {
11445
+ throw nativeError("ERR_FS_CP_NON_DIR_TO_DIR", `Cannot overwrite directory ${dest} with non-directory ${src}`);
11446
+ }
11447
+ }
11448
+ const srcSlash = src.endsWith("/") ? src : `${src}/`;
11449
+ const subdir = () => nativeError("ERR_FS_CP_EINVAL", `Cannot copy ${srcSlash} to a subdirectory of self ${dest}`);
11450
+ if (srcIsDir && dest.startsWith(srcSlash)) throw subdir();
11451
+ if (path.dirname(src) !== path.dirname(dest) && equivalent(src, path.dirname(dest))) throw subdir();
11452
+ if (srcIsDir && !recursive) {
11453
+ throw nativeError("ERR_FS_EISDIR", `Recursive option not enabled, cannot copy a directory: ${srcSlash}`);
11454
+ }
11455
+ if (!destSt || !exists(path.dirname(dest))) tryCall(() => mkdirpSync(path.dirname(dest)));
11456
+ }
11457
+ function getStatsSync(src, dest, opts) {
11458
+ const srcSt = opts.dereference ? stat(src) : lstat(src);
11459
+ const destSt = tryCall(() => opts.dereference ? ops.stat(abs(dest)) : ops.lstat(abs(dest)));
11460
+ if (srcSt.isDirectory && opts.recursive) return copyDirSync(src, dest, opts, !destSt);
11461
+ if (srcSt.isSymbolicLink) return onLinkSync(destSt, src, dest, opts.verbatimSymlinks);
11462
+ if (!destSt) return copyFileSync(src, dest, opts.mode);
11463
+ if (opts.force) {
11464
+ unlink(dest);
11465
+ return copyFileSync(src, dest, opts.mode);
11466
+ }
11467
+ if (opts.errorOnExist) {
11468
+ throw systemError("ERR_FS_CP_EEXIST", { message: `${dest} already exists`, path: dest, code: "EEXIST" });
11469
+ }
11470
+ return void 0;
11471
+ }
11472
+ function copyDirSync(src, dest, opts, mkDir) {
11473
+ if (!opts.filter) return nativeCopyDir(src, dest, opts);
11474
+ if (mkDir) call(() => ops.mkdir(abs(dest)), "mkdir", dest);
11475
+ for (const name of readdir(src)) {
11476
+ const srcItem = path.join(src, name);
11477
+ const destItem = path.join(dest, name);
11478
+ const shouldCopy = opts.filter(srcItem, destItem);
11479
+ if (isPromise(shouldCopy)) throw invalidFilterReturn();
11480
+ if (shouldCopy) getStatsSync(srcItem, destItem, opts);
11481
+ }
11482
+ return void 0;
11483
+ }
11484
+ function nativeCopyDir(src, dest, opts) {
11485
+ call(() => mkdirpSync(dest), "cp", dest);
11486
+ const walk2 = (srcDir, destDir) => {
11487
+ for (const name of readdir(srcDir)) {
11488
+ const srcItem = path.join(srcDir, name);
11489
+ const destItem = path.join(destDir, name);
11490
+ const st = lstat(srcItem);
11491
+ if (st.isSymbolicLink) {
11492
+ const target = readlink(srcItem);
11493
+ if (opts.verbatimSymlinks) {
11494
+ if (tryCall(() => ops.lstat(abs(destItem)))) throw fsError("EEXIST", "cp", destDir);
11495
+ symlink(target, destItem);
11496
+ continue;
11497
+ }
11498
+ if (exists(destItem)) {
11499
+ const destLink = tryCall(() => ops.lstat(abs(destItem)));
11500
+ if (destLink?.isSymbolicLink) {
11501
+ unlink(destItem);
11502
+ } else if (!stat(destItem).isDirectory) {
11503
+ if (!opts.dereference || !opts.force && opts.errorOnExist) {
11504
+ throw fsError("EEXIST", "cp", destItem);
11505
+ }
11506
+ }
11507
+ } else if (tryCall(() => ops.lstat(abs(destItem)))?.isSymbolicLink) {
11508
+ unlink(destItem);
11509
+ }
11510
+ symlink(weaklyCanonical(path.resolve(srcDir, target)), destItem);
11511
+ } else if (st.isDirectory) {
11512
+ if (!tryCall(() => ops.lstat(abs(destItem)))) call(() => ops.mkdir(abs(destItem)), "cp", destDir);
11513
+ walk2(srcItem, destItem);
11514
+ } else {
11515
+ const there = tryCall(() => ops.lstat(abs(destItem)));
11516
+ if (there) {
11517
+ if (opts.force) {
11518
+ unlink(destItem);
11519
+ } else if (opts.errorOnExist) {
11520
+ throw nativeError(
11521
+ "ERR_FS_CP_EEXIST",
11522
+ `[ERR_FS_CP_EEXIST]: Target already exists: cp returned EEXIST (${destItem} already exists)`
11523
+ );
11524
+ } else {
11525
+ continue;
11526
+ }
11527
+ }
11528
+ copyFileSync(srcItem, destItem);
11529
+ }
11530
+ }
11531
+ };
11532
+ walk2(src, dest);
11533
+ }
11534
+ function onLinkSync(destSt, src, dest, verbatimSymlinks) {
11535
+ let resolvedSrc = readlink(src);
11536
+ if (!verbatimSymlinks && !path.isAbsolute(resolvedSrc)) resolvedSrc = path.resolve(path.dirname(src), resolvedSrc);
11537
+ if (!destSt) return symlink(resolvedSrc, dest);
11538
+ let resolvedDest;
11539
+ try {
11540
+ resolvedDest = readlink(dest);
11541
+ } catch (err) {
11542
+ if (err.code === "EINVAL" || err.code === "UNKNOWN") return symlink(resolvedSrc, dest);
11543
+ throw err;
11544
+ }
11545
+ if (!path.isAbsolute(resolvedDest)) resolvedDest = path.resolve(path.dirname(dest), resolvedDest);
11546
+ if (isSrcSubdir(resolvedSrc, resolvedDest)) {
11547
+ throw systemError("ERR_FS_CP_EINVAL", {
11548
+ message: `cannot copy ${resolvedSrc} to a subdirectory of self ${resolvedDest}`,
11549
+ path: dest,
11550
+ code: "EINVAL"
11551
+ });
11552
+ }
11553
+ if (tryCall(() => ops.stat(abs(dest)))?.isDirectory && isSrcSubdir(resolvedDest, resolvedSrc)) {
11554
+ throw systemError("ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY", {
11555
+ message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
11556
+ path: dest,
11557
+ code: "EINVAL"
11558
+ });
11559
+ }
11560
+ unlink(dest);
11561
+ return symlink(resolvedSrc, dest);
11562
+ }
11563
+ function cpSync(src, dest, options) {
11564
+ const opts = withDefaults(options);
11565
+ src = String(src);
11566
+ dest = String(dest);
11567
+ if (opts.filter) {
11568
+ const shouldCopy = opts.filter(src, dest);
11569
+ if (isPromise(shouldCopy)) throw invalidFilterReturn();
11570
+ if (!shouldCopy) return;
11571
+ }
11572
+ checkPathsSync(src, dest, opts.dereference, opts.recursive);
11573
+ getStatsSync(src, dest, opts);
11574
+ }
11575
+ const sameFile = (a, aPath, b, bPath) => {
11576
+ if (a?.ino && a?.dev && b?.ino && b?.dev) return a.ino === b.ino && a.dev === b.dev;
11577
+ return equivalent(aPath, bPath);
11578
+ };
11579
+ async function cp(src, dest, options) {
11580
+ const opts = withDefaults(options);
11581
+ src = String(src);
11582
+ dest = String(dest);
11583
+ const checked = await checkPaths(src, dest, opts);
11584
+ if (checked.skipped) return;
11585
+ checkParentPaths(src, checked.srcStat, dest);
11586
+ if (!exists(path.dirname(dest))) mkdirpSync(path.dirname(dest));
11587
+ await copyEntry(checked.destStat, src, dest, opts);
11588
+ }
11589
+ async function checkPaths(src, dest, opts) {
11590
+ if (opts.filter && !await opts.filter(src, dest)) return { skipped: true };
11591
+ const statFn = opts.dereference ? stat : lstat;
11592
+ const srcStat = statFn(src);
11593
+ let destStat = null;
11594
+ try {
11595
+ destStat = statFn(dest);
11596
+ } catch (err) {
11597
+ if (err.code !== "ENOENT") throw err;
11598
+ }
11599
+ if (destStat) {
11600
+ if (sameFile(srcStat, src, destStat, dest)) {
11601
+ throw systemError("ERR_FS_CP_EINVAL", { message: "src and dest cannot be the same", path: dest, code: "EINVAL" });
11602
+ }
11603
+ if (srcStat.isDirectory && !destStat.isDirectory) {
11604
+ throw systemError("ERR_FS_CP_DIR_TO_NON_DIR", {
11605
+ message: `cannot overwrite non-directory ${dest} with directory ${src}`,
11606
+ path: dest,
11607
+ code: "EISDIR"
11608
+ });
11609
+ }
11610
+ if (!srcStat.isDirectory && destStat.isDirectory) {
11611
+ throw systemError("ERR_FS_CP_NON_DIR_TO_DIR", {
11612
+ message: `cannot overwrite directory ${dest} with non-directory ${src}`,
11613
+ path: dest,
11614
+ code: "ENOTDIR"
11615
+ });
11616
+ }
11617
+ }
11618
+ if (srcStat.isDirectory && isSrcSubdir(src, dest)) {
11619
+ throw systemError("ERR_FS_CP_EINVAL", {
11620
+ message: `cannot copy ${src} to a subdirectory of self ${dest}`,
11621
+ path: dest,
11622
+ code: "EINVAL"
11623
+ });
11624
+ }
11625
+ return { srcStat, destStat, skipped: false };
11626
+ }
11627
+ function checkParentPaths(src, srcStat, dest) {
11628
+ const srcParent = path.resolve(path.dirname(src));
11629
+ const destParent = path.resolve(path.dirname(dest));
11630
+ if (destParent === srcParent || destParent === "/") return;
11631
+ const destStat = tryCall(() => ops.stat(destParent));
11632
+ if (!destStat) return;
11633
+ const same = sameFile(srcStat, src, destStat, destParent);
11634
+ if (same) {
11635
+ throw systemError("ERR_FS_CP_EINVAL", {
11636
+ message: `cannot copy ${src} to a subdirectory of self ${dest}`,
11637
+ path: dest,
11638
+ code: "EINVAL"
11639
+ });
11640
+ }
11641
+ checkParentPaths(src, srcStat, destParent);
11642
+ }
11643
+ async function copyEntry(destStat, src, dest, opts) {
11644
+ const srcStat = opts.dereference ? stat(src) : lstat(src);
11645
+ if (srcStat.isDirectory && opts.recursive) {
11646
+ if (!destStat) call(() => ops.mkdir(abs(dest)), "mkdir", dest);
11647
+ for (const name of readdir(src)) {
11648
+ const srcItem = path.join(src, name);
11649
+ const destItem = path.join(dest, name);
11650
+ const checked = await checkPaths(srcItem, destItem, opts);
11651
+ if (!checked.skipped) await copyEntry(checked.destStat, srcItem, destItem, opts);
11652
+ }
11653
+ return;
11654
+ }
11655
+ if (srcStat.isDirectory) {
11656
+ throw systemError("ERR_FS_EISDIR", { message: `${src} is a directory (not copied)`, path: src, code: "EISDIR" });
11657
+ }
11658
+ if (srcStat.isSymbolicLink) {
11659
+ let resolvedSrc = readlink(src);
11660
+ if (!opts.verbatimSymlinks && !path.isAbsolute(resolvedSrc)) {
11661
+ resolvedSrc = path.resolve(path.dirname(src), resolvedSrc);
11662
+ }
11663
+ if (!destStat) {
11664
+ symlink(resolvedSrc, dest);
11665
+ return;
11666
+ }
11667
+ let resolvedDest;
11668
+ try {
11669
+ resolvedDest = readlink(dest);
11670
+ } catch (err) {
11671
+ if (err.code === "EINVAL" || err.code === "UNKNOWN") {
11672
+ symlink(resolvedSrc, dest);
11673
+ return;
11674
+ }
11675
+ throw err;
11676
+ }
11677
+ if (!path.isAbsolute(resolvedDest)) resolvedDest = path.resolve(path.dirname(dest), resolvedDest);
11678
+ if (isSrcSubdir(resolvedSrc, resolvedDest)) {
11679
+ throw systemError("ERR_FS_CP_EINVAL", {
11680
+ message: `cannot copy ${resolvedSrc} to a subdirectory of self ${resolvedDest}`,
11681
+ path: dest,
11682
+ code: "EINVAL"
11683
+ });
11684
+ }
11685
+ if (tryCall(() => ops.stat(abs(src)))?.isDirectory && isSrcSubdir(resolvedDest, resolvedSrc)) {
11686
+ throw systemError("ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY", {
11687
+ message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
11688
+ path: dest,
11689
+ code: "EINVAL"
11690
+ });
11691
+ }
11692
+ unlink(dest);
11693
+ symlink(resolvedSrc, dest);
11694
+ return;
11695
+ }
11696
+ if (!destStat) {
11697
+ copyFileSync(src, dest, opts.mode);
11698
+ return;
11699
+ }
11700
+ if (opts.force) {
11701
+ unlink(dest);
11702
+ copyFileSync(src, dest, opts.mode);
11703
+ } else if (opts.errorOnExist) {
11704
+ throw systemError("ERR_FS_CP_EEXIST", { message: `${dest} already exists`, path: dest, code: "EEXIST" });
11705
+ }
11706
+ }
11707
+ return { cpSync, cp, realpathSync, weaklyCanonical };
11708
+ }
11709
+
11276
11710
  // src/runtime/builtins/fs.mjs
11277
11711
  var encoder3 = new TextEncoder();
11278
11712
  var decoder3 = new TextDecoder();
11279
- var ERRNO = {
11713
+ var ERRNO2 = {
11280
11714
  ENOENT: -2,
11281
11715
  EEXIST: -17,
11282
11716
  EISDIR: -21,
@@ -11288,7 +11722,9 @@ var ERRNO = {
11288
11722
  ENOTEMPTY: -39,
11289
11723
  // Linux (the shim's process.platform)
11290
11724
  EBADF: -9,
11291
- ENOTSUP: -45
11725
+ ENOTSUP: -45,
11726
+ EXDEV: -18,
11727
+ ELOOP: -40
11292
11728
  };
11293
11729
  var DESCRIPTIONS = {
11294
11730
  ENOENT: "no such file or directory",
@@ -11301,7 +11737,9 @@ var DESCRIPTIONS = {
11301
11737
  EIO: "i/o error",
11302
11738
  ENOTEMPTY: "directory not empty",
11303
11739
  EBADF: "bad file descriptor",
11304
- ENOTSUP: "operation not supported"
11740
+ ENOTSUP: "operation not supported",
11741
+ EXDEV: "cross-device link not permitted",
11742
+ ELOOP: "too many symbolic links encountered"
11305
11743
  };
11306
11744
  function nodeFsError(code, syscall, pathArg, err, dest) {
11307
11745
  const c = typeof code === "string" ? code : err?.code || "EIO";
@@ -11316,7 +11754,7 @@ function nodeFsError(code, syscall, pathArg, err, dest) {
11316
11754
  }
11317
11755
  const e = new Error(msg);
11318
11756
  e.code = c;
11319
- e.errno = ERRNO[c] ?? -1;
11757
+ e.errno = ERRNO2[c] ?? -1;
11320
11758
  e.syscall = syscall;
11321
11759
  if (pathArg !== void 0 && pathArg !== null) e.path = pathArg;
11322
11760
  if (dest !== void 0) e.dest = dest;
@@ -11324,11 +11762,6 @@ function nodeFsError(code, syscall, pathArg, err, dest) {
11324
11762
  }
11325
11763
  var FS_READ_STREAM = /* @__PURE__ */ Symbol("fs.ReadStream");
11326
11764
  var FS_WRITE_STREAM = /* @__PURE__ */ Symbol("fs.WriteStream");
11327
- function cpInvalid(message) {
11328
- const e = new Error(message);
11329
- e.code = "ERR_FS_CP_EINVAL";
11330
- return e;
11331
- }
11332
11765
  function rmIsDirectoryError(pathArg) {
11333
11766
  const e = new Error(`Path is a directory: rm returned EISDIR (is a directory) ${pathArg}`);
11334
11767
  e.name = "SystemError";
@@ -11349,15 +11782,19 @@ var S_IFMT = 61440;
11349
11782
  var S_IFREG = 32768;
11350
11783
  var S_IFDIR = 16384;
11351
11784
  var S_IFLNK = 40960;
11785
+ var modeType = (mode) => {
11786
+ if (typeof mode === "bigint") return Number(BigInt.asUintN(32, mode) & BigInt(S_IFMT));
11787
+ return typeof mode === "number" ? mode & S_IFMT : -1;
11788
+ };
11352
11789
  var Stats = class {
11353
11790
  isFile() {
11354
- return (this.mode & S_IFMT) === S_IFREG;
11791
+ return modeType(this.mode) === S_IFREG;
11355
11792
  }
11356
11793
  isDirectory() {
11357
- return (this.mode & S_IFMT) === S_IFDIR;
11794
+ return modeType(this.mode) === S_IFDIR;
11358
11795
  }
11359
11796
  isSymbolicLink() {
11360
- return (this.mode & S_IFMT) === S_IFLNK;
11797
+ return modeType(this.mode) === S_IFLNK;
11361
11798
  }
11362
11799
  isBlockDevice() {
11363
11800
  return false;
@@ -11372,13 +11809,49 @@ var Stats = class {
11372
11809
  return false;
11373
11810
  }
11374
11811
  };
11375
- function statView(st) {
11812
+ for (const name of ["atime", "mtime", "ctime", "birthtime"]) {
11813
+ Object.defineProperty(Stats.prototype, name, {
11814
+ configurable: true,
11815
+ enumerable: false,
11816
+ get() {
11817
+ return new Date(Number(this[`${name}Ms`]));
11818
+ },
11819
+ set(value) {
11820
+ Object.defineProperty(this, name, { value, writable: true, configurable: true, enumerable: true });
11821
+ }
11822
+ });
11823
+ }
11824
+ function statView(st, bigint = false) {
11376
11825
  const mtimeMs = st.mtimeMs ?? (st.mtime ? Number(st.mtime) : 0);
11377
11826
  const atimeMs = st.atimeMs ?? mtimeMs;
11378
11827
  const ctimeMs = st.ctimeMs ?? mtimeMs;
11379
11828
  const type = st.isDirectory ? S_IFDIR : st.isSymbolicLink ? S_IFLNK : S_IFREG;
11380
11829
  const perm = typeof st.mode === "number" ? st.mode & ~S_IFMT : st.isDirectory ? 493 : 420;
11381
11830
  const size = st.size ?? 0;
11831
+ if (bigint) {
11832
+ const B = (v) => BigInt(Math.trunc(Number(v) || 0));
11833
+ const ns = (ms) => BigInt(Math.trunc(ms * 1e6));
11834
+ return Object.assign(new Stats(), {
11835
+ dev: B(st.dev),
11836
+ mode: B(type | perm),
11837
+ nlink: B(st.nlink ?? 1),
11838
+ uid: B(st.uid),
11839
+ gid: B(st.gid),
11840
+ rdev: 0n,
11841
+ blksize: 4096n,
11842
+ ino: B(st.ino),
11843
+ size: B(size),
11844
+ blocks: B(Math.ceil(size / 512)),
11845
+ atimeMs: B(atimeMs),
11846
+ mtimeMs: B(mtimeMs),
11847
+ ctimeMs: B(ctimeMs),
11848
+ birthtimeMs: B(ctimeMs),
11849
+ atimeNs: ns(atimeMs),
11850
+ mtimeNs: ns(mtimeMs),
11851
+ ctimeNs: ns(ctimeMs),
11852
+ birthtimeNs: ns(ctimeMs)
11853
+ });
11854
+ }
11382
11855
  return Object.assign(new Stats(), {
11383
11856
  dev: st.dev ?? 0,
11384
11857
  mode: type | perm,
@@ -11393,11 +11866,7 @@ function statView(st) {
11393
11866
  atimeMs,
11394
11867
  mtimeMs,
11395
11868
  ctimeMs,
11396
- birthtimeMs: ctimeMs,
11397
- atime: new Date(atimeMs),
11398
- mtime: new Date(mtimeMs),
11399
- ctime: new Date(ctimeMs),
11400
- birthtime: new Date(ctimeMs)
11869
+ birthtimeMs: ctimeMs
11401
11870
  });
11402
11871
  }
11403
11872
  var Dirent = class {
@@ -11439,12 +11908,46 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11439
11908
  const wrapBuffer = (bytes) => Buffer2 ? Buffer2.from(bytes) : bytes;
11440
11909
  const optEncoding = (options) => typeof options === "string" ? options : options?.encoding ?? null;
11441
11910
  const optFlag = (options, fallback) => options && typeof options === "object" && options.flag || fallback;
11911
+ const ENCODINGS = /* @__PURE__ */ new Set([
11912
+ "utf8",
11913
+ "utf-8",
11914
+ "ucs2",
11915
+ "ucs-2",
11916
+ "utf16le",
11917
+ "utf-16le",
11918
+ "latin1",
11919
+ "binary",
11920
+ "base64",
11921
+ "base64url",
11922
+ "hex",
11923
+ "ascii",
11924
+ "buffer"
11925
+ ]);
11926
+ const checkEncoding = (encoding) => {
11927
+ if (encoding == null || ENCODINGS.has(String(encoding).toLowerCase())) return;
11928
+ const err = new TypeError(`The argument 'encoding' is invalid encoding. Received '${encoding}'`);
11929
+ err.code = "ERR_INVALID_ARG_VALUE";
11930
+ throw err;
11931
+ };
11442
11932
  const decodeAs = (bytes, encoding) => {
11443
- if (!encoding || encoding === "buffer") return wrapBuffer(bytes);
11444
- if (encoding === "utf8" || encoding === "utf-8") return decoder3.decode(bytes);
11445
- return Buffer2 ? Buffer2.from(bytes).toString(encoding) : decoder3.decode(bytes);
11933
+ checkEncoding(encoding);
11934
+ if (!encoding) return wrapBuffer(bytes);
11935
+ const enc = String(encoding).toLowerCase();
11936
+ if (enc === "buffer") {
11937
+ const err = new TypeError("Unknown encoding: buffer");
11938
+ err.code = "ERR_UNKNOWN_ENCODING";
11939
+ throw err;
11940
+ }
11941
+ if (enc === "utf8" || enc === "utf-8") return decoder3.decode(bytes);
11942
+ if (enc === "ascii") {
11943
+ let out = "";
11944
+ for (let i2 = 0; i2 < bytes.length; i2++) out += String.fromCharCode(bytes[i2] & 127);
11945
+ return out;
11946
+ }
11947
+ return Buffer2 ? Buffer2.from(bytes).toString(enc) : decoder3.decode(bytes);
11446
11948
  };
11447
11949
  const encodeAs = (data2, encoding) => {
11950
+ checkEncoding(encoding);
11448
11951
  if (typeof data2 === "string" && encoding && encoding !== "utf8" && encoding !== "utf-8" && Buffer2) {
11449
11952
  const b = Buffer2.from(data2, encoding);
11450
11953
  return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
@@ -11615,9 +12118,17 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11615
12118
  }
11616
12119
  return;
11617
12120
  }
12121
+ const given = [];
12122
+ for (let cur2 = String(p); ; ) {
12123
+ given.unshift(cur2);
12124
+ const up = path.dirname(cur2);
12125
+ if (up === cur2) break;
12126
+ cur2 = up;
12127
+ }
11618
12128
  const parts = String(target).split("/").filter(Boolean);
11619
12129
  let cur = "";
11620
12130
  let first;
12131
+ let firstAbs;
11621
12132
  for (const part of parts) {
11622
12133
  cur += `/${part}`;
11623
12134
  if (syncFs.exists(cur)) {
@@ -11632,12 +12143,15 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11632
12143
  }
11633
12144
  try {
11634
12145
  syncFs.mkdir(cur);
11635
- first ??= path.isAbsolute(String(p)) ? cur : path.relative(process2.cwd(), cur);
12146
+ firstAbs ??= cur;
11636
12147
  } catch (err) {
11637
12148
  if (err?.code === "EEXIST") continue;
11638
12149
  throw nodeFsError(err?.code || "EIO", "mkdir", pathArg, err);
11639
12150
  }
11640
12151
  }
12152
+ if (firstAbs !== void 0) {
12153
+ first = given.find((g) => abs(g) === firstAbs) ?? firstAbs;
12154
+ }
11641
12155
  return first;
11642
12156
  }
11643
12157
  const typeAt = (full) => {
@@ -11657,11 +12171,14 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11657
12171
  }
11658
12172
  if (!ok) throw nodeFsError("ENOENT", syscall, p);
11659
12173
  }
11660
- function readdirSync(p, options) {
12174
+ const MAX_LINK_DEPTH = 40;
12175
+ function readdirSync(p, options, { followLinks = true } = {}) {
11661
12176
  const pathArg = p;
11662
12177
  const target = abs(p);
11663
12178
  const encoding = optEncoding(options);
12179
+ checkEncoding(encoding);
11664
12180
  const asName = (name) => encoding === "buffer" ? wrapBuffer(encoder3.encode(name)) : name;
12181
+ const dirent = (name, type, parent) => new Dirent(asName(name), type, parent);
11665
12182
  let names;
11666
12183
  try {
11667
12184
  names = syncFs.readdir(target);
@@ -11670,32 +12187,40 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11670
12187
  }
11671
12188
  if (!options?.recursive) {
11672
12189
  if (options?.withFileTypes) {
11673
- return names.map((name) => new Dirent(name, typeAt(path.join(target, name)), String(pathArg)));
12190
+ return names.map((name) => dirent(name, typeAt(path.join(target, name)), String(pathArg)));
11674
12191
  }
11675
12192
  return names.map(asName);
11676
12193
  }
11677
12194
  const out = [];
11678
- const queue = [{ dir: target, rel: "", parent: String(pathArg), names }];
12195
+ const queue = [{ dir: target, rel: "", parent: String(pathArg), names, links: 0 }];
11679
12196
  while (queue.length) {
11680
- const { dir, rel, parent, names: entries } = queue.shift();
12197
+ const { dir, rel, parent, names: entries, links } = queue.shift();
11681
12198
  for (const name of entries) {
11682
12199
  const full = path.join(dir, name);
11683
12200
  const type = typeAt(full);
11684
- out.push(options.withFileTypes ? new Dirent(name, type, parent) : asName(rel ? `${rel}/${name}` : name));
11685
- if (type === "dir") {
11686
- let children;
12201
+ out.push(options.withFileTypes ? dirent(name, type, parent) : asName(rel ? `${rel}/${name}` : name));
12202
+ let descend = type === "dir";
12203
+ if (followLinks && type === "link" && links < MAX_LINK_DEPTH) {
11687
12204
  try {
11688
- children = syncFs.readdir(full);
12205
+ descend = !!syncFs.stat(full).isDirectory;
11689
12206
  } catch {
11690
- children = [];
12207
+ descend = false;
11691
12208
  }
11692
- queue.push({
11693
- dir: full,
11694
- rel: rel ? `${rel}/${name}` : name,
11695
- parent: path.join(parent, name),
11696
- names: children
11697
- });
11698
12209
  }
12210
+ if (!descend) continue;
12211
+ let children;
12212
+ try {
12213
+ children = syncFs.readdir(full);
12214
+ } catch {
12215
+ continue;
12216
+ }
12217
+ queue.push({
12218
+ dir: full,
12219
+ rel: rel ? `${rel}/${name}` : name,
12220
+ parent: path.join(parent, name),
12221
+ names: children,
12222
+ links: links + (type === "link" ? 1 : 0)
12223
+ });
11699
12224
  }
11700
12225
  }
11701
12226
  return out;
@@ -11703,6 +12228,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11703
12228
  const syncApi = {
11704
12229
  readFileSync(p, options) {
11705
12230
  const encoding = optEncoding(options);
12231
+ checkEncoding(encoding);
11706
12232
  if (p === 0 || p === "0") return readStdinSync(encoding);
11707
12233
  if (typeof p === "number") {
11708
12234
  const ent = fdTable.get(p);
@@ -11726,13 +12252,13 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11726
12252
  if (st.isDirectory) {
11727
12253
  const e = new Error("EISDIR: illegal operation on a directory, read");
11728
12254
  e.code = "EISDIR";
11729
- e.errno = ERRNO.EISDIR;
12255
+ e.errno = ERRNO2.EISDIR;
11730
12256
  e.syscall = "read";
11731
12257
  throw e;
11732
12258
  }
11733
12259
  return decodeAs(syncFs.readFile(target), encoding);
11734
12260
  } catch (err) {
11735
- if (err?.code && err.syscall) throw err;
12261
+ if (err?.code && err.syscall || String(err?.code).startsWith("ERR_")) throw err;
11736
12262
  throw nodeFsError(err?.code || "ENOENT", "open", pathArg, err);
11737
12263
  }
11738
12264
  },
@@ -11750,6 +12276,23 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11750
12276
  const pathArg = p;
11751
12277
  const target = abs(p);
11752
12278
  if (flag.includes("x") && syncFs.exists(target)) throw nodeFsError("EEXIST", "open", pathArg);
12279
+ if (flag.startsWith("r")) {
12280
+ let cur;
12281
+ try {
12282
+ cur = syncFs.readFile(target);
12283
+ } catch (err) {
12284
+ throw nodeFsError(err?.code || "ENOENT", "open", pathArg, err);
12285
+ }
12286
+ const out = new Uint8Array(Math.max(cur.length, bytes.length));
12287
+ out.set(cur, 0);
12288
+ out.set(bytes, 0);
12289
+ try {
12290
+ syncFs.writeFile(target, out);
12291
+ } catch (err) {
12292
+ throw nodeFsError(err?.code || "EIO", "write", pathArg, err);
12293
+ }
12294
+ return;
12295
+ }
11753
12296
  try {
11754
12297
  syncFs.writeFile(target, bytes);
11755
12298
  } catch (err) {
@@ -11758,6 +12301,11 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11758
12301
  },
11759
12302
  appendFileSync(p, data2, options) {
11760
12303
  const next = encodeAs(data2, optEncoding(options));
12304
+ const flag = optFlag(options, "a");
12305
+ if (!flag.includes("a")) {
12306
+ syncApi.writeFileSync(p, next, { flag });
12307
+ return;
12308
+ }
11761
12309
  if (typeof p === "number") {
11762
12310
  const ent = fdTable.get(p);
11763
12311
  let end = null;
@@ -11805,7 +12353,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11805
12353
  statSync(p, options) {
11806
12354
  const pathArg = p;
11807
12355
  try {
11808
- return statView(syncFs.stat(abs(p)));
12356
+ return statView(syncFs.stat(abs(p)), options?.bigint === true);
11809
12357
  } catch (err) {
11810
12358
  const code = err?.code || "ENOENT";
11811
12359
  if (options?.throwIfNoEntry === false && (code === "ENOENT" || code === "ENOTDIR")) return void 0;
@@ -11815,27 +12363,17 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11815
12363
  lstatSync(p, options) {
11816
12364
  const pathArg = p;
11817
12365
  try {
11818
- return statView(syncFs.lstat(abs(p)));
12366
+ return statView(syncFs.lstat(abs(p)), options?.bigint === true);
11819
12367
  } catch (err) {
11820
12368
  const code = err?.code || "ENOENT";
11821
12369
  if (options?.throwIfNoEntry === false && (code === "ENOENT" || code === "ENOTDIR")) return void 0;
11822
12370
  throw nodeFsError(code, "lstat", pathArg, err);
11823
12371
  }
11824
12372
  },
11825
- /**
11826
- * Resolve to a canonical absolute path. Symlink walk is not implemented;
11827
- * when the path exists we return the normalized absolute form (enough for
11828
- * pnpm's cmd shims, which only need dirname(realpathSync(argv[1]))).
11829
- */
11830
- realpathSync(p) {
11831
- const pathArg = p;
11832
- const target = abs(p);
11833
- try {
11834
- syncFs.stat(target);
11835
- return target;
11836
- } catch (err) {
11837
- throw nodeFsError(err?.code || "ENOENT", "realpath", pathArg, err);
11838
- }
12373
+ /** Node's JS realpath: every symlink along the path resolved. */
12374
+ realpathSync(p, options) {
12375
+ const real = getCp().realpathSync(abs(p));
12376
+ return optEncoding(options) === "buffer" ? wrapBuffer(encoder3.encode(real)) : real;
11839
12377
  },
11840
12378
  readdirSync,
11841
12379
  mkdirSync,
@@ -11991,11 +12529,11 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11991
12529
  throw nodeFsError(err?.code || "EIO", "write", ent.path, err);
11992
12530
  }
11993
12531
  },
11994
- fstatSync(fd) {
12532
+ fstatSync(fd, options) {
11995
12533
  const ent = fdTable.get(fd);
11996
12534
  if (!ent) throw nodeFsError("EBADF", "fstat", void 0);
11997
12535
  try {
11998
- return statView(syncFs.stat(ent.path));
12536
+ return statView(syncFs.stat(ent.path), options?.bigint === true);
11999
12537
  } catch (err) {
12000
12538
  throw nodeFsError(err?.code || "EIO", "fstat", ent.path, err);
12001
12539
  }
@@ -12026,7 +12564,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12026
12564
  try {
12027
12565
  syncFs.symlink(target, abs(p));
12028
12566
  } catch (err) {
12029
- throw nodeFsError(err?.code || "EIO", "symlink", p, err);
12567
+ throw nodeFsError(err?.code || "EIO", "symlink", target, err, p);
12030
12568
  }
12031
12569
  },
12032
12570
  readlinkSync(p) {
@@ -12037,6 +12575,17 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12037
12575
  }
12038
12576
  },
12039
12577
  copyFileSync(src, dest, mode = 0) {
12578
+ if (mode == null) mode = 0;
12579
+ if (typeof mode !== "number" || !Number.isInteger(mode)) {
12580
+ const err = new TypeError("mode must be int32 or null/undefined");
12581
+ err.code = "ERR_INVALID_ARG_TYPE";
12582
+ throw err;
12583
+ }
12584
+ if (mode < 0 || mode > 7) {
12585
+ const err = new RangeError("mode is out of range: >= 0 && <= 7");
12586
+ err.code = "ERR_OUT_OF_RANGE";
12587
+ throw err;
12588
+ }
12040
12589
  const from = abs(src);
12041
12590
  const to = abs(dest);
12042
12591
  let st;
@@ -12053,42 +12602,10 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12053
12602
  throw nodeFsError(err?.code || "EIO", "copyfile", src, err, dest);
12054
12603
  }
12055
12604
  },
12056
- cpSync(src, dest, options = {}) {
12057
- const from = abs(src);
12058
- const to = abs(dest);
12059
- if (from === to) throw cpInvalid(`src and dest cannot be the same ${src}`);
12060
- if (to.startsWith(`${from}/`)) {
12061
- throw cpInvalid(`Cannot copy ${src}/ to a subdirectory of self ${dest}`);
12062
- }
12063
- let st;
12064
- try {
12065
- st = syncFs.stat(from);
12066
- } catch (err) {
12067
- throw nodeFsError(err?.code || "ENOENT", "cp", src, err);
12068
- }
12069
- if (st.isDirectory) {
12070
- if (!options?.recursive) {
12071
- const e = new Error(`Recursive option not enabled, cannot copy a directory: ${src}/`);
12072
- e.code = "ERR_FS_EISDIR";
12073
- throw e;
12074
- }
12075
- mkdirSync(to, { recursive: true });
12076
- for (const name of syncFs.readdir(from)) {
12077
- syncApi.cpSync(path.join(from, name), path.join(to, name), options);
12078
- }
12079
- return;
12080
- }
12081
- const exists = syncFs.exists(to);
12082
- if (exists && options?.errorOnExist && options?.force === false) {
12083
- const e = new Error(`Target already exists: cp returned EEXIST (${to} already exists)`);
12084
- e.name = "SystemError";
12085
- e.code = "ERR_FS_CP_EEXIST";
12086
- throw e;
12087
- }
12088
- if (exists && options?.force === false) return;
12089
- syncFs.writeFile(to, syncFs.readFile(from));
12605
+ cpSync(src, dest, options) {
12606
+ getCp().cpSync(src, dest, options);
12090
12607
  },
12091
- mkdtempSync(prefix, options) {
12608
+ mkdtempSync(prefix, options, { namedError = false } = {}) {
12092
12609
  const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
12093
12610
  const bytes = new Uint8Array(6);
12094
12611
  for (let attempt = 0; attempt < 100; attempt++) {
@@ -12096,6 +12613,14 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12096
12613
  const name = `${prefix}${[...bytes].map((b) => chars[b % chars.length]).join("")}`;
12097
12614
  const target = abs(name);
12098
12615
  if (syncFs.exists(target)) continue;
12616
+ const parent = path.dirname(target);
12617
+ let parentOk = false;
12618
+ try {
12619
+ parentOk = !!syncFs.stat(parent).isDirectory;
12620
+ } catch {
12621
+ parentOk = false;
12622
+ }
12623
+ if (!parentOk) throw nodeFsError("ENOENT", "mkdtemp", namedError ? name : `${prefix}XXXXXX`);
12099
12624
  try {
12100
12625
  syncFs.mkdir(target);
12101
12626
  } catch (err) {
@@ -12156,11 +12681,51 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12156
12681
  fdatasyncSync(fd) {
12157
12682
  if (fd !== 0 && fd !== 1 && fd !== 2 && !fdTable.has(fd)) throw nodeFsError("EBADF", "fdatasync", void 0);
12158
12683
  },
12159
- opendirSync(p) {
12160
- const entries = readdirSync(p, { withFileTypes: true });
12684
+ opendirSync(p, options) {
12685
+ let entries;
12686
+ try {
12687
+ entries = readdirSync(p, { withFileTypes: true, recursive: options?.recursive === true }, { followLinks: false });
12688
+ } catch (err) {
12689
+ throw nodeFsError(err?.code || "ENOENT", "opendir", void 0, err);
12690
+ }
12161
12691
  return createDir(String(p), entries);
12692
+ },
12693
+ linkSync(existingPath, newPath) {
12694
+ try {
12695
+ syncFs.link(abs(existingPath), abs(newPath));
12696
+ } catch (err) {
12697
+ throw nodeFsError(err?.code || "EIO", "link", existingPath, err, newPath);
12698
+ }
12162
12699
  }
12163
12700
  };
12701
+ let cpImpl;
12702
+ function getCp() {
12703
+ cpImpl ??= createCp({
12704
+ path,
12705
+ abs,
12706
+ fsError: nodeFsError,
12707
+ copyFileSync: (src, dest, mode) => syncApi.copyFileSync(src, dest, mode),
12708
+ mkdirpSync: (p) => mkdirSync(p, { recursive: true }),
12709
+ ops: {
12710
+ lstat: (p) => syncFs.lstat(p),
12711
+ stat: (p) => syncFs.stat(p),
12712
+ readlink: (p) => syncFs.readlink(p),
12713
+ symlink: (target, p) => syncFs.symlink(target, p),
12714
+ readdir: (p) => syncFs.readdir(p),
12715
+ mkdir: (p) => syncFs.mkdir(p),
12716
+ unlink: (p) => syncFs.unlink(p)
12717
+ }
12718
+ });
12719
+ return cpImpl;
12720
+ }
12721
+ function realpathNative(p, options) {
12722
+ try {
12723
+ return syncApi.realpathSync(p, options);
12724
+ } catch (err) {
12725
+ throw nodeFsError(err?.code || "ENOENT", "realpath", p, err);
12726
+ }
12727
+ }
12728
+ syncApi.realpathSync.native = realpathNative;
12164
12729
  function createDir(dirPath, entries) {
12165
12730
  let closed = false;
12166
12731
  const next = () => {
@@ -12188,13 +12753,24 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12188
12753
  return Promise.resolve().then(next);
12189
12754
  },
12190
12755
  closeSync() {
12756
+ if (closed) next();
12191
12757
  closed = true;
12192
12758
  },
12193
12759
  close(cb) {
12760
+ let err = null;
12761
+ if (closed) {
12762
+ try {
12763
+ next();
12764
+ } catch (e) {
12765
+ err = e;
12766
+ }
12767
+ }
12194
12768
  closed = true;
12195
- if (typeof cb === "function") queueMicrotask(() => cb(null));
12196
- else return Promise.resolve();
12197
- return void 0;
12769
+ if (typeof cb === "function") {
12770
+ queueMicrotask(() => cb(err));
12771
+ return void 0;
12772
+ }
12773
+ return err ? Promise.reject(err) : Promise.resolve();
12198
12774
  },
12199
12775
  async *[Symbol.asyncIterator]() {
12200
12776
  try {
@@ -12247,61 +12823,54 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12247
12823
  return track(
12248
12824
  (async () => {
12249
12825
  const encoding = optEncoding(options);
12826
+ checkEncoding(encoding);
12250
12827
  try {
12251
12828
  return decodeAs(await asyncFs.readFile(abs(p)), encoding);
12252
12829
  } catch (err) {
12830
+ if (String(err?.code).startsWith("ERR_")) throw err;
12253
12831
  throw nodeFsError(err?.code || "ENOENT", "open", p, err);
12254
12832
  }
12255
12833
  })()
12256
12834
  );
12257
12835
  },
12836
+ // The write happens when the call is made, as Node's open does in call
12837
+ // order: a later `flag: 'wx'` sees the file an earlier writeFile made.
12258
12838
  writeFile(p, data2, options) {
12259
- return track(
12260
- (async () => {
12261
- const bytes = encodeAs(data2, optEncoding(options));
12262
- const flag = optFlag(options, "w");
12263
- if (flag.includes("a")) return promises.appendFile(p, bytes);
12264
- const target = abs(p);
12265
- if (flag.includes("x") && await asyncFs.exists(target)) throw nodeFsError("EEXIST", "open", p);
12266
- try {
12267
- await asyncFs.writeFile(target, bytes);
12268
- } catch (err) {
12269
- throw nodeFsError(err?.code || "EIO", "open", p, err);
12270
- }
12271
- return void 0;
12272
- })()
12273
- );
12839
+ let result;
12840
+ try {
12841
+ syncApi.writeFileSync(p, data2, options);
12842
+ result = Promise.resolve();
12843
+ } catch (err) {
12844
+ result = Promise.reject(err);
12845
+ }
12846
+ return track(result);
12274
12847
  },
12275
12848
  appendFile(p, data2, options) {
12276
- return track(
12277
- (async () => {
12278
- const target = abs(p);
12279
- let prev = new Uint8Array(0);
12280
- if (await asyncFs.exists(target)) prev = await asyncFs.readFile(target);
12281
- const next = encodeAs(data2, optEncoding(options));
12282
- const merged = new Uint8Array(prev.length + next.length);
12283
- merged.set(prev);
12284
- merged.set(next, prev.length);
12285
- await asyncFs.writeFile(target, merged);
12286
- })()
12287
- );
12849
+ let result;
12850
+ try {
12851
+ syncApi.appendFileSync(p, data2, options);
12852
+ result = Promise.resolve();
12853
+ } catch (err) {
12854
+ result = Promise.reject(err);
12855
+ }
12856
+ return track(result);
12288
12857
  },
12289
- stat(p) {
12858
+ stat(p, options) {
12290
12859
  return track(
12291
12860
  (async () => {
12292
12861
  try {
12293
- return statView(await asyncFs.stat(abs(p)));
12862
+ return statView(await asyncFs.stat(abs(p)), options?.bigint === true);
12294
12863
  } catch (err) {
12295
12864
  throw nodeFsError(err?.code || "ENOENT", "stat", p, err);
12296
12865
  }
12297
12866
  })()
12298
12867
  );
12299
12868
  },
12300
- lstat(p) {
12869
+ lstat(p, options) {
12301
12870
  return track(
12302
12871
  (async () => {
12303
12872
  try {
12304
- return statView(await asyncFs.lstat(abs(p)));
12873
+ return statView(await asyncFs.lstat(abs(p)), options?.bigint === true);
12305
12874
  } catch (err) {
12306
12875
  throw nodeFsError(err?.code || "ENOENT", "lstat", p, err);
12307
12876
  }
@@ -12309,7 +12878,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12309
12878
  );
12310
12879
  },
12311
12880
  readdir(p, options) {
12312
- return track((async () => readdirSync(p, options))());
12881
+ return track((async () => readdirSync(p, options, { followLinks: !options?.withFileTypes }))());
12313
12882
  },
12314
12883
  mkdir(p, options = {}) {
12315
12884
  return track((async () => mkdirSync(p, options))());
@@ -12324,16 +12893,19 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12324
12893
  return track((async () => syncApi.copyFileSync(src, dest, mode))());
12325
12894
  },
12326
12895
  cp(src, dest, options) {
12327
- return track((async () => syncApi.cpSync(src, dest, options))());
12896
+ return track(getCp().cp(src, dest, options));
12897
+ },
12898
+ link(existingPath, newPath) {
12899
+ return track((async () => syncApi.linkSync(existingPath, newPath))());
12328
12900
  },
12329
12901
  mkdtemp(prefix, options) {
12330
- return track((async () => syncApi.mkdtempSync(prefix, options))());
12902
+ return track((async () => syncApi.mkdtempSync(prefix, options, { namedError: true }))());
12331
12903
  },
12332
12904
  truncate(p, len) {
12333
12905
  return track((async () => syncApi.truncateSync(p, len))());
12334
12906
  },
12335
- realpath(p) {
12336
- return track((async () => syncApi.realpathSync(p))());
12907
+ realpath(p, options) {
12908
+ return track((async () => realpathNative(p, options))());
12337
12909
  },
12338
12910
  chmod(p) {
12339
12911
  return track((async () => syncApi.chmodSync(p))());
@@ -12353,8 +12925,8 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12353
12925
  lutimes(p) {
12354
12926
  return track((async () => syncApi.lutimesSync(p))());
12355
12927
  },
12356
- opendir(p) {
12357
- return track((async () => syncApi.opendirSync(p))());
12928
+ opendir(p, options) {
12929
+ return track((async () => syncApi.opendirSync(p, options))());
12358
12930
  },
12359
12931
  unlink(p) {
12360
12932
  return track(
@@ -12676,7 +13248,9 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
12676
13248
  access: callbackify(syncApi.accessSync),
12677
13249
  stat: callbackify(syncApi.statSync),
12678
13250
  lstat: callbackify(syncApi.lstatSync),
12679
- realpath: callbackify(syncApi.realpathSync),
13251
+ realpath: Object.assign(callbackify(syncApi.realpathSync), {
13252
+ native: callbackify(realpathNative)
13253
+ }),
12680
13254
  readdir: callbackify(syncApi.readdirSync),
12681
13255
  mkdir: callbackify(syncApi.mkdirSync, { minArgsBeforeCb: 2 }),
12682
13256
  rmdir: callbackify(syncApi.rmdirSync),
@@ -12708,7 +13282,16 @@ ${e.stack}
12708
13282
  return void 0;
12709
13283
  },
12710
13284
  copyFile: callbackify(syncApi.copyFileSync, { minArgsBeforeCb: 2 }),
12711
- cp: callbackify(syncApi.cpSync, { minArgsBeforeCb: 2 }),
13285
+ cp(src, dest, options, callback) {
13286
+ const cb = typeof options === "function" ? options : callback;
13287
+ const opts = typeof options === "function" ? void 0 : options;
13288
+ requireCallback(cb);
13289
+ track(getCp().cp(src, dest, opts)).then(
13290
+ () => cb(null),
13291
+ (err) => cb(err)
13292
+ );
13293
+ },
13294
+ link: callbackify(syncApi.linkSync, { minArgsBeforeCb: 2 }),
12712
13295
  mkdtemp: callbackify(syncApi.mkdtempSync),
12713
13296
  truncate: callbackify(syncApi.truncateSync),
12714
13297
  ftruncate: callbackify(syncApi.ftruncateSync),