@callstack/apex 0.3.0 → 0.4.1

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.
Files changed (3) hide show
  1. package/README.md +41 -10
  2. package/dist/cli.js +689 -483
  3. package/package.json +3 -2
package/dist/cli.js CHANGED
@@ -48,13 +48,13 @@ function createScanner(text, ignoreTrivia = false) {
48
48
  if (text.charCodeAt(pos) === 48) pos++;
49
49
  else {
50
50
  pos++;
51
- while (pos < text.length && isDigit(text.charCodeAt(pos))) pos++;
51
+ while (pos < text.length && isDigit$1(text.charCodeAt(pos))) pos++;
52
52
  }
53
53
  if (pos < text.length && text.charCodeAt(pos) === 46) {
54
54
  pos++;
55
- if (pos < text.length && isDigit(text.charCodeAt(pos))) {
55
+ if (pos < text.length && isDigit$1(text.charCodeAt(pos))) {
56
56
  pos++;
57
- while (pos < text.length && isDigit(text.charCodeAt(pos))) pos++;
57
+ while (pos < text.length && isDigit$1(text.charCodeAt(pos))) pos++;
58
58
  } else {
59
59
  scanError = 3;
60
60
  return text.substring(start, pos);
@@ -64,9 +64,9 @@ function createScanner(text, ignoreTrivia = false) {
64
64
  if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
65
65
  pos++;
66
66
  if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) pos++;
67
- if (pos < text.length && isDigit(text.charCodeAt(pos))) {
67
+ if (pos < text.length && isDigit$1(text.charCodeAt(pos))) {
68
68
  pos++;
69
- while (pos < text.length && isDigit(text.charCodeAt(pos))) pos++;
69
+ while (pos < text.length && isDigit$1(text.charCodeAt(pos))) pos++;
70
70
  end = pos;
71
71
  } else scanError = 3;
72
72
  }
@@ -234,7 +234,7 @@ function createScanner(text, ignoreTrivia = false) {
234
234
  case 45:
235
235
  value += String.fromCharCode(code);
236
236
  pos++;
237
- if (pos === len || !isDigit(text.charCodeAt(pos))) return token = 16;
237
+ if (pos === len || !isDigit$1(text.charCodeAt(pos))) return token = 16;
238
238
  case 48:
239
239
  case 49:
240
240
  case 50:
@@ -306,7 +306,7 @@ function isWhiteSpace(ch) {
306
306
  function isLineBreak(ch) {
307
307
  return ch === 10 || ch === 13;
308
308
  }
309
- function isDigit(ch) {
309
+ function isDigit$1(ch) {
310
310
  return ch >= 48 && ch <= 57;
311
311
  }
312
312
  var CharacterCodes;
@@ -1275,11 +1275,11 @@ function applyEdits(text, edits) {
1275
1275
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1276
1276
  */
1277
1277
  function getLineColFromPtr(string, ptr) {
1278
- let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
1278
+ let lines = string.slice(0, ptr).split(/\r?\n/);
1279
1279
  return [lines.length, lines.pop().length + 1];
1280
1280
  }
1281
1281
  function makeCodeBlock(string, line, column) {
1282
- let lines = string.split(/\r\n|\n|\r/g);
1282
+ let lines = string.split(/\r?\n/);
1283
1283
  let codeblock = "";
1284
1284
  let numberLen = (Math.log10(line + 1) | 0) + 1;
1285
1285
  for (let i = line - 1; i <= line + 1; i++) {
@@ -1296,7 +1296,7 @@ function makeCodeBlock(string, line, column) {
1296
1296
  }
1297
1297
  return codeblock;
1298
1298
  }
1299
- var TomlError = class extends Error {
1299
+ var TomlError = class TomlError extends Error {
1300
1300
  line;
1301
1301
  column;
1302
1302
  codeblock;
@@ -1308,10 +1308,17 @@ var TomlError = class extends Error {
1308
1308
  this.column = column;
1309
1309
  this.codeblock = codeblock;
1310
1310
  }
1311
+ /** @internal */
1312
+ static x(message, ctx, ptr) {
1313
+ throw new TomlError(message, {
1314
+ toml: ctx.s,
1315
+ ptr: ptr ?? ctx.p
1316
+ });
1317
+ }
1311
1318
  };
1312
1319
 
1313
1320
  //#endregion
1314
- //#region node_modules/smol-toml/dist/util.js
1321
+ //#region node_modules/smol-toml/dist/primitive.js
1315
1322
  /*!
1316
1323
  * Copyright (c) Squirrel Chat et al., All rights reserved.
1317
1324
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1339,64 +1346,76 @@ var TomlError = class extends Error {
1339
1346
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1340
1347
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1341
1348
  */
1342
- function isEscaped(str, ptr) {
1343
- let i = 0;
1344
- while (str[ptr - ++i] === "\\");
1345
- return --i && i % 2;
1346
- }
1347
- function indexOfNewline(str, start = 0, end = str.length) {
1348
- let idx = str.indexOf("\n", start);
1349
- if (str[idx - 1] === "\r") idx--;
1350
- return idx <= end ? idx : -1;
1351
- }
1352
- function skipComment(str, ptr) {
1353
- for (let i = ptr; i < str.length; i++) {
1354
- let c = str[i];
1355
- if (c === "\n") return i;
1356
- if (c === "\r" && str[i + 1] === "\n") return i + 1;
1357
- if (c < " " && c !== " " || c === "") throw new TomlError("control characters are not allowed in comments", {
1358
- toml: str,
1359
- ptr
1360
- });
1349
+ /** @internal */
1350
+ function parseString(ctx) {
1351
+ let startPtr = ctx.p;
1352
+ let c = ctx.s.charCodeAt(ctx.p++);
1353
+ let first = c;
1354
+ let isLiteral = c === 39;
1355
+ let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);
1356
+ if (isMultiline) {
1357
+ if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 10) ctx.p++;
1358
+ else if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) ctx.p += 2;
1361
1359
  }
1362
- return str.length;
1363
- }
1364
- function skipVoid(str, ptr, banNewLines, banComments) {
1365
- let c;
1366
- while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n")) ptr++;
1367
- return banComments || c !== "#" ? ptr : skipVoid(str, skipComment(str, ptr), banNewLines);
1368
- }
1369
- function skipUntil(str, ptr, sep, end, banNewLines = false) {
1370
- if (!end) {
1371
- ptr = indexOfNewline(str, ptr);
1372
- return ptr < 0 ? str.length : ptr;
1373
- }
1374
- for (let i = ptr; i < str.length; i++) {
1375
- let c = str[i];
1376
- if (c === "#") i = indexOfNewline(str, i);
1377
- else if (c === sep) return i + 1;
1378
- else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) return i;
1379
- }
1380
- throw new TomlError("cannot find end of structure", {
1381
- toml: str,
1382
- ptr
1383
- });
1384
- }
1385
- function getStringEnd(str, seek) {
1386
- let first = str[seek];
1387
- let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
1388
- seek += target.length - 1;
1389
- do
1390
- seek = str.indexOf(target, ++seek);
1391
- while (seek > -1 && first !== "'" && isEscaped(str, seek));
1392
- if (seek > -1) {
1393
- seek += target.length;
1394
- if (target.length > 1) {
1395
- if (str[seek] === first) seek++;
1396
- if (str[seek] === first) seek++;
1360
+ let parsed = "";
1361
+ let sliceStart = ctx.p;
1362
+ let state = 0;
1363
+ for (; ctx.p < ctx.s.length; ctx.p++) {
1364
+ c = ctx.s.charCodeAt(ctx.p);
1365
+ if (isMultiline && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)) state = state && 3;
1366
+ else if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in strings", ctx);
1367
+ else if ((!state || state === 3) && c === first && (!isMultiline || ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first)) {
1368
+ if (isMultiline) {
1369
+ if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
1370
+ if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
1371
+ }
1372
+ if (!state) {
1373
+ let s = ctx.s.slice(sliceStart, ctx.p);
1374
+ parsed = parsed ? parsed + s : s;
1375
+ }
1376
+ ctx.p += isMultiline ? 3 : 1;
1377
+ return parsed;
1378
+ } else if (!state) {
1379
+ if (!isLiteral && c === 92) {
1380
+ parsed += ctx.s.slice(sliceStart, sliceStart = ctx.p);
1381
+ state = 1;
1382
+ }
1383
+ } else if (state === 1) {
1384
+ if (c === 120 || c === 117 || c === 85) {
1385
+ let errPtr = ctx.p++ - 1;
1386
+ let value = 0;
1387
+ let len = c === 120 ? 2 : c === 117 ? 4 : 8;
1388
+ for (let j = 0; j < len; j++, ctx.p++) {
1389
+ let hex = ctx.s.charCodeAt(ctx.p);
1390
+ let digit = hex >= 48 && hex <= 57 ? hex - 48 : hex >= 65 && hex <= 70 ? hex - 65 + 10 : hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1;
1391
+ if (digit < 0) TomlError.x("invalid non-hex character in unicode escape", ctx);
1392
+ value = value << 4 | digit;
1393
+ }
1394
+ if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) TomlError.x("invalid unicode escape", ctx, errPtr);
1395
+ parsed += String.fromCodePoint(value);
1396
+ sliceStart = ctx.p--;
1397
+ state = 0;
1398
+ } else if (isMultiline && (c === 32 || c === 9)) state = 2;
1399
+ else {
1400
+ if (c === 98) parsed += "\b";
1401
+ else if (c === 116) parsed += " ";
1402
+ else if (c === 110) parsed += "\n";
1403
+ else if (c === 102) parsed += "\f";
1404
+ else if (c === 114) parsed += "\r";
1405
+ else if (c === 101) parsed += "\x1B";
1406
+ else if (c === 34) parsed += "\"";
1407
+ else if (c === 92) parsed += "\\";
1408
+ else TomlError.x("unrecognised escape sequence", ctx);
1409
+ sliceStart = ctx.p + 1;
1410
+ state = 0;
1411
+ }
1412
+ } else if (c !== 32 && c !== 9) {
1413
+ if (state === 2) TomlError.x("invalid escape: only line-ending whitespace may be escaped", ctx, sliceStart);
1414
+ state = !isLiteral && c === 92 ? 1 : 0;
1415
+ sliceStart = ctx.p;
1397
1416
  }
1398
1417
  }
1399
- return seek;
1418
+ TomlError.x("unfinished string", ctx, startPtr);
1400
1419
  }
1401
1420
 
1402
1421
  //#endregion
@@ -1428,31 +1447,48 @@ function getStringEnd(str, seek) {
1428
1447
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1429
1448
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1430
1449
  */
1431
- let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}:\d{2}(?:\.\d+)?)?(Z|[-+]\d{2}:\d{2})?$/i;
1450
+ let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[Tt ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|z|[-+]\d{2}:\d{2})?$/i;
1432
1451
  var TomlDate = class TomlDate extends Date {
1433
1452
  #hasDate = false;
1434
1453
  #hasTime = false;
1435
1454
  #offset = null;
1436
- constructor(date) {
1455
+ constructor(date, fasttype, unsafeDelim) {
1437
1456
  let hasDate = true;
1438
1457
  let hasTime = true;
1439
1458
  let offset = "Z";
1459
+ let c;
1440
1460
  if (typeof date === "string") {
1441
- let match = date.match(DATE_TIME_RE);
1442
- if (match) {
1443
- if (!match[1]) {
1444
- hasDate = false;
1445
- date = `0000-01-01T${date}`;
1446
- }
1447
- hasTime = !!match[2];
1448
- hasTime && date[10] === " " && (date = date.replace(" ", "T"));
1449
- if (match[2] && +match[2] > 23) date = "";
1450
- else {
1451
- offset = match[3] || null;
1452
- date = date.toUpperCase();
1453
- if (!offset && hasTime) date += "Z";
1454
- }
1455
- } else date = "";
1461
+ if (fasttype) prep: {
1462
+ if (fasttype < 3) {
1463
+ if (+date.slice(11, 13) > 23) {
1464
+ date = "";
1465
+ break prep;
1466
+ }
1467
+ if (fasttype === 2) {
1468
+ offset = null;
1469
+ date += "Z";
1470
+ } else if ((c = date.charCodeAt(date.length - 1)) !== 90 && c !== 122) offset = date.slice(date.length - 6);
1471
+ if (unsafeDelim) date = date.slice(0, 10) + "T" + date.slice(11);
1472
+ } else if (fasttype === 4) date = +date.slice(0, 2) > 23 ? "" : `0000-01-01T${date}Z`;
1473
+ hasDate = fasttype !== 4;
1474
+ hasTime = fasttype !== 3;
1475
+ }
1476
+ else {
1477
+ let match = date.match(DATE_TIME_RE);
1478
+ if (match) {
1479
+ if (!match[1]) {
1480
+ hasDate = false;
1481
+ date = `0000-01-01T${date}`;
1482
+ }
1483
+ hasTime = !!match[2];
1484
+ hasTime && date[10] === " " && (date = date.replace(" ", "T"));
1485
+ if (match[2] && +match[2] > 23) date = "";
1486
+ else {
1487
+ offset = match[3] || null;
1488
+ if (!offset && hasTime) date += "Z";
1489
+ }
1490
+ } else date = "";
1491
+ }
1456
1492
  }
1457
1493
  super(date);
1458
1494
  if (!isNaN(this.getTime())) {
@@ -1481,7 +1517,7 @@ var TomlDate = class TomlDate extends Date {
1481
1517
  if (this.isDate()) return iso.slice(0, 10);
1482
1518
  if (this.isTime()) return iso.slice(11, 23);
1483
1519
  if (this.#offset === null) return iso.slice(0, -1);
1484
- if (this.#offset === "Z") return iso;
1520
+ if (this.#offset === "Z" || this.#offset === "z") return iso;
1485
1521
  let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
1486
1522
  offset = this.#offset[0] === "-" ? offset : -offset;
1487
1523
  return (/* @__PURE__ */ new Date(this.getTime() - offset * 6e4)).toISOString().slice(0, -1) + this.#offset;
@@ -1511,7 +1547,7 @@ var TomlDate = class TomlDate extends Date {
1511
1547
  };
1512
1548
 
1513
1549
  //#endregion
1514
- //#region node_modules/smol-toml/dist/primitive.js
1550
+ //#region node_modules/smol-toml/dist/extract.js
1515
1551
  /*!
1516
1552
  * Copyright (c) Squirrel Chat et al., All rights reserved.
1517
1553
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1539,117 +1575,147 @@ var TomlDate = class TomlDate extends Date {
1539
1575
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1540
1576
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1541
1577
  */
1542
- let INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
1543
- let FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
1544
- let LEADING_ZERO = /^[+-]?0[0-9_]/;
1545
- let ESCAPE_REGEX = /^[0-9a-f]{4,8}$/i;
1546
- let ESC_MAP = {
1547
- b: "\b",
1548
- t: " ",
1549
- n: "\n",
1550
- f: "\f",
1551
- r: "\r",
1552
- "\"": "\"",
1553
- "\\": "\\"
1554
- };
1555
- function parseString(str, ptr = 0, endPtr = str.length) {
1556
- let isLiteral = str[ptr] === "'";
1557
- let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1];
1558
- if (isMultiline) {
1559
- endPtr -= 2;
1560
- if (str[ptr += 2] === "\r") ptr++;
1561
- if (str[ptr] === "\n") ptr++;
1578
+ function isDigit(char, base = 10) {
1579
+ return base === 16 ? char > 47 && char < 58 || char > 64 && char < 71 || char > 96 && char < 103 : char > 47 && char < 48 + base;
1580
+ }
1581
+ function isEndOfValue(char, delim) {
1582
+ return char === 32 || char === 9 || char === 10 || char === 13 || delim && (char === delim || char === 44) || char === 35;
1583
+ }
1584
+ /** @internal */
1585
+ function extractValue(ctx, end) {
1586
+ let errPtr = ctx.p;
1587
+ let c = ctx.s.charCodeAt(ctx.p);
1588
+ if (c === 91 || c === 123) {
1589
+ ctx.d-- || TomlError.x("document contains excessively nested structures. aborting.", ctx);
1590
+ let value = c === 91 ? parseArray(ctx) : parseInlineTable(ctx);
1591
+ ctx.d++;
1592
+ return value;
1562
1593
  }
1563
- let tmp = 0;
1564
- let isEscape;
1565
- let parsed = "";
1566
- let sliceStart = ptr;
1567
- while (ptr < endPtr - 1) {
1568
- let c = str[ptr++];
1569
- if (c === "\n" || c === "\r" && str[ptr] === "\n") {
1570
- if (!isMultiline) throw new TomlError("newlines are not allowed in strings", {
1571
- toml: str,
1572
- ptr: ptr - 1
1573
- });
1574
- } else if (c < " " && c !== " " || c === "") throw new TomlError("control characters are not allowed in strings", {
1575
- toml: str,
1576
- ptr: ptr - 1
1577
- });
1578
- if (isEscape) {
1579
- isEscape = false;
1580
- if (c === "u" || c === "U") {
1581
- let code = str.slice(ptr, ptr += c === "u" ? 4 : 8);
1582
- if (!ESCAPE_REGEX.test(code)) throw new TomlError("invalid unicode escape", {
1583
- toml: str,
1584
- ptr: tmp
1585
- });
1586
- try {
1587
- parsed += String.fromCodePoint(parseInt(code, 16));
1588
- } catch {
1589
- throw new TomlError("invalid unicode escape", {
1590
- toml: str,
1591
- ptr: tmp
1592
- });
1593
- }
1594
- } else if (isMultiline && (c === "\n" || c === " " || c === " " || c === "\r")) {
1595
- ptr = skipVoid(str, ptr - 1, true);
1596
- if (str[ptr] !== "\n" && str[ptr] !== "\r") throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
1597
- toml: str,
1598
- ptr: tmp
1599
- });
1600
- ptr = skipVoid(str, ptr);
1601
- } else if (c in ESC_MAP) parsed += ESC_MAP[c];
1602
- else throw new TomlError("unrecognized escape sequence", {
1603
- toml: str,
1604
- ptr: tmp
1605
- });
1606
- sliceStart = ptr;
1607
- } else if (!isLiteral && c === "\\") {
1608
- tmp = ptr - 1;
1609
- isEscape = true;
1610
- parsed += str.slice(sliceStart, tmp);
1594
+ if (c === 34 || c === 39) return parseString(ctx);
1595
+ if (c === 116) {
1596
+ if (ctx.s.charCodeAt(++ctx.p) !== 114 || ctx.s.charCodeAt(++ctx.p) !== 117 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
1597
+ return ctx.p++, true;
1598
+ }
1599
+ if (c === 102) {
1600
+ if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 108 || ctx.s.charCodeAt(++ctx.p) !== 115 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
1601
+ return ctx.p++, false;
1602
+ }
1603
+ if (c === 43 || c === 45) return parseNumber(ctx, ctx.p, ctx.s.charCodeAt(++ctx.p), 44 - c, end);
1604
+ if (ctx.s.charCodeAt(ctx.p + 4) === 45 && ctx.s.charCodeAt(ctx.p + 7) === 45) return parseDate(ctx, c, end);
1605
+ if (ctx.s.charCodeAt(ctx.p + 2) === 58) return parseTime(ctx, c, end);
1606
+ return parseNumber(ctx, ctx.p, c, 0, end);
1607
+ }
1608
+ function parseNumber(ctx, startPtr, startChr, sign, endChr) {
1609
+ let c = startChr;
1610
+ let state = 0;
1611
+ let hasUnderscores = false;
1612
+ if (c === 105) {
1613
+ if (ctx.s.charCodeAt(++ctx.p) !== 110 || ctx.s.charCodeAt(++ctx.p) !== 102) TomlError.x("invalid value", ctx, startPtr);
1614
+ return ctx.p++, (sign || 1) / 0;
1615
+ }
1616
+ if (c === 110) {
1617
+ if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 110) TomlError.x("invalid value", ctx, startPtr);
1618
+ return ctx.p++, NaN;
1619
+ }
1620
+ if (c === 48) {
1621
+ if (++ctx.p >= ctx.s.length || isEndOfValue(c = ctx.s.charCodeAt(ctx.p), endChr)) return ctx.bi === true ? 0n : 0;
1622
+ if (!sign) {
1623
+ if (c === 120) return parseIntegerBaseN(ctx, startPtr, 16, endChr);
1624
+ else if (c === 98) return parseIntegerBaseN(ctx, startPtr, 2, endChr);
1625
+ else if (c === 111) return parseIntegerBaseN(ctx, startPtr, 8, endChr);
1626
+ }
1627
+ if (c === 46) state = 2;
1628
+ else if (c === 101 || c === 69) state = 4;
1629
+ else TomlError.x("illegal leading zero", ctx, startPtr);
1630
+ } else if (!isDigit(c)) TomlError.x("invalid value", ctx, startPtr);
1631
+ while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) {
1632
+ if (!state) state = 1;
1633
+ if (c === 95) {
1634
+ if (!(state & 1)) TomlError.x("illegal underscore", ctx);
1635
+ state += 11;
1636
+ hasUnderscores = true;
1637
+ } else if (state === 1 && c === 46) state = 2;
1638
+ else if ((state === 1 || state === 3) && (c === 101 || c === 69)) state = 4;
1639
+ else if (state === 4 && (c === 43 || c === 45)) state = 6;
1640
+ else if (!isDigit(c)) TomlError.x(`illegal character in numeric literal`, ctx);
1641
+ else if (state > 9) state -= 11;
1642
+ else if (!(state & 1)) state++;
1643
+ }
1644
+ if (!state) {
1645
+ let val = (startChr - 48) * (sign || 1);
1646
+ return ctx.bi === true ? BigInt(val) : val;
1647
+ }
1648
+ if (!(state & 1)) TomlError.x("unfinished numeric value", ctx, startPtr);
1649
+ let str = ctx.s.slice(startPtr, ctx.p);
1650
+ if (hasUnderscores) str = str.replaceAll("_", "");
1651
+ return state > 1 ? parseFloat(str) : parseInteger(ctx, str, 10, startPtr);
1652
+ }
1653
+ function parseIntegerBaseN(ctx, startPtr, base, endChr) {
1654
+ let c, underscore = 1;
1655
+ while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) if (c === 95) {
1656
+ if (underscore & 1) TomlError.x("illegal underscore", ctx);
1657
+ underscore = 3;
1658
+ } else if (!isDigit(c, base)) TomlError.x(`illegal character in numeric literal`, ctx);
1659
+ else if (underscore & 1) underscore--;
1660
+ if (underscore & 1) TomlError.x("unfinished numeric value", ctx);
1661
+ let str = ctx.s.slice(startPtr + 2, ctx.p);
1662
+ if (underscore) str = str.replaceAll("_", "");
1663
+ return parseInteger(ctx, str, base, startPtr);
1664
+ }
1665
+ function parseInteger(ctx, str, base, startPtr) {
1666
+ if (ctx.bi !== true) int: {
1667
+ let val = parseInt(str, base);
1668
+ if (!Number.isSafeInteger(val)) {
1669
+ if (ctx.bi) break int;
1670
+ TomlError.x("integer value cannot be represented losslessly", ctx, startPtr);
1611
1671
  }
1672
+ return val;
1673
+ }
1674
+ return base === 10 ? BigInt(str) : BigInt((base === 2 ? "0b" : base === 8 ? "0o" : "0x") + str);
1675
+ }
1676
+ function parseDate(ctx, c, endChr) {
1677
+ let startPtr = ctx.p++, unsafeSeparator;
1678
+ if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++))) return parseNumber(ctx, ctx.p = startPtr, c, 0, endChr);
1679
+ ctx.p += 5;
1680
+ if (!isDigit(ctx.s.charCodeAt(ctx.p++))) TomlError.x("invalid date-time: date part is malformed", ctx, startPtr);
1681
+ if (ctx.p >= ctx.s.length || ((c = ctx.s.charCodeAt(ctx.p)) !== 32 || (unsafeSeparator = true, !isDigit(ctx.s.charCodeAt(ctx.p + 1)))) && c !== 84 && c !== 116) return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 3, false, startPtr);
1682
+ if (ctx.s.charCodeAt(ctx.p += 3) !== 58) TomlError.x("invalid date-time: time part is malformed", ctx, startPtr);
1683
+ if (ctx.s.charCodeAt(ctx.p += 3) === 58) ctx.p += 3;
1684
+ if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
1685
+ if (c = ctx.s.charCodeAt(ctx.p)) {
1686
+ if (c === 90 || c === 122) return readDate(ctx, ctx.s.slice(startPtr, ++ctx.p), 1, unsafeSeparator, startPtr, "[+00:00]");
1687
+ if (c === 43 || c === 45) return readDate(ctx, ctx.s.slice(startPtr, ctx.p += 6), 1, unsafeSeparator, startPtr, !ctx.ld && "[" + ctx.s.slice(ctx.p - 6, ctx.p) + "]");
1688
+ }
1689
+ return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 2, unsafeSeparator, startPtr);
1690
+ }
1691
+ function parseTime(ctx, c, endChr) {
1692
+ let start = ctx.p;
1693
+ if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(++ctx.p))) return parseNumber(ctx, --ctx.p, c, 0, endChr);
1694
+ if (ctx.s.charCodeAt(ctx.p += 4) === 58) ctx.p += 3;
1695
+ if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
1696
+ return readDate(ctx, ctx.s.slice(start, ctx.p), 4, false, start);
1697
+ }
1698
+ function readDate(ctx, str, type, unsafeDelim, errPtr, temporalSuffix) {
1699
+ if (ctx.ld) {
1700
+ let date = new TomlDate(str, type, unsafeDelim);
1701
+ if (!date.isValid()) TomlError.x("invalid date", ctx, errPtr);
1702
+ return date;
1612
1703
  }
1613
- return parsed + str.slice(sliceStart, endPtr - 1);
1614
- }
1615
- function parseValue(value, toml, ptr, integersAsBigInt) {
1616
- if (value === "true") return true;
1617
- if (value === "false") return false;
1618
- if (value === "-inf") return -Infinity;
1619
- if (value === "inf" || value === "+inf") return Infinity;
1620
- if (value === "nan" || value === "+nan" || value === "-nan") return NaN;
1621
- if (value === "-0") return integersAsBigInt ? 0n : 0;
1622
- let isInt = INT_REGEX.test(value);
1623
- if (isInt || FLOAT_REGEX.test(value)) {
1624
- if (LEADING_ZERO.test(value)) throw new TomlError("leading zeroes are not allowed", {
1625
- toml,
1626
- ptr
1627
- });
1628
- value = value.replace(/_/g, "");
1629
- let numeric = +value;
1630
- if (isNaN(numeric)) throw new TomlError("invalid number", {
1631
- toml,
1632
- ptr
1633
- });
1634
- if (isInt) {
1635
- if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) throw new TomlError("integer value cannot be represented losslessly", {
1636
- toml,
1637
- ptr
1638
- });
1639
- if (isInt || integersAsBigInt === true) numeric = BigInt(value);
1704
+ try {
1705
+ if (temporalSuffix) str += temporalSuffix;
1706
+ switch (type) {
1707
+ case 1: return Temporal.ZonedDateTime.from(str);
1708
+ case 2: return Temporal.PlainDateTime.from(str);
1709
+ case 3: return Temporal.PlainDate.from(str);
1710
+ case 4: return Temporal.PlainTime.from(str);
1640
1711
  }
1641
- return numeric;
1712
+ } catch (e) {
1713
+ TomlError.x(e instanceof Error ? e.message : "" + e, ctx, errPtr);
1642
1714
  }
1643
- const date = new TomlDate(value);
1644
- if (!date.isValid()) throw new TomlError("invalid value", {
1645
- toml,
1646
- ptr
1647
- });
1648
- return date;
1649
1715
  }
1650
1716
 
1651
1717
  //#endregion
1652
- //#region node_modules/smol-toml/dist/extract.js
1718
+ //#region node_modules/smol-toml/dist/util.js
1653
1719
  /*!
1654
1720
  * Copyright (c) Squirrel Chat et al., All rights reserved.
1655
1721
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1677,66 +1743,26 @@ function parseValue(value, toml, ptr, integersAsBigInt) {
1677
1743
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1678
1744
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1679
1745
  */
1680
- function sliceAndTrimEndOf(str, startPtr, endPtr, allowNewLines) {
1681
- let value = str.slice(startPtr, endPtr);
1682
- let commentIdx = value.indexOf("#");
1683
- if (commentIdx > -1) {
1684
- skipComment(str, commentIdx);
1685
- value = value.slice(0, commentIdx);
1686
- }
1687
- let trimmed = value.trimEnd();
1688
- if (!allowNewLines) {
1689
- let newlineIdx = value.indexOf("\n", trimmed.length);
1690
- if (newlineIdx > -1) throw new TomlError("newlines are not allowed in inline tables", {
1691
- toml: str,
1692
- ptr: startPtr + newlineIdx
1693
- });
1694
- }
1695
- return [trimmed, commentIdx];
1696
- }
1697
- function extractValue(str, ptr, end, depth, integersAsBigInt) {
1698
- if (depth === 0) throw new TomlError("document contains excessively nested structures. aborting.", {
1699
- toml: str,
1700
- ptr
1701
- });
1702
- let c = str[ptr];
1703
- if (c === "[" || c === "{") {
1704
- let [value, endPtr] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
1705
- let newPtr = end ? skipUntil(str, endPtr, ",", end) : endPtr;
1706
- if (endPtr - newPtr && end === "}") {
1707
- let nextNewLine = indexOfNewline(str, endPtr, newPtr);
1708
- if (nextNewLine > -1) throw new TomlError("newlines are not allowed in inline tables", {
1709
- toml: str,
1710
- ptr: nextNewLine
1711
- });
1712
- }
1713
- return [value, newPtr];
1714
- }
1715
- let endPtr;
1716
- if (c === "\"" || c === "'") {
1717
- endPtr = getStringEnd(str, ptr);
1718
- let parsed = parseString(str, ptr, endPtr);
1719
- if (end) {
1720
- endPtr = skipVoid(str, endPtr, end !== "]");
1721
- if (str[endPtr] && str[endPtr] !== "," && str[endPtr] !== end && str[endPtr] !== "\n" && str[endPtr] !== "\r") throw new TomlError("unexpected character encountered", {
1722
- toml: str,
1723
- ptr: endPtr
1724
- });
1725
- endPtr += +(str[endPtr] === ",");
1746
+ /** @internal */
1747
+ function skipComment(ctx) {
1748
+ for (; ctx.p < ctx.s.length; ctx.p++) {
1749
+ let c = ctx.s.charCodeAt(ctx.p);
1750
+ if (c === 10) break;
1751
+ if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) {
1752
+ ctx.p++;
1753
+ break;
1726
1754
  }
1727
- return [parsed, endPtr];
1755
+ if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in comments", ctx);
1728
1756
  }
1729
- endPtr = skipUntil(str, ptr, ",", end);
1730
- let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ","), end === "]");
1731
- if (!slice[0]) throw new TomlError("incomplete key-value declaration: no value specified", {
1732
- toml: str,
1733
- ptr
1734
- });
1735
- if (end && slice[1] > -1) {
1736
- endPtr = skipVoid(str, ptr + slice[1]);
1737
- endPtr += +(str[endPtr] === ",");
1757
+ }
1758
+ /** @internal */
1759
+ function skipVoid(ctx, banNewLines, banComments) {
1760
+ let c;
1761
+ while (ctx.p < ctx.s.length) {
1762
+ while (ctx.p < ctx.s.length && ((c = ctx.s.charCodeAt(ctx.p)) === 32 || c === 9 || !banNewLines && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10))) ctx.p++;
1763
+ if (banComments || c !== 35) break;
1764
+ skipComment(ctx);
1738
1765
  }
1739
- return [parseValue(slice[0], str, ptr, integersAsBigInt), endPtr];
1740
1766
  }
1741
1767
 
1742
1768
  //#endregion
@@ -1768,132 +1794,99 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) {
1768
1794
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1769
1795
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1770
1796
  */
1771
- let KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
1772
- function parseKey(str, ptr, end = "=") {
1773
- let dot = ptr - 1;
1797
+ /** @internal */
1798
+ function parseKey(ctx, end = 61) {
1799
+ let startPtr;
1800
+ let state = 0;
1774
1801
  let parsed = [];
1775
- let endPtr = str.indexOf(end, ptr);
1776
- if (endPtr < 0) throw new TomlError("incomplete key-value: cannot find end of key", {
1777
- toml: str,
1778
- ptr
1779
- });
1780
- do {
1781
- let c = str[ptr = ++dot];
1782
- if (c !== " " && c !== " ") {
1783
- if (c === "\"" || c === "'") {
1784
- if (c === str[ptr + 1] && c === str[ptr + 2]) throw new TomlError("multiline strings are not allowed in keys", {
1785
- toml: str,
1786
- ptr
1787
- });
1788
- let eos = getStringEnd(str, ptr);
1789
- if (eos < 0) throw new TomlError("unfinished string encountered", {
1790
- toml: str,
1791
- ptr
1792
- });
1793
- dot = str.indexOf(".", eos);
1794
- let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
1795
- let newLine = indexOfNewline(strEnd);
1796
- if (newLine > -1) throw new TomlError("newlines are not allowed in keys", {
1797
- toml: str,
1798
- ptr: ptr + dot + newLine
1799
- });
1800
- if (strEnd.trimStart()) throw new TomlError("found extra tokens after the string part", {
1801
- toml: str,
1802
- ptr: eos
1803
- });
1804
- if (endPtr < eos) {
1805
- endPtr = str.indexOf(end, eos);
1806
- if (endPtr < 0) throw new TomlError("incomplete key-value: cannot find end of key", {
1807
- toml: str,
1808
- ptr
1809
- });
1810
- }
1811
- parsed.push(parseString(str, ptr, eos));
1812
- } else {
1813
- dot = str.indexOf(".", ptr);
1814
- let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
1815
- if (!KEY_PART_RE.test(part)) throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
1816
- toml: str,
1817
- ptr
1818
- });
1819
- parsed.push(part.trimEnd());
1802
+ let sliceStart;
1803
+ let c = ctx.s.charCodeAt(startPtr = ctx.p);
1804
+ do
1805
+ if (c === end) {
1806
+ if (!state) TomlError.x("unexpected end of key", ctx);
1807
+ if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
1808
+ return ctx.p++, parsed;
1809
+ } else if (c === 46) {
1810
+ if (!state) TomlError.x("illegal empty bare key", ctx);
1811
+ if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
1812
+ state = 0;
1813
+ } else if (!state && (c === 34 || c === 39)) {
1814
+ if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) TomlError.x("illegal quoted key: multiline strings are not allowed", ctx);
1815
+ parsed.push(parseString(ctx));
1816
+ state = 2;
1817
+ ctx.p--;
1818
+ } else if (c === 32 || c === 9) {
1819
+ if (state === 1) {
1820
+ parsed.push(ctx.s.slice(sliceStart, ctx.p));
1821
+ state = 2;
1820
1822
  }
1823
+ } else if (state === 2 || c < 48 && c !== 45 || c > 57 && c < 65 || c > 90 && c < 97 && c !== 95 || c > 122) TomlError.x("illegal character in key", ctx);
1824
+ else if (!state) {
1825
+ state = 1;
1826
+ sliceStart = ctx.p;
1821
1827
  }
1822
- } while (dot + 1 && dot < endPtr);
1823
- return [parsed, skipVoid(str, endPtr + 1, true, true)];
1828
+ while (c = ctx.s.charCodeAt(++ctx.p));
1829
+ TomlError.x("incomplete key-value: cannot find end of key", ctx, startPtr);
1824
1830
  }
1825
- function parseInlineTable(str, ptr, depth, integersAsBigInt) {
1826
- let res = {};
1831
+ /** @internal */
1832
+ function parseInlineTable(ctx) {
1833
+ let startPtr = ctx.p++;
1834
+ let res = Object.create(null);
1827
1835
  let seen = /* @__PURE__ */ new Set();
1828
1836
  let c;
1829
- let comma = 0;
1830
- ptr++;
1831
- while ((c = str[ptr++]) !== "}" && c) {
1832
- let err = {
1833
- toml: str,
1834
- ptr: ptr - 1
1835
- };
1836
- if (c === "\n") throw new TomlError("newlines are not allowed in inline tables", err);
1837
- else if (c === "#") throw new TomlError("inline tables cannot contain comments", err);
1838
- else if (c === ",") throw new TomlError("expected key-value, found comma", err);
1839
- else if (c !== " " && c !== " ") {
1840
- let k;
1841
- let t = res;
1842
- let hasOwn = false;
1843
- let [key, keyEndPtr] = parseKey(str, ptr - 1);
1844
- for (let i = 0; i < key.length; i++) {
1845
- if (i) t = hasOwn ? t[k] : t[k] = {};
1846
- k = key[i];
1847
- if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) throw new TomlError("trying to redefine an already defined value", {
1848
- toml: str,
1849
- ptr
1850
- });
1851
- if (!hasOwn && k === "__proto__") Object.defineProperty(t, k, {
1852
- enumerable: true,
1853
- configurable: true,
1854
- writable: true
1855
- });
1837
+ while (ctx.p < ctx.s.length) {
1838
+ skipVoid(ctx);
1839
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 125) {
1840
+ ctx.p++;
1841
+ return res;
1842
+ }
1843
+ let k;
1844
+ let t = res;
1845
+ let hasOwn = false;
1846
+ let errPtr = ctx.p;
1847
+ let key = parseKey(ctx);
1848
+ for (let i = 0; i < key.length; i++) {
1849
+ if (i) t = hasOwn ? t[k] : t[k] = Object.create(null);
1850
+ k = key[i];
1851
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
1852
+ let unsafe = k === "__proto__";
1853
+ if (ctx.uk && (unsafe || k === "constructor")) {
1854
+ t = ctx.uk !== 1 && TomlError.x("document contains an unsafe property", ctx, errPtr);
1855
+ break;
1856
1856
  }
1857
- if (hasOwn) throw new TomlError("trying to redefine an already defined value", {
1858
- toml: str,
1859
- ptr
1857
+ if (!hasOwn && unsafe) Object.defineProperty(t, k, {
1858
+ enumerable: true,
1859
+ configurable: true,
1860
+ writable: true
1860
1861
  });
1861
- let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
1862
- seen.add(value);
1863
- t[k] = value;
1864
- ptr = valueEndPtr;
1865
- comma = str[ptr - 1] === "," ? ptr - 1 : 0;
1866
1862
  }
1867
- }
1868
- if (comma) throw new TomlError("trailing commas are not allowed in inline tables", {
1869
- toml: str,
1870
- ptr: comma
1871
- });
1872
- if (!c) throw new TomlError("unfinished table encountered", {
1873
- toml: str,
1874
- ptr
1875
- });
1876
- return [res, ptr];
1877
- }
1878
- function parseArray(str, ptr, depth, integersAsBigInt) {
1863
+ if (hasOwn) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
1864
+ skipVoid(ctx, true, true);
1865
+ let value = extractValue(ctx, 125);
1866
+ if (t && typeof (t[k] = value) === "object") seen.add(value);
1867
+ skipVoid(ctx);
1868
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 125) return res;
1869
+ if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
1870
+ }
1871
+ TomlError.x("unfinished table", ctx, startPtr);
1872
+ }
1873
+ /** @internal */
1874
+ function parseArray(ctx) {
1875
+ let startPtr = ctx.p++;
1879
1876
  let res = [];
1880
1877
  let c;
1881
- ptr++;
1882
- while ((c = str[ptr++]) !== "]" && c) if (c === ",") throw new TomlError("expected value, found comma", {
1883
- toml: str,
1884
- ptr: ptr - 1
1885
- });
1886
- else if (c === "#") ptr = skipComment(str, ptr);
1887
- else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
1888
- let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
1889
- res.push(e[0]);
1890
- ptr = e[1];
1891
- }
1892
- if (!c) throw new TomlError("unfinished array encountered", {
1893
- toml: str,
1894
- ptr
1895
- });
1896
- return [res, ptr];
1878
+ while (ctx.p < ctx.s.length) {
1879
+ skipVoid(ctx);
1880
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 93) {
1881
+ ctx.p++;
1882
+ return res;
1883
+ }
1884
+ res.push(extractValue(ctx, 93));
1885
+ skipVoid(ctx);
1886
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 93) return res;
1887
+ if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
1888
+ }
1889
+ TomlError.x("unfinished array", ctx, startPtr);
1897
1890
  }
1898
1891
 
1899
1892
  //#endregion
@@ -1925,7 +1918,7 @@ function parseArray(str, ptr, depth, integersAsBigInt) {
1925
1918
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1926
1919
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1927
1920
  */
1928
- function peekTable(key, table, meta, type) {
1921
+ function peekTable(ctx, key, table, meta, type) {
1929
1922
  let t = table;
1930
1923
  let m = meta;
1931
1924
  let k;
@@ -1933,7 +1926,7 @@ function peekTable(key, table, meta, type) {
1933
1926
  let state;
1934
1927
  for (let i = 0; i < key.length; i++) {
1935
1928
  if (i) {
1936
- t = hasOwn ? t[k] : t[k] = {};
1929
+ t = hasOwn ? t[k] : t[k] = Object.create(null);
1937
1930
  m = (state = m[k]).c;
1938
1931
  if (type === 0 && (state.t === 1 || state.t === 2)) return null;
1939
1932
  if (state.t === 2) {
@@ -1945,7 +1938,9 @@ function peekTable(key, table, meta, type) {
1945
1938
  k = key[i];
1946
1939
  if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) return null;
1947
1940
  if (!hasOwn) {
1948
- if (k === "__proto__") {
1941
+ let unsafe = k === "__proto__";
1942
+ if (ctx.uk && (unsafe || k === "constructor")) return false;
1943
+ if (unsafe) {
1949
1944
  Object.defineProperty(t, k, {
1950
1945
  enumerable: true,
1951
1946
  configurable: true,
@@ -1961,7 +1956,7 @@ function peekTable(key, table, meta, type) {
1961
1956
  t: i < key.length - 1 && type === 2 ? 3 : type,
1962
1957
  d: false,
1963
1958
  i: 0,
1964
- c: {}
1959
+ c: Object.create(null)
1965
1960
  };
1966
1961
  }
1967
1962
  }
@@ -1972,17 +1967,17 @@ function peekTable(key, table, meta, type) {
1972
1967
  state.d = true;
1973
1968
  t[k] = [];
1974
1969
  }
1975
- t[k].push(t = {});
1970
+ t[k].push(t = Object.create(null));
1976
1971
  state.c[state.i++] = state = {
1977
1972
  t: 1,
1978
1973
  d: false,
1979
1974
  i: 0,
1980
- c: {}
1975
+ c: Object.create(null)
1981
1976
  };
1982
1977
  }
1983
1978
  if (state.d) return null;
1984
1979
  state.d = true;
1985
- if (type === 1) t = hasOwn ? t[k] : t[k] = {};
1980
+ if (type === 1) t = hasOwn ? t[k] : t[k] = Object.create(null);
1986
1981
  else if (type === 0 && hasOwn) return null;
1987
1982
  return [
1988
1983
  k,
@@ -1990,47 +1985,55 @@ function peekTable(key, table, meta, type) {
1990
1985
  state.c
1991
1986
  ];
1992
1987
  }
1993
- function parse$1(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
1994
- let res = {};
1995
- let meta = {};
1988
+ function validateTablePeek(ctx, peek, ptr) {
1989
+ if (peek === null || ctx.uk === 2) TomlError.x(peek === null ? "trying to redefine an already defined table or value" : "document contains an unsafe property", ctx, ptr);
1990
+ }
1991
+ function parse$1(toml, options = {}) {
1992
+ let ctx = {
1993
+ s: toml,
1994
+ p: 0,
1995
+ d: options.maxDepth ?? 1e3,
1996
+ bi: options.integersAsBigInt ?? false,
1997
+ ld: options.useLegacyDate ?? true,
1998
+ uk: options.unsafeKeyBehaviour === "throw" ? 2 : options.unsafeKeyBehaviour === "drop" ? 1 : 0
1999
+ };
2000
+ let res = Object.create(null);
2001
+ let meta = Object.create(null);
2002
+ let tmp;
2003
+ let skipping = false;
1996
2004
  let tbl = res;
1997
2005
  let m = meta;
1998
- for (let ptr = skipVoid(toml, 0); ptr < toml.length;) {
1999
- if (toml[ptr] === "[") {
2000
- let isTableArray = toml[++ptr] === "[";
2001
- let k = parseKey(toml, ptr += +isTableArray, "]");
2006
+ if (toml.charCodeAt(0) === 65279) ctx.p++;
2007
+ skipVoid(ctx);
2008
+ while (ctx.p < toml.length) {
2009
+ if (toml.charCodeAt(ctx.p) === 91) {
2010
+ let isTableArray = toml.charCodeAt(++ctx.p) === 91;
2011
+ tmp = ctx.p += +isTableArray;
2012
+ skipping = false;
2013
+ let k = parseKey(ctx, 93);
2002
2014
  if (isTableArray) {
2003
- if (toml[k[1] - 1] !== "]") throw new TomlError("expected end of table declaration", {
2004
- toml,
2005
- ptr: k[1] - 1
2006
- });
2007
- k[1]++;
2015
+ if (toml.charCodeAt(ctx.p) !== 93) TomlError.x("expected end of table array declaration", ctx);
2016
+ ctx.p++;
2017
+ }
2018
+ let p = peekTable(ctx, k, res, meta, isTableArray ? 2 : 1);
2019
+ if (!p) {
2020
+ validateTablePeek(ctx, p, tmp);
2021
+ skipping = true;
2022
+ } else {
2023
+ m = p[2];
2024
+ tbl = p[1];
2008
2025
  }
2009
- let p = peekTable(k[0], res, meta, isTableArray ? 2 : 1);
2010
- if (!p) throw new TomlError("trying to redefine an already defined table or value", {
2011
- toml,
2012
- ptr
2013
- });
2014
- m = p[2];
2015
- tbl = p[1];
2016
- ptr = k[1];
2017
2026
  } else {
2018
- let k = parseKey(toml, ptr);
2019
- let p = peekTable(k[0], tbl, m, 0);
2020
- if (!p) throw new TomlError("trying to redefine an already defined table or value", {
2021
- toml,
2022
- ptr
2023
- });
2024
- let v = extractValue(toml, k[1], void 0, maxDepth, integersAsBigInt);
2025
- p[1][p[0]] = v[0];
2026
- ptr = v[1];
2027
+ tmp = ctx.p;
2028
+ let p = peekTable(ctx, parseKey(ctx), tbl, m, 0);
2029
+ if (!p && !skipping) validateTablePeek(ctx, p, tmp);
2030
+ skipVoid(ctx, true, true);
2031
+ let v = extractValue(ctx, void 0);
2032
+ if (p && !skipping) p[1][p[0]] = v;
2027
2033
  }
2028
- ptr = skipVoid(toml, ptr, true);
2029
- if (toml[ptr] && toml[ptr] !== "\n" && toml[ptr] !== "\r") throw new TomlError("each key-value declaration must be followed by an end-of-line", {
2030
- toml,
2031
- ptr
2032
- });
2033
- ptr = skipVoid(toml, ptr);
2034
+ skipVoid(ctx, true);
2035
+ if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 10 && (tmp !== 13 || toml.charCodeAt(ctx.p + 1) !== 10)) TomlError.x("each key-value declaration must be followed by an end-of-line", ctx);
2036
+ skipVoid(ctx);
2034
2037
  }
2035
2038
  return res;
2036
2039
  }
@@ -2065,11 +2068,20 @@ function parse$1(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
2065
2068
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2066
2069
  */
2067
2070
  let BARE_KEY = /^[a-z0-9-_]+$/i;
2071
+ let HAS_WELLFORMED = !!"".isWellFormed;
2068
2072
  function extendedTypeOf(obj) {
2069
2073
  let type = typeof obj;
2070
2074
  if (type === "object") {
2071
2075
  if (Array.isArray(obj)) return "array";
2072
- if (obj instanceof Date) return "date";
2076
+ if (typeof obj.getUTCDate === "function" && obj instanceof Date) return "date";
2077
+ if (globalThis.Temporal) {
2078
+ if (obj.until) {
2079
+ if (obj instanceof Temporal.ZonedDateTime) return "temporal/tz+uc";
2080
+ if (obj instanceof Temporal.PlainDateTime || obj instanceof Temporal.PlainDate) return "temporal/uc";
2081
+ if (obj instanceof Temporal.PlainTime || obj instanceof Temporal.Instant) return "temporal";
2082
+ if (obj instanceof Temporal.PlainYearMonth) return "temporal/x";
2083
+ } else if (obj.toPlainDate && obj instanceof Temporal.PlainMonthDay || obj.negated && obj instanceof Temporal.Duration) return "temporal/x";
2084
+ }
2073
2085
  }
2074
2086
  return type;
2075
2087
  }
@@ -2077,61 +2089,79 @@ function isArrayOfTables(obj) {
2077
2089
  for (let i = 0; i < obj.length; i++) if (extendedTypeOf(obj[i]) !== "object") return false;
2078
2090
  return obj.length != 0;
2079
2091
  }
2092
+ function formatWellFormedStringUnchecked(s) {
2093
+ return JSON.stringify(s).replaceAll("", "\\u007f");
2094
+ }
2080
2095
  function formatString(s) {
2081
- return JSON.stringify(s).replace(/\x7f/g, "\\u007f");
2096
+ return formatWellFormedStringUnchecked(HAS_WELLFORMED ? s.toWellFormed() : s);
2097
+ }
2098
+ function formatKey(s) {
2099
+ if (BARE_KEY.test(s)) return s;
2100
+ if (HAS_WELLFORMED && !s.isWellFormed()) throw new RangeError("key contains illegal lone surrogates");
2101
+ return formatWellFormedStringUnchecked(s);
2082
2102
  }
2083
- function stringifyValue(val, type, depth, numberAsFloat) {
2103
+ function stringifyValue(val, type, depth, numberAsFloat, strictTemporal) {
2084
2104
  if (depth === 0) throw new Error("Could not stringify the object: maximum object depth exceeded");
2085
- if (type === "number") {
2086
- if (isNaN(val)) return "nan";
2087
- if (val === Infinity) return "inf";
2088
- if (val === -Infinity) return "-inf";
2089
- if (numberAsFloat && Number.isInteger(val)) return val.toFixed(1);
2090
- return val.toString();
2091
- }
2092
- if (type === "bigint" || type === "boolean") return val.toString();
2093
- if (type === "string") return formatString(val);
2094
- if (type === "date") {
2095
- if (isNaN(val.getTime())) throw new TypeError("cannot serialize invalid date");
2096
- return val.toISOString();
2097
- }
2098
- if (type === "object") return stringifyInlineTable(val, depth, numberAsFloat);
2099
- if (type === "array") return stringifyArray(val, depth, numberAsFloat);
2100
- }
2101
- function stringifyInlineTable(obj, depth, numberAsFloat) {
2105
+ switch (type) {
2106
+ case "number":
2107
+ if (isNaN(val)) return "nan";
2108
+ if (val === Infinity) return "inf";
2109
+ if (val === -Infinity) return "-inf";
2110
+ if (Number.isInteger(val) && (numberAsFloat || !Number.isSafeInteger(val))) return val.toFixed(1);
2111
+ case "bigint":
2112
+ case "boolean":
2113
+ case "temporal": return val.toString();
2114
+ case "string": return formatString(val);
2115
+ case "date":
2116
+ if (isNaN(val.getTime())) throw new TypeError("cannot serialize invalid date");
2117
+ return val.toISOString();
2118
+ case "object": return stringifyInlineTable(val, depth, numberAsFloat, strictTemporal);
2119
+ case "array": return stringifyArray(val, depth, numberAsFloat, strictTemporal);
2120
+ case "temporal/tz+uc": if (strictTemporal) {
2121
+ let tz = val.timeZoneId;
2122
+ let tzc = tz.charCodeAt(0);
2123
+ if (tzc !== 43 && tzc !== 45 && (tzc !== 85 && tzc !== 71 && tzc !== 90 && tzc !== 69 || tz !== "UTC" && tz !== "UCT" && tz !== "Universal" && tz !== "Zulu" && !tz.startsWith("GMT") && tz !== "Greenwich" && !tz.startsWith("Etc/"))) throw new TypeError("Temporal objects with an IANA timezone are not allowed in Temporal strict mode");
2124
+ }
2125
+ case "temporal/uc":
2126
+ if (strictTemporal && val.calendarId !== "iso8601") throw new TypeError("Temporal objects with a non-default calendar are not allowed in Temporal strict mode");
2127
+ return val.toString({
2128
+ calendarName: "never",
2129
+ timeZoneName: "never"
2130
+ });
2131
+ case "temporal/x": throw new TypeError("Unsupported " + val[Symbol.toStringTag]);
2132
+ }
2133
+ }
2134
+ function stringifyInlineTable(obj, depth, numberAsFloat, strictTemporal) {
2102
2135
  let keys = Object.keys(obj);
2103
2136
  if (keys.length === 0) return "{}";
2104
2137
  let res = "{ ";
2105
2138
  for (let i = 0; i < keys.length; i++) {
2106
2139
  let k = keys[i];
2107
2140
  if (i) res += ", ";
2108
- res += BARE_KEY.test(k) ? k : formatString(k);
2109
- res += " = ";
2110
- res += stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat);
2141
+ res += formatKey(k) + " = " + stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat, strictTemporal);
2111
2142
  }
2112
2143
  return res + " }";
2113
2144
  }
2114
- function stringifyArray(array, depth, numberAsFloat) {
2145
+ function stringifyArray(array, depth, numberAsFloat, strictTemporal) {
2115
2146
  if (array.length === 0) return "[]";
2116
2147
  let res = "[ ";
2117
2148
  for (let i = 0; i < array.length; i++) {
2118
2149
  if (i) res += ", ";
2119
2150
  if (array[i] === null || array[i] === void 0) throw new TypeError("arrays cannot contain null or undefined values");
2120
- res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat);
2151
+ res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat, strictTemporal);
2121
2152
  }
2122
2153
  return res + " ]";
2123
2154
  }
2124
- function stringifyArrayTable(array, key, depth, numberAsFloat) {
2155
+ function stringifyArrayTable(array, key, depth, numberAsFloat, strictTemporal) {
2125
2156
  if (depth === 0) throw new Error("Could not stringify the object: maximum object depth exceeded");
2126
2157
  let res = "";
2127
2158
  for (let i = 0; i < array.length; i++) {
2128
- res += `[[${key}]]\n`;
2129
- res += stringifyTable(array[i], key, depth, numberAsFloat);
2130
- res += "\n\n";
2159
+ res += `${res && "\n"}[[${key}]]\n`;
2160
+ res += stringifyTable(0, array[i], key, depth, numberAsFloat, strictTemporal);
2131
2161
  }
2132
2162
  return res;
2133
2163
  }
2134
- function stringifyTable(obj, prefix, depth, numberAsFloat) {
2164
+ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat, strictTemporal) {
2135
2165
  if (depth === 0) throw new Error("Could not stringify the object: maximum object depth exceeded");
2136
2166
  let preamble = "";
2137
2167
  let tables = "";
@@ -2141,39 +2171,78 @@ function stringifyTable(obj, prefix, depth, numberAsFloat) {
2141
2171
  if (obj[k] !== null && obj[k] !== void 0) {
2142
2172
  let type = extendedTypeOf(obj[k]);
2143
2173
  if (type === "symbol" || type === "function") throw new TypeError(`cannot serialize values of type '${type}'`);
2144
- let key = BARE_KEY.test(k) ? k : formatString(k);
2145
- if (type === "array" && isArrayOfTables(obj[k])) tables += stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
2174
+ let key = formatKey(k);
2175
+ if (type === "array" && isArrayOfTables(obj[k])) tables += (tables && "\n") + stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat, strictTemporal);
2146
2176
  else if (type === "object") {
2147
2177
  let tblKey = prefix ? `${prefix}.${key}` : key;
2148
- tables += `[${tblKey}]\n`;
2149
- tables += stringifyTable(obj[k], tblKey, depth - 1, numberAsFloat);
2150
- tables += "\n\n";
2178
+ tables += (tables && "\n") + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat, strictTemporal);
2151
2179
  } else {
2152
2180
  preamble += key;
2153
2181
  preamble += " = ";
2154
- preamble += stringifyValue(obj[k], type, depth, numberAsFloat);
2182
+ preamble += stringifyValue(obj[k], type, depth, numberAsFloat, strictTemporal);
2155
2183
  preamble += "\n";
2156
2184
  }
2157
2185
  }
2158
2186
  }
2159
- return `${preamble}\n${tables}`.trim();
2187
+ if (tableKey && (preamble || !tables)) preamble = preamble ? `[${tableKey}]\n${preamble}` : `[${tableKey}]`;
2188
+ return preamble && tables ? `${preamble}\n${tables}` : preamble || tables;
2160
2189
  }
2161
- function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
2190
+ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false, strictTemporal = false } = {}) {
2162
2191
  if (extendedTypeOf(obj) !== "object") throw new TypeError("stringify can only be called with an object");
2163
- return stringifyTable(obj, "", maxDepth, numbersAsFloat);
2192
+ let str = stringifyTable(0, obj, "", maxDepth, numbersAsFloat, strictTemporal);
2193
+ if (str[str.length - 1] !== "\n") return str + "\n";
2194
+ return str;
2164
2195
  }
2165
2196
 
2197
+ //#endregion
2198
+ //#region node_modules/smol-toml/dist/index.js
2199
+ /*!
2200
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2201
+ * SPDX-License-Identifier: BSD-3-Clause
2202
+ *
2203
+ * Redistribution and use in source and binary forms, with or without
2204
+ * modification, are permitted provided that the following conditions are met:
2205
+ *
2206
+ * 1. Redistributions of source code must retain the above copyright notice, this
2207
+ * list of conditions and the following disclaimer.
2208
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2209
+ * this list of conditions and the following disclaimer in the
2210
+ * documentation and/or other materials provided with the distribution.
2211
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2212
+ * may be used to endorse or promote products derived from this software without
2213
+ * specific prior written permission.
2214
+ *
2215
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2216
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2217
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2218
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2219
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2220
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2221
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2222
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2223
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2224
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2225
+ */
2226
+
2166
2227
  //#endregion
2167
2228
  //#region src/config.js
2168
2229
  async function assertSafePath(path) {
2169
- let current = parse(resolve(path)).root;
2170
- for (const part of resolve(path).slice(current.length).split(/[\\/]/).filter(Boolean)) {
2230
+ const full = resolve(path);
2231
+ let current = parse(full).root;
2232
+ for (const part of full.slice(current.length).split(/[\\/]/).filter(Boolean)) {
2171
2233
  current = join(current, part);
2234
+ let info;
2172
2235
  try {
2173
- if ((await lstat(current)).isSymbolicLink()) throw new Error(`Refusing symbolic link: ${current}`);
2236
+ info = await lstat(current);
2174
2237
  } catch (error) {
2175
- if (error.code !== "ENOENT") throw error;
2238
+ if (error.code === "ENOENT") return;
2239
+ throw error;
2176
2240
  }
2241
+ if (!info.isSymbolicLink()) continue;
2242
+ if (current === full) throw new Error(`Refusing symbolic link: ${current}`);
2243
+ await stat(current).catch((error) => {
2244
+ throw error.code === "ENOENT" ? /* @__PURE__ */ new Error(`Refusing dangling symbolic link: ${current}`) : error;
2245
+ });
2177
2246
  }
2178
2247
  }
2179
2248
  async function readConfig(path) {
@@ -2188,6 +2257,8 @@ async function readConfig(path) {
2188
2257
  function object(value) {
2189
2258
  return value !== null && typeof value === "object" && !Array.isArray(value);
2190
2259
  }
2260
+ const plain$1 = (value) => Array.isArray(value) ? value.map(plain$1) : value !== null && typeof value === "object" && Object.getPrototypeOf(value) === null ? Object.fromEntries(Object.entries(value).map(([key, item]) => [key, plain$1(item)])) : value;
2261
+ const parseToml = (text) => plain$1(parse$1(text));
2191
2262
  function parseJson(text, path) {
2192
2263
  const errors = [];
2193
2264
  const value = parse$2(text ?? "{}", errors, { allowTrailingComma: true });
@@ -2212,26 +2283,123 @@ function editJson(text, changes, path) {
2212
2283
  parseJson(next, path);
2213
2284
  return next;
2214
2285
  }
2215
- function addToml(text, desired, path) {
2216
- let existing;
2286
+ function updateToml(text, desired, path, obsolete = []) {
2287
+ const before = text ?? "";
2217
2288
  try {
2218
- existing = parse$1(text ?? "");
2289
+ parseToml(before);
2219
2290
  } catch {
2220
2291
  throw new Error(`Invalid TOML in ${path}; nothing overwritten.`);
2221
2292
  }
2222
- const missing = {};
2223
- for (const [key, value] of Object.entries(desired)) if (!Object.hasOwn(existing, key)) missing[key] = value;
2224
- else if (!isDeepStrictEqual(existing[key], value)) throw new Error(`Conflicting ${key} in ${path}. Review it manually; nothing overwritten.`);
2225
- if (!Object.keys(missing).length) return text ?? "";
2226
- const scalars = Object.fromEntries(Object.entries(missing).filter(([, value]) => !object(value)));
2227
- const tables = Object.fromEntries(Object.entries(missing).filter(([, value]) => object(value)));
2228
- const parts = [];
2229
- if (Object.keys(scalars).length) parts.push(stringify(scalars));
2230
- if ((text ?? "").trim()) parts.push(text);
2231
- if (Object.keys(tables).length) parts.push(stringify(tables));
2232
- const next = `${parts.map((part) => part.replace(/\s+$/, "")).join("\n\n")}\n`;
2233
- parse$1(next);
2234
- return next;
2293
+ const eol = before.includes("\r\n") ? "\r\n" : "\n";
2294
+ const keyText = (key) => /^[\w-]+$/.test(key) ? key : JSON.stringify(key);
2295
+ const lines = before.split(/\r?\n/);
2296
+ const valueAt = (value, keys) => keys.reduce((parent, key) => parent?.[key], value);
2297
+ const merge = (old, next) => object(next) ? Object.fromEntries(Object.entries({
2298
+ ...object(old) ? old : {},
2299
+ ...next
2300
+ }).map(([key, value]) => [key, Object.hasOwn(next, key) ? merge(old?.[key], next[key]) : value])) : next;
2301
+ const inline = (value) => value instanceof Date ? stringify({ value }).trim().replace(/^value\s*=\s*/, "") : object(value) ? `{ ${Object.entries(value).map(([key, item]) => `${JSON.stringify(key)} = ${inline(item)}`).join(", ")} }` : Array.isArray(value) ? `[${value.map(inline).join(", ")}]` : stringify({ value }).trim().replace(/^value\s*=\s*/, "");
2302
+ const statements = [];
2303
+ let section = [];
2304
+ for (let i = 0; i < lines.length; i++) {
2305
+ if (!lines[i].trim() || lines[i].trimStart().startsWith("#")) {
2306
+ statements.push({
2307
+ text: lines[i],
2308
+ section
2309
+ });
2310
+ continue;
2311
+ }
2312
+ let block = lines[i], parsed;
2313
+ for (;;) try {
2314
+ parsed = parseToml(block);
2315
+ break;
2316
+ } catch {
2317
+ if (++i >= lines.length) throw new Error(`Cannot safely update TOML in ${path}.`);
2318
+ block += eol + lines[i];
2319
+ }
2320
+ if (block.trimStart().startsWith("[")) {
2321
+ section = [];
2322
+ let cursor = parsed;
2323
+ while (object(cursor) && Object.keys(cursor).length === 1) {
2324
+ const key = Object.keys(cursor)[0];
2325
+ section.push(key);
2326
+ cursor = cursor[key];
2327
+ }
2328
+ statements.push({
2329
+ text: block,
2330
+ section,
2331
+ header: true,
2332
+ array: Array.isArray(cursor)
2333
+ });
2334
+ continue;
2335
+ }
2336
+ let equal = 0, keyQuote = null;
2337
+ for (; equal < block.length; equal++) {
2338
+ const char = block[equal];
2339
+ if (keyQuote === "\"" && char === "\\") {
2340
+ equal++;
2341
+ continue;
2342
+ }
2343
+ if (keyQuote) {
2344
+ if (char === keyQuote) keyQuote = null;
2345
+ } else if (char === "\"" || char === "'") keyQuote = char;
2346
+ else if (char === "=") break;
2347
+ }
2348
+ const rawKey = block.slice(0, equal).trim();
2349
+ let cursor = parseToml(`${rawKey} = 0`), keys = [];
2350
+ while (object(cursor)) {
2351
+ const key = Object.keys(cursor)[0];
2352
+ keys.push(key);
2353
+ cursor = cursor[key];
2354
+ }
2355
+ const full = [...section, ...keys];
2356
+ if (obsolete.includes(full.join("."))) continue;
2357
+ const next = valueAt(desired, full);
2358
+ if (next !== void 0 && !isDeepStrictEqual(valueAt(parsed, keys), merge(valueAt(parsed, keys), next))) {
2359
+ let comment = "", quote = null;
2360
+ if (!block.includes(eol)) for (let j = equal + 1; j < block.length; j++) {
2361
+ const char = block[j];
2362
+ if (quote === "\"" && char === "\\") {
2363
+ j++;
2364
+ continue;
2365
+ }
2366
+ if (quote) {
2367
+ if (char === quote) quote = null;
2368
+ } else if (char === "\"" || char === "'") quote = char;
2369
+ else if (char === "#") {
2370
+ comment = ` ${block.slice(j)}`;
2371
+ break;
2372
+ }
2373
+ }
2374
+ block = `${block.slice(0, equal + 1)} ${inline(merge(valueAt(parsed, keys), next))}${comment}`;
2375
+ }
2376
+ statements.push({
2377
+ text: block,
2378
+ section
2379
+ });
2380
+ }
2381
+ const leaves = (value, prefix = []) => Object.entries(value).flatMap(([key, item]) => object(item) ? leaves(item, [...prefix, key]) : [[[...prefix, key], item]]);
2382
+ for (const [keys, value] of leaves(desired)) {
2383
+ const current = parseToml(statements.map((item) => item.text).join(eol));
2384
+ if (isDeepStrictEqual(valueAt(current, keys), value)) continue;
2385
+ let header = -1, prefix = [];
2386
+ statements.forEach((item, index) => {
2387
+ if (item.header && !item.array && item.section.length < keys.length && item.section.every((key, i) => key === keys[i]) && item.section.length > prefix.length) {
2388
+ header = index;
2389
+ prefix = item.section;
2390
+ }
2391
+ });
2392
+ let end = statements.findIndex((item, index) => index > header && item.header);
2393
+ if (end === -1) end = statements.length;
2394
+ statements.splice(end, 0, {
2395
+ text: `${keys.slice(prefix.length).map(keyText).join(".")} = ${inline(value)}`,
2396
+ section: prefix
2397
+ });
2398
+ }
2399
+ const after = statements.map((item) => item.text).join(eol);
2400
+ const result = parseToml(after);
2401
+ for (const [keys, value] of leaves(desired)) if (!isDeepStrictEqual(valueAt(result, keys), value)) throw new Error(`Cannot safely update ${keys.join(".")} in ${path}.`);
2402
+ return after === before ? before : `${after.replace(/\s+$/, "")}${eol}`;
2235
2403
  }
2236
2404
  function sha256(text) {
2237
2405
  return createHash("sha256").update(text, "utf8").digest("hex");
@@ -2311,8 +2479,7 @@ const RUNNABLE = [
2311
2479
  "pi"
2312
2480
  ];
2313
2481
  const CONTEXT_WINDOW = 262144;
2314
- const MAX_INPUT = 24e4;
2315
- const MAX_OUTPUT = 16384;
2482
+ const MAX_OUTPUT = 32768;
2316
2483
  const EFFORTS = [
2317
2484
  "none",
2318
2485
  "low",
@@ -2330,7 +2497,6 @@ const OPENCODE_MODEL = {
2330
2497
  },
2331
2498
  limit: {
2332
2499
  context: CONTEXT_WINDOW,
2333
- input: MAX_INPUT,
2334
2500
  output: MAX_OUTPUT
2335
2501
  },
2336
2502
  options: { reasoningEffort: "medium" },
@@ -2349,7 +2515,6 @@ const OPENCODE_V2_PROVIDER = {
2349
2515
  },
2350
2516
  limit: {
2351
2517
  context: CONTEXT_WINDOW,
2352
- input: MAX_INPUT,
2353
2518
  output: MAX_OUTPUT
2354
2519
  },
2355
2520
  settings: { reasoningEffort: "medium" },
@@ -2372,7 +2537,8 @@ const PI_MODEL = {
2372
2537
  xhigh: "xhigh",
2373
2538
  max: null
2374
2539
  },
2375
- contextWindow: CONTEXT_WINDOW
2540
+ contextWindow: CONTEXT_WINDOW,
2541
+ maxTokens: MAX_OUTPUT
2376
2542
  };
2377
2543
  async function exists(path) {
2378
2544
  try {
@@ -2497,7 +2663,34 @@ async function planAssistant(assistant) {
2497
2663
  const storedKey = await openCodeHasKey(assistant.authFile);
2498
2664
  await json(hasJsonc ? "opencode.jsonc" : "opencode.json", (existing) => {
2499
2665
  v2 = Object.hasOwn(existing, "providers");
2500
- if (v2) return [[["providers", "callstack.ai"], OPENCODE_V2_PROVIDER]];
2666
+ if (v2) return [
2667
+ [[
2668
+ "providers",
2669
+ "callstack.ai",
2670
+ "name"
2671
+ ], OPENCODE_V2_PROVIDER.name],
2672
+ [[
2673
+ "providers",
2674
+ "callstack.ai",
2675
+ "package"
2676
+ ], OPENCODE_V2_PROVIDER.package],
2677
+ [[
2678
+ "providers",
2679
+ "callstack.ai",
2680
+ "settings",
2681
+ "baseURL"
2682
+ ], BASE_URL],
2683
+ ...Object.entries(OPENCODE_V2_PROVIDER.models[MODEL]).map(([key, value]) => [[
2684
+ "providers",
2685
+ "callstack.ai",
2686
+ "models",
2687
+ MODEL,
2688
+ key
2689
+ ], key === "settings" ? {
2690
+ ...existing.providers?.["callstack.ai"]?.models?.[MODEL]?.settings,
2691
+ ...value
2692
+ } : value])
2693
+ ];
2501
2694
  return [
2502
2695
  [[
2503
2696
  "provider",
@@ -2515,18 +2708,22 @@ async function planAssistant(assistant) {
2515
2708
  "options",
2516
2709
  "baseURL"
2517
2710
  ], BASE_URL],
2518
- ...storedKey ? [] : [[[
2711
+ ...storedKey || existing.provider?.["callstack.ai"]?.options?.apiKey ? [] : [[[
2519
2712
  "provider",
2520
2713
  "callstack.ai",
2521
2714
  "options",
2522
2715
  "apiKey"
2523
2716
  ], "{env:CALLSTACK_AUTH_TOKEN}"]],
2524
- [[
2717
+ ...Object.entries(OPENCODE_MODEL).map(([key, value]) => [[
2525
2718
  "provider",
2526
2719
  "callstack.ai",
2527
2720
  "models",
2528
- MODEL
2529
- ], OPENCODE_MODEL]
2721
+ MODEL,
2722
+ key
2723
+ ], key === "options" ? {
2724
+ ...existing.provider?.["callstack.ai"]?.models?.[MODEL]?.options,
2725
+ ...value
2726
+ } : value])
2530
2727
  ];
2531
2728
  });
2532
2729
  if (v2) changes[0].steps = ["OpenCode 2 stores provider keys itself: run /connect in OpenCode, pick callstack.ai → \"Manually enter API Key\", and paste your Callstack key."];
@@ -2557,9 +2754,14 @@ async function planAssistant(assistant) {
2557
2754
  "providers",
2558
2755
  "callstack",
2559
2756
  "models"
2560
- ], models.some((model) => model.id === "callstack/Apex") ? models.map((model) => model.id === "callstack/Apex" ? PI_MODEL : model) : [...models, PI_MODEL]]
2757
+ ], models.some((model) => model.id === "callstack/Apex") ? models.map((model) => model.id === "callstack/Apex" ? {
2758
+ ...model,
2759
+ ...PI_MODEL,
2760
+ ...model.compat ? { compat: Object.fromEntries(Object.entries(model.compat).filter(([key]) => key !== "reasoningEffortMap")) } : {}
2761
+ } : model) : [...models, PI_MODEL]]
2561
2762
  ];
2562
2763
  });
2764
+ await json("settings.json", [[["modelThinkingLevels", `callstack/${MODEL}`], "medium"]]);
2563
2765
  break;
2564
2766
  case "claude":
2565
2767
  await json("settings.json", [[["env", "CLAUDE_CODE_ATTRIBUTION_HEADER"], "0"]]);
@@ -2567,7 +2769,7 @@ async function planAssistant(assistant) {
2567
2769
  case "codex": {
2568
2770
  const path = join(assistant.directory, "callstack_ai.config.toml");
2569
2771
  const before = await readConfig(path);
2570
- const after = addToml(before, {
2772
+ const after = updateToml(before, {
2571
2773
  model_provider: "callstack_ai",
2572
2774
  model: MODEL,
2573
2775
  model_context_window: CONTEXT_WINDOW,
@@ -2579,7 +2781,7 @@ async function planAssistant(assistant) {
2579
2781
  wire_api: "responses",
2580
2782
  requires_openai_auth: false
2581
2783
  } }
2582
- }, path);
2784
+ }, path, ["model_max_output_tokens", "model_auto_compact_token_limit"]);
2583
2785
  changes.push({
2584
2786
  path,
2585
2787
  before,
@@ -2609,7 +2811,9 @@ function launchOptions(id, env = process.env) {
2609
2811
  "--provider",
2610
2812
  "callstack",
2611
2813
  "--model",
2612
- MODEL
2814
+ MODEL,
2815
+ "--thinking",
2816
+ "medium"
2613
2817
  ],
2614
2818
  env: childEnv
2615
2819
  };
@@ -2629,7 +2833,9 @@ function launchOptions(id, env = process.env) {
2629
2833
  ANTHROPIC_DEFAULT_OPUS_MODEL: MODEL,
2630
2834
  ANTHROPIC_DEFAULT_SONNET_MODEL: MODEL,
2631
2835
  ANTHROPIC_DEFAULT_HAIKU_MODEL: MODEL,
2632
- CLAUDE_CODE_SUBAGENT_MODEL: MODEL
2836
+ CLAUDE_CODE_SUBAGENT_MODEL: MODEL,
2837
+ CLAUDE_CODE_MAX_CONTEXT_TOKENS: String(CONTEXT_WINDOW),
2838
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: String(MAX_OUTPUT)
2633
2839
  });
2634
2840
  return {
2635
2841
  args: ["--model", MODEL],
@@ -2663,7 +2869,11 @@ const AI_SDK_SNIPPET = [
2663
2869
  ` baseURL: '${BASE_URL}',`,
2664
2870
  " apiKey: process.env.CALLSTACK_AUTH_TOKEN,",
2665
2871
  "});",
2666
- `// apex('${MODEL}') with generateText / streamText.`,
2872
+ "const requestOptions = {",
2873
+ ` model: apex('${MODEL}'),`,
2874
+ ` maxOutputTokens: ${MAX_OUTPUT},`,
2875
+ "};",
2876
+ "// Pass requestOptions with your prompt to generateText / streamText.",
2667
2877
  `// Reasoning effort (${EFFORTS.join(", ")}):`,
2668
2878
  "// providerOptions: { callstack: { reasoningEffort: 'medium' } }"
2669
2879
  ];
@@ -2674,11 +2884,7 @@ const MANUAL = {
2674
2884
  "Keep the generated apiKey secret reference; add this object to its models array:",
2675
2885
  ...COPILOT_MODEL.split("\n")
2676
2886
  ],
2677
- "ai-sdk": [
2678
- "Apex CLI never writes your key into a project. Keep it in CALLSTACK_AUTH_TOKEN (for example in a .env that git ignores) and create the provider with:",
2679
- ...AI_SDK_SNIPPET,
2680
- `Eve: set modelContextWindowTokens: ${CONTEXT_WINDOW} on defineAgent, or compaction will fail to compile.`
2681
- ]
2887
+ "ai-sdk": ["Apex CLI never writes your key into a project. Keep it in CALLSTACK_AUTH_TOKEN (for example in a .env that git ignores) and create the provider with:", ...AI_SDK_SNIPPET]
2682
2888
  };
2683
2889
  const MANUAL_IDS = Object.keys(MANUAL);
2684
2890
 
@@ -3657,7 +3863,7 @@ const maskChanges = (changes, secret) => changes.map((change) => ({
3657
3863
  //#region src/diff.js
3658
3864
  function readValues(text, format) {
3659
3865
  if (format === "toml") try {
3660
- return parse$1(text);
3866
+ return parseToml(text);
3661
3867
  } catch {
3662
3868
  throw new Error("Invalid TOML while reading values.");
3663
3869
  }