11'use strict' 
22
3- const  util  =  require ( 'util' ) 
4- 
5- const  fs  =  require ( 'fs' ) 
3+ const  fs  =  require ( '@npmcli/fs' ) 
64const  fsm  =  require ( 'fs-minipass' ) 
75const  ssri  =  require ( 'ssri' ) 
86const  contentPath  =  require ( './path' ) 
97const  Pipeline  =  require ( 'minipass-pipeline' ) 
108
11- const  lstat  =  util . promisify ( fs . lstat ) 
12- const  readFile  =  util . promisify ( fs . readFile ) 
13- const  copyFile  =  util . promisify ( fs . copyFile ) 
14- 
159module . exports  =  read 
1610
1711const  MAX_SINGLE_READ_SIZE  =  64  *  1024  *  1024 
18- function  read  ( cache ,  integrity ,  opts  =  { } )  { 
12+ async   function  read  ( cache ,  integrity ,  opts  =  { } )  { 
1913  const  {  size }  =  opts 
20-   return   withContentSri ( cache ,  integrity ,  ( cpath ,  sri )  =>  { 
14+   const   {  stat ,  cpath ,  sri  }   =   await   withContentSri ( cache ,  integrity ,   async  ( cpath ,  sri )  =>  { 
2115    // get size 
22-     return  lstat ( cpath ) . then ( stat  =>  ( {  stat,  cpath,  sri } ) ) 
23-   } ) . then ( ( {  stat,  cpath,  sri } )  =>  { 
24-     if  ( typeof  size  ===  'number'  &&  stat . size  !==  size )  { 
25-       throw  sizeError ( size ,  stat . size ) 
26-     } 
16+     const  stat  =  await  fs . lstat ( cpath ) 
17+     return  {  stat,  cpath,  sri } 
18+   } ) 
19+   if  ( typeof  size  ===  'number'  &&  stat . size  !==  size )  { 
20+     throw  sizeError ( size ,  stat . size ) 
21+   } 
2722
28-      if  ( stat . size  >  MAX_SINGLE_READ_SIZE )  { 
29-        return  readPipeline ( cpath ,  stat . size ,  sri ,  new  Pipeline ( ) ) . concat ( ) 
30-      } 
23+   if  ( stat . size  >  MAX_SINGLE_READ_SIZE )  { 
24+     return  readPipeline ( cpath ,  stat . size ,  sri ,  new  Pipeline ( ) ) . concat ( ) 
25+   } 
3126
32-      return   readFile ( cpath ,  null ) . then ( ( data )   =>   { 
33-        if  ( ! ssri . checkData ( data ,  sri ) )  { 
34-          throw  integrityError ( sri ,  cpath ) 
35-        } 
27+   const   data   =   await   fs . readFile ( cpath ,  {   encoding :  null   } ) 
28+   if  ( ! ssri . checkData ( data ,  sri ) )  { 
29+     throw  integrityError ( sri ,  cpath ) 
30+   } 
3631
37-       return  data 
38-     } ) 
39-   } ) 
32+   return  data 
4033} 
4134
4235const  readPipeline  =  ( cpath ,  size ,  sri ,  stream )  =>  { 
@@ -58,7 +51,7 @@ module.exports.sync = readSync
5851function  readSync  ( cache ,  integrity ,  opts  =  { } )  { 
5952  const  {  size }  =  opts 
6053  return  withContentSriSync ( cache ,  integrity ,  ( cpath ,  sri )  =>  { 
61-     const  data  =  fs . readFileSync ( cpath ) 
54+     const  data  =  fs . readFileSync ( cpath ,   {   encoding :  null   } ) 
6255    if  ( typeof  size  ===  'number'  &&  size  !==  data . length )  { 
6356      throw  sizeError ( size ,  data . length ) 
6457    } 
@@ -77,16 +70,19 @@ module.exports.readStream = readStream
7770function  readStream  ( cache ,  integrity ,  opts  =  { } )  { 
7871  const  {  size }  =  opts 
7972  const  stream  =  new  Pipeline ( ) 
80-   withContentSri ( cache ,  integrity ,  ( cpath ,  sri )  =>  { 
81-     // just lstat to ensure it exists 
82-     return  lstat ( cpath ) . then ( ( stat )  =>  ( {  stat,  cpath,  sri } ) ) 
83-   } ) . then ( ( {  stat,  cpath,  sri } )  =>  { 
73+   // Set all this up to run on the stream and then just return the stream 
74+   Promise . resolve ( ) . then ( async  ( )  =>  { 
75+     const  {  stat,  cpath,  sri }  =  await  withContentSri ( cache ,  integrity ,  async  ( cpath ,  sri )  =>  { 
76+       // just lstat to ensure it exists 
77+       const  stat  =  await  fs . lstat ( cpath ) 
78+       return  {  stat,  cpath,  sri } 
79+     } ) 
8480    if  ( typeof  size  ===  'number'  &&  size  !==  stat . size )  { 
8581      return  stream . emit ( 'error' ,  sizeError ( size ,  stat . size ) ) 
8682    } 
8783
8884    readPipeline ( cpath ,  stat . size ,  sri ,  stream ) 
89-   } ,   er   =>  stream . emit ( 'error' ,  er ) ) 
85+   } ) . catch ( err   =>  stream . emit ( 'error' ,  err ) ) 
9086
9187  return  stream 
9288} 
@@ -96,7 +92,7 @@ module.exports.copy.sync = copySync
9692
9793function  copy  ( cache ,  integrity ,  dest )  { 
9894  return  withContentSri ( cache ,  integrity ,  ( cpath ,  sri )  =>  { 
99-     return  copyFile ( cpath ,  dest ) 
95+     return  fs . copyFile ( cpath ,  dest ) 
10096  } ) 
10197} 
10298
@@ -108,14 +104,17 @@ function copySync (cache, integrity, dest) {
108104
109105module . exports . hasContent  =  hasContent 
110106
111- function  hasContent  ( cache ,  integrity )  { 
107+ async   function  hasContent  ( cache ,  integrity )  { 
112108  if  ( ! integrity )  { 
113-     return  Promise . resolve ( false ) 
109+     return  false 
114110  } 
115111
116-   return  withContentSri ( cache ,  integrity ,  ( cpath ,  sri )  =>  { 
117-     return  lstat ( cpath ) . then ( ( stat )  =>  ( {  size : stat . size ,  sri,  stat } ) ) 
118-   } ) . catch ( ( err )  =>  { 
112+   try  { 
113+     return  await  withContentSri ( cache ,  integrity ,  async  ( cpath ,  sri )  =>  { 
114+       const  stat  =  await  fs . lstat ( cpath ) 
115+       return  {  size : stat . size ,  sri,  stat } 
116+     } ) 
117+   }  catch  ( err )  { 
119118    if  ( err . code  ===  'ENOENT' )  { 
120119      return  false 
121120    } 
@@ -128,7 +127,7 @@ function hasContent (cache, integrity) {
128127        return  false 
129128      } 
130129    } 
131-   } ) 
130+   } 
132131} 
133132
134133module . exports . hasContent . sync  =  hasContentSync 
@@ -159,61 +158,47 @@ function hasContentSync (cache, integrity) {
159158  } ) 
160159} 
161160
162- function  withContentSri  ( cache ,  integrity ,  fn )  { 
163-   const  tryFn  =  ( )  =>  { 
164-     const  sri  =  ssri . parse ( integrity ) 
165-     // If `integrity` has multiple entries, pick the first digest 
166-     // with available local data. 
167-     const  algo  =  sri . pickAlgorithm ( ) 
168-     const  digests  =  sri [ algo ] 
169- 
170-     if  ( digests . length  <=  1 )  { 
171-       const  cpath  =  contentPath ( cache ,  digests [ 0 ] ) 
172-       return  fn ( cpath ,  digests [ 0 ] ) 
173-     }  else  { 
174-       // Can't use race here because a generic error can happen before 
175-       // a ENOENT error, and can happen before a valid result 
176-       return  Promise 
177-         . all ( digests . map ( ( meta )  =>  { 
178-           return  withContentSri ( cache ,  meta ,  fn ) 
179-             . catch ( ( err )  =>  { 
180-               if  ( err . code  ===  'ENOENT' )  { 
181-                 return  Object . assign ( 
182-                   new  Error ( 'No matching content found for '  +  sri . toString ( ) ) , 
183-                   {  code : 'ENOENT'  } 
184-                 ) 
185-               } 
186-               return  err 
187-             } ) 
188-         } ) ) 
189-         . then ( ( results )  =>  { 
190-           // Return the first non error if it is found 
191-           const  result  =  results . find ( ( r )  =>  ! ( r  instanceof  Error ) ) 
192-           if  ( result )  { 
193-             return  result 
194-           } 
195- 
196-           // Throw the No matching content found error 
197-           const  enoentError  =  results . find ( ( r )  =>  r . code  ===  'ENOENT' ) 
198-           if  ( enoentError )  { 
199-             throw  enoentError 
200-           } 
201- 
202-           // Throw generic error 
203-           throw  results . find ( ( r )  =>  r  instanceof  Error ) 
204-         } ) 
161+ async  function  withContentSri  ( cache ,  integrity ,  fn )  { 
162+   const  sri  =  ssri . parse ( integrity ) 
163+   // If `integrity` has multiple entries, pick the first digest 
164+   // with available local data. 
165+   const  algo  =  sri . pickAlgorithm ( ) 
166+   const  digests  =  sri [ algo ] 
167+ 
168+   if  ( digests . length  <=  1 )  { 
169+     const  cpath  =  contentPath ( cache ,  digests [ 0 ] ) 
170+     return  fn ( cpath ,  digests [ 0 ] ) 
171+   }  else  { 
172+     // Can't use race here because a generic error can happen before 
173+     // a ENOENT error, and can happen before a valid result 
174+     const  results  =  await  Promise . all ( digests . map ( async  ( meta )  =>  { 
175+       try  { 
176+         return  await  withContentSri ( cache ,  meta ,  fn ) 
177+       }  catch  ( err )  { 
178+         if  ( err . code  ===  'ENOENT' )  { 
179+           return  Object . assign ( 
180+             new  Error ( 'No matching content found for '  +  sri . toString ( ) ) , 
181+             {  code : 'ENOENT'  } 
182+           ) 
183+         } 
184+         return  err 
185+       } 
186+     } ) ) 
187+     // Return the first non error if it is found 
188+     const  result  =  results . find ( ( r )  =>  ! ( r  instanceof  Error ) ) 
189+     if  ( result )  { 
190+       return  result 
205191    } 
206-   } 
207192
208-   return  new  Promise ( ( resolve ,  reject )  =>  { 
209-     try  { 
210-       tryFn ( ) 
211-         . then ( resolve ) 
212-         . catch ( reject ) 
213-     }  catch  ( err )  { 
214-       reject ( err ) 
193+     // Throw the No matching content found error 
194+     const  enoentError  =  results . find ( ( r )  =>  r . code  ===  'ENOENT' ) 
195+     if  ( enoentError )  { 
196+       throw  enoentError 
215197    } 
216-   } ) 
198+ 
199+     // Throw generic error 
200+     throw  results . find ( ( r )  =>  r  instanceof  Error ) 
201+   } 
217202} 
218203
219204function  withContentSriSync  ( cache ,  integrity ,  fn )  { 
0 commit comments