@apistudio/apim-cli
Version:
CLI for API Management Products
165 lines (164 loc) • 5.53 kB
JavaScript
import { LogWrapper } from '../service/log-wrapper.js';
import { createObjectCsvStringifier } from 'csv-writer';
import { PDFDocument, StandardFonts } from 'pdf-lib';
export const errorsArray = [];
export const addErrorToResponse = (errorCode, field, description) => {
errorsArray.push({
code: errorCode,
field: field,
description: description,
});
LogWrapper.logDebug('0202', errorCode, field, description);
};
export const constructErrorResponse = () => {
LogWrapper.logDebug('0003', 'Constructing error response.');
const tempErrorsArray = [...errorsArray];
errorsArray.length = 0;
LogWrapper.logDebug('0203', `${tempErrorsArray.length}`);
return {
respCode: 400,
message: 'Invalid Assets or Reference in the Zip',
Endpoints: [],
errors: tempErrorsArray,
};
};
// TODO confirm and update sensitive keys and patterns
const SENSITIVE_KEYS = ['password', 'token'];
const SENSITIVE_PATTERNS = [
/secret/i,
/sensitive/i,
/env/i,
/auth/i,
/credential/i,
/api.?key/i,
/bearer/i,
];
export const filterSensitiveData = (data) => {
const filter = (obj) => {
const result = {};
for (const key in obj) {
const lowerKey = key.toLowerCase();
const isSensitive = SENSITIVE_KEYS.includes(lowerKey) ||
SENSITIVE_PATTERNS.some((pattern) => pattern.test(lowerKey));
if (isSensitive) {
continue;
}
const value = obj[key];
if (value && typeof value === 'object' && !Array.isArray(value)) {
result[key] = filter(value); // Recurse into nested object
}
else {
result[key] = value;
}
}
return result;
};
return filter(data);
};
export const generateCSV = (data) => {
if (data.length === 0) {
return Buffer.from('', 'utf-8');
}
const headers = Object.keys(data[0] || {}).map((field) => ({
id: field,
title: field,
}));
const csvStringifier = createObjectCsvStringifier({ header: headers });
const csv = csvStringifier.getHeaderString() + csvStringifier.stringifyRecords(data);
return Buffer.from(csv, 'utf-8');
};
export const generatePDF = async (data) => {
const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage();
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
let y = page.getHeight() - 50;
page.drawText('Run Report', {
x: 200,
y,
size: 14,
font,
});
y -= 30;
data.forEach((entry, index) => {
page.drawText(`Entry ${index + 1}`, {
x: 50,
y,
size: 12,
font,
});
y -= 20;
for (const [key, value] of Object.entries(entry)) {
page.drawText(`${key}: ${value}`, {
x: 60,
y,
size: 10,
font,
});
y -= 15;
}
y -= 10;
});
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes);
};
export const sanitizeAxiosResponse = (response, error = null) => {
if (error) {
// If we got an Axios error, extract meaningful info
const cookieHeader = error.response?.headers.find((h) => h.key.toLowerCase() === 'set-cookie');
const cookies = cookieHeader?.value || []; // This is an array of cookie strings
return {
success: false,
message: error.message,
code: error.code || null,
status: error.response?.status || null,
statusText: error.response?.statusText || null,
headers: error.response?.headers || {},
cookies: parseSetCookies(cookies),
config: {
method: error.config?.method,
url: error.config?.url,
timeout: error.config?.timeout,
},
data: error.response?.data || null,
};
}
const cookieHeader = response.headers.find((h) => h.key.toLowerCase() === 'set-cookie');
const cookies = cookieHeader?.value || []; // This is an array of cookie strings
// Success case
return {
success: isSuccessStatus(response.status),
status: response.status,
statusText: response.statusText,
headers: response.headers,
cookies: parseSetCookies(cookies),
config: {
method: response.config?.method,
url: response.config?.url,
timeout: response.config?.timeout,
},
data: response.data,
responseTime: response.responseTime,
};
};
export const isSuccessStatus = (status) => {
return status >= 200 && status < 300;
};
export const parseSetCookies = (cookies) => {
// Handle empty, null, or undefined input
if (!cookies || (typeof cookies === 'string' && cookies.trim() === '')) {
return [];
}
// Convert single string to array if needed
const cookieArray = Array.isArray(cookies) ? cookies : [cookies];
return cookieArray.map((cookieStr) => {
const parts = cookieStr.split(';').map((p) => p.trim());
// First part is always the cookie itself: name=value
const [nameValue] = parts;
const [name, ...valParts] = nameValue.split('=');
const value = valParts.join('=');
return {
key: name.trim(),
value: value.trim(),
};
});
};