"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const qs = require("qs");
const Fetch_1 = require("../lib/Fetch");
const Logger_1 = require("../lib/Logger");
const logger = Logger_1.default.of('remote-service');
class REST {
    constructor(baseUrl) {
        this.baseUrl = baseUrl;
    }
    toUrl(path) {
        let query;
        if (typeof path !== 'string') {
            let qo = typeof path.query === 'string' ? qs.parse(path.query) : path.query;
            query = qs.stringify(Object.assign(Object.assign({}, qo), this.additionalQueries), { addQueryPrefix: true, format: 'RFC1738' });
            path = path.path;
        }
        else {
            query = '';
        }
        return `${this.baseUrl}/${path}${query}`;
    }
    async request(method, path, body) {
        const url = this.toUrl(path);
        const init = {
            method,
            headers: Object.assign({ 'Content-Type': 'application/json;charset=UTF-8' }, this.additionalHeaders),
        };
        if (method !== 'GET' && body) {
            init.body = typeof body === 'string' ? body : JSON.stringify(body);
        }
        try {
            const r = await (0, Fetch_1.default)(url, init);
            if (!r.ok) {
                throw new Fetch_1.ResponseError(r);
            }
            return await r.json();
        }
        catch (e) {
            logger.warn(`${(e === null || e === void 0 ? void 0 : e.code) ? `${e.code} ${e.message}` : String(e)} on ${method} ${url}`, {
                url,
                init,
            });
        }
    }
    async get(path) {
        return this.request('GET', path);
    }
    async post(path, body) {
        return this.request('POST', path, body);
    }
    async put(path, body) {
        return this.request('PUT', path, body);
    }
    async patch(path, body) {
        return this.request('PATCH', path, body);
    }
    async delete(path) {
        return this.request('DELETE', path);
    }
}
exports.default = REST;
