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