mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-01 03:09:37 +08:00
- 新增 JMX/Endpoint/Agent 三种 JVM 连接模式与配置归一化链路 - 支持资源浏览、变更预览、写入应用、审计记录与只读约束 - 接入 AI 结构化写入计划与诊断计划回填能力 - 新增 Agent Bridge、Arthas Tunnel、JMX Helper 诊断传输实现 - 增加诊断控制台、命令模板、输出历史与自动补全交互 - 补齐前后端契约、运行夹具与 JVM 相关回归测试
239 lines
5.7 KiB
TypeScript
239 lines
5.7 KiB
TypeScript
import type { JVMActionDefinition } from "../types";
|
||
|
||
type JVMActionDisplay = {
|
||
action: string;
|
||
label: string;
|
||
description?: string;
|
||
};
|
||
|
||
const ACTION_FALLBACK_META: Record<
|
||
string,
|
||
{ label: string; description?: string }
|
||
> = {
|
||
set: {
|
||
label: "设置属性",
|
||
description: "更新当前资源暴露的可写属性值。",
|
||
},
|
||
invoke: {
|
||
label: "调用操作",
|
||
description: "调用当前资源暴露的管理操作。",
|
||
},
|
||
put: {
|
||
label: "写入资源",
|
||
description: "将 payload 内容写入当前 JVM 资源。",
|
||
},
|
||
clear: {
|
||
label: "清空资源",
|
||
description: "清空当前 JVM 资源里的数据或状态。",
|
||
},
|
||
evict: {
|
||
label: "驱逐缓存",
|
||
description: "将目标缓存项从当前 JVM 运行时中驱逐。",
|
||
},
|
||
remove: {
|
||
label: "删除条目",
|
||
description: "删除当前资源中的指定条目。",
|
||
},
|
||
delete: {
|
||
label: "删除资源",
|
||
description: "删除或注销当前资源。",
|
||
},
|
||
refresh: {
|
||
label: "刷新资源",
|
||
description: "刷新当前资源的运行时状态。",
|
||
},
|
||
reload: {
|
||
label: "重新加载",
|
||
description: "重新加载当前资源或其配置。",
|
||
},
|
||
reset: {
|
||
label: "重置状态",
|
||
description: "将当前资源恢复到初始或默认状态。",
|
||
},
|
||
};
|
||
|
||
const normalizeText = (value: unknown): string => String(value || "").trim();
|
||
|
||
const looksLikeStructuredJSONText = (value: string): boolean => {
|
||
const trimmed = normalizeText(value);
|
||
if (!trimmed) {
|
||
return false;
|
||
}
|
||
if (
|
||
!(
|
||
(trimmed.startsWith("{") && trimmed.endsWith("}")) ||
|
||
(trimmed.startsWith("[") && trimmed.endsWith("]"))
|
||
)
|
||
) {
|
||
return false;
|
||
}
|
||
try {
|
||
JSON.parse(trimmed);
|
||
return true;
|
||
} catch {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
export const resolveJVMActionDisplay = (
|
||
value?: Partial<JVMActionDefinition> | string | null,
|
||
): JVMActionDisplay => {
|
||
const action = normalizeText(
|
||
typeof value === "string" ? value : value?.action,
|
||
);
|
||
const fallback = ACTION_FALLBACK_META[action.toLowerCase()] || null;
|
||
const label =
|
||
normalizeText(typeof value === "string" ? "" : value?.label) ||
|
||
fallback?.label ||
|
||
action ||
|
||
"未命名动作";
|
||
const description =
|
||
normalizeText(typeof value === "string" ? "" : value?.description) ||
|
||
fallback?.description ||
|
||
"";
|
||
|
||
return {
|
||
action,
|
||
label,
|
||
description: description || undefined,
|
||
};
|
||
};
|
||
|
||
export const formatJVMActionDisplayText = (
|
||
value?: Partial<JVMActionDefinition> | string | null,
|
||
): string => {
|
||
const resolved = resolveJVMActionDisplay(value);
|
||
if (!resolved.action || resolved.label === resolved.action) {
|
||
return resolved.label;
|
||
}
|
||
return `${resolved.label}(${resolved.action})`;
|
||
};
|
||
|
||
export const formatJVMActionSummary = (
|
||
actions?: JVMActionDefinition[] | null,
|
||
): string => {
|
||
if (!Array.isArray(actions) || actions.length === 0) {
|
||
return "-";
|
||
}
|
||
return actions
|
||
.map((item) => formatJVMActionDisplayText(item))
|
||
.filter((item) => item !== "")
|
||
.join(", ");
|
||
};
|
||
|
||
export const formatJVMRiskLevelText = (value?: string | null): string => {
|
||
const normalized = normalizeText(value).toLowerCase();
|
||
if (normalized === "low") {
|
||
return "低";
|
||
}
|
||
if (normalized === "medium") {
|
||
return "中";
|
||
}
|
||
if (normalized === "high") {
|
||
return "高";
|
||
}
|
||
return normalizeText(value) || "未知";
|
||
};
|
||
|
||
export const resolveJVMAuditResultColor = (value?: string | null): string => {
|
||
const normalized = normalizeText(value).toLowerCase();
|
||
if (
|
||
normalized === "applied" ||
|
||
normalized.includes("success") ||
|
||
normalized.includes("ok") ||
|
||
normalized.includes("done")
|
||
) {
|
||
return "green";
|
||
}
|
||
if (normalized.includes("warn")) {
|
||
return "gold";
|
||
}
|
||
if (
|
||
normalized.includes("block") ||
|
||
normalized.includes("deny") ||
|
||
normalized.includes("forbid") ||
|
||
normalized.includes("fail") ||
|
||
normalized.includes("error")
|
||
) {
|
||
return "red";
|
||
}
|
||
return "default";
|
||
};
|
||
|
||
export const formatJVMAuditResultLabel = (value?: string | null): string => {
|
||
const normalized = normalizeText(value).toLowerCase();
|
||
if (!normalized) {
|
||
return "未知";
|
||
}
|
||
if (normalized === "applied") {
|
||
return "已执行";
|
||
}
|
||
if (
|
||
normalized.includes("success") ||
|
||
normalized.includes("ok") ||
|
||
normalized.includes("done")
|
||
) {
|
||
return "成功";
|
||
}
|
||
if (normalized.includes("warn")) {
|
||
return "警告";
|
||
}
|
||
if (
|
||
normalized.includes("block") ||
|
||
normalized.includes("deny") ||
|
||
normalized.includes("forbid")
|
||
) {
|
||
return "已阻断";
|
||
}
|
||
if (normalized.includes("fail") || normalized.includes("error")) {
|
||
return "失败";
|
||
}
|
||
return normalizeText(value);
|
||
};
|
||
|
||
export const resolveJVMValueEditorLanguage = (
|
||
format: string,
|
||
value: unknown,
|
||
): string => {
|
||
const normalizedFormat = normalizeText(format).toLowerCase();
|
||
if (
|
||
["json", "array", "object", "number", "boolean", "null"].includes(
|
||
normalizedFormat,
|
||
)
|
||
) {
|
||
return "json";
|
||
}
|
||
if (normalizedFormat === "sql") {
|
||
return "sql";
|
||
}
|
||
if (normalizedFormat === "xml") {
|
||
return "xml";
|
||
}
|
||
if (normalizedFormat === "yaml" || normalizedFormat === "yml") {
|
||
return "yaml";
|
||
}
|
||
if (typeof value === "string") {
|
||
return looksLikeStructuredJSONText(value) ? "json" : "plaintext";
|
||
}
|
||
if (
|
||
value === null ||
|
||
typeof value === "number" ||
|
||
typeof value === "boolean" ||
|
||
Array.isArray(value)
|
||
) {
|
||
return "json";
|
||
}
|
||
if (value && typeof value === "object") {
|
||
return "json";
|
||
}
|
||
return "plaintext";
|
||
};
|
||
|
||
export const estimateJVMResourceEditorHeight = (value: unknown): number => {
|
||
const text = String(value ?? "");
|
||
const lineCount = Math.max(1, text.split(/\r?\n/).length);
|
||
return Math.min(420, Math.max(180, lineCount * 22 + 24));
|
||
};
|
||
|
||
export type { JVMActionDisplay };
|