1import { errorTag } from "@t3tools/shared/observability";
2
3export function structuralProtocolMethod(value: string): string {
4 return value.length <= 128 && /^[A-Za-z][A-Za-z0-9._:/-]*$/.test(value) ? value : "unknown";
5}
6
7/** Never log payload values: they may contain secrets, prompts, or unbounded output. */
8export function summarizeNativeProtocolPayload(
9 payload: unknown,
10): Readonly<Record<string, unknown>> {
11 if (payload === null) return { valueType: "null" };
12 if (typeof payload === "string") {
13 return { valueType: "string", byteLength: new TextEncoder().encode(payload).byteLength };
14 }
15 if (payload instanceof Uint8Array) {
16 return { valueType: "bytes", byteLength: payload.byteLength };
17 }
18 if (Array.isArray(payload)) {
19 return { valueType: "array", itemCount: payload.length };
20 }
21 if (typeof payload !== "object") {
22 return { valueType: typeof payload };
23 }
24
25 try {
26 const record = payload as Record<string, unknown>;
27 return {
28 valueType: "object",
29 fieldCount: Object.keys(record).length,
30 ...(typeof record._tag === "string" ? { messageTag: errorTag(record) } : {}),
31 ...(typeof record.tag === "string" ? { method: structuralProtocolMethod(record.tag) } : {}),
32 };
33 } catch {
34 return { valueType: "object" };
35 }
36}