@@ -4,6 +4,8 @@ const errors = require('internal/errors');
44const  binding  =  process . binding ( 'util' ) ; 
55const  signals  =  process . binding ( 'constants' ) . os . signals ; 
66
7+ const  {  createPromise,  promiseResolve,  promiseReject }  =  binding ; 
8+ 
79const  kArrowMessagePrivateSymbolIndex  =  binding [ 'arrow_message_private_symbol' ] ; 
810const  kDecoratedPrivateSymbolIndex  =  binding [ 'decorated_private_symbol' ] ; 
911const  noCrypto  =  ! process . versions . openssl ; 
@@ -217,3 +219,62 @@ module.exports = exports = {
217219  // default isEncoding implementation, just in case userland overrides it. 
218220  kIsEncodingSymbol : Symbol ( 'node.isEncoding' ) 
219221} ; 
222+ 
223+ const  kCustomPromisifiedSymbol  =  Symbol ( 'util.promisify.custom' ) ; 
224+ const  kCustomPromisifyArgsSymbol  =  Symbol ( 'customPromisifyArgs' ) ; 
225+ 
226+ function  promisify ( orig )  { 
227+   if  ( typeof  orig  !==  'function' )  { 
228+     const  errors  =  require ( 'internal/errors' ) ; 
229+     throw  new  errors . TypeError ( 'ERR_INVALID_ARG_TYPE' ,  'original' ,  'function' ) ; 
230+   } 
231+ 
232+   if  ( orig [ kCustomPromisifiedSymbol ] )  { 
233+     const  fn  =  orig [ kCustomPromisifiedSymbol ] ; 
234+     if  ( typeof  fn  !==  'function' )  { 
235+       throw  new  TypeError ( 'The [util.promisify.custom] property must be '  + 
236+                           'a function' ) ; 
237+     } 
238+     Object . defineProperty ( fn ,  kCustomPromisifiedSymbol ,  { 
239+       value : fn ,  enumerable : false ,  writable : false ,  configurable : true 
240+     } ) ; 
241+     return  fn ; 
242+   } 
243+ 
244+   // Names to create an object from in case the callback receives multiple 
245+   // arguments, e.g. ['stdout', 'stderr'] for child_process.exec. 
246+   const  argumentNames  =  orig [ kCustomPromisifyArgsSymbol ] ; 
247+ 
248+   function  fn ( ...args )  { 
249+     const  promise  =  createPromise ( ) ; 
250+     try  { 
251+       orig . call ( this ,  ...args ,  ( err ,  ...values )  =>  { 
252+         if  ( err )  { 
253+           promiseReject ( promise ,  err ) ; 
254+         }  else  if  ( argumentNames  !==  undefined  &&  values . length  >  1 )  { 
255+           const  obj  =  { } ; 
256+           for  ( var  i  =  0 ;  i  <  argumentNames . length ;  i ++ ) 
257+             obj [ argumentNames [ i ] ]  =  values [ i ] ; 
258+           promiseResolve ( promise ,  obj ) ; 
259+         }  else  { 
260+           promiseResolve ( promise ,  values [ 0 ] ) ; 
261+         } 
262+       } ) ; 
263+     }  catch  ( err )  { 
264+       promiseReject ( promise ,  err ) ; 
265+     } 
266+     return  promise ; 
267+   } 
268+ 
269+   Object . setPrototypeOf ( fn ,  Object . getPrototypeOf ( orig ) ) ; 
270+ 
271+   Object . defineProperty ( fn ,  kCustomPromisifiedSymbol ,  { 
272+     value : fn ,  enumerable : false ,  writable : false ,  configurable : true 
273+   } ) ; 
274+   return  Object . defineProperties ( fn ,  Object . getOwnPropertyDescriptors ( orig ) ) ; 
275+ } 
276+ 
277+ promisify . custom  =  kCustomPromisifiedSymbol ; 
278+ 
279+ exports . promisify  =  promisify ; 
280+ exports . customPromisifyArgs  =  kCustomPromisifyArgsSymbol ; 
0 commit comments