@fgv/ts-utils 5.1.0-16 → 5.1.0-17

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.
@@ -31,7 +31,7 @@ import { captureResult, failWithDetail, fail, succeed, succeedWithDetail } from
31
31
  */
32
32
  export class Collector {
33
33
  /**
34
- * {@inheritDoc Collections.ResultMap.size}
34
+ * Returns the number of entries in the map.
35
35
  */
36
36
  get size() {
37
37
  return this._byIndex.length;
@@ -87,13 +87,16 @@ export class Collector {
87
87
  return succeedWithDetail(item, 'added');
88
88
  }
89
89
  /**
90
- * {@inheritDoc Collections.ResultMap.entries}
90
+ * Returns an iterator over the map entries.
91
+ * @returns An iterator over the map entries.
91
92
  */
92
93
  entries() {
93
94
  return this._byKey.entries();
94
95
  }
95
96
  /**
96
- * {@inheritDoc Collections.ResultMap.forEach}
97
+ * Calls a function for each entry in the map.
98
+ * @param callback - The function to call for each entry.
99
+ * @param arg - An optional argument to pass to the callback.
97
100
  */
98
101
  forEach(callback, arg) {
99
102
  for (const [key, value] of this._byKey.entries()) {
@@ -101,14 +104,20 @@ export class Collector {
101
104
  }
102
105
  }
103
106
  /**
104
- * {@inheritDoc Collections.ResultMap.get}
107
+ * Gets a value by key.
108
+ * @param key - The key to look up.
109
+ * @returns Returns {@link DetailedSuccess | Success} with the value and detail `exists` if found,
110
+ * or {@link DetailedFailure | Failure} with detail `not-found` if the key does not exist.
105
111
  */
106
112
  get(key) {
107
113
  const item = this._byKey.get(key);
108
114
  return item ? succeedWithDetail(item, 'exists') : failWithDetail(`${key}: not found`, 'not-found');
109
115
  }
110
116
  /**
111
- * {@inheritDoc Collections.IReadOnlyCollector.getAt}
117
+ * Gets the item at a specified index.
118
+ * @param index - The index of the item to retrieve.
119
+ * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure}
120
+ * with an error if the index is out of range.
112
121
  */
113
122
  getAt(index) {
114
123
  if (typeof index !== 'number') {
@@ -146,25 +155,30 @@ export class Collector {
146
155
  });
147
156
  }
148
157
  /**
149
- * {@inheritDoc Collections.ResultMap.has}
158
+ * Returns true if the map contains an entry with the given key.
159
+ * @param key - The key to check for.
160
+ * @returns `true` if the key exists, `false` otherwise.
150
161
  */
151
162
  has(key) {
152
163
  return this._byKey.has(key);
153
164
  }
154
165
  /**
155
- * {@inheritDoc Collections.ResultMap.keys}
166
+ * Returns an iterator over the map keys.
167
+ * @returns An iterator over the map keys.
156
168
  */
157
169
  keys() {
158
170
  return this._byKey.keys();
159
171
  }
160
172
  /**
161
- * {@inheritDoc Collections.ResultMap.values}
173
+ * Returns an iterator over the map values.
174
+ * @returns An iterator over the map values.
162
175
  */
163
176
  values() {
164
177
  return this._byKey.values();
165
178
  }
166
179
  /**
167
- * {@inheritDoc Collections.IReadOnlyCollector.valuesByIndex}
180
+ * Gets all items in the collection, ordered by index.
181
+ * @returns An array of items in the collection, ordered by index.
168
182
  */
169
183
  valuesByIndex() {
170
184
  return this._byIndex;
@@ -37,7 +37,12 @@ export class CollectorValidator {
37
37
  this.converters = params.converters;
38
38
  }
39
39
  /**
40
- * {@inheritDoc Collections.Collector.add}
40
+ * Adds an item to the collection, failing if a different item with the same key already exists. Note
41
+ * that adding an object that is already in the collection again will succeed without updating the collection.
42
+ * @param item - The item to add.
43
+ * @returns Returns {@link DetailedSuccess | Success} with the item and detail `added` if it was added
44
+ * or detail `exists` if the item was already in the map. Returns {@link DetailedFailure | Failure} with
45
+ * an error message and appropriate detail if the item could not be added.
41
46
  */
42
47
  add(item) {
43
48
  return this._convertValue(item).onSuccess((i) => {
@@ -44,25 +44,45 @@ export class BaseConverter {
44
44
  this._brand = traits === null || traits === void 0 ? void 0 : traits.brand;
45
45
  }
46
46
  /**
47
- * {@inheritDoc Converter.isOptional}
47
+ * Indicates whether this element is explicitly optional.
48
48
  */
49
49
  get isOptional() {
50
50
  return this._isOptional;
51
51
  }
52
52
  /**
53
- * {@inheritDoc Converter.brand}
53
+ * Returns the brand for a branded type.
54
54
  */
55
55
  get brand() {
56
56
  return this._brand;
57
57
  }
58
58
  /**
59
- * {@inheritDoc Converter.convert}
59
+ * Converts from `unknown` to `<T>`. For objects and arrays, is guaranteed
60
+ * to return a new entity, with any unrecognized properties removed.
61
+ * @param from - The `unknown` to be converted
62
+ * @param context - An optional conversion context of type `<TC>` to be used in
63
+ * the conversion.
64
+ * @returns A {@link Result} with a {@link Success} and a value on success or an
65
+ * {@link Failure} with a a message on failure.
60
66
  */
61
67
  convert(from, context) {
62
68
  return this._converter(from, this, context !== null && context !== void 0 ? context : this._defaultContext);
63
69
  }
64
70
  /**
65
- * {@inheritDoc Converter.convertOptional}
71
+ * Converts from `unknown` to `<T>` or `undefined`, as appropriate.
72
+ *
73
+ * @remarks
74
+ * If `onError` is `failOnError`, the converter succeeds for
75
+ * `undefined` or any convertible value, but reports an error
76
+ * if it encounters a value that cannot be converted.
77
+ *
78
+ * If `onError` is `ignoreErrors` (default) then values that
79
+ * cannot be converted result in a successful return of `undefined`.
80
+ * @param from - The `unknown` to be converted
81
+ * @param context - An optional conversion context of type `<TC>` to be used in
82
+ * the conversion.
83
+ * @param onError - Specifies handling of values that cannot be converted (default `ignoreErrors`).
84
+ * @returns A {@link Result} with a {@link Success} and a value on success or an
85
+ * {@link Failure} with a a message on failure.
66
86
  */
67
87
  convertOptional(from, context, onError) {
68
88
  const result = this._converter(from, this, this._context(context));
@@ -73,7 +93,18 @@ export class BaseConverter {
73
93
  return result;
74
94
  }
75
95
  /**
76
- * {@inheritDoc Converter.optional}
96
+ * Creates a {@link Converter} for an optional value.
97
+ *
98
+ * @remarks
99
+ * If `onError` is `failOnError`, the resulting converter will accept `undefined`
100
+ * or a convertible value, but report an error if it encounters a value that cannot be
101
+ * converted.
102
+ *
103
+ * If `onError` is `ignoreErrors` (default) then values that cannot be converted will
104
+ * result in a successful return of `undefined`.
105
+ *
106
+ * @param onError - Specifies handling of values that cannot be converted (default `ignoreErrors`).
107
+ * @returns A new {@link Converter} returning `<T|undefined>`.
77
108
  */
78
109
  optional(onError) {
79
110
  return new BaseConverter((from, __self, context) => {
@@ -82,7 +113,11 @@ export class BaseConverter {
82
113
  })._with(this._traits({ isOptional: true }));
83
114
  }
84
115
  /**
85
- * {@inheritDoc Converter.map}
116
+ * Creates a {@link Converter} which applies a (possibly) mapping conversion to
117
+ * the converted value of this {@link Converter}.
118
+ * @param mapper - A function which maps from the the result type `<T>` of this
119
+ * converter to a new result type `<T2>`.
120
+ * @returns A new {@link Converter} returning `<T2>`.
86
121
  */
87
122
  map(mapper) {
88
123
  return new BaseConverter((from, __self, context) => {
@@ -94,7 +129,12 @@ export class BaseConverter {
94
129
  })._with(this._traits());
95
130
  }
96
131
  /**
97
- * {@inheritDoc Converter.mapConvert}
132
+ * Creates a {@link Converter} which applies an additional supplied
133
+ * converter to the result of this converter.
134
+ *
135
+ * @param mapConverter - The {@link Converter} to be applied to the
136
+ * converted result from this {@link Converter}.
137
+ * @returns A new {@link Converter} returning `<T2>`.
98
138
  */
99
139
  mapConvert(mapConverter) {
100
140
  return new BaseConverter((from, __self, context) => {
@@ -106,7 +146,15 @@ export class BaseConverter {
106
146
  })._with(this._traits());
107
147
  }
108
148
  /**
109
- * {@inheritDoc Converter.mapItems}
149
+ * Creates a {@link Converter} which maps the individual items of a collection
150
+ * resulting from this {@link Converter} using the supplied map function.
151
+ *
152
+ * @remarks
153
+ * Fails if `from` is not an array.
154
+ *
155
+ * @param mapper - The map function to be applied to each element of the
156
+ * result of this {@link Converter}.
157
+ * @returns A new {@link Converter} returning `<TI[]>`.
110
158
  */
111
159
  mapItems(mapper) {
112
160
  return new BaseConverter((from, __self, context) => {
@@ -119,7 +167,15 @@ export class BaseConverter {
119
167
  });
120
168
  }
121
169
  /**
122
- * {@inheritDoc Converter.mapConvertItems}
170
+ * Creates a {@link Converter} which maps the individual items of a collection
171
+ * resulting from this {@link Converter} using the supplied {@link Converter}.
172
+ *
173
+ * @remarks
174
+ * Fails if `from` is not an array.
175
+ *
176
+ * @param mapConverter - The {@link Converter} to be applied to each element of the
177
+ * result of this {@link Converter}.
178
+ * @returns A new {@link Converter} returning `<TI[]>`.
123
179
  */
124
180
  mapConvertItems(mapConverter) {
125
181
  return new BaseConverter((from, __self, context) => {
@@ -132,7 +188,10 @@ export class BaseConverter {
132
188
  });
133
189
  }
134
190
  /**
135
- * {@inheritDoc Converter.withAction}
191
+ * Creates a {@link Converter | Converter} which applies a supplied action after
192
+ * conversion. The supplied action is always called regardless of success or failure
193
+ * of the base conversion and is allowed to mutate the return type.
194
+ * @param action - The action to be applied.
136
195
  */
137
196
  withAction(action) {
138
197
  return new BaseConverter((from, __self, context) => {
@@ -140,7 +199,11 @@ export class BaseConverter {
140
199
  })._with(this._traits());
141
200
  }
142
201
  /**
143
- * {@inheritDoc Converter.withTypeGuard}
202
+ * Creates a {@link Converter} which applies a supplied type guard to the conversion
203
+ * result.
204
+ * @param guard - The type guard function to apply.
205
+ * @param message - Optional message to be reported if the type guard fails.
206
+ * @returns A new {@link Converter} returning `<TI>`.
144
207
  */
145
208
  withTypeGuard(guard, message) {
146
209
  return new BaseConverter((from, __self, context) => {
@@ -153,7 +216,15 @@ export class BaseConverter {
153
216
  })._with(this._traits());
154
217
  }
155
218
  /**
156
- * {@inheritDoc Converter.withItemTypeGuard}
219
+ * Creates a {@link Converter} which applies a supplied type guard to each member of
220
+ * the conversion result from this converter.
221
+ *
222
+ * @remarks
223
+ * Fails if the conversion result is not an array or if any member fails the
224
+ * type guard.
225
+ * @param guard - The type guard function to apply to each element.
226
+ * @param message - Optional message to be reported if the type guard fails.
227
+ * @returns A new {@link Converter} returning `<TI>`.
157
228
  */
158
229
  withItemTypeGuard(guard, message) {
159
230
  return new BaseConverter((from, __self, context) => {
@@ -171,7 +242,15 @@ export class BaseConverter {
171
242
  })._with(this._traits());
172
243
  }
173
244
  /**
174
- * {@inheritDoc Converter.withConstraint}
245
+ * Creates a {@link Converter} which applies an optional constraint to the result
246
+ * of this conversion. If this {@link Converter} (the base converter) succeeds, the new
247
+ * converter calls a supplied constraint evaluation function with the conversion, which
248
+ * fails the entire conversion if the constraint function returns either `false` or
249
+ * {@link Failure | Failure<T>}.
250
+ *
251
+ * @param constraint - Constraint evaluation function.
252
+ * @param options - {@link Conversion.ConstraintOptions | Options} for constraint evaluation.
253
+ * @returns A new {@link Converter} returning `<T>`.
175
254
  */
176
255
  withConstraint(constraint, options) {
177
256
  return new BaseConverter((from, __self, context) => {
@@ -190,7 +269,10 @@ export class BaseConverter {
190
269
  })._with(this._traits());
191
270
  }
192
271
  /**
193
- * {@inheritDoc Converter.withBrand}
272
+ * Returns a converter which adds a brand to the type to prevent mismatched usage
273
+ * of simple types.
274
+ * @param brand - The brand to be applied to the result value.
275
+ * @returns A {@link Converter} returning `Brand<T, B>`.
194
276
  */
195
277
  withBrand(brand) {
196
278
  if (this._brand) {
@@ -203,7 +285,8 @@ export class BaseConverter {
203
285
  })._with(this._traits({ brand }));
204
286
  }
205
287
  /**
206
- * {@inheritDoc Converter.withDefault}
288
+ * Returns a Converter which always succeeds with a default value rather than failing.
289
+ * @param defaultValue - The default value to use if conversion fails.
207
290
  */
208
291
  withDefault(defaultValue) {
209
292
  return new GenericDefaultingConverter(this, defaultValue);
@@ -222,7 +305,10 @@ export class BaseConverter {
222
305
  return supplied !== null && supplied !== void 0 ? supplied : this._defaultContext;
223
306
  }
224
307
  /**
225
- * {@inheritDoc Converter.withFormattedError}
308
+ * Creates a new {@link Converter} which is derived from this one but which returns an
309
+ * error message formatted by the supplied formatter if the conversion fails.
310
+ * @param formatter - The formatter to be applied.
311
+ * @returns A new {@link Converter} returning `<T>`.
226
312
  */
227
313
  withFormattedError(formatter) {
228
314
  return new BaseConverter((from, __self, context) => {
@@ -86,51 +86,76 @@ export function isDetailLogger(logger) {
86
86
  export class LoggerBase {
87
87
  constructor(logLevel) {
88
88
  /**
89
- * {@inheritDoc Logging.ILogger.logLevel}
89
+ * The level of logging to be used.
90
90
  */
91
91
  this.logLevel = 'info';
92
92
  this.logLevel = logLevel !== null && logLevel !== void 0 ? logLevel : 'info';
93
93
  }
94
94
  /**
95
- * {@inheritDoc Logging.ILogger.detail}
95
+ * Logs a detail message.
96
+ * @param message - The message to log.
97
+ * @param parameters - The parameters to log.
98
+ * @returns `Success` with the logged message if the level is enabled, or
99
+ * `Success` with `undefined` if the message is suppressed.
96
100
  */
97
101
  detail(message, ...parameters) {
98
102
  return this.log('detail', message, ...parameters);
99
103
  }
100
104
  /**
101
- * {@inheritDoc Logging.ILogger.info}
105
+ * Logs an info message.
106
+ * @param message - The message to log.
107
+ * @param parameters - The parameters to log.
108
+ * @returns `Success` with the logged message if the level is enabled, or
109
+ * `Success` with `undefined` if the message is suppressed.
102
110
  */
103
111
  info(message, ...parameters) {
104
112
  return this.log('info', message, ...parameters);
105
113
  }
106
114
  /**
107
- * {@inheritDoc Logging.ILogger.warn}
115
+ * Logs a warning message.
116
+ * @param message - The message to log.
117
+ * @param parameters - The parameters to log.
118
+ * @returns `Success` with the logged message if the level is enabled, or
119
+ * `Success` with `undefined` if the message is suppressed.
108
120
  */
109
121
  warn(message, ...parameters) {
110
122
  return this.log('warning', message, ...parameters);
111
123
  }
112
124
  /**
113
- * {@inheritDoc Logging.ILogger.error}
125
+ * Logs an error message.
126
+ * @param message - The message to log.
127
+ * @param parameters - The parameters to log.
128
+ * @returns `Success` with the logged message if the level is enabled, or
129
+ * `Success` with `undefined` if the message is suppressed.
114
130
  */
115
131
  error(message, ...parameters) {
116
132
  return this.log('error', message, ...parameters);
117
133
  }
118
134
  /**
119
- * {@inheritDoc Logging.IDetailLogger.errorWithDetail}
135
+ * Logs a short error summary at `error` level, then emits `detail` at `detail` level.
136
+ * @param message - Short human-readable summary.
137
+ * @param detail - Full detail (e.g. raw converter error) logged at `detail` level.
120
138
  */
121
139
  errorWithDetail(message, detail) {
122
140
  this.detail(detail);
123
141
  return this.error(message);
124
142
  }
125
143
  /**
126
- * {@inheritDoc Logging.IDetailLogger.warnWithDetail}
144
+ * Logs a short warning summary at `warning` level, then emits `detail` at `detail` level.
145
+ * @param message - Short human-readable summary.
146
+ * @param detail - Full detail logged at `detail` level.
127
147
  */
128
148
  warnWithDetail(message, detail) {
129
149
  this.detail(detail);
130
150
  return this.warn(message);
131
151
  }
132
152
  /**
133
- * {@inheritDoc Logging.ILogger.log}
153
+ * Logs a message at the given level.
154
+ * @param level - The level of the message.
155
+ * @param message - The message to log.
156
+ * @param parameters - The parameters to log.
157
+ * @returns `Success` with the logged message if the level is enabled, or
158
+ * `Success` with `undefined` if the message is suppressed.
134
159
  */
135
160
  log(level, message, ...parameters) {
136
161
  if (shouldLog(level, this.logLevel)) {