import { escapeHTML } from "./chunk-A4OOMLXK.js"; import { apiFetchJson } from "./chunk-PLQL6WIO.js"; // frontend/js/pages/logs/logList.js var STATIC_ERROR_MAP = { "API_KEY_INVALID": { type: "\u5BC6\u94A5\u65E0\u6548", style: "red" }, "INVALID_ARGUMENT": { type: "\u53C2\u6570\u65E0\u6548", style: "red" }, "PERMISSION_DENIED": { type: "\u6743\u9650\u4E0D\u8DB3", style: "red" }, "NOT_FOUND": { type: "\u8D44\u6E90\u672A\u627E\u5230", style: "gray" }, "RESOURCE_EXHAUSTED": { type: "\u8D44\u6E90\u8017\u5C3D", style: "orange" }, "QUOTA_EXCEEDED": { type: "\u914D\u989D\u8017\u5C3D", style: "orange" }, "DEADLINE_EXCEEDED": { type: "\u8BF7\u6C42\u8D85\u65F6", style: "yellow" }, "CANCELLED": { type: "\u8BF7\u6C42\u5DF2\u53D6\u6D88", style: "gray" }, "INTERNAL": { type: "Google\u5185\u90E8\u9519\u8BEF", style: "yellow" }, "UNAVAILABLE": { type: "\u670D\u52A1\u4E0D\u53EF\u7528", style: "yellow" } }; var STATUS_CODE_MAP = { 400: { type: "\u9519\u8BEF\u8BF7\u6C42", style: "red" }, 401: { type: "\u8BA4\u8BC1\u5931\u8D25", style: "red" }, 403: { type: "\u7981\u6B62\u8BBF\u95EE", style: "red" }, 404: { type: "\u8D44\u6E90\u672A\u627E\u5230", style: "gray" }, 413: { type: "\u8BF7\u6C42\u4F53\u8FC7\u5927", style: "orange" }, 429: { type: "\u8BF7\u6C42\u9891\u7387\u8FC7\u9AD8", style: "orange" }, 500: { type: "\u5185\u90E8\u670D\u52A1\u9519\u8BEF", style: "yellow" }, 503: { type: "\u670D\u52A1\u4E0D\u53EF\u7528", style: "yellow" } }; var SPECIAL_CASE_MAP = [ { code: 400, keyword: "api key not found", type: "\u65E0\u6548\u5BC6\u94A5", style: "red" }, { code: 404, keyword: "call listmodels", type: "\u6A21\u578B\u914D\u7F6E\u9519\u8BEF", style: "orange" } ]; var styleToClass = (style) => { switch (style) { case "red": return "bg-red-500/10 text-red-600"; case "orange": return "bg-orange-500/10 text-orange-600"; case "yellow": return "bg-yellow-500/10 text-yellow-600"; case "gray": return "bg-zinc-500/10 text-zinc-600"; default: return "bg-destructive/10 text-destructive"; } }; var errorCodeRegex = /(\d+)$/; var LogList = class { constructor(container, dataStore2) { this.container = container; this.dataStore = dataStore2; if (!this.container) console.error("LogList: container element (tbody) not found."); } renderLoading() { if (!this.container) return; this.container.innerHTML = ` \u52A0\u8F7D\u65E5\u5FD7\u4E2D...`; } render(logs, pagination) { if (!this.container) return; if (!logs || logs.length === 0) { this.container.innerHTML = `\u6CA1\u6709\u627E\u5230\u76F8\u5173\u7684\u65E5\u5FD7\u8BB0\u5F55\u3002`; return; } const { page, page_size } = pagination; const startIndex = (page - 1) * page_size; const logsHtml = logs.map((log, index) => this.createLogRowHtml(log, startIndex + index + 1)).join(""); this.container.innerHTML = logsHtml; } _interpretError(log) { if (log.IsSuccess) { return { type: "N/A", statusCodeHtml: `\u6210\u529F` }; } const codeMatch = log.ErrorCode ? log.ErrorCode.match(errorCodeRegex) : null; if (codeMatch && codeMatch[1] && log.ErrorMessage) { const code = parseInt(codeMatch[1], 10); const lowerCaseMsg = log.ErrorMessage.toLowerCase(); for (const rule of SPECIAL_CASE_MAP) { if (code === rule.code && lowerCaseMsg.includes(rule.keyword)) { return { type: rule.type, statusCodeHtml: `${code}` }; } } } if (log.ErrorCode && STATIC_ERROR_MAP[log.ErrorCode]) { const mapping = STATIC_ERROR_MAP[log.ErrorCode]; return { type: mapping.type, statusCodeHtml: `${log.ErrorCode}` }; } if (codeMatch && codeMatch[1]) { const code = parseInt(codeMatch[1], 10); let mapping = STATUS_CODE_MAP[code]; if (!mapping && code >= 500 && code < 600) { mapping = STATUS_CODE_MAP[500]; } if (mapping) { return { type: mapping.type, statusCodeHtml: `${code}` }; } } if (!log.ErrorCode && !log.ErrorMessage) { return { type: "\u672A\u77E5", statusCodeHtml: `N/A` }; } return { type: "\u672A\u77E5\u9519\u8BEF", statusCodeHtml: `\u5931\u8D25` }; } _formatModelName(modelName) { const styleClass = ""; return `
${modelName}
`; } createLogRowHtml(log, index) { const group = this.dataStore.groups.get(log.GroupID); const groupName = group ? group.display_name : log.GroupID ? `Group #${log.GroupID}` : "N/A"; const key = this.dataStore.keys.get(log.KeyID); let apiKeyDisplay; if (key && key.APIKey && key.APIKey.length >= 8) { const masked = `${key.APIKey.substring(0, 4)}......${key.APIKey.substring(key.APIKey.length - 4)}`; apiKeyDisplay = escapeHTML(masked); } else { apiKeyDisplay = log.KeyID ? `Key #${log.KeyID}` : "N/A"; } const errorInfo = this._interpretError(log); const modelNameFormatted = this._formatModelName(log.ModelName); const errorMessageAttr = log.ErrorMessage ? `data-error-message="${escape(log.ErrorMessage)}"` : ""; const requestTime = new Date(log.RequestTime).toLocaleString(); return ` ${index} ${apiKeyDisplay} ${groupName} ${errorInfo.type} ${errorInfo.statusCodeHtml} ${modelNameFormatted} ${requestTime} `; } }; var logList_default = LogList; // frontend/js/pages/logs/index.js var dataStore = { groups: /* @__PURE__ */ new Map(), keys: /* @__PURE__ */ new Map() }; var LogsPage = class { constructor() { this.state = { logs: [], pagination: { page: 1, pages: 1, total: 0, page_size: 20 }, isLoading: true, filters: { page: 1, page_size: 20 } }; this.elements = { tableBody: document.getElementById("logs-table-body") }; this.initialized = !!this.elements.tableBody; if (this.initialized) { this.logList = new logList_default(this.elements.tableBody, dataStore); } } async init() { if (!this.initialized) return; this.initEventListeners(); await this.loadGroupsOnce(); await this.loadAndRenderLogs(); } initEventListeners() { } async loadGroupsOnce() { if (dataStore.groups.size > 0) return; try { const { success, data } = await apiFetchJson("/admin/keygroups"); if (success && Array.isArray(data)) { data.forEach((group) => dataStore.groups.set(group.id, group)); } } catch (error) { console.error("Failed to load key groups:", error); } } async loadAndRenderLogs() { this.state.isLoading = true; this.logList.renderLoading(); try { const query = new URLSearchParams(this.state.filters); const { success, data } = await apiFetchJson(`/admin/logs?${query.toString()}`); if (success && typeof data === "object") { const { items, total, page, page_size } = data; this.state.logs = items; this.state.pagination = { page, page_size, total, pages: Math.ceil(total / page_size) }; await this.enrichLogsWithKeyNames(items); this.logList.render(this.state.logs, this.state.pagination); } else { this.logList.render([], this.state.pagination); } } catch (error) { console.error("Failed to load logs:", error); this.logList.render([], this.state.pagination); } finally { this.state.isLoading = false; } } async enrichLogsWithKeyNames(logs) { const missingKeyIds = [...new Set( logs.filter((log) => log.KeyID && !dataStore.keys.has(log.KeyID)).map((log) => log.KeyID) )]; if (missingKeyIds.length === 0) return; try { const idsQuery = missingKeyIds.join(","); const { success, data } = await apiFetchJson(`/admin/apikeys?ids=${idsQuery}`); if (success && Array.isArray(data)) { data.forEach((key) => dataStore.keys.set(key.ID, key)); } } catch (error) { console.error(`Failed to fetch key details:`, error); } } }; function logs_default() { const page = new LogsPage(); page.init(); } export { logs_default as default };