Add mount/unmount lifecycle on `VirtualFileSystem`, a handler registry that fs.js and fs/promises.js consult via `vfsState.handlers`, and a router that maps absolute paths to the VFS that owns them. When a VFS is mounted, the public `fs.*` and `fs/promises` APIs (including streams, `fs.watch`, and `opendir`) dispatch to the provider for paths under the mount point, and fall through to the real filesystem otherwise. Includes per-method dispatch tests, error-path coverage, multi-mount routing tests, and router unit tests. Ref: https://github.com/nodejs/node/pull/63115 Signed-off-by: Matteo Collina <hello@matteocollina.com> PR-URL: https://github.com/nodejs/node/pull/63537 Refs: https://github.com/nodejs/node/pull/63115 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Paolo Insogna <paolo@cowtech.it>
205 lines
4.1 KiB
JavaScript
205 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ErrorCaptureStackTrace,
|
|
} = primordials;
|
|
|
|
const {
|
|
UVException,
|
|
} = require('internal/errors');
|
|
|
|
const {
|
|
UV_ENOENT,
|
|
UV_ENOTDIR,
|
|
UV_ENOTEMPTY,
|
|
UV_EISDIR,
|
|
UV_EBADF,
|
|
UV_EEXIST,
|
|
UV_EROFS,
|
|
UV_EINVAL,
|
|
UV_ELOOP,
|
|
UV_EACCES,
|
|
UV_EXDEV,
|
|
} = internalBinding('uv');
|
|
|
|
/**
|
|
* Creates an ENOENT error for virtual file system operations.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path that was not found
|
|
* @returns {Error}
|
|
*/
|
|
function createENOENT(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_ENOENT,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createENOENT);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an ENOTDIR error.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path that is not a directory
|
|
* @returns {Error}
|
|
*/
|
|
function createENOTDIR(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_ENOTDIR,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createENOTDIR);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an ENOTEMPTY error for non-empty directory.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path of the non-empty directory
|
|
* @returns {Error}
|
|
*/
|
|
function createENOTEMPTY(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_ENOTEMPTY,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createENOTEMPTY);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EISDIR error.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path that is a directory
|
|
* @returns {Error}
|
|
*/
|
|
function createEISDIR(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EISDIR,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEISDIR);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EBADF error for invalid file descriptor operations.
|
|
* @param {string} syscall The system call name
|
|
* @returns {Error}
|
|
*/
|
|
function createEBADF(syscall) {
|
|
const err = new UVException({
|
|
errno: UV_EBADF,
|
|
syscall,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEBADF);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EEXIST error.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path that already exists
|
|
* @returns {Error}
|
|
*/
|
|
function createEEXIST(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EEXIST,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEEXIST);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EROFS error for read-only file system.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path
|
|
* @returns {Error}
|
|
*/
|
|
function createEROFS(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EROFS,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEROFS);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EINVAL error for invalid argument.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path
|
|
* @returns {Error}
|
|
*/
|
|
function createEINVAL(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EINVAL,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEINVAL);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an ELOOP error for too many symbolic links.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path
|
|
* @returns {Error}
|
|
*/
|
|
function createELOOP(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_ELOOP,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createELOOP);
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* Creates an EACCES error for permission denied.
|
|
* @param {string} syscall The system call name
|
|
* @param {string} path The path
|
|
* @returns {Error}
|
|
*/
|
|
function createEACCES(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EACCES,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEACCES);
|
|
return err;
|
|
}
|
|
|
|
function createEXDEV(syscall, path) {
|
|
const err = new UVException({
|
|
errno: UV_EXDEV,
|
|
syscall,
|
|
path,
|
|
});
|
|
ErrorCaptureStackTrace(err, createEXDEV);
|
|
return err;
|
|
}
|
|
|
|
module.exports = {
|
|
createENOENT,
|
|
createENOTDIR,
|
|
createENOTEMPTY,
|
|
createEISDIR,
|
|
createEBADF,
|
|
createEEXIST,
|
|
createEROFS,
|
|
createEINVAL,
|
|
createELOOP,
|
|
createEACCES,
|
|
createEXDEV,
|
|
};
|