@visulima/fs
Version:
Human friendly file system utilities for Node.js
135 lines (125 loc) • 4.64 kB
JavaScript
import { createRequire as __cjs_createRequire } from "node:module";
const __cjs_require = __cjs_createRequire(import.meta.url);
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule = (module) => {
// Check if we're in Node.js and version supports getBuiltinModule
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
// Node.js 20.16.0+ and 22.3.0+
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
return __cjs_getProcess.getBuiltinModule(module);
}
}
// Fallback to createRequire
return __cjs_require(module);
};
const {
cwd
} = __cjs_getProcess;
import { toPath } from '@visulima/path/utils';
const {
mkdir,
rename: rename$1,
copyFile,
unlink
} = __cjs_getBuiltinModule("node:fs/promises");
import { dirname, resolve } from '@visulima/path';
import isAccessible from './isAccessible-iOp0Bou6.js';
const {
mkdirSync,
renameSync: renameSync$1,
copyFileSync,
unlinkSync
} = __cjs_getBuiltinModule("node:fs");
import isAccessibleSync from './isAccessibleSync-38BmiIcx.js';
class SameDirectoryError extends Error {
constructor(source, destination) {
super(`Source directory "${dirname(source)}" does not match destination directory "${dirname(destination)}"`);
this.name = "SameDirectoryError";
}
}
const validateSameDirectory = (source, destination) => {
if (!source || !destination) {
throw new Error("Source and destination paths must not be empty");
}
if (dirname(source) !== dirname(destination)) {
throw new SameDirectoryError(source, destination);
}
};
const internalMoveFile = async (sourcePath, destinationPath, { cwd, directoryMode, overwrite, validateDirectory }) => {
if (cwd) {
sourcePath = resolve(cwd, sourcePath);
destinationPath = resolve(cwd, destinationPath);
}
if (validateDirectory) {
validateSameDirectory(sourcePath, destinationPath);
}
if (!overwrite && await isAccessible(destinationPath)) {
throw new Error(`The destination file exists: ${destinationPath}`);
}
await mkdir(dirname(destinationPath), {
mode: directoryMode,
recursive: true
});
try {
await rename$1(sourcePath, destinationPath);
} catch (error) {
if (error.code === "EXDEV") {
await copyFile(sourcePath, destinationPath);
await unlink(sourcePath);
} else {
throw error;
}
}
};
const internalMoveFileSync = (sourcePath, destinationPath, { cwd, directoryMode, overwrite, validateDirectory }) => {
if (cwd) {
sourcePath = resolve(cwd, sourcePath);
destinationPath = resolve(cwd, destinationPath);
}
if (validateDirectory) {
validateSameDirectory(sourcePath, destinationPath);
}
if (!overwrite && isAccessibleSync(destinationPath)) {
throw new Error(`The destination file exists: ${destinationPath}`);
}
mkdirSync(dirname(destinationPath), {
mode: directoryMode,
recursive: true
});
try {
renameSync$1(sourcePath, destinationPath);
} catch (error) {
if (error.code === "EXDEV") {
copyFileSync(sourcePath, destinationPath);
unlinkSync(sourcePath);
} else {
throw error;
}
}
};
const move = async (sourcePath, destinationPath, options = {}) => {
const internalOptions = {
overwrite: true,
validateDirectory: false,
...options,
cwd: options.cwd ? toPath(options.cwd) : cwd()
};
await internalMoveFile(sourcePath, destinationPath, internalOptions);
};
const moveSync = (sourcePath, destinationPath, options) => {
const internalOptions = { overwrite: true, validateDirectory: false, ...options };
internalOptions.cwd = internalOptions.cwd ? toPath(internalOptions.cwd) : cwd();
internalMoveFileSync(sourcePath, destinationPath, internalOptions);
};
const rename = async (source, destination, options) => {
const internalOptions = { overwrite: true, ...options, validateDirectory: true };
internalOptions.cwd = internalOptions.cwd ? toPath(internalOptions.cwd) : cwd();
await internalMoveFile(source, destination, internalOptions);
};
const renameSync = (source, destination, options) => {
const internalOptions = { overwrite: true, ...options, validateDirectory: true };
internalOptions.cwd = internalOptions.cwd ? toPath(internalOptions.cwd) : cwd();
internalMoveFileSync(source, destination, internalOptions);
};
export { move, moveSync, rename, renameSync };