"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const axios = require("axios");
const buildURL = require('axios/lib/helpers/buildURL');
const { default: request } = axios;
class SyncanoClient {
    constructor(instanceName, options = {}) {
        this.DEFAULT_HEADERS = {
            'Content-Type': 'application/json'
        };
        this.transform = (res) => {
            if (typeof this.transformResponse === 'function') {
                return this.transformResponse(res);
            }
            return res.data;
        };
        this.host = options.host || 'syncano.space';
        this.token = options.token;
        this.transformResponse = options.transformResponse;
        this.instanceName = instanceName;
    }
    /**
     * Helper method that generates endpoint url
     *
     * @param {string} path Endpoint path in format `socket-name/endpoint-name`
     * @param {object} [params] The params to be appended
     * @returns {string} The formatted url
     */
    url(path, params, options = {
        protocol: 'https'
    }) {
        let baseURL = `${options.protocol}://${this.instanceName}.${this.host}/${path}/`;
        if (path.startsWith('http') || path.startsWith('/')) {
            baseURL = path;
        }
        return buildURL(baseURL, Object.assign({ user_key: this.token }, params));
    }
    /**
     * Set user api key. Use this to make all request authenticated
     * Call this method without any argument to clear api key
     *
     * @param {string} [token]
     */
    setToken(token) {
        this.token = token;
        return this;
    }
    /**
     * Send request using GET method
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {object} [params={}] Additional request parameters
     * @param {axios.AxiosRequestConfig} [options={}] Additional request options, like headers. See axios config for info
     * @see https://github.com/axios/axios#request-config
     */
    get(endpoint, params, options) {
        this.checkInstanceName();
        return request.get(this.url(endpoint), this.options(Object.assign({ params }, options))).then(this.transform);
    }
    /**
     * Send request using PATCH method
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {any} [data={}] Additional request parameters
     * @param {axios.AxiosRequestConfig} [options={}] Additional request options, like headers. See axios config for info
     * @see https://github.com/axios/axios#request-config
     */
    patch(endpoint, data, options) {
        this.checkInstanceName();
        return request.patch(this.url(endpoint), data, this.options(options)).then(this.transform);
    }
    /**
     * Send request using POST method
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {any} [data={}] Additional request parameters
     * @param {axios.AxiosRequestConfig} [options={}] Additional request options, like headers. See axios config for info
     * @see https://github.com/axios/axios#request-config
     */
    post(endpoint, data, options) {
        this.checkInstanceName();
        return request.post(this.url(endpoint), data, this.options(options)).then(this.transform);
    }
    /**
     * Send request using PUT method
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {any} [data={}] Additional request parameters
     * @param {axios.AxiosRequestConfig} [options={}] Additional request options, like headers. See axios config for info
     * @see https://github.com/axios/axios#request-config
     */
    put(endpoint, data, options) {
        this.checkInstanceName();
        return request.put(this.url(endpoint), data, this.options(options)).then(this.transform);
    }
    /**
     * Send request using DELETE method
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {object} [params={}] Additional request parameters
     * @param {axios.AxiosRequestConfig} [options={}] Additional request options, like headers. See axios config for info
     * @see https://github.com/axios/axios#request-config
     */
    delete(endpoint, params, options) {
        this.checkInstanceName();
        return request.delete(this.url(endpoint), this.options(Object.assign({ params }, options))).then(this.transform);
    }
    /**
     *
     *
     * @param {string} endpoint Endpoint path in format `socket-name/endpoint-name`
     * @param {object} [params] Params to be appended to the URL
     */
    listen(endpoint, params) {
        const url = this.url(endpoint, Object.assign({ transport: 'websocket' }, params), { protocol: 'wss' });
        return new WebSocket(url);
    }
    options(options = {
        params: {}
    }) {
        return Object.assign({}, options, { params: Object.assign({ user_key: this.token }, options.params), headers: Object.assign({}, this.DEFAULT_HEADERS, options.headers) });
    }
    checkInstanceName() {
        if (!this.instanceName) {
            throw new Error(`Syncano Client was initialized with invalid instance name: "${this.instanceName}"`);
        }
    }
}
exports.default = SyncanoClient;
module.exports = SyncanoClient;
module.exports.default = SyncanoClient;
//# sourceMappingURL=index.js.map