@@ -4,61 +4,91 @@ import {HAS_LAZY_LOADED_TRANSLATORS} from './loaderFlags';
44
55//#region ESM to CJS support
66if ( ! HAS_LAZY_LOADED_TRANSLATORS ) {
7- /*
8- In order to import CJS files from ESM Node does some translating
9- internally[1]. This translator calls an unpatched `readFileSync`[2]
10- which itself calls an internal `tryStatSync`[3] which calls
11- `binding.fstat`[4]. A PR[5] has been made to use the monkey-patchable
12- `fs.readFileSync` but assuming that wont be merged this region of code
13- patches that final `binding.fstat` call.
14-
15- 1: https://github.com/nodejs/node/blob/d872aaf1cf20d5b6f56a699e2e3a64300e034269/lib/internal/modules/esm/translators.js#L177-L277
16- 2: https://github.com/nodejs/node/blob/d872aaf1cf20d5b6f56a699e2e3a64300e034269/lib/internal/modules/esm/translators.js#L240
17- 3: https://github.com/nodejs/node/blob/1317252dfe8824fd9cfee125d2aaa94004db2f3b/lib/fs.js#L452
18- 4: https://github.com/nodejs/node/blob/1317252dfe8824fd9cfee125d2aaa94004db2f3b/lib/fs.js#L403
19- 5: https://github.com/nodejs/node/pull/39513
20- */
21-
227 const binding = ( process as any ) . binding ( `fs` ) as {
238 fstat : ( fd : number , useBigint : false , req : any , ctx : object ) => Float64Array ;
9+ /**
10+ * Added in https://github.com/nodejs/node/pull/48658 / v20.5.0
11+ * Renamed in https://github.com/nodejs/node/pull/49593 / v20.8.0
12+ */
13+ readFileSync ?: ( path : string , flag : number ) => string ;
14+ /**
15+ * Added in https://github.com/nodejs/node/pull/49593
16+ */
17+ readFileUtf8 ?: ( path : string , flag : number ) => string ;
2418 } ;
25- const originalfstat = binding . fstat ;
26-
27- // Those values must be synced with packages/yarnpkg-fslib/sources/ZipOpenFS.ts
28- const ZIP_MASK = 0xff000000 ;
29- const ZIP_MAGIC = 0x2a000000 ;
3019
31- binding . fstat = function ( ... args ) {
32- const [ fd , useBigint , req ] = args ;
33- if ( ( fd & ZIP_MASK ) === ZIP_MAGIC && useBigint === false && req === undefined ) {
20+ const originalReadFile = binding . readFileUtf8 || binding . readFileSync ;
21+ if ( originalReadFile ) {
22+ binding . readFileSync = binding . readFileUtf8 = function ( ... args ) {
3423 try {
35- const stats = fs . fstatSync ( fd ) ;
36- // The reverse of this internal util
37- // https://github.com/nodejs/node/blob/8886b63cf66c29d453fdc1ece2e489dace97ae9d/lib/internal/fs/utils.js#L542-L551
38- return new Float64Array ( [
39- stats . dev ,
40- stats . mode ,
41- stats . nlink ,
42- stats . uid ,
43- stats . gid ,
44- stats . rdev ,
45- stats . blksize ,
46- stats . ino ,
47- stats . size ,
48- stats . blocks ,
49- // atime sec
50- // atime ns
51- // mtime sec
52- // mtime ns
53- // ctime sec
54- // ctime ns
55- // birthtime sec
56- // birthtime ns
57- ] ) ;
58- } catch { }
59- }
24+ return fs . readFileSync ( args [ 0 ] , {
25+ encoding : `utf8` ,
26+ // @ts -expect-error - The docs says it needs to be a string but
27+ // links to https://nodejs.org/dist/latest-v20.x/docs/api/fs.html#file-system-flags
28+ // which says it can be a number which matches the implementation.
29+ flag : args [ 1 ] ,
30+ } ) ;
31+ } catch { }
6032
61- return originalfstat . apply ( this , args ) ;
62- } ;
33+ return originalReadFile . apply ( this , args ) ;
34+ } ;
35+ } else {
36+ /*
37+ In order to import CJS files from ESM Node does some translating
38+ internally[1]. This translator calls an unpatched `readFileSync`[2]
39+ which itself calls an internal `tryStatSync`[3] which calls
40+ `binding.fstat`[4]. A PR[5] has been made to use the monkey-patchable
41+ `fs.readFileSync` but assuming that wont be merged this region of code
42+ patches that final `binding.fstat` call.
43+
44+ 1: https://github.com/nodejs/node/blob/d872aaf1cf20d5b6f56a699e2e3a64300e034269/lib/internal/modules/esm/translators.js#L177-L277
45+ 2: https://github.com/nodejs/node/blob/d872aaf1cf20d5b6f56a699e2e3a64300e034269/lib/internal/modules/esm/translators.js#L240
46+ 3: https://github.com/nodejs/node/blob/1317252dfe8824fd9cfee125d2aaa94004db2f3b/lib/fs.js#L452
47+ 4: https://github.com/nodejs/node/blob/1317252dfe8824fd9cfee125d2aaa94004db2f3b/lib/fs.js#L403
48+ 5: https://github.com/nodejs/node/pull/39513
49+ */
50+
51+ const binding = ( process as any ) . binding ( `fs` ) as {
52+ fstat : ( fd : number , useBigint : false , req : any , ctx : object ) => Float64Array ;
53+ } ;
54+ const originalfstat = binding . fstat ;
55+
56+ // Those values must be synced with packages/yarnpkg-fslib/sources/ZipOpenFS.ts
57+ const ZIP_MASK = 0xff000000 ;
58+ const ZIP_MAGIC = 0x2a000000 ;
59+
60+ binding . fstat = function ( ...args ) {
61+ const [ fd , useBigint , req ] = args ;
62+ if ( ( fd & ZIP_MASK ) === ZIP_MAGIC && useBigint === false && req === undefined ) {
63+ try {
64+ const stats = fs . fstatSync ( fd ) ;
65+ // The reverse of this internal util
66+ // https://github.com/nodejs/node/blob/8886b63cf66c29d453fdc1ece2e489dace97ae9d/lib/internal/fs/utils.js#L542-L551
67+ return new Float64Array ( [
68+ stats . dev ,
69+ stats . mode ,
70+ stats . nlink ,
71+ stats . uid ,
72+ stats . gid ,
73+ stats . rdev ,
74+ stats . blksize ,
75+ stats . ino ,
76+ stats . size ,
77+ stats . blocks ,
78+ // atime sec
79+ // atime ns
80+ // mtime sec
81+ // mtime ns
82+ // ctime sec
83+ // ctime ns
84+ // birthtime sec
85+ // birthtime ns
86+ ] ) ;
87+ } catch { }
88+ }
89+
90+ return originalfstat . apply ( this , args ) ;
91+ } ;
92+ }
6393}
6494//#endregion
0 commit comments