General source code refactoring
This commit is contained in:
198
src/features/debug/content-log.js
Normal file
198
src/features/debug/content-log.js
Normal file
@@ -0,0 +1,198 @@
|
||||
function createDebugContentLog({
|
||||
DEBUG_BODY_LIMIT,
|
||||
debugState,
|
||||
renderDebugPanel
|
||||
}) {
|
||||
function logRequestStart(details) {
|
||||
const entry = {
|
||||
id: debugState.requestLog.length + 1,
|
||||
name: details.name,
|
||||
method: details.method,
|
||||
url: details.url,
|
||||
headers: details.headers,
|
||||
status: "pending",
|
||||
startedAt: new Date(),
|
||||
completedAt: null,
|
||||
durationMs: null,
|
||||
httpStatus: null,
|
||||
statusText: "",
|
||||
requestHeaders: details.headers,
|
||||
requestBody: details.body || "",
|
||||
metadata: details.metadata || {},
|
||||
responseHeaders: {},
|
||||
responseBody: "",
|
||||
responseBodyTruncated: false,
|
||||
error: ""
|
||||
};
|
||||
|
||||
debugState.requestLog.push(entry);
|
||||
renderDebugPanel();
|
||||
return entry;
|
||||
}
|
||||
|
||||
function logRequestSuccess(entry, response, responseBody) {
|
||||
entry.status = response.ok ? "success" : "failed";
|
||||
entry.completedAt = new Date();
|
||||
entry.durationMs = entry.completedAt.getTime() - entry.startedAt.getTime();
|
||||
entry.httpStatus = response.status;
|
||||
entry.statusText = response.statusText || "";
|
||||
entry.responseHeaders = headersToObject(response.headers);
|
||||
entry.responseBody = responseBody.value;
|
||||
entry.responseBodyTruncated = responseBody.truncated;
|
||||
renderDebugPanel();
|
||||
}
|
||||
|
||||
function logRequestFailure(entry, errorMessage) {
|
||||
entry.status = "failed";
|
||||
entry.completedAt = new Date();
|
||||
entry.durationMs = entry.completedAt.getTime() - entry.startedAt.getTime();
|
||||
entry.error = errorMessage;
|
||||
renderDebugPanel();
|
||||
}
|
||||
|
||||
function appendBackgroundRequestLog(entries) {
|
||||
if (!Array.isArray(entries) || entries.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
entries.forEach((entry) => {
|
||||
debugState.requestLog.push({
|
||||
id: debugState.requestLog.length + 1,
|
||||
name: entry.name || "backgroundRequest",
|
||||
method: entry.method || "GET",
|
||||
url: entry.url || "",
|
||||
headers: entry.requestHeaders || {},
|
||||
status: entry.status || "failed",
|
||||
startedAt: new Date(entry.startedAt),
|
||||
completedAt: entry.completedAt ? new Date(entry.completedAt) : null,
|
||||
durationMs: entry.durationMs,
|
||||
httpStatus: entry.httpStatus,
|
||||
statusText: entry.statusText || "",
|
||||
requestHeaders: entry.requestHeaders || {},
|
||||
requestBody: entry.requestBody || "",
|
||||
metadata: entry.metadata || { executionContext: "background" },
|
||||
responseHeaders: entry.responseHeaders || {},
|
||||
responseBody: entry.responseBody || "",
|
||||
responseBodyTruncated: Boolean(entry.responseBodyTruncated),
|
||||
error: entry.error || ""
|
||||
});
|
||||
});
|
||||
renderDebugPanel();
|
||||
}
|
||||
|
||||
async function readResponseBodyForDebug(response) {
|
||||
try {
|
||||
const text = await response.clone().text();
|
||||
return createDebugBody(text);
|
||||
} catch (error) {
|
||||
return {
|
||||
value: `Unable to read response body: ${error.message || "unknown error"}`,
|
||||
truncated: false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function createDebugBody(text) {
|
||||
if (text.length > DEBUG_BODY_LIMIT) {
|
||||
return {
|
||||
value: `${text.slice(0, DEBUG_BODY_LIMIT)}\n... truncated ${text.length - DEBUG_BODY_LIMIT} characters`,
|
||||
truncated: true
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
value: text || "(empty response body)",
|
||||
truncated: false
|
||||
};
|
||||
}
|
||||
|
||||
function headersToObject(headers) {
|
||||
const headerMap = {};
|
||||
|
||||
headers.forEach((value, key) => {
|
||||
headerMap[key] = value;
|
||||
});
|
||||
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
function formatHeaderBlock(headers) {
|
||||
const entries = Object.entries(headers);
|
||||
|
||||
if (entries.length === 0) {
|
||||
return "(none)";
|
||||
}
|
||||
|
||||
return entries
|
||||
.map(([key, value]) => `${key}: ${debugState.debugSecretsVisible || !isSensitiveDebugKey(key)
|
||||
? value
|
||||
: formatHiddenDebugValue(value)}`)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function formatDebugBody(body) {
|
||||
const text = body || "(none)";
|
||||
|
||||
if (debugState.debugSecretsVisible) {
|
||||
return text;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.stringify(maskSensitiveDebugValue(JSON.parse(text)), null, 2);
|
||||
} catch (error) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function maskSensitiveDebugValue(value, parentKey = "") {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => maskSensitiveDebugValue(item, parentKey));
|
||||
}
|
||||
|
||||
if (!value || typeof value !== "object") {
|
||||
return value;
|
||||
}
|
||||
|
||||
return Object.fromEntries(Object.entries(value).map(([key, child]) => {
|
||||
const isSensitive = isSensitiveDebugKey(key)
|
||||
|| (key === "value" && /uiaasHeader|uiassHeader/i.test(parentKey));
|
||||
return [key, isSensitive
|
||||
? formatHiddenDebugValue(child)
|
||||
: maskSensitiveDebugValue(child, key)];
|
||||
}));
|
||||
}
|
||||
|
||||
function isSensitiveDebugKey(key) {
|
||||
return /authorization|cookie|password|secret|(^|[_-])token($|[_-])|token$/i.test(key);
|
||||
}
|
||||
|
||||
function formatHiddenDebugValue(value) {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
return "(missing)";
|
||||
}
|
||||
|
||||
return `(present, ${String(value).length} characters)`;
|
||||
}
|
||||
|
||||
function formatMetadataBlock(metadata) {
|
||||
const entries = Object.entries(metadata);
|
||||
|
||||
if (entries.length === 0) {
|
||||
return "(none)";
|
||||
}
|
||||
|
||||
return entries
|
||||
.map(([key, value]) => `${key}: ${value || "(none)"}`)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function maskToken(token) {
|
||||
if (token.length <= 10) {
|
||||
return "(present)";
|
||||
}
|
||||
|
||||
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
||||
}
|
||||
|
||||
return { logRequestStart, logRequestSuccess, logRequestFailure, appendBackgroundRequestLog, readResponseBodyForDebug, createDebugBody, headersToObject, formatHeaderBlock, formatDebugBody, maskSensitiveDebugValue, isSensitiveDebugKey, formatHiddenDebugValue, formatMetadataBlock, maskToken };
|
||||
}
|
||||
Reference in New Issue
Block a user