• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const ObjectGetOwnPropertyDescriptors = require('object.getownpropertydescriptors');
4const util = require('util');
5const timers = require('timers');
6
7const kCustomPromisifiedSymbol = util.promisify && util.promisify.custom || Symbol('util.promisify.custom');
8//const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs');
9
10function promisify(orig) {
11  if (typeof orig !== 'function') {
12    //const errors = require('internal/errors');
13    //throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'original', 'function');
14    var err = TypeError(`The "original" argument must be of type function`);
15    err.code = 'ERR_INVALID_ARG_TYPE';
16    err.name = `TypeError [${err.code}]`;
17    throw err
18  }
19
20  if (orig === timers.setTimeout || orig === timers.setImmediate) {
21    const _orig = orig
22    orig = function () {
23      var args = [];
24      for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]);
25      const _cb = args.pop()
26      const cb = function () {
27        var args = [];
28        for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]);
29        _cb.apply(null, [null].concat(args))
30      }
31      _orig.apply(timers, [cb].concat(args))
32    }
33  }
34
35  if (orig[kCustomPromisifiedSymbol]) {
36    const fn = orig[kCustomPromisifiedSymbol];
37    if (typeof fn !== 'function') {
38      throw new TypeError('The [util.promisify.custom] property must be ' +
39                          'a function');
40    }
41    Object.defineProperty(fn, kCustomPromisifiedSymbol, {
42      value: fn, enumerable: false, writable: false, configurable: true
43    });
44    return fn;
45  }
46
47  // Names to create an object from in case the callback receives multiple
48  // arguments, e.g. ['stdout', 'stderr'] for child_process.exec.
49  //const argumentNames = orig[kCustomPromisifyArgsSymbol];
50
51  function fn() {
52    var args = [];
53    for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]);
54
55    let resolve, reject;
56    const promise = new Promise(function (_resolve, _reject) {
57      resolve = _resolve;
58      reject = _reject;
59    });
60    try {
61      orig.apply(this, args.concat(function (err) {
62        var values = [];
63        for (var i = 1; i < arguments.length; i++) values.push(arguments[i]);
64        if (err) {
65          reject(err);
66        //} else if (argumentNames !== undefined && values.length > 1) {
67        //  const obj = {};
68        //  for (var i = 0; i < argumentNames.length; i++)
69        //    obj[argumentNames[i]] = values[i];
70        //  resolve(obj);
71        } else {
72          resolve(values[0]);
73        }
74      }));
75    } catch (err) {
76      reject(err);
77    }
78    return promise;
79  }
80
81  Object.setPrototypeOf(fn, Object.getPrototypeOf(orig));
82
83  Object.defineProperty(fn, kCustomPromisifiedSymbol, {
84    value: fn, enumerable: false, writable: false, configurable: true
85  });
86  return Object.defineProperties(fn, ObjectGetOwnPropertyDescriptors(orig));
87}
88
89promisify.custom = kCustomPromisifiedSymbol;
90
91module.exports = promisify;
92