@@ -4,6 +4,8 @@ const errors = require('internal/errors');
4
4
const binding = process . binding ( 'util' ) ;
5
5
const signals = process . binding ( 'constants' ) . os . signals ;
6
6
7
+ const { createPromise, promiseResolve, promiseReject } = binding ;
8
+
7
9
const kArrowMessagePrivateSymbolIndex = binding [ 'arrow_message_private_symbol' ] ;
8
10
const kDecoratedPrivateSymbolIndex = binding [ 'decorated_private_symbol' ] ;
9
11
const noCrypto = ! process . versions . openssl ;
@@ -217,3 +219,62 @@ module.exports = exports = {
217
219
// default isEncoding implementation, just in case userland overrides it.
218
220
kIsEncodingSymbol : Symbol ( 'node.isEncoding' )
219
221
} ;
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