UNPKG

liveperson-functions-cli

Version:
238 lines 10.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RestClient = void 0; /* eslint-disable @typescript-eslint/require-await */ const bent = require("bent"); const uuid_1 = require("uuid"); const constants_1 = require("../util/constants"); const predicates_1 = require("../util/predicates"); const restError_1 = require("../types/errors/restError"); const helper_1 = require("../util/helper"); const networkError_1 = require("../types/errors/networkError"); class RestClient { constructor(baseUrl, apiKey) { this.baseUrl = baseUrl; this.apiKey = apiKey; // This allows us to use the http protocol for QA if (baseUrl.startsWith('http')) { this.baseUrl = baseUrl.replace('http://', ''); this.protocol = 'http'; } else { this.protocol = 'https'; } } async createNamespace(accountId, namespace, options) { try { const query = options.ttl ? `?ttlSecond=${options.ttl}` : ''; const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}${query}`; const body = { name: namespace }; await this.performRequestWithDeadline('POST', url, body, { acceptedStatusCodes: [204], contentType: 'buffer', timeout: constants_1.TEN_SECONDS, }); const namespaces = await this.getListOfNamespaces(accountId); return namespaces.find((current) => current.name === namespace); } catch (error) { throw await this.transform(error); } } async deleteNamespace(accountId, namespace) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}`; await this.performRequestWithDeadline('DELETE', url, undefined, { acceptedStatusCodes: [204], contentType: 'buffer', timeout: constants_1.TEN_SECONDS, }); } catch (error) { throw await this.transform(error); } } async getListOfNamespaces(accountId) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}`; const namespaces = (await this.performRequestWithDeadline('GET', url, undefined, { acceptedStatusCodes: [200], contentType: 'json', timeout: constants_1.TEN_SECONDS, })); return namespaces.map((current) => ({ name: current === null || current === void 0 ? void 0 : current.name, createdAt: new Date(current === null || current === void 0 ? void 0 : current.createdAt), ...((current === null || current === void 0 ? void 0 : current.ttlSecond) && { ttlSecond: current === null || current === void 0 ? void 0 : current.ttlSecond, }), // Will add property if present })); } catch (error) { throw await this.transform(error); } } async setOrUpdatePropertiesInNamespace(accountId, namespace, properties, sessionId = constants_1.DEFAULT_ENTITIY) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/${sessionId}/properties`; await this.performRequestWithDeadline('PATCH', url, properties, { acceptedStatusCodes: [204], contentType: 'buffer', timeout: constants_1.TEN_SECONDS, }); return await this.getAllPropertiesInSession(accountId, namespace, sessionId); } catch (error) { throw await this.transform(error); } } async getAllPropertiesInSession(accountId, namespace, sessionId = constants_1.DEFAULT_ENTITIY) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/${sessionId}/properties`; const entitiy = await this.performRequestWithDeadline('GET', url, undefined, { acceptedStatusCodes: [200], contentType: 'json', timeout: constants_1.TEN_SECONDS, }); return entitiy; } catch (error) { throw await this.transform(error); } } async getSelectedPropertiesInSession(accountId, namespace, propertyNames, sessionId = constants_1.DEFAULT_ENTITIY) { const outEntity = {}; // TODO: Maybe need to parallize requests to increase speed for (const property of propertyNames) { try { outEntity[property] = await this.getPropertyInSession(accountId, namespace, property, sessionId); } catch (error) { if (!(0, predicates_1.isNotFoundError)(error)) { throw error; } } } return outEntity; } async getPropertyInSession(accountId, namespace, propertyName, sessionId = constants_1.DEFAULT_ENTITIY) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/${sessionId}/properties/${propertyName}`; const value = await this.performRequestWithDeadline('GET', url, undefined, { acceptedStatusCodes: [200], contentType: 'string', timeout: constants_1.TEN_SECONDS, }); try { return JSON.parse(value); } catch (error) { return value; } } catch (error) { throw await this.transform(error); } } async deletePropertyInSession(accountId, namespace, propertyName, sessionId = constants_1.DEFAULT_ENTITIY) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/${sessionId}/properties/${propertyName}`; await this.performRequestWithDeadline('DELETE', url, undefined, { acceptedStatusCodes: [204], contentType: 'buffer', timeout: constants_1.TEN_SECONDS, }); } catch (error) { throw await this.transform(error); } } async deleteSession(accountId, namespace, sessionId) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/${sessionId}/properties/`; await this.performRequestWithDeadline('DELETE', url, undefined, { acceptedStatusCodes: [204], contentType: 'buffer', timeout: constants_1.TEN_SECONDS, }); } catch (error) { throw await this.transform(error); } } async getListOfSessions(accountId, namespace) { try { const url = `${this.protocol}://${this.baseUrl}/v1/account/${accountId}/${namespace}/session-ids`; const entityList = await this.performRequestWithDeadline('GET', url, undefined, { acceptedStatusCodes: [200], contentType: 'json', timeout: constants_1.TEN_SECONDS, }); return entityList; } catch (error) { throw await this.transform(error); } } async performRequestWithDeadline(method, url, body = undefined, options) { const request = bent(method, options.contentType, ...options.acceptedStatusCodes); for (let attempt = 0; attempt < 3; attempt++) { try { return await (0, helper_1.runTaskWithDeadline)(request(url, body, this.generateHeaders()), options.timeout); } catch (error) { if (!(0, predicates_1.isRetriableError)(error)) { throw error; } if (attempt >= 2) { throw error; } await new Promise((resolve) => setTimeout(resolve, (attempt + 1) * constants_1.CALL_DELAY)); } } // This is here because otherwise Typescript complains, but should never reach here return null; } /** * Helper Method returning an object containing all relevant headers. */ generateHeaders() { // Try to keep then in sync with package.json const name = '@liveperson/context-service'; const version = '0.1.0'; return { 'maven-api-key': this.apiKey, // eslint-disable-next-line @typescript-eslint/naming-convention 'Content-Type': 'application/json', // eslint-disable-next-line @typescript-eslint/naming-convention Accept: 'application/json', // eslint-disable-next-line @typescript-eslint/naming-convention 'X-REQUEST-ID': (0, uuid_1.v4)(), // eslint-disable-next-line @typescript-eslint/naming-convention 'User-Agent': `${name} v${version}`, }; } /** * This method takes an error returned by the bent library and turn it into * either an RestError or a NetworkError * @param error object from bent */ async transform(error) { if ((0, predicates_1.isNetworkError)(error)) { return new networkError_1.NetworkError((error.code || error.errno), error.message); } if (typeof (error === null || error === void 0 ? void 0 : error.json) === 'function') { try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const { message } = await error.json(); return new restError_1.RestError((error === null || error === void 0 ? void 0 : error.statusCode) || -1, message); } catch (_) { return new restError_1.RestError((error === null || error === void 0 ? void 0 : error.statusCode) || -1, error.message); } } return new restError_1.RestError((error === null || error === void 0 ? void 0 : error.statusCode) || -1, error.message); } } exports.RestClient = RestClient; //# sourceMappingURL=client.js.map