@@ -36,6 +36,7 @@ const { emitExperimentalWarning } = require('internal/util');
3636const kProvider = Symbol ( 'kProvider' ) ;
3737const kMountPoint = Symbol ( 'kMountPoint' ) ;
3838const kMounted = Symbol ( 'kMounted' ) ;
39+ const kOverlay = Symbol ( 'kOverlay' ) ;
3940const kModuleHooks = Symbol ( 'kModuleHooks' ) ;
4041const kPromises = Symbol ( 'kPromises' ) ;
4142const kVirtualCwd = Symbol ( 'kVirtualCwd' ) ;
@@ -65,6 +66,7 @@ class VirtualFileSystem {
6566 * @param {object } [options] Configuration options
6667 * @param {boolean } [options.moduleHooks] Whether to enable require/import hooks (default: true)
6768 * @param {boolean } [options.virtualCwd] Whether to enable virtual working directory
69+ * @param {boolean } [options.overlay] Whether to enable overlay mode (only intercept existing files)
6870 */
6971 constructor ( providerOrOptions , options = { } ) {
7072 emitExperimentalWarning ( 'VirtualFileSystem' ) ;
@@ -89,10 +91,14 @@ class VirtualFileSystem {
8991 if ( options . virtualCwd !== undefined ) {
9092 validateBoolean ( options . virtualCwd , 'options.virtualCwd' ) ;
9193 }
94+ if ( options . overlay !== undefined ) {
95+ validateBoolean ( options . overlay , 'options.overlay' ) ;
96+ }
9297
9398 this [ kProvider ] = provider ?? new MemoryProvider ( ) ;
9499 this [ kMountPoint ] = null ;
95100 this [ kMounted ] = false ;
101+ this [ kOverlay ] = options . overlay === true ;
96102 this [ kModuleHooks ] = options . moduleHooks !== false ;
97103 this [ kPromises ] = null ; // Lazy-initialized
98104 this [ kVirtualCwdEnabled ] = options . virtualCwd === true ;
@@ -121,7 +127,7 @@ class VirtualFileSystem {
121127 * Returns true if VFS is mounted.
122128 * @returns {boolean }
123129 */
124- get isMounted ( ) {
130+ get mounted ( ) {
125131 return this [ kMounted ] ;
126132 }
127133
@@ -133,6 +139,16 @@ class VirtualFileSystem {
133139 return this [ kProvider ] . readonly ;
134140 }
135141
142+ /**
143+ * Returns true if overlay mode is enabled.
144+ * In overlay mode, the VFS only intercepts paths that exist in the VFS,
145+ * allowing other paths to fall through to the real file system.
146+ * @returns {boolean }
147+ */
148+ get overlay ( ) {
149+ return this [ kOverlay ] ;
150+ }
151+
136152 /**
137153 * Returns true if virtual working directory is enabled.
138154 * @returns {boolean }
@@ -319,6 +335,8 @@ class VirtualFileSystem {
319335
320336 /**
321337 * Checks if a path should be handled by this VFS.
338+ * In mount mode (default), returns true for all paths under the mount point.
339+ * In overlay mode, returns true only if the path exists in the VFS.
322340 * @param {string } inputPath The path to check
323341 * @returns {boolean }
324342 */
@@ -328,7 +346,21 @@ class VirtualFileSystem {
328346 }
329347
330348 const normalized = normalizePath ( inputPath ) ;
331- return isUnderMountPoint ( normalized , this [ kMountPoint ] ) ;
349+ if ( ! isUnderMountPoint ( normalized , this [ kMountPoint ] ) ) {
350+ return false ;
351+ }
352+
353+ // In overlay mode, only handle if the path exists in VFS
354+ if ( this [ kOverlay ] ) {
355+ try {
356+ const providerPath = getRelativePath ( normalized , this [ kMountPoint ] ) ;
357+ return this [ kProvider ] . existsSync ( providerPath ) ;
358+ } catch {
359+ return false ;
360+ }
361+ }
362+
363+ return true ;
332364 }
333365
334366 // ==================== FS Operations (Sync) ====================
@@ -428,6 +460,32 @@ class VirtualFileSystem {
428460 return undefined ;
429461 }
430462
463+ /**
464+ * Adds a file directly to the VFS provider.
465+ * This writes directly to the provider bypassing mount point logic,
466+ * making it useful for populating the VFS before or after mounting.
467+ * @param {string } filePath The file path (relative to VFS root)
468+ * @param {Buffer|string } content The file content
469+ */
470+ addFile ( filePath , content ) {
471+ const { dirname } = require ( 'path' ) ;
472+ const parentDir = dirname ( filePath ) ;
473+ if ( parentDir !== '/' ) {
474+ this [ kProvider ] . mkdirSync ( parentDir , { __proto__ : null , recursive : true } ) ;
475+ }
476+ this [ kProvider ] . writeFileSync ( filePath , content ) ;
477+ }
478+
479+ /**
480+ * Adds a directory directly to the VFS provider.
481+ * This writes directly to the provider bypassing mount point logic,
482+ * making it useful for populating the VFS before or after mounting.
483+ * @param {string } dirPath The directory path (relative to VFS root)
484+ */
485+ addDirectory ( dirPath ) {
486+ this [ kProvider ] . mkdirSync ( dirPath , { __proto__ : null , recursive : true } ) ;
487+ }
488+
431489 /**
432490 * Removes a directory synchronously.
433491 * @param {string } dirPath The directory path
0 commit comments