@o3co/ts.hocon 1.6.0 → 1.7.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.
- package/dist/{config-CjSkQ4_l.d.cts → config-DCSLXkNY.d.cts} +9 -6
- package/dist/{config-CjSkQ4_l.d.ts → config-DCSLXkNY.d.ts} +9 -6
- package/dist/index.cjs +135 -157
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +135 -157
- package/dist/zod.cjs +135 -157
- package/dist/zod.d.cts +1 -1
- package/dist/zod.d.ts +1 -1
- package/dist/zod.js +135 -157
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -237,55 +237,6 @@ var NotResolvedError = class extends ConfigError {
|
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
239
|
|
|
240
|
-
// src/internal/resolver/types.ts
|
|
241
|
-
var separatorValues = /* @__PURE__ */ new WeakSet();
|
|
242
|
-
function isSubst(v) {
|
|
243
|
-
return v._kind === "subst-placeholder";
|
|
244
|
-
}
|
|
245
|
-
function isConcat(v) {
|
|
246
|
-
return v._kind === "concat-placeholder";
|
|
247
|
-
}
|
|
248
|
-
function isAppend(v) {
|
|
249
|
-
return v._kind === "append-placeholder";
|
|
250
|
-
}
|
|
251
|
-
function isResObj(v) {
|
|
252
|
-
return v._kind === "res-obj";
|
|
253
|
-
}
|
|
254
|
-
function makeResObj() {
|
|
255
|
-
return { _kind: "res-obj", fields: /* @__PURE__ */ new Map(), priorValues: /* @__PURE__ */ new Map() };
|
|
256
|
-
}
|
|
257
|
-
function mergeUnresolved(receiver, fallback) {
|
|
258
|
-
const result = makeResObj();
|
|
259
|
-
for (const [k, v] of fallback.fields) {
|
|
260
|
-
result.fields.set(k, v);
|
|
261
|
-
}
|
|
262
|
-
for (const [k, v] of fallback.priorValues) {
|
|
263
|
-
result.priorValues.set(k, v);
|
|
264
|
-
}
|
|
265
|
-
for (const [k, rv] of receiver.fields) {
|
|
266
|
-
const existing = result.fields.get(k);
|
|
267
|
-
if (existing !== void 0) {
|
|
268
|
-
const recPrior = receiver.priorValues.get(k);
|
|
269
|
-
if (recPrior !== void 0 && !isResObj(recPrior)) {
|
|
270
|
-
result.fields.set(k, rv);
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
if (isResObj(rv) && isResObj(existing)) {
|
|
274
|
-
result.fields.set(k, mergeUnresolved(rv, existing));
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
result.priorValues.set(k, existing);
|
|
278
|
-
}
|
|
279
|
-
result.fields.set(k, rv);
|
|
280
|
-
}
|
|
281
|
-
for (const [k, v] of receiver.priorValues) {
|
|
282
|
-
if (receiver.fields.has(k)) {
|
|
283
|
-
result.priorValues.set(k, v);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
240
|
// src/internal/resolver/fold-self-ref.ts
|
|
290
241
|
function substFullKey(s) {
|
|
291
242
|
return stringSegmentsToKey(s.segments.map((seg) => seg.text));
|
|
@@ -301,9 +252,6 @@ function stringSegmentsToKey(segments) {
|
|
|
301
252
|
function containsSelfRef(v, fullKey) {
|
|
302
253
|
if (isSubst(v)) return !v.knownAbsent && substFullKey(v) === fullKey;
|
|
303
254
|
if (isConcat(v)) return v.nodes.some((n) => containsSelfRef(n, fullKey));
|
|
304
|
-
if (isAppend(v)) {
|
|
305
|
-
return containsSelfRef(v.existing, fullKey) || containsSelfRef(v.elem, fullKey);
|
|
306
|
-
}
|
|
307
255
|
if (isResObj(v)) {
|
|
308
256
|
for (const f of v.fields.values()) {
|
|
309
257
|
if (containsSelfRef(f, fullKey)) return true;
|
|
@@ -334,19 +282,12 @@ function foldSelfRef(v, fullKey, replacement) {
|
|
|
334
282
|
col: v.col
|
|
335
283
|
};
|
|
336
284
|
}
|
|
337
|
-
if (isAppend(v)) {
|
|
338
|
-
return {
|
|
339
|
-
_kind: "append-placeholder",
|
|
340
|
-
existing: foldSelfRef(v.existing, fullKey, replacement),
|
|
341
|
-
elem: foldSelfRef(v.elem, fullKey, replacement)
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
285
|
if (isResObj(v)) {
|
|
345
286
|
const newFields = /* @__PURE__ */ new Map();
|
|
346
287
|
for (const [k, val] of v.fields) {
|
|
347
288
|
newFields.set(k, foldSelfRef(val, fullKey, replacement));
|
|
348
289
|
}
|
|
349
|
-
return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues) };
|
|
290
|
+
return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
|
|
350
291
|
}
|
|
351
292
|
const hv = v;
|
|
352
293
|
if (hv.kind === "array") {
|
|
@@ -364,6 +305,41 @@ function foldSelfRef(v, fullKey, replacement) {
|
|
|
364
305
|
}
|
|
365
306
|
return v;
|
|
366
307
|
}
|
|
308
|
+
function foldKnownAbsentSelfRef(v, fullKey, replacement) {
|
|
309
|
+
if (isSubst(v)) {
|
|
310
|
+
return v.knownAbsent && substFullKey(v) === fullKey ? replacement : v;
|
|
311
|
+
}
|
|
312
|
+
if (isConcat(v)) {
|
|
313
|
+
return {
|
|
314
|
+
_kind: "concat-placeholder",
|
|
315
|
+
nodes: v.nodes.map((n) => foldKnownAbsentSelfRef(n, fullKey, replacement)),
|
|
316
|
+
line: v.line,
|
|
317
|
+
col: v.col
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (isResObj(v)) {
|
|
321
|
+
const newFields = /* @__PURE__ */ new Map();
|
|
322
|
+
for (const [k, val] of v.fields) {
|
|
323
|
+
newFields.set(k, foldKnownAbsentSelfRef(val, fullKey, replacement));
|
|
324
|
+
}
|
|
325
|
+
return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
|
|
326
|
+
}
|
|
327
|
+
const hv = v;
|
|
328
|
+
if (hv.kind === "array") {
|
|
329
|
+
return {
|
|
330
|
+
kind: "array",
|
|
331
|
+
items: hv.items.map((item) => foldKnownAbsentSelfRef(item, fullKey, replacement))
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (hv.kind === "object") {
|
|
335
|
+
const newFields = /* @__PURE__ */ new Map();
|
|
336
|
+
for (const [k, val] of hv.fields) {
|
|
337
|
+
newFields.set(k, foldKnownAbsentSelfRef(val, fullKey, replacement));
|
|
338
|
+
}
|
|
339
|
+
return { kind: "object", fields: newFields };
|
|
340
|
+
}
|
|
341
|
+
return v;
|
|
342
|
+
}
|
|
367
343
|
function foldOrSkipPrior(prior, fullKey, old) {
|
|
368
344
|
if (!containsSelfRef(prior, fullKey)) return cloneResolverValue(prior);
|
|
369
345
|
if (old === void 0) return foldOptionalSelfRefAbsent(prior, fullKey);
|
|
@@ -392,12 +368,6 @@ function foldOptionalSelfRefAbsent(v, fullKey) {
|
|
|
392
368
|
}
|
|
393
369
|
return { _kind: "concat-placeholder", nodes, line: v.line, col: v.col };
|
|
394
370
|
}
|
|
395
|
-
if (isAppend(v)) {
|
|
396
|
-
const existing = foldOptionalSelfRefAbsent(v.existing, fullKey);
|
|
397
|
-
const elem = foldOptionalSelfRefAbsent(v.elem, fullKey);
|
|
398
|
-
if (existing === void 0 || elem === void 0) return void 0;
|
|
399
|
-
return { _kind: "append-placeholder", existing, elem };
|
|
400
|
-
}
|
|
401
371
|
if (isResObj(v)) {
|
|
402
372
|
const fields = /* @__PURE__ */ new Map();
|
|
403
373
|
for (const [key, value] of v.fields) {
|
|
@@ -405,7 +375,7 @@ function foldOptionalSelfRefAbsent(v, fullKey) {
|
|
|
405
375
|
if (folded === void 0) return void 0;
|
|
406
376
|
fields.set(key, folded);
|
|
407
377
|
}
|
|
408
|
-
return { _kind: "res-obj", fields, priorValues: new Map(v.priorValues) };
|
|
378
|
+
return { _kind: "res-obj", fields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
|
|
409
379
|
}
|
|
410
380
|
const hv = v;
|
|
411
381
|
if (hv.kind === "array") {
|
|
@@ -454,14 +424,7 @@ function cloneResolverValue(v) {
|
|
|
454
424
|
for (const [k, val] of v.fields) newFields.set(k, cloneResolverValue(val));
|
|
455
425
|
const newPriors = /* @__PURE__ */ new Map();
|
|
456
426
|
for (const [k, val] of v.priorValues) newPriors.set(k, cloneResolverValue(val));
|
|
457
|
-
return { _kind: "res-obj", fields: newFields, priorValues: newPriors };
|
|
458
|
-
}
|
|
459
|
-
if (isAppend(v)) {
|
|
460
|
-
return {
|
|
461
|
-
_kind: "append-placeholder",
|
|
462
|
-
existing: cloneResolverValue(v.existing),
|
|
463
|
-
elem: cloneResolverValue(v.elem)
|
|
464
|
-
};
|
|
427
|
+
return { _kind: "res-obj", fields: newFields, priorValues: newPriors, resetKeys: new Set(v.resetKeys) };
|
|
465
428
|
}
|
|
466
429
|
const hv = v;
|
|
467
430
|
if (hv.kind === "array") {
|
|
@@ -496,14 +459,11 @@ function foldNestedSelfRefs(v, pathPrefix) {
|
|
|
496
459
|
}
|
|
497
460
|
newFields.set(k, finalVal);
|
|
498
461
|
}
|
|
499
|
-
return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues) };
|
|
462
|
+
return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
|
|
500
463
|
}
|
|
501
464
|
function containsSubstByPath(v, target) {
|
|
502
465
|
if (isSubst(v)) return !v.knownAbsent && segmentsTextEqual(v.segments, target);
|
|
503
466
|
if (isConcat(v)) return v.nodes.some((n) => containsSubstByPath(n, target));
|
|
504
|
-
if (isAppend(v)) {
|
|
505
|
-
return containsSubstByPath(v.existing, target) || containsSubstByPath(v.elem, target);
|
|
506
|
-
}
|
|
507
467
|
if (isResObj(v)) {
|
|
508
468
|
for (const f of v.fields.values()) {
|
|
509
469
|
if (containsSubstByPath(f, target)) return true;
|
|
@@ -532,6 +492,53 @@ function segmentsTextEqual(a, b) {
|
|
|
532
492
|
return true;
|
|
533
493
|
}
|
|
534
494
|
|
|
495
|
+
// src/internal/resolver/types.ts
|
|
496
|
+
var separatorValues = /* @__PURE__ */ new WeakSet();
|
|
497
|
+
function isSubst(v) {
|
|
498
|
+
return v._kind === "subst-placeholder";
|
|
499
|
+
}
|
|
500
|
+
function isConcat(v) {
|
|
501
|
+
return v._kind === "concat-placeholder";
|
|
502
|
+
}
|
|
503
|
+
function isResObj(v) {
|
|
504
|
+
return v._kind === "res-obj";
|
|
505
|
+
}
|
|
506
|
+
function makeResObj() {
|
|
507
|
+
return { _kind: "res-obj", fields: /* @__PURE__ */ new Map(), priorValues: /* @__PURE__ */ new Map(), resetKeys: /* @__PURE__ */ new Set() };
|
|
508
|
+
}
|
|
509
|
+
function mergeUnresolved(receiver, fallback) {
|
|
510
|
+
const result = makeResObj();
|
|
511
|
+
for (const [k, v] of fallback.fields) {
|
|
512
|
+
result.fields.set(k, v);
|
|
513
|
+
}
|
|
514
|
+
for (const [k, v] of fallback.priorValues) {
|
|
515
|
+
result.priorValues.set(k, v);
|
|
516
|
+
}
|
|
517
|
+
for (const [k, rv] of receiver.fields) {
|
|
518
|
+
const existing = result.fields.get(k);
|
|
519
|
+
if (existing !== void 0) {
|
|
520
|
+
const recPrior = receiver.priorValues.get(k);
|
|
521
|
+
if (recPrior !== void 0 && !isResObj(recPrior)) {
|
|
522
|
+
result.fields.set(k, rv);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
if (isResObj(rv) && isResObj(existing)) {
|
|
526
|
+
result.fields.set(k, mergeUnresolved(rv, existing));
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
const foldedPrior = foldOrSkipPrior(existing, k, void 0);
|
|
530
|
+
if (foldedPrior !== void 0) result.priorValues.set(k, foldedPrior);
|
|
531
|
+
}
|
|
532
|
+
result.fields.set(k, rv);
|
|
533
|
+
}
|
|
534
|
+
for (const [k, v] of receiver.priorValues) {
|
|
535
|
+
if (receiver.fields.has(k)) {
|
|
536
|
+
result.priorValues.set(k, v);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return result;
|
|
540
|
+
}
|
|
541
|
+
|
|
535
542
|
// src/internal/resolver/utils.ts
|
|
536
543
|
function segmentsToKey(segments) {
|
|
537
544
|
return segments.map((s) => {
|
|
@@ -585,9 +592,19 @@ function deepMergeResObjInto(dst, src, pathPrefix = []) {
|
|
|
585
592
|
deepMergeResObjInto(dstVal, srcVal, childPrefix);
|
|
586
593
|
} else {
|
|
587
594
|
if (dstVal !== void 0) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
595
|
+
if (src.resetKeys.has(k)) {
|
|
596
|
+
dst.priorValues.delete(k);
|
|
597
|
+
} else {
|
|
598
|
+
const dstFolded = foldOrSkipPrior(dstVal, fullKey, dst.priorValues.get(k));
|
|
599
|
+
if (dstFolded !== void 0) {
|
|
600
|
+
const srcPrior = src.priorValues.get(k);
|
|
601
|
+
if (srcPrior !== void 0) {
|
|
602
|
+
dst.priorValues.set(k, foldKnownAbsentSelfRef(srcPrior, fullKey, dstFolded));
|
|
603
|
+
} else {
|
|
604
|
+
dst.priorValues.set(k, dstFolded);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
591
608
|
}
|
|
592
609
|
dst.fields.set(k, srcVal);
|
|
593
610
|
}
|
|
@@ -597,6 +614,7 @@ function deepMergeResObjInto(dst, src, pathPrefix = []) {
|
|
|
597
614
|
dst.priorValues.set(k, srcPrior);
|
|
598
615
|
}
|
|
599
616
|
}
|
|
617
|
+
for (const k of src.resetKeys) dst.resetKeys.add(k);
|
|
600
618
|
}
|
|
601
619
|
function hoconValueToResObj(hv) {
|
|
602
620
|
const obj = makeResObj();
|
|
@@ -1852,31 +1870,15 @@ var StructureBuilder = class _StructureBuilder {
|
|
|
1852
1870
|
const childPrefix = [...pathPrefix, head];
|
|
1853
1871
|
const fullKey = stringSegmentsToKey(childPrefix);
|
|
1854
1872
|
if (field.append) {
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
const folded = foldOrSkipPrior(existing2, fullKey, oldPrior);
|
|
1858
|
-
if (folded !== void 0) obj.priorValues.set(head, folded);
|
|
1859
|
-
obj.fields.set(head, {
|
|
1860
|
-
_kind: "append-placeholder",
|
|
1861
|
-
// Use the folded existing (self-ref-free) for the Append. When the
|
|
1862
|
-
// fold returned undefined (self-ref present but no old prior),
|
|
1863
|
-
// fall back to the original existing — resolveSubst will then
|
|
1864
|
-
// raise the "self-ref with no prior value" error at resolve time,
|
|
1865
|
-
// matching the pre-fix behaviour for that edge case.
|
|
1866
|
-
//
|
|
1867
|
-
// Clone `folded` again so the Append.existing and priorValues[head]
|
|
1868
|
-
// do not share the same Subst/Concat references — relativizeResObj
|
|
1869
|
-
// walks BOTH `fields` and `priorValues` and mutates Subst.segments
|
|
1870
|
-
// in place, so a shared reference would get its prefix applied
|
|
1871
|
-
// twice (resulting in e.g. `${outer.outer.base}` instead of
|
|
1872
|
-
// `${outer.base}`). Codex review on PR #131.
|
|
1873
|
-
existing: folded !== void 0 ? cloneResolverValue(folded) : existing2,
|
|
1874
|
-
elem: this.astToResolverValue(field.value, childPrefix)
|
|
1875
|
-
});
|
|
1873
|
+
const synthetic = this.desugarAppend(field, childPrefix);
|
|
1874
|
+
this.applyField(obj, synthetic, pathPrefix);
|
|
1876
1875
|
return;
|
|
1877
1876
|
}
|
|
1878
1877
|
const existing = obj.fields.get(head);
|
|
1879
1878
|
const newVal = this.astToResolverValue(field.value, childPrefix);
|
|
1879
|
+
if (!containsSelfRef(newVal, fullKey)) {
|
|
1880
|
+
obj.resetKeys.add(head);
|
|
1881
|
+
}
|
|
1880
1882
|
if (existing !== void 0) {
|
|
1881
1883
|
const oldPrior = obj.priorValues.get(head);
|
|
1882
1884
|
const priorInput = isResObj(existing) ? foldNestedSelfRefs(existing, childPrefix) : existing;
|
|
@@ -1918,19 +1920,15 @@ var StructureBuilder = class _StructureBuilder {
|
|
|
1918
1920
|
const childPrefix = [...pathPrefix, head];
|
|
1919
1921
|
const fullKey = stringSegmentsToKey(childPrefix);
|
|
1920
1922
|
if (field.append) {
|
|
1921
|
-
const
|
|
1922
|
-
|
|
1923
|
-
const folded = foldOrSkipPrior(existing2, fullKey, oldPrior);
|
|
1924
|
-
if (folded !== void 0) obj.priorValues.set(head, folded);
|
|
1925
|
-
obj.fields.set(head, {
|
|
1926
|
-
_kind: "append-placeholder",
|
|
1927
|
-
existing: folded !== void 0 ? cloneResolverValue(folded) : existing2,
|
|
1928
|
-
elem: await this.astToResolverValueAsync(field.value, childPrefix)
|
|
1929
|
-
});
|
|
1923
|
+
const synthetic = this.desugarAppend(field, childPrefix);
|
|
1924
|
+
await this.applyFieldAsync(obj, synthetic, pathPrefix);
|
|
1930
1925
|
return;
|
|
1931
1926
|
}
|
|
1932
1927
|
const existing = obj.fields.get(head);
|
|
1933
1928
|
const newVal = await this.astToResolverValueAsync(field.value, childPrefix);
|
|
1929
|
+
if (!containsSelfRef(newVal, fullKey)) {
|
|
1930
|
+
obj.resetKeys.add(head);
|
|
1931
|
+
}
|
|
1934
1932
|
if (existing !== void 0) {
|
|
1935
1933
|
const oldPrior = obj.priorValues.get(head);
|
|
1936
1934
|
const priorInput = isResObj(existing) ? foldNestedSelfRefs(existing, childPrefix) : existing;
|
|
@@ -1943,6 +1941,21 @@ var StructureBuilder = class _StructureBuilder {
|
|
|
1943
1941
|
}
|
|
1944
1942
|
obj.fields.set(head, newVal);
|
|
1945
1943
|
}
|
|
1944
|
+
/** Builds the `key = ${?fullkey} [value]` field that `key += value` desugars
|
|
1945
|
+
* to (S13b.2, HOCON.md L732). `childPrefix` is the field's fully-qualified
|
|
1946
|
+
* path (pathPrefix + key), so a nested `srv { items += x }` references
|
|
1947
|
+
* `${?srv.items}`; include relativization rewrites it under a mount prefix.
|
|
1948
|
+
* `field.key` is already single-segment here (multi-segment keys are split
|
|
1949
|
+
* into nested objects upstream). Returns a NEW AstField (append=false);
|
|
1950
|
+
* positions inherit from the original field so resolve-time errors (the
|
|
1951
|
+
* S13b.2 non-array check, now via the scalar+array concat) keep a location. */
|
|
1952
|
+
desugarAppend(field, childPrefix) {
|
|
1953
|
+
const segments = childPrefix.map((text) => ({ text, line: field.pos.line, col: field.pos.col }));
|
|
1954
|
+
const subst = { kind: "subst", segments, optional: true, listSuffix: false, pos: field.pos };
|
|
1955
|
+
const elemArray = { kind: "array", items: [field.value], pos: field.pos };
|
|
1956
|
+
const synthetic = { kind: "concat", nodes: [subst, elemArray], pos: field.pos };
|
|
1957
|
+
return { key: field.key, value: synthetic, append: false, pos: field.pos };
|
|
1958
|
+
}
|
|
1946
1959
|
astToResolverValue(ast, pathPrefix) {
|
|
1947
1960
|
switch (ast.kind) {
|
|
1948
1961
|
case "scalar": {
|
|
@@ -2007,11 +2020,6 @@ var StructureBuilder = class _StructureBuilder {
|
|
|
2007
2020
|
}
|
|
2008
2021
|
return;
|
|
2009
2022
|
}
|
|
2010
|
-
if (isAppend(val)) {
|
|
2011
|
-
this.relativizeSubstPaths(val.existing, prefixSegments);
|
|
2012
|
-
this.relativizeSubstPaths(val.elem, prefixSegments);
|
|
2013
|
-
return;
|
|
2014
|
-
}
|
|
2015
2023
|
if (isResObj(val)) {
|
|
2016
2024
|
this.relativizeResObj(val, prefixSegments);
|
|
2017
2025
|
return;
|
|
@@ -2160,7 +2168,6 @@ var SubstitutionResolver = class {
|
|
|
2160
2168
|
this.resolvingConcats.delete(v);
|
|
2161
2169
|
}
|
|
2162
2170
|
}
|
|
2163
|
-
if (isAppend(v)) return this.resolveAppend(v, scope);
|
|
2164
2171
|
if (isResObj(v)) return this.resolveResObj(v);
|
|
2165
2172
|
const hv = v;
|
|
2166
2173
|
if (hv.kind === "array") {
|
|
@@ -2445,38 +2452,6 @@ var SubstitutionResolver = class {
|
|
|
2445
2452
|
}
|
|
2446
2453
|
return folded;
|
|
2447
2454
|
}
|
|
2448
|
-
resolveAppend(a, scope) {
|
|
2449
|
-
const existing = this.resolveVal(a.existing, scope) ?? { kind: "array", items: [] };
|
|
2450
|
-
if (this.opts.allowUnresolved && (isSubst(existing) || isConcat(existing) || isAppend(existing))) {
|
|
2451
|
-
return a;
|
|
2452
|
-
}
|
|
2453
|
-
const elem = this.resolveVal(a.elem, scope);
|
|
2454
|
-
let priorItems;
|
|
2455
|
-
if (existing.kind === "array") {
|
|
2456
|
-
priorItems = existing.items;
|
|
2457
|
-
} else if (existing.kind === "object") {
|
|
2458
|
-
const converted = numericObjectToArray(existing);
|
|
2459
|
-
if (converted === null) {
|
|
2460
|
-
throw new ResolveError(
|
|
2461
|
-
`'+=' on non-array value: prior value is object with non-numeric keys (spec L732)`,
|
|
2462
|
-
"",
|
|
2463
|
-
0,
|
|
2464
|
-
0
|
|
2465
|
-
);
|
|
2466
|
-
}
|
|
2467
|
-
priorItems = converted;
|
|
2468
|
-
} else {
|
|
2469
|
-
throw new ResolveError(
|
|
2470
|
-
`'+=' on non-array value: prior value is ${existing.kind} (spec L732)`,
|
|
2471
|
-
"",
|
|
2472
|
-
0,
|
|
2473
|
-
0
|
|
2474
|
-
);
|
|
2475
|
-
}
|
|
2476
|
-
const items = [...priorItems];
|
|
2477
|
-
if (elem !== void 0) items.push(elem);
|
|
2478
|
-
return { kind: "array", items };
|
|
2479
|
-
}
|
|
2480
2455
|
};
|
|
2481
2456
|
|
|
2482
2457
|
// src/internal/resolver/resolver.ts
|
|
@@ -2494,7 +2469,7 @@ function containsPlaceholders(tree) {
|
|
|
2494
2469
|
}
|
|
2495
2470
|
function valContainsPlaceholders(v) {
|
|
2496
2471
|
const rv = v;
|
|
2497
|
-
if (isSubst(rv) || isConcat(rv)
|
|
2472
|
+
if (isSubst(rv) || isConcat(rv)) return true;
|
|
2498
2473
|
if (isResObj(rv)) return containsPlaceholders(rv);
|
|
2499
2474
|
const hv = v;
|
|
2500
2475
|
if (hv?.kind === "array") {
|
|
@@ -2505,7 +2480,7 @@ function valContainsPlaceholders(v) {
|
|
|
2505
2480
|
function buildPartialHoconFromResObj(tree) {
|
|
2506
2481
|
const fields = /* @__PURE__ */ new Map();
|
|
2507
2482
|
for (const [k, v] of tree.fields) {
|
|
2508
|
-
if (!isSubst(v) && !isConcat(v)
|
|
2483
|
+
if (!isSubst(v) && !isConcat(v)) {
|
|
2509
2484
|
if (isResObj(v)) {
|
|
2510
2485
|
fields.set(k, buildPartialHoconFromResObj(v));
|
|
2511
2486
|
} else {
|
|
@@ -2898,7 +2873,7 @@ function hoconToJs(v) {
|
|
|
2898
2873
|
function resObjToKeyShape(tree) {
|
|
2899
2874
|
const fields = /* @__PURE__ */ new Map();
|
|
2900
2875
|
for (const [k, v] of tree.fields) {
|
|
2901
|
-
if (isSubst(v) || isConcat(v)
|
|
2876
|
+
if (isSubst(v) || isConcat(v)) {
|
|
2902
2877
|
fields.set(k, { kind: "scalar", raw: "", valueType: "null" });
|
|
2903
2878
|
} else if (isResObj(v)) {
|
|
2904
2879
|
fields.set(k, resObjToKeyShape(v));
|
|
@@ -2912,7 +2887,7 @@ function stripPlaceholderFields(v) {
|
|
|
2912
2887
|
const fields = /* @__PURE__ */ new Map();
|
|
2913
2888
|
let hadPlaceholders = false;
|
|
2914
2889
|
for (const [k, val] of v.fields) {
|
|
2915
|
-
if (val._kind === "subst-placeholder" || val._kind === "concat-placeholder"
|
|
2890
|
+
if (val._kind === "subst-placeholder" || val._kind === "concat-placeholder") {
|
|
2916
2891
|
hadPlaceholders = true;
|
|
2917
2892
|
} else if (val.kind === "object") {
|
|
2918
2893
|
const inner = stripPlaceholderFields(val);
|
|
@@ -2946,9 +2921,8 @@ function renderHoconAsJSON(v) {
|
|
|
2946
2921
|
case "boolean":
|
|
2947
2922
|
return v.raw;
|
|
2948
2923
|
case "number": {
|
|
2949
|
-
const
|
|
2950
|
-
|
|
2951
|
-
return JSON.stringify(v.raw);
|
|
2924
|
+
const norm = normalizeLeadingZeroNumber(v.raw);
|
|
2925
|
+
return JSON_NUMBER_RE.test(norm) ? norm : JSON.stringify(v.raw);
|
|
2952
2926
|
}
|
|
2953
2927
|
case "string":
|
|
2954
2928
|
return JSON.stringify(v.raw);
|
|
@@ -2970,6 +2944,10 @@ function renderHoconAsJSON(v) {
|
|
|
2970
2944
|
}
|
|
2971
2945
|
throw new Error(`renderHoconAsJSON: unsupported value kind (unresolved placeholder?)`);
|
|
2972
2946
|
}
|
|
2947
|
+
var JSON_NUMBER_RE = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2948
|
+
function normalizeLeadingZeroNumber(raw) {
|
|
2949
|
+
return raw.replace(/^([+-]?)0+(\d)/, "$1$2");
|
|
2950
|
+
}
|
|
2973
2951
|
|
|
2974
2952
|
// src/parse.ts
|
|
2975
2953
|
import * as fs from "fs";
|