mason-parser 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -11
- package/dist/index.d.mts +19 -5
- package/dist/index.d.ts +19 -5
- package/dist/index.js +765 -128
- package/dist/index.mjs +761 -128
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,227 +20,837 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
fastParseWithTrace: () => fastParseWithTrace,
|
|
23
24
|
parse: () => parse,
|
|
24
25
|
parseMSON: () => parse,
|
|
26
|
+
parseMaSON: () => parseWithTrace,
|
|
25
27
|
parsePrimitiveValue: () => parsePrimitiveValue,
|
|
28
|
+
parseValueWithMultiline: () => parseValueWithMultiline,
|
|
26
29
|
parseWithTrace: () => parseWithTrace,
|
|
27
30
|
stringify: () => stringify,
|
|
28
31
|
stringifyMSON: () => stringify,
|
|
32
|
+
stringifyMaSON: () => stringify,
|
|
29
33
|
stringifyPrimitiveValue: () => stringifyPrimitiveValue
|
|
30
34
|
});
|
|
31
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var BACKTICK_REGEX = /`+/g;
|
|
37
|
+
var DOUBLE_QUOTE_REGEX = /"/g;
|
|
38
|
+
var LANGUAGE_TAG_REGEX = /^[a-zA-Z0-9+#-]+$/;
|
|
39
|
+
var NUMBER_REGEX = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
40
|
+
function findColonIndex(line, start) {
|
|
41
|
+
const len = line.length;
|
|
42
|
+
let inDouble = false;
|
|
43
|
+
let inSingle = false;
|
|
44
|
+
let inBacktick = false;
|
|
45
|
+
for (let i = start; i < len; i++) {
|
|
46
|
+
const code = line.charCodeAt(i);
|
|
47
|
+
if (code === 92) {
|
|
48
|
+
i++;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (code === 34 && !inSingle && !inBacktick) {
|
|
52
|
+
inDouble = !inDouble;
|
|
53
|
+
} else if (code === 39 && !inDouble && !inBacktick) {
|
|
54
|
+
inSingle = !inSingle;
|
|
55
|
+
} else if (code === 96 && !inDouble && !inSingle) {
|
|
56
|
+
inBacktick = !inBacktick;
|
|
57
|
+
} else if (code === 58 && !inDouble && !inSingle && !inBacktick) {
|
|
58
|
+
return i;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return -1;
|
|
62
|
+
}
|
|
32
63
|
function parsePrimitiveValue(val) {
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
64
|
+
const len = val.length;
|
|
65
|
+
if (len === 0) return val;
|
|
66
|
+
const first = val.charCodeAt(0);
|
|
67
|
+
const last = val.charCodeAt(len - 1);
|
|
68
|
+
if (len >= 2) {
|
|
69
|
+
if (first === 34 && last === 34 || first === 39 && last === 39 || first === 96 && last === 96) {
|
|
70
|
+
const content = val.slice(1, -1);
|
|
71
|
+
if (content.indexOf("\\") !== -1) {
|
|
72
|
+
if (first === 34) {
|
|
73
|
+
return content.replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
74
|
+
} else if (first === 39) {
|
|
75
|
+
return content.replace(/\\'/g, "'").replace(/\\\\/g, "\\");
|
|
76
|
+
} else if (first === 96) {
|
|
77
|
+
return content.replace(/\\`/g, "`").replace(/\\\\/g, "\\");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return content;
|
|
81
|
+
}
|
|
36
82
|
}
|
|
37
|
-
if (
|
|
38
|
-
if (
|
|
39
|
-
if (
|
|
40
|
-
if (
|
|
41
|
-
|
|
83
|
+
if (first === 116 && val === "true") return true;
|
|
84
|
+
if (first === 102 && val === "false") return false;
|
|
85
|
+
if (first === 110 && val === "null") return null;
|
|
86
|
+
if (first >= 48 && first <= 57 || first === 45 || first === 46 || first === 43) {
|
|
87
|
+
if (NUMBER_REGEX.test(val)) {
|
|
88
|
+
const num = Number(val);
|
|
89
|
+
if (!isNaN(num)) {
|
|
90
|
+
return num;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return val;
|
|
95
|
+
}
|
|
96
|
+
function parseValueWithMultiline(initialValStr, lines, currentLineIndex) {
|
|
97
|
+
const valStr = initialValStr;
|
|
98
|
+
let nextLineIndex = currentLineIndex;
|
|
99
|
+
let backtickCount = 0;
|
|
100
|
+
while (backtickCount < valStr.length && valStr.charCodeAt(backtickCount) === 96) {
|
|
101
|
+
backtickCount++;
|
|
102
|
+
}
|
|
103
|
+
if (backtickCount > 0) {
|
|
104
|
+
const termSeq = "`".repeat(backtickCount);
|
|
105
|
+
if (valStr.endsWith(termSeq) && valStr.length >= backtickCount * 2) {
|
|
106
|
+
let content = valStr.slice(backtickCount, -backtickCount);
|
|
107
|
+
if (backtickCount > 1 && content.startsWith(" ") && content.endsWith(" ") && content.trim() !== "") {
|
|
108
|
+
content = content.slice(1, -1);
|
|
109
|
+
}
|
|
110
|
+
const trimmedVal = content.trim();
|
|
111
|
+
if (trimmedVal === "true" || trimmedVal === "false" || trimmedVal === "null" || trimmedVal !== "" && !isNaN(Number(trimmedVal))) {
|
|
112
|
+
return { value: parsePrimitiveValue(trimmedVal), nextLineIndex };
|
|
113
|
+
} else {
|
|
114
|
+
return { value: content, nextLineIndex };
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
let firstLineContent = valStr.slice(backtickCount).trim();
|
|
118
|
+
if (backtickCount >= 3 && LANGUAGE_TAG_REGEX.test(firstLineContent)) {
|
|
119
|
+
firstLineContent = "";
|
|
120
|
+
}
|
|
121
|
+
let multilineContent = firstLineContent;
|
|
122
|
+
if (multilineContent) {
|
|
123
|
+
multilineContent += "\n";
|
|
124
|
+
}
|
|
125
|
+
let j = currentLineIndex + 1;
|
|
126
|
+
for (; j < lines.length; j++) {
|
|
127
|
+
const nextRawLine = lines[j];
|
|
128
|
+
let endIdx = nextRawLine.length - 1;
|
|
129
|
+
while (endIdx >= 0) {
|
|
130
|
+
const code = nextRawLine.charCodeAt(endIdx);
|
|
131
|
+
if (code === 32 || code === 9 || code === 13) {
|
|
132
|
+
endIdx--;
|
|
133
|
+
} else {
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let endsWithTerm = false;
|
|
138
|
+
if (endIdx + 1 >= backtickCount) {
|
|
139
|
+
endsWithTerm = true;
|
|
140
|
+
for (let k = 0; k < backtickCount; k++) {
|
|
141
|
+
if (nextRawLine.charCodeAt(endIdx - k) !== 96) {
|
|
142
|
+
endsWithTerm = false;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (endsWithTerm) {
|
|
148
|
+
const lastIndex = endIdx - backtickCount + 1;
|
|
149
|
+
const lineContent = nextRawLine.slice(0, lastIndex);
|
|
150
|
+
multilineContent += lineContent;
|
|
151
|
+
nextLineIndex = j;
|
|
152
|
+
break;
|
|
153
|
+
} else {
|
|
154
|
+
multilineContent += nextRawLine + "\n";
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const trimmedVal = multilineContent.trim();
|
|
158
|
+
if (trimmedVal === "true" || trimmedVal === "false" || trimmedVal === "null" || trimmedVal !== "" && !isNaN(Number(trimmedVal))) {
|
|
159
|
+
return { value: parsePrimitiveValue(trimmedVal), nextLineIndex };
|
|
160
|
+
} else {
|
|
161
|
+
let cleanStr = multilineContent;
|
|
162
|
+
if (cleanStr.startsWith("\n")) {
|
|
163
|
+
cleanStr = cleanStr.slice(1);
|
|
164
|
+
} else if (cleanStr.startsWith("\r\n")) {
|
|
165
|
+
cleanStr = cleanStr.slice(2);
|
|
166
|
+
}
|
|
167
|
+
if (cleanStr.endsWith("\n")) {
|
|
168
|
+
cleanStr = cleanStr.slice(0, -1);
|
|
169
|
+
}
|
|
170
|
+
if (cleanStr.endsWith("\r")) {
|
|
171
|
+
cleanStr = cleanStr.slice(0, -1);
|
|
172
|
+
}
|
|
173
|
+
if (cleanStr.startsWith('"') && cleanStr.endsWith('"') || cleanStr.startsWith("'") && cleanStr.endsWith("'")) {
|
|
174
|
+
cleanStr = cleanStr.slice(1, -1);
|
|
175
|
+
}
|
|
176
|
+
return { value: cleanStr, nextLineIndex };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
42
179
|
}
|
|
43
|
-
return
|
|
180
|
+
return { value: parsePrimitiveValue(valStr), nextLineIndex };
|
|
44
181
|
}
|
|
45
182
|
function stringifyPrimitiveValue(val) {
|
|
46
183
|
if (val === null) return "null";
|
|
47
184
|
if (typeof val === "boolean") return val ? "true" : "false";
|
|
48
185
|
if (typeof val === "number") return String(val);
|
|
49
186
|
const str = String(val);
|
|
50
|
-
|
|
187
|
+
if (str.includes("\n")) {
|
|
188
|
+
let maxConsecutive = 0;
|
|
189
|
+
let match;
|
|
190
|
+
BACKTICK_REGEX.lastIndex = 0;
|
|
191
|
+
while ((match = BACKTICK_REGEX.exec(str)) !== null) {
|
|
192
|
+
if (match[0].length > maxConsecutive) {
|
|
193
|
+
maxConsecutive = match[0].length;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const wrapCount = maxConsecutive + 1;
|
|
197
|
+
const wrapSeq = "`".repeat(wrapCount);
|
|
198
|
+
return `${wrapSeq}
|
|
199
|
+
${str}
|
|
200
|
+
${wrapSeq}`;
|
|
201
|
+
}
|
|
202
|
+
if (str.includes("`")) {
|
|
203
|
+
let maxConsecutive = 0;
|
|
204
|
+
let match;
|
|
205
|
+
BACKTICK_REGEX.lastIndex = 0;
|
|
206
|
+
while ((match = BACKTICK_REGEX.exec(str)) !== null) {
|
|
207
|
+
if (match[0].length > maxConsecutive) {
|
|
208
|
+
maxConsecutive = match[0].length;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const wrapCount = maxConsecutive + 1;
|
|
212
|
+
const wrapSeq = "`".repeat(wrapCount);
|
|
213
|
+
return `${wrapSeq}${str}${wrapSeq}`;
|
|
214
|
+
}
|
|
215
|
+
const needsQuotes = str.trim() !== str || str.includes(":") || str === "true" || str === "false" || str === "null" || NUMBER_REGEX.test(str) && str !== "";
|
|
51
216
|
if (needsQuotes) {
|
|
52
|
-
return `"${str.replace(
|
|
217
|
+
return `"${str.replace(DOUBLE_QUOTE_REGEX, '\\"')}"`;
|
|
53
218
|
}
|
|
54
219
|
return str;
|
|
55
220
|
}
|
|
56
|
-
function parse(text) {
|
|
57
|
-
return parseWithTrace(text).data;
|
|
221
|
+
function parse(text, options) {
|
|
222
|
+
return parseWithTrace(text, options).data;
|
|
223
|
+
}
|
|
224
|
+
function fastParseWithTrace(text) {
|
|
225
|
+
const startTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
226
|
+
const lines = text.split(/\r?\n/);
|
|
227
|
+
let root = {};
|
|
228
|
+
let rootConvertedToArray = false;
|
|
229
|
+
const stack = [];
|
|
230
|
+
for (let i = 0; i < lines.length; i++) {
|
|
231
|
+
const rawLine = lines[i];
|
|
232
|
+
const len = rawLine.length;
|
|
233
|
+
let startIdx = 0;
|
|
234
|
+
while (startIdx < len) {
|
|
235
|
+
const code = rawLine.charCodeAt(startIdx);
|
|
236
|
+
if (code === 32 || code === 9 || code === 13) {
|
|
237
|
+
startIdx++;
|
|
238
|
+
} else {
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (startIdx === len) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const firstChar = rawLine.charCodeAt(startIdx);
|
|
246
|
+
if (firstChar === 60 && rawLine.startsWith("<!--", startIdx)) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
let endIdx = len - 1;
|
|
250
|
+
while (endIdx > startIdx) {
|
|
251
|
+
const code = rawLine.charCodeAt(endIdx);
|
|
252
|
+
if (code === 32 || code === 9 || code === 13) {
|
|
253
|
+
endIdx--;
|
|
254
|
+
} else {
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const trimmedLen = endIdx - startIdx + 1;
|
|
259
|
+
if (trimmedLen === 2 && rawLine.charCodeAt(startIdx) === 91 && rawLine.charCodeAt(startIdx + 1) === 93) {
|
|
260
|
+
let isRootEmpty = false;
|
|
261
|
+
if (Array.isArray(root)) {
|
|
262
|
+
isRootEmpty = root.length === 0;
|
|
263
|
+
} else {
|
|
264
|
+
let hasKeys = false;
|
|
265
|
+
for (const _ in root) {
|
|
266
|
+
hasKeys = true;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
isRootEmpty = !hasKeys;
|
|
270
|
+
}
|
|
271
|
+
if (stack.length === 0 && !rootConvertedToArray && isRootEmpty) {
|
|
272
|
+
root = [];
|
|
273
|
+
rootConvertedToArray = true;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (firstChar === 35) {
|
|
278
|
+
let hashCount = 0;
|
|
279
|
+
while (startIdx + hashCount <= endIdx && rawLine.charCodeAt(startIdx + hashCount) === 35) {
|
|
280
|
+
hashCount++;
|
|
281
|
+
}
|
|
282
|
+
let hStart = startIdx + hashCount;
|
|
283
|
+
while (hStart <= endIdx) {
|
|
284
|
+
const code = rawLine.charCodeAt(hStart);
|
|
285
|
+
if (code === 32 || code === 9) {
|
|
286
|
+
hStart++;
|
|
287
|
+
} else {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let actualHeadingName = "";
|
|
292
|
+
let isExplicitArray = false;
|
|
293
|
+
if (hStart <= endIdx) {
|
|
294
|
+
if (endIdx - hStart >= 1 && rawLine.charCodeAt(endIdx - 1) === 91 && rawLine.charCodeAt(endIdx) === 93) {
|
|
295
|
+
isExplicitArray = true;
|
|
296
|
+
let hEnd = endIdx - 2;
|
|
297
|
+
while (hEnd >= hStart) {
|
|
298
|
+
const code = rawLine.charCodeAt(hEnd);
|
|
299
|
+
if (code === 32 || code === 9) {
|
|
300
|
+
hEnd--;
|
|
301
|
+
} else {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
actualHeadingName = hStart <= hEnd ? rawLine.slice(hStart, hEnd + 1) : "";
|
|
306
|
+
} else {
|
|
307
|
+
actualHeadingName = rawLine.slice(hStart, endIdx + 1);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
while (stack.length > 0 && stack[stack.length - 1].level >= hashCount) {
|
|
311
|
+
stack.pop();
|
|
312
|
+
}
|
|
313
|
+
let activeParent = root;
|
|
314
|
+
let activeParentItem = null;
|
|
315
|
+
if (stack.length > 0) {
|
|
316
|
+
activeParentItem = stack[stack.length - 1];
|
|
317
|
+
activeParent = activeParentItem.value;
|
|
318
|
+
}
|
|
319
|
+
if (!actualHeadingName) {
|
|
320
|
+
if (activeParentItem && activeParentItem.isExplicitArray || Array.isArray(activeParent)) {
|
|
321
|
+
actualHeadingName = "";
|
|
322
|
+
} else {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const newNode = isExplicitArray ? [] : {};
|
|
327
|
+
if (activeParentItem && activeParentItem.isExplicitArray) {
|
|
328
|
+
activeParent.push(newNode);
|
|
329
|
+
} else if (Array.isArray(activeParent)) {
|
|
330
|
+
if (actualHeadingName === "") {
|
|
331
|
+
activeParent.push(newNode);
|
|
332
|
+
} else {
|
|
333
|
+
activeParent.push({ [actualHeadingName]: newNode });
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
activeParent[actualHeadingName] = newNode;
|
|
337
|
+
}
|
|
338
|
+
stack.push({
|
|
339
|
+
level: hashCount,
|
|
340
|
+
key: actualHeadingName,
|
|
341
|
+
parent: activeParent,
|
|
342
|
+
value: newNode,
|
|
343
|
+
type: isExplicitArray ? "array" : "object",
|
|
344
|
+
isExplicitArray
|
|
345
|
+
});
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (firstChar === 42 || firstChar === 45 || firstChar === 43) {
|
|
349
|
+
let bulletValIdx = startIdx + 1;
|
|
350
|
+
while (bulletValIdx <= endIdx) {
|
|
351
|
+
const code = rawLine.charCodeAt(bulletValIdx);
|
|
352
|
+
if (code === 32 || code === 9) {
|
|
353
|
+
bulletValIdx++;
|
|
354
|
+
} else {
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const bulletValStr = bulletValIdx <= endIdx ? rawLine.slice(bulletValIdx, endIdx + 1) : "";
|
|
359
|
+
let value;
|
|
360
|
+
if (bulletValStr.charCodeAt(0) === 96) {
|
|
361
|
+
const multiline = parseValueWithMultiline(bulletValStr, lines, i);
|
|
362
|
+
value = multiline.value;
|
|
363
|
+
i = multiline.nextLineIndex;
|
|
364
|
+
} else {
|
|
365
|
+
value = parsePrimitiveValue(bulletValStr);
|
|
366
|
+
}
|
|
367
|
+
if (stack.length === 0) {
|
|
368
|
+
if (!root._items) {
|
|
369
|
+
root._items = [];
|
|
370
|
+
}
|
|
371
|
+
root._items.push(value);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const activeItem = stack[stack.length - 1];
|
|
375
|
+
if (activeItem.type !== "array") {
|
|
376
|
+
let hasKeys = false;
|
|
377
|
+
for (const k in activeItem.value) {
|
|
378
|
+
if (Object.prototype.hasOwnProperty.call(activeItem.value, k)) {
|
|
379
|
+
hasKeys = true;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!hasKeys) {
|
|
384
|
+
const parent = activeItem.parent;
|
|
385
|
+
const key = activeItem.key;
|
|
386
|
+
activeItem.type = "array";
|
|
387
|
+
activeItem.value = [];
|
|
388
|
+
if (Array.isArray(parent)) {
|
|
389
|
+
parent[parent.length - 1] = { [key]: activeItem.value };
|
|
390
|
+
} else {
|
|
391
|
+
parent[key] = activeItem.value;
|
|
392
|
+
}
|
|
393
|
+
activeItem.value.push(value);
|
|
394
|
+
} else {
|
|
395
|
+
if (!activeItem.value._items) {
|
|
396
|
+
activeItem.value._items = [];
|
|
397
|
+
}
|
|
398
|
+
activeItem.value._items.push(value);
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
activeItem.value.push(value);
|
|
402
|
+
}
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const colonIndex = findColonIndex(rawLine, startIdx);
|
|
406
|
+
if (colonIndex !== -1 && colonIndex <= endIdx) {
|
|
407
|
+
let kEnd = colonIndex - 1;
|
|
408
|
+
while (kEnd >= startIdx) {
|
|
409
|
+
const code = rawLine.charCodeAt(kEnd);
|
|
410
|
+
if (code === 32 || code === 9) {
|
|
411
|
+
kEnd--;
|
|
412
|
+
} else {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const key = startIdx <= kEnd ? rawLine.slice(startIdx, kEnd + 1) : "";
|
|
417
|
+
let vStart = colonIndex + 1;
|
|
418
|
+
while (vStart <= endIdx) {
|
|
419
|
+
const code = rawLine.charCodeAt(vStart);
|
|
420
|
+
if (code === 32 || code === 9) {
|
|
421
|
+
vStart++;
|
|
422
|
+
} else {
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const valStr = vStart <= endIdx ? rawLine.slice(vStart, endIdx + 1) : "";
|
|
427
|
+
let parsedVal;
|
|
428
|
+
if (valStr.charCodeAt(0) === 96) {
|
|
429
|
+
const multiline = parseValueWithMultiline(valStr, lines, i);
|
|
430
|
+
parsedVal = multiline.value;
|
|
431
|
+
i = multiline.nextLineIndex;
|
|
432
|
+
} else {
|
|
433
|
+
parsedVal = parsePrimitiveValue(valStr);
|
|
434
|
+
}
|
|
435
|
+
if (stack.length === 0) {
|
|
436
|
+
root[key] = parsedVal;
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
const activeItem = stack[stack.length - 1];
|
|
440
|
+
if (activeItem.type === "array") {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
activeItem.value[key] = parsedVal;
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
const duration = (typeof performance !== "undefined" ? performance.now() : Date.now()) - startTime;
|
|
448
|
+
return {
|
|
449
|
+
data: root,
|
|
450
|
+
trace: [],
|
|
451
|
+
stats: {
|
|
452
|
+
parseTimeMs: duration,
|
|
453
|
+
linesProcessed: lines.length,
|
|
454
|
+
charCount: text.length,
|
|
455
|
+
estimatedTokens: Math.ceil(text.length / 3.8),
|
|
456
|
+
jsonCharCount: 0,
|
|
457
|
+
jsonEstimatedTokens: 0,
|
|
458
|
+
tokenSavingsPercent: 0
|
|
459
|
+
}
|
|
460
|
+
};
|
|
58
461
|
}
|
|
59
|
-
function parseWithTrace(text) {
|
|
462
|
+
function parseWithTrace(text, options) {
|
|
463
|
+
if (options?.noTrace) {
|
|
464
|
+
return fastParseWithTrace(text);
|
|
465
|
+
}
|
|
60
466
|
const startTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
61
467
|
const lines = text.split(/\r?\n/);
|
|
62
468
|
const trace = [];
|
|
63
|
-
const
|
|
469
|
+
const noTrace = options?.noTrace ?? false;
|
|
470
|
+
let root = {};
|
|
471
|
+
let rootConvertedToArray = false;
|
|
64
472
|
const stack = [];
|
|
65
|
-
const getStackNames = () =>
|
|
473
|
+
const getStackNames = () => {
|
|
474
|
+
if (noTrace) return [];
|
|
475
|
+
return stack.map((s) => `${"#".repeat(s.level)} ${s.key}`);
|
|
476
|
+
};
|
|
66
477
|
for (let i = 0; i < lines.length; i++) {
|
|
67
478
|
const rawLine = lines[i];
|
|
68
|
-
const line = rawLine.trim();
|
|
69
479
|
const lineNumber = i + 1;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
480
|
+
let startIdx = 0;
|
|
481
|
+
const len = rawLine.length;
|
|
482
|
+
while (startIdx < len) {
|
|
483
|
+
const code = rawLine.charCodeAt(startIdx);
|
|
484
|
+
if (code === 32 || code === 9 || code === 13) {
|
|
485
|
+
startIdx++;
|
|
486
|
+
} else {
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (startIdx === len) {
|
|
491
|
+
if (!noTrace) {
|
|
492
|
+
trace.push({
|
|
493
|
+
lineNumber,
|
|
494
|
+
lineText: rawLine,
|
|
495
|
+
action: "Skipped empty line or comment",
|
|
496
|
+
stackDepth: stack.length,
|
|
497
|
+
currentStack: getStackNames(),
|
|
498
|
+
status: "info"
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const firstChar = rawLine.charCodeAt(startIdx);
|
|
504
|
+
if (firstChar === 60 && rawLine.startsWith("<!--", startIdx)) {
|
|
505
|
+
if (!noTrace) {
|
|
506
|
+
trace.push({
|
|
507
|
+
lineNumber,
|
|
508
|
+
lineText: rawLine,
|
|
509
|
+
action: "Skipped empty line or comment",
|
|
510
|
+
stackDepth: stack.length,
|
|
511
|
+
currentStack: getStackNames(),
|
|
512
|
+
status: "info"
|
|
513
|
+
});
|
|
514
|
+
}
|
|
79
515
|
continue;
|
|
80
516
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
517
|
+
let endIdx = len - 1;
|
|
518
|
+
while (endIdx > startIdx) {
|
|
519
|
+
const code = rawLine.charCodeAt(endIdx);
|
|
520
|
+
if (code === 32 || code === 9 || code === 13) {
|
|
521
|
+
endIdx--;
|
|
522
|
+
} else {
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
const trimmedLen = endIdx - startIdx + 1;
|
|
527
|
+
if (trimmedLen === 2 && rawLine.charCodeAt(startIdx) === 91 && rawLine.charCodeAt(startIdx + 1) === 93) {
|
|
528
|
+
let isRootEmpty = false;
|
|
529
|
+
if (Array.isArray(root)) {
|
|
530
|
+
isRootEmpty = root.length === 0;
|
|
531
|
+
} else {
|
|
532
|
+
let hasKeys = false;
|
|
533
|
+
for (const _ in root) {
|
|
534
|
+
hasKeys = true;
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
isRootEmpty = !hasKeys;
|
|
538
|
+
}
|
|
539
|
+
if (stack.length === 0 && !rootConvertedToArray && isRootEmpty) {
|
|
540
|
+
root = [];
|
|
541
|
+
rootConvertedToArray = true;
|
|
542
|
+
if (!noTrace) {
|
|
87
543
|
trace.push({
|
|
88
544
|
lineNumber,
|
|
89
545
|
lineText: rawLine,
|
|
90
|
-
action:
|
|
546
|
+
action: 'Converted root container to an Array via top-level "[]"',
|
|
91
547
|
stackDepth: stack.length,
|
|
92
548
|
currentStack: getStackNames(),
|
|
93
|
-
status: "
|
|
549
|
+
status: "success"
|
|
94
550
|
});
|
|
95
|
-
continue;
|
|
96
551
|
}
|
|
97
|
-
|
|
98
|
-
|
|
552
|
+
continue;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (firstChar === 35) {
|
|
556
|
+
let hashCount = 0;
|
|
557
|
+
while (startIdx + hashCount <= endIdx && rawLine.charCodeAt(startIdx + hashCount) === 35) {
|
|
558
|
+
hashCount++;
|
|
559
|
+
}
|
|
560
|
+
let hStart = startIdx + hashCount;
|
|
561
|
+
while (hStart <= endIdx) {
|
|
562
|
+
const code = rawLine.charCodeAt(hStart);
|
|
563
|
+
if (code === 32 || code === 9) {
|
|
564
|
+
hStart++;
|
|
565
|
+
} else {
|
|
566
|
+
break;
|
|
99
567
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
568
|
+
}
|
|
569
|
+
const headingName = hStart <= endIdx ? rawLine.slice(hStart, endIdx + 1) : "";
|
|
570
|
+
while (stack.length > 0 && stack[stack.length - 1].level >= hashCount) {
|
|
571
|
+
stack.pop();
|
|
572
|
+
}
|
|
573
|
+
let activeParent = root;
|
|
574
|
+
let activeParentItem = null;
|
|
575
|
+
if (stack.length > 0) {
|
|
576
|
+
activeParentItem = stack[stack.length - 1];
|
|
577
|
+
activeParent = activeParentItem.value;
|
|
578
|
+
}
|
|
579
|
+
let actualHeadingName = headingName;
|
|
580
|
+
let isExplicitArray = false;
|
|
581
|
+
if (headingName.endsWith("[]")) {
|
|
582
|
+
actualHeadingName = headingName.slice(0, -2).trim();
|
|
583
|
+
isExplicitArray = true;
|
|
584
|
+
}
|
|
585
|
+
if (!actualHeadingName) {
|
|
586
|
+
if (activeParentItem && activeParentItem.isExplicitArray || Array.isArray(activeParent)) {
|
|
587
|
+
actualHeadingName = "";
|
|
588
|
+
} else {
|
|
589
|
+
if (!noTrace) {
|
|
590
|
+
trace.push({
|
|
591
|
+
lineNumber,
|
|
592
|
+
lineText: rawLine,
|
|
593
|
+
action: `Warning: Empty heading name at level ${hashCount}`,
|
|
594
|
+
stackDepth: stack.length,
|
|
595
|
+
currentStack: getStackNames(),
|
|
596
|
+
status: "warning"
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
continue;
|
|
104
600
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
601
|
+
}
|
|
602
|
+
const newNode = isExplicitArray ? [] : {};
|
|
603
|
+
if (activeParentItem && activeParentItem.isExplicitArray) {
|
|
604
|
+
activeParent.push(newNode);
|
|
605
|
+
if (!noTrace) {
|
|
108
606
|
trace.push({
|
|
109
607
|
lineNumber,
|
|
110
608
|
lineText: rawLine,
|
|
111
|
-
action: `
|
|
609
|
+
action: `Pushed new item into explicit array "${activeParentItem.key}" via heading "${actualHeadingName}"`,
|
|
112
610
|
stackDepth: stack.length,
|
|
113
611
|
currentStack: getStackNames(),
|
|
114
612
|
status: "success"
|
|
115
613
|
});
|
|
614
|
+
}
|
|
615
|
+
} else if (Array.isArray(activeParent)) {
|
|
616
|
+
if (actualHeadingName === "") {
|
|
617
|
+
activeParent.push(newNode);
|
|
618
|
+
if (!noTrace) {
|
|
619
|
+
trace.push({
|
|
620
|
+
lineNumber,
|
|
621
|
+
lineText: rawLine,
|
|
622
|
+
action: `Pushed anonymous object directly into parent Array`,
|
|
623
|
+
stackDepth: stack.length,
|
|
624
|
+
currentStack: getStackNames(),
|
|
625
|
+
status: "success"
|
|
626
|
+
});
|
|
627
|
+
}
|
|
116
628
|
} else {
|
|
117
|
-
activeParent[
|
|
629
|
+
activeParent.push({ [actualHeadingName]: newNode });
|
|
630
|
+
if (!noTrace) {
|
|
631
|
+
trace.push({
|
|
632
|
+
lineNumber,
|
|
633
|
+
lineText: rawLine,
|
|
634
|
+
action: `Created heading "${actualHeadingName}" at level ${hashCount} and pushed inside parent Array`,
|
|
635
|
+
stackDepth: stack.length,
|
|
636
|
+
currentStack: getStackNames(),
|
|
637
|
+
status: "success"
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
} else {
|
|
642
|
+
activeParent[actualHeadingName] = newNode;
|
|
643
|
+
if (!noTrace) {
|
|
118
644
|
trace.push({
|
|
119
645
|
lineNumber,
|
|
120
646
|
lineText: rawLine,
|
|
121
|
-
action: `Created heading "${
|
|
647
|
+
action: `Created heading "${actualHeadingName}" at level ${hashCount} in parent Object${isExplicitArray ? " as Array" : ""}`,
|
|
122
648
|
stackDepth: stack.length,
|
|
123
649
|
currentStack: getStackNames(),
|
|
124
650
|
status: "success"
|
|
125
651
|
});
|
|
126
652
|
}
|
|
127
|
-
stack.push({
|
|
128
|
-
level: hashCount,
|
|
129
|
-
key: headingName,
|
|
130
|
-
parent: activeParent,
|
|
131
|
-
value: newNode,
|
|
132
|
-
type: "object"
|
|
133
|
-
});
|
|
134
|
-
continue;
|
|
135
653
|
}
|
|
654
|
+
stack.push({
|
|
655
|
+
level: hashCount,
|
|
656
|
+
key: actualHeadingName,
|
|
657
|
+
parent: activeParent,
|
|
658
|
+
value: newNode,
|
|
659
|
+
type: isExplicitArray ? "array" : "object",
|
|
660
|
+
isExplicitArray
|
|
661
|
+
});
|
|
662
|
+
continue;
|
|
136
663
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
664
|
+
if (firstChar === 42 || firstChar === 45 || firstChar === 43) {
|
|
665
|
+
let bulletValIdx = startIdx + 1;
|
|
666
|
+
while (bulletValIdx <= endIdx) {
|
|
667
|
+
const code = rawLine.charCodeAt(bulletValIdx);
|
|
668
|
+
if (code === 32 || code === 9) {
|
|
669
|
+
bulletValIdx++;
|
|
670
|
+
} else {
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const bulletValStr = bulletValIdx <= endIdx ? rawLine.slice(bulletValIdx, endIdx + 1) : "";
|
|
675
|
+
const { value, nextLineIndex } = parseValueWithMultiline(bulletValStr, lines, i);
|
|
676
|
+
i = nextLineIndex;
|
|
141
677
|
if (stack.length === 0) {
|
|
142
678
|
if (!root._items) {
|
|
143
679
|
root._items = [];
|
|
144
680
|
}
|
|
145
681
|
root._items.push(value);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
682
|
+
if (!noTrace) {
|
|
683
|
+
trace.push({
|
|
684
|
+
lineNumber,
|
|
685
|
+
lineText: rawLine,
|
|
686
|
+
action: `No active heading. Pushed bullet item to root implicit list "_items"`,
|
|
687
|
+
stackDepth: stack.length,
|
|
688
|
+
currentStack: getStackNames(),
|
|
689
|
+
status: "info"
|
|
690
|
+
});
|
|
691
|
+
}
|
|
154
692
|
continue;
|
|
155
693
|
}
|
|
156
694
|
const activeItem = stack[stack.length - 1];
|
|
157
695
|
if (activeItem.type !== "array") {
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
696
|
+
let hasKeys = false;
|
|
697
|
+
for (const k in activeItem.value) {
|
|
698
|
+
if (Object.prototype.hasOwnProperty.call(activeItem.value, k)) {
|
|
699
|
+
hasKeys = true;
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (!hasKeys) {
|
|
704
|
+
const parent = activeItem.parent;
|
|
705
|
+
const key = activeItem.key;
|
|
706
|
+
activeItem.type = "array";
|
|
707
|
+
activeItem.value = [];
|
|
708
|
+
if (Array.isArray(parent)) {
|
|
709
|
+
parent[parent.length - 1] = { [key]: activeItem.value };
|
|
710
|
+
} else {
|
|
711
|
+
parent[key] = activeItem.value;
|
|
712
|
+
}
|
|
713
|
+
if (!noTrace) {
|
|
714
|
+
trace.push({
|
|
715
|
+
lineNumber,
|
|
716
|
+
lineText: rawLine,
|
|
717
|
+
action: `Array trigger: Converted heading "${key}" to an Array because it was an empty Object`,
|
|
718
|
+
stackDepth: stack.length,
|
|
719
|
+
currentStack: getStackNames(),
|
|
720
|
+
status: "info"
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
activeItem.value.push(value);
|
|
724
|
+
if (!noTrace) {
|
|
725
|
+
trace.push({
|
|
726
|
+
lineNumber,
|
|
727
|
+
lineText: rawLine,
|
|
728
|
+
action: `Pushed item "${value}" (type: ${typeof value}) into array "${activeItem.key}"`,
|
|
729
|
+
stackDepth: stack.length,
|
|
730
|
+
currentStack: getStackNames(),
|
|
731
|
+
status: "success"
|
|
732
|
+
});
|
|
733
|
+
}
|
|
164
734
|
} else {
|
|
165
|
-
|
|
735
|
+
if (!activeItem.value._items) {
|
|
736
|
+
activeItem.value._items = [];
|
|
737
|
+
}
|
|
738
|
+
activeItem.value._items.push(value);
|
|
739
|
+
if (!noTrace) {
|
|
740
|
+
trace.push({
|
|
741
|
+
lineNumber,
|
|
742
|
+
lineText: rawLine,
|
|
743
|
+
action: `Pushed bullet item "${value}" to implicit list "_items" inside non-empty Object under heading "${activeItem.key}"`,
|
|
744
|
+
stackDepth: stack.length,
|
|
745
|
+
currentStack: getStackNames(),
|
|
746
|
+
status: "info"
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
} else {
|
|
751
|
+
activeItem.value.push(value);
|
|
752
|
+
if (!noTrace) {
|
|
753
|
+
trace.push({
|
|
754
|
+
lineNumber,
|
|
755
|
+
lineText: rawLine,
|
|
756
|
+
action: `Pushed item "${value}" (type: ${typeof value}) into array "${activeItem.key}"`,
|
|
757
|
+
stackDepth: stack.length,
|
|
758
|
+
currentStack: getStackNames(),
|
|
759
|
+
status: "success"
|
|
760
|
+
});
|
|
166
761
|
}
|
|
167
|
-
trace.push({
|
|
168
|
-
lineNumber,
|
|
169
|
-
lineText: rawLine,
|
|
170
|
-
action: `Array trigger: Converted heading "${key}" to an Array`,
|
|
171
|
-
stackDepth: stack.length,
|
|
172
|
-
currentStack: getStackNames(),
|
|
173
|
-
status: "info"
|
|
174
|
-
});
|
|
175
762
|
}
|
|
176
|
-
activeItem.value.push(value);
|
|
177
|
-
trace.push({
|
|
178
|
-
lineNumber,
|
|
179
|
-
lineText: rawLine,
|
|
180
|
-
action: `Pushed item "${value}" (type: ${typeof value}) into array "${activeItem.key}"`,
|
|
181
|
-
stackDepth: stack.length,
|
|
182
|
-
currentStack: getStackNames(),
|
|
183
|
-
status: "success"
|
|
184
|
-
});
|
|
185
763
|
continue;
|
|
186
764
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
765
|
+
const colonIndex = findColonIndex(rawLine, startIdx);
|
|
766
|
+
if (colonIndex !== -1 && colonIndex <= endIdx) {
|
|
767
|
+
let kEnd = colonIndex - 1;
|
|
768
|
+
while (kEnd >= startIdx) {
|
|
769
|
+
const code = rawLine.charCodeAt(kEnd);
|
|
770
|
+
if (code === 32 || code === 9) {
|
|
771
|
+
kEnd--;
|
|
772
|
+
} else {
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
const key = startIdx <= kEnd ? rawLine.slice(startIdx, kEnd + 1) : "";
|
|
777
|
+
let vStart = colonIndex + 1;
|
|
778
|
+
while (vStart <= endIdx) {
|
|
779
|
+
const code = rawLine.charCodeAt(vStart);
|
|
780
|
+
if (code === 32 || code === 9) {
|
|
781
|
+
vStart++;
|
|
782
|
+
} else {
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
const valStr = vStart <= endIdx ? rawLine.slice(vStart, endIdx + 1) : "";
|
|
787
|
+
const { value: parsedVal, nextLineIndex } = parseValueWithMultiline(valStr, lines, i);
|
|
788
|
+
i = nextLineIndex;
|
|
192
789
|
if (stack.length === 0) {
|
|
193
790
|
root[key] = parsedVal;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
791
|
+
if (!noTrace) {
|
|
792
|
+
trace.push({
|
|
793
|
+
lineNumber,
|
|
794
|
+
lineText: rawLine,
|
|
795
|
+
action: `Set root key "${key}" to "${parsedVal}"`,
|
|
796
|
+
stackDepth: stack.length,
|
|
797
|
+
currentStack: getStackNames(),
|
|
798
|
+
status: "success"
|
|
799
|
+
});
|
|
800
|
+
}
|
|
202
801
|
continue;
|
|
203
802
|
}
|
|
204
803
|
const activeItem = stack[stack.length - 1];
|
|
205
804
|
if (activeItem.type === "array") {
|
|
805
|
+
if (!noTrace) {
|
|
806
|
+
trace.push({
|
|
807
|
+
lineNumber,
|
|
808
|
+
lineText: rawLine,
|
|
809
|
+
action: `Error: Key-value "${key}" encountered inside array "${activeItem.key}"`,
|
|
810
|
+
stackDepth: stack.length,
|
|
811
|
+
currentStack: getStackNames(),
|
|
812
|
+
status: "error"
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
activeItem.value[key] = parsedVal;
|
|
818
|
+
if (!noTrace) {
|
|
206
819
|
trace.push({
|
|
207
820
|
lineNumber,
|
|
208
821
|
lineText: rawLine,
|
|
209
|
-
action: `
|
|
822
|
+
action: `Set key "${key}" to "${parsedVal}" in active heading "${activeItem.key}"`,
|
|
210
823
|
stackDepth: stack.length,
|
|
211
824
|
currentStack: getStackNames(),
|
|
212
|
-
status: "
|
|
825
|
+
status: "success"
|
|
213
826
|
});
|
|
214
|
-
continue;
|
|
215
827
|
}
|
|
216
|
-
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
if (!noTrace) {
|
|
217
831
|
trace.push({
|
|
218
832
|
lineNumber,
|
|
219
833
|
lineText: rawLine,
|
|
220
|
-
action: `
|
|
834
|
+
action: `Unparsed content: Line skipped or treated as plain text`,
|
|
221
835
|
stackDepth: stack.length,
|
|
222
836
|
currentStack: getStackNames(),
|
|
223
|
-
status: "
|
|
837
|
+
status: "warning"
|
|
224
838
|
});
|
|
225
|
-
continue;
|
|
226
839
|
}
|
|
227
|
-
trace.push({
|
|
228
|
-
lineNumber,
|
|
229
|
-
lineText: rawLine,
|
|
230
|
-
action: `Unparsed content: Line skipped or treated as plain text`,
|
|
231
|
-
stackDepth: stack.length,
|
|
232
|
-
currentStack: getStackNames(),
|
|
233
|
-
status: "warning"
|
|
234
|
-
});
|
|
235
840
|
}
|
|
236
841
|
const endTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
237
842
|
const parseTimeMs = Number((endTime - startTime).toFixed(3));
|
|
238
843
|
const charCount = text.length;
|
|
239
844
|
const estimatedTokens = Math.ceil(charCount / 4.1);
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
845
|
+
let jsonCharCount = 0;
|
|
846
|
+
let jsonEstimatedTokens = 0;
|
|
847
|
+
let tokenSavingsPercent = 0;
|
|
848
|
+
if (!noTrace) {
|
|
849
|
+
const jsonString = JSON.stringify(root, null, 2);
|
|
850
|
+
jsonCharCount = jsonString.length;
|
|
851
|
+
jsonEstimatedTokens = Math.ceil(jsonCharCount / 3.7);
|
|
852
|
+
tokenSavingsPercent = Number(((jsonEstimatedTokens - estimatedTokens) / jsonEstimatedTokens * 100).toFixed(1));
|
|
853
|
+
}
|
|
244
854
|
return {
|
|
245
855
|
data: root,
|
|
246
856
|
trace,
|
|
@@ -255,14 +865,35 @@ function parseWithTrace(text) {
|
|
|
255
865
|
}
|
|
256
866
|
};
|
|
257
867
|
}
|
|
258
|
-
function stringify(obj, level = 0) {
|
|
868
|
+
function stringify(obj, level = 0, parentKey) {
|
|
259
869
|
if (obj === null || obj === void 0) return "";
|
|
260
870
|
let output = "";
|
|
261
871
|
const hashes = (lvl) => "#".repeat(lvl);
|
|
262
872
|
if (Array.isArray(obj)) {
|
|
873
|
+
if (level === 0) {
|
|
874
|
+
output += "[]\n\n";
|
|
875
|
+
}
|
|
876
|
+
let itemName = "Item";
|
|
877
|
+
if (parentKey) {
|
|
878
|
+
if (parentKey.endsWith("ies")) {
|
|
879
|
+
itemName = parentKey.slice(0, -3) + "y";
|
|
880
|
+
} else if (parentKey.endsWith("s") && !parentKey.endsWith("ss")) {
|
|
881
|
+
itemName = parentKey.slice(0, -1);
|
|
882
|
+
} else {
|
|
883
|
+
itemName = parentKey;
|
|
884
|
+
}
|
|
885
|
+
itemName = itemName.charAt(0).toUpperCase() + itemName.slice(1);
|
|
886
|
+
}
|
|
263
887
|
for (const item of obj) {
|
|
264
888
|
if (typeof item === "object" && item !== null) {
|
|
265
|
-
|
|
889
|
+
const nextLevel = level + 1;
|
|
890
|
+
output += `${hashes(nextLevel)} ${itemName}
|
|
891
|
+
`;
|
|
892
|
+
const nestedString = stringify(item, nextLevel);
|
|
893
|
+
if (nestedString) {
|
|
894
|
+
output += nestedString;
|
|
895
|
+
}
|
|
896
|
+
output += "\n";
|
|
266
897
|
} else {
|
|
267
898
|
output += `* ${stringifyPrimitiveValue(item)}
|
|
268
899
|
`;
|
|
@@ -281,10 +912,12 @@ function stringify(obj, level = 0) {
|
|
|
281
912
|
}
|
|
282
913
|
for (const key of complex) {
|
|
283
914
|
const nextLevel = level + 1;
|
|
284
|
-
output += `${hashes(nextLevel)} ${key}
|
|
285
|
-
`;
|
|
286
915
|
const val = obj[key];
|
|
287
|
-
const
|
|
916
|
+
const isArrayOfObjects = Array.isArray(val) && val.some((item) => typeof item === "object" && item !== null);
|
|
917
|
+
const headingNameSuffix = isArrayOfObjects ? "[]" : "";
|
|
918
|
+
output += `${hashes(nextLevel)} ${key}${headingNameSuffix}
|
|
919
|
+
`;
|
|
920
|
+
const nestedString = stringify(val, nextLevel, key);
|
|
288
921
|
if (nestedString) {
|
|
289
922
|
output += nestedString;
|
|
290
923
|
}
|
|
@@ -295,11 +928,15 @@ function stringify(obj, level = 0) {
|
|
|
295
928
|
}
|
|
296
929
|
// Annotate the CommonJS export names for ESM import in node:
|
|
297
930
|
0 && (module.exports = {
|
|
931
|
+
fastParseWithTrace,
|
|
298
932
|
parse,
|
|
299
933
|
parseMSON,
|
|
934
|
+
parseMaSON,
|
|
300
935
|
parsePrimitiveValue,
|
|
936
|
+
parseValueWithMultiline,
|
|
301
937
|
parseWithTrace,
|
|
302
938
|
stringify,
|
|
303
939
|
stringifyMSON,
|
|
940
|
+
stringifyMaSON,
|
|
304
941
|
stringifyPrimitiveValue
|
|
305
942
|
});
|