mick-whats/args2-node

View on GitHub
lib/index.js

Summary

Maintainability
D
2 days
Test Coverage
// Generated by CoffeeScript 1.12.7
(function() {
  var Args2,
    _,
    slice = [].slice;

  _ = require('lodash-core');

  Args2 = (function() {
    var choiceInternalFunction;

    function Args2(args1) {
      var args, res;
      this.args = args1;
      if (this['arguments'] != null) {
        args = Array.prototype.slice.call(this['arguments'], 0);
      } else if (this.args) {
        args = Array.prototype.slice.call(this.args, 0);
      } else {
        args = Array.prototype.slice.call(this, 0);
      }
      this.args = args;
      res = {
        nums: [],
        strs: [],
        objs: [],
        arrays: [],
        bools: [],
        funcs: [],
        others: []
      };
      args.forEach(function(item) {
        if (_.isNumber(item)) {
          return res.nums.push(item);
        } else if (_.isString(item)) {
          return res.strs.push(item);
        } else if (_.isPlainObject(item)) {
          return res.objs.push(item);
        } else if (_.isArray(item)) {
          return res.arrays.push(item);
        } else if (_.isBoolean(item)) {
          return res.bools.push(item);
        } else if (_.isFunction(item)) {
          return res.funcs.push(item);
        } else {
          return res.others.push(item);
        }
      });
      _.merge(this, res);
      return this;
    }

    Args2.prototype.get = function(
      typingFn,
      argType,
      required,
      defaultValue,
      last
    ) {
      var argArray, dict, errMsg, ref, refIndex;
      if (last == null) {
        last = false;
      }
      dict = {
        strs: 'String',
        nums: 'Number',
        objs: 'Object',
        arrays: 'Array',
        bools: 'Boolean',
        funcs: 'Function',
        others: 'Other'
      };
      argArray = this[argType];
      if (argArray.length) {
        if (last) {
          ref = argArray.pop();
          if (!_.isUndefined(ref)) {
            refIndex = _.findLastIndex(this.args, function(o) {
              if (_.isFunction(typingFn)) {
                return typingFn(o);
              } else {
                return ref === o;
              }
            });
            this.args.splice(refIndex, 1);
          }
          return ref;
        } else {
          ref = argArray.shift();
          if (!_.isUndefined(ref)) {
            refIndex = _.findIndex(this.args, function(o) {
              if (_.isFunction(typingFn)) {
                return typingFn(o);
              } else {
                return ref === o;
              }
            });
            this.args.splice(refIndex, 1);
          }
          return ref;
        }
      } else {
        if (required) {
          if (defaultValue) {
            errMsg = defaultValue;
          } else {
            errMsg = dict[argType] + ' argument required';
          }
          throw new Error(errMsg);
        } else if (_.isUndefined(defaultValue)) {
          return void 0;
        } else {
          return defaultValue;
        }
      }
    };

    Args2.prototype.str = function(required, defaultValue) {
      return this.get(_.isString, 'strs', required, defaultValue);
    };

    Args2.prototype.num = function(required, defaultValue) {
      return this.get(_.isNumber, 'nums', required, defaultValue);
    };

    Args2.prototype.obj = function(required, defaultValue) {
      return this.get(_.isPlainObject, 'objs', required, defaultValue);
    };

    Args2.prototype.array = function(required, defaultValue) {
      return this.get(_.isArray, 'arrays', required, defaultValue);
    };

    Args2.prototype.bool = function(required, defaultValue) {
      return this.get(_.isBoolean, 'bools', required, defaultValue);
    };

    Args2.prototype.func = function(required, defaultValue) {
      return this.get(_.isFunction, 'funcs', required, defaultValue);
    };

    Args2.prototype.other = function(required, defaultValue) {
      return this.get(null, 'others', required, defaultValue);
    };

    Args2.prototype.string = Args2.prototype.str;

    Args2.prototype.number = Args2.prototype.num;

    Args2.prototype.object = Args2.prototype.obj;

    Args2.prototype.arr = Args2.prototype.array;

    Args2.prototype.boolean = Args2.prototype.bool;

    Args2.prototype['function'] = Args2.prototype.func;

    Args2.prototype.callback = Args2.prototype.func;

    Args2.prototype.rStr = function(required, defaultValue) {
      return this.get(_.isString, 'strs', required, defaultValue, true);
    };

    Args2.prototype.rNum = function(required, defaultValue) {
      return this.get(_.isNumber, 'nums', required, defaultValue, true);
    };

    Args2.prototype.rObj = function(required, defaultValue) {
      return this.get(_.isPlainObject, 'objs', required, defaultValue, true);
    };

    Args2.prototype.rArray = function(required, defaultValue) {
      return this.get(_.isArray, 'arrays', required, defaultValue, true);
    };

    Args2.prototype.rBool = function(required, defaultValue) {
      return this.get(_.isBoolean, 'bools', required, defaultValue, true);
    };

    Args2.prototype.rFunc = function(required, defaultValue) {
      return this.get(_.isFunction, 'funcs', required, defaultValue, true);
    };

    Args2.prototype.rOther = function(required, defaultValue) {
      return this.get(null, 'others', required, defaultValue, true);
    };

    Args2.prototype.rString = Args2.prototype.rStr;

    Args2.prototype.rNumber = Args2.prototype.rNum;

    Args2.prototype.rObject = Args2.prototype.rObj;

    Args2.prototype.rArr = Args2.prototype.rArray;

    Args2.prototype.rBoolean = Args2.prototype.rBool;

    Args2.prototype.rFunction = Args2.prototype.rFunc;

    Args2.prototype.rCallback = Args2.prototype.rFunc;

    choiceInternalFunction = function(ref, isShift) {
      var names;
      names = (function() {
        switch (true) {
          case _.isString(ref):
            return ['str', 'rStr'];
          case _.isNumber(ref):
            return ['num', 'rNum'];
          case _.isArray(ref):
            return ['arr', 'rArr'];
          case _.isPlainObject(ref):
            return ['obj', 'rObj'];
          case _.isBoolean(ref):
            return ['bool', 'rBool'];
          case _.isFunction(ref):
            return ['func', 'rFunc'];
          default:
            return ['other', 'rOther'];
        }
      })();
      if (isShift) {
        return names[0];
      } else {
        return names[1];
      }
    };

    Args2.prototype.shift = function(required, defaultValue) {
      var errMsg, internalFunction, ref;
      if (this.args.length) {
        ref = this.args[0];
        internalFunction = choiceInternalFunction(ref, true);
        return this[internalFunction]();
      } else {
        if (required) {
          if (defaultValue) {
            errMsg = defaultValue;
          } else {
            errMsg = 'argument is required';
          }
          throw new Error(errMsg);
        } else if (_.isUndefined(defaultValue)) {
          return void 0;
        } else {
          return defaultValue;
        }
      }
    };

    Args2.prototype.pop = function(required, defaultValue) {
      var errMsg, internalFunction, ref;
      if (this.args.length) {
        ref = _.last(this.args);
        internalFunction = choiceInternalFunction(ref, false);
        return this[internalFunction]();
      } else {
        if (required) {
          if (defaultValue) {
            errMsg = defaultValue;
          } else {
            errMsg = 'argument is required';
          }
          throw new Error(errMsg);
        } else if (_.isUndefined(defaultValue)) {
          return void 0;
        } else {
          return defaultValue;
        }
      }
    };

    Args2.prototype.bridge = function(fn, _this) {
      _this = _this || {};
      return fn.apply(this, this.args);
    };

    Args2.prototype.pass = Args2.prototype.bridge;

    /*
     * argumentsを別のFunctionに丸投げする
     * @param [Function] 丸投げする先のFunction
     * @param [Arguments] 必ずargumentsを指定
     * @option [Argument] 追加する引数があれば指定。可変長引数。
     * @return [???] 丸投げしたFunctionのvalue
     */

    Args2.bridge = function() {
      var _args, args, fn;
      (fn = arguments[0]),
        (args = arguments[1]),
        (_args = 3 <= arguments.length ? slice.call(arguments, 2) : []);
      args = Array.prototype.slice.call(args, 0);
      if (_args.length) {
        args = args.concat(_args);
      }
      return fn.apply(this, args);
    };

    Args2.pass = Args2.bridge;

    Args2.assign = function(argu, types) {
      var args, res;
      args = new Args2(argu);
      res = [];
      types.forEach(function(type) {
        return res.push(
          (function() {
            switch (type) {
              case 'str':
              case 'string':
                return args.str();
              case 'num':
              case 'number':
                return args.num();
              case 'obj':
              case 'object':
                return args.obj();
              case 'arr':
              case 'array':
                return args.arr();
              case 'bool':
              case 'boolean':
                return args.bool();
              case 'func':
              case 'function':
              case 'fn':
                return args.func();
              default:
                return args.other();
            }
          })()
        );
      });

      return res;
    };

    return Args2;
  })();

  module.exports = Args2;
}.call(this));