@controlplane/cli
Version:
Control Plane Corporation CLI
188 lines (186 loc) • 6.55 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertAuthTokenForDebug = exports.makeClient = exports.makeSessionClient = exports.wire = void 0;
const _ = require("lodash");
const https = require("https");
const querystring = require("querystring");
const winston = require("winston");
const axios_retry_1 = require("axios-retry");
const version_1 = require("../util/version");
const stream_1 = require("stream");
const client_1 = require("../rest/client");
const logger_1 = require("../util/logger");
const axiosRetry_1 = require("../util/axiosRetry");
exports.wire = winston.createLogger({
level: 'debug',
exitOnError: false,
transports: [
new winston.transports.Console({
level: 'error',
stderrLevels: ['error', 'warning', 'notice', 'info', 'debug'],
format: winston.format.combine(winston.format.printf((ti) => {
return new Date().toLocaleTimeString() + ' ' + ti.message;
})),
}),
],
});
function addDebugInterceptors(instance) {
instance.interceptors.request.use((req) => {
exports.wire.debug(formatRequest(req));
return req;
});
instance.interceptors.response.use((res) => {
exports.wire.debug(formatResponse(res));
if (res.status >= 200 && res.status < 300) {
return res;
}
throw require('axios/lib/core/createError')('Request failed with status code ' + res.status, res.config, null, res.request, res);
});
}
function makeSessionClient(session, endpoint) {
let timeout;
if (session.profile.request.timeout !== undefined) {
// millis
timeout = 1000 * session.profile.request.timeout;
}
const cfg = {
validateStatus: (status) => {
if (session.debug.debug) {
return true;
}
return status >= 200 && status < 300;
},
maxContentLength: -1,
baseURL: endpoint !== null && endpoint !== void 0 ? endpoint : session.request.endpoint,
timeout: timeout,
headers: {
'User-Agent': `cpln-cli ${version_1.About.build}/ node ${process.version}`,
'x-cpln-session': session.id,
},
};
if (session.request.insecure) {
cfg.httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
}
if (session.request.token) {
cfg.headers['Authorization'] = `Bearer ${session.request.token}`;
}
const axiosInstance = require('axios').default.create(cfg);
(0, axios_retry_1.default)(axiosInstance, (0, axiosRetry_1.getStandardRetryConfig)());
if (session.debug.debug) {
addDebugInterceptors(axiosInstance);
}
if (session.request.token) {
return new client_1.RestClient(axiosInstance);
}
///////////////// dynamic on-demand auth
async function lazyAuthenticateHeader(cfg) {
// header populated already, explicitly
if (cfg.headers['Authorization']) {
return;
}
// get new token & save it
const oldAuth = _.cloneDeep(session.profile.authInfo);
const computedHeader = await require('../login/auth').makeAuthorizationHeader(session.profile);
if (!_.isEqual(oldAuth, session.profile.authInfo)) {
logger_1.logger.debug('Persisting new token to profile');
session.env.profileManager.update(session.profile);
}
cfg.headers['Authorization'] = computedHeader;
session.request.token = computedHeader;
}
axiosInstance.interceptors.request.use(async (cfg) => {
await lazyAuthenticateHeader(cfg);
return cfg;
});
return new client_1.RestClient(axiosInstance);
}
exports.makeSessionClient = makeSessionClient;
function makeClient(request, endpoint) {
let timeout = undefined;
if (request.timeout) {
timeout = request.timeout * 1000; // Convert from seconds to milli seconds
}
const cfg = {
validateStatus: (status) => {
return status >= 200 && status < 300;
},
maxContentLength: -1,
baseURL: endpoint !== null && endpoint !== void 0 ? endpoint : request.endpoint,
timeout: timeout,
headers: {
'User-Agent': `cpln-cli ${version_1.About.build}/ node ${process.version}`,
},
};
if (request.insecure) {
cfg.httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
}
if (request.token) {
cfg.headers['Authorization'] = request.token;
}
return new client_1.RestClient(require('axios').default.create(cfg));
}
exports.makeClient = makeClient;
function convertAuthTokenForDebug(token) {
if (token.startsWith('Bearer ')) {
token = token.split('Bearer ')[1];
}
token = `${token.slice(0, 3)}...${token.slice(token.length - 3)}`;
return token;
}
exports.convertAuthTokenForDebug = convertAuthTokenForDebug;
function formatRequest(req) {
const { common, get, head, post, put, patch, ...others } = req.headers;
let headers = Object.keys({ ...common, ...req.headers[req.method], ...others })
.filter((key) => key != 'delete' && req.headers[key])
.map((key) => {
let value = req.headers[key];
if (key.toLowerCase() === 'authorization') {
value = convertAuthTokenForDebug(value);
}
return `${key}: ${value}`;
})
.join('\n> ');
let body = '';
if (!!req.data && typeof req.data === 'object') {
body = JSON.stringify(req.data, undefined, 2);
}
else if (!!req.data && typeof req.data === 'string') {
body = req.data;
}
let q = querystring.stringify(req.params);
if (q.length > 0) {
q = '?' + q;
}
return `>>>>
> ${req.method.toUpperCase()} ${req.url}${q}
> Host: ${new URL(req.baseURL).hostname}
> ${headers}
${body}
>>>>>>>`;
}
function formatResponse(res) {
let body = '';
if (res.data instanceof stream_1.Readable) {
//console.log(res.data)
body = '[...streaming data...]';
}
else if (!!res.data && typeof res.data === 'object') {
body = JSON.stringify(res.data, null, 2);
}
else if (!!res.data && typeof res.data === 'string') {
body = res.data;
}
const headers = Object.entries(res.headers)
.map(([key, value]) => `${key}: ${value}`)
.join('\n< ');
return `<<<<
< ${res.status} ${res.statusText}
< ${headers}
${body}
<<<<<<<<`;
}
//# sourceMappingURL=client.js.map
;