runCallbacksAsync = function() {
  let hook, args, callbacks, formattedHook;
  if (typeof arguments[0] === 'object' && arguments.length === 1) {
    const singleArgument = arguments[0];
    hook = singleArgument.name;
    formattedHook = formatHookName(hook);
    args = [singleArgument.properties]; // wrap in array for apply
    callbacks = singleArgument.callbacks ? singleArgument.callbacks : Callbacks[formattedHook];
  } else {
    // OpenCRUD backwards compatibility
    // the first argument is the name of the hook or an array of functions
    hook = arguments[0];
    formattedHook = formatHookName(hook);
    callbacks = Array.isArray(hook) ? hook : Callbacks[formattedHook];
    // successive arguments are passed to each iteration
    args = Array.prototype.slice.call(arguments).slice(1);
    // if first argument is an array, use that as callbacks array; else use formatted hook name
    callbacks = Array.isArray(hook) ? hook : Callbacks[formattedHook];
  }

  if (typeof callbacks !== 'undefined' && !!callbacks.length) {
    const _runCallbacksAsync = () =>
        Promise.all(
            callbacks.map(callback => {
                if (!callback) {
                  throw new Error(`Found undefined callback on hook ${hook}`);
                }
                debug(`\x1b[32m>> Running async callback [${callback.name}] on hook [${hook}]\x1b[0m`);
                return callback.apply(this, args);
            }),
        );

    if (Meteor.isServer) {
      // TODO: find out if we can safely use promises on the server, too - https://github.com/VulcanJS/Vulcan/pull/2065
      return new Promise(async (resolve, reject) => {
          Meteor.defer(function() {
            _runCallbacksAsync().then(resolve).catch(reject);
          });
      });
    }
    return _runCallbacksAsync();
  }
  return [];
}
@summary Successively run all of a hook's callbacks on an item, in async mode (only works on server)
@param {String} hook - First argument: the name of the hook
@param {Any} args - Other arguments will be passed to each successive iteration