11'use strict' ;
22
33const {
4+ ArrayFrom,
45 ArrayPrototypePush,
56 DateNow,
67 SafeMap,
8+ StringPrototypeReplaceAll,
79 Symbol,
810} = primordials ;
911
@@ -37,6 +39,7 @@ const {
3739 createSymlinkStats,
3840} = require ( 'internal/vfs/stats' ) ;
3941const { Dirent } = require ( 'internal/fs/utils' ) ;
42+ const { kEmptyObject } = require ( 'internal/util' ) ;
4043const {
4144 fs : {
4245 UV_DIRENT_FILE ,
@@ -62,7 +65,7 @@ const kMaxSymlinkDepth = 40;
6265 * Internal entry representation for MemoryProvider.
6366 */
6467class MemoryEntry {
65- constructor ( type , options = { } ) {
68+ constructor ( type , options = kEmptyObject ) {
6669 this . type = type ;
6770 this . mode = options . mode ?? ( type === TYPE_DIR ? 0o755 : 0o644 ) ;
6871 this . content = null ; // For files - static Buffer content
@@ -85,7 +88,7 @@ class MemoryEntry {
8588 getContentSync ( ) {
8689 if ( this . contentProvider !== null ) {
8790 const result = this . contentProvider ( ) ;
88- if ( result && typeof result . then === 'function' ) {
91+ if ( typeof result ? .then === 'function' ) {
8992 // It's a Promise - can't use sync API
9093 throw new ERR_INVALID_STATE ( 'cannot use sync API with async content provider' ) ;
9194 }
@@ -171,9 +174,9 @@ class MemoryProvider extends VirtualProvider {
171174 */
172175 #normalizePath( path ) {
173176 // Convert backslashes to forward slashes
174- let normalized = path . replace ( / \\ / g , '/' ) ;
177+ let normalized = StringPrototypeReplaceAll ( path , '\\' , '/' ) ;
175178 // Ensure absolute path
176- if ( ! normalized . startsWith ( '/' ) ) {
179+ if ( normalized [ 0 ] !== '/' ) {
177180 normalized = '/' + normalized ;
178181 }
179182 // Use path.posix.normalize to resolve . and ..
@@ -368,8 +371,7 @@ class MemoryProvider extends VirtualProvider {
368371 }
369372
370373 // Ensure final directory is populated
371- const finalPath = pathPosix . join ( '/' , ...segments ) ;
372- this . #ensurePopulated( current , finalPath ) ;
374+ this . #ensurePopulated( current , parentPath ) ;
373375
374376 return current ;
375377 }
@@ -453,16 +455,13 @@ class MemoryProvider extends VirtualProvider {
453455 try {
454456 entry = this . #getEntry( normalized , 'open' ) ;
455457 } catch ( err ) {
456- if ( err . code === 'ENOENT' && isCreate ) {
457- // Create the file
458- const parent = this . #ensureParent( normalized , true , 'open' ) ;
459- const name = this . #getBaseName( normalized ) ;
460- entry = new MemoryEntry ( TYPE_FILE , { mode } ) ;
461- entry . content = Buffer . alloc ( 0 ) ;
462- parent . children . set ( name , entry ) ;
463- } else {
464- throw err ;
465- }
458+ if ( err . code !== 'ENOENT' || ! isCreate ) throw err ;
459+ // Create the file
460+ const parent = this . #ensureParent( normalized , true , 'open' ) ;
461+ const name = this . #getBaseName( normalized ) ;
462+ entry = new MemoryEntry ( TYPE_FILE , { mode } ) ;
463+ entry . content = Buffer . alloc ( 0 ) ;
464+ parent . children . set ( name , entry ) ;
466465 }
467466
468467 if ( entry . isDirectory ( ) ) {
@@ -509,13 +508,10 @@ class MemoryProvider extends VirtualProvider {
509508 // Ensure directory is populated (for lazy population)
510509 this . #ensurePopulated( entry , path ) ;
511510
512- const names = [ ...entry . children . keys ( ) ] ;
513-
514511 if ( options ?. withFileTypes ) {
515512 const normalized = this . #normalizePath( path ) ;
516513 const dirents = [ ] ;
517- for ( const name of names ) {
518- const childEntry = entry . children . get ( name ) ;
514+ for ( const { 0 : name , 1 : childEntry } of entry . children ) {
519515 let type ;
520516 if ( childEntry . isSymbolicLink ( ) ) {
521517 type = UV_DIRENT_LINK ;
@@ -529,7 +525,7 @@ class MemoryProvider extends VirtualProvider {
529525 return dirents ;
530526 }
531527
532- return names ;
528+ return ArrayFrom ( entry . children . keys ( ) ) ;
533529 }
534530
535531 async readdir ( path , options ) {
0 commit comments