'use strict';

var hapic = require('hapic');

/*
 * Copyright (c) 2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

exports.AuthorizeResponseMode = void 0;
(function (AuthorizeResponseMode) {
  AuthorizeResponseMode["QUERY"] = "query";
  AuthorizeResponseMode["FRAGMENT"] = "fragment";
  AuthorizeResponseMode["FORM_POST"] = "form_post";
  AuthorizeResponseMode["WEB_MESSAGE"] = "web_message";
})(exports.AuthorizeResponseMode || (exports.AuthorizeResponseMode = {}));

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 _objectSpread2(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) {
      _defineProperty(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 _regeneratorRuntime() {
  _regeneratorRuntime = function () {
    return exports;
  };
  var exports = {},
    Op = Object.prototype,
    hasOwn = Op.hasOwnProperty,
    defineProperty = Object.defineProperty || function (obj, key, desc) {
      obj[key] = desc.value;
    },
    $Symbol = "function" == typeof Symbol ? Symbol : {},
    iteratorSymbol = $Symbol.iterator || "@@iterator",
    asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
    toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  function define(obj, key, value) {
    return Object.defineProperty(obj, key, {
      value: value,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }), obj[key];
  }
  try {
    define({}, "");
  } catch (err) {
    define = function (obj, key, value) {
      return obj[key] = value;
    };
  }
  function wrap(innerFn, outerFn, self, tryLocsList) {
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
      generator = Object.create(protoGenerator.prototype),
      context = new Context(tryLocsList || []);
    return defineProperty(generator, "_invoke", {
      value: makeInvokeMethod(innerFn, self, context)
    }), generator;
  }
  function tryCatch(fn, obj, arg) {
    try {
      return {
        type: "normal",
        arg: fn.call(obj, arg)
      };
    } catch (err) {
      return {
        type: "throw",
        arg: err
      };
    }
  }
  exports.wrap = wrap;
  var ContinueSentinel = {};
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}
  var IteratorPrototype = {};
  define(IteratorPrototype, iteratorSymbol, function () {
    return this;
  });
  var getProto = Object.getPrototypeOf,
    NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function (method) {
      define(prototype, method, function (arg) {
        return this._invoke(method, arg);
      });
    });
  }
  function AsyncIterator(generator, PromiseImpl) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if ("throw" !== record.type) {
        var result = record.arg,
          value = result.value;
        return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
          invoke("next", value, resolve, reject);
        }, function (err) {
          invoke("throw", err, resolve, reject);
        }) : PromiseImpl.resolve(value).then(function (unwrapped) {
          result.value = unwrapped, resolve(result);
        }, function (error) {
          return invoke("throw", error, resolve, reject);
        });
      }
      reject(record.arg);
    }
    var previousPromise;
    defineProperty(this, "_invoke", {
      value: function (method, arg) {
        function callInvokeWithMethodAndArg() {
          return new PromiseImpl(function (resolve, reject) {
            invoke(method, arg, resolve, reject);
          });
        }
        return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
      }
    });
  }
  function makeInvokeMethod(innerFn, self, context) {
    var state = "suspendedStart";
    return function (method, arg) {
      if ("executing" === state) throw new Error("Generator is already running");
      if ("completed" === state) {
        if ("throw" === method) throw arg;
        return doneResult();
      }
      for (context.method = method, context.arg = arg;;) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }
        if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
          if ("suspendedStart" === state) throw state = "completed", context.arg;
          context.dispatchException(context.arg);
        } else "return" === context.method && context.abrupt("return", context.arg);
        state = "executing";
        var record = tryCatch(innerFn, self, context);
        if ("normal" === record.type) {
          if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
          return {
            value: record.arg,
            done: context.done
          };
        }
        "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
      }
    };
  }
  function maybeInvokeDelegate(delegate, context) {
    var methodName = context.method,
      method = delegate.iterator[methodName];
    if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel;
    var record = tryCatch(method, delegate.iterator, context.arg);
    if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
    var info = record.arg;
    return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
  }
  function pushTryEntry(locs) {
    var entry = {
      tryLoc: locs[0]
    };
    1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
  }
  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal", delete record.arg, entry.completion = record;
  }
  function Context(tryLocsList) {
    this.tryEntries = [{
      tryLoc: "root"
    }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
  }
  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) return iteratorMethod.call(iterable);
      if ("function" == typeof iterable.next) return iterable;
      if (!isNaN(iterable.length)) {
        var i = -1,
          next = function next() {
            for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
            return next.value = undefined, next.done = !0, next;
          };
        return next.next = next;
      }
    }
    return {
      next: doneResult
    };
  }
  function doneResult() {
    return {
      value: undefined,
      done: !0
    };
  }
  return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
    value: GeneratorFunctionPrototype,
    configurable: !0
  }), defineProperty(GeneratorFunctionPrototype, "constructor", {
    value: GeneratorFunction,
    configurable: !0
  }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
    var ctor = "function" == typeof genFun && genFun.constructor;
    return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
  }, exports.mark = function (genFun) {
    return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
  }, exports.awrap = function (arg) {
    return {
      __await: arg
    };
  }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
    return this;
  }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
    void 0 === PromiseImpl && (PromiseImpl = Promise);
    var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
    return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
      return result.done ? result.value : iter.next();
    });
  }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
    return this;
  }), define(Gp, "toString", function () {
    return "[object Generator]";
  }), exports.keys = function (val) {
    var object = Object(val),
      keys = [];
    for (var key in object) keys.push(key);
    return keys.reverse(), function next() {
      for (; keys.length;) {
        var key = keys.pop();
        if (key in object) return next.value = key, next.done = !1, next;
      }
      return next.done = !0, next;
    };
  }, exports.values = values, Context.prototype = {
    constructor: Context,
    reset: function (skipTempReset) {
      if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
    },
    stop: function () {
      this.done = !0;
      var rootRecord = this.tryEntries[0].completion;
      if ("throw" === rootRecord.type) throw rootRecord.arg;
      return this.rval;
    },
    dispatchException: function (exception) {
      if (this.done) throw exception;
      var context = this;
      function handle(loc, caught) {
        return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
      }
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i],
          record = entry.completion;
        if ("root" === entry.tryLoc) return handle("end");
        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc"),
            hasFinally = hasOwn.call(entry, "finallyLoc");
          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
          } else {
            if (!hasFinally) throw new Error("try statement without catch or finally");
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          }
        }
      }
    },
    abrupt: function (type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }
      finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
      var record = finallyEntry ? finallyEntry.completion : {};
      return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
    },
    complete: function (record, afterLoc) {
      if ("throw" === record.type) throw record.arg;
      return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
    },
    finish: function (finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
      }
    },
    catch: function (tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if ("throw" === record.type) {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }
      throw new Error("illegal catch attempt");
    },
    delegateYield: function (iterable, resultName, nextLoc) {
      return this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
    }
  }, exports;
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}
function _asyncToGenerator(fn) {
  return function () {
    var self = this,
      args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }
      _next(undefined);
    });
  };
}
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  }
}
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  Object.defineProperty(subClass, "prototype", {
    writable: false
  });
  if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
  _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };
  return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  if (Reflect.construct.sham) return false;
  if (typeof Proxy === "function") return true;
  try {
    Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
    return true;
  } catch (e) {
    return false;
  }
}
function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }
  return self;
}
function _possibleConstructorReturn(self, call) {
  if (call && (typeof call === "object" || typeof call === "function")) {
    return call;
  } else if (call !== void 0) {
    throw new TypeError("Derived constructors may only return object or undefined");
  }
  return _assertThisInitialized(self);
}
function _createSuper(Derived) {
  var hasNativeReflectConstruct = _isNativeReflectConstruct();
  return function _createSuperInternal() {
    var Super = _getPrototypeOf(Derived),
      result;
    if (hasNativeReflectConstruct) {
      var NewTarget = _getPrototypeOf(this).constructor;
      result = Reflect.construct(Super, arguments, NewTarget);
    } else {
      result = Super.apply(this, arguments);
    }
    return _possibleConstructorReturn(this, result);
  };
}
function _superPropBase(object, property) {
  while (!Object.prototype.hasOwnProperty.call(object, property)) {
    object = _getPrototypeOf(object);
    if (object === null) break;
  }
  return object;
}
function _get() {
  if (typeof Reflect !== "undefined" && Reflect.get) {
    _get = Reflect.get.bind();
  } else {
    _get = function _get(target, property, receiver) {
      var base = _superPropBase(target, property);
      if (!base) return;
      var desc = Object.getOwnPropertyDescriptor(base, property);
      if (desc.get) {
        return desc.get.call(arguments.length < 3 ? target : receiver);
      }
      return desc.value;
    };
  }
  return _get.apply(this, arguments);
}
function _toConsumableArray(arr) {
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  return arr2;
}
function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}

/*
 * Copyright (c) 2021.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

// eslint-disable-next-line @typescript-eslint/ban-types
function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

var BaseOAuth2API = /*#__PURE__*/function () {
  // -----------------------------------------------------------------------------------

  function BaseOAuth2API(client, options) {
    _classCallCheck(this, BaseOAuth2API);
    this.client = client;
    if (options) {
      this.options = options;
    } else if (hasOwnProperty(client, 'options')) {
      this.options = client.options;
    }
  }

  // -----------------------------------------------------------------------------------
  _createClass(BaseOAuth2API, [{
    key: "setClient",
    value: function setClient(client) {
      this.client = client;
    }
  }, {
    key: "setOptions",
    value: function setOptions(options) {
      this.options = options;
    }
  }]);
  return BaseOAuth2API;
}();

var AuthorizeAPI = /*#__PURE__*/function (_BaseOAuth2API) {
  _inherits(AuthorizeAPI, _BaseOAuth2API);
  var _super = _createSuper(AuthorizeAPI);
  // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
  function AuthorizeAPI(client, options) {
    _classCallCheck(this, AuthorizeAPI);
    return _super.call(this, client, options);
  }
  _createClass(AuthorizeAPI, [{
    key: "buildURL",
    value: function buildURL(parameters) {
      parameters = parameters || {};
      var baseURL;
      var input;
      if (this.options.authorization_endpoint) {
        input = this.options.authorization_endpoint;
      } else {
        input = 'authorize';
        var clientURL = this.client.getUri();
        if (clientURL) {
          baseURL = clientURL;
        }
      }
      var url = new URL(input, baseURL);
      url.searchParams.set('response_type', parameters.response_type || 'code');
      if (this.options.client_id) {
        url.searchParams.set('client_id', this.options.client_id);
      }
      url.searchParams.set('redirect_uri', parameters.redirect_uri || this.options.redirect_uri);
      var scope = [];
      if (this.options.scope) {
        var _input = Array.isArray(this.options.scope) ? this.options.scope : this.options.scope.split(' ');
        scope.push.apply(scope, _toConsumableArray(_input));
      }
      if (parameters.scope) {
        var _input2 = Array.isArray(parameters.scope) ? parameters.scope : parameters.scope.split(' ');
        scope.push.apply(scope, _toConsumableArray(_input2));
      }
      if (scope.length > 0) {
        url.searchParams.set('scope', scope.join(' '));
      }
      return url.href;
    }
  }]);
  return AuthorizeAPI;
}(BaseOAuth2API);

var TokenAPI = /*#__PURE__*/function (_BaseOAuth2API) {
  _inherits(TokenAPI, _BaseOAuth2API);
  var _super = _createSuper(TokenAPI);
  // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
  function TokenAPI(client, options) {
    _classCallCheck(this, TokenAPI);
    return _super.call(this, client, options);
  }

  // ------------------------------------------------------------------
  _createClass(TokenAPI, [{
    key: "createWithRefreshToken",
    value: function () {
      var _createWithRefreshToken = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(parameters) {
        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                return _context.abrupt("return", this.create(this.buildTokenParameters(_objectSpread2({
                  grant_type: 'refresh_token'
                }, parameters))));
              case 1:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));
      function createWithRefreshToken(_x) {
        return _createWithRefreshToken.apply(this, arguments);
      }
      return createWithRefreshToken;
    }()
  }, {
    key: "createWithClientCredentials",
    value: function () {
      var _createWithClientCredentials = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(parameters) {
        return _regeneratorRuntime().wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                return _context2.abrupt("return", this.create(this.buildTokenParameters(_objectSpread2({
                  grant_type: 'client_credentials'
                }, parameters || {}))));
              case 1:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));
      function createWithClientCredentials(_x2) {
        return _createWithClientCredentials.apply(this, arguments);
      }
      return createWithClientCredentials;
    }()
  }, {
    key: "createWithPasswordGrant",
    value: function () {
      var _createWithPasswordGrant = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(parameters) {
        return _regeneratorRuntime().wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                return _context3.abrupt("return", this.create(this.buildTokenParameters(_objectSpread2({
                  grant_type: 'password'
                }, parameters))));
              case 1:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));
      function createWithPasswordGrant(_x3) {
        return _createWithPasswordGrant.apply(this, arguments);
      }
      return createWithPasswordGrant;
    }()
  }, {
    key: "createWithAuthorizeGrant",
    value: function () {
      var _createWithAuthorizeGrant = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(parameters) {
        return _regeneratorRuntime().wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                return _context4.abrupt("return", this.create(this.buildTokenParameters(_objectSpread2({
                  grant_type: 'authorization_code'
                }, parameters))));
              case 1:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));
      function createWithAuthorizeGrant(_x4) {
        return _createWithAuthorizeGrant.apply(this, arguments);
      }
      return createWithAuthorizeGrant;
    }()
  }, {
    key: "createWithRobotCredentials",
    value: function () {
      var _createWithRobotCredentials = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(parameters) {
        return _regeneratorRuntime().wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                return _context5.abrupt("return", this.create(this.buildTokenParameters(_objectSpread2({
                  grant_type: 'robot_credentials'
                }, parameters))));
              case 1:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));
      function createWithRobotCredentials(_x5) {
        return _createWithRobotCredentials.apply(this, arguments);
      }
      return createWithRobotCredentials;
    }() // ------------------------------------------------------------------
    /**
     * @throws Error
     * @param parameters
     */
  }, {
    key: "create",
    value: function () {
      var _create = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(parameters) {
        var urlSearchParams, parameterKeys, i, _yield$this$client$po, data, tokenResponse;
        return _regeneratorRuntime().wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                urlSearchParams = new URLSearchParams();
                parameterKeys = Object.keys(parameters);
                for (i = 0; i < parameterKeys.length; i++) {
                  urlSearchParams.append(parameterKeys[i], parameters[parameterKeys[i]]);
                }
                _context6.next = 5;
                return this.client.post(this.options.token_endpoint || '/token', urlSearchParams, {
                  headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                  }
                });
              case 5:
                _yield$this$client$po = _context6.sent;
                data = _yield$this$client$po.data;
                tokenResponse = {
                  access_token: data.access_token,
                  expires_in: data.expires_in,
                  token_type: data.token_type || 'Bearer'
                };
                if (data.refresh_token) {
                  tokenResponse.refresh_token = data.refresh_token;
                }
                if (typeof data.id_token === 'string') {
                  tokenResponse.id_token = data.id_token;
                }
                if (typeof data.mac_key === 'string') {
                  tokenResponse.mac_key = data.mac_key;
                }
                if (typeof data.mac_algorithm === 'string') {
                  tokenResponse.mac_algorithm = data.mac_algorithm;
                }
                return _context6.abrupt("return", tokenResponse);
              case 13:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));
      function create(_x6) {
        return _create.apply(this, arguments);
      }
      return create;
    }()
  }, {
    key: "introspect",
    value: function () {
      var _introspect = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(token, typeHint) {
        var urlSearchParams, _yield$this$client$po2, data;
        return _regeneratorRuntime().wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                urlSearchParams = new URLSearchParams();
                urlSearchParams.append('token', token);
                if (typeHint) {
                  urlSearchParams.append('token_type_hint', typeHint);
                }
                _context7.next = 5;
                return this.client.post(this.options.introspection_endpoint || '/token/introspect', urlSearchParams, {
                  headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                  }
                });
              case 5:
                _yield$this$client$po2 = _context7.sent;
                data = _yield$this$client$po2.data;
                return _context7.abrupt("return", data);
              case 8:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));
      function introspect(_x7, _x8) {
        return _introspect.apply(this, arguments);
      }
      return introspect;
    }() // ------------------------------------------------------------------
  }, {
    key: "buildTokenParameters",
    value: function buildTokenParameters(parameters) {
      if (this.options.client_id) {
        parameters.client_id = this.options.client_id;
      }
      if (parameters.grant_type !== 'authorization_code' && parameters.grant_type !== 'robot_credentials') {
        if (typeof parameters.scope === 'undefined' && this.options.scope) {
          parameters.scope = this.options.scope;
        }
        if (Array.isArray(parameters.scope)) {
          parameters.scope = parameters.scope.join(' ');
        }
      }
      if (parameters.grant_type === 'authorization_code') {
        if (typeof parameters.redirect_uri === 'undefined') {
          parameters.redirect_uri = this.options.redirect_uri;
        }
      }
      if (this.options.client_id) {
        parameters.client_id = this.options.client_id;
      }
      if (typeof this.options.client_secret === 'string') {
        parameters.client_secret = this.options.client_secret;
      }
      return parameters;
    }
  }]);
  return TokenAPI;
}(BaseOAuth2API);

var UserinfoAPI = /*#__PURE__*/function (_BaseOAuth2API) {
  _inherits(UserinfoAPI, _BaseOAuth2API);
  var _super = _createSuper(UserinfoAPI);
  // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
  function UserinfoAPI(client, options) {
    _classCallCheck(this, UserinfoAPI);
    return _super.call(this, client, options);
  }

  // -----------------------------------------------------------------------------------

  /**
   * @throws Error
   * @param token
   */
  _createClass(UserinfoAPI, [{
    key: "get",
    value: function () {
      var _get = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(token) {
        var _yield$this$client$ge, data;
        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                _context.next = 2;
                return this.client.get(this.options.userinfo_endpoint || '/userinfo', {
                  headers: {
                    Authorization: "Bearer ".concat(token)
                  }
                });
              case 2:
                _yield$this$client$ge = _context.sent;
                data = _yield$this$client$ge.data;
                return _context.abrupt("return", data);
              case 5:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));
      function get(_x) {
        return _get.apply(this, arguments);
      }
      return get;
    }()
  }]);
  return UserinfoAPI;
}(BaseOAuth2API);

var Client = /*#__PURE__*/function (_BaseClient) {
  _inherits(Client, _BaseClient);
  var _super = _createSuper(Client);
  // -----------------------------------------------------------------------------------

  // -----------------------------------------------------------------------------------

  function Client(config) {
    var _this;
    _classCallCheck(this, Client);
    _this = _super.call(this, config);
    config = config || {};
    _this.options = config.options || {};
    _this.token = new TokenAPI(_this.driver, _this.options);
    _this.authorize = new AuthorizeAPI(_this.driver, _this.options);
    _this.userInfo = new UserinfoAPI(_this.driver, _this.options);
    return _this;
  }

  // -----------------------------------------------------------------------------------
  _createClass(Client, [{
    key: "setDriver",
    value: function setDriver(client) {
      _get(_getPrototypeOf(Client.prototype), "setDriver", this).call(this, client);
      this.authorize.setClient(client);
      this.token.setClient(client);
      this.userInfo.setClient(client);
    }
  }, {
    key: "setOptions",
    value: function setOptions(options) {
      this.options = options;
      this.authorize.setOptions(options);
      this.token.setOptions(options);
      this.userInfo.setOptions(options);
    }

    // -----------------------------------------------------------------------------------
  }, {
    key: "useOpenIDDiscovery",
    value: function () {
      var _useOpenIDDiscovery = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(baseURL) {
        var url, _yield$this$driver$ge, data;
        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                url = '/.well-known/openid-configuration';
                if (baseURL) {
                  url = new URL(url, baseURL).href;
                }
                _context.next = 4;
                return this.driver.get(url);
              case 4:
                _yield$this$driver$ge = _context.sent;
                data = _yield$this$driver$ge.data;
                if (data.authorization_endpoint) {
                  this.options.authorization_endpoint = data.authorization_endpoint;
                }
                if (data.introspection_endpoint) {
                  this.options.introspection_endpoint = data.introspection_endpoint;
                }
                if (data.token_endpoint) {
                  this.options.token_endpoint = data.token_endpoint;
                }
                if (data.userinfo_endpoint) {
                  this.options.userinfo_endpoint = data.userinfo_endpoint;
                }
                this.setOptions(this.options);
              case 11:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));
      function useOpenIDDiscovery(_x) {
        return _useOpenIDDiscovery.apply(this, arguments);
      }
      return useOpenIDDiscovery;
    }()
  }]);
  return Client;
}(hapic.Client);

exports.AuthorizeAPI = AuthorizeAPI;
exports.Client = Client;
exports.TokenAPI = TokenAPI;
exports.UserinfoAPI = UserinfoAPI;
exports.hasOwnProperty = hasOwnProperty;
//# sourceMappingURL=index.cjs.js.map
