1- // fs polyfill module for isolated-vm
1+ // fs polyfill module for the sandbox
22// This module runs inside the isolate and provides Node.js fs API compatibility
33// It communicates with the host via the _fs Reference object
44
@@ -1031,12 +1031,12 @@ const fs = {
10311031 try {
10321032 if ( encoding ) {
10331033 // Text mode - use text read
1034- const content = _fs . readFile ( pathStr ) ;
1034+ const content = _fs . readFile . applySyncPromise ( undefined , [ pathStr ] ) ;
10351035 return content ;
10361036 } else {
1037- // Binary mode - host returns raw Uint8Array via MessagePack bin
1038- const binaryData = _fs . readFileBinary ( pathStr ) ;
1039- return Buffer . from ( binaryData ) ;
1037+ // Binary mode - use binary read with base64 encoding
1038+ const base64Content = _fs . readFileBinary . applySyncPromise ( undefined , [ pathStr ] ) ;
1039+ return Buffer . from ( base64Content , "base64" ) ;
10401040 }
10411041 } catch ( err ) {
10421042 const errMsg = ( err as Error ) . message || String ( err ) ;
@@ -1079,14 +1079,15 @@ const fs = {
10791079 if ( typeof data === "string" ) {
10801080 // Text mode - use text write
10811081 // Return the result so async callers (fs.promises) can await it.
1082- return _fs . writeFile ( pathStr , data ) ;
1082+ return _fs . writeFile . applySyncPromise ( undefined , [ pathStr , data ] ) ;
10831083 } else if ( ArrayBuffer . isView ( data ) ) {
1084- // Binary mode - send raw Uint8Array via MessagePack bin
1084+ // Binary mode - convert to base64 and use binary write
10851085 const uint8 = new Uint8Array ( data . buffer , data . byteOffset , data . byteLength ) ;
1086- return _fs . writeFileBinary ( pathStr , uint8 ) ;
1086+ const base64 = Buffer . from ( uint8 ) . toString ( "base64" ) ;
1087+ return _fs . writeFileBinary . applySyncPromise ( undefined , [ pathStr , base64 ] ) ;
10871088 } else {
10881089 // Fallback to text mode
1089- return _fs . writeFile ( pathStr , String ( data ) ) ;
1090+ return _fs . writeFile . applySyncPromise ( undefined , [ pathStr , String ( data ) ] ) ;
10901091 }
10911092 } ,
10921093
@@ -1105,9 +1106,9 @@ const fs = {
11051106 readdirSync ( path : PathLike , options ?: nodeFs . ObjectEncodingOptions & { withFileTypes ?: boolean ; recursive ?: boolean } ) : string [ ] | Dirent [ ] {
11061107 const rawPath = toPathString ( path ) ;
11071108 const pathStr = rawPath ;
1108- let entries : Array < { name : string ; isDirectory : boolean } > ;
1109+ let entriesJson : string ;
11091110 try {
1110- entries = _fs . readDir ( pathStr ) ;
1111+ entriesJson = _fs . readDir . applySyncPromise ( undefined , [ pathStr ] ) ;
11111112 } catch ( err ) {
11121113 // Convert "entry not found" and similar errors to proper ENOENT
11131114 const errMsg = ( err as Error ) . message || String ( err ) ;
@@ -1121,6 +1122,10 @@ const fs = {
11211122 }
11221123 throw err ;
11231124 }
1125+ const entries = JSON . parse ( entriesJson ) as Array < {
1126+ name : string ;
1127+ isDirectory : boolean ;
1128+ } > ;
11241129 if ( options ?. withFileTypes ) {
11251130 return entries . map ( ( e ) => new Dirent ( e . name , e . isDirectory , rawPath ) ) ;
11261131 }
@@ -1131,13 +1136,13 @@ const fs = {
11311136 const rawPath = toPathString ( path ) ;
11321137 const pathStr = rawPath ;
11331138 const recursive = typeof options === "object" ? options ?. recursive ?? false : false ;
1134- _fs . mkdir ( pathStr , recursive ) ;
1139+ _fs . mkdir . applySyncPromise ( undefined , [ pathStr , recursive ] ) ;
11351140 return recursive ? rawPath : undefined ;
11361141 } ,
11371142
11381143 rmdirSync ( path : PathLike , _options ?: RmDirOptions ) : void {
11391144 const pathStr = toPathString ( path ) ;
1140- _fs . rmdir ( pathStr ) ;
1145+ _fs . rmdir . applySyncPromise ( undefined , [ pathStr ] ) ;
11411146 } ,
11421147
11431148 rmSync ( path : PathLike , options ?: { force ?: boolean ; recursive ?: boolean } ) : void {
@@ -1175,15 +1180,15 @@ const fs = {
11751180
11761181 existsSync ( path : PathLike ) : boolean {
11771182 const pathStr = toPathString ( path ) ;
1178- return _fs . exists ( pathStr ) ;
1183+ return _fs . exists . applySyncPromise ( undefined , [ pathStr ] ) ;
11791184 } ,
11801185
11811186 statSync ( path : PathLike , _options ?: nodeFs . StatSyncOptions ) : Stats {
11821187 const rawPath = toPathString ( path ) ;
11831188 const pathStr = rawPath ;
1184- let stat : { mode : number ; size : number ; isDirectory : boolean ; atimeMs : number ; mtimeMs : number ; ctimeMs : number ; birthtimeMs : number } ;
1189+ let statJson : string ;
11851190 try {
1186- stat = _fs . stat ( pathStr ) ;
1191+ statJson = _fs . stat . applySyncPromise ( undefined , [ pathStr ] ) ;
11871192 } catch ( err ) {
11881193 // Convert various "not found" errors to proper ENOENT
11891194 const errMsg = ( err as Error ) . message || String ( err ) ;
@@ -1202,24 +1207,42 @@ const fs = {
12021207 }
12031208 throw err ;
12041209 }
1210+ const stat = JSON . parse ( statJson ) as {
1211+ mode : number ;
1212+ size : number ;
1213+ atimeMs ?: number ;
1214+ mtimeMs ?: number ;
1215+ ctimeMs ?: number ;
1216+ birthtimeMs ?: number ;
1217+ } ;
12051218 return new Stats ( stat ) ;
12061219 } ,
12071220
12081221 lstatSync ( path : PathLike , _options ?: nodeFs . StatSyncOptions ) : Stats {
12091222 const pathStr = toPathString ( path ) ;
1210- const stat = bridgeCall ( ( ) => _fs . lstat ( pathStr ) , "lstat" , pathStr ) ;
1223+ const statJson = bridgeCall ( ( ) => _fs . lstat . applySyncPromise ( undefined , [ pathStr ] ) , "lstat" , pathStr ) ;
1224+ const stat = JSON . parse ( statJson ) as {
1225+ mode : number ;
1226+ size : number ;
1227+ isDirectory : boolean ;
1228+ isSymbolicLink ?: boolean ;
1229+ atimeMs ?: number ;
1230+ mtimeMs ?: number ;
1231+ ctimeMs ?: number ;
1232+ birthtimeMs ?: number ;
1233+ } ;
12111234 return new Stats ( stat ) ;
12121235 } ,
12131236
12141237 unlinkSync ( path : PathLike ) : void {
12151238 const pathStr = toPathString ( path ) ;
1216- _fs . unlink ( pathStr ) ;
1239+ _fs . unlink . applySyncPromise ( undefined , [ pathStr ] ) ;
12171240 } ,
12181241
12191242 renameSync ( oldPath : PathLike , newPath : PathLike ) : void {
12201243 const oldPathStr = toPathString ( oldPath ) ;
12211244 const newPathStr = toPathString ( newPath ) ;
1222- _fs . rename ( oldPathStr , newPathStr ) ;
1245+ _fs . rename . applySyncPromise ( undefined , [ oldPathStr , newPathStr ] ) ;
12231246 } ,
12241247
12251248 copyFileSync ( src : PathLike , dest : PathLike , _mode ?: number ) : void {
@@ -1550,41 +1573,41 @@ const fs = {
15501573 chmodSync ( path : PathLike , mode : Mode ) : void {
15511574 const pathStr = toPathString ( path ) ;
15521575 const modeNum = typeof mode === "string" ? parseInt ( mode , 8 ) : mode ;
1553- bridgeCall ( ( ) => _fs . chmod ( pathStr , modeNum ) , "chmod" , pathStr ) ;
1576+ bridgeCall ( ( ) => _fs . chmod . applySyncPromise ( undefined , [ pathStr , modeNum ] ) , "chmod" , pathStr ) ;
15541577 } ,
15551578
15561579 chownSync ( path : PathLike , uid : number , gid : number ) : void {
15571580 const pathStr = toPathString ( path ) ;
1558- bridgeCall ( ( ) => _fs . chown ( pathStr , uid , gid ) , "chown" , pathStr ) ;
1581+ bridgeCall ( ( ) => _fs . chown . applySyncPromise ( undefined , [ pathStr , uid , gid ] ) , "chown" , pathStr ) ;
15591582 } ,
15601583
15611584 linkSync ( existingPath : PathLike , newPath : PathLike ) : void {
15621585 const existingStr = toPathString ( existingPath ) ;
15631586 const newStr = toPathString ( newPath ) ;
1564- bridgeCall ( ( ) => _fs . link ( existingStr , newStr ) , "link" , newStr ) ;
1587+ bridgeCall ( ( ) => _fs . link . applySyncPromise ( undefined , [ existingStr , newStr ] ) , "link" , newStr ) ;
15651588 } ,
15661589
15671590 symlinkSync ( target : PathLike , path : PathLike , _type ?: string | null ) : void {
15681591 const targetStr = toPathString ( target ) ;
15691592 const pathStr = toPathString ( path ) ;
1570- bridgeCall ( ( ) => _fs . symlink ( targetStr , pathStr ) , "symlink" , pathStr ) ;
1593+ bridgeCall ( ( ) => _fs . symlink . applySyncPromise ( undefined , [ targetStr , pathStr ] ) , "symlink" , pathStr ) ;
15711594 } ,
15721595
15731596 readlinkSync ( path : PathLike , _options ?: nodeFs . EncodingOption ) : string {
15741597 const pathStr = toPathString ( path ) ;
1575- return bridgeCall ( ( ) => _fs . readlink ( pathStr ) , "readlink" , pathStr ) ;
1598+ return bridgeCall ( ( ) => _fs . readlink . applySyncPromise ( undefined , [ pathStr ] ) , "readlink" , pathStr ) ;
15761599 } ,
15771600
15781601 truncateSync ( path : PathLike , len ?: number | null ) : void {
15791602 const pathStr = toPathString ( path ) ;
1580- bridgeCall ( ( ) => _fs . truncate ( pathStr , len ?? 0 ) , "truncate" , pathStr ) ;
1603+ bridgeCall ( ( ) => _fs . truncate . applySyncPromise ( undefined , [ pathStr , len ?? 0 ] ) , "truncate" , pathStr ) ;
15811604 } ,
15821605
15831606 utimesSync ( path : PathLike , atime : string | number | Date , mtime : string | number | Date ) : void {
15841607 const pathStr = toPathString ( path ) ;
15851608 const atimeNum = typeof atime === "number" ? atime : new Date ( atime ) . getTime ( ) / 1000 ;
15861609 const mtimeNum = typeof mtime === "number" ? mtime : new Date ( mtime ) . getTime ( ) / 1000 ;
1587- bridgeCall ( ( ) => _fs . utimes ( pathStr , atimeNum , mtimeNum ) , "utimes" , pathStr ) ;
1610+ bridgeCall ( ( ) => _fs . utimes . applySyncPromise ( undefined , [ pathStr , atimeNum , mtimeNum ] ) , "utimes" , pathStr ) ;
15881611 } ,
15891612
15901613 // Async methods - wrap sync methods in callbacks/promises
0 commit comments