@poe-platform/safe-bash 0.1.508 → 0.1.509
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/dist/safe-bash/chunks/chunk-4OKU6JXB.js +5279 -0
- package/dist/safe-bash/chunks/chunk-4OKU6JXB.js.map +7 -0
- package/dist/safe-bash/chunks/chunk-5HT35GTV.js +520 -0
- package/dist/safe-bash/chunks/chunk-5HT35GTV.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-3ISDVRIM.js → chunk-B637PJBS.js} +19 -523
- package/dist/safe-bash/chunks/chunk-B637PJBS.js.map +7 -0
- package/dist/safe-bash/commands/structured/query-core.d.ts +35 -0
- package/dist/safe-bash/commands/structured/query-core.d.ts.map +1 -0
- package/dist/safe-bash/commands/structured/query-core.js +588 -0
- package/dist/safe-bash/commands/structured/query-core.js.map +1 -0
- package/dist/safe-bash/commands/xml/index.browser.js +2 -1
- package/dist/safe-bash/commands/yq/accounting.d.ts +64 -0
- package/dist/safe-bash/commands/yq/accounting.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/accounting.js +257 -0
- package/dist/safe-bash/commands/yq/accounting.js.map +1 -0
- package/dist/safe-bash/commands/yq/encoder.d.ts +6 -0
- package/dist/safe-bash/commands/yq/encoder.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/encoder.js +240 -0
- package/dist/safe-bash/commands/yq/encoder.js.map +1 -0
- package/dist/safe-bash/commands/yq/errors.d.ts +15 -0
- package/dist/safe-bash/commands/yq/errors.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/errors.js +37 -0
- package/dist/safe-bash/commands/yq/errors.js.map +1 -0
- package/dist/safe-bash/commands/yq/index.browser.js +12 -0
- package/dist/safe-bash/commands/yq/index.browser.js.map +7 -0
- package/dist/safe-bash/commands/yq/index.d.ts +9 -0
- package/dist/safe-bash/commands/yq/index.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/index.js +719 -0
- package/dist/safe-bash/commands/yq/index.js.map +1 -0
- package/dist/safe-bash/commands/yq/parser.d.ts +5 -0
- package/dist/safe-bash/commands/yq/parser.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/parser.js +1326 -0
- package/dist/safe-bash/commands/yq/parser.js.map +1 -0
- package/dist/safe-bash/commands/yq/toml.d.ts +5 -0
- package/dist/safe-bash/commands/yq/toml.d.ts.map +1 -0
- package/dist/safe-bash/commands/yq/toml.js +690 -0
- package/dist/safe-bash/commands/yq/toml.js.map +1 -0
- package/dist/safe-bash/core.browser.js +221 -2171
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/core.d.ts +1 -0
- package/dist/safe-bash/core.d.ts.map +1 -1
- package/dist/safe-bash/core.js +1 -0
- package/dist/safe-bash/core.js.map +1 -1
- package/package.json +8 -2
- package/dist/safe-bash/chunks/chunk-3ISDVRIM.js.map +0 -7
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
import { object, objectKeyIterator, objectSize, put } from "../structured/limits.js";
|
|
2
|
+
import { Decimal, numberText } from "../structured/numbers.js";
|
|
3
|
+
import { YqLedger, yqCaps } from "./accounting.js";
|
|
4
|
+
import { YqError, limit } from "./errors.js";
|
|
5
|
+
class TomlParser {
|
|
6
|
+
source;
|
|
7
|
+
work;
|
|
8
|
+
ledger;
|
|
9
|
+
#offset = 0;
|
|
10
|
+
#line = 1;
|
|
11
|
+
#column = 1;
|
|
12
|
+
#pending = 0;
|
|
13
|
+
#tables = new WeakMap();
|
|
14
|
+
#arraysOfTables = new WeakSet();
|
|
15
|
+
constructor(source, work, ledger) {
|
|
16
|
+
this.source = source;
|
|
17
|
+
this.work = work;
|
|
18
|
+
this.ledger = ledger;
|
|
19
|
+
}
|
|
20
|
+
#syntax() { throw new YqError("input", "INPUT_TOML_SYNTAX", 5, undefined, this.#line, this.#column); }
|
|
21
|
+
#conflict() { throw new YqError("schema", "SCHEMA_DUPLICATE_KEY", 5, undefined, this.#line, this.#column); }
|
|
22
|
+
#schema(code) {
|
|
23
|
+
throw new YqError("schema", code, 5, undefined, this.#line, this.#column);
|
|
24
|
+
}
|
|
25
|
+
#peek(distance = 0) { return this.source[this.#offset + distance] ?? ""; }
|
|
26
|
+
#take() {
|
|
27
|
+
if (this.#offset >= this.source.length)
|
|
28
|
+
this.#syntax();
|
|
29
|
+
const point = this.source.codePointAt(this.#offset);
|
|
30
|
+
if (point >= 0xd800 && point <= 0xdfff || point < 32 && point !== 9 && point !== 10 && point !== 13 || point === 127)
|
|
31
|
+
this.#syntax();
|
|
32
|
+
let value = String.fromCodePoint(point);
|
|
33
|
+
this.#offset += value.length;
|
|
34
|
+
this.#pending++;
|
|
35
|
+
if (point === 13) {
|
|
36
|
+
if (this.#peek() !== "\n")
|
|
37
|
+
this.#syntax();
|
|
38
|
+
this.#offset++;
|
|
39
|
+
value = "\n";
|
|
40
|
+
}
|
|
41
|
+
if (value === "\n") {
|
|
42
|
+
this.#line++;
|
|
43
|
+
this.#column = 1;
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
this.#column++;
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
async #flush() {
|
|
50
|
+
if (this.#pending) {
|
|
51
|
+
const units = this.#pending;
|
|
52
|
+
this.#pending = 0;
|
|
53
|
+
await this.work.charge(units);
|
|
54
|
+
}
|
|
55
|
+
this.work.assertOpen();
|
|
56
|
+
}
|
|
57
|
+
async #space(newlines) {
|
|
58
|
+
while (true) {
|
|
59
|
+
const character = this.#peek();
|
|
60
|
+
if (character === " " || character === "\t" || newlines && (character === "\n" || character === "\r"))
|
|
61
|
+
this.#take();
|
|
62
|
+
else if (newlines && character === "#") {
|
|
63
|
+
while (this.#peek() && this.#peek() !== "\n" && this.#peek() !== "\r") {
|
|
64
|
+
this.#take();
|
|
65
|
+
if (this.#pending >= 256)
|
|
66
|
+
await this.#flush();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
break;
|
|
71
|
+
if (this.#pending >= 256)
|
|
72
|
+
await this.#flush();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async #lineEnd() {
|
|
76
|
+
await this.#space(false);
|
|
77
|
+
if (this.#peek() === "#") {
|
|
78
|
+
while (this.#peek() && this.#peek() !== "\n" && this.#peek() !== "\r") {
|
|
79
|
+
this.#take();
|
|
80
|
+
if (this.#pending >= 256)
|
|
81
|
+
await this.#flush();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (this.#peek() === "\n" || this.#peek() === "\r")
|
|
85
|
+
this.#take();
|
|
86
|
+
else if (this.#peek())
|
|
87
|
+
this.#syntax();
|
|
88
|
+
}
|
|
89
|
+
#depth(depth) { if (depth > yqCaps.maxDepth)
|
|
90
|
+
throw limit("LIMIT_MAX_DEPTH"); }
|
|
91
|
+
async #node() {
|
|
92
|
+
await this.#flush();
|
|
93
|
+
await this.work.charge(1);
|
|
94
|
+
this.work.assertOpen();
|
|
95
|
+
this.ledger.admitNode();
|
|
96
|
+
}
|
|
97
|
+
async #table(kind, depth) {
|
|
98
|
+
this.#depth(depth);
|
|
99
|
+
await this.#node();
|
|
100
|
+
this.ledger.admitValueBytes(2);
|
|
101
|
+
const value = object();
|
|
102
|
+
this.#tables.set(value, { kind, depth, sealed: false });
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
async #array(depth) {
|
|
106
|
+
this.#depth(depth);
|
|
107
|
+
await this.#node();
|
|
108
|
+
this.ledger.admitValueBytes(2);
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
async #scalar(value) {
|
|
112
|
+
await this.#node();
|
|
113
|
+
if (typeof value !== "string") {
|
|
114
|
+
const text = typeof value === "boolean" ? String(value) : numberText(value);
|
|
115
|
+
this.ledger.admitScalar(text.length);
|
|
116
|
+
this.ledger.admitValueBytes(text.length);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
let rawBytes = 0;
|
|
120
|
+
let compactBytes = 2;
|
|
121
|
+
let work = 0;
|
|
122
|
+
for (const character of value) {
|
|
123
|
+
const point = character.codePointAt(0);
|
|
124
|
+
const bytes = point <= 0x7f ? 1 : point <= 0x7ff ? 2 : point <= 0xffff ? 3 : 4;
|
|
125
|
+
rawBytes += bytes;
|
|
126
|
+
compactBytes += point === 34 || point === 92 || [8, 9, 10, 12, 13].includes(point) ? 2 : point < 32 ? 6 : bytes;
|
|
127
|
+
this.ledger.admitScalar(rawBytes);
|
|
128
|
+
if (++work === 256) {
|
|
129
|
+
await this.work.charge(work);
|
|
130
|
+
this.work.assertOpen();
|
|
131
|
+
work = 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (work)
|
|
135
|
+
await this.work.charge(work);
|
|
136
|
+
this.work.assertOpen();
|
|
137
|
+
this.ledger.admitValueBytes(compactBytes);
|
|
138
|
+
}
|
|
139
|
+
async #member(table, key, value) {
|
|
140
|
+
if (Object.hasOwn(table, key))
|
|
141
|
+
this.#conflict();
|
|
142
|
+
const size = objectSize(table);
|
|
143
|
+
if (size >= yqCaps.maxCollectionSize)
|
|
144
|
+
throw limit("LIMIT_MAX_COLLECTION_SIZE");
|
|
145
|
+
await this.#scalar(key);
|
|
146
|
+
this.ledger.admitValueBytes(size ? 2 : 1);
|
|
147
|
+
this.work.assertOpen();
|
|
148
|
+
put(table, key, value);
|
|
149
|
+
}
|
|
150
|
+
#append(array, value) {
|
|
151
|
+
if (array.length >= yqCaps.maxCollectionSize)
|
|
152
|
+
throw limit("LIMIT_MAX_COLLECTION_SIZE");
|
|
153
|
+
if (array.length)
|
|
154
|
+
this.ledger.admitValueBytes(1);
|
|
155
|
+
this.work.assertOpen();
|
|
156
|
+
array.push(value);
|
|
157
|
+
}
|
|
158
|
+
async #string(key = false) {
|
|
159
|
+
const quote = this.#take();
|
|
160
|
+
let multiline = false;
|
|
161
|
+
if (!key && this.#peek() === quote && this.#peek(1) === quote) {
|
|
162
|
+
this.#take();
|
|
163
|
+
this.#take();
|
|
164
|
+
multiline = true;
|
|
165
|
+
if (this.#peek() === "\n" || this.#peek() === "\r")
|
|
166
|
+
this.#take();
|
|
167
|
+
}
|
|
168
|
+
const parts = [];
|
|
169
|
+
let part = "";
|
|
170
|
+
let bytes = 0;
|
|
171
|
+
const append = (value) => {
|
|
172
|
+
bytes += Buffer.byteLength(value);
|
|
173
|
+
this.ledger.admitScalar(bytes);
|
|
174
|
+
part += value;
|
|
175
|
+
if (part.length >= 256) {
|
|
176
|
+
parts.push(part);
|
|
177
|
+
part = "";
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
while (this.#peek()) {
|
|
181
|
+
const character = this.#take();
|
|
182
|
+
if (character === quote) {
|
|
183
|
+
if (!multiline) {
|
|
184
|
+
parts.push(part);
|
|
185
|
+
return parts.join("");
|
|
186
|
+
}
|
|
187
|
+
let count = 1;
|
|
188
|
+
while (count < 5 && this.#peek() === quote) {
|
|
189
|
+
this.#take();
|
|
190
|
+
count++;
|
|
191
|
+
}
|
|
192
|
+
if (count >= 3) {
|
|
193
|
+
append(quote.repeat(count - 3));
|
|
194
|
+
parts.push(part);
|
|
195
|
+
return parts.join("");
|
|
196
|
+
}
|
|
197
|
+
append(quote.repeat(count));
|
|
198
|
+
}
|
|
199
|
+
else if (character === "\n") {
|
|
200
|
+
if (!multiline)
|
|
201
|
+
this.#syntax();
|
|
202
|
+
append(character);
|
|
203
|
+
}
|
|
204
|
+
else if (quote === '"' && character === "\\") {
|
|
205
|
+
if (multiline && [" ", "\t", "\n", "\r"].includes(this.#peek())) {
|
|
206
|
+
await this.#space(false);
|
|
207
|
+
if (this.#peek() !== "\n" && this.#peek() !== "\r")
|
|
208
|
+
this.#syntax();
|
|
209
|
+
this.#take();
|
|
210
|
+
while ([" ", "\t", "\n", "\r"].includes(this.#peek())) {
|
|
211
|
+
this.#take();
|
|
212
|
+
if (this.#pending >= 256)
|
|
213
|
+
await this.#flush();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const escape = this.#take();
|
|
218
|
+
const simple = { b: "\b", t: "\t", n: "\n", f: "\f", r: "\r", '"': '"', "\\": "\\" };
|
|
219
|
+
if (Object.hasOwn(simple, escape))
|
|
220
|
+
append(simple[escape]);
|
|
221
|
+
else if (escape === "u" || escape === "U") {
|
|
222
|
+
let point = 0;
|
|
223
|
+
for (let index = 0; index < (escape === "u" ? 4 : 8); index++) {
|
|
224
|
+
const digit = this.#digit(this.#take(), 16);
|
|
225
|
+
if (digit < 0)
|
|
226
|
+
this.#syntax();
|
|
227
|
+
point = point * 16 + digit;
|
|
228
|
+
}
|
|
229
|
+
if (point > 0x10ffff || point >= 0xd800 && point <= 0xdfff)
|
|
230
|
+
this.#syntax();
|
|
231
|
+
append(String.fromCodePoint(point));
|
|
232
|
+
}
|
|
233
|
+
else
|
|
234
|
+
this.#syntax();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else
|
|
238
|
+
append(character);
|
|
239
|
+
if (this.#pending >= 256)
|
|
240
|
+
await this.#flush();
|
|
241
|
+
}
|
|
242
|
+
return this.#syntax();
|
|
243
|
+
}
|
|
244
|
+
#digit(character, base) {
|
|
245
|
+
const code = character.charCodeAt(0);
|
|
246
|
+
const digit = code >= 48 && code <= 57 ? code - 48 : code >= 65 && code <= 70 ? code - 55 : code >= 97 && code <= 102 ? code - 87 : -1;
|
|
247
|
+
return digit >= 0 && digit < base ? digit : -1;
|
|
248
|
+
}
|
|
249
|
+
async #keyPath() {
|
|
250
|
+
const path = [];
|
|
251
|
+
while (true) {
|
|
252
|
+
await this.#space(false);
|
|
253
|
+
let key;
|
|
254
|
+
if (this.#peek() === '"' || this.#peek() === "'")
|
|
255
|
+
key = await this.#string(true);
|
|
256
|
+
else {
|
|
257
|
+
const start = this.#offset;
|
|
258
|
+
while (this.#peek()) {
|
|
259
|
+
const code = this.#peek().charCodeAt(0);
|
|
260
|
+
if (!(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 95 || code === 45))
|
|
261
|
+
break;
|
|
262
|
+
this.#take();
|
|
263
|
+
if (this.#offset - start > yqCaps.maxScalarBytes)
|
|
264
|
+
throw limit("LIMIT_MAX_SCALAR_BYTES");
|
|
265
|
+
if (this.#pending >= 256)
|
|
266
|
+
await this.#flush();
|
|
267
|
+
}
|
|
268
|
+
if (this.#offset === start)
|
|
269
|
+
this.#syntax();
|
|
270
|
+
key = this.source.slice(start, this.#offset);
|
|
271
|
+
}
|
|
272
|
+
if (path.length >= yqCaps.maxDepth)
|
|
273
|
+
throw limit("LIMIT_MAX_DEPTH");
|
|
274
|
+
path.push(key);
|
|
275
|
+
await this.#space(false);
|
|
276
|
+
if (this.#peek() !== ".")
|
|
277
|
+
return path;
|
|
278
|
+
this.#take();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
#state(table) {
|
|
282
|
+
const state = this.#tables.get(table);
|
|
283
|
+
if (!state)
|
|
284
|
+
this.#conflict();
|
|
285
|
+
return state;
|
|
286
|
+
}
|
|
287
|
+
async #parents(start, path, kind, allowAoT) {
|
|
288
|
+
let current = start;
|
|
289
|
+
for (const key of path) {
|
|
290
|
+
await this.work.charge(1);
|
|
291
|
+
this.work.assertOpen();
|
|
292
|
+
const parent = this.#state(current);
|
|
293
|
+
if (parent.sealed)
|
|
294
|
+
this.#conflict();
|
|
295
|
+
let value = current[key];
|
|
296
|
+
if (!Object.hasOwn(current, key)) {
|
|
297
|
+
value = await this.#table(kind, parent.depth + 1);
|
|
298
|
+
await this.#member(current, key, value);
|
|
299
|
+
}
|
|
300
|
+
else if (Array.isArray(value) && allowAoT && this.#arraysOfTables.has(value))
|
|
301
|
+
value = value.at(-1);
|
|
302
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Decimal)
|
|
303
|
+
this.#conflict();
|
|
304
|
+
const state = this.#state(value);
|
|
305
|
+
if (state.sealed)
|
|
306
|
+
this.#conflict();
|
|
307
|
+
if (kind === "dotted" && state.kind === "header")
|
|
308
|
+
this.#conflict();
|
|
309
|
+
if (kind === "dotted" && state.kind === "implicit")
|
|
310
|
+
state.kind = "dotted";
|
|
311
|
+
current = value;
|
|
312
|
+
}
|
|
313
|
+
return current;
|
|
314
|
+
}
|
|
315
|
+
async #assignment(current) {
|
|
316
|
+
const path = await this.#keyPath();
|
|
317
|
+
if (this.#take() !== "=")
|
|
318
|
+
this.#syntax();
|
|
319
|
+
await this.#space(false);
|
|
320
|
+
const parent = await this.#parents(current, path.slice(0, -1), "dotted", false);
|
|
321
|
+
if (this.#state(parent).sealed || Object.hasOwn(parent, path.at(-1)))
|
|
322
|
+
this.#conflict();
|
|
323
|
+
if (objectSize(parent) >= yqCaps.maxCollectionSize)
|
|
324
|
+
throw limit("LIMIT_MAX_COLLECTION_SIZE");
|
|
325
|
+
const value = await this.#value(this.#state(parent).depth + 1);
|
|
326
|
+
await this.#member(parent, path.at(-1), value);
|
|
327
|
+
}
|
|
328
|
+
async #header(root) {
|
|
329
|
+
this.#take();
|
|
330
|
+
const array = this.#peek() === "[";
|
|
331
|
+
if (array)
|
|
332
|
+
this.#take();
|
|
333
|
+
const path = await this.#keyPath();
|
|
334
|
+
if (this.#take() !== "]" || array && this.#take() !== "]")
|
|
335
|
+
this.#syntax();
|
|
336
|
+
await this.#lineEnd();
|
|
337
|
+
const parent = await this.#parents(root, path.slice(0, -1), "implicit", true);
|
|
338
|
+
const key = path.at(-1);
|
|
339
|
+
const parentState = this.#state(parent);
|
|
340
|
+
if (parentState.sealed)
|
|
341
|
+
this.#conflict();
|
|
342
|
+
const exists = Object.hasOwn(parent, key);
|
|
343
|
+
const existing = parent[key];
|
|
344
|
+
if (array) {
|
|
345
|
+
let values;
|
|
346
|
+
if (exists) {
|
|
347
|
+
if (!Array.isArray(existing) || !this.#arraysOfTables.has(existing))
|
|
348
|
+
this.#conflict();
|
|
349
|
+
values = existing;
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
values = await this.#array(parentState.depth + 1);
|
|
353
|
+
this.#arraysOfTables.add(values);
|
|
354
|
+
await this.#member(parent, key, values);
|
|
355
|
+
}
|
|
356
|
+
if (values.length >= yqCaps.maxCollectionSize)
|
|
357
|
+
throw limit("LIMIT_MAX_COLLECTION_SIZE");
|
|
358
|
+
const table = await this.#table("header", parentState.depth + 2);
|
|
359
|
+
this.#append(values, table);
|
|
360
|
+
return table;
|
|
361
|
+
}
|
|
362
|
+
if (exists) {
|
|
363
|
+
if (typeof existing !== "object" || existing === null || Array.isArray(existing) || existing instanceof Decimal)
|
|
364
|
+
this.#conflict();
|
|
365
|
+
const state = this.#state(existing);
|
|
366
|
+
if (state.kind !== "implicit" || state.sealed)
|
|
367
|
+
this.#conflict();
|
|
368
|
+
state.kind = "header";
|
|
369
|
+
return existing;
|
|
370
|
+
}
|
|
371
|
+
const table = await this.#table("header", parentState.depth + 1);
|
|
372
|
+
await this.#member(parent, key, table);
|
|
373
|
+
return table;
|
|
374
|
+
}
|
|
375
|
+
async #seal(table) {
|
|
376
|
+
const pending = [table];
|
|
377
|
+
while (pending.length) {
|
|
378
|
+
const current = pending.pop();
|
|
379
|
+
await this.work.charge(1);
|
|
380
|
+
this.work.assertOpen();
|
|
381
|
+
this.#state(current).sealed = true;
|
|
382
|
+
for (const key of objectKeyIterator(current)) {
|
|
383
|
+
await this.work.charge(1);
|
|
384
|
+
this.work.assertOpen();
|
|
385
|
+
const value = current[key];
|
|
386
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Decimal))
|
|
387
|
+
pending.push(value);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
async #value(depth) {
|
|
392
|
+
this.#depth(depth);
|
|
393
|
+
const character = this.#peek();
|
|
394
|
+
if (character === '"' || character === "'") {
|
|
395
|
+
const value = await this.#string();
|
|
396
|
+
await this.#scalar(value);
|
|
397
|
+
return value;
|
|
398
|
+
}
|
|
399
|
+
if (character === "[") {
|
|
400
|
+
this.#take();
|
|
401
|
+
const result = await this.#array(depth);
|
|
402
|
+
await this.#space(true);
|
|
403
|
+
while (this.#peek() !== "]") {
|
|
404
|
+
if (!this.#peek())
|
|
405
|
+
this.#syntax();
|
|
406
|
+
if (result.length >= yqCaps.maxCollectionSize)
|
|
407
|
+
throw limit("LIMIT_MAX_COLLECTION_SIZE");
|
|
408
|
+
const value = await this.#value(depth + 1);
|
|
409
|
+
this.#append(result, value);
|
|
410
|
+
await this.#space(true);
|
|
411
|
+
if (this.#peek() !== ",")
|
|
412
|
+
break;
|
|
413
|
+
this.#take();
|
|
414
|
+
await this.#space(true);
|
|
415
|
+
}
|
|
416
|
+
if (this.#take() !== "]")
|
|
417
|
+
this.#syntax();
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
if (character === "{") {
|
|
421
|
+
this.#take();
|
|
422
|
+
const result = await this.#table("inline", depth);
|
|
423
|
+
await this.#space(false);
|
|
424
|
+
if (this.#peek() !== "}") {
|
|
425
|
+
while (true) {
|
|
426
|
+
await this.#assignment(result);
|
|
427
|
+
await this.#space(false);
|
|
428
|
+
if (this.#peek() !== ",")
|
|
429
|
+
break;
|
|
430
|
+
this.#take();
|
|
431
|
+
await this.#space(false);
|
|
432
|
+
if (this.#peek() === "}")
|
|
433
|
+
this.#syntax();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (this.#take() !== "}")
|
|
437
|
+
this.#syntax();
|
|
438
|
+
await this.#seal(result);
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
const start = this.#offset;
|
|
442
|
+
while (this.#peek()) {
|
|
443
|
+
const next = this.#peek();
|
|
444
|
+
if (" \t\r\n#,]}".includes(next)) {
|
|
445
|
+
if (next === " " && this.#offset - start === 10 && this.source[start + 4] === "-" && this.source[start + 7] === "-" && this.#digit(this.#peek(1), 10) >= 0)
|
|
446
|
+
this.#take();
|
|
447
|
+
else
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
else
|
|
451
|
+
this.#take();
|
|
452
|
+
if (this.#offset - start > yqCaps.maxScalarBytes)
|
|
453
|
+
throw limit("LIMIT_MAX_SCALAR_BYTES");
|
|
454
|
+
if (this.#pending >= 256)
|
|
455
|
+
await this.#flush();
|
|
456
|
+
}
|
|
457
|
+
if (this.#offset === start)
|
|
458
|
+
this.#syntax();
|
|
459
|
+
const raw = this.source.slice(start, this.#offset);
|
|
460
|
+
await this.#flush();
|
|
461
|
+
let value;
|
|
462
|
+
if (raw === "true" || raw === "false")
|
|
463
|
+
value = raw === "true";
|
|
464
|
+
else if (raw.length >= 8 && (raw[2] === ":" || raw[4] === "-" && raw[7] === "-")) {
|
|
465
|
+
await this.#date(raw);
|
|
466
|
+
value = raw;
|
|
467
|
+
}
|
|
468
|
+
else
|
|
469
|
+
value = await this.#number(raw);
|
|
470
|
+
await this.#scalar(value);
|
|
471
|
+
return value;
|
|
472
|
+
}
|
|
473
|
+
async #number(raw) {
|
|
474
|
+
let start = 0;
|
|
475
|
+
const negative = raw[0] === "-";
|
|
476
|
+
if (negative || raw[0] === "+")
|
|
477
|
+
start++;
|
|
478
|
+
const unsigned = raw.slice(start);
|
|
479
|
+
if (unsigned === "inf" || unsigned === "nan")
|
|
480
|
+
this.#schema("SCHEMA_NONFINITE_NUMBER");
|
|
481
|
+
let base = 10;
|
|
482
|
+
if (unsigned.startsWith("0x"))
|
|
483
|
+
base = 16;
|
|
484
|
+
else if (unsigned.startsWith("0o"))
|
|
485
|
+
base = 8;
|
|
486
|
+
else if (unsigned.startsWith("0b"))
|
|
487
|
+
base = 2;
|
|
488
|
+
if (base !== 10) {
|
|
489
|
+
if (start)
|
|
490
|
+
this.#syntax();
|
|
491
|
+
let value = 0;
|
|
492
|
+
let previousDigit = false;
|
|
493
|
+
if (raw.length <= 2)
|
|
494
|
+
this.#syntax();
|
|
495
|
+
for (let index = 2; index < raw.length; index++) {
|
|
496
|
+
const character = raw[index];
|
|
497
|
+
if (character === "_") {
|
|
498
|
+
if (!previousDigit || this.#digit(raw[index + 1] ?? "", base) < 0)
|
|
499
|
+
this.#syntax();
|
|
500
|
+
previousDigit = false;
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
const digit = this.#digit(character, base);
|
|
504
|
+
if (digit < 0)
|
|
505
|
+
this.#syntax();
|
|
506
|
+
if (value > Math.floor((Number.MAX_SAFE_INTEGER - digit) / base))
|
|
507
|
+
this.#schema("SCHEMA_UNSAFE_INTEGER");
|
|
508
|
+
value = value * base + digit;
|
|
509
|
+
previousDigit = true;
|
|
510
|
+
}
|
|
511
|
+
if (index % 256 === 0) {
|
|
512
|
+
await this.work.charge(256);
|
|
513
|
+
this.work.assertOpen();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return value;
|
|
517
|
+
}
|
|
518
|
+
let clean = "";
|
|
519
|
+
let integerDigits = 0;
|
|
520
|
+
let fractionDigits = 0;
|
|
521
|
+
let exponentDigits = 0;
|
|
522
|
+
let exponentValue = 0;
|
|
523
|
+
let exponentNegative = false;
|
|
524
|
+
let state = "integer";
|
|
525
|
+
let previousDigit = false;
|
|
526
|
+
let coefficient = "";
|
|
527
|
+
for (let index = start; index < raw.length; index++) {
|
|
528
|
+
const character = raw[index];
|
|
529
|
+
const digit = this.#digit(character, 10);
|
|
530
|
+
if (digit >= 0) {
|
|
531
|
+
clean += character;
|
|
532
|
+
previousDigit = true;
|
|
533
|
+
if (state === "integer") {
|
|
534
|
+
integerDigits++;
|
|
535
|
+
coefficient += character;
|
|
536
|
+
}
|
|
537
|
+
else if (state === "fraction") {
|
|
538
|
+
fractionDigits++;
|
|
539
|
+
coefficient += character;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
exponentDigits++;
|
|
543
|
+
if (exponentValue > 1_147_483_646)
|
|
544
|
+
this.#schema("SCHEMA_DECIMAL_RANGE");
|
|
545
|
+
exponentValue = exponentValue * 10 + digit;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
else if (character === "_") {
|
|
549
|
+
if (!previousDigit || this.#digit(raw[index + 1] ?? "", 10) < 0)
|
|
550
|
+
this.#syntax();
|
|
551
|
+
previousDigit = false;
|
|
552
|
+
}
|
|
553
|
+
else if (character === "." && state === "integer" && previousDigit) {
|
|
554
|
+
state = "fraction";
|
|
555
|
+
previousDigit = false;
|
|
556
|
+
clean += character;
|
|
557
|
+
}
|
|
558
|
+
else if ((character === "e" || character === "E") && state !== "exponent" && previousDigit) {
|
|
559
|
+
state = "exponent";
|
|
560
|
+
previousDigit = false;
|
|
561
|
+
clean += "e";
|
|
562
|
+
if (raw[index + 1] === "+" || raw[index + 1] === "-") {
|
|
563
|
+
exponentNegative = raw[index + 1] === "-";
|
|
564
|
+
clean += raw[++index];
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
else
|
|
568
|
+
this.#syntax();
|
|
569
|
+
if ((index - start + 1) % 256 === 0) {
|
|
570
|
+
await this.work.charge(256);
|
|
571
|
+
this.work.assertOpen();
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
if (!previousDigit || !integerDigits || integerDigits > 1 && unsigned[0] === "0" || state === "fraction" && !fractionDigits || state === "exponent" && !exponentDigits)
|
|
575
|
+
this.#syntax();
|
|
576
|
+
const signed = (negative ? "-" : "") + clean;
|
|
577
|
+
const value = Number(signed);
|
|
578
|
+
if (!Number.isFinite(value))
|
|
579
|
+
this.#schema("SCHEMA_NONFINITE_NUMBER");
|
|
580
|
+
if (Number.isInteger(value) && !Number.isSafeInteger(value))
|
|
581
|
+
this.#schema("SCHEMA_UNSAFE_INTEGER");
|
|
582
|
+
if (state === "integer")
|
|
583
|
+
return value;
|
|
584
|
+
let exponent = (exponentNegative ? -exponentValue : exponentValue) - fractionDigits;
|
|
585
|
+
if (exponent < -1_147_483_646 || exponent > 999_999_999)
|
|
586
|
+
this.#schema("SCHEMA_DECIMAL_RANGE");
|
|
587
|
+
let first = 0;
|
|
588
|
+
while (first < coefficient.length - 1 && coefficient[first] === "0") {
|
|
589
|
+
first++;
|
|
590
|
+
if (first % 256 === 0) {
|
|
591
|
+
await this.work.charge(256);
|
|
592
|
+
this.work.assertOpen();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
let last = coefficient.length;
|
|
596
|
+
while (last > first + 1 && coefficient[last - 1] === "0") {
|
|
597
|
+
last--;
|
|
598
|
+
exponent++;
|
|
599
|
+
if ((coefficient.length - last) % 256 === 0) {
|
|
600
|
+
await this.work.charge(256);
|
|
601
|
+
this.work.assertOpen();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
const digits = coefficient.slice(first, last);
|
|
605
|
+
if (digits !== "0" && exponent >= 0 && (digits.length + exponent > 16 || !Number.isSafeInteger(Number(`${digits}e${exponent}`))))
|
|
606
|
+
this.#schema("SCHEMA_UNSAFE_INTEGER");
|
|
607
|
+
return new Decimal(digits, exponent, negative, signed, value);
|
|
608
|
+
}
|
|
609
|
+
async #date(raw) {
|
|
610
|
+
const digits = (offset, length) => {
|
|
611
|
+
let value = 0;
|
|
612
|
+
for (let index = offset; index < offset + length; index++) {
|
|
613
|
+
const digit = this.#digit(raw[index] ?? "", 10);
|
|
614
|
+
if (digit < 0)
|
|
615
|
+
this.#syntax();
|
|
616
|
+
value = value * 10 + digit;
|
|
617
|
+
}
|
|
618
|
+
return value;
|
|
619
|
+
};
|
|
620
|
+
let offset = 0;
|
|
621
|
+
const date = raw[4] === "-" && raw[7] === "-";
|
|
622
|
+
if (date) {
|
|
623
|
+
const year = digits(0, 4), month = digits(5, 2), day = digits(8, 2);
|
|
624
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
625
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
626
|
+
if (year < 1 || month < 1 || month > 12 || day < 1 || day > days[month - 1])
|
|
627
|
+
this.#syntax();
|
|
628
|
+
if (raw.length === 10)
|
|
629
|
+
return;
|
|
630
|
+
if (!["T", "t", " "].includes(raw[10]))
|
|
631
|
+
this.#syntax();
|
|
632
|
+
offset = 11;
|
|
633
|
+
}
|
|
634
|
+
if (raw[offset + 2] !== ":" || raw[offset + 5] !== ":" || digits(offset, 2) > 23 || digits(offset + 3, 2) > 59 || digits(offset + 6, 2) > 59)
|
|
635
|
+
this.#syntax();
|
|
636
|
+
offset += 8;
|
|
637
|
+
if (raw[offset] === ".") {
|
|
638
|
+
const start = ++offset;
|
|
639
|
+
while (this.#digit(raw[offset] ?? "", 10) >= 0) {
|
|
640
|
+
offset++;
|
|
641
|
+
if ((offset - start) % 256 === 0) {
|
|
642
|
+
await this.work.charge(256);
|
|
643
|
+
this.work.assertOpen();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (offset === start)
|
|
647
|
+
this.#syntax();
|
|
648
|
+
}
|
|
649
|
+
if (offset === raw.length)
|
|
650
|
+
return;
|
|
651
|
+
if (!date)
|
|
652
|
+
this.#syntax();
|
|
653
|
+
if (raw[offset] === "Z" || raw[offset] === "z")
|
|
654
|
+
offset++;
|
|
655
|
+
else if (raw[offset] === "+" || raw[offset] === "-") {
|
|
656
|
+
if (raw[offset + 3] !== ":" || digits(offset + 1, 2) > 23 || digits(offset + 4, 2) > 59)
|
|
657
|
+
this.#syntax();
|
|
658
|
+
offset += 6;
|
|
659
|
+
}
|
|
660
|
+
else
|
|
661
|
+
this.#syntax();
|
|
662
|
+
if (offset !== raw.length)
|
|
663
|
+
this.#syntax();
|
|
664
|
+
}
|
|
665
|
+
async parse() {
|
|
666
|
+
if (this.source.charCodeAt(0) === 0xfeff)
|
|
667
|
+
this.#syntax();
|
|
668
|
+
const root = await this.#table("root", 1);
|
|
669
|
+
let current = root;
|
|
670
|
+
while (true) {
|
|
671
|
+
await this.#space(true);
|
|
672
|
+
if (!this.#peek())
|
|
673
|
+
break;
|
|
674
|
+
if (this.#peek() === "[")
|
|
675
|
+
current = await this.#header(root);
|
|
676
|
+
else {
|
|
677
|
+
await this.#assignment(current);
|
|
678
|
+
await this.#lineEnd();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
await this.#flush();
|
|
682
|
+
return root;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
export async function parseTomlDocument(text, work, ledger, rawBytes) {
|
|
686
|
+
work.assertOpen();
|
|
687
|
+
ledger.beginDocument(rawBytes);
|
|
688
|
+
return new TomlParser(text, work, ledger).parse();
|
|
689
|
+
}
|
|
690
|
+
//# sourceMappingURL=toml.js.map
|