UNPKG

zcatalyst-cli

Version:

Command Line Tool for CATALYST

318 lines (317 loc) 14.8 kB
'use strict'; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const request_1 = __importDefault(require("request")); const progress_1 = __importDefault(require("../progress")); const index_js_1 = __importDefault(require("../error/index.js")); const errorResponse_1 = __importDefault(require("../errorResponse")); const runtime_store_1 = __importDefault(require("../runtime-store")); const constants_1 = require("../util_modules/constants"); const js_1 = require("../util_modules/js"); const index_1 = require("../util_modules/logger/index"); const project_1 = require("../util_modules/project"); const fs_1 = require("fs"); const throbber_1 = __importDefault(require("../throbber")); const stream_1 = require("stream"); class API { constructor({ authNeeded = true, resolveOnError = false, maxRetry = 3, env = constants_1.DEFAULT.env_name, log = {}, headers = {}, isExternal = false, origin = constants_1.ORIGIN.admin, json = true, showWarning = true, envId = (0, project_1.getEnvId)(), printError = true } = {}) { this.requestOpts = { url: origin, method: 'GET', json, headers }; const projectSecretKey = process.env.CATALYST_PROJECT_SECRET_KEY || process.env.ZC_PROJECT_SECRET_KEY; if (!isExternal) { this.requestOpts.headers = Object.assign(Object.assign({}, this.requestOpts.headers), { Accept: 'application/vnd.catalyst.v2+json', 'X-CATALYST-Environment': env }); if (projectSecretKey) { this.requestOpts.headers['X-ZC-PROJECT-SECRET-KEY'] = projectSecretKey; } if (envId) { this.requestOpts.headers['CATALYST-ORG'] = envId; } } this.requestOpts.headers = Object.assign(Object.assign({}, this.requestOpts.headers), { 'User-Agent': runtime_store_1.default.get('cli.package.name') + '/' + runtime_store_1.default.get('cli.package.version') }); this.authNeeded = authNeeded; this.resolveOnHTTPError = resolveOnError; this.logOpts = log; this.maxRetryCount = maxRetry; this.retryCount = 0; this.showWarning = showWarning; this.printError = printError; } _logReq() { let qs = this.requestOpts.qs ? '\nQuery params: ' + JSON.stringify(this.requestOpts.qs) : ''; qs = this.logOpts.skipQuery === true ? '\n<request query omitted>' : qs; let body = this.requestOpts.body ? '\nRequest Body: ' + JSON.stringify(this.requestOpts.body) : ''; body += this.requestOpts.form ? '\nRequest Form: ' + JSON.stringify(this.requestOpts.form) : ''; body = this.logOpts.skipReqBody === true ? '\n<request body omitted>' : body; (0, index_1.debug)('>>>> HTTP REQUEST : ' + this.requestOpts.method + ' ' + this.requestOpts.url + ' ' + qs + body + '\n'); } _logResp(resp) { const ignoreHeaders = [ 'content-security-policy-report-only', 'set-cookie', 'content-security-policy' ]; const logHeaders = Object.assign({}, resp.headers); ignoreHeaders.forEach((header) => delete logHeaders[header]); (0, index_1.debug)('<<<< HTTP RESPONSE : ' + resp.statusCode + '\n' + 'Response Headers: ' + JSON.stringify(logHeaders) + '\n'); if (!js_1.JS.isUndefined(resp.timings)) { (0, index_1.debug)('TOTAL TIME TAKEN : ' + Number(resp.timings.end.toFixed(3)) + ' ms\n'); (0, index_1.debug)('REQUEST PHASES : ' + resp.timingPhases); } if (resp.statusCode >= 200 && resp.statusCode < 300 && this.logOpts.progress !== undefined) { js_1.JS.set(this.logOpts, 'progress.total', resp.headers['content-length']); this.downloadProgress = new progress_1.default(this.logOpts.progress); } } _logUploadProgress({ chunk, error } = {}) { if (this.uploadProgress) { !chunk || error ? this.uploadProgress.error(error) : this.uploadProgress.tick(chunk.length); } } _logDownloadProgress({ chunk, error } = {}) { if (this.downloadProgress) { if (chunk) { return this.downloadProgress.tick(chunk.length); } if (error) { return this.downloadProgress.error(error); } } } _addAuthHeader() { return __awaiter(this, void 0, void 0, function* () { const credential = (yield Promise.resolve().then(() => __importStar(require('../authentication/credential.js')))).default; const accessToken = yield credential.getAccessToken(); js_1.JS.set(this.requestOpts, 'headers.authorization', 'Bearer ' + accessToken); }); } _parseResponse(resp, body, rawResponse) { const rawResponseData = rawResponse.length > 0 ? Buffer.concat(rawResponse) : undefined; if (rawResponseData && js_1.JS.includes(resp.headers['content-type'], 'json')) { try { body = JSON.parse(rawResponseData.toString()); } catch (e) { const err = index_js_1.default.getErrorInstance(e); (0, index_1.debug)('API Parsing Error: ' + err.message); } } if (resp.statusCode >= 400 && !this.logOpts.skipRespBody) { (0, index_1.debug)('Response Body : ' + JSON.stringify(resp.body) + '\n'); if (!this.resolveOnHTTPError) { const errRes = (0, errorResponse_1.default)(resp, body, !this.printError); this._logDownloadProgress({ error: errRes }); throw errRes; } this._logDownloadProgress({ error: (0, errorResponse_1.default)(resp, body, !this.printError) }); } return { status: resp.statusCode, response: resp, body: js_1.JS.includes(resp.headers['content-type'], 'json') && typeof body === 'string' ? JSON.parse(body) : body }; } _retry(err) { return __awaiter(this, void 0, void 0, function* () { if (++this.retryCount > this.maxRetryCount) { throw new index_js_1.default('API Error after retrying : ' + err.message, { original: err, exit: 2 }); } (0, index_1.debug)('API Error while firing request : ' + err.message + '\n'); (0, index_1.debug)('>>>> RETRYING\n'); return this._request(true); }); } _request(retry = false) { return __awaiter(this, void 0, void 0, function* () { if (!retry) { this._logReq(); } return new Promise((resolve, reject) => { const responseBuffer = []; let isJSONResponse = false; let isErrorPage = false; const throbber = throbber_1.default.getInstance(); if (this.logOpts.uploadProgress !== undefined && this.logOpts.stream instanceof fs_1.ReadStream) { const _stream = this.logOpts.stream; this.uploadProgress = new progress_1.default(this.logOpts.uploadProgress); _stream.on('data', (chunk) => { this._logUploadProgress({ chunk }); }); _stream.on('error', (er) => this._logUploadProgress({ error: er })); } if (this.logOpts.awaitingSpinner) { this.logOpts.stream ? this.logOpts.stream.on('end', () => throbber.add('response_await', { text: this.logOpts.awaitingSpinner })) : throbber.add('response_await', { text: this.logOpts.awaitingSpinner }); } (0, request_1.default)(this.requestOpts, (err) => __awaiter(this, void 0, void 0, function* () { this.logOpts.awaitingSpinner && throbber.remove('response_await'); this._logUploadProgress({ error: err }); this._logDownloadProgress({ error: err }); if (err) { switch (err.code) { case 'ETIMEDOUT': case 'ENOTFOUND': case 'ESOCKETTIMEDOUT': this.showWarning && (0, index_1.warning)(err.code + ' has occured while communicating remote server. Kindly be patient while the cli retries this request.'); try { resolve(yield this._retry(err)); } catch (e) { const error = index_js_1.default.getErrorInstance(e); error.exit = 2; reject(error); } break; } reject(new index_js_1.default('API Error: ' + err.message, { original: err, exit: 2 })); } })) .on('request', () => { this.requestOpts.body instanceof stream_1.Readable && this.requestOpts.body.isPaused() && this.requestOpts.body.resume(); }) .on('response', (resp) => { isJSONResponse = js_1.JS.includes(resp.headers['content-type'], 'json'); isErrorPage = !(resp.statusCode >= 200 && resp.statusCode < 300); this._logResp(resp); }) .on('complete', (resp, body) => __awaiter(this, void 0, void 0, function* () { try { resolve(this._parseResponse(resp, body, responseBuffer)); } catch (err) { reject(err); } })) .on('data', (data) => { if (isJSONResponse) { responseBuffer.push(data); } if (!isErrorPage) { this._logDownloadProgress({ chunk: data }); } }); }); }); } fire(method, path, options) { return __awaiter(this, void 0, void 0, function* () { this.resolveOnHTTPError = js_1.JS.get(options, 'resolveOnError', this.resolveOnHTTPError); this.printError = (options === null || options === void 0 ? void 0 : options.printError) || this.printError; this.maxRetryCount = js_1.JS.get(options, 'maxRetry', this.maxRetryCount); this.authNeeded = js_1.JS.get(options, 'authNeeded', this.authNeeded); this.logOpts = js_1.JS.get(options, 'log', this.logOpts); this.requestOpts = js_1.JS.defaultsDeep(js_1.JS.omit(options, ['origin', 'auth', 'maxRetry', 'resolveOnError', 'log']), this.requestOpts); this.requestOpts.url = ((options === null || options === void 0 ? void 0 : options.origin) || this.requestOpts.url || constants_1.ORIGIN.admin) + path; this.requestOpts.method = method; if (this.authNeeded) { yield this._addAuthHeader(); return this._request(); } return this._request(); }); } get(path, options) { return __awaiter(this, void 0, void 0, function* () { return this.fire('GET', path, options); }); } put(path, options) { return __awaiter(this, void 0, void 0, function* () { return this.fire('PUT', path, options); }); } post(path, options) { return __awaiter(this, void 0, void 0, function* () { return this.fire('POST', path, options); }); } delete(path, options) { return __awaiter(this, void 0, void 0, function* () { return this.fire('DELETE', path, options); }); } head(path) { return __awaiter(this, void 0, void 0, function* () { return this.fire('HEAD', path); }); } patch(path, options) { return __awaiter(this, void 0, void 0, function* () { return this.fire('PATCH', path, options); }); } } exports.default = API;