@@ -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