code: function wrapFunction(fn, firstArg) {
    return function() {
      var resolve, reject;
      var promise = new Promise(function(res, rej) {
        resolve = res;
        reject = rej;
      });
  
      var args = [].slice.call(arguments);
      var originalCallback = args[firstArg ? 0 : args.length - 1];
  
      function callback(err, value) {
        if (originalCallback)
          originalCallback.apply(this, arguments);
  
        if (err)
          reject(err);
        else
          resolve(value);
      }
  
      if (typeof originalCallback !== 'function') {
        // Callback wasn't provided to the async function, add the custom one.
        originalCallback = null;
        if (firstArg)
          args.unshift(callback);
        else
          args.push(callback);
      } else {
        // Callback was provided to the async function, replace it.
        args[firstArg ? 0 : args.length - 1] = callback;
      }
  
      fn.apply(this, args);
  
      return promise;
    };
  }
docs: Wrap a single async function to make the callback optional and hook it to
  trigger reject/resolve of the Promise, which it returns (this ignores the
  async function's return value). This enables the use of await with the
  wrapped function.
  
  @param {Function} fn Function to wrap.
  @param {boolean} firstArg True if the async callback is the first argument.
  @return {Function}