UNPKG

microstrategy

Version:

A node.js wrapper for the MicroStrategy REST API & Task API

277 lines (239 loc) 6.98 kB
const axios = require('axios'); const qs = require('querystring'); const assert = require('assert'); module.exports = class RestConnection { constructor({ baseUrl = 'https://demo.microstrategy.com/MicroStrategyLibrary/api', skipValidateResponseStatusCode = false, skipThrowOnHTTPException = false }) { this._baseUrl; this.setBaseUrl(baseUrl); this.defaultHeaders = { Accept: 'application/json', 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate, br', }; this.sessionHeaders = {}; this.sessionCredentials; this.globalRequestOptions = { withCredentials: true, timeout: 1000 * 60 * 10 // 10 minute timeout by default }; // Flag to skip checking the HTTP response status code in any request this.skipValidateResponseStatusCode = !!skipValidateResponseStatusCode; // Flag to treat HTTP exceptions as a resolved promise (instead of rejecting) this.skipThrowOnHTTPException = !!skipThrowOnHTTPException; } /** * @returns {Object} default headers required by almost every request */ getDefaultHeaders() { return this.defaultHeaders; } /** * @public Get request options included with every request. See for detailed list of options: https://github.com/axios/axios#request-config * @returns {Object} with default options included with every axios request. Modify with care. */ getRequestOptions() { return this.globalRequestOptions; } /** * @returns URL pointing to MicroStrategy Library REST API base */ getBaseUrl() { return this._baseUrl; } /** * @param {String} newUrl - URL pointing to MicroStrategy Library REST API base */ setBaseUrl(newUrl) { this._baseUrl = newUrl; // Ensure URL ends in backslash if (this.getBaseUrl().substr(-1) != '/') { this._baseUrl += '/'; } return this; } /** * Get stored auth token from memory. Assumes token was previously stored via auth.login() or setSessionHeaders() * @returns {String} authToken */ getAuthToken() { if (!this.sessionHeaders) { throw new Error( 'No stored session headers - create session first via auth.login()' ); } const token = this.sessionHeaders['X-MSTR-AuthToken']; if (!token) { throw new Error( 'No stored auth token - create session first via auth.login()' ); } return token; } /** * Store auth token in-memory for future executions. Other methods will automatically try to use this token. * @param {String} tokenValue */ setAuthToken(tokenValue) { this.sessionHeaders['X-MSTR-AuthToken'] = tokenValue; return this; } getSessionHeaders() { return this.sessionHeaders; } setSessionHeaders(sessionHeaders) { if (!sessionHeaders) { this.sessionHeaders = {}; } else { this.sessionHeaders = { ...sessionHeaders }; } return this; } getSessionCredentials() { return this.sessionCredentials; } setSessionCredentials(requestParams = {}) { this.sessionCredentials = requestParams; return this; } setProjectId(projectID) { this.projectID = projectID; return this; } getProjectId() { return this.projectID; } /** * Get header used to dictate which project to use. * * @param {String} projectId * @param {Object} [mergeHeaders={}] Optional, other headers to include in returned object. * @returns {Object} containing header to specify this project in a request */ getProjectHeader(projectId = this.getProjectId(), mergeHeaders = {}) { if (typeof projectId == 'boolean' && !!projectId) { projectId = this.getProjectId(); } assert(projectId, 'No projectId provided. Provide it as a function parameter or pre-set it universally using restApi.setProjectId()'); return { 'X-MSTR-ProjectID': projectId, ...mergeHeaders, }; } /** * Make HTTP request to MicroStrategy REST API * * @param {String} endpoint - example: 'auth/login' * @param {Object} params - request parameters * @param {String} [method='GET'] - HTTP method (GET/POST/PUT/DELETE/etc) * @param {Object} customHeaders - optional: extra headers to merge into request * @param {Object} [additionalOptions={}] - Additional query parameters used in specific endpoints * @returns {Promise} resolving with axios request response. */ _makeRequest( endpoint, params, method = 'GET', customHeaders, additionalOptions = {} ) { const fullUrl = this.getBaseUrl() + endpoint; switch (method.toUpperCase()) { case 'GET': return this.get(fullUrl, params, customHeaders); case 'HEAD': return this.get(fullUrl, params, customHeaders, true, 'HEAD'); case 'POST': return this.post(fullUrl, params, additionalOptions, customHeaders); case 'PATCH': return this.post( fullUrl, params, additionalOptions, customHeaders, 'PATCH' ); case 'DELETE': return this.post( fullUrl, params, additionalOptions, customHeaders, 'DELETE' ); case 'PUT': return this.post( fullUrl, params, additionalOptions, customHeaders, 'PUT' ); } } get( url, queryParams, customHeaders = {}, mergeHeaders = true, requestMethod = 'GET' ) { const options = { method: requestMethod, headers: this._getHeaders(customHeaders, mergeHeaders), url: url, ...this.getRequestOptions() }; if (queryParams) { options.url += '?' + qs.stringify(queryParams); } // console.log("Making GET request: ", options); return axios(options); } post( url, requestBody, queryParams, customHeaders = {}, requestMethod = 'POST', mergeHeaders = true ) { const options = { method: requestMethod, headers: this._getHeaders(customHeaders, mergeHeaders), data: requestBody, url: url, ...this.getRequestOptions() }; if (queryParams) { options.url += '?' + qs.stringify(queryParams); } if (requestBody) { options.data = requestBody; } // console.log("Making POST request: ", options); return axios(options); } /** * @private Merge headers and automatically append sessionHeaders if available * * @param {Object} [customHeaders={}] * @param {boolean} mergeHeaders * @returns {Object} containing desired headers merged into single object */ _getHeaders(customHeaders = {}, mergeHeaders) { const defaultHeaders = this.getDefaultHeaders(); const sessionHeaders = this.getSessionHeaders(); if (mergeHeaders) { return { ...customHeaders, ...defaultHeaders, ...sessionHeaders, }; } return Object.keys(customHeaders).length ? customHeaders : defaultHeaders; } };