"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RemoteServerError = void 0;
exports.authenticateRequest = authenticateRequest;
exports.apiRequest = apiRequest;
const build_url_1 = require("../../../urls/build-url");
const request_1 = require("../../../request");
const searchPostsFormat_1 = require("../enums/searchPostsFormat");
class RemoteServerError extends request_1.RemoteServerError {
    constructor(message, url, status, error) {
        super(message, url, status);
        this.error = error;
    }
}
exports.RemoteServerError = RemoteServerError;
/**
 * returns Promise that resolves token to use in Discussions API requests
 *
 * @export
 * @param {IDiscussionsRequestOptions} options
 * @return {*}  {Promise<string>}
 */
function authenticateRequest(options) {
    const { token, authentication } = options;
    let tokenPromise = () => {
        return Promise.resolve(token);
    };
    if (authentication) {
        tokenPromise = authentication.getToken.bind(authentication, authentication.portal);
    }
    return tokenPromise();
}
/**
 * parses IDiscussionsRequestOptions and makes request against Discussions API
 *
 * @export
 * @template T
 * @param {string} route
 * @param {IDiscussionsRequestOptions} options
 * @param {string} [token]
 * @param {string} [version]
 * @return {*}  {Promise<T>}
 */
function apiRequest(route, options, version, token) {
    var _a;
    let routeWithParams = route;
    const headers = new Headers(options.headers);
    headers.append("Content-Type", "application/json");
    if (token) {
        headers.append("Authorization", `Bearer ${token}`);
    }
    const opts = {
        headers,
        method: options.httpMethod || "GET",
        mode: options.mode,
        cache: options.cache,
        credentials: options.credentials,
    };
    const apiBase = (0, build_url_1.buildUrl)({
        // TODO: we _want_ to use getHubApiUrl(),
        // but have to deal w/ the fact that this package overwrites IHubRequestOptions
        host: options.hubApiUrl || "https://hub.arcgis.com",
        path: `/api/discussions/${version}`,
    });
    if (options.data) {
        if (options.httpMethod === "GET") {
            const queryParams = new URLSearchParams(options.data).toString();
            routeWithParams += `?${queryParams}`;
        }
        else {
            opts.body = JSON.stringify(options.data);
        }
    }
    // this currently only applies to the search post route. we should rework things in the future such that we don't need
    // to do this sort of evaluation in common logic.
    const isCSV = ["/posts", "/posts/search"].includes(route) &&
        (((_a = options.data) === null || _a === void 0 ? void 0 : _a.f) === searchPostsFormat_1.SearchPostsFormat.CSV ||
            headers.get("Accept") === "text/csv");
    const url = [
        apiBase.replace(/\/$/, ""),
        routeWithParams.replace(/^\//, ""),
    ].join("/");
    return fetch(url, opts).then((res) => {
        if (res.ok) {
            return isCSV ? res.text() : res.json();
        }
        else {
            const { statusText, status } = res;
            return res.json().then((err) => {
                throw new RemoteServerError(statusText, url, status, JSON.stringify(err.message));
            });
        }
    });
}
//# sourceMappingURL=request.js.map