@o3co/ts.hocon 1.12.0 → 1.14.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.
Files changed (43) hide show
  1. package/README.ja.md +256 -32
  2. package/README.md +166 -32
  3. package/dist/adapters/env.cjs +26 -1678
  4. package/dist/adapters/env.d.cts +1 -1
  5. package/dist/adapters/env.d.ts +1 -1
  6. package/dist/adapters/env.js +11 -1625
  7. package/dist/adapters/json5.cjs +496 -0
  8. package/dist/adapters/json5.d.cts +47 -0
  9. package/dist/adapters/json5.d.ts +47 -0
  10. package/dist/adapters/json5.js +496 -0
  11. package/dist/adapters/jsonc.cjs +17 -1632
  12. package/dist/adapters/jsonc.d.cts +1 -1
  13. package/dist/adapters/jsonc.d.ts +1 -1
  14. package/dist/adapters/jsonc.js +9 -1586
  15. package/dist/adapters/properties.cjs +7 -1773
  16. package/dist/adapters/properties.d.cts +1 -1
  17. package/dist/adapters/properties.d.ts +1 -1
  18. package/dist/adapters/properties.js +6 -1735
  19. package/dist/adapters/toml.cjs +12 -1626
  20. package/dist/adapters/toml.d.cts +1 -1
  21. package/dist/adapters/toml.d.ts +1 -1
  22. package/dist/adapters/toml.js +10 -1589
  23. package/dist/adapters/yaml.cjs +20 -1635
  24. package/dist/adapters/yaml.d.cts +1 -1
  25. package/dist/adapters/yaml.d.ts +1 -1
  26. package/dist/adapters/yaml.js +10 -1589
  27. package/dist/chunk-GBNQADHT.cjs +83 -0
  28. package/dist/chunk-IMJ7QHIK.cjs +158 -0
  29. package/dist/chunk-QY7ECGS6.js +83 -0
  30. package/dist/chunk-RO4D6BH7.cjs +3792 -0
  31. package/dist/chunk-WTXULUZS.js +3792 -0
  32. package/dist/chunk-XWKO4JM3.js +158 -0
  33. package/dist/{config-Dlq6rF3w.d.cts → config-OccaKqXu.d.cts} +148 -4
  34. package/dist/{config-Dlq6rF3w.d.ts → config-OccaKqXu.d.ts} +148 -4
  35. package/dist/index.cjs +35 -3449
  36. package/dist/index.d.cts +2 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +25 -3383
  39. package/dist/zod.cjs +107 -3291
  40. package/dist/zod.d.cts +83 -3
  41. package/dist/zod.d.ts +83 -3
  42. package/dist/zod.js +95 -3245
  43. package/package.json +12 -2
@@ -0,0 +1,158 @@
1
+ import {
2
+ Config,
3
+ ConfigError,
4
+ ParseError,
5
+ buildTree,
6
+ buildTreeAsync,
7
+ containsPlaceholders,
8
+ guardStackDepth,
9
+ guardStackDepthAsync,
10
+ parseTokens,
11
+ resolve,
12
+ resolveAsync,
13
+ tokenize
14
+ } from "./chunk-WTXULUZS.js";
15
+
16
+ // src/parse.ts
17
+ import * as fs from "fs";
18
+ import * as path from "path";
19
+ function defaultParseOptions() {
20
+ return { resolveSubstitutions: true };
21
+ }
22
+ function defaultResolveOptions() {
23
+ return { useSystemEnvironment: true, allowUnresolved: false };
24
+ }
25
+ function getEnv(opts) {
26
+ if (opts.env !== void 0) return opts.env;
27
+ if (typeof process !== "undefined" && process.env) return process.env;
28
+ return {};
29
+ }
30
+ function defaultReadFileSync(filePath) {
31
+ return fs.readFileSync(filePath, "utf-8");
32
+ }
33
+ async function defaultReadFile(filePath) {
34
+ return fs.promises.readFile(filePath, "utf-8");
35
+ }
36
+ function buildResolveContext(input, opts) {
37
+ const tokens = tokenize(input);
38
+ const ast = parseTokens(tokens);
39
+ if (ast.kind === "array") {
40
+ const origin = opts.originDescription ?? "input";
41
+ throw new ConfigError(
42
+ `${origin}: ${ast.pos.line}:${ast.pos.col}: document has type array rather than object at file root (HOCON.md L989-991); the Config API requires an object root`,
43
+ ""
44
+ );
45
+ }
46
+ const resolveOpts = {
47
+ env: getEnv(opts),
48
+ baseDir: opts.baseDir,
49
+ readFileSync: opts.readFileSync ?? defaultReadFileSync,
50
+ readFile: opts.readFile,
51
+ originDescription: opts.originDescription,
52
+ resolveFrom: opts.resolveFrom,
53
+ packageResolver: opts.packageResolver
54
+ };
55
+ return { ast, resolveOpts };
56
+ }
57
+ function parse(input, opts = {}) {
58
+ return parseStringWithOptions(input, opts);
59
+ }
60
+ var parseString = parse;
61
+ function parseStringWithOptions(input, opts = {}) {
62
+ return guardStackDepth(
63
+ () => parseStringInner(input, opts),
64
+ (msg) => new ParseError(msg, 1, 1, opts.originDescription)
65
+ );
66
+ }
67
+ function parseStringInner(input, opts) {
68
+ const resolveSubstitutions = opts.resolveSubstitutions ?? true;
69
+ const { ast, resolveOpts } = buildResolveContext(input, opts);
70
+ if (resolveSubstitutions) {
71
+ const value = resolve(ast, resolveOpts);
72
+ if (value.kind !== "object") throw new Error("resolved value is not an object");
73
+ return new Config(value, { resolved: true, originDescription: opts.originDescription });
74
+ }
75
+ const tree = buildTree(ast, resolveOpts);
76
+ const hasPlaceholders = containsPlaceholders(tree);
77
+ return Config._fromUnresolvedResObj(tree, {
78
+ parseBaseDir: opts.baseDir,
79
+ originDescription: opts.originDescription,
80
+ resolved: !hasPlaceholders,
81
+ resolveOpts
82
+ });
83
+ }
84
+ function parseFileWithOptions(filePath, opts = {}) {
85
+ if (typeof process === "undefined" && !opts.readFileSync) {
86
+ throw new Error("parseFileWithOptions is not supported in browser environments without opts.readFileSync.");
87
+ }
88
+ const resolvedPath = path.resolve(filePath);
89
+ const readFileSync2 = opts.readFileSync ?? defaultReadFileSync;
90
+ const input = readFileSync2(resolvedPath);
91
+ return parseStringWithOptions(input, {
92
+ ...opts,
93
+ baseDir: opts.baseDir ?? path.dirname(resolvedPath),
94
+ readFileSync: readFileSync2
95
+ });
96
+ }
97
+ async function parseAsync(input, opts = {}) {
98
+ return guardStackDepthAsync(
99
+ () => parseStringInnerAsync(input, opts),
100
+ (msg) => new ParseError(msg, 1, 1, opts.originDescription)
101
+ );
102
+ }
103
+ async function parseStringInnerAsync(input, opts) {
104
+ const resolveSubstitutions = opts.resolveSubstitutions ?? true;
105
+ const { ast, resolveOpts } = buildResolveContext(input, opts);
106
+ if (resolveSubstitutions) {
107
+ const value = await resolveAsync(ast, resolveOpts);
108
+ if (value.kind !== "object") throw new Error("resolved value is not an object");
109
+ return new Config(value, { resolved: true, originDescription: opts.originDescription });
110
+ }
111
+ const tree = await buildTreeAsync(ast, resolveOpts);
112
+ const hasPlaceholders = containsPlaceholders(tree);
113
+ return Config._fromUnresolvedResObj(tree, {
114
+ parseBaseDir: opts.baseDir,
115
+ originDescription: opts.originDescription,
116
+ resolved: !hasPlaceholders,
117
+ resolveOpts
118
+ });
119
+ }
120
+ function parseFile(filePath, opts = {}) {
121
+ if (typeof process === "undefined" && !opts.readFileSync) {
122
+ throw new Error("parseFile is not supported in browser environments. Provide opts.readFileSync or use parse() instead.");
123
+ }
124
+ const resolvedPath = path.resolve(filePath);
125
+ const readFileSync2 = opts.readFileSync ?? defaultReadFileSync;
126
+ const input = readFileSync2(resolvedPath);
127
+ return parse(input, {
128
+ ...opts,
129
+ baseDir: opts.baseDir ?? path.dirname(resolvedPath),
130
+ readFileSync: readFileSync2
131
+ });
132
+ }
133
+ async function parseFileAsync(filePath, opts = {}) {
134
+ if (typeof process === "undefined" && !opts.readFile) {
135
+ throw new Error("parseFileAsync is not supported in browser environments. Provide opts.readFile or use parseAsync() instead.");
136
+ }
137
+ const resolvedPath = path.resolve(filePath);
138
+ const readFile = opts.readFile ?? defaultReadFile;
139
+ const input = await readFile(resolvedPath);
140
+ return parseAsync(input, {
141
+ ...opts,
142
+ baseDir: opts.baseDir ?? path.dirname(resolvedPath),
143
+ readFile,
144
+ readFileSync: opts.readFileSync ?? defaultReadFileSync
145
+ });
146
+ }
147
+
148
+ export {
149
+ defaultParseOptions,
150
+ defaultResolveOptions,
151
+ parse,
152
+ parseString,
153
+ parseStringWithOptions,
154
+ parseFileWithOptions,
155
+ parseAsync,
156
+ parseFile,
157
+ parseFileAsync
158
+ };
@@ -206,6 +206,19 @@ declare function defaultParseOptions(): Required<Pick<ParseOptions, 'resolveSubs
206
206
  /** Returns a ResolveOptions object with Lightbend-aligned defaults:
207
207
  * useSystemEnvironment=true, allowUnresolved=false. */
208
208
  declare function defaultResolveOptions(): Required<ResolveOptions>;
209
+ /**
210
+ * Parse a HOCON string into a Config. Substitutions are resolved unless
211
+ * `opts.resolveSubstitutions` is false (then the Config is unresolved; finish
212
+ * it with `resolve()` / `resolveWith()`). Includes are read with
213
+ * `opts.readFileSync` (default: `fs`). A bare `include "x.conf"` resolves
214
+ * relative to `opts.baseDir` (default: the current directory); a relative
215
+ * `include file("x.conf")` always resolves from the current directory.
216
+ *
217
+ * @throws {@link ParseError} on a syntax error, or a document nested too deeply.
218
+ * @throws {@link ResolveError} on a substitution that cannot be resolved, a cycle,
219
+ * or a required include that cannot be found.
220
+ * @throws {@link ConfigError} when the document root is not an object.
221
+ */
209
222
  declare function parse(input: string, opts?: ParseOptions): Config;
210
223
  /** Lightbend-aligned alias for parse(). Produces a fully resolved Config. */
211
224
  declare const parseString: typeof parse;
@@ -220,11 +233,35 @@ declare function parseFileWithOptions(filePath: string, opts?: ParseOptions): Co
220
233
  * asynchronously via `readFile` when provided.
221
234
  */
222
235
  declare function parseAsync(input: string, opts?: ParseOptions): Promise<Config>;
236
+ /**
237
+ * Read and parse a HOCON file, as {@link parse} does with the file's text; a
238
+ * bare `include` resolves relative to the file's directory (unless
239
+ * `opts.baseDir` is set), a relative `include file(...)` from the current
240
+ * directory. Needs Node.js, or `opts.readFileSync` elsewhere.
241
+ *
242
+ * @throws as {@link parse}, plus whatever reading the file throws.
243
+ */
223
244
  declare function parseFile(filePath: string, opts?: ParseOptions): Config;
245
+ /**
246
+ * {@link parseFile} with the file and its includes read asynchronously
247
+ * (`opts.readFile`, default `fs.promises`). Needs Node.js, or `opts.readFile`
248
+ * elsewhere.
249
+ *
250
+ * @throws (rejects) as {@link parseFile}.
251
+ */
224
252
  declare function parseFileAsync(filePath: string, opts?: ParseOptions): Promise<Config>;
225
253
 
226
254
  type DurationUnit = 'ns' | 'us' | 'ms' | 's' | 'm' | 'h' | 'd';
227
255
  type ByteUnit = 'B' | 'KB' | 'KiB' | 'MB' | 'MiB' | 'GB' | 'GiB' | 'TB' | 'TiB';
256
+ /**
257
+ * A calendar period, as {@link Config.getPeriod} returns it. Weeks are folded
258
+ * into days (`2w` is 14 days). A component may be negative.
259
+ */
260
+ interface Period {
261
+ readonly years: number;
262
+ readonly months: number;
263
+ readonly days: number;
264
+ }
228
265
 
229
266
  declare class Config {
230
267
  private readonly root;
@@ -236,6 +273,13 @@ declare class Config {
236
273
  readonly _originDescription: string | undefined;
237
274
  /** @internal ResObj tree for deferred-resolution path. Set when resolved=false. */
238
275
  readonly _resObjRoot: ResObj | undefined;
276
+ /**
277
+ * @internal What is still unresolved after a partial resolve
278
+ * (`allowUnresolved: true`), with resolved values in place. The unresolved
279
+ * checks read this; `_resObjRoot` keeps the original tree for the next
280
+ * resolve. Unset when the two are the same (a deferred parse).
281
+ */
282
+ private readonly _pendingRoot;
239
283
  /** @internal ResolveOptions stored for the resolve() call. */
240
284
  private readonly _resolveOpts;
241
285
  constructor(root: HoconValue & {
@@ -245,6 +289,7 @@ declare class Config {
245
289
  parseBaseDir?: string;
246
290
  originDescription?: string;
247
291
  resObjRoot?: ResObj;
292
+ pendingRoot?: ResObj;
248
293
  resolveOpts?: ResolveOptions$1;
249
294
  });
250
295
  /** Returns true when the Config's value tree contains no unresolved
@@ -279,13 +324,87 @@ declare class Config {
279
324
  * cannot be represented. This matches `getConfig` / `getList`.
280
325
  */
281
326
  getValue(path: string): ReadonlyHoconValue | undefined;
327
+ /**
328
+ * The scalar at `path` as its text: a number or boolean comes back as written
329
+ * (`8080`, `true`).
330
+ *
331
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
332
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is
333
+ * `null`.
334
+ */
282
335
  getString(path: string): string;
336
+ /**
337
+ * The scalar at `path` as a number. A string that reads as a decimal number
338
+ * (`"8080"`, `"1.5e3"`) is accepted.
339
+ *
340
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
341
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is not a
342
+ * number.
343
+ */
283
344
  getNumber(path: string): number;
345
+ /**
346
+ * The scalar at `path` as a boolean: `true` / `yes` / `on` and `false` /
347
+ * `no` / `off`, in any case.
348
+ *
349
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
350
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is not one
351
+ * of those words.
352
+ */
284
353
  getBoolean(path: string): boolean;
354
+ /**
355
+ * The duration at `path` in `unit` (default `ms`): a string with a unit
356
+ * (`"30s"`, `"1.5h"`), or a number or unit-less string, which is
357
+ * milliseconds. The number is read exactly and rounded once in `unit` (E20).
358
+ * Negative durations are allowed.
359
+ *
360
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
361
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, the text is
362
+ * not a duration, or the result is not a finite number (E21).
363
+ */
285
364
  getDuration(path: string, unit?: DurationUnit): number;
365
+ /**
366
+ * The byte size at `path` in `unit` (default `B`): a string with a unit
367
+ * (`"64KiB"`, `"1.5MB"`), or a number or unit-less string, which is bytes.
368
+ * The exact size is truncated toward zero to whole bytes, then converted to
369
+ * `unit` (E20).
370
+ *
371
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
372
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, the text is
373
+ * not a byte size, the size is negative, or it exceeds 2^53-1 bytes (the
374
+ * largest integer a JS number holds exactly).
375
+ */
286
376
  getBytes(path: string, unit?: ByteUnit): number;
377
+ /**
378
+ * The calendar period at `path` (`7d`, `2w`, `3m`, `1y`; a bare integer is
379
+ * days). Integer only, unlike {@link getDuration} / {@link getBytes}.
380
+ *
381
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
382
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, or the text
383
+ * is not a period.
384
+ */
385
+ getPeriod(path: string): Period;
386
+ /**
387
+ * The object at `path` as a Config of its own, with paths relative to it.
388
+ *
389
+ * @throws {@link NotResolvedError} when the object holds an unresolved substitution.
390
+ * @throws {@link ConfigError} when `path` is missing or is not an object.
391
+ */
287
392
  getConfig(path: string): Config;
393
+ /**
394
+ * The list at `path` as plain values (see {@link get}). An object with integer
395
+ * keys (`"0"`, `"1"`, …) is read as a list too, in key order with gaps closed
396
+ * up; its other keys are ignored (S15).
397
+ *
398
+ * @throws {@link NotResolvedError} when the list holds an unresolved substitution.
399
+ * @throws {@link ConfigError} when `path` is missing or is not a list.
400
+ */
288
401
  getList(path: string): unknown[];
402
+ /**
403
+ * Whether `path` is present. A path whose value is still an unresolved
404
+ * substitution is present too (`true`, no throw), as in go.hocon; reading it
405
+ * throws {@link NotResolvedError}. A path *under* such a value is not known
406
+ * yet and answers `false`.
407
+ */
289
408
  has(path: string): boolean;
290
409
  keys(): string[];
291
410
  withFallback(fallback: Config | undefined): Config;
@@ -363,6 +482,28 @@ declare class Config {
363
482
  toObject(opts?: {
364
483
  nullPrototype?: boolean;
365
484
  }): unknown;
485
+ /**
486
+ * Renders this resolved Config as HOCON text (E18; lockstep with go.hocon's
487
+ * `Config.RenderHOCON`, v1.11.0).
488
+ *
489
+ * The output round-trips: parsing it back yields the same value tree. That
490
+ * is the correctness contract, not byte-for-byte formatting — a scalar is
491
+ * quoted whenever leaving it bare would re-parse as a different type (a
492
+ * string `"8080"` becomes `"8080"`, not `8080`), and left bare only when it
493
+ * provably cannot.
494
+ *
495
+ * The Config must be resolved and hold only data (objects, arrays, string /
496
+ * number / boolean / null scalars) — exactly what {@link fromMap} and the
497
+ * format adapters produce. An unresolved placeholder throws
498
+ * {@link ConfigError}; substitutions have no textual round trip through a
499
+ * value tree.
500
+ *
501
+ * The root object's fields are emitted without enclosing braces, nested
502
+ * objects as `key { … }`, arrays as newline-separated `[ … ]`, indented two
503
+ * spaces. Source comments are not represented — a value tree does not carry
504
+ * them.
505
+ */
506
+ renderHocon(): string;
366
507
  /**
367
508
  * @internal Test-only: renders this resolved Config's value tree as canonical
368
509
  * JSON (sorted keys, no whitespace). Used by Layer-2 fixture tests to compare
@@ -372,9 +513,12 @@ declare class Config {
372
513
  */
373
514
  _renderJSONForTest(): string;
374
515
  private lookupNode;
516
+ /** Whether `path` names a field in the unresolved tree (a placeholder included). */
517
+ private _unresolvedTreeHas;
375
518
  /**
376
- * _resObjRootSubtreeHasPlaceholders — walk _resObjRoot to the given path and
377
- * return true if the subtree there contains any unresolved placeholder.
519
+ * _subtreeHasPlaceholders — walk the unresolved tree (`_pendingRoot` after a
520
+ * partial resolve, else `_resObjRoot`) to the given path and return true if
521
+ * the subtree there contains any unresolved placeholder.
378
522
  * Used by getConfig / getList (T2) to detect transitive unresolved placeholders
379
523
  * in object / array subtrees that would otherwise appear to be "resolved" in the
380
524
  * partial HoconValue root (because individual leaf fields are omitted rather than
@@ -382,8 +526,8 @@ declare class Config {
382
526
  * sub-containers are retained in the partial root with the placeholder-keyed
383
527
  * fields omitted from them — so the object appears "present but empty-ish").
384
528
  */
385
- private _resObjRootSubtreeHasPlaceholders;
529
+ private _subtreeHasPlaceholders;
386
530
  private requireScalar;
387
531
  }
388
532
 
389
- export { type ByteUnit as B, Config as C, type DurationUnit as D, type HoconValue as H, type PackageResolver as P, type ReadonlyHoconValue as R, type ScalarValueType as S, type ParseOptions as a, type ResolveOptions as b, asArray as c, asBoolean as d, asNumber as e, asObject as f, asString as g, defaultParseOptions as h, defaultResolveOptions as i, isArray as j, isNull as k, isObject as l, isScalar as m, parseAsync as n, parseFile as o, parse as p, parseFileAsync as q, parseFileWithOptions as r, parseString as s, parseStringWithOptions as t };
533
+ export { type ByteUnit as B, Config as C, type DurationUnit as D, type HoconValue as H, type PackageResolver as P, type ReadonlyHoconValue as R, type ScalarValueType as S, type ParseOptions as a, type Period as b, type ResolveOptions as c, asArray as d, asBoolean as e, asNumber as f, asObject as g, asString as h, defaultParseOptions as i, defaultResolveOptions as j, isArray as k, isNull as l, isObject as m, isScalar as n, parseAsync as o, parse as p, parseFile as q, parseFileAsync as r, parseFileWithOptions as s, parseString as t, parseStringWithOptions as u };
@@ -206,6 +206,19 @@ declare function defaultParseOptions(): Required<Pick<ParseOptions, 'resolveSubs
206
206
  /** Returns a ResolveOptions object with Lightbend-aligned defaults:
207
207
  * useSystemEnvironment=true, allowUnresolved=false. */
208
208
  declare function defaultResolveOptions(): Required<ResolveOptions>;
209
+ /**
210
+ * Parse a HOCON string into a Config. Substitutions are resolved unless
211
+ * `opts.resolveSubstitutions` is false (then the Config is unresolved; finish
212
+ * it with `resolve()` / `resolveWith()`). Includes are read with
213
+ * `opts.readFileSync` (default: `fs`). A bare `include "x.conf"` resolves
214
+ * relative to `opts.baseDir` (default: the current directory); a relative
215
+ * `include file("x.conf")` always resolves from the current directory.
216
+ *
217
+ * @throws {@link ParseError} on a syntax error, or a document nested too deeply.
218
+ * @throws {@link ResolveError} on a substitution that cannot be resolved, a cycle,
219
+ * or a required include that cannot be found.
220
+ * @throws {@link ConfigError} when the document root is not an object.
221
+ */
209
222
  declare function parse(input: string, opts?: ParseOptions): Config;
210
223
  /** Lightbend-aligned alias for parse(). Produces a fully resolved Config. */
211
224
  declare const parseString: typeof parse;
@@ -220,11 +233,35 @@ declare function parseFileWithOptions(filePath: string, opts?: ParseOptions): Co
220
233
  * asynchronously via `readFile` when provided.
221
234
  */
222
235
  declare function parseAsync(input: string, opts?: ParseOptions): Promise<Config>;
236
+ /**
237
+ * Read and parse a HOCON file, as {@link parse} does with the file's text; a
238
+ * bare `include` resolves relative to the file's directory (unless
239
+ * `opts.baseDir` is set), a relative `include file(...)` from the current
240
+ * directory. Needs Node.js, or `opts.readFileSync` elsewhere.
241
+ *
242
+ * @throws as {@link parse}, plus whatever reading the file throws.
243
+ */
223
244
  declare function parseFile(filePath: string, opts?: ParseOptions): Config;
245
+ /**
246
+ * {@link parseFile} with the file and its includes read asynchronously
247
+ * (`opts.readFile`, default `fs.promises`). Needs Node.js, or `opts.readFile`
248
+ * elsewhere.
249
+ *
250
+ * @throws (rejects) as {@link parseFile}.
251
+ */
224
252
  declare function parseFileAsync(filePath: string, opts?: ParseOptions): Promise<Config>;
225
253
 
226
254
  type DurationUnit = 'ns' | 'us' | 'ms' | 's' | 'm' | 'h' | 'd';
227
255
  type ByteUnit = 'B' | 'KB' | 'KiB' | 'MB' | 'MiB' | 'GB' | 'GiB' | 'TB' | 'TiB';
256
+ /**
257
+ * A calendar period, as {@link Config.getPeriod} returns it. Weeks are folded
258
+ * into days (`2w` is 14 days). A component may be negative.
259
+ */
260
+ interface Period {
261
+ readonly years: number;
262
+ readonly months: number;
263
+ readonly days: number;
264
+ }
228
265
 
229
266
  declare class Config {
230
267
  private readonly root;
@@ -236,6 +273,13 @@ declare class Config {
236
273
  readonly _originDescription: string | undefined;
237
274
  /** @internal ResObj tree for deferred-resolution path. Set when resolved=false. */
238
275
  readonly _resObjRoot: ResObj | undefined;
276
+ /**
277
+ * @internal What is still unresolved after a partial resolve
278
+ * (`allowUnresolved: true`), with resolved values in place. The unresolved
279
+ * checks read this; `_resObjRoot` keeps the original tree for the next
280
+ * resolve. Unset when the two are the same (a deferred parse).
281
+ */
282
+ private readonly _pendingRoot;
239
283
  /** @internal ResolveOptions stored for the resolve() call. */
240
284
  private readonly _resolveOpts;
241
285
  constructor(root: HoconValue & {
@@ -245,6 +289,7 @@ declare class Config {
245
289
  parseBaseDir?: string;
246
290
  originDescription?: string;
247
291
  resObjRoot?: ResObj;
292
+ pendingRoot?: ResObj;
248
293
  resolveOpts?: ResolveOptions$1;
249
294
  });
250
295
  /** Returns true when the Config's value tree contains no unresolved
@@ -279,13 +324,87 @@ declare class Config {
279
324
  * cannot be represented. This matches `getConfig` / `getList`.
280
325
  */
281
326
  getValue(path: string): ReadonlyHoconValue | undefined;
327
+ /**
328
+ * The scalar at `path` as its text: a number or boolean comes back as written
329
+ * (`8080`, `true`).
330
+ *
331
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
332
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is
333
+ * `null`.
334
+ */
282
335
  getString(path: string): string;
336
+ /**
337
+ * The scalar at `path` as a number. A string that reads as a decimal number
338
+ * (`"8080"`, `"1.5e3"`) is accepted.
339
+ *
340
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
341
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is not a
342
+ * number.
343
+ */
283
344
  getNumber(path: string): number;
345
+ /**
346
+ * The scalar at `path` as a boolean: `true` / `yes` / `on` and `false` /
347
+ * `no` / `off`, in any case.
348
+ *
349
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
350
+ * @throws {@link ConfigError} when `path` is missing or is not a scalar, or the value is not one
351
+ * of those words.
352
+ */
284
353
  getBoolean(path: string): boolean;
354
+ /**
355
+ * The duration at `path` in `unit` (default `ms`): a string with a unit
356
+ * (`"30s"`, `"1.5h"`), or a number or unit-less string, which is
357
+ * milliseconds. The number is read exactly and rounded once in `unit` (E20).
358
+ * Negative durations are allowed.
359
+ *
360
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
361
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, the text is
362
+ * not a duration, or the result is not a finite number (E21).
363
+ */
285
364
  getDuration(path: string, unit?: DurationUnit): number;
365
+ /**
366
+ * The byte size at `path` in `unit` (default `B`): a string with a unit
367
+ * (`"64KiB"`, `"1.5MB"`), or a number or unit-less string, which is bytes.
368
+ * The exact size is truncated toward zero to whole bytes, then converted to
369
+ * `unit` (E20).
370
+ *
371
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
372
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, the text is
373
+ * not a byte size, the size is negative, or it exceeds 2^53-1 bytes (the
374
+ * largest integer a JS number holds exactly).
375
+ */
286
376
  getBytes(path: string, unit?: ByteUnit): number;
377
+ /**
378
+ * The calendar period at `path` (`7d`, `2w`, `3m`, `1y`; a bare integer is
379
+ * days). Integer only, unlike {@link getDuration} / {@link getBytes}.
380
+ *
381
+ * @throws {@link NotResolvedError} when the value is an unresolved substitution.
382
+ * @throws {@link ConfigError} when `path` is missing or is not a string or number, or the text
383
+ * is not a period.
384
+ */
385
+ getPeriod(path: string): Period;
386
+ /**
387
+ * The object at `path` as a Config of its own, with paths relative to it.
388
+ *
389
+ * @throws {@link NotResolvedError} when the object holds an unresolved substitution.
390
+ * @throws {@link ConfigError} when `path` is missing or is not an object.
391
+ */
287
392
  getConfig(path: string): Config;
393
+ /**
394
+ * The list at `path` as plain values (see {@link get}). An object with integer
395
+ * keys (`"0"`, `"1"`, …) is read as a list too, in key order with gaps closed
396
+ * up; its other keys are ignored (S15).
397
+ *
398
+ * @throws {@link NotResolvedError} when the list holds an unresolved substitution.
399
+ * @throws {@link ConfigError} when `path` is missing or is not a list.
400
+ */
288
401
  getList(path: string): unknown[];
402
+ /**
403
+ * Whether `path` is present. A path whose value is still an unresolved
404
+ * substitution is present too (`true`, no throw), as in go.hocon; reading it
405
+ * throws {@link NotResolvedError}. A path *under* such a value is not known
406
+ * yet and answers `false`.
407
+ */
289
408
  has(path: string): boolean;
290
409
  keys(): string[];
291
410
  withFallback(fallback: Config | undefined): Config;
@@ -363,6 +482,28 @@ declare class Config {
363
482
  toObject(opts?: {
364
483
  nullPrototype?: boolean;
365
484
  }): unknown;
485
+ /**
486
+ * Renders this resolved Config as HOCON text (E18; lockstep with go.hocon's
487
+ * `Config.RenderHOCON`, v1.11.0).
488
+ *
489
+ * The output round-trips: parsing it back yields the same value tree. That
490
+ * is the correctness contract, not byte-for-byte formatting — a scalar is
491
+ * quoted whenever leaving it bare would re-parse as a different type (a
492
+ * string `"8080"` becomes `"8080"`, not `8080`), and left bare only when it
493
+ * provably cannot.
494
+ *
495
+ * The Config must be resolved and hold only data (objects, arrays, string /
496
+ * number / boolean / null scalars) — exactly what {@link fromMap} and the
497
+ * format adapters produce. An unresolved placeholder throws
498
+ * {@link ConfigError}; substitutions have no textual round trip through a
499
+ * value tree.
500
+ *
501
+ * The root object's fields are emitted without enclosing braces, nested
502
+ * objects as `key { … }`, arrays as newline-separated `[ … ]`, indented two
503
+ * spaces. Source comments are not represented — a value tree does not carry
504
+ * them.
505
+ */
506
+ renderHocon(): string;
366
507
  /**
367
508
  * @internal Test-only: renders this resolved Config's value tree as canonical
368
509
  * JSON (sorted keys, no whitespace). Used by Layer-2 fixture tests to compare
@@ -372,9 +513,12 @@ declare class Config {
372
513
  */
373
514
  _renderJSONForTest(): string;
374
515
  private lookupNode;
516
+ /** Whether `path` names a field in the unresolved tree (a placeholder included). */
517
+ private _unresolvedTreeHas;
375
518
  /**
376
- * _resObjRootSubtreeHasPlaceholders — walk _resObjRoot to the given path and
377
- * return true if the subtree there contains any unresolved placeholder.
519
+ * _subtreeHasPlaceholders — walk the unresolved tree (`_pendingRoot` after a
520
+ * partial resolve, else `_resObjRoot`) to the given path and return true if
521
+ * the subtree there contains any unresolved placeholder.
378
522
  * Used by getConfig / getList (T2) to detect transitive unresolved placeholders
379
523
  * in object / array subtrees that would otherwise appear to be "resolved" in the
380
524
  * partial HoconValue root (because individual leaf fields are omitted rather than
@@ -382,8 +526,8 @@ declare class Config {
382
526
  * sub-containers are retained in the partial root with the placeholder-keyed
383
527
  * fields omitted from them — so the object appears "present but empty-ish").
384
528
  */
385
- private _resObjRootSubtreeHasPlaceholders;
529
+ private _subtreeHasPlaceholders;
386
530
  private requireScalar;
387
531
  }
388
532
 
389
- export { type ByteUnit as B, Config as C, type DurationUnit as D, type HoconValue as H, type PackageResolver as P, type ReadonlyHoconValue as R, type ScalarValueType as S, type ParseOptions as a, type ResolveOptions as b, asArray as c, asBoolean as d, asNumber as e, asObject as f, asString as g, defaultParseOptions as h, defaultResolveOptions as i, isArray as j, isNull as k, isObject as l, isScalar as m, parseAsync as n, parseFile as o, parse as p, parseFileAsync as q, parseFileWithOptions as r, parseString as s, parseStringWithOptions as t };
533
+ export { type ByteUnit as B, Config as C, type DurationUnit as D, type HoconValue as H, type PackageResolver as P, type ReadonlyHoconValue as R, type ScalarValueType as S, type ParseOptions as a, type Period as b, type ResolveOptions as c, asArray as d, asBoolean as e, asNumber as f, asObject as g, asString as h, defaultParseOptions as i, defaultResolveOptions as j, isArray as k, isNull as l, isObject as m, isScalar as n, parseAsync as o, parse as p, parseFile as q, parseFileAsync as r, parseFileWithOptions as s, parseString as t, parseStringWithOptions as u };