-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
_inspect.ts
58 lines (53 loc) · 1.69 KB
/
_inspect.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const defaultThreshold = 20;
export type InspectOptions = {
// The maximum number of characters of a single attribute
threshold?: number;
};
/**
* Inspect a value
*/
export function inspect(value: unknown, options: InspectOptions = {}): string {
if (value === null) {
return "null";
} else if (Array.isArray(value)) {
return inspectArray(value, options);
}
switch (typeof value) {
case "string":
return JSON.stringify(value);
case "bigint":
return `${value}n`;
case "object":
if (value.constructor?.name !== "Object") {
return value.constructor?.name;
}
return inspectRecord(value as Record<PropertyKey, unknown>, options);
case "function":
return value.name || "(anonymous)";
}
return value?.toString() ?? "undefined";
}
function inspectArray(value: unknown[], options: InspectOptions): string {
const { threshold = defaultThreshold } = options;
const vs = value.map((v) => inspect(v, options));
const s = vs.join(", ");
if (s.length <= threshold) return `[${s}]`;
const m = vs.join(",\n");
return `[\n${indent(2, m)}\n]`;
}
function inspectRecord(
value: Record<PropertyKey, unknown>,
options: InspectOptions,
): string {
const { threshold = defaultThreshold } = options;
const vs = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)]
.map((k) => `${k.toString()}: ${inspect(value[k], options)}`);
const s = vs.join(", ");
if (s.length <= threshold) return `{${s}}`;
const m = vs.join(",\n");
return `{\n${indent(2, m)}\n}`;
}
function indent(level: number, text: string): string {
const prefix = " ".repeat(level);
return text.split("\n").map((line) => `${prefix}${line}`).join("\n");
}