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