feat(zookeeper): add UTF-8 value preview

Closes #6897
This commit is contained in:
t8y2 committed 2026-08-22 07:21:26 +00:00
1 parent b2cf487734
commit fe269a28db
14 files changed
+209 -6

No files matched your search

+24 -1
View File
@@ -1,8 +1,31 @@
import { describe, expect, it } from "vitest";
import { formatZooKeeperMetadataRows, formatZooKeeperSummaryBadges, prettyPrintJsonText } from "@/lib/kv/kvValueDisplay";
import { decodeBase64Utf8Preview, formatZooKeeperMetadataRows, formatZooKeeperSummaryBadges, prettyPrintJsonText } from "@/lib/kv/kvValueDisplay";
import type { KvKeyMetadata } from "@/lib/backend/api";
describe("kv value display helpers", () => {
it("decodes a valid Base64 value as a lossless UTF-8 preview", () => {
expect(decodeBase64Utf8Preview("5L2g5aW9")).toEqual({
ok: true,
value: "你好",
lossy: false,
});
});
it("marks replacement decoding of invalid UTF-8 bytes as lossy", () => {
expect(decodeBase64Utf8Preview("ZoBv")).toEqual({
ok: true,
value: "f�o",
lossy: true,
});
});
it("rejects malformed Base64 without throwing", () => {
expect(decodeBase64Utf8Preview("not base64!")).toEqual({
ok: false,
error: "invalid_base64",
});
});
it("pretty prints valid JSON text", () => {
expect(prettyPrintJsonText('{"name":"张三","roles":["admin","reader"]}')).toEqual({
ok: true,
+29
View File
@@ -8,6 +8,8 @@ export interface PrettyPrintJsonResult {
error?: "invalid_json";
}
export type Base64Utf8PreviewResult = { ok: true; value: string; lossy: boolean } | { ok: false; error: "invalid_base64" };
export interface DisplayItem {
label: string;
value: string;
@@ -20,6 +22,33 @@ export interface ZooKeeperSummaryLabels {
size?: string;
}
const strictBase64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
export function decodeBase64Utf8Preview(value: string): Base64Utf8PreviewResult {
const normalized = value.replace(/\s+/g, "");
if (!strictBase64Pattern.test(normalized)) return { ok: false, error: "invalid_base64" };
try {
const binary = atob(normalized);
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
try {
return {
ok: true,
value: new TextDecoder("utf-8", { fatal: true }).decode(bytes),
lossy: false,
};
} catch {
return {
ok: true,
value: new TextDecoder("utf-8").decode(bytes),
lossy: true,
};
}
} catch {
return { ok: false, error: "invalid_base64" };
}
}
export function prettyPrintJsonText(text: string): PrettyPrintJsonResult {
try {
return { ok: true, value: safeJsonFormat(text, 2) };