UNPKG

piral-cli

Version:

The standard CLI for creating and building a Piral instance or a Pilet.

260 lines • 8.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAxiosOptions = getAxiosOptions; exports.getCertificate = getCertificate; exports.getAuthorizationHeaders = getAuthorizationHeaders; exports.getDefaultAgent = getDefaultAgent; exports.getAgent = getAgent; exports.downloadFile = downloadFile; exports.createAxiosForm = createAxiosForm; exports.handleAxiosError = handleAxiosError; exports.postData = postData; exports.postForm = postForm; exports.postFile = postFile; const path_1 = require("path"); const https_1 = require("https"); const os_1 = require("os"); const fs_1 = require("fs"); const log_1 = require("./log"); const config_1 = require("./config"); const info_1 = require("./info"); const io_1 = require("./io"); const interactive_1 = require("./interactive"); const external_1 = require("../external"); function getMessage(body) { if (typeof body === 'string') { try { const content = JSON.parse(body); return content.message; } catch (ex) { return body; } } else if (body && typeof body === 'object') { if ('message' in body) { return body.message; } else { return JSON.stringify(body); } } return ''; } function streamToFile(source, target) { const dest = (0, fs_1.createWriteStream)(target); return new Promise((resolve, reject) => { source.pipe(dest); source.on('error', (err) => reject(err)); dest.on('finish', () => resolve([target])); }); } function getAxiosOptions(url) { const auth = config_1.config.auth?.[url]; switch (auth?.mode) { case 'header': return { headers: { [auth.key]: auth.value, }, }; case 'http': return { auth: { username: auth.username, password: auth.password, }, }; default: return {}; } } async function getCertificate(cert = config_1.config.cert) { (0, log_1.log)('generalDebug_0003', 'Checking if certificate exists.'); if (await (0, io_1.checkExists)(cert)) { const dir = (0, path_1.dirname)(cert); const file = (0, path_1.basename)(cert); (0, log_1.log)('generalDebug_0003', `Reading certificate file "${file}" from "${dir}".`); return await (0, io_1.readBinary)(dir, file); } return undefined; } function getAuthorizationHeaders(scheme, key) { if (key) { switch (scheme) { case 'basic': return { authorization: `Basic ${key}`, }; case 'bearer': return { authorization: `Bearer ${key}`, }; case 'digest': return { authorization: `Digest ${key}`, }; case 'none': default: return { authorization: key, }; } } return {}; } async function getDefaultAgent() { const ca = await getCertificate(); const allowSelfSigned = config_1.config.allowSelfSigned; return getAgent({ ca, allowSelfSigned }); } function getAgent({ allowSelfSigned, ca }) { if (ca) { return new https_1.Agent({ ca }); } else if (allowSelfSigned) { return new https_1.Agent({ rejectUnauthorized: false }); } else { return undefined; } } function downloadFile(target, httpsAgent) { return external_1.axios .get(target, { responseType: 'stream', headers: info_1.standardHeaders, httpsAgent, }) .then((res) => { const rid = Math.random().toString(36).split('.').pop(); const target = (0, path_1.join)((0, os_1.tmpdir)(), `pilet_${rid}.tgz`); (0, log_1.log)('generalDebug_0003', `Writing the downloaded file to "${target}".`); return streamToFile(res.data, target); }) .catch((error) => { (0, log_1.log)('failedHttpGet_0068', error.message); return []; }); } function createAxiosForm(formData) { const form = new external_1.FormData(); Object.keys(formData).forEach((key) => { const value = formData[key]; if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { form.append(key, value); } else if (Array.isArray(value)) { form.append(key, value[0], value[1]); } else { // unknown value - skip for now } }); return form; } function handleAxiosError(error, interactive, httpsAgent, refetch, onfail) { if (!onfail) { onfail = () => { throw error; }; } if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx const { data, statusText, status } = error.response; if (interactive && 'interactiveAuth' in data) { const { interactiveAuth } = data; if (typeof interactiveAuth === 'string') { (0, log_1.log)('generalDebug_0003', `Received status "${status}" from HTTP - trying interactive log in to "${interactiveAuth}".`); return (0, interactive_1.getTokenInteractively)(interactiveAuth, httpsAgent).then(({ mode, token }) => refetch(mode, token)); } } const message = getMessage(data) || ''; return onfail(status, statusText, message); } else if (error.isAxiosError) { // axios initiated error: try to parse message from error object let errorMessage = error.errno || 'Unknown Axios Error'; if (typeof error.toJSON === 'function') { const errorObj = error.toJSON(); errorMessage = errorObj?.message ?? errorMessage; } return onfail(500, undefined, errorMessage); } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js return onfail(500, undefined, error.request); } else { // Something happened in setting up the request that triggered an Error return onfail(500, undefined, error.message); } } function createPayload(data, scheme, key, customHeaders, isForm) { if (isForm) { const form = createAxiosForm(data); const extraHeaders = form.getHeaders(); const headers = { ...info_1.standardHeaders, ...customHeaders, ...getAuthorizationHeaders(scheme, key), ...extraHeaders, }; return [form, headers]; } else { const headers = { ...info_1.standardHeaders, ...customHeaders, ...getAuthorizationHeaders(scheme, key), }; return [data, headers]; } } async function postData(target, scheme, key, data, customHeaders = {}, httpsAgent = undefined, isForm = false, interactive = false) { try { const [body, headers] = createPayload(data, scheme, key, customHeaders, isForm); const res = await external_1.axios.post(target, body, { headers, httpsAgent, maxContentLength: Infinity, maxBodyLength: Infinity, }); return { status: res.status, success: true, response: res.data, }; } catch (error) { return await handleAxiosError(error, interactive, httpsAgent, (mode, token) => postData(target, mode, token, data, customHeaders, httpsAgent, isForm, false), (status, statusText, response) => { if (status === 500) { (0, log_1.log)('failedHttpPost_0065', response); return { status: 500, success: false, response: undefined, }; } else { (0, log_1.log)('unsuccessfulHttpPost_0066', statusText, status, response); return { status, success: false, response, }; } }); } } function postForm(target, scheme, key, formData, customHeaders = {}, httpsAgent = undefined, interactive = false) { return postData(target, scheme, key, formData, customHeaders, httpsAgent, true, interactive); } function postFile(target, scheme, key, file, customFields = {}, customHeaders = {}, agent = undefined, interactive = false) { const data = { ...customFields, file: [file, 'pilet.tgz'] }; return postForm(target, scheme, key, data, customHeaders, agent, interactive); } //# sourceMappingURL=http.js.map