@@ -1047,3 +1047,53 @@ process.versions[exports.inspect.custom] =
10471047 ( depth ) => exports . format ( JSON . parse ( JSON . stringify ( process . versions ) ) ) ;
10481048
10491049exports . 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