Source: restclient.js

/*! meta-client/modules/restclient */
/*jslint
    browser, long
*/
/*global
    URLSearchParams
*/
/**
 * restclient module.
 *
 * @module meta-client/modules/restclient
 */
import _ from "underscore";
import ext from "util-web/modules/ext";
import Logger from "js-logger";
import metaClient from "meta-client/modules/client";
import protocol from "meta-core/modules/protocol";

const LOG = Logger.get("meta-client/restclient");

const factory = function ({engine, password, user}) {
    const restclient = {};
    const tokenResourceUri = metaClient.forgeEngineRestUrl(engine) + protocol.TOKEN_RESOURCE;
    let currentToken;
    const requestNewToken = function () {
        const data = new URLSearchParams();
        data.append(protocol.USER_PARAM, user);
        if (_.isEmpty(password) === false) {
            data.append(protocol.PASSWORD_PARAM, password);
        }
        LOG.debug("requestNewToken");
        return fetch(tokenResourceUri, {
            body: data,
            headers: {"Content-Type": "application/x-www-form-urlencoded"},
            method: "POST"
        }).then(function (response) {
            if (response.ok) {
                return response.text().then(function (text) {
                    LOG.debug("requestNewToken received");
                    currentToken = text;
                    return true;
                });
            }
            LOG.warn(`requestNewToken failed, status=${response.status}`);
            return response.ok;
        }, function (exc) {
            LOG.warn(`requestNewToken failed`, exc);
        });
    };

    restclient.prepareRequest = function (fetchOptions) {
        const tokenPromise = (
            _.isEmpty(currentToken)
            ? requestNewToken()
            : Promise.resolve(undefined)
        );
        LOG.debug("prepareRequest");
        return tokenPromise.then(function () {
            const headers = {};
            headers[protocol.AUTHORIZATION_HEADER] = protocol.getTokenHeader(currentToken);
            return ext.merge({headers}, fetchOptions);
        });
    };

    restclient.executeRequest = function (url, fetchOptions) {
        LOG.debug(`executeRequest, url=${url}`);
        return restclient.prepareRequest(fetchOptions).then(function (preparedFetchOptions) {
            return fetch(url, preparedFetchOptions);
        }).then(function (response) {
            if (protocol.isHttpResponseUnauthorized(response)) {
                return requestNewToken().then(function (hasNewToken) {
                    if (hasNewToken) {
                        return restclient.executeRequest(url, fetchOptions);
                    }
                    throw new Error("executeRequest, requestNewToken failed");
                });
            }
            return response;
        });
    };

    return Object.freeze(restclient);
};

export default Object.freeze(factory);