forked from leezng/vue-json-pretty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
123 lines (117 loc) · 3.23 KB
/
index.js
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
export function getDataType(value) {
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
// type enum: content | objectStart | objectEnd | objectCollapsed | arrayStart | arrayEnd | arrayCollapsed
export function jsonFlatten(
data,
path = 'root',
level = 0,
{ key, index, type = 'content', showComma = false, length = 1 } = {},
) {
const dataType = getDataType(data);
if (dataType === 'array') {
const inner = arrFlat(
data.map((item, idx, arr) =>
jsonFlatten(item, `${path}[${idx}]`, level + 1, {
index: idx,
showComma: idx !== arr.length - 1,
length,
type,
}),
),
);
return [
jsonFlatten('[', path, level, { key, length: data.length, type: 'arrayStart' })[0],
].concat(
inner,
jsonFlatten(']', path, level, { showComma, length: data.length, type: 'arrayEnd' })[0],
);
} else if (dataType === 'object') {
const keys = Object.keys(data);
const inner = arrFlat(
keys.map((objKey, idx, arr) =>
jsonFlatten(
data[objKey],
/^[a-zA-Z_]\w*$/.test(objKey) ? `${path}.${objKey}` : `${path}["${objKey}"]`,
level + 1,
{
key: objKey,
showComma: idx !== arr.length - 1,
length,
type,
},
),
),
);
return [
jsonFlatten('{', path, level, { key, index, length: keys.length, type: 'objectStart' })[0],
].concat(
inner,
jsonFlatten('}', path, level, { showComma, length: keys.length, type: 'objectEnd' })[0],
);
}
return [
{
content: data,
level,
key,
index,
path,
showComma,
length,
type,
},
];
}
export function arrFlat(arr) {
if (typeof Array.prototype.flat === 'function') {
return arr.flat();
}
const stack = [...arr];
const result = [];
while (stack.length) {
const first = stack.shift();
if (Array.isArray(first)) {
stack.unshift(...first);
} else {
result.push(first);
}
}
return result;
}
export function cloneDeep(source, hash = new WeakMap()) {
if (source === null || source === undefined) return source;
if (source instanceof Date) return new Date(source);
if (source instanceof RegExp) return new RegExp(source);
if (typeof source !== 'object') return source;
if (hash.get(source)) return hash.get(source);
if (Array.isArray(source)) {
const output = source.map((item) => cloneDeep(item, hash));
hash.set(source, output);
return output;
}
const output = {};
for (const key in source) {
output[key] = cloneDeep(source[key], hash);
}
hash.set(source, output);
return output;
}
export function stringToAutoType(source) {
let value;
if (source === 'null') value = null;
else if (source === 'undefined') value = undefined;
else if (source === 'true') value = true;
else if (source === 'false') value = false;
else if (
source[0] + source[source.length - 1] === '""' ||
source[0] + source[source.length - 1] === "''"
) {
value = source.slice(1, -1);
} else if ((typeof Number(source) === 'number' && !isNaN(Number(source))) || source === 'NaN') {
value = Number(source);
} else {
value = source;
}
return value;
}