@@ -1055,3 +1055,53 @@ process.versions[exports.inspect.custom] =
10551055 ( depth ) => exports . format ( JSON . parse ( JSON . stringify ( process . versions ) ) ) ;
10561056
10571057exports . promisify = internalUtil . promisify ;
1058+
1059+ function callbackifyOnRejected ( reason , cb ) {
1060+ // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
1061+ // Because `null` is a special error value in callbacks which means "no error
1062+ // occurred", we error-wrap so the callback consumer can distinguish between
1063+ // "the promise rejected with null" or "the promise fulfilled with undefined".
1064+ if ( ! reason ) {
1065+ const newReason = new errors . Error ( 'FALSY_VALUE_REJECTION' ) ;
1066+ newReason . reason = reason ;
1067+ reason = newReason ;
1068+ Error . captureStackTrace ( reason , callbackifyOnRejected ) ;
1069+ }
1070+ return cb ( reason ) ;
1071+ }
1072+
1073+
1074+ function callbackify ( original ) {
1075+ if ( typeof original !== 'function' ) {
1076+ throw new errors . TypeError (
1077+ 'ERR_INVALID_ARG_TYPE' ,
1078+ 'original' ,
1079+ 'function' ) ;
1080+ }
1081+
1082+ // We DO NOT return the promise as it gives the user a false sense that
1083+ // the promise is actually somehow related to the callback's execution
1084+ // and that the callback throwing will reject the promise.
1085+ function callbackified ( ...args ) {
1086+ const maybeCb = args . pop ( ) ;
1087+ if ( typeof maybeCb !== 'function' ) {
1088+ throw new errors . TypeError (
1089+ 'ERR_INVALID_ARG_TYPE' ,
1090+ 'last argument' ,
1091+ 'function' ) ;
1092+ }
1093+ const cb = ( ...args ) => { Reflect . apply ( maybeCb , this , args ) ; } ;
1094+ // In true node style we process the callback on `nextTick` with all the
1095+ // implications (stack, `uncaughtException`, `async_hooks`)
1096+ Reflect . apply ( original , this , args )
1097+ . then ( ( ret ) => process . nextTick ( cb , null , ret ) ,
1098+ ( rej ) => process . nextTick ( callbackifyOnRejected , rej , cb ) ) ;
1099+ }
1100+
1101+ Object . setPrototypeOf ( callbackified , Object . getPrototypeOf ( original ) ) ;
1102+ Object . defineProperties ( callbackified ,
1103+ Object . getOwnPropertyDescriptors ( original ) ) ;
1104+ return callbackified ;
1105+ }
1106+
1107+ exports . callbackify = callbackify ;
0 commit comments