@o3co/ts.hocon 1.6.0 → 1.6.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.
package/dist/zod.cjs CHANGED
@@ -280,55 +280,6 @@ var NotResolvedError = class extends ConfigError {
280
280
  }
281
281
  };
282
282
 
283
- // src/internal/resolver/types.ts
284
- var separatorValues = /* @__PURE__ */ new WeakSet();
285
- function isSubst(v) {
286
- return v._kind === "subst-placeholder";
287
- }
288
- function isConcat(v) {
289
- return v._kind === "concat-placeholder";
290
- }
291
- function isAppend(v) {
292
- return v._kind === "append-placeholder";
293
- }
294
- function isResObj(v) {
295
- return v._kind === "res-obj";
296
- }
297
- function makeResObj() {
298
- return { _kind: "res-obj", fields: /* @__PURE__ */ new Map(), priorValues: /* @__PURE__ */ new Map() };
299
- }
300
- function mergeUnresolved(receiver, fallback) {
301
- const result = makeResObj();
302
- for (const [k, v] of fallback.fields) {
303
- result.fields.set(k, v);
304
- }
305
- for (const [k, v] of fallback.priorValues) {
306
- result.priorValues.set(k, v);
307
- }
308
- for (const [k, rv] of receiver.fields) {
309
- const existing = result.fields.get(k);
310
- if (existing !== void 0) {
311
- const recPrior = receiver.priorValues.get(k);
312
- if (recPrior !== void 0 && !isResObj(recPrior)) {
313
- result.fields.set(k, rv);
314
- continue;
315
- }
316
- if (isResObj(rv) && isResObj(existing)) {
317
- result.fields.set(k, mergeUnresolved(rv, existing));
318
- continue;
319
- }
320
- result.priorValues.set(k, existing);
321
- }
322
- result.fields.set(k, rv);
323
- }
324
- for (const [k, v] of receiver.priorValues) {
325
- if (receiver.fields.has(k)) {
326
- result.priorValues.set(k, v);
327
- }
328
- }
329
- return result;
330
- }
331
-
332
283
  // src/internal/resolver/fold-self-ref.ts
333
284
  function substFullKey(s) {
334
285
  return stringSegmentsToKey(s.segments.map((seg) => seg.text));
@@ -344,9 +295,6 @@ function stringSegmentsToKey(segments) {
344
295
  function containsSelfRef(v, fullKey) {
345
296
  if (isSubst(v)) return !v.knownAbsent && substFullKey(v) === fullKey;
346
297
  if (isConcat(v)) return v.nodes.some((n) => containsSelfRef(n, fullKey));
347
- if (isAppend(v)) {
348
- return containsSelfRef(v.existing, fullKey) || containsSelfRef(v.elem, fullKey);
349
- }
350
298
  if (isResObj(v)) {
351
299
  for (const f of v.fields.values()) {
352
300
  if (containsSelfRef(f, fullKey)) return true;
@@ -377,19 +325,12 @@ function foldSelfRef(v, fullKey, replacement) {
377
325
  col: v.col
378
326
  };
379
327
  }
380
- if (isAppend(v)) {
381
- return {
382
- _kind: "append-placeholder",
383
- existing: foldSelfRef(v.existing, fullKey, replacement),
384
- elem: foldSelfRef(v.elem, fullKey, replacement)
385
- };
386
- }
387
328
  if (isResObj(v)) {
388
329
  const newFields = /* @__PURE__ */ new Map();
389
330
  for (const [k, val] of v.fields) {
390
331
  newFields.set(k, foldSelfRef(val, fullKey, replacement));
391
332
  }
392
- return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues) };
333
+ return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
393
334
  }
394
335
  const hv = v;
395
336
  if (hv.kind === "array") {
@@ -407,6 +348,41 @@ function foldSelfRef(v, fullKey, replacement) {
407
348
  }
408
349
  return v;
409
350
  }
351
+ function foldKnownAbsentSelfRef(v, fullKey, replacement) {
352
+ if (isSubst(v)) {
353
+ return v.knownAbsent && substFullKey(v) === fullKey ? replacement : v;
354
+ }
355
+ if (isConcat(v)) {
356
+ return {
357
+ _kind: "concat-placeholder",
358
+ nodes: v.nodes.map((n) => foldKnownAbsentSelfRef(n, fullKey, replacement)),
359
+ line: v.line,
360
+ col: v.col
361
+ };
362
+ }
363
+ if (isResObj(v)) {
364
+ const newFields = /* @__PURE__ */ new Map();
365
+ for (const [k, val] of v.fields) {
366
+ newFields.set(k, foldKnownAbsentSelfRef(val, fullKey, replacement));
367
+ }
368
+ return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
369
+ }
370
+ const hv = v;
371
+ if (hv.kind === "array") {
372
+ return {
373
+ kind: "array",
374
+ items: hv.items.map((item) => foldKnownAbsentSelfRef(item, fullKey, replacement))
375
+ };
376
+ }
377
+ if (hv.kind === "object") {
378
+ const newFields = /* @__PURE__ */ new Map();
379
+ for (const [k, val] of hv.fields) {
380
+ newFields.set(k, foldKnownAbsentSelfRef(val, fullKey, replacement));
381
+ }
382
+ return { kind: "object", fields: newFields };
383
+ }
384
+ return v;
385
+ }
410
386
  function foldOrSkipPrior(prior, fullKey, old) {
411
387
  if (!containsSelfRef(prior, fullKey)) return cloneResolverValue(prior);
412
388
  if (old === void 0) return foldOptionalSelfRefAbsent(prior, fullKey);
@@ -435,12 +411,6 @@ function foldOptionalSelfRefAbsent(v, fullKey) {
435
411
  }
436
412
  return { _kind: "concat-placeholder", nodes, line: v.line, col: v.col };
437
413
  }
438
- if (isAppend(v)) {
439
- const existing = foldOptionalSelfRefAbsent(v.existing, fullKey);
440
- const elem = foldOptionalSelfRefAbsent(v.elem, fullKey);
441
- if (existing === void 0 || elem === void 0) return void 0;
442
- return { _kind: "append-placeholder", existing, elem };
443
- }
444
414
  if (isResObj(v)) {
445
415
  const fields = /* @__PURE__ */ new Map();
446
416
  for (const [key, value] of v.fields) {
@@ -448,7 +418,7 @@ function foldOptionalSelfRefAbsent(v, fullKey) {
448
418
  if (folded === void 0) return void 0;
449
419
  fields.set(key, folded);
450
420
  }
451
- return { _kind: "res-obj", fields, priorValues: new Map(v.priorValues) };
421
+ return { _kind: "res-obj", fields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
452
422
  }
453
423
  const hv = v;
454
424
  if (hv.kind === "array") {
@@ -497,14 +467,7 @@ function cloneResolverValue(v) {
497
467
  for (const [k, val] of v.fields) newFields.set(k, cloneResolverValue(val));
498
468
  const newPriors = /* @__PURE__ */ new Map();
499
469
  for (const [k, val] of v.priorValues) newPriors.set(k, cloneResolverValue(val));
500
- return { _kind: "res-obj", fields: newFields, priorValues: newPriors };
501
- }
502
- if (isAppend(v)) {
503
- return {
504
- _kind: "append-placeholder",
505
- existing: cloneResolverValue(v.existing),
506
- elem: cloneResolverValue(v.elem)
507
- };
470
+ return { _kind: "res-obj", fields: newFields, priorValues: newPriors, resetKeys: new Set(v.resetKeys) };
508
471
  }
509
472
  const hv = v;
510
473
  if (hv.kind === "array") {
@@ -539,14 +502,11 @@ function foldNestedSelfRefs(v, pathPrefix) {
539
502
  }
540
503
  newFields.set(k, finalVal);
541
504
  }
542
- return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues) };
505
+ return { _kind: "res-obj", fields: newFields, priorValues: new Map(v.priorValues), resetKeys: new Set(v.resetKeys) };
543
506
  }
544
507
  function containsSubstByPath(v, target) {
545
508
  if (isSubst(v)) return !v.knownAbsent && segmentsTextEqual(v.segments, target);
546
509
  if (isConcat(v)) return v.nodes.some((n) => containsSubstByPath(n, target));
547
- if (isAppend(v)) {
548
- return containsSubstByPath(v.existing, target) || containsSubstByPath(v.elem, target);
549
- }
550
510
  if (isResObj(v)) {
551
511
  for (const f of v.fields.values()) {
552
512
  if (containsSubstByPath(f, target)) return true;
@@ -575,6 +535,53 @@ function segmentsTextEqual(a, b) {
575
535
  return true;
576
536
  }
577
537
 
538
+ // src/internal/resolver/types.ts
539
+ var separatorValues = /* @__PURE__ */ new WeakSet();
540
+ function isSubst(v) {
541
+ return v._kind === "subst-placeholder";
542
+ }
543
+ function isConcat(v) {
544
+ return v._kind === "concat-placeholder";
545
+ }
546
+ function isResObj(v) {
547
+ return v._kind === "res-obj";
548
+ }
549
+ function makeResObj() {
550
+ return { _kind: "res-obj", fields: /* @__PURE__ */ new Map(), priorValues: /* @__PURE__ */ new Map(), resetKeys: /* @__PURE__ */ new Set() };
551
+ }
552
+ function mergeUnresolved(receiver, fallback) {
553
+ const result = makeResObj();
554
+ for (const [k, v] of fallback.fields) {
555
+ result.fields.set(k, v);
556
+ }
557
+ for (const [k, v] of fallback.priorValues) {
558
+ result.priorValues.set(k, v);
559
+ }
560
+ for (const [k, rv] of receiver.fields) {
561
+ const existing = result.fields.get(k);
562
+ if (existing !== void 0) {
563
+ const recPrior = receiver.priorValues.get(k);
564
+ if (recPrior !== void 0 && !isResObj(recPrior)) {
565
+ result.fields.set(k, rv);
566
+ continue;
567
+ }
568
+ if (isResObj(rv) && isResObj(existing)) {
569
+ result.fields.set(k, mergeUnresolved(rv, existing));
570
+ continue;
571
+ }
572
+ const foldedPrior = foldOrSkipPrior(existing, k, void 0);
573
+ if (foldedPrior !== void 0) result.priorValues.set(k, foldedPrior);
574
+ }
575
+ result.fields.set(k, rv);
576
+ }
577
+ for (const [k, v] of receiver.priorValues) {
578
+ if (receiver.fields.has(k)) {
579
+ result.priorValues.set(k, v);
580
+ }
581
+ }
582
+ return result;
583
+ }
584
+
578
585
  // src/internal/resolver/utils.ts
579
586
  function segmentsToKey(segments) {
580
587
  return segments.map((s) => {
@@ -628,9 +635,19 @@ function deepMergeResObjInto(dst, src, pathPrefix = []) {
628
635
  deepMergeResObjInto(dstVal, srcVal, childPrefix);
629
636
  } else {
630
637
  if (dstVal !== void 0) {
631
- const priorExisting = dst.priorValues.get(k);
632
- const prior = foldOrSkipPrior(dstVal, fullKey, priorExisting);
633
- if (prior !== void 0) dst.priorValues.set(k, prior);
638
+ if (src.resetKeys.has(k)) {
639
+ dst.priorValues.delete(k);
640
+ } else {
641
+ const dstFolded = foldOrSkipPrior(dstVal, fullKey, dst.priorValues.get(k));
642
+ if (dstFolded !== void 0) {
643
+ const srcPrior = src.priorValues.get(k);
644
+ if (srcPrior !== void 0) {
645
+ dst.priorValues.set(k, foldKnownAbsentSelfRef(srcPrior, fullKey, dstFolded));
646
+ } else {
647
+ dst.priorValues.set(k, dstFolded);
648
+ }
649
+ }
650
+ }
634
651
  }
635
652
  dst.fields.set(k, srcVal);
636
653
  }
@@ -640,6 +657,7 @@ function deepMergeResObjInto(dst, src, pathPrefix = []) {
640
657
  dst.priorValues.set(k, srcPrior);
641
658
  }
642
659
  }
660
+ for (const k of src.resetKeys) dst.resetKeys.add(k);
643
661
  }
644
662
  function hoconValueToResObj(hv) {
645
663
  const obj = makeResObj();
@@ -1896,31 +1914,15 @@ var StructureBuilder = class _StructureBuilder {
1896
1914
  const childPrefix = [...pathPrefix, head];
1897
1915
  const fullKey = stringSegmentsToKey(childPrefix);
1898
1916
  if (field.append) {
1899
- const existing2 = obj.fields.get(head) ?? { kind: "array", items: [] };
1900
- const oldPrior = obj.priorValues.get(head);
1901
- const folded = foldOrSkipPrior(existing2, fullKey, oldPrior);
1902
- if (folded !== void 0) obj.priorValues.set(head, folded);
1903
- obj.fields.set(head, {
1904
- _kind: "append-placeholder",
1905
- // Use the folded existing (self-ref-free) for the Append. When the
1906
- // fold returned undefined (self-ref present but no old prior),
1907
- // fall back to the original existing — resolveSubst will then
1908
- // raise the "self-ref with no prior value" error at resolve time,
1909
- // matching the pre-fix behaviour for that edge case.
1910
- //
1911
- // Clone `folded` again so the Append.existing and priorValues[head]
1912
- // do not share the same Subst/Concat references — relativizeResObj
1913
- // walks BOTH `fields` and `priorValues` and mutates Subst.segments
1914
- // in place, so a shared reference would get its prefix applied
1915
- // twice (resulting in e.g. `${outer.outer.base}` instead of
1916
- // `${outer.base}`). Codex review on PR #131.
1917
- existing: folded !== void 0 ? cloneResolverValue(folded) : existing2,
1918
- elem: this.astToResolverValue(field.value, childPrefix)
1919
- });
1917
+ const synthetic = this.desugarAppend(field, childPrefix);
1918
+ this.applyField(obj, synthetic, pathPrefix);
1920
1919
  return;
1921
1920
  }
1922
1921
  const existing = obj.fields.get(head);
1923
1922
  const newVal = this.astToResolverValue(field.value, childPrefix);
1923
+ if (!containsSelfRef(newVal, fullKey)) {
1924
+ obj.resetKeys.add(head);
1925
+ }
1924
1926
  if (existing !== void 0) {
1925
1927
  const oldPrior = obj.priorValues.get(head);
1926
1928
  const priorInput = isResObj(existing) ? foldNestedSelfRefs(existing, childPrefix) : existing;
@@ -1962,19 +1964,15 @@ var StructureBuilder = class _StructureBuilder {
1962
1964
  const childPrefix = [...pathPrefix, head];
1963
1965
  const fullKey = stringSegmentsToKey(childPrefix);
1964
1966
  if (field.append) {
1965
- const existing2 = obj.fields.get(head) ?? { kind: "array", items: [] };
1966
- const oldPrior = obj.priorValues.get(head);
1967
- const folded = foldOrSkipPrior(existing2, fullKey, oldPrior);
1968
- if (folded !== void 0) obj.priorValues.set(head, folded);
1969
- obj.fields.set(head, {
1970
- _kind: "append-placeholder",
1971
- existing: folded !== void 0 ? cloneResolverValue(folded) : existing2,
1972
- elem: await this.astToResolverValueAsync(field.value, childPrefix)
1973
- });
1967
+ const synthetic = this.desugarAppend(field, childPrefix);
1968
+ await this.applyFieldAsync(obj, synthetic, pathPrefix);
1974
1969
  return;
1975
1970
  }
1976
1971
  const existing = obj.fields.get(head);
1977
1972
  const newVal = await this.astToResolverValueAsync(field.value, childPrefix);
1973
+ if (!containsSelfRef(newVal, fullKey)) {
1974
+ obj.resetKeys.add(head);
1975
+ }
1978
1976
  if (existing !== void 0) {
1979
1977
  const oldPrior = obj.priorValues.get(head);
1980
1978
  const priorInput = isResObj(existing) ? foldNestedSelfRefs(existing, childPrefix) : existing;
@@ -1987,6 +1985,21 @@ var StructureBuilder = class _StructureBuilder {
1987
1985
  }
1988
1986
  obj.fields.set(head, newVal);
1989
1987
  }
1988
+ /** Builds the `key = ${?fullkey} [value]` field that `key += value` desugars
1989
+ * to (S13b.2, HOCON.md L732). `childPrefix` is the field's fully-qualified
1990
+ * path (pathPrefix + key), so a nested `srv { items += x }` references
1991
+ * `${?srv.items}`; include relativization rewrites it under a mount prefix.
1992
+ * `field.key` is already single-segment here (multi-segment keys are split
1993
+ * into nested objects upstream). Returns a NEW AstField (append=false);
1994
+ * positions inherit from the original field so resolve-time errors (the
1995
+ * S13b.2 non-array check, now via the scalar+array concat) keep a location. */
1996
+ desugarAppend(field, childPrefix) {
1997
+ const segments = childPrefix.map((text) => ({ text, line: field.pos.line, col: field.pos.col }));
1998
+ const subst = { kind: "subst", segments, optional: true, listSuffix: false, pos: field.pos };
1999
+ const elemArray = { kind: "array", items: [field.value], pos: field.pos };
2000
+ const synthetic = { kind: "concat", nodes: [subst, elemArray], pos: field.pos };
2001
+ return { key: field.key, value: synthetic, append: false, pos: field.pos };
2002
+ }
1990
2003
  astToResolverValue(ast, pathPrefix) {
1991
2004
  switch (ast.kind) {
1992
2005
  case "scalar": {
@@ -2051,11 +2064,6 @@ var StructureBuilder = class _StructureBuilder {
2051
2064
  }
2052
2065
  return;
2053
2066
  }
2054
- if (isAppend(val)) {
2055
- this.relativizeSubstPaths(val.existing, prefixSegments);
2056
- this.relativizeSubstPaths(val.elem, prefixSegments);
2057
- return;
2058
- }
2059
2067
  if (isResObj(val)) {
2060
2068
  this.relativizeResObj(val, prefixSegments);
2061
2069
  return;
@@ -2204,7 +2212,6 @@ var SubstitutionResolver = class {
2204
2212
  this.resolvingConcats.delete(v);
2205
2213
  }
2206
2214
  }
2207
- if (isAppend(v)) return this.resolveAppend(v, scope);
2208
2215
  if (isResObj(v)) return this.resolveResObj(v);
2209
2216
  const hv = v;
2210
2217
  if (hv.kind === "array") {
@@ -2489,38 +2496,6 @@ var SubstitutionResolver = class {
2489
2496
  }
2490
2497
  return folded;
2491
2498
  }
2492
- resolveAppend(a, scope) {
2493
- const existing = this.resolveVal(a.existing, scope) ?? { kind: "array", items: [] };
2494
- if (this.opts.allowUnresolved && (isSubst(existing) || isConcat(existing) || isAppend(existing))) {
2495
- return a;
2496
- }
2497
- const elem = this.resolveVal(a.elem, scope);
2498
- let priorItems;
2499
- if (existing.kind === "array") {
2500
- priorItems = existing.items;
2501
- } else if (existing.kind === "object") {
2502
- const converted = numericObjectToArray(existing);
2503
- if (converted === null) {
2504
- throw new ResolveError(
2505
- `'+=' on non-array value: prior value is object with non-numeric keys (spec L732)`,
2506
- "",
2507
- 0,
2508
- 0
2509
- );
2510
- }
2511
- priorItems = converted;
2512
- } else {
2513
- throw new ResolveError(
2514
- `'+=' on non-array value: prior value is ${existing.kind} (spec L732)`,
2515
- "",
2516
- 0,
2517
- 0
2518
- );
2519
- }
2520
- const items = [...priorItems];
2521
- if (elem !== void 0) items.push(elem);
2522
- return { kind: "array", items };
2523
- }
2524
2499
  };
2525
2500
 
2526
2501
  // src/internal/resolver/resolver.ts
@@ -2538,7 +2513,7 @@ function containsPlaceholders(tree) {
2538
2513
  }
2539
2514
  function valContainsPlaceholders(v) {
2540
2515
  const rv = v;
2541
- if (isSubst(rv) || isConcat(rv) || isAppend(rv)) return true;
2516
+ if (isSubst(rv) || isConcat(rv)) return true;
2542
2517
  if (isResObj(rv)) return containsPlaceholders(rv);
2543
2518
  const hv = v;
2544
2519
  if (hv?.kind === "array") {
@@ -2549,7 +2524,7 @@ function valContainsPlaceholders(v) {
2549
2524
  function buildPartialHoconFromResObj(tree) {
2550
2525
  const fields = /* @__PURE__ */ new Map();
2551
2526
  for (const [k, v] of tree.fields) {
2552
- if (!isSubst(v) && !isConcat(v) && !isAppend(v)) {
2527
+ if (!isSubst(v) && !isConcat(v)) {
2553
2528
  if (isResObj(v)) {
2554
2529
  fields.set(k, buildPartialHoconFromResObj(v));
2555
2530
  } else {
@@ -2938,7 +2913,7 @@ function hoconToJs(v) {
2938
2913
  function resObjToKeyShape(tree) {
2939
2914
  const fields = /* @__PURE__ */ new Map();
2940
2915
  for (const [k, v] of tree.fields) {
2941
- if (isSubst(v) || isConcat(v) || isAppend(v)) {
2916
+ if (isSubst(v) || isConcat(v)) {
2942
2917
  fields.set(k, { kind: "scalar", raw: "", valueType: "null" });
2943
2918
  } else if (isResObj(v)) {
2944
2919
  fields.set(k, resObjToKeyShape(v));
@@ -2952,7 +2927,7 @@ function stripPlaceholderFields(v) {
2952
2927
  const fields = /* @__PURE__ */ new Map();
2953
2928
  let hadPlaceholders = false;
2954
2929
  for (const [k, val] of v.fields) {
2955
- if (val._kind === "subst-placeholder" || val._kind === "concat-placeholder" || val._kind === "append-placeholder") {
2930
+ if (val._kind === "subst-placeholder" || val._kind === "concat-placeholder") {
2956
2931
  hadPlaceholders = true;
2957
2932
  } else if (val.kind === "object") {
2958
2933
  const inner = stripPlaceholderFields(val);
package/dist/zod.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ZodType } from 'zod';
2
- import { C as Config, a as ParseOptions } from './config-CjSkQ4_l.cjs';
2
+ import { C as Config, a as ParseOptions } from './config-DCSLXkNY.cjs';
3
3
 
4
4
  declare function validate<T>(config: Config, schema: ZodType<T>): T;
5
5
  declare function getValidated<T>(config: Config, path: string, schema: ZodType<T>): T;
package/dist/zod.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ZodType } from 'zod';
2
- import { C as Config, a as ParseOptions } from './config-CjSkQ4_l.js';
2
+ import { C as Config, a as ParseOptions } from './config-DCSLXkNY.js';
3
3
 
4
4
  declare function validate<T>(config: Config, schema: ZodType<T>): T;
5
5
  declare function getValidated<T>(config: Config, path: string, schema: ZodType<T>): T;