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