@fgv/ts-utils 5.0.2 → 5.1.0-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 (104) hide show
  1. package/README.md +152 -84
  2. package/dist/index.js +2 -2
  3. package/dist/packlets/base/messageAggregator.js +6 -6
  4. package/dist/packlets/base/result.js +39 -39
  5. package/dist/packlets/base/utils.js +47 -0
  6. package/dist/packlets/collections/aggregatedResultMap.js +722 -0
  7. package/dist/packlets/collections/collector.js +9 -9
  8. package/dist/packlets/collections/collectorValidator.js +4 -4
  9. package/dist/packlets/collections/converters.js +39 -0
  10. package/dist/packlets/collections/convertingCollectorValidator.js +3 -3
  11. package/dist/packlets/collections/convertingResultMap.js +208 -0
  12. package/dist/packlets/collections/index.js +4 -0
  13. package/dist/packlets/collections/keyValueConverters.js +1 -4
  14. package/dist/packlets/collections/readOnlyConvertingResultMap.js +193 -0
  15. package/dist/packlets/collections/resultMapValidator.js +50 -6
  16. package/dist/packlets/collections/validatingConvertingResultMap.js +78 -0
  17. package/dist/packlets/conversion/advancedConverters.js +249 -0
  18. package/dist/packlets/conversion/baseConverter.js +23 -16
  19. package/dist/packlets/conversion/basicConverters.js +571 -0
  20. package/dist/packlets/conversion/converters.js +3 -617
  21. package/dist/packlets/conversion/defaultingConverter.js +21 -15
  22. package/dist/packlets/logging/bootLogger.js +122 -0
  23. package/dist/packlets/logging/index.js +1 -0
  24. package/dist/packlets/logging/logReporter.js +32 -1
  25. package/dist/packlets/logging/logger.js +25 -5
  26. package/dist/packlets/validation/classes.js +1 -0
  27. package/dist/packlets/validation/compositeId.js +60 -0
  28. package/dist/packlets/validation/field.js +1 -1
  29. package/dist/packlets/validation/genericValidator.js +24 -10
  30. package/dist/packlets/validation/object.js +3 -6
  31. package/dist/packlets/validation/validators.js +12 -0
  32. package/dist/ts-utils.d.ts +1633 -200
  33. package/dist/tsdoc-metadata.json +1 -1
  34. package/lib/index.d.ts +2 -2
  35. package/lib/index.js +2 -1
  36. package/lib/packlets/base/mapResults.d.ts +3 -3
  37. package/lib/packlets/base/messageAggregator.d.ts +6 -6
  38. package/lib/packlets/base/messageAggregator.js +6 -6
  39. package/lib/packlets/base/result.d.ts +74 -51
  40. package/lib/packlets/base/result.js +39 -39
  41. package/lib/packlets/base/utils.d.ts +42 -0
  42. package/lib/packlets/base/utils.js +52 -0
  43. package/lib/packlets/collections/aggregatedResultMap.d.ts +433 -0
  44. package/lib/packlets/collections/aggregatedResultMap.js +728 -0
  45. package/lib/packlets/collections/collector.d.ts +11 -10
  46. package/lib/packlets/collections/collector.js +9 -9
  47. package/lib/packlets/collections/collectorValidator.d.ts +12 -10
  48. package/lib/packlets/collections/collectorValidator.js +4 -4
  49. package/lib/packlets/collections/converters.d.ts +18 -0
  50. package/lib/packlets/collections/converters.js +42 -0
  51. package/lib/packlets/collections/convertingCollector.d.ts +4 -4
  52. package/lib/packlets/collections/convertingCollectorValidator.d.ts +10 -7
  53. package/lib/packlets/collections/convertingCollectorValidator.js +3 -3
  54. package/lib/packlets/collections/convertingResultMap.d.ts +176 -0
  55. package/lib/packlets/collections/convertingResultMap.js +213 -0
  56. package/lib/packlets/collections/index.d.ts +4 -0
  57. package/lib/packlets/collections/index.js +4 -0
  58. package/lib/packlets/collections/keyValueConverters.d.ts +1 -4
  59. package/lib/packlets/collections/keyValueConverters.js +1 -4
  60. package/lib/packlets/collections/readOnlyConvertingResultMap.d.ts +153 -0
  61. package/lib/packlets/collections/readOnlyConvertingResultMap.js +197 -0
  62. package/lib/packlets/collections/readonlyResultMap.d.ts +7 -7
  63. package/lib/packlets/collections/resultMap.d.ts +108 -2
  64. package/lib/packlets/collections/resultMapValidator.d.ts +45 -11
  65. package/lib/packlets/collections/resultMapValidator.js +52 -7
  66. package/lib/packlets/collections/validatingCollector.d.ts +5 -5
  67. package/lib/packlets/collections/validatingConvertingCollector.d.ts +3 -3
  68. package/lib/packlets/collections/validatingConvertingResultMap.d.ts +102 -0
  69. package/lib/packlets/collections/validatingConvertingResultMap.js +83 -0
  70. package/lib/packlets/collections/validatingResultMap.d.ts +1 -1
  71. package/lib/packlets/conversion/advancedConverters.d.ts +170 -0
  72. package/lib/packlets/conversion/advancedConverters.js +258 -0
  73. package/lib/packlets/conversion/baseConverter.d.ts +39 -23
  74. package/lib/packlets/conversion/baseConverter.js +23 -16
  75. package/lib/packlets/conversion/basicConverters.d.ts +470 -0
  76. package/lib/packlets/conversion/basicConverters.js +595 -0
  77. package/lib/packlets/conversion/converter.d.ts +7 -0
  78. package/lib/packlets/conversion/converters.d.ts +2 -535
  79. package/lib/packlets/conversion/converters.js +17 -639
  80. package/lib/packlets/conversion/defaultingConverter.d.ts +20 -16
  81. package/lib/packlets/conversion/defaultingConverter.js +21 -15
  82. package/lib/packlets/logging/bootLogger.d.ts +84 -0
  83. package/lib/packlets/logging/bootLogger.js +126 -0
  84. package/lib/packlets/logging/index.d.ts +1 -0
  85. package/lib/packlets/logging/index.js +1 -0
  86. package/lib/packlets/logging/logReporter.d.ts +18 -3
  87. package/lib/packlets/logging/logReporter.js +31 -0
  88. package/lib/packlets/logging/logger.d.ts +39 -6
  89. package/lib/packlets/logging/logger.js +26 -5
  90. package/lib/packlets/validation/classes.d.ts +1 -0
  91. package/lib/packlets/validation/classes.js +3 -1
  92. package/lib/packlets/validation/compositeId.d.ts +29 -0
  93. package/lib/packlets/validation/compositeId.js +64 -0
  94. package/lib/packlets/validation/field.d.ts +1 -1
  95. package/lib/packlets/validation/field.js +1 -1
  96. package/lib/packlets/validation/genericValidator.d.ts +15 -11
  97. package/lib/packlets/validation/genericValidator.js +24 -10
  98. package/lib/packlets/validation/object.d.ts +3 -6
  99. package/lib/packlets/validation/object.js +3 -6
  100. package/lib/packlets/validation/traits.d.ts +3 -3
  101. package/lib/packlets/validation/validator.d.ts +7 -0
  102. package/lib/packlets/validation/validators.d.ts +10 -0
  103. package/lib/packlets/validation/validators.js +13 -0
  104. package/package.json +14 -14
@@ -8,15 +8,15 @@ import { ConstraintOptions, ConversionErrorFormatter, Converter, DefaultingConve
8
8
  export declare class GenericDefaultingConverter<T, TD = T, TC = unknown> implements DefaultingConverter<T, TD, TC> {
9
9
  private _converter;
10
10
  /**
11
- * {@inheritdoc Conversion.DefaultingConverter.defaultValue}
11
+ * {@inheritDoc Conversion.DefaultingConverter.defaultValue}
12
12
  */
13
13
  defaultValue: TD;
14
14
  /**
15
- * {@inheritdoc Converter.isOptional}
15
+ * {@inheritDoc Converter.isOptional}
16
16
  */
17
17
  get isOptional(): boolean;
18
18
  /**
19
- * {@inheritdoc Converter.isOptional}
19
+ * {@inheritDoc Converter.isOptional}
20
20
  */
21
21
  get brand(): string | undefined;
22
22
  /**
@@ -26,55 +26,55 @@ export declare class GenericDefaultingConverter<T, TD = T, TC = unknown> impleme
26
26
  */
27
27
  constructor(converter: Converter<T, TC>, defaultValue: TD);
28
28
  /**
29
- * {@inheritdoc Converter.convert}
29
+ * {@inheritDoc Converter.convert}
30
30
  */
31
31
  convert(from: unknown, ctx?: TC | undefined): Success<T | TD>;
32
32
  /**
33
- * {@inheritdoc Converter.convertOptional}
33
+ * {@inheritDoc Converter.convertOptional}
34
34
  */
35
35
  convertOptional(from: unknown, context?: TC | undefined, onError?: ('failOnError' | 'ignoreErrors') | undefined): Result<T | TD | undefined>;
36
36
  /**
37
- * {@inheritdoc Converter.optional}
37
+ * {@inheritDoc Converter.optional}
38
38
  */
39
39
  optional(onError?: ('failOnError' | 'ignoreErrors') | undefined): Converter<T | TD | undefined, TC>;
40
40
  /**
41
- * {@inheritdoc Converter.map}
41
+ * {@inheritDoc Converter.map}
42
42
  */
43
43
  map<T2>(mapper: (from: T | TD) => Result<T2>): Converter<T2, TC>;
44
44
  /**
45
- * {@inheritdoc Converter.mapConvert}
45
+ * {@inheritDoc Converter.mapConvert}
46
46
  */
47
47
  mapConvert<T2>(mapConverter: Converter<T2, unknown>): Converter<T2, TC>;
48
48
  /**
49
- * {@inheritdoc Converter.mapItems}
49
+ * {@inheritDoc Converter.mapItems}
50
50
  */
51
51
  mapItems<TI>(mapper: (from: unknown) => Result<TI>): Converter<TI[], TC>;
52
52
  /**
53
- * {@inheritdoc Converter.mapConvertItems}
53
+ * {@inheritDoc Converter.mapConvertItems}
54
54
  */
55
55
  mapConvertItems<TI>(mapConverter: Converter<TI, unknown>): Converter<TI[], TC>;
56
56
  /**
57
- * {@inheritdoc Converter.withAction}
57
+ * {@inheritDoc Converter.withAction}
58
58
  */
59
59
  withAction<T2>(action: (result: Result<T | TD>) => Result<T2>): Converter<T2, TC>;
60
60
  /**
61
- * {@inheritdoc Converter.withTypeGuard}
61
+ * {@inheritDoc Converter.withTypeGuard}
62
62
  */
63
63
  withTypeGuard<TI>(guard: (from: unknown) => from is TI, message?: string | undefined): Converter<TI, TC>;
64
64
  /**
65
- * {@inheritdoc Converter.withItemTypeGuard}
65
+ * {@inheritDoc Converter.withItemTypeGuard}
66
66
  */
67
67
  withItemTypeGuard<TI>(guard: (from: unknown) => from is TI, message?: string | undefined): Converter<TI[], TC>;
68
68
  /**
69
- * {@inheritdoc Converter.withConstraint}
69
+ * {@inheritDoc Converter.withConstraint}
70
70
  */
71
71
  withConstraint(constraint: (val: T | TD) => boolean | Result<T | TD>, options?: ConstraintOptions | undefined): Converter<T | TD, TC>;
72
72
  /**
73
- * {@inheritdoc Converter.withBrand}
73
+ * {@inheritDoc Converter.withBrand}
74
74
  */
75
75
  withBrand<B extends string>(brand: B): Converter<Brand<T | TD, B>, TC>;
76
76
  /**
77
- * {@inheritdoc Converter.withFormattedError}
77
+ * {@inheritDoc Converter.withFormattedError}
78
78
  */
79
79
  withFormattedError(formatter: ConversionErrorFormatter<TC>): Converter<T | TD, TC>;
80
80
  /**
@@ -85,6 +85,10 @@ export declare class GenericDefaultingConverter<T, TD = T, TC = unknown> impleme
85
85
  * {@link Conversion.DefaultingConverter | DefaultingConverter}.
86
86
  */
87
87
  withDefault<TD2 = T>(dflt: TD2): DefaultingConverter<T, TD2, TC>;
88
+ /**
89
+ * {@inheritDoc Converter.or}
90
+ */
91
+ or(__converter: Converter<T, TC>): DefaultingConverter<T, TD, TC>;
88
92
  private _applyDefault;
89
93
  }
90
94
  //# sourceMappingURL=defaultingConverter.d.ts.map
@@ -30,13 +30,13 @@ const base_1 = require("../base");
30
30
  */
31
31
  class GenericDefaultingConverter {
32
32
  /**
33
- * {@inheritdoc Converter.isOptional}
33
+ * {@inheritDoc Converter.isOptional}
34
34
  */
35
35
  get isOptional() {
36
36
  return this._converter.isOptional;
37
37
  }
38
38
  /**
39
- * {@inheritdoc Converter.isOptional}
39
+ * {@inheritDoc Converter.isOptional}
40
40
  */
41
41
  get brand() {
42
42
  return this._converter.brand;
@@ -51,13 +51,13 @@ class GenericDefaultingConverter {
51
51
  this._converter = converter;
52
52
  }
53
53
  /**
54
- * {@inheritdoc Converter.convert}
54
+ * {@inheritDoc Converter.convert}
55
55
  */
56
56
  convert(from, ctx) {
57
57
  return this._applyDefault(this._converter.convert(from, ctx));
58
58
  }
59
59
  /**
60
- * {@inheritdoc Converter.convertOptional}
60
+ * {@inheritDoc Converter.convertOptional}
61
61
  */
62
62
  convertOptional(from, context, onError) {
63
63
  const converted = this._converter.convertOptional(from, context, onError);
@@ -67,7 +67,7 @@ class GenericDefaultingConverter {
67
67
  return converted;
68
68
  }
69
69
  /**
70
- * {@inheritdoc Converter.optional}
70
+ * {@inheritDoc Converter.optional}
71
71
  */
72
72
  optional(onError) {
73
73
  // need to let the inner converter do its optional thing first or our default
@@ -75,61 +75,61 @@ class GenericDefaultingConverter {
75
75
  return this._converter.optional(onError).withAction((result) => this._applyDefault(result));
76
76
  }
77
77
  /**
78
- * {@inheritdoc Converter.map}
78
+ * {@inheritDoc Converter.map}
79
79
  */
80
80
  map(mapper) {
81
81
  return this._converter.withAction((result) => this._applyDefault(result)).map(mapper);
82
82
  }
83
83
  /**
84
- * {@inheritdoc Converter.mapConvert}
84
+ * {@inheritDoc Converter.mapConvert}
85
85
  */
86
86
  mapConvert(mapConverter) {
87
87
  return this._converter.withAction((result) => this._applyDefault(result)).mapConvert(mapConverter);
88
88
  }
89
89
  /**
90
- * {@inheritdoc Converter.mapItems}
90
+ * {@inheritDoc Converter.mapItems}
91
91
  */
92
92
  mapItems(mapper) {
93
93
  return this._converter.withAction((result) => this._applyDefault(result)).mapItems(mapper);
94
94
  }
95
95
  /**
96
- * {@inheritdoc Converter.mapConvertItems}
96
+ * {@inheritDoc Converter.mapConvertItems}
97
97
  */
98
98
  mapConvertItems(mapConverter) {
99
99
  return this._converter.withAction((result) => this._applyDefault(result)).mapConvertItems(mapConverter);
100
100
  }
101
101
  /**
102
- * {@inheritdoc Converter.withAction}
102
+ * {@inheritDoc Converter.withAction}
103
103
  */
104
104
  withAction(action) {
105
105
  return this._converter.withAction((result) => this._applyDefault(result)).withAction(action);
106
106
  }
107
107
  /**
108
- * {@inheritdoc Converter.withTypeGuard}
108
+ * {@inheritDoc Converter.withTypeGuard}
109
109
  */
110
110
  withTypeGuard(guard, message) {
111
111
  return this._converter.withAction((result) => this._applyDefault(result)).withTypeGuard(guard);
112
112
  }
113
113
  /**
114
- * {@inheritdoc Converter.withItemTypeGuard}
114
+ * {@inheritDoc Converter.withItemTypeGuard}
115
115
  */
116
116
  withItemTypeGuard(guard, message) {
117
117
  return this._converter.withAction((result) => this._applyDefault(result)).withItemTypeGuard(guard);
118
118
  }
119
119
  /**
120
- * {@inheritdoc Converter.withConstraint}
120
+ * {@inheritDoc Converter.withConstraint}
121
121
  */
122
122
  withConstraint(constraint, options) {
123
123
  return this._converter.withAction((result) => this._applyDefault(result)).withConstraint(constraint);
124
124
  }
125
125
  /**
126
- * {@inheritdoc Converter.withBrand}
126
+ * {@inheritDoc Converter.withBrand}
127
127
  */
128
128
  withBrand(brand) {
129
129
  return this._converter.withAction((result) => this._applyDefault(result)).withBrand(brand);
130
130
  }
131
131
  /**
132
- * {@inheritdoc Converter.withFormattedError}
132
+ * {@inheritDoc Converter.withFormattedError}
133
133
  */
134
134
  withFormattedError(formatter) {
135
135
  // formatter should never actually be invoked for a defaulting converter
@@ -145,6 +145,12 @@ class GenericDefaultingConverter {
145
145
  withDefault(dflt) {
146
146
  return new GenericDefaultingConverter(this._converter, dflt);
147
147
  }
148
+ /**
149
+ * {@inheritDoc Converter.or}
150
+ */
151
+ or(__converter) {
152
+ return this;
153
+ }
148
154
  _applyDefault(converted) {
149
155
  return converted.success ? converted : (0, base_1.succeed)(this.defaultValue);
150
156
  }
@@ -0,0 +1,84 @@
1
+ import { MessageLogLevel, Success } from '../base';
2
+ import { IDetailLogger, ILogger, ReporterLogLevel } from './logger';
3
+ /**
4
+ * A logger that buffers log entries during startup, then replays them
5
+ * to a real logger once it becomes available.
6
+ *
7
+ * @remarks
8
+ * During application bootstrap, the real logger (e.g. one backed by
9
+ * toast notifications) may not be available yet. `BootLogger` solves
10
+ * this by:
11
+ * 1. Buffering all log calls in memory during the boot phase.
12
+ * 2. When {@link BootLogger.ready | ready()} is called with the real
13
+ * logger, replaying all buffered entries and then forwarding all
14
+ * subsequent calls directly.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // Create early, before the real logger exists
19
+ * const bootLogger = new BootLogger('detail');
20
+ * bootLogger.info('Starting up...');
21
+ *
22
+ * // Later, when the real logger is available
23
+ * bootLogger.ready(realLogger);
24
+ * // 'Starting up...' is replayed to realLogger
25
+ * // All future calls go directly to realLogger
26
+ * ```
27
+ *
28
+ * @public
29
+ */
30
+ export declare class BootLogger implements IDetailLogger {
31
+ private _buffer;
32
+ private _delegate;
33
+ private _isReady;
34
+ /**
35
+ * Creates a new boot logger.
36
+ * @param logLevel - The log level for the initial in-memory buffer phase.
37
+ * Defaults to 'detail' to capture everything during boot.
38
+ */
39
+ constructor(logLevel?: ReporterLogLevel);
40
+ /**
41
+ * {@inheritDoc Logging.ILogger.logLevel}
42
+ */
43
+ get logLevel(): ReporterLogLevel;
44
+ /**
45
+ * Whether the boot logger has been connected to a real logger.
46
+ */
47
+ get isReady(): boolean;
48
+ /**
49
+ * Connects this boot logger to a real logger.
50
+ * All buffered entries are replayed to the new logger in order,
51
+ * and all subsequent calls are forwarded directly.
52
+ * @param logger - The real logger to forward to.
53
+ */
54
+ ready(logger: ILogger): void;
55
+ /**
56
+ * {@inheritDoc Logging.ILogger.log}
57
+ */
58
+ log(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
59
+ /**
60
+ * {@inheritDoc Logging.ILogger.detail}
61
+ */
62
+ detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
63
+ /**
64
+ * {@inheritDoc Logging.ILogger.info}
65
+ */
66
+ info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
67
+ /**
68
+ * {@inheritDoc Logging.ILogger.warn}
69
+ */
70
+ warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
71
+ /**
72
+ * {@inheritDoc Logging.ILogger.error}
73
+ */
74
+ error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
75
+ /**
76
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
77
+ */
78
+ errorWithDetail(message: string, detail: unknown): Success<string | undefined>;
79
+ /**
80
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
81
+ */
82
+ warnWithDetail(message: string, detail: unknown): Success<string | undefined>;
83
+ }
84
+ //# sourceMappingURL=bootLogger.d.ts.map
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BootLogger = void 0;
4
+ const logger_1 = require("./logger");
5
+ /**
6
+ * A logger that buffers log entries during startup, then replays them
7
+ * to a real logger once it becomes available.
8
+ *
9
+ * @remarks
10
+ * During application bootstrap, the real logger (e.g. one backed by
11
+ * toast notifications) may not be available yet. `BootLogger` solves
12
+ * this by:
13
+ * 1. Buffering all log calls in memory during the boot phase.
14
+ * 2. When {@link BootLogger.ready | ready()} is called with the real
15
+ * logger, replaying all buffered entries and then forwarding all
16
+ * subsequent calls directly.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Create early, before the real logger exists
21
+ * const bootLogger = new BootLogger('detail');
22
+ * bootLogger.info('Starting up...');
23
+ *
24
+ * // Later, when the real logger is available
25
+ * bootLogger.ready(realLogger);
26
+ * // 'Starting up...' is replayed to realLogger
27
+ * // All future calls go directly to realLogger
28
+ * ```
29
+ *
30
+ * @public
31
+ */
32
+ class BootLogger {
33
+ /**
34
+ * Creates a new boot logger.
35
+ * @param logLevel - The log level for the initial in-memory buffer phase.
36
+ * Defaults to 'detail' to capture everything during boot.
37
+ */
38
+ constructor(logLevel) {
39
+ this._buffer = [];
40
+ this._isReady = false;
41
+ this._delegate = new logger_1.InMemoryLogger(logLevel !== null && logLevel !== void 0 ? logLevel : 'detail');
42
+ }
43
+ /**
44
+ * {@inheritDoc Logging.ILogger.logLevel}
45
+ */
46
+ get logLevel() {
47
+ return this._delegate.logLevel;
48
+ }
49
+ /**
50
+ * Whether the boot logger has been connected to a real logger.
51
+ */
52
+ get isReady() {
53
+ return this._isReady;
54
+ }
55
+ /**
56
+ * Connects this boot logger to a real logger.
57
+ * All buffered entries are replayed to the new logger in order,
58
+ * and all subsequent calls are forwarded directly.
59
+ * @param logger - The real logger to forward to.
60
+ */
61
+ ready(logger) {
62
+ // Replay buffered entries
63
+ for (const entry of this._buffer) {
64
+ logger.log(entry.level, entry.message, ...entry.parameters);
65
+ }
66
+ // Switch to the real logger and discard the buffer
67
+ this._delegate = logger;
68
+ this._buffer = [];
69
+ this._isReady = true;
70
+ }
71
+ /**
72
+ * {@inheritDoc Logging.ILogger.log}
73
+ */
74
+ log(level, message, ...parameters) {
75
+ if (!this._isReady) {
76
+ this._buffer.push({ level, message, parameters });
77
+ }
78
+ return this._delegate.log(level, message, ...parameters);
79
+ }
80
+ /**
81
+ * {@inheritDoc Logging.ILogger.detail}
82
+ */
83
+ detail(message, ...parameters) {
84
+ return this.log('detail', message, ...parameters);
85
+ }
86
+ /**
87
+ * {@inheritDoc Logging.ILogger.info}
88
+ */
89
+ info(message, ...parameters) {
90
+ return this.log('info', message, ...parameters);
91
+ }
92
+ /**
93
+ * {@inheritDoc Logging.ILogger.warn}
94
+ */
95
+ warn(message, ...parameters) {
96
+ return this.log('warning', message, ...parameters);
97
+ }
98
+ /**
99
+ * {@inheritDoc Logging.ILogger.error}
100
+ */
101
+ error(message, ...parameters) {
102
+ return this.log('error', message, ...parameters);
103
+ }
104
+ /**
105
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
106
+ */
107
+ errorWithDetail(message, detail) {
108
+ if ((0, logger_1.isDetailLogger)(this._delegate)) {
109
+ return this._delegate.errorWithDetail(message, detail);
110
+ }
111
+ this.log('detail', detail);
112
+ return this.log('error', message);
113
+ }
114
+ /**
115
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
116
+ */
117
+ warnWithDetail(message, detail) {
118
+ if ((0, logger_1.isDetailLogger)(this._delegate)) {
119
+ return this._delegate.warnWithDetail(message, detail);
120
+ }
121
+ this.log('detail', detail);
122
+ return this.log('warning', message);
123
+ }
124
+ }
125
+ exports.BootLogger = BootLogger;
126
+ //# sourceMappingURL=bootLogger.js.map
@@ -1,3 +1,4 @@
1
+ export * from './bootLogger';
1
2
  export * from './logger';
2
3
  export * from './logReporter';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -35,6 +35,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
35
35
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
+ __exportStar(require("./bootLogger"), exports);
38
39
  __exportStar(require("./logger"), exports);
39
40
  __exportStar(require("./logReporter"), exports);
40
41
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- import { ILogger, ReporterLogLevel } from './logger';
2
- import { ErrorFormatter, IResultReporter, MessageLogLevel, Success } from '../base';
1
+ import { IDetailLogger, ILogger, ReporterLogLevel } from './logger';
2
+ import { ErrorFormatter, IResultReporter, MessageLogLevel, Result, Success } from '../base';
3
3
  /**
4
4
  * A function that formats a value for logging.
5
5
  * @public
@@ -24,7 +24,7 @@ export interface ILogReporterCreateParams<T, TD = unknown> {
24
24
  * both {@link Logging.ILogger | ILogger} and {@link IResultReporter | IResultReporter}.
25
25
  * @public
26
26
  */
27
- export declare class LogReporter<T, TD = unknown> implements ILogger, IResultReporter<T, TD> {
27
+ export declare class LogReporter<T, TD = unknown> implements IDetailLogger, IResultReporter<T, TD> {
28
28
  /**
29
29
  * Base logger used to by this reporter.
30
30
  * @public
@@ -45,6 +45,13 @@ export declare class LogReporter<T, TD = unknown> implements ILogger, IResultRep
45
45
  * @param params - The parameters for creating the {@link Logging.LogReporter | LogReporter}.
46
46
  */
47
47
  constructor(params?: ILogReporterCreateParams<T, TD>);
48
+ /**
49
+ * Creates a default {@link Logging.LogReporter | LogReporter} with a {@link Logging.NoOpLogger | NoOpLogger} with the
50
+ * supplied parameters, returning both the logger and reporter.
51
+ * @param logger - Optional logger to use; defaults to a new {@link Logging.NoOpLogger | NoOpLogger} if not provided.
52
+ * @returns
53
+ */
54
+ static createDefault(logger?: ILogger): Result<LogReporter<unknown>>;
48
55
  /**
49
56
  * {@inheritDoc Logging.ILogger.logLevel}
50
57
  */
@@ -65,6 +72,14 @@ export declare class LogReporter<T, TD = unknown> implements ILogger, IResultRep
65
72
  * {@inheritDoc Logging.ILogger.error}
66
73
  */
67
74
  error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
75
+ /**
76
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
77
+ */
78
+ errorWithDetail(message: string, detail: unknown): Success<string | undefined>;
79
+ /**
80
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
81
+ */
82
+ warnWithDetail(message: string, detail: unknown): Success<string | undefined>;
68
83
  /**
69
84
  * {@inheritDoc Logging.ILogger.log}
70
85
  */
@@ -23,6 +23,7 @@ exports.LogReporter = void 0;
23
23
  * SOFTWARE.
24
24
  */
25
25
  const logger_1 = require("./logger");
26
+ const base_1 = require("../base");
26
27
  /**
27
28
  * Abstract base class which wraps an existing {@link Logging.ILogger | ILogger} to implement
28
29
  * both {@link Logging.ILogger | ILogger} and {@link IResultReporter | IResultReporter}.
@@ -41,6 +42,16 @@ class LogReporter {
41
42
  this._valueFormatter = (_b = params.valueFormatter) !== null && _b !== void 0 ? _b : LogReporter.tryFormatObject;
42
43
  this._messageFormatter = (_c = params.messageFormatter) !== null && _c !== void 0 ? _c : ((message, __detail) => message);
43
44
  }
45
+ /**
46
+ * Creates a default {@link Logging.LogReporter | LogReporter} with a {@link Logging.NoOpLogger | NoOpLogger} with the
47
+ * supplied parameters, returning both the logger and reporter.
48
+ * @param logger - Optional logger to use; defaults to a new {@link Logging.NoOpLogger | NoOpLogger} if not provided.
49
+ * @returns
50
+ */
51
+ static createDefault(logger) {
52
+ logger = logger !== null && logger !== void 0 ? logger : new logger_1.NoOpLogger();
53
+ return (0, base_1.captureResult)(() => new LogReporter({ logger }));
54
+ }
44
55
  /**
45
56
  * {@inheritDoc Logging.ILogger.logLevel}
46
57
  */
@@ -71,6 +82,26 @@ class LogReporter {
71
82
  error(message, ...parameters) {
72
83
  return this.logger.error(message, ...parameters);
73
84
  }
85
+ /**
86
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
87
+ */
88
+ errorWithDetail(message, detail) {
89
+ if ((0, logger_1.isDetailLogger)(this.logger)) {
90
+ return this.logger.errorWithDetail(message, detail);
91
+ }
92
+ this.logger.detail(detail);
93
+ return this.logger.error(message);
94
+ }
95
+ /**
96
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
97
+ */
98
+ warnWithDetail(message, detail) {
99
+ if ((0, logger_1.isDetailLogger)(this.logger)) {
100
+ return this.logger.warnWithDetail(message, detail);
101
+ }
102
+ this.logger.detail(detail);
103
+ return this.logger.warn(message);
104
+ }
74
105
  /**
75
106
  * {@inheritDoc Logging.ILogger.log}
76
107
  */
@@ -72,10 +72,39 @@ export interface ILogger {
72
72
  error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
73
73
  }
74
74
  /**
75
- * Abstract base class which implements {@link Logging.ILogger | ILogger}.
75
+ * Extended logger interface that supports logging a short summary message at a
76
+ * primary level (error/warn) while emitting the full detail at `detail` level.
77
+ *
78
+ * The detail is suppressed by default (requires log level `'detail'` or `'all'`),
79
+ * keeping the primary log clean while preserving the full context for debugging.
76
80
  * @public
77
81
  */
78
- export declare abstract class LoggerBase implements ILogger {
82
+ export interface IDetailLogger extends ILogger {
83
+ /**
84
+ * Logs a short error summary at `error` level, then emits `detail` at `detail` level.
85
+ * @param message - Short human-readable summary.
86
+ * @param detail - Full detail (e.g. raw converter error) logged at `detail` level.
87
+ */
88
+ errorWithDetail(message: string, detail: unknown): Success<string | undefined>;
89
+ /**
90
+ * Logs a short warning summary at `warning` level, then emits `detail` at `detail` level.
91
+ * @param message - Short human-readable summary.
92
+ * @param detail - Full detail logged at `detail` level.
93
+ */
94
+ warnWithDetail(message: string, detail: unknown): Success<string | undefined>;
95
+ }
96
+ /**
97
+ * Type guard that checks whether a logger implements {@link IDetailLogger}.
98
+ * @param logger - The logger to check.
99
+ * @returns `true` if the logger implements `IDetailLogger`.
100
+ * @public
101
+ */
102
+ export declare function isDetailLogger(logger: ILogger): logger is IDetailLogger;
103
+ /**
104
+ * Abstract base class which implements {@link Logging.IDetailLogger | IDetailLogger}.
105
+ * @public
106
+ */
107
+ export declare abstract class LoggerBase implements IDetailLogger {
79
108
  /**
80
109
  * {@inheritDoc Logging.ILogger.logLevel}
81
110
  */
@@ -97,6 +126,14 @@ export declare abstract class LoggerBase implements ILogger {
97
126
  * {@inheritDoc Logging.ILogger.error}
98
127
  */
99
128
  error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;
129
+ /**
130
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
131
+ */
132
+ errorWithDetail(message: string, detail: unknown): Success<string | undefined>;
133
+ /**
134
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
135
+ */
136
+ warnWithDetail(message: string, detail: unknown): Success<string | undefined>;
100
137
  /**
101
138
  * {@inheritDoc Logging.ILogger.log}
102
139
  */
@@ -162,10 +199,6 @@ export declare class InMemoryLogger extends LoggerBase {
162
199
  protected _log(message: string, __level: MessageLogLevel): Success<string | undefined>;
163
200
  /**
164
201
  * {@inheritDoc Logging.LoggerBase._suppressLog}
165
- * @param level - The level of the message.
166
- * @param message - The message to suppress.
167
- * @param parameters - The parameters to suppress.
168
- * @returns `Success` with `undefined` if the message is suppressed.
169
202
  * @internal
170
203
  */
171
204
  protected _suppressLog(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<undefined>;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NoOpLogger = exports.ConsoleLogger = exports.InMemoryLogger = exports.LoggerBase = void 0;
4
4
  exports.shouldLog = shouldLog;
5
5
  exports.stringifyLogValue = stringifyLogValue;
6
+ exports.isDetailLogger = isDetailLogger;
6
7
  /*
7
8
  * Copyright (c) 2020 Erik Fortune
8
9
  *
@@ -75,7 +76,17 @@ function stringifyLogValue(value, maxLength) {
75
76
  return str;
76
77
  }
77
78
  /**
78
- * Abstract base class which implements {@link Logging.ILogger | ILogger}.
79
+ * Type guard that checks whether a logger implements {@link IDetailLogger}.
80
+ * @param logger - The logger to check.
81
+ * @returns `true` if the logger implements `IDetailLogger`.
82
+ * @public
83
+ */
84
+ function isDetailLogger(logger) {
85
+ return (typeof logger.errorWithDetail === 'function' &&
86
+ typeof logger.warnWithDetail === 'function');
87
+ }
88
+ /**
89
+ * Abstract base class which implements {@link Logging.IDetailLogger | IDetailLogger}.
79
90
  * @public
80
91
  */
81
92
  class LoggerBase {
@@ -110,6 +121,20 @@ class LoggerBase {
110
121
  error(message, ...parameters) {
111
122
  return this.log('error', message, ...parameters);
112
123
  }
124
+ /**
125
+ * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
126
+ */
127
+ errorWithDetail(message, detail) {
128
+ this.detail(detail);
129
+ return this.error(message);
130
+ }
131
+ /**
132
+ * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
133
+ */
134
+ warnWithDetail(message, detail) {
135
+ this.detail(detail);
136
+ return this.warn(message);
137
+ }
113
138
  /**
114
139
  * {@inheritDoc Logging.ILogger.log}
115
140
  */
@@ -194,10 +219,6 @@ class InMemoryLogger extends LoggerBase {
194
219
  }
195
220
  /**
196
221
  * {@inheritDoc Logging.LoggerBase._suppressLog}
197
- * @param level - The level of the message.
198
- * @param message - The message to suppress.
199
- * @param parameters - The parameters to suppress.
200
- * @returns `Success` with `undefined` if the message is suppressed.
201
222
  * @internal
202
223
  */
203
224
  _suppressLog(level, message, ...parameters) {
@@ -1,5 +1,6 @@
1
1
  export { ArrayValidator, ArrayValidatorConstructorParams } from './array';
2
2
  export { BooleanValidator, BooleanValidatorConstructorParams } from './boolean';
3
+ export { CompositeIdValidator, CompositeIdValidatorConstructorParams } from './compositeId';
3
4
  export { NumberValidator, NumberValidatorConstructorParams } from './number';
4
5
  export { FieldValidators, ObjectValidator, ObjectValidatorConstructorParams, ObjectValidatorOptions } from './object';
5
6
  export { OneOfValidator, OneOfValidatorConstructorParams } from './oneOf';