{"size": 1121, "ext": "js", "max_stars_repo_path": "src/KoaSemver.js", "max_stars_repo_name": "lopezjurip/koa-semver", "max_stars_repo_stars_event_min_datetime": "2017-04-20T15:04:20.000Z", "max_stars_repo_stars_event_max_datetime": "2017-05-31T17:13:55.000Z", "max_issues_repo_path": "src/KoaSemver.js", "max_issues_repo_name": "mrpatiwi/koa-semver", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "src/KoaSemver.js", "max_forks_repo_name": "mrpatiwi/koa-semver", "max_forks_repo_forks_event_min_datetime": "2018-11-05T07:52:36.000Z", "max_forks_repo_forks_event_max_datetime": "2018-11-05T07:52:36.000Z"}
{"max_stars_count": 3, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 21.1509433962, "max_line_length": 78, "alphanum_fraction": 0.5807314897}
const semver = require("semver");
const isFunction = require("lodash/isFunction");

const handlers = require("./handlers");

class KoaSemver {
  static test(requested, target) {
    return !requested || semver.satisfies(requested, target);
  }

  constructor(modes = []) {
    this.modes = modes;
  }

  use(handler) {
    if (isFunction(handler)) {
      this.modes.push(handler);
    } else {
      throw new Error("koa-semver `use` must receive a function as argument");
    }
  }

  clone() {
    return new KoaSemver([...this.modes]);
  }

  matcher(target = "*") {
    return middleware => (ctx, next) => {
      const requested = this.modes.reduce(
        (acc, handler) => acc || handler(ctx),
        null
      );

      if (middleware && KoaSemver.test(requested, target)) {
        ctx.state.semver = {
          target,
          requested,
        };
        return middleware(ctx, next);
      } else {
        return next();
      }
    };
  }

  match(target = "*", middleware = null) {
    return this.matcher(target)(middleware);
  }
}

module.exports = KoaSemver;
module.exports.handlers = handlers;
