@o3co/ts.hocon 1.10.0 → 1.11.0

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.
@@ -513,36 +513,48 @@ function deepMergeHoconValues(base, overlay) {
513
513
  // src/internal/resolver/include-loader.ts
514
514
  import { createRequire } from "module";
515
515
  import * as nodePath from "path";
516
+ import { pathToFileURL } from "url";
517
+
518
+ // src/internal/strip-bom.ts
519
+ function stripBom(input) {
520
+ return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
521
+ }
516
522
 
517
523
  // src/internal/properties/properties.ts
518
524
  function nestPairs(pairs) {
519
525
  const root = /* @__PURE__ */ Object.create(null);
520
- const sorted = [...pairs].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
521
- for (const [key, value] of sorted) {
522
- setNested(root, key.split("."), value);
526
+ const sorted = [...pairs].sort(([a], [b]) => compareSegments(a, b));
527
+ for (const [segments, value] of sorted) {
528
+ setNested(root, segments, value);
523
529
  }
524
530
  return root;
525
531
  }
526
- var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
532
+ function compareSegments(a, b) {
533
+ const n = Math.min(a.length, b.length);
534
+ for (let i = 0; i < n; i++) {
535
+ const x = a[i];
536
+ const y = b[i];
537
+ if (x !== y) return x < y ? -1 : 1;
538
+ }
539
+ return a.length - b.length;
540
+ }
541
+ function pathKey(segments) {
542
+ return JSON.stringify(segments);
543
+ }
527
544
  function setNested(obj, segments, value) {
528
545
  let current = obj;
529
546
  for (let i = 0; i < segments.length - 1; i++) {
530
547
  const seg = segments[i];
531
- if (seg === void 0 || DANGEROUS_KEYS.has(seg)) return;
532
548
  if (!(seg in current) || typeof current[seg] !== "object" || current[seg] === null) {
533
549
  current[seg] = /* @__PURE__ */ Object.create(null);
534
550
  }
535
551
  current = current[seg];
536
552
  }
537
553
  const last = segments[segments.length - 1];
538
- if (last === void 0 || DANGEROUS_KEYS.has(last)) return;
539
554
  if (typeof current[last] === "object" && current[last] !== null) return;
540
555
  current[last] = value;
541
556
  }
542
557
 
543
- // src/internal/resolver/include-loader.ts
544
- var _require = createRequire(import.meta.url);
545
-
546
558
  // src/value/numeric-array.ts
547
559
  function numericObjectToArray(value) {
548
560
  if (value.kind !== "object") return null;
@@ -1130,10 +1142,10 @@ var Config = class _Config {
1130
1142
  }
1131
1143
  if (v.kind === "object") {
1132
1144
  const converted = numericObjectToArray(v);
1133
- if (converted !== null) return converted.map(hoconToJs);
1145
+ if (converted !== null) return converted.map((item) => hoconToJs(item));
1134
1146
  }
1135
1147
  if (v.kind !== "array") throw new ConfigError(`expected array at ${path}`, path);
1136
- return v.items.map(hoconToJs);
1148
+ return v.items.map((item) => hoconToJs(item));
1137
1149
  }
1138
1150
  has(path) {
1139
1151
  return this.lookupNode(path) !== void 0;
@@ -1261,8 +1273,52 @@ var Config = class _Config {
1261
1273
  originDescription: this._originDescription
1262
1274
  });
1263
1275
  }
1264
- toObject() {
1265
- return hoconToJs(this.root);
1276
+ /**
1277
+ * The whole config as plain JS data: objects, arrays, strings, numbers,
1278
+ * booleans and `null`.
1279
+ *
1280
+ * Keys are reproduced exactly as the config carries them, `__proto__`,
1281
+ * `constructor` and `prototype` included: each is defined as an **own data
1282
+ * property**, so the returned object's prototype is always
1283
+ * `Object.prototype`, and this call writes nothing to the global one.
1284
+ *
1285
+ * ### Passing the result to other code
1286
+ *
1287
+ * A config file — especially a `.properties` file or an env namespace you
1288
+ * merged in — can therefore hand you an own `__proto__` key, and what happens
1289
+ * next depends entirely on how the consumer copies it:
1290
+ *
1291
+ * ```ts
1292
+ * const data = cfg.toObject()
1293
+ * { ...data } // safe — own properties are copied as data
1294
+ * structuredClone(data) // safe
1295
+ * Object.assign({}, data) // NOT safe — [[Set]] on the {} target hits
1296
+ * // Object.prototype's __proto__ setter: the key
1297
+ * // vanishes and config data becomes the result's
1298
+ * // prototype
1299
+ * deepMerge({}, data) // NOT safe — a naive recursive merge reads
1300
+ * // target['__proto__'], gets Object.prototype,
1301
+ * // and writes to it: global pollution
1302
+ * for (const k in data) … // prefer Object.entries / Object.keys
1303
+ * ```
1304
+ *
1305
+ * Those two hazards come from the **destination** object's prototype, so no
1306
+ * option here can disarm them — copy with spread or `structuredClone` instead.
1307
+ *
1308
+ * What `{ nullPrototype: true }` does give you is a result that inherits
1309
+ * nothing: every object comes back with a `null` prototype, so reading
1310
+ * `x.__proto__`, `x.constructor` or `x.toString` yields config data or
1311
+ * `undefined` rather than something from `Object.prototype`, and code that
1312
+ * merges *into* this object cannot climb out of it. Keys are all still
1313
+ * present. The trade-off is the usual one for prototype-less objects: not
1314
+ * `instanceof Object`, and no `hasOwnProperty` of their own.
1315
+ *
1316
+ * Numbers follow the JS number model, so an integer wider than 2^53 rounds
1317
+ * here even when the config holds it exactly — read those with
1318
+ * {@link Config.getString} instead.
1319
+ */
1320
+ toObject(opts) {
1321
+ return hoconToJs(this.root, opts?.nullPrototype === true);
1266
1322
  }
1267
1323
  /**
1268
1324
  * @internal Test-only: renders this resolved Config's value tree as canonical
@@ -1374,16 +1430,25 @@ function scalarToJs(raw, valueType) {
1374
1430
  return raw;
1375
1431
  }
1376
1432
  }
1377
- function hoconToJs(v) {
1433
+ function hoconToJs(v, nullPrototype = false) {
1378
1434
  switch (v.kind) {
1379
1435
  case "scalar":
1380
1436
  return scalarToJs(v.raw, v.valueType);
1381
1437
  case "array":
1382
- return v.items.map(hoconToJs);
1438
+ return v.items.map((item) => hoconToJs(item, nullPrototype));
1383
1439
  case "object": {
1384
- const obj = /* @__PURE__ */ Object.create(null);
1385
- for (const [k, val] of v.fields) obj[k] = hoconToJs(val);
1386
- return Object.assign({}, obj);
1440
+ const entries = Array.from(v.fields, ([k, val]) => [k, hoconToJs(val, nullPrototype)]);
1441
+ if (nullPrototype) {
1442
+ const obj = /* @__PURE__ */ Object.create(null);
1443
+ for (const [k, val] of entries) Object.defineProperty(obj, k, {
1444
+ value: val,
1445
+ writable: true,
1446
+ enumerable: true,
1447
+ configurable: true
1448
+ });
1449
+ return obj;
1450
+ }
1451
+ return Object.fromEntries(entries);
1387
1452
  }
1388
1453
  }
1389
1454
  }
@@ -1472,6 +1537,8 @@ function fromMap(values, originDescription) {
1472
1537
  const root = { kind: "object", fields };
1473
1538
  return Config._fromResolvedValue(root, { originDescription });
1474
1539
  }
1540
+ var INT64_MAX = 9223372036854775807n;
1541
+ var INT64_MIN = -9223372036854775808n;
1475
1542
  function coerceObject(obj, atPath) {
1476
1543
  const fields = /* @__PURE__ */ new Map();
1477
1544
  for (const [k, v] of Object.entries(obj)) {
@@ -1500,14 +1567,14 @@ function coerceValue(v, atPath) {
1500
1567
  atPath
1501
1568
  );
1502
1569
  }
1503
- return { kind: "scalar", raw: String(v), valueType: "number" };
1570
+ return { kind: "scalar", raw: Object.is(v, -0) ? "-0" : String(v), valueType: "number" };
1504
1571
  }
1505
1572
  case "boolean":
1506
1573
  return { kind: "scalar", raw: v ? "true" : "false", valueType: "boolean" };
1507
1574
  case "bigint": {
1508
- if (v > BigInt(Number.MAX_SAFE_INTEGER) || v < BigInt(Number.MIN_SAFE_INTEGER)) {
1575
+ if (v > INT64_MAX || v < INT64_MIN) {
1509
1576
  throw new ConfigError(
1510
- `fromMap: bigint ${v} exceeds Number.MAX_SAFE_INTEGER (not representable as HOCON number) at path "${atPath}"`,
1577
+ `fromMap: integer ${v} is out of int64 range (HOCON integers are int64; spec F0.5) at path "${atPath}"`,
1511
1578
  atPath
1512
1579
  );
1513
1580
  }
@@ -1548,11 +1615,12 @@ function loadEnv(opts = {}) {
1548
1615
  const value = source[name];
1549
1616
  if (value === void 0) continue;
1550
1617
  const path = toPath(name.slice(prefix.length));
1551
- const prev = seen.get(path);
1618
+ const key = pathKey(path);
1619
+ const prev = seen.get(key);
1552
1620
  if (prev !== void 0) {
1553
- throw new ConfigError(`loadEnv: ${prev} and ${name} both map to "${path}"`, path);
1621
+ throw new ConfigError(`loadEnv: ${prev} and ${name} both map to "${path.join(".")}"`, path.join("."));
1554
1622
  }
1555
- seen.set(path, name);
1623
+ seen.set(key, name);
1556
1624
  pairs.push([path, value]);
1557
1625
  }
1558
1626
  return fromMap(nestPairs(pairs), opts.originDescription ?? "environment variables");
@@ -1561,7 +1629,7 @@ function parseDotEnv(input, opts = {}) {
1561
1629
  const origin = opts.originDescription ?? ".env";
1562
1630
  const prefix = opts.prefix ?? "";
1563
1631
  const pairs = [];
1564
- const lines = input.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
1632
+ const lines = stripBom(input).replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
1565
1633
  for (let i = 0; i < lines.length; i++) {
1566
1634
  const raw = (lines[i] ?? "").trim();
1567
1635
  if (raw === "" || raw.startsWith("#")) continue;
@@ -1577,11 +1645,14 @@ function parseDotEnv(input, opts = {}) {
1577
1645
  return fromMap(nestPairs(pairs), origin);
1578
1646
  }
1579
1647
  function toPath(name) {
1580
- const segs = name.split(SEPARATOR).map((s) => s.toLowerCase());
1648
+ const segs = name.split(SEPARATOR).map(asciiLower);
1581
1649
  if (segs.some((s) => s === "")) {
1582
1650
  throw new ConfigError(`env: "${name}" produces an empty path segment`, name);
1583
1651
  }
1584
- return segs.join(".");
1652
+ return segs;
1653
+ }
1654
+ function asciiLower(s) {
1655
+ return s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
1585
1656
  }
1586
1657
  function dotEnvValue(v, origin, line, name) {
1587
1658
  const fail = (msg) => {
@@ -550,8 +550,12 @@ function deepMergeHoconValues(base, overlay) {
550
550
  // src/internal/resolver/include-loader.ts
551
551
  var import_node_module = require("module");
552
552
  var nodePath = __toESM(require("path"), 1);
553
- var import_meta = {};
554
- var _require = (0, import_node_module.createRequire)(import_meta.url);
553
+ var import_node_url = require("url");
554
+
555
+ // src/internal/strip-bom.ts
556
+ function stripBom(input) {
557
+ return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
558
+ }
555
559
 
556
560
  // src/value/numeric-array.ts
557
561
  function numericObjectToArray(value) {
@@ -1140,10 +1144,10 @@ var Config = class _Config {
1140
1144
  }
1141
1145
  if (v.kind === "object") {
1142
1146
  const converted = numericObjectToArray(v);
1143
- if (converted !== null) return converted.map(hoconToJs);
1147
+ if (converted !== null) return converted.map((item) => hoconToJs(item));
1144
1148
  }
1145
1149
  if (v.kind !== "array") throw new ConfigError(`expected array at ${path}`, path);
1146
- return v.items.map(hoconToJs);
1150
+ return v.items.map((item) => hoconToJs(item));
1147
1151
  }
1148
1152
  has(path) {
1149
1153
  return this.lookupNode(path) !== void 0;
@@ -1271,8 +1275,52 @@ var Config = class _Config {
1271
1275
  originDescription: this._originDescription
1272
1276
  });
1273
1277
  }
1274
- toObject() {
1275
- return hoconToJs(this.root);
1278
+ /**
1279
+ * The whole config as plain JS data: objects, arrays, strings, numbers,
1280
+ * booleans and `null`.
1281
+ *
1282
+ * Keys are reproduced exactly as the config carries them, `__proto__`,
1283
+ * `constructor` and `prototype` included: each is defined as an **own data
1284
+ * property**, so the returned object's prototype is always
1285
+ * `Object.prototype`, and this call writes nothing to the global one.
1286
+ *
1287
+ * ### Passing the result to other code
1288
+ *
1289
+ * A config file — especially a `.properties` file or an env namespace you
1290
+ * merged in — can therefore hand you an own `__proto__` key, and what happens
1291
+ * next depends entirely on how the consumer copies it:
1292
+ *
1293
+ * ```ts
1294
+ * const data = cfg.toObject()
1295
+ * { ...data } // safe — own properties are copied as data
1296
+ * structuredClone(data) // safe
1297
+ * Object.assign({}, data) // NOT safe — [[Set]] on the {} target hits
1298
+ * // Object.prototype's __proto__ setter: the key
1299
+ * // vanishes and config data becomes the result's
1300
+ * // prototype
1301
+ * deepMerge({}, data) // NOT safe — a naive recursive merge reads
1302
+ * // target['__proto__'], gets Object.prototype,
1303
+ * // and writes to it: global pollution
1304
+ * for (const k in data) … // prefer Object.entries / Object.keys
1305
+ * ```
1306
+ *
1307
+ * Those two hazards come from the **destination** object's prototype, so no
1308
+ * option here can disarm them — copy with spread or `structuredClone` instead.
1309
+ *
1310
+ * What `{ nullPrototype: true }` does give you is a result that inherits
1311
+ * nothing: every object comes back with a `null` prototype, so reading
1312
+ * `x.__proto__`, `x.constructor` or `x.toString` yields config data or
1313
+ * `undefined` rather than something from `Object.prototype`, and code that
1314
+ * merges *into* this object cannot climb out of it. Keys are all still
1315
+ * present. The trade-off is the usual one for prototype-less objects: not
1316
+ * `instanceof Object`, and no `hasOwnProperty` of their own.
1317
+ *
1318
+ * Numbers follow the JS number model, so an integer wider than 2^53 rounds
1319
+ * here even when the config holds it exactly — read those with
1320
+ * {@link Config.getString} instead.
1321
+ */
1322
+ toObject(opts) {
1323
+ return hoconToJs(this.root, opts?.nullPrototype === true);
1276
1324
  }
1277
1325
  /**
1278
1326
  * @internal Test-only: renders this resolved Config's value tree as canonical
@@ -1384,16 +1432,25 @@ function scalarToJs(raw, valueType) {
1384
1432
  return raw;
1385
1433
  }
1386
1434
  }
1387
- function hoconToJs(v) {
1435
+ function hoconToJs(v, nullPrototype = false) {
1388
1436
  switch (v.kind) {
1389
1437
  case "scalar":
1390
1438
  return scalarToJs(v.raw, v.valueType);
1391
1439
  case "array":
1392
- return v.items.map(hoconToJs);
1440
+ return v.items.map((item) => hoconToJs(item, nullPrototype));
1393
1441
  case "object": {
1394
- const obj = /* @__PURE__ */ Object.create(null);
1395
- for (const [k, val] of v.fields) obj[k] = hoconToJs(val);
1396
- return Object.assign({}, obj);
1442
+ const entries = Array.from(v.fields, ([k, val]) => [k, hoconToJs(val, nullPrototype)]);
1443
+ if (nullPrototype) {
1444
+ const obj = /* @__PURE__ */ Object.create(null);
1445
+ for (const [k, val] of entries) Object.defineProperty(obj, k, {
1446
+ value: val,
1447
+ writable: true,
1448
+ enumerable: true,
1449
+ configurable: true
1450
+ });
1451
+ return obj;
1452
+ }
1453
+ return Object.fromEntries(entries);
1397
1454
  }
1398
1455
  }
1399
1456
  }
@@ -1482,6 +1539,8 @@ function fromMap(values, originDescription) {
1482
1539
  const root = { kind: "object", fields };
1483
1540
  return Config._fromResolvedValue(root, { originDescription });
1484
1541
  }
1542
+ var INT64_MAX = 9223372036854775807n;
1543
+ var INT64_MIN = -9223372036854775808n;
1485
1544
  function coerceObject(obj, atPath) {
1486
1545
  const fields = /* @__PURE__ */ new Map();
1487
1546
  for (const [k, v] of Object.entries(obj)) {
@@ -1510,14 +1569,14 @@ function coerceValue(v, atPath) {
1510
1569
  atPath
1511
1570
  );
1512
1571
  }
1513
- return { kind: "scalar", raw: String(v), valueType: "number" };
1572
+ return { kind: "scalar", raw: Object.is(v, -0) ? "-0" : String(v), valueType: "number" };
1514
1573
  }
1515
1574
  case "boolean":
1516
1575
  return { kind: "scalar", raw: v ? "true" : "false", valueType: "boolean" };
1517
1576
  case "bigint": {
1518
- if (v > BigInt(Number.MAX_SAFE_INTEGER) || v < BigInt(Number.MIN_SAFE_INTEGER)) {
1577
+ if (v > INT64_MAX || v < INT64_MIN) {
1519
1578
  throw new ConfigError(
1520
- `fromMap: bigint ${v} exceeds Number.MAX_SAFE_INTEGER (not representable as HOCON number) at path "${atPath}"`,
1579
+ `fromMap: integer ${v} is out of int64 range (HOCON integers are int64; spec F0.5) at path "${atPath}"`,
1521
1580
  atPath
1522
1581
  );
1523
1582
  }
@@ -1541,7 +1600,7 @@ function coerceValue(v, atPath) {
1541
1600
 
1542
1601
  // src/adapters/jsonc.ts
1543
1602
  function parseJsonc(input, originDescription) {
1544
- const doc = JSON.parse(stripTrailingCommas(stripComments(input)));
1603
+ const doc = JSON.parse(stripTrailingCommas(stripComments(stripBom(input))), bigIntReviver);
1545
1604
  if (doc === null || typeof doc !== "object" || Array.isArray(doc)) {
1546
1605
  throw new ConfigError(
1547
1606
  `jsonc: document root is ${Array.isArray(doc) ? "an array" : typeof doc}, but a config root must be an object (spec F0.3)`,
@@ -1550,6 +1609,50 @@ function parseJsonc(input, originDescription) {
1550
1609
  }
1551
1610
  return fromMap(doc, originDescription);
1552
1611
  }
1612
+ function isIntegerLiteral(source) {
1613
+ return !/[.eE]/.test(source);
1614
+ }
1615
+ var HAS_SOURCE_TEXT_ACCESS = (() => {
1616
+ let seen;
1617
+ JSON.parse("1", function(_k, v, context) {
1618
+ seen = context?.source;
1619
+ return v;
1620
+ });
1621
+ return seen !== void 0;
1622
+ })();
1623
+ function bigIntReviver(key, value, context) {
1624
+ if (typeof value !== "number" || Number.isSafeInteger(value)) return value;
1625
+ const source = context?.source;
1626
+ if (source === void 0) {
1627
+ if (!Number.isInteger(value)) return value;
1628
+ throw new ConfigError(
1629
+ `jsonc: the integer at "${key || "<root>"}" needs more precision than a JS number holds, and this runtime does not expose JSON.parse source text (${HAS_SOURCE_TEXT_ACCESS ? "unexpected \u2014 the capability probe said otherwise" : "requires Node >= 22 or an engine with JSON.parse source access"}), so it cannot be read losslessly (spec F0.5)`,
1630
+ key
1631
+ );
1632
+ }
1633
+ if (!isIntegerLiteral(source)) return value;
1634
+ return BigInt(source);
1635
+ }
1636
+ function isLineBreak(c) {
1637
+ return c === "\n" || c === "\r";
1638
+ }
1639
+ function lineBreaksOf(span) {
1640
+ let out = "";
1641
+ for (let i = 0; i < span.length; i++) {
1642
+ const c = span[i];
1643
+ if (c === "\r") {
1644
+ if (span[i + 1] === "\n") {
1645
+ out += "\r\n";
1646
+ i++;
1647
+ } else {
1648
+ out += "\r";
1649
+ }
1650
+ } else if (c === "\n") {
1651
+ out += "\n";
1652
+ }
1653
+ }
1654
+ return out;
1655
+ }
1553
1656
  function stripComments(src) {
1554
1657
  let out = "";
1555
1658
  for (let i = 0; i < src.length; ) {
@@ -1561,13 +1664,13 @@ function stripComments(src) {
1561
1664
  continue;
1562
1665
  }
1563
1666
  if (c === "/" && src[i + 1] === "/") {
1564
- while (i < src.length && src[i] !== "\n") i++;
1667
+ while (i < src.length && !isLineBreak(src[i])) i++;
1565
1668
  continue;
1566
1669
  }
1567
1670
  if (c === "/" && src[i + 1] === "*") {
1568
1671
  const end = src.indexOf("*/", i + 2);
1569
1672
  if (end === -1) throw new ConfigError("jsonc: unterminated block comment", "");
1570
- for (const ch of src.slice(i, end + 2)) if (ch === "\n") out += "\n";
1673
+ out += lineBreaksOf(src.slice(i, end + 2)) || " ";
1571
1674
  i = end + 2;
1572
1675
  continue;
1573
1676
  }
@@ -1,4 +1,4 @@
1
- import { C as Config } from '../config-PdhVgeLS.cjs';
1
+ import { C as Config } from '../config-Dlq6rF3w.cjs';
2
2
 
3
3
  /**
4
4
  * Read JSON with comments and trailing commas — the dialect VS Code and
@@ -10,15 +10,35 @@ import { C as Config } from '../config-PdhVgeLS.cjs';
10
10
  * of its own.)
11
11
  *
12
12
  * Comments and trailing commas are removed and `JSON.parse` does the rest, so
13
- * the accepted grammar is otherwise exactly the platform's JSON.
13
+ * the accepted grammar is otherwise exactly the platform's JSON. A comment is
14
+ * replaced by whitespace rather than deleted, so it separates the tokens around
15
+ * it and `{"a":1/*x*\/2}` is a syntax error rather than `{"a":12}` (F3.2).
16
+ *
17
+ * Integers are ingested losslessly (F0.5): a literal too wide for a JS `number`
18
+ * keeps its digits — `getString` returns them exactly — and one outside int64
19
+ * is refused instead of being rounded. `getNumber` and `toObject` still apply
20
+ * the JS number model, as they do for HOCON's own literals, so read large
21
+ * identifiers with `getString`.
14
22
  *
15
23
  * See docs/specs/format-ingestion-mapping.md items F3.x in the hocon scope.
16
24
  */
17
25
  declare function parseJsonc(input: string, originDescription?: string): Config;
18
26
  /**
19
27
  * Remove `//` line comments and block comments, leaving string literals alone.
20
- * Newlines inside removed spans are kept so JSON.parse still reports useful
21
- * positions.
28
+ *
29
+ * F3.2: a comment is replaced by *whitespace*, never the empty string — it must
30
+ * keep separating the tokens around it, so a `1`, a block comment and a `2` stay
31
+ * two tokens and fail the JSON decode instead of silently reading as `12`.
32
+ * Newlines inside a removed span are kept so JSON.parse still reports useful
33
+ * positions; a span with no newline becomes a single space.
34
+ *
35
+ * A `//` comment ends at **LF or CR** (F3.2), and at nothing else. Stopping only
36
+ * at LF let a CR-terminated comment eat the rest of the line, and the
37
+ * trailing-comma pass then tidied the remains into valid JSON — so
38
+ * `{"a":1,//c\r"b":2,\n"c":3}` decoded as `{"a":1,"c":3}`, losing a key with no
39
+ * error at all. Stopping at U+2028/U+2029 would be the mirror-image mistake:
40
+ * ending a comment the dialect's own parser is still inside, so the document
41
+ * would mean something different here than in VS Code. See {@link isLineBreak}.
22
42
  */
23
43
  declare function stripComments(src: string): string;
24
44
 
@@ -1,4 +1,4 @@
1
- import { C as Config } from '../config-PdhVgeLS.js';
1
+ import { C as Config } from '../config-Dlq6rF3w.js';
2
2
 
3
3
  /**
4
4
  * Read JSON with comments and trailing commas — the dialect VS Code and
@@ -10,15 +10,35 @@ import { C as Config } from '../config-PdhVgeLS.js';
10
10
  * of its own.)
11
11
  *
12
12
  * Comments and trailing commas are removed and `JSON.parse` does the rest, so
13
- * the accepted grammar is otherwise exactly the platform's JSON.
13
+ * the accepted grammar is otherwise exactly the platform's JSON. A comment is
14
+ * replaced by whitespace rather than deleted, so it separates the tokens around
15
+ * it and `{"a":1/*x*\/2}` is a syntax error rather than `{"a":12}` (F3.2).
16
+ *
17
+ * Integers are ingested losslessly (F0.5): a literal too wide for a JS `number`
18
+ * keeps its digits — `getString` returns them exactly — and one outside int64
19
+ * is refused instead of being rounded. `getNumber` and `toObject` still apply
20
+ * the JS number model, as they do for HOCON's own literals, so read large
21
+ * identifiers with `getString`.
14
22
  *
15
23
  * See docs/specs/format-ingestion-mapping.md items F3.x in the hocon scope.
16
24
  */
17
25
  declare function parseJsonc(input: string, originDescription?: string): Config;
18
26
  /**
19
27
  * Remove `//` line comments and block comments, leaving string literals alone.
20
- * Newlines inside removed spans are kept so JSON.parse still reports useful
21
- * positions.
28
+ *
29
+ * F3.2: a comment is replaced by *whitespace*, never the empty string — it must
30
+ * keep separating the tokens around it, so a `1`, a block comment and a `2` stay
31
+ * two tokens and fail the JSON decode instead of silently reading as `12`.
32
+ * Newlines inside a removed span are kept so JSON.parse still reports useful
33
+ * positions; a span with no newline becomes a single space.
34
+ *
35
+ * A `//` comment ends at **LF or CR** (F3.2), and at nothing else. Stopping only
36
+ * at LF let a CR-terminated comment eat the rest of the line, and the
37
+ * trailing-comma pass then tidied the remains into valid JSON — so
38
+ * `{"a":1,//c\r"b":2,\n"c":3}` decoded as `{"a":1,"c":3}`, losing a key with no
39
+ * error at all. Stopping at U+2028/U+2029 would be the mirror-image mistake:
40
+ * ending a comment the dialect's own parser is still inside, so the document
41
+ * would mean something different here than in VS Code. See {@link isLineBreak}.
22
42
  */
23
43
  declare function stripComments(src: string): string;
24
44