返回 CodeWhale
json.ts
根目录 / crates / tui / extension-host / src / json.ts
1 /**
2 * A value that survives `JSON.stringify` unchanged and is accepted on the wire:
3 * `null`, booleans, strings, finite numbers, dense arrays, and plain objects
4 * whose own keys are enumerable string data properties. Holes, extra array
5 * properties, accessors and symbol keys would serialize to something other
6 * than what was checked (a hole becomes `null`, a getter can answer twice), so
7 * they are refused rather than passed to Rust as a different value.
8 */
9 import type { Json } from './protocol.ts'
10
11 export function isJson(value: unknown, depth = 0): value is Json {
12 if (depth > 64) return false
13 if (value === null) return true
14 switch (typeof value) {
15 case 'boolean':
16 case 'string':
17 return true
18 case 'number':
19 return Number.isFinite(value)
20 case 'object': {
21 const array = Array.isArray(value)
22 if (!array && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return false
23 const keys = Reflect.ownKeys(value as object)
24 if (array && keys.length !== (value as unknown[]).length + 1) return false
25 for (const key of keys) {
26 if (array && key === 'length') continue
27 if (typeof key !== 'string') return false
28 if (array && (!/^(0|[1-9]\d*)$/u.test(key) || Number(key) >= (value as unknown[]).length)) return false
29 const descriptor = Object.getOwnPropertyDescriptor(value, key)!
30 if (!descriptor.enumerable || !('value' in descriptor) || !isJson(descriptor.value, depth + 1)) return false
31 }
32 return true
33 }
34 default:
35 return false
36 }
37 }
38
38 lines TYPESCRIPT