/home/techb158/cosmic-risk.abdallabala.com/src/integrations/pm-clients
Edit: /home/techb158/cosmic-risk.abdallabala.com/src/integrations/pm-clients/http-client.js (2418B)
function ensureFetch(fetchImpl) {
const resolved = fetchImpl || global.fetch;
if (!resolved) {
throw new Error("Global fetch is not available. Use Node.js 20+ or inject a fetch implementation.");
}
return resolved;
}
async function fetchJson(url, options = {}, fetchImpl) {
const fetchFn = ensureFetch(fetchImpl);
const response = await fetchFn(url, options);
const text = await response.text();
let body = null;
try {
body = text ? JSON.parse(text) : null;
} catch (_error) {
body = { raw: text };
}
if (!response.ok) {
const message = body && (body.message || body.error || body.error_description) || text || response.statusText;
const error = new Error(`HTTP ${response.status}: ${message}`);
error.status = response.status;
error.body = body;
throw error;
}
return body;
}
function encodeQuery(params) {
const search = new URLSearchParams();
Object.entries(params || {}).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== "") {
search.set(key, String(value));
}
});
return search.toString();
}
function buildRiskDescription(risk, mitigations = []) {
const mitigationLines = mitigations.length
? mitigations.map(item => `- ${item.title || item.id} (${item.status || "Unknown"}, ${item.progressPercent || 0}% progress, ${item.effectivenessPercent || 0}% effectiveness)`).join("\n")
: "- No mitigation action recorded yet";
return [
`COSMIC AI-Risk: ${risk.title}`,
`Description: ${risk.description || "Not provided"}`,
`Dimension: ${risk.dimension || "Not specified"}`,
`Domain: ${risk.domain || "Not specified"}`,
`Lifecycle phase: ${risk.lifecyclePhase || "Not specified"}`,
`Probability: ${risk.probability}`,
`Impact: ${risk.impact}`,
`Detectability: ${risk.detectability}`,
`Status: ${risk.status}`,
`Approval: ${risk.approvalStatus || "PENDING"}`,
`Evidence: ${risk.evidenceSummary || "No evidence summary"}`,
"",
"Mitigations:",
mitigationLines,
"",
"Generated by COSMIC AI-Risk Dashboard."
].join("\n");
}
function jiraDoc(text) {
return {
type: "doc",
version: 1,
content: String(text).split("\n").map(line => ({
type: "paragraph",
content: line ? [{ type: "text", text: line }] : []
}))
};
}
module.exports = {
fetchJson,
encodeQuery,
buildRiskDescription,
jiraDoc
};