caprover-lib
Version:
A library to communicate with CapRover instances
176 lines (142 loc) • 5.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ErrorFactory = _interopRequireDefault(require("../utils/ErrorFactory"));
var _Logger = _interopRequireDefault(require("../utils/Logger"));
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
var _url = require("url");
var _formData = _interopRequireDefault(require("form-data"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const TOKEN_HEADER = 'x-captain-auth';
const NAMESPACE = 'x-namespace';
const CAPTAIN = 'captain';
class HttpClient {
constructor(baseUrl, authToken, onAuthFailure) {//
_defineProperty(this, "GET", 'GET');
_defineProperty(this, "POST", 'POST');
_defineProperty(this, "POST_DATA", 'POST_DATA');
_defineProperty(this, "isDestroyed", false);
this.baseUrl = baseUrl;
this.authToken = authToken;
this.onAuthFailure = onAuthFailure;
}
createHeaders() {
const headers = {};
if (this.authToken) {
headers[TOKEN_HEADER] = this.authToken;
}
headers[NAMESPACE] = CAPTAIN; // check user/appData or apiManager.uploadAppData before changing this signature.
return headers;
}
setAuthToken(authToken) {
this.authToken = authToken;
}
destroy() {
this.isDestroyed = true;
}
fetch(method, endpoint, variables) {
const self = this;
return function () {
return Promise.resolve() //
.then(function () {
if (!process.env.REACT_APP_IS_DEBUG) {
return Promise.resolve();
}
return new Promise(function (res) {
setTimeout(res, 500);
});
}).then(function () {
return self.fetchInternal(method, endpoint, variables); //
}).then(function (data) {
if (data.status === _ErrorFactory.default.STATUS_AUTH_TOKEN_INVALID) {
return self.onAuthFailure() //
.then(function () {
return self.fetchInternal(method, endpoint, variables).then(function (newRequestResponse) {
return newRequestResponse;
});
});
} else {
return data;
}
}).then(function (data) {
if (data.status !== _ErrorFactory.default.OKAY && data.status !== _ErrorFactory.default.OKAY_BUILD_STARTED) {
throw _ErrorFactory.default.createError(data.status || _ErrorFactory.default.UNKNOWN_ERROR, data.description || '');
}
return data;
}).then(function (data) {
// tslint:disable-next-line: max-line-length
// These two blocks are clearly memory leaks! But I don't have time to fix them now... I need to CANCEL the promise, but since I don't
// have CANCEL method on the native Promise, I return a promise that will never RETURN if the HttpClient is destroyed.
// tslint:disable-next-line: max-line-length
// Will fix them later... but it shouldn't be a big deal anyways as it's only a problem when user navigates away from a page before the
// network request returns back.
return new Promise(function (resolve, reject) {
// data.data here is the "data" field inside the API response! {status: 100, description: "Login succeeded", data: {…}}
if (!self.isDestroyed) {
return resolve(data.data);
}
_Logger.default.dev('Destroyed then not called');
});
}).catch(function (error) {
// Logger.log('');
// Logger.error(error.message || error);
return new Promise(function (resolve, reject) {
if (!self.isDestroyed) {
return reject(error);
}
_Logger.default.dev('Destroyed catch not called');
});
});
};
}
fetchInternal(method, endpoint, variables) {
if (method === this.GET) {
return this.getReq(endpoint, variables);
}
if (method === this.POST || method === this.POST_DATA) {
return this.postReq(endpoint, variables, method);
}
throw new Error('Unknown method: ' + method);
}
getReq(endpoint, variables) {
const url = new _url.URL(this.baseUrl + endpoint);
url.search = new _url.URLSearchParams(variables).toString();
return (0, _nodeFetch.default)(url.toString(), {
method: 'GET',
headers: { ...this.createHeaders(),
'Content-Type': 'application/json',
Accept: 'application/json'
}
}).then(data => data.json()).then(function (data) {
return data;
});
}
postReq(endpoint, variables, method) {
if (method === this.POST_DATA) {
return (0, _nodeFetch.default)(this.baseUrl + endpoint, {
method: 'POST',
headers: { ...this.createHeaders(),
'Content-Type': 'application/json',
Accept: 'application/json'
},
body: new _formData.default(variables)
}).then(data => data.json()).then(function (data) {
return data;
});
}
return (0, _nodeFetch.default)(this.baseUrl + endpoint, {
method: 'POST',
headers: { ...this.createHeaders(),
'Content-Type': 'application/json',
Accept: 'application/json'
},
body: JSON.stringify(variables)
}).then(data => data.json()).then(function (data) {
return data;
});
}
}
exports.default = HttpClient;