"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Fn = Fn;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _lodash = require("lodash");

var _arg = require("./arg");

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function Fn(config) {
  var _this = this;

  // Required
  this.name = config.name; // Name of function
  // Return type of function.
  // This SHOULD be supplied. We use it for UI and autocomplete hinting,
  // We may also use it for optimizations in the future.

  this.type = config.type;
  this.aliases = config.aliases || []; // Function to run function (context, args)

  this.fn = function () {
    return Promise.resolve(config.fn.apply(config, arguments));
  }; // Optional


  this.help = config.help || ''; // A short help text

  this.args = (0, _lodash.mapValues)(config.args || {}, function (arg, name) {
    return new _arg.Arg(_objectSpread({
      name: name
    }, arg));
  });
  this.context = config.context || {};

  this.accepts = function (type) {
    if (!_this.context.types) return true; // If you don't tell us about context, we'll assume you don't care what you get

    return (0, _lodash.includes)(_this.context.types, type); // Otherwise, check it
  };
}