import { Client as Client$1, hasOwnProperty as hasOwnProperty$1, useConfig } from 'hapic';
export { Client as BaseClient, buildConfig, hasConfig, isClientError, setConfig, unsetConfig, useConfig } from '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.
 */ var AuthorizeResponseMode;
(function(AuthorizeResponseMode) {
    AuthorizeResponseMode["QUERY"] = 'query';
    AuthorizeResponseMode["FRAGMENT"] = 'fragment';
    AuthorizeResponseMode["FORM_POST"] = 'form_post';
    AuthorizeResponseMode["WEB_MESSAGE"] = 'web_message';
})(AuthorizeResponseMode || (AuthorizeResponseMode = {}));

/*
 * 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);
}

class BaseOAuth2API {
    // -----------------------------------------------------------------------------------
    setClient(client) {
        this.client = client;
    }
    setOptions(options) {
        this.options = options;
    }
    // -----------------------------------------------------------------------------------
    constructor(client, options){
        this.client = client;
        if (options) {
            this.options = options;
        } else if (hasOwnProperty(client, 'options')) {
            this.options = client.options;
        } else {
            this.options = options || {};
        }
    }
}

class AuthorizeAPI extends BaseOAuth2API {
    buildURL(parameters) {
        parameters = parameters || {};
        let baseURL;
        let input;
        if (this.options.authorization_endpoint) {
            input = this.options.authorization_endpoint;
        } else {
            const clientURL = this.client.getUri();
            if (clientURL) {
                baseURL = clientURL;
            }
        }
        const url = new URL(input || 'authorize', baseURL);
        url.searchParams.set('response_type', parameters.response_type || 'code');
        if (this.options.client_id) {
            url.searchParams.set('client_id', this.options.client_id);
        }
        const redirectUri = parameters.redirect_uri || this.options.redirect_uri;
        if (redirectUri) {
            url.searchParams.set('redirect_uri', redirectUri);
        }
        const scope = [];
        if (this.options.scope) {
            const input = Array.isArray(this.options.scope) ? this.options.scope : this.options.scope.split(' ');
            scope.push(...input);
        }
        if (parameters.scope) {
            const input = Array.isArray(parameters.scope) ? parameters.scope : parameters.scope.split(' ');
            scope.push(...input);
        }
        if (scope.length > 0) {
            url.searchParams.set('scope', scope.join(' '));
        }
        return url.href;
    }
    // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
    constructor(client, options){
        super(client, options);
    }
}

/*
 * 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.
 */ function asyncGeneratorStep$2(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$2(fn) {
    return function() {
        var self = this, args = arguments;
        return new Promise(function(resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}
function _extends() {
    _extends = Object.assign || function(target) {
        for(var i = 1; i < arguments.length; i++){
            var source = arguments[i];
            for(var key in source){
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    };
    return _extends.apply(this, arguments);
}
class TokenAPI extends BaseOAuth2API {
    // ------------------------------------------------------------------
    createWithRefreshToken(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            return _this.create(_this.buildTokenParameters(_extends({
                grant_type: 'refresh_token'
            }, parameters)));
        })();
    }
    createWithClientCredentials(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            return _this.create(_this.buildTokenParameters(_extends({
                grant_type: 'client_credentials'
            }, parameters || {})));
        })();
    }
    createWithPasswordGrant(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            return _this.create(_this.buildTokenParameters(_extends({
                grant_type: 'password'
            }, parameters)));
        })();
    }
    createWithAuthorizeGrant(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            return _this.create(_this.buildTokenParameters(_extends({
                grant_type: 'authorization_code'
            }, parameters)));
        })();
    }
    createWithRobotCredentials(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            return _this.create(_this.buildTokenParameters(_extends({
                grant_type: 'robot_credentials'
            }, parameters)));
        })();
    }
    // ------------------------------------------------------------------
    /**
     * @throws Error
     * @param parameters
     */ create(parameters) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            const urlSearchParams = new URLSearchParams();
            const parameterKeys = Object.keys(parameters);
            for(let i = 0; i < parameterKeys.length; i++){
                urlSearchParams.append(parameterKeys[i], parameters[parameterKeys[i]]);
            }
            const { data  } = yield _this.client.post(_this.options.token_endpoint || '/token', urlSearchParams, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });
            const 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 tokenResponse;
        })();
    }
    introspect(token, typeHint) {
        var _this = this;
        return _asyncToGenerator$2(function*() {
            const urlSearchParams = new URLSearchParams();
            urlSearchParams.append('token', token);
            if (typeHint) {
                urlSearchParams.append('token_type_hint', typeHint);
            }
            const { data  } = yield _this.client.post(_this.options.introspection_endpoint || '/token/introspect', urlSearchParams, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });
            return data;
        })();
    }
    // ------------------------------------------------------------------
    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;
    }
    // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
    constructor(client, options){
        super(client, options);
    }
}

/*
 * 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.
 */ function asyncGeneratorStep$1(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$1(fn) {
    return function() {
        var self = this, args = arguments;
        return new Promise(function(resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}
class UserinfoAPI extends BaseOAuth2API {
    // -----------------------------------------------------------------------------------
    /**
     * @throws Error
     * @param token
     */ get(token) {
        var _this = this;
        return _asyncToGenerator$1(function*() {
            const { data  } = yield _this.client.get(_this.options.userinfo_endpoint || '/userinfo', {
                headers: {
                    Authorization: `Bearer ${token}`
                }
            });
            return data;
        })();
    }
    // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor
    constructor(client, options){
        super(client, options);
    }
}

/*
 * Copyright (c) 2021-2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */ 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);
        });
    };
}
class Client extends Client$1 {
    // -----------------------------------------------------------------------------------
    setDriver(client) {
        super.setDriver(client);
        this.authorize.setClient(client);
        this.token.setClient(client);
        this.userInfo.setClient(client);
    }
    setOptions(options) {
        this.options = options;
        this.authorize.setOptions(options);
        this.token.setOptions(options);
        this.userInfo.setOptions(options);
    }
    // -----------------------------------------------------------------------------------
    buildOpenIDDiscoveryURL(baseURL) {
        let url = '.well-known/openid-configuration';
        if (baseURL) {
            url = new URL(url, baseURL).href;
        } else {
            url = `/${url}`;
        }
        return url;
    }
    useOpenIDDiscovery(baseURL) {
        var _this = this;
        return _asyncToGenerator(function*() {
            const url = _this.buildOpenIDDiscoveryURL(baseURL);
            const { data  } = yield _this.driver.get(url);
            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);
        })();
    }
    // -----------------------------------------------------------------------------------
    constructor(config){
        super(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);
    }
}

const instanceMap = {};
/**
 * Verify if an oauth2 client singleton instance exists.
 *
 * @param key
 */ function hasClient(key) {
    return hasOwnProperty$1(instanceMap, key || 'default');
}
/**
 * Set the oauth2 client singleton instance.
 *
 * @param client
 * @param key
 */ function setClient(client, key) {
    key = key || 'default';
    instanceMap[key] = client;
    return client;
}
/**
 * Receive an oauth2 singleton instance.
 *
 * @param key
 */ function useClient(key) {
    key = key || 'default';
    if (Object.prototype.hasOwnProperty.call(instanceMap, key)) {
        return instanceMap[key];
    }
    const config = useConfig(key);
    const instance = createClient(config);
    instanceMap[key] = instance;
    return instance;
}
/**
 * Unset an oauth2 client singleton instance.
 *
 * @param key
 */ function unsetClient(key) {
    key = key || 'default';
    if (hasOwnProperty$1(instanceMap, key)) {
        delete instanceMap[key];
    }
}
/**
 * Create an oauth2 client.
 *
 * @param input
 */ function createClient(input) {
    return new Client(input);
}

const client = createClient();

export { AuthorizeAPI, AuthorizeResponseMode, Client, TokenAPI, UserinfoAPI, createClient, client as default, hasClient, hasOwnProperty, setClient, unsetClient, useClient };
//# sourceMappingURL=index.mjs.map
