@fgv/ts-utils 5.0.0-3 → 5.0.0-30

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 (164) hide show
  1. package/CHANGELOG.json +0 -21
  2. package/dist/ts-utils.d.ts +364 -41
  3. package/dist/tsdoc-metadata.json +1 -1
  4. package/eslint.config.js +37 -0
  5. package/lib/index.d.ts +2 -1
  6. package/lib/index.js +3 -1
  7. package/lib/packlets/base/index.d.ts +0 -2
  8. package/lib/packlets/base/index.js +1 -25
  9. package/lib/packlets/base/result.d.ts +61 -0
  10. package/lib/packlets/base/result.js +49 -0
  11. package/lib/packlets/collections/collector.d.ts +9 -0
  12. package/lib/packlets/collections/collector.js +6 -0
  13. package/lib/packlets/collections/validatingCollector.d.ts +5 -1
  14. package/lib/packlets/conversion/baseConverter.js +0 -1
  15. package/lib/packlets/conversion/converters.js +0 -2
  16. package/lib/packlets/conversion/objectConverter.js +1 -2
  17. package/lib/packlets/hash/crcNormalizer.js +3 -1
  18. package/lib/packlets/hash/hashingNormalizer.js +4 -3
  19. package/lib/packlets/logging/index.d.ts +3 -0
  20. package/lib/packlets/logging/index.js +40 -0
  21. package/lib/packlets/logging/logReporter.d.ts +88 -0
  22. package/lib/packlets/logging/logReporter.js +114 -0
  23. package/lib/packlets/logging/logger.d.ts +197 -0
  24. package/lib/packlets/logging/logger.js +244 -0
  25. package/lib/packlets/validation/array.d.ts +2 -1
  26. package/lib/packlets/validation/array.js +2 -1
  27. package/lib/packlets/validation/common.d.ts +0 -8
  28. package/lib/packlets/validation/field.d.ts +1 -1
  29. package/lib/packlets/validation/field.js +1 -1
  30. package/lib/packlets/validation/genericValidator.d.ts +1 -6
  31. package/lib/packlets/validation/genericValidator.js +11 -11
  32. package/lib/packlets/validation/object.d.ts +1 -1
  33. package/lib/packlets/validation/object.js +1 -2
  34. package/lib/packlets/validation/oneOf.d.ts +2 -1
  35. package/lib/packlets/validation/oneOf.js +2 -1
  36. package/lib/packlets/validation/typeGuard.d.ts +3 -2
  37. package/lib/packlets/validation/typeGuard.js +2 -1
  38. package/lib/packlets/validation/validator.d.ts +7 -0
  39. package/lib/packlets/validation/validatorBase.d.ts +2 -1
  40. package/lib/packlets/validation/validatorBase.js +1 -1
  41. package/lib/packlets/validation/validators.d.ts +2 -2
  42. package/lib/packlets/validation/validators.js +3 -3
  43. package/package.json +16 -16
  44. package/CHANGELOG.md +0 -135
  45. package/lib/index.d.ts.map +0 -1
  46. package/lib/index.js.map +0 -1
  47. package/lib/packlets/base/brand.d.ts.map +0 -1
  48. package/lib/packlets/base/brand.js.map +0 -1
  49. package/lib/packlets/base/index.d.ts.map +0 -1
  50. package/lib/packlets/base/index.js.map +0 -1
  51. package/lib/packlets/base/logger.d.ts +0 -52
  52. package/lib/packlets/base/logger.d.ts.map +0 -1
  53. package/lib/packlets/base/logger.js +0 -128
  54. package/lib/packlets/base/logger.js.map +0 -1
  55. package/lib/packlets/base/mapResults.d.ts.map +0 -1
  56. package/lib/packlets/base/mapResults.js.map +0 -1
  57. package/lib/packlets/base/messageAggregator.d.ts.map +0 -1
  58. package/lib/packlets/base/messageAggregator.js.map +0 -1
  59. package/lib/packlets/base/normalize.d.ts.map +0 -1
  60. package/lib/packlets/base/normalize.js.map +0 -1
  61. package/lib/packlets/base/result.d.ts.map +0 -1
  62. package/lib/packlets/base/result.js.map +0 -1
  63. package/lib/packlets/base/utils.d.ts.map +0 -1
  64. package/lib/packlets/base/utils.js.map +0 -1
  65. package/lib/packlets/collections/collectible.d.ts.map +0 -1
  66. package/lib/packlets/collections/collectible.js.map +0 -1
  67. package/lib/packlets/collections/collector.d.ts.map +0 -1
  68. package/lib/packlets/collections/collector.js.map +0 -1
  69. package/lib/packlets/collections/collectorValidator.d.ts.map +0 -1
  70. package/lib/packlets/collections/collectorValidator.js.map +0 -1
  71. package/lib/packlets/collections/common.d.ts.map +0 -1
  72. package/lib/packlets/collections/common.js.map +0 -1
  73. package/lib/packlets/collections/convertingCollector.d.ts.map +0 -1
  74. package/lib/packlets/collections/convertingCollector.js.map +0 -1
  75. package/lib/packlets/collections/convertingCollectorValidator.d.ts.map +0 -1
  76. package/lib/packlets/collections/convertingCollectorValidator.js.map +0 -1
  77. package/lib/packlets/collections/index.d.ts.map +0 -1
  78. package/lib/packlets/collections/index.js.map +0 -1
  79. package/lib/packlets/collections/keyValueConverters.d.ts.map +0 -1
  80. package/lib/packlets/collections/keyValueConverters.js.map +0 -1
  81. package/lib/packlets/collections/readonlyResultMap.d.ts.map +0 -1
  82. package/lib/packlets/collections/readonlyResultMap.js.map +0 -1
  83. package/lib/packlets/collections/resultMap.d.ts.map +0 -1
  84. package/lib/packlets/collections/resultMap.js.map +0 -1
  85. package/lib/packlets/collections/resultMapValidator.d.ts.map +0 -1
  86. package/lib/packlets/collections/resultMapValidator.js.map +0 -1
  87. package/lib/packlets/collections/utils.d.ts.map +0 -1
  88. package/lib/packlets/collections/utils.js.map +0 -1
  89. package/lib/packlets/collections/validatingCollector.d.ts.map +0 -1
  90. package/lib/packlets/collections/validatingCollector.js.map +0 -1
  91. package/lib/packlets/collections/validatingConvertingCollector.d.ts.map +0 -1
  92. package/lib/packlets/collections/validatingConvertingCollector.js.map +0 -1
  93. package/lib/packlets/collections/validatingResultMap.d.ts.map +0 -1
  94. package/lib/packlets/collections/validatingResultMap.js.map +0 -1
  95. package/lib/packlets/conversion/baseConverter.d.ts.map +0 -1
  96. package/lib/packlets/conversion/baseConverter.js.map +0 -1
  97. package/lib/packlets/conversion/converter.d.ts.map +0 -1
  98. package/lib/packlets/conversion/converter.js.map +0 -1
  99. package/lib/packlets/conversion/converters.d.ts.map +0 -1
  100. package/lib/packlets/conversion/converters.js.map +0 -1
  101. package/lib/packlets/conversion/defaultingConverter.d.ts.map +0 -1
  102. package/lib/packlets/conversion/defaultingConverter.js.map +0 -1
  103. package/lib/packlets/conversion/index.d.ts.map +0 -1
  104. package/lib/packlets/conversion/index.js.map +0 -1
  105. package/lib/packlets/conversion/objectConverter.d.ts.map +0 -1
  106. package/lib/packlets/conversion/objectConverter.js.map +0 -1
  107. package/lib/packlets/conversion/stringConverter.d.ts.map +0 -1
  108. package/lib/packlets/conversion/stringConverter.js.map +0 -1
  109. package/lib/packlets/file-tree/directoryItem.d.ts.map +0 -1
  110. package/lib/packlets/file-tree/directoryItem.js.map +0 -1
  111. package/lib/packlets/file-tree/fileItem.d.ts.map +0 -1
  112. package/lib/packlets/file-tree/fileItem.js.map +0 -1
  113. package/lib/packlets/file-tree/fileTree.d.ts.map +0 -1
  114. package/lib/packlets/file-tree/fileTree.js.map +0 -1
  115. package/lib/packlets/file-tree/fileTreeAccessors.d.ts.map +0 -1
  116. package/lib/packlets/file-tree/fileTreeAccessors.js.map +0 -1
  117. package/lib/packlets/file-tree/fsTree.d.ts.map +0 -1
  118. package/lib/packlets/file-tree/fsTree.js.map +0 -1
  119. package/lib/packlets/file-tree/in-memory/inMemoryTree.d.ts.map +0 -1
  120. package/lib/packlets/file-tree/in-memory/inMemoryTree.js.map +0 -1
  121. package/lib/packlets/file-tree/in-memory/index.d.ts.map +0 -1
  122. package/lib/packlets/file-tree/in-memory/index.js.map +0 -1
  123. package/lib/packlets/file-tree/in-memory/treeBuilder.d.ts.map +0 -1
  124. package/lib/packlets/file-tree/in-memory/treeBuilder.js.map +0 -1
  125. package/lib/packlets/file-tree/index.d.ts.map +0 -1
  126. package/lib/packlets/file-tree/index.js.map +0 -1
  127. package/lib/packlets/hash/crcNormalizer.d.ts.map +0 -1
  128. package/lib/packlets/hash/crcNormalizer.js.map +0 -1
  129. package/lib/packlets/hash/hashingNormalizer.d.ts.map +0 -1
  130. package/lib/packlets/hash/hashingNormalizer.js.map +0 -1
  131. package/lib/packlets/hash/index.d.ts.map +0 -1
  132. package/lib/packlets/hash/index.js.map +0 -1
  133. package/lib/packlets/validation/array.d.ts.map +0 -1
  134. package/lib/packlets/validation/array.js.map +0 -1
  135. package/lib/packlets/validation/boolean.d.ts.map +0 -1
  136. package/lib/packlets/validation/boolean.js.map +0 -1
  137. package/lib/packlets/validation/classes.d.ts.map +0 -1
  138. package/lib/packlets/validation/classes.js.map +0 -1
  139. package/lib/packlets/validation/common.d.ts.map +0 -1
  140. package/lib/packlets/validation/common.js.map +0 -1
  141. package/lib/packlets/validation/field.d.ts.map +0 -1
  142. package/lib/packlets/validation/field.js.map +0 -1
  143. package/lib/packlets/validation/genericValidator.d.ts.map +0 -1
  144. package/lib/packlets/validation/genericValidator.js.map +0 -1
  145. package/lib/packlets/validation/index.d.ts.map +0 -1
  146. package/lib/packlets/validation/index.js.map +0 -1
  147. package/lib/packlets/validation/number.d.ts.map +0 -1
  148. package/lib/packlets/validation/number.js.map +0 -1
  149. package/lib/packlets/validation/object.d.ts.map +0 -1
  150. package/lib/packlets/validation/object.js.map +0 -1
  151. package/lib/packlets/validation/oneOf.d.ts.map +0 -1
  152. package/lib/packlets/validation/oneOf.js.map +0 -1
  153. package/lib/packlets/validation/string.d.ts.map +0 -1
  154. package/lib/packlets/validation/string.js.map +0 -1
  155. package/lib/packlets/validation/traits.d.ts.map +0 -1
  156. package/lib/packlets/validation/traits.js.map +0 -1
  157. package/lib/packlets/validation/typeGuard.d.ts.map +0 -1
  158. package/lib/packlets/validation/typeGuard.js.map +0 -1
  159. package/lib/packlets/validation/validator.d.ts.map +0 -1
  160. package/lib/packlets/validation/validator.js.map +0 -1
  161. package/lib/packlets/validation/validatorBase.d.ts.map +0 -1
  162. package/lib/packlets/validation/validatorBase.js.map +0 -1
  163. package/lib/packlets/validation/validators.d.ts.map +0 -1
  164. package/lib/packlets/validation/validators.js.map +0 -1
package/CHANGELOG.json CHANGED
@@ -1,27 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-utils",
3
3
  "entries": [
4
- {
5
- "version": "5.0.0",
6
- "tag": "@fgv/ts-utils_v5.0.0",
7
- "date": "Thu, 17 Jul 2025 00:13:24 GMT",
8
- "comments": {
9
- "none": [
10
- {
11
- "comment": "add result helpers, clean up object converter"
12
- },
13
- {
14
- "comment": "object converter partial/required helpers"
15
- },
16
- {
17
- "comment": "add Result.withErrorFormat"
18
- },
19
- {
20
- "comment": "bump version"
21
- }
22
- ]
23
- }
24
- },
25
4
  {
26
5
  "version": "4.6.0",
27
6
  "tag": "@fgv/ts-utils_v4.6.0",
@@ -58,10 +58,11 @@ declare class ArrayValidator<T, TC = unknown> extends ValidatorBase<T[], TC> {
58
58
  * validator.
59
59
  * @param from - The `unknown` value to be tested.
60
60
  * @param context - Optional validation context will be propagated to element validator.
61
+ * @param self - Optional self-reference for recursive validation.
61
62
  * @returns Returns `true` if `from` is an `array` of valid elements, or
62
63
  * {@link Failure} with an error message if not.
63
64
  */
64
- protected _validate<T>(from: unknown, context?: TC): boolean | Failure<T>;
65
+ protected _validate(from: unknown, context?: TC, self?: Validator<T[], TC>): boolean | Failure<T[]>;
65
66
  }
66
67
 
67
68
  /**
@@ -74,7 +75,6 @@ declare interface ArrayValidatorConstructorParams<T, TC = unknown> extends Valid
74
75
 
75
76
  declare namespace Base {
76
77
  export {
77
- ValidatorFunc,
78
78
  GenericValidatorConstructorParams,
79
79
  GenericValidator
80
80
  }
@@ -490,6 +490,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
490
490
  * {@inheritdoc Collections.ResultMap.values}
491
491
  */
492
492
  values(): IterableIterator<TITEM>;
493
+ /**
494
+ * {@inheritdoc Collections.IReadOnlyCollector.valuesByIndex}
495
+ */
496
+ valuesByIndex(): ReadonlyArray<TITEM>;
493
497
  /**
494
498
  * Gets a read-only version of this collector.
495
499
  */
@@ -559,6 +563,23 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
559
563
  protected _convertValue(value: unknown): DetailedResult<TITEM, CollectorResultDetail>;
560
564
  }
561
565
 
566
+ /**
567
+ * A console logger that outputs messages to the console.
568
+ * @public
569
+ */
570
+ declare class ConsoleLogger extends LoggerBase {
571
+ /**
572
+ * Creates a new console logger.
573
+ * @param logLevel - The level of logging to be used.
574
+ */
575
+ constructor(logLevel?: ReporterLogLevel);
576
+ /**
577
+ * {@inheritDoc Logging.LoggerBase._log}
578
+ * @internal
579
+ */
580
+ protected _log(message: string, level: MessageLogLevel): Success<string | undefined>;
581
+ }
582
+
562
583
  /**
563
584
  * A {@link Validation.Constraint | Constraint<T>} function returns
564
585
  * `true` if the supplied value meets the constraint. Can return
@@ -1080,6 +1101,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
1080
1101
  * {@inheritdoc IResult.withErrorFormat}
1081
1102
  */
1082
1103
  withErrorFormat(cb: ErrorFormatter<TD>): DetailedResult<T, TD>;
1104
+ /**
1105
+ * {@inheritdoc IResult.report}
1106
+ */
1107
+ report(reporter?: IResultReporter<T, TD>, options?: IResultReportOptions<TD>): this;
1083
1108
  orThrow(logOrFormat?: IResultLogger<TD> | ErrorFormatter<TD>): never;
1084
1109
  orThrow(cb: ErrorFormatter): never;
1085
1110
  /**
@@ -1168,6 +1193,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
1168
1193
  * {@inheritdoc Success.withErrorFormat}
1169
1194
  */
1170
1195
  withErrorFormat(cb: ErrorFormatter): DetailedResult<T, TD>;
1196
+ /**
1197
+ * {@inheritdoc IResult.report}
1198
+ */
1199
+ report(reporter?: IResultReporter<T, TD>, options?: IResultReportOptions<TD>): this;
1171
1200
  /**
1172
1201
  * Creates a {@link DetailedSuccess | DetailedSuccess<T, TD>} with the supplied value and
1173
1202
  * optional detail.
@@ -1409,6 +1438,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
1409
1438
  * {@inheritdoc IResult.aggregateError}
1410
1439
  */
1411
1440
  aggregateError(errors: IMessageAggregator): this;
1441
+ /**
1442
+ * {@inheritdoc IResult.report}
1443
+ */
1444
+ report(reporter?: IResultReporter<T>, options?: IResultReportOptions): this;
1412
1445
  /**
1413
1446
  * Get a 'friendly' string representation of this object.
1414
1447
  * @remarks
@@ -2204,6 +2237,68 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2204
2237
  value: Validator<TV, unknown> | Converter<TV, unknown> | ConverterFunc<TV, unknown>;
2205
2238
  }
2206
2239
 
2240
+ /**
2241
+ * Generic Result-aware logger interface with multiple levels of logging.
2242
+ * @public
2243
+ */
2244
+ declare interface ILogger {
2245
+ /**
2246
+ * The level of logging to be used.
2247
+ */
2248
+ readonly logLevel: ReporterLogLevel;
2249
+ /**
2250
+ * Logs a message at the given level.
2251
+ * @param level - The level of the message.
2252
+ * @param message - The message to log.
2253
+ * @param parameters - The parameters to log.
2254
+ * @returns `Success` with the logged message if the level is enabled, or
2255
+ * `Success` with `undefined` if the message is suppressed.
2256
+ */
2257
+ log(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2258
+ /**
2259
+ * Logs a detail message.
2260
+ * @param message - The message to log.
2261
+ * @param parameters - The parameters to log.
2262
+ * @returns `Success` with the logged message if the level is enabled, or
2263
+ * `Success` with `undefined` if the message is suppressed.
2264
+ */
2265
+ detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2266
+ /**
2267
+ * Logs an info message.
2268
+ * @param message - The message to log.
2269
+ * @param parameters - The parameters to log.
2270
+ * @returns `Success` with the logged message if the level is enabled, or
2271
+ * `Success` with `undefined` if the message is suppressed.
2272
+ */
2273
+ info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2274
+ /**
2275
+ * Logs a warning message.
2276
+ * @param message - The message to log.
2277
+ * @param parameters - The parameters to log.
2278
+ * @returns `Success` with the logged message if the level is enabled, or
2279
+ * `Success` with `undefined` if the message is suppressed.
2280
+ */
2281
+ warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2282
+ /**
2283
+ * Logs an error message.
2284
+ * @param message - The message to log.
2285
+ * @param parameters - The parameters to log.
2286
+ * @returns `Success` with the logged message if the level is enabled, or
2287
+ * `Success` with `undefined` if the message is suppressed.
2288
+ */
2289
+ error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2290
+ }
2291
+
2292
+ /**
2293
+ * Parameters for creating a {@link Logging.LogReporter | LogReporter}.
2294
+ * @public
2295
+ */
2296
+ declare interface ILogReporterCreateParams<T, TD = unknown> {
2297
+ logger?: ILogger;
2298
+ valueFormatter?: LogValueFormatter<T, TD>;
2299
+ messageFormatter?: LogMessageFormatter<TD>;
2300
+ }
2301
+
2207
2302
  /**
2208
2303
  * Simple error aggregator to simplify collecting all errors in
2209
2304
  * a flow.
@@ -2263,17 +2358,51 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2263
2358
  declare function inMemory(files: IInMemoryFile[], prefix?: string): Result<FileTree_2>;
2264
2359
 
2265
2360
  /**
2361
+ * An in-memory logger that stores logged and suppressed messages.
2266
2362
  * @public
2267
2363
  */
2268
2364
  declare class InMemoryLogger extends LoggerBase {
2269
- protected _messages: string[];
2270
- protected _silent: string[];
2271
- constructor(logLevel?: LogLevel);
2272
- get messages(): string[];
2273
- get silent(): string[];
2365
+ /**
2366
+ * The messages that have been logged.
2367
+ * @internal
2368
+ */
2369
+ private _logged;
2370
+ /**
2371
+ * The messages that have been suppressed.
2372
+ * @internal
2373
+ */
2374
+ private _suppressed;
2375
+ /**
2376
+ * Creates a new in-memory logger.
2377
+ * @param logLevel - The level of logging to be used.
2378
+ */
2379
+ constructor(logLevel?: ReporterLogLevel);
2380
+ /**
2381
+ * The messages that have been logged.
2382
+ */
2383
+ get logged(): string[];
2384
+ /**
2385
+ * The messages that have been suppressed.
2386
+ */
2387
+ get suppressed(): string[];
2388
+ /**
2389
+ * Clears the logged and suppressed messages.
2390
+ */
2274
2391
  clear(): void;
2275
- protected _innerLog(message: string): Success<string | undefined>;
2276
- protected _innerSilent(message: string): Success<string | undefined>;
2392
+ /**
2393
+ * {@inheritDoc Logging.LoggerBase._log}
2394
+ * @internal
2395
+ */
2396
+ protected _log(message: string, __level: MessageLogLevel): Success<string | undefined>;
2397
+ /**
2398
+ * {@inheritDoc Logging.LoggerBase._suppressLog}
2399
+ * @param level - The level of the message.
2400
+ * @param message - The message to suppress.
2401
+ * @param parameters - The parameters to suppress.
2402
+ * @returns `Success` with `undefined` if the message is suppressed.
2403
+ * @internal
2404
+ */
2405
+ protected _suppressLog(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<undefined>;
2277
2406
  }
2278
2407
 
2279
2408
  /**
@@ -2344,6 +2473,11 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2344
2473
  * with an error if the index is out of range.
2345
2474
  */
2346
2475
  getAt(index: number): Result<TITEM>;
2476
+ /**
2477
+ * Gets all items in the collection, ordered by index.
2478
+ * @returns An array of items in the collection, ordered by index.
2479
+ */
2480
+ valuesByIndex(): ReadonlyArray<TITEM>;
2347
2481
  }
2348
2482
 
2349
2483
  /**
@@ -2444,7 +2578,11 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2444
2578
  /**
2445
2579
  * {@inheritdoc Collections.IReadOnlyValidatingCollector.getAt}
2446
2580
  */
2447
- readonly getAt: (index: number) => Result<TITEM>;
2581
+ getAt(index: number): Result<TITEM>;
2582
+ /**
2583
+ * {@inheritdoc Collections.IReadOnlyCollector.valuesByIndex}
2584
+ */
2585
+ valuesByIndex(): ReadonlyArray<TITEM>;
2448
2586
  }
2449
2587
 
2450
2588
  /**
@@ -2634,6 +2772,12 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2634
2772
  * errors will be aggregated.
2635
2773
  */
2636
2774
  aggregateError(errors: IMessageAggregator): this;
2775
+ /**
2776
+ * Reports the result to the supplied reporter
2777
+ * @param reporter - The {@link IResultReporter | reporter} to which the result will be reported.
2778
+ * @param options - The {@link IResultReportOptions | options} for reporting the result.
2779
+ */
2780
+ report(reporter?: IResultReporter<T>, options?: IResultReportOptions): this;
2637
2781
  }
2638
2782
 
2639
2783
  /**
@@ -2665,6 +2809,34 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2665
2809
  converters: KeyValueConverters<TK, TV>;
2666
2810
  }
2667
2811
 
2812
+ /**
2813
+ * Interface for reporting a result.
2814
+ * @public
2815
+ */
2816
+ export declare interface IResultReporter<T, TD = unknown> {
2817
+ reportSuccess(level: MessageLogLevel, value: T, detail?: TD): void;
2818
+ reportFailure(level: MessageLogLevel, message: string, detail?: TD): void;
2819
+ }
2820
+
2821
+ /**
2822
+ * Options for reporting a result.
2823
+ * @public
2824
+ */
2825
+ export declare interface IResultReportOptions<TD = unknown> {
2826
+ /**
2827
+ * The level of reporting to be used for failure results. Default is 'error'.
2828
+ */
2829
+ failure?: MessageLogLevel;
2830
+ /**
2831
+ * The level of reporting to be used for success results. Default is 'quiet'.
2832
+ */
2833
+ success?: MessageLogLevel;
2834
+ /**
2835
+ * The error formatter to be used for reporting an error result.
2836
+ */
2837
+ message?: ErrorFormatter<TD>;
2838
+ }
2839
+
2668
2840
  /**
2669
2841
  * Helper function to create a {@link Converter | Converter} from a supplied type guard function.
2670
2842
  * @param description - a description of the thing to be validated for use in error messages
@@ -2850,49 +3022,153 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
2850
3022
  declare function literal_2<T extends string | number | boolean | symbol | null | undefined>(value: T): Validator<T>;
2851
3023
 
2852
3024
  /**
3025
+ * Abstract base class which implements {@link Logging.ILogger | ILogger}.
2853
3026
  * @public
2854
3027
  */
2855
- declare interface Logger {
2856
- log(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2857
- detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2858
- info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2859
- warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2860
- warnAndFail<T>(message?: unknown, ...parameters: unknown[]): Failure<T>;
2861
- error<T>(message?: unknown, ...parameters: unknown[]): Failure<T>;
2862
- }
2863
-
2864
- /**
2865
- * @public
2866
- */
2867
- declare abstract class LoggerBase {
2868
- logLevel: LogLevel;
2869
- constructor(logLevel?: LogLevel);
3028
+ declare abstract class LoggerBase implements ILogger {
3029
+ /**
3030
+ * {@inheritDoc Logging.ILogger.logLevel}
3031
+ */
3032
+ logLevel: ReporterLogLevel;
3033
+ protected constructor(logLevel?: ReporterLogLevel);
3034
+ /**
3035
+ * {@inheritDoc Logging.ILogger.detail}
3036
+ */
2870
3037
  detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3038
+ /**
3039
+ * {@inheritDoc Logging.ILogger.info}
3040
+ */
2871
3041
  info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3042
+ /**
3043
+ * {@inheritDoc Logging.ILogger.warn}
3044
+ */
2872
3045
  warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
2873
- warnAndFail<T>(message?: unknown, ...parameters: unknown[]): Failure<T>;
2874
- error<T>(message?: unknown, ...parameters: unknown[]): Failure<T>;
2875
- log(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3046
+ /**
3047
+ * {@inheritDoc Logging.ILogger.error}
3048
+ */
3049
+ error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3050
+ /**
3051
+ * {@inheritDoc Logging.ILogger.log}
3052
+ */
3053
+ log(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3054
+ /**
3055
+ * Formats a message and parameters into a string.
3056
+ * @param message - The message to format.
3057
+ * @param parameters - The parameters to format.
3058
+ * @returns The formatted message.
3059
+ * @public
3060
+ */
2876
3061
  protected _format(message?: unknown, ...parameters: unknown[]): string;
2877
- protected _innerSilent(__message: string): Success<string | undefined>;
2878
- protected abstract _innerLog(message: string): Success<string | undefined>;
3062
+ /**
3063
+ * Inner method called for suppressed log messages.
3064
+ * @public
3065
+ */
3066
+ protected _suppressLog(__level: MessageLogLevel, __message?: unknown, ...__parameters: unknown[]): Success<undefined>;
3067
+ /**
3068
+ * Inner method called for logged messages. Should be implemented by derived classes.
3069
+ * @param message - The message to log.
3070
+ * @param level - The {@link MessageLogLevel | level} of the message.
3071
+ * @returns `Success` with the logged message, or `Success` with `undefined` if the message is suppressed.
3072
+ * @public
3073
+ */
3074
+ protected abstract _log(message: string, level: MessageLogLevel): Success<string | undefined>;
2879
3075
  }
2880
3076
 
2881
3077
  declare namespace Logging {
2882
3078
  export {
2883
- LogLevel,
2884
- Logger,
3079
+ shouldLog,
3080
+ ReporterLogLevel,
3081
+ ILogger,
2885
3082
  LoggerBase,
2886
3083
  InMemoryLogger,
2887
- NoOpLogger
3084
+ ConsoleLogger,
3085
+ NoOpLogger,
3086
+ LogValueFormatter,
3087
+ LogMessageFormatter,
3088
+ ILogReporterCreateParams,
3089
+ LogReporter
2888
3090
  }
2889
3091
  }
2890
3092
  export { Logging }
2891
3093
 
2892
3094
  /**
3095
+ * A function that formats a message for logging.
2893
3096
  * @public
2894
3097
  */
2895
- declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
3098
+ declare type LogMessageFormatter<TD = unknown> = (message: string, detail?: TD) => string;
3099
+
3100
+ /**
3101
+ * Abstract base class which wraps an existing {@link Logging.ILogger | ILogger} to implement
3102
+ * both {@link Logging.ILogger | ILogger} and {@link IResultReporter | IResultReporter}.
3103
+ * @public
3104
+ */
3105
+ declare class LogReporter<T, TD = unknown> implements ILogger, IResultReporter<T, TD> {
3106
+ /**
3107
+ * The logger to wrap.
3108
+ * @internal
3109
+ */
3110
+ protected readonly _logger: ILogger;
3111
+ /**
3112
+ * The formatter to use for values.
3113
+ * @internal
3114
+ */
3115
+ protected readonly _valueFormatter: LogValueFormatter<T, TD>;
3116
+ /**
3117
+ * The formatter to use for messages.
3118
+ * @internal
3119
+ */
3120
+ protected readonly _messageFormatter: LogMessageFormatter<TD>;
3121
+ /**
3122
+ * Creates a new {@link Logging.LogReporter | LogReporter}.
3123
+ * @param params - The parameters for creating the {@link Logging.LogReporter | LogReporter}.
3124
+ */
3125
+ constructor(params?: ILogReporterCreateParams<T, TD>);
3126
+ /**
3127
+ * {@inheritDoc Logging.ILogger.logLevel}
3128
+ */
3129
+ get logLevel(): ReporterLogLevel;
3130
+ /**
3131
+ * {@inheritDoc Logging.ILogger.detail}
3132
+ */
3133
+ detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3134
+ /**
3135
+ * {@inheritDoc Logging.ILogger.info}
3136
+ */
3137
+ info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3138
+ /**
3139
+ * {@inheritDoc Logging.ILogger.warn}
3140
+ */
3141
+ warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3142
+ /**
3143
+ * {@inheritDoc Logging.ILogger.error}
3144
+ */
3145
+ error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3146
+ /**
3147
+ * {@inheritDoc Logging.ILogger.log}
3148
+ */
3149
+ log(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
3150
+ /**
3151
+ * {@inheritDoc IResultReporter.reportSuccess}
3152
+ */
3153
+ reportSuccess(level: MessageLogLevel, value: T, detail?: TD): void;
3154
+ /**
3155
+ * {@inheritDoc IResultReporter.reportFailure}
3156
+ */
3157
+ reportFailure(level: MessageLogLevel, message: string, detail?: TD): void;
3158
+ /**
3159
+ * Generic method to try to format an object for logging.
3160
+ * @param value - The value to format.
3161
+ * @param detail - The detail to format.
3162
+ * @returns
3163
+ */
3164
+ static tryFormatObject<T = unknown, TD = unknown>(value: T, detail?: TD): string;
3165
+ }
3166
+
3167
+ /**
3168
+ * A function that formats a value for logging.
3169
+ * @public
3170
+ */
3171
+ declare type LogValueFormatter<T, TD = unknown> = (value: T, detail?: TD) => string;
2896
3172
 
2897
3173
  /**
2898
3174
  * Aggregates successful results from a collection of {@link DetailedResult | DetailedResult<T, TD>},
@@ -3078,10 +3354,26 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
3078
3354
  }
3079
3355
 
3080
3356
  /**
3357
+ * The severity level at which a message should be logged.
3358
+ * @public
3359
+ */
3360
+ export declare type MessageLogLevel = 'quiet' | 'detail' | 'info' | 'warning' | 'error';
3361
+
3362
+ /**
3363
+ * A no-op {@link Logging.LoggerBase | LoggerBase} that does not log anything.
3081
3364
  * @public
3082
3365
  */
3083
3366
  declare class NoOpLogger extends LoggerBase {
3084
- protected _innerLog(message: string): Success<string | undefined>;
3367
+ /**
3368
+ * Creates a new no-op logger.
3369
+ * @param logLevel - The level of logging to be used.
3370
+ */
3371
+ constructor(logLevel?: ReporterLogLevel);
3372
+ /**
3373
+ * {@inheritDoc Logging.LoggerBase._log}
3374
+ * @internal
3375
+ */
3376
+ protected _log(message: string, __level: MessageLogLevel): Success<string | undefined>;
3085
3377
  }
3086
3378
 
3087
3379
  /**
@@ -3420,7 +3712,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
3420
3712
  * {@inheritdoc Validation.ValidatorBase._validate}
3421
3713
  * @internal
3422
3714
  */
3423
- protected _validate(from: unknown, context?: TC): boolean | Failure<T>;
3715
+ protected _validate(from: unknown, context?: TC, self?: Validator<T, TC>): boolean | Failure<T>;
3424
3716
  }
3425
3717
 
3426
3718
  /**
@@ -3522,10 +3814,11 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
3522
3814
  * of the configured validators.
3523
3815
  * @param from - The `unknown` value to be tested.
3524
3816
  * @param context - Optional validation context will be propagated to element validator.
3817
+ * @param self - Optional self-reference for recursive validation.
3525
3818
  * @returns Returns `true` if `from` is an `array` of valid elements, or
3526
3819
  * {@link Failure} with an error message if not.
3527
3820
  */
3528
- protected _validate<T>(from: unknown, context?: TC): boolean | Failure<T>;
3821
+ protected _validate<T>(from: unknown, context?: TC, self?: Validator<T, TC>): boolean | Failure<T>;
3529
3822
  }
3530
3823
 
3531
3824
  /**
@@ -3780,6 +4073,12 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
3780
4073
  */
3781
4074
  export declare function recordToMap<TS, TD, TK extends string = string>(src: Record<TK, TS>, factory: KeyedThingFactory<TS, TD, TK>): Result<Map<TK, TD>>;
3782
4075
 
4076
+ /**
4077
+ * The level of logging to be used.
4078
+ * @public
4079
+ */
4080
+ declare type ReporterLogLevel = 'all' | 'detail' | 'info' | 'warning' | 'error' | 'silent';
4081
+
3783
4082
  /**
3784
4083
  * Represents the {@link IResult | result} of some operation or sequence of operations.
3785
4084
  * @remarks
@@ -4040,6 +4339,15 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4040
4339
  */
4041
4340
  export declare type ResultValueType<T> = T extends Result<infer TV> ? TV : never;
4042
4341
 
4342
+ /**
4343
+ * Compares two log levels.
4344
+ * @param message - The first log level.
4345
+ * @param reporter - The second log level.
4346
+ * @returns `true` if the message should be logged, `false` if it should be suppressed.
4347
+ * @public
4348
+ */
4349
+ declare function shouldLog(message: MessageLogLevel, reporter: ReporterLogLevel): boolean;
4350
+
4043
4351
  /**
4044
4352
  * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter} which converts an object
4045
4353
  * without changing shape, a {@link Conversion.FieldConverters | FieldConverters<T, TC>} and an optional
@@ -4335,6 +4643,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4335
4643
  * {@inheritdoc IResult.aggregateError}
4336
4644
  */
4337
4645
  aggregateError(__errors: IMessageAggregator): this;
4646
+ /**
4647
+ * {@inheritdoc IResult.report}
4648
+ */
4649
+ report(reporter?: IResultReporter<T>, options?: IResultReportOptions): this;
4338
4650
  /**
4339
4651
  * Creates a {@link Success | Success<T>} with the supplied value.
4340
4652
  * @param value - The value to be returned.
@@ -4439,11 +4751,12 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4439
4751
  * type guard, returning a `Failure<T>` containing more information about a failure.
4440
4752
  * @param from - Value to be converted.
4441
4753
  * @param context - Optional validation context.
4754
+ * @param self - Optional self-reference for recursive validation.
4442
4755
  * @returns `true` if `from` is valid, {@link Failure | Failure<T>}
4443
4756
  * with an error message if `from` is invalid.
4444
4757
  * @internal
4445
4758
  */
4446
- protected _validate(from: unknown, context?: TC): boolean | Failure<T>;
4759
+ protected _validate(from: unknown, context?: TC, self?: Validator<T, TC>): boolean | Failure<T>;
4447
4760
  }
4448
4761
 
4449
4762
  /**
@@ -4462,6 +4775,15 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4462
4775
  */
4463
4776
  declare type TypeGuardWithContext<T, TC = unknown> = (from: unknown, context?: TC) => from is T;
4464
4777
 
4778
+ /**
4779
+ * Uses a value or calls a supplied initializer if the supplied value is undefined.
4780
+ * @param value - the value
4781
+ * @param initializer - a function that initializes the value if it is undefined
4782
+ * @returns `Success` with the value if it is defined, or the result of calling the initializer function.
4783
+ * @public
4784
+ */
4785
+ export declare function useOrInitialize<T>(value: T | undefined, initializer: () => Result<T>): Result<T>;
4786
+
4465
4787
  declare namespace Utils {
4466
4788
  export {
4467
4789
  isIterable
@@ -4592,12 +4914,12 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4592
4914
  Classes,
4593
4915
  Validators,
4594
4916
  TypeGuardWithContext,
4595
- ValidatorFunc,
4596
4917
  FunctionConstraintTrait,
4597
4918
  ConstraintTrait,
4598
4919
  ValidatorTraitValues,
4599
4920
  defaultValidatorTraits,
4600
4921
  ValidatorTraits,
4922
+ ValidatorFunc,
4601
4923
  ValidatorOptions,
4602
4924
  Constraint,
4603
4925
  ValidationErrorFormatter,
@@ -4713,11 +5035,12 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4713
5035
  * Abstract validation method to me implemented by derived classes.
4714
5036
  * @param from - Value to be converted.
4715
5037
  * @param context - Optional validation context.
5038
+ * @param self - Optional self-reference for recursive validation.
4716
5039
  * @returns `true` if `from` is valid, {@link Failure | Failure<T>}
4717
5040
  * with an error message if `from` is invalid.
4718
5041
  * @internal
4719
5042
  */
4720
- protected abstract _validate(from: unknown, context?: TC): boolean | Failure<T>;
5043
+ protected abstract _validate(from: unknown, context?: TC, self?: Validator<T, TC>): boolean | Failure<T>;
4721
5044
  }
4722
5045
 
4723
5046
  /**
@@ -4731,7 +5054,7 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
4731
5054
  * an optionally-supplied validation context of type `<TC>`.
4732
5055
  * @public
4733
5056
  */
4734
- declare type ValidatorFunc<T, TC> = (from: unknown, context?: TC) => boolean | Failure<T>;
5057
+ declare type ValidatorFunc<T, TC> = (from: unknown, context?: TC, self?: Validator<T, TC>) => boolean | Failure<T>;
4735
5058
 
4736
5059
  /**
4737
5060
  * Options that apply to any {@link Validation.Validator | Validator}.