UNPKG

caprover-api

Version:
174 lines (173 loc) 6.61 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ErrorFactory_1 = __importDefault(require("./ErrorFactory")); const cross_fetch_1 = __importDefault(require("cross-fetch")); function buildQueryParams(params) { if (!params || Object.keys(params).length === 0) return ''; return ('?' + Object.entries(params) .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)) .join('&')); } let TOKEN_HEADER = 'x-captain-auth'; let NAMESPACE = 'x-namespace'; let CAPTAIN = 'captain'; class CrossFetchEngine { static async post(url, variables, headers) { const res = await (0, cross_fetch_1.default)(url, { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers, }, body: JSON.stringify(variables), }); if (!res.ok) { const errBody = await res.text(); throw new Error(`HTTP ${res.status}: ${errBody}`); } return res.json(); } static async get(url, params, headers) { const fullUrl = url + (params && Object.keys(params).length > 0 ? buildQueryParams(params) : ''); const res = await (0, cross_fetch_1.default)(fullUrl, { method: 'GET', headers: { 'Content-Type': 'application/json', ...headers, }, }); if (!res.ok) { const errBody = await res.text(); throw new Error(`HTTP ${res.status}: ${errBody}`); } return res.json(); } } class HttpClient { constructor(baseUrl, authTokenProvider, onLoginRequested) { this.baseUrl = baseUrl; this.authTokenProvider = authTokenProvider; this.onLoginRequested = onLoginRequested; this.GET = 'GET'; this.POST = 'POST'; this.isDestroyed = false; // } createHeaders() { let headers = {}; headers[NAMESPACE] = CAPTAIN; // check user/appData or apiManager.uploadAppData before changing this signature. return Promise.resolve() // .then(() => { return this.authTokenProvider(); }) .then((authToken) => { if (authToken) headers[TOKEN_HEADER] = authToken; return headers; }); } destroy() { this.isDestroyed = true; } fetch(method, endpoint, variables) { const self = this; return function () { return Promise.resolve() // .then(function () { return self.fetchInternal(method, endpoint, variables); // }) .then(function (fetchResponse) { if ( // if we ever get STATUS_ERROR_NOT_AUTHORIZED when trying to log in, we will end up in an infinite loop! fetchResponse.status === ErrorFactory_1.default.STATUS_AUTH_TOKEN_INVALID) { return self .onLoginRequested() // .then(function () { return self .fetchInternal(method, endpoint, variables) .then(function (httpResponse) { return httpResponse; }); }) .catch(function (error) { return Promise.reject(error); }); } else { return fetchResponse; } }) .then(function (data) { if (data.status !== ErrorFactory_1.default.OKAY && data.status !== ErrorFactory_1.default.OK_PARTIALLY && data.status !== ErrorFactory_1.default.OKAY_BUILD_STARTED) { throw ErrorFactory_1.default.createError(data.status || ErrorFactory_1.default.UNKNOWN_ERROR, data.description || ''); } return data; }) .then(function (data) { // 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. // 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); }); }) .catch(function (error) { return new Promise(function (resolve, reject) { if (!self.isDestroyed) return reject(error); }); }); }; } fetchInternal(method, endpoint, variables) { if (method === this.GET) return this.getReq(endpoint, variables); if (method === this.POST) return this.postReq(endpoint, variables); throw new Error(`Unknown method: ${method}`); } getReq(endpoint, variables) { const self = this; return Promise.resolve() // .then(function () { return self.createHeaders(); }) .then(function (headers) { return CrossFetchEngine.get(self.baseUrl + endpoint, variables, headers); }) .then(function (data) { // console.log(data); return data; }); } postReq(endpoint, variables) { const self = this; return Promise.resolve() // .then(function () { return self.createHeaders(); }) .then(function (headers) { return CrossFetchEngine.post(self.baseUrl + endpoint, variables, headers); }) .then(function (data) { // console.log(data); return data; }); } } exports.default = HttpClient;