@likec4/log 1.48.0 → 1.50.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.
@@ -0,0 +1,76 @@
1
+ # Licenses of Bundled Dependencies
2
+
3
+ The published artifact additionally contains code with the following licenses:
4
+ MIT
5
+
6
+ # Bundled Dependencies
7
+
8
+ ## is-error-instance
9
+
10
+ License: MIT
11
+ By: ehmicky
12
+ Repository: https://github.com/ehmicky/is-error-instance
13
+
14
+ > Copyright © 2024 ehmicky
15
+ >
16
+ > Permission is hereby granted, free of charge, to any person obtaining a copy of
17
+ > this software and associated documentation files (the “Software”), to deal in
18
+ > the Software without restriction, including without limitation the rights to
19
+ > use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
20
+ > the Software, and to permit persons to whom the Software is furnished to do so,
21
+ > subject to the following conditions:
22
+ >
23
+ > The above copyright notice and this permission notice shall be included in all
24
+ > copies or substantial portions of the Software.
25
+ >
26
+ > THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
28
+ > FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
29
+ > COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
30
+ > IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31
+ > CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+
33
+ ---------------------------------------
34
+
35
+ ## is-plain-obj, safe-stringify
36
+
37
+ License: MIT
38
+ By: Sindre Sorhus
39
+ Repositories: https://github.com/sindresorhus/is-plain-obj, https://github.com/sindresorhus/safe-stringify
40
+
41
+ > MIT License
42
+ >
43
+ > Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
44
+ >
45
+ > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
46
+ >
47
+ > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
48
+ >
49
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50
+
51
+ ---------------------------------------
52
+
53
+ ## merge-error-cause, normalize-exception, redefine-property, set-error-class, set-error-message, set-error-props, wrap-error-message
54
+
55
+ License: MIT
56
+ By: ehmicky
57
+ Repositories: https://github.com/ehmicky/merge-error-cause, https://github.com/ehmicky/normalize-exception, https://github.com/ehmicky/redefine-property, https://github.com/ehmicky/set-error-class, https://github.com/ehmicky/set-error-message, https://github.com/ehmicky/set-error-props, https://github.com/ehmicky/wrap-error-message
58
+
59
+ > Copyright © 2025 ehmicky
60
+ >
61
+ > Permission is hereby granted, free of charge, to any person obtaining a copy of
62
+ > this software and associated documentation files (the “Software”), to deal in
63
+ > the Software without restriction, including without limitation the rights to
64
+ > use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
65
+ > the Software, and to permit persons to whom the Software is furnished to do so,
66
+ > subject to the following conditions:
67
+ >
68
+ > The above copyright notice and this permission notice shall be included in all
69
+ > copies or substantial portions of the Software.
70
+ >
71
+ > THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
72
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
73
+ > FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
74
+ > COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
75
+ > IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
76
+ > CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,6 +1,4 @@
1
- //#region ../../node_modules/.pnpm/is-error-instance@3.0.1/node_modules/is-error-instance/build/src/main.js
2
1
  const isErrorInstance = (value) => isInstanceOfError(value) || hasErrorTag(value);
3
- var main_default = isErrorInstance;
4
2
  const isInstanceOfError = (value) => {
5
3
  try {
6
4
  return value instanceof Error;
@@ -21,6 +19,4 @@ const ERROR_TAGS = new Set([
21
19
  "[object DOMError]",
22
20
  "[object Exception]"
23
21
  ]);
24
-
25
- //#endregion
26
- export { main_default as t };
22
+ export { isErrorInstance as t };
@@ -1,9 +1,6 @@
1
- //#region ../../node_modules/.pnpm/is-plain-obj@4.1.0/node_modules/is-plain-obj/index.js
2
1
  function isPlainObject(value) {
3
2
  if (typeof value !== "object" || value === null) return false;
4
3
  const prototype = Object.getPrototypeOf(value);
5
4
  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
6
5
  }
7
-
8
- //#endregion
9
- export { isPlainObject as t };
6
+ export { isPlainObject as t };
@@ -1,7 +1,5 @@
1
- import { t as main_default$7 } from "./is-error-instance.mjs";
1
+ import { t as isErrorInstance } from "./is-error-instance.mjs";
2
2
  import { t as isPlainObject } from "./is-plain-obj.mjs";
3
-
4
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/descriptors.js
5
3
  const normalizeDescriptors = (error) => {
6
4
  CORE_ERROR_PROPS.forEach((propName) => {
7
5
  normalizeDescriptor$1(error, propName);
@@ -42,9 +40,6 @@ const setErrorDescriptor = (error, propName, descriptor) => {
42
40
  configurable: true
43
41
  });
44
42
  };
45
-
46
- //#endregion
47
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/aggregate.js
48
43
  const normalizeAggregate = (error, recurse) => {
49
44
  if (Array.isArray(error.errors)) setErrorProperty$1(error, "errors", error.errors.filter(isDefined).map(recurse).filter(Boolean));
50
45
  else if (isAggregateError(error)) setErrorProperty$1(error, "errors", []);
@@ -56,18 +51,12 @@ const deleteAggregateErrors = (error) => {
56
51
  delete error.errors;
57
52
  if (error.errors !== void 0) setErrorProperty$1(error, "errors", []);
58
53
  };
59
-
60
- //#endregion
61
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/cause.js
62
54
  const normalizeCause = (error, recurse) => {
63
55
  if (!("cause" in error)) return;
64
56
  const cause = error.cause === void 0 ? error.cause : recurse(error.cause);
65
57
  if (cause === void 0) delete error.cause;
66
58
  else setErrorProperty$1(error, "cause", cause);
67
59
  };
68
-
69
- //#endregion
70
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/create/modifiable.js
71
60
  const isNonModifiableError = (error) => !Object.isExtensible(error) || CORE_ERROR_PROPS.some((propName) => isNonConfigurableProp(error, propName) || isThrowingProp(error, propName));
72
61
  const isNonConfigurableProp = (error, propName) => {
73
62
  const descriptor = Object.getOwnPropertyDescriptor(error, propName);
@@ -81,9 +70,6 @@ const isThrowingProp = (error, propName) => {
81
70
  return true;
82
71
  }
83
72
  };
84
-
85
- //#endregion
86
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/stack.js
87
73
  const setStack = (error) => {
88
74
  setErrorProperty$1(error, "stack", getStack$3(error.message, error.name));
89
75
  };
@@ -102,9 +88,6 @@ const getErrorClass = (name) => {
102
88
  Object.defineProperty(StackError.prototype, "name", descriptor);
103
89
  return StackError;
104
90
  };
105
-
106
- //#endregion
107
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/create/copy.js
108
91
  const copyObject = (object) => {
109
92
  const objectCopy = {};
110
93
  for (const propName of getPropsToCopy(object)) try {
@@ -138,9 +121,6 @@ const isInheritedProp = (object, propName) => {
138
121
  return false;
139
122
  }
140
123
  };
141
-
142
- //#endregion
143
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/create/object.js
144
124
  const objectifyError = (object) => {
145
125
  const { name, message, stack, cause, errors, ...objectA } = copyObject(object);
146
126
  const messageA = getMessage$1(message, objectA);
@@ -194,9 +174,6 @@ const assignObjectProps = (error, object) => {
194
174
  const setNewErrorProperty = (error, propName, propValue) => {
195
175
  if (propValue !== void 0) setErrorProperty$1(error, propName, propValue);
196
176
  };
197
-
198
- //#endregion
199
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/create/string.js
200
177
  const stringifyError = (value) => {
201
178
  try {
202
179
  const error = new Error(String(value));
@@ -206,13 +183,10 @@ const stringifyError = (value) => {
206
183
  return error_;
207
184
  }
208
185
  };
209
-
210
- //#endregion
211
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/create/main.js
212
186
  const { toString: objectToString } = Object.prototype;
213
187
  const createError = (value) => {
214
188
  if (isErrorPlainObj(value)) return objectifyError(value);
215
- if (!main_default$7(value)) return stringifyError(value);
189
+ if (!isErrorInstance(value)) return stringifyError(value);
216
190
  if (isInvalidError(value)) return objectifyError(value);
217
191
  return value;
218
192
  };
@@ -232,11 +206,7 @@ const isProxy = (value) => {
232
206
  }
233
207
  };
234
208
  const hasInvalidConstructor = (error) => typeof error.constructor !== "function" || typeof error.constructor.name !== "string" || error.constructor.name === "" || error.constructor.prototype !== Object.getPrototypeOf(error);
235
-
236
- //#endregion
237
- //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/main.js
238
209
  const normalizeException = (error, { shallow = false } = {}) => recurseException(error, [], shallow);
239
- var main_default$6 = normalizeException;
240
210
  const recurseException = (error, parents, shallow) => {
241
211
  if (parents.includes(error)) return;
242
212
  const recurse = shallow ? identity : (innerError) => recurseException(innerError, [...parents, error], shallow);
@@ -265,9 +235,6 @@ const normalizeStack = (error) => {
265
235
  if (!isDefinedString$1(error.stack)) setStack(error);
266
236
  };
267
237
  const isDefinedString$1 = (value) => typeof value === "string" && value !== "";
268
-
269
- //#endregion
270
- //#region ../../node_modules/.pnpm/set-error-class@3.0.1/node_modules/set-error-class/build/src/args.js
271
238
  const normalizeArgs$1 = (error, ErrorClass, currentName = error.name) => {
272
239
  validateErrorClass(ErrorClass);
273
240
  if (typeof currentName !== "string") throw new TypeError(`currentName must be a string: ${currentName}`);
@@ -281,9 +248,6 @@ const validateErrorClass = (ErrorClass) => {
281
248
  const isClass = (ErrorClass) => typeof ErrorClass === "function" && typeof ErrorClass.prototype === "object" && ErrorClass.prototype !== null;
282
249
  const isErrorClass = (prototype) => prototype !== null && (prototype.name === "Error" || isErrorClass(Object.getPrototypeOf(prototype)));
283
250
  const hasConstructor = (ErrorClass) => typeof ErrorClass.prototype.constructor === "function";
284
-
285
- //#endregion
286
- //#region ../../node_modules/.pnpm/set-error-class@3.0.1/node_modules/set-error-class/build/src/enum.js
287
251
  const setNonEnumProp$1 = (error, propName, value) => {
288
252
  Object.defineProperty(error, propName, {
289
253
  value,
@@ -292,9 +256,6 @@ const setNonEnumProp$1 = (error, propName, value) => {
292
256
  configurable: true
293
257
  });
294
258
  };
295
-
296
- //#endregion
297
- //#region ../../node_modules/.pnpm/set-error-class@3.0.1/node_modules/set-error-class/build/src/prototype.js
298
259
  const updatePrototype = (error, ErrorClass) => {
299
260
  if (Object.getPrototypeOf(error) === ErrorClass.prototype) return;
300
261
  setPrototype(error, ErrorClass);
@@ -316,9 +277,6 @@ const isDefinedString = (value) => typeof value === "string" && value !== "";
316
277
  const deleteOwnProperty = (error, propName) => {
317
278
  if (Object.hasOwn(error, propName)) delete error[propName];
318
279
  };
319
-
320
- //#endregion
321
- //#region ../../node_modules/.pnpm/set-error-class@3.0.1/node_modules/set-error-class/build/src/stack.js
322
280
  const updateStack$1 = (error, currentName) => {
323
281
  if (!shouldUpdateStack(error, currentName)) return;
324
282
  setNonEnumProp$1(error, "stack", getStack$2(error, currentName));
@@ -349,20 +307,13 @@ const getReplacers$1 = (currentName, newName) => [
349
307
  [`${currentName} `, `${newName} `],
350
308
  [currentName, newName]
351
309
  ];
352
-
353
- //#endregion
354
- //#region ../../node_modules/.pnpm/set-error-class@3.0.1/node_modules/set-error-class/build/src/main.js
355
310
  const setErrorClass = (error, ErrorClass, currentName) => {
356
- const errorA = main_default$6(error);
311
+ const errorA = normalizeException(error);
357
312
  const currentNameA = normalizeArgs$1(errorA, ErrorClass, currentName);
358
313
  updatePrototype(errorA, ErrorClass);
359
314
  updateStack$1(errorA, currentNameA);
360
315
  return errorA;
361
316
  };
362
- var main_default$5 = setErrorClass;
363
-
364
- //#endregion
365
- //#region ../../node_modules/.pnpm/redefine-property@3.0.1/node_modules/redefine-property/build/src/merge.js
366
317
  const mergeDescriptors = (newDescriptor, currentDescriptor) => currentDescriptor.configurable === false ? mergeNonConfig(newDescriptor, currentDescriptor) : mergeConfig(newDescriptor, currentDescriptor);
367
318
  const mergeNonConfig = (newDescriptor, currentDescriptor) => ({
368
319
  ...currentDescriptor,
@@ -397,9 +348,6 @@ const mergeValue = (newDescriptor, currentDescriptor, writable) => {
397
348
  };
398
349
  const hasGetSet = ({ get, set }) => get !== void 0 || set !== void 0;
399
350
  const mergeDescriptor = (newValue, currentValue, defaultValue) => newValue ?? currentValue ?? defaultValue;
400
-
401
- //#endregion
402
- //#region ../../node_modules/.pnpm/redefine-property@3.0.1/node_modules/redefine-property/build/src/normalize.js
403
351
  const normalizeInput = (input, key, newDescriptor) => {
404
352
  if (!isAnyObj(input)) throw new TypeError(`Argument must be an object: ${input}`);
405
353
  if (!isValidKey(key)) throw new TypeError(`Property key must be a string, a symbol or an integer: ${key}`);
@@ -455,14 +403,10 @@ const validateUnknownProps = (unknownProps) => {
455
403
  const [unknownProp] = Object.keys(unknownProps);
456
404
  if (unknownProp !== void 0) throw new TypeError(`Unknown descriptor property "${unknownProp}": ${unknownProps[unknownProp]}`);
457
405
  };
458
-
459
- //#endregion
460
- //#region ../../node_modules/.pnpm/redefine-property@3.0.1/node_modules/redefine-property/build/src/main.js
461
406
  const redefineProperty = (input, key, newDescriptor) => {
462
407
  setProperty(input, key, mergeDescriptors(normalizeInput(input, key, newDescriptor), getCurrentDescriptor(input, key)));
463
408
  return input;
464
409
  };
465
- var main_default$4 = redefineProperty;
466
410
  const getCurrentDescriptor = (input, key) => {
467
411
  const descriptor = Object.getOwnPropertyDescriptor(input, key);
468
412
  if (descriptor !== void 0) return descriptor;
@@ -474,9 +418,6 @@ const setProperty = (input, key, finalDescriptor) => {
474
418
  Object.defineProperty(input, key, finalDescriptor);
475
419
  } catch {}
476
420
  };
477
-
478
- //#endregion
479
- //#region ../../node_modules/.pnpm/set-error-props@6.0.1/node_modules/set-error-props/build/src/assign.js
480
421
  const assignProp = (error, propName, propValue) => {
481
422
  if (propValue !== void 0) return setProp(error, propName, propValue);
482
423
  try {
@@ -485,15 +426,12 @@ const assignProp = (error, propName, propValue) => {
485
426
  if (error[propName] !== void 0) return setProp(error, propName);
486
427
  };
487
428
  const setProp = (error, propName, propValue) => {
488
- main_default$4(error, propName, {
429
+ redefineProperty(error, propName, {
489
430
  value: propValue,
490
431
  ...getNonEnum(propName)
491
432
  });
492
433
  };
493
434
  const getNonEnum = (propName) => typeof propName === "string" && propName.startsWith("_") ? { enumerable: false } : {};
494
-
495
- //#endregion
496
- //#region ../../node_modules/.pnpm/set-error-props@6.0.1/node_modules/set-error-props/build/src/options.js
497
435
  const normalizeOptions = (error, props, opts = {}) => {
498
436
  validateErrorOrObject(error, "First argument");
499
437
  validateErrorOrObject(props, "Second argument");
@@ -506,10 +444,7 @@ const validateErrorOrObject = (value, prefix) => {
506
444
  if (value === void 0) throw new TypeError(`${prefix} is required.`);
507
445
  if (!isErrorOrObject(value)) throw new TypeError(`${prefix} must be a plain object or an error: ${value}`);
508
446
  };
509
- const isErrorOrObject = (value) => isPlainObject(value) || main_default$7(value);
510
-
511
- //#endregion
512
- //#region ../../node_modules/.pnpm/set-error-props@6.0.1/node_modules/set-error-props/build/src/skip.js
447
+ const isErrorOrObject = (value) => isPlainObject(value) || isErrorInstance(value);
513
448
  const shouldSkipProp = ({ error, props, propName, soft }) => isIgnoredPropName(propName) || !isEnum.call(props, propName) || soft && error[propName] !== void 0;
514
449
  const isIgnoredPropName = (propName) => propName in CHECK_ERROR || IGNORED_PROPS.has(propName);
515
450
  const CHECK_ERROR = /* @__PURE__ */ new Error("check");
@@ -519,9 +454,6 @@ const IGNORED_PROPS = new Set([
519
454
  "cause"
520
455
  ]);
521
456
  const { propertyIsEnumerable: isEnum } = Object.prototype;
522
-
523
- //#endregion
524
- //#region ../../node_modules/.pnpm/set-error-props@6.0.1/node_modules/set-error-props/build/src/main.js
525
457
  const setErrorProps = (error, props, opts) => {
526
458
  const { soft } = normalizeOptions(error, props, opts);
527
459
  for (const propName of Reflect.ownKeys(props)) setErrorProp({
@@ -532,7 +464,6 @@ const setErrorProps = (error, props, opts) => {
532
464
  });
533
465
  return error;
534
466
  };
535
- var main_default$3 = setErrorProps;
536
467
  const setErrorProp = ({ error, props, propName, soft }) => {
537
468
  if (!shouldSkipProp({
538
469
  error,
@@ -541,9 +472,6 @@ const setErrorProp = ({ error, props, propName, soft }) => {
541
472
  soft
542
473
  })) assignProp(error, propName, props[propName]);
543
474
  };
544
-
545
- //#endregion
546
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/set.js
547
475
  const setErrorProperty = (error, propName, value) => {
548
476
  Object.defineProperty(error, propName, {
549
477
  value,
@@ -552,9 +480,6 @@ const setErrorProperty = (error, propName, value) => {
552
480
  configurable: true
553
481
  });
554
482
  };
555
-
556
- //#endregion
557
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/aggregate.js
558
483
  const mergeAggregateCauses = (parent, recurse) => {
559
484
  if (parent.errors === void 0) return;
560
485
  setErrorProperty(parent, "errors", parent.errors.map((error) => recurse(error).error).filter(Boolean));
@@ -570,17 +495,11 @@ const mergeSourceErrors = (target, source) => {
570
495
  if (source.errors !== void 0) setErrorProperty(target, "errors", source.errors);
571
496
  };
572
497
  const hasErrors = (targetOrSource) => targetOrSource.errors !== void 0 && targetOrSource.errors.length !== 0;
573
-
574
- //#endregion
575
- //#region ../../node_modules/.pnpm/set-error-message@3.0.1/node_modules/set-error-message/build/src/args.js
576
498
  const normalizeArgs = (error, newMessage, currentMessage = error.message) => {
577
499
  if (typeof newMessage !== "string") throw new TypeError(`newMessage must be a string: ${newMessage}`);
578
500
  if (typeof currentMessage !== "string") throw new TypeError(`currentMessage must be a string: ${currentMessage}`);
579
501
  return currentMessage;
580
502
  };
581
-
582
- //#endregion
583
- //#region ../../node_modules/.pnpm/set-error-message@3.0.1/node_modules/set-error-message/build/src/stack.js
584
503
  const getStack$1 = ({ name, stack }, newMessage, currentMessage) => currentMessage !== "" && stack.includes(currentMessage) ? replaceMessage({
585
504
  name,
586
505
  stack,
@@ -604,17 +523,13 @@ const insertMessage = (name, stack, newMessage) => {
604
523
  if (stack === name || stack.startsWith(`${name}\n`)) return stack.replace(name, `${nameAndColon}${newMessageA}`);
605
524
  return stack.startsWith(nameAndColon) ? stack.replace(nameAndColon, `${nameAndColon}${newMessageA}\n`) : `${nameAndColon}${newMessageA}\n${stack}`;
606
525
  };
607
-
608
- //#endregion
609
- //#region ../../node_modules/.pnpm/set-error-message@3.0.1/node_modules/set-error-message/build/src/main.js
610
526
  const setErrorMessage = (error, newMessage, currentMessage) => {
611
- const errorA = main_default$6(error);
527
+ const errorA = normalizeException(error);
612
528
  const currentMessageA = normalizeArgs(errorA, newMessage, currentMessage);
613
529
  setNonEnumProp(errorA, "message", newMessage);
614
530
  updateStack(errorA, newMessage, currentMessageA);
615
531
  return errorA;
616
532
  };
617
- var main_default$2 = setErrorMessage;
618
533
  const updateStack = (error, newMessage, currentMessage) => {
619
534
  if (newMessage === currentMessage || !stackIncludesMessage()) return;
620
535
  setNonEnumProp(error, "stack", getStack$1(error, newMessage, currentMessage));
@@ -632,15 +547,11 @@ const setNonEnumProp = (error, propName, value) => {
632
547
  configurable: true
633
548
  });
634
549
  };
635
-
636
- //#endregion
637
- //#region ../../node_modules/.pnpm/wrap-error-message@3.0.1/node_modules/wrap-error-message/build/src/main.js
638
550
  const wrapErrorMessage = (error, newMessage, oldMessage) => {
639
551
  if (typeof newMessage !== "string") throw new TypeError(`Second argument must be a message string: ${newMessage}`);
640
- const errorA = main_default$6(error);
641
- return main_default$2(errorA, getMessage(newMessage, errorA.message), oldMessage);
552
+ const errorA = normalizeException(error);
553
+ return setErrorMessage(errorA, getMessage(newMessage, errorA.message), oldMessage);
642
554
  };
643
- var main_default$1 = wrapErrorMessage;
644
555
  const getMessage = (rawNewMessage, rawCurrentMessage) => {
645
556
  const newMessage = rawNewMessage.trim();
646
557
  const currentMessage = rawCurrentMessage.trim();
@@ -654,18 +565,12 @@ const concatMessages = (newMessage, currentMessage, rawNewMessage) => {
654
565
  };
655
566
  const PREPEND_CHAR = ":";
656
567
  const PREPEND_NEWLINE_CHAR = "\n";
657
-
658
- //#endregion
659
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/message.js
660
568
  const mergeMessage = ({ parent, child, target, stackError }) => {
661
569
  const parentMessage = parent.message;
662
570
  const stackErrorMessage = stackError.message;
663
571
  target.message = child.message;
664
- return main_default$1(target, parentMessage, stackErrorMessage);
572
+ return wrapErrorMessage(target, parentMessage, stackErrorMessage);
665
573
  };
666
-
667
- //#endregion
668
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/stack.js
669
574
  const hasStack = (error, stack) => getStack(error) === stack;
670
575
  const getStack = (error) => typeof error === "object" && error !== null ? error.stack : void 0;
671
576
  const mergeStack = ({ wrap, target, source, childHasStack }) => {
@@ -673,25 +578,18 @@ const mergeStack = ({ wrap, target, source, childHasStack }) => {
673
578
  setErrorProperty(target, "stack", source.stack);
674
579
  return source;
675
580
  };
676
-
677
- //#endregion
678
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/wrap.js
679
581
  const getWrap = (parent) => {
680
582
  const { wrap, name } = parent;
681
583
  if (typeof wrap !== "boolean") return name === "Error";
682
584
  if (Object.hasOwn(parent, "wrap")) delete parent.wrap;
683
585
  return wrap;
684
586
  };
685
-
686
- //#endregion
687
- //#region ../../node_modules/.pnpm/merge-error-cause@5.0.2/node_modules/merge-error-cause/build/src/main.js
688
587
  const mergeErrorCause = (error) => mergeError(error, []).error;
689
- var main_default = mergeErrorCause;
690
588
  const mergeError = (error, parents) => {
691
589
  if (parents.includes(error)) return {};
692
590
  const recurse = (innerError) => mergeError(innerError, [...parents, error]);
693
591
  const stack = getStack(error);
694
- const errorA = main_default$6(error, { shallow: true });
592
+ const errorA = normalizeException(error, { shallow: true });
695
593
  const parentHasStack = hasStack(errorA, stack);
696
594
  mergeAggregateCauses(errorA, recurse);
697
595
  const { parent: errorB, childHasStack } = mergeCause(errorA, recurse);
@@ -730,7 +628,7 @@ const mergeChild = ({ parent, child, childHasStack, wrap }) => {
730
628
  const targetB = mergeMessage({
731
629
  parent,
732
630
  child,
733
- target: main_default$5(target, target.constructor, stackError.name),
631
+ target: setErrorClass(target, target.constructor, stackError.name),
734
632
  stackError
735
633
  });
736
634
  mergeAggregateErrors({
@@ -739,8 +637,6 @@ const mergeChild = ({ parent, child, childHasStack, wrap }) => {
739
637
  parent,
740
638
  child
741
639
  });
742
- return main_default$3(targetB, source, { soft: !wrap });
640
+ return setErrorProps(targetB, source, { soft: !wrap });
743
641
  };
744
-
745
- //#endregion
746
- export { main_default$1 as n, main_default as t };
642
+ export { wrapErrorMessage as n, mergeErrorCause as t };
@@ -1,21 +1,19 @@
1
- //#region ../../node_modules/.pnpm/safe-stringify@1.2.0/node_modules/safe-stringify/index.js
2
- function safeStringifyReplacer(seen) {
3
- const replacer = function(key, value) {
4
- if (typeof value?.toJSON === "function") value = value.toJSON();
5
- if (!(value !== null && typeof value === "object")) return value;
6
- if (seen.has(value)) return "[Circular]";
7
- seen.add(value);
8
- const newValue = Array.isArray(value) ? [] : {};
9
- for (const [key2, value2] of Object.entries(value)) newValue[key2] = replacer(key2, value2);
10
- seen.delete(value);
11
- return newValue;
12
- };
13
- return replacer;
1
+ function serializeValue(value, seen, trace, currentPath) {
2
+ if (typeof value?.toJSON === "function") value = value.toJSON();
3
+ if (!(value !== null && typeof value === "object")) return value;
4
+ if (seen.has(value)) {
5
+ if (!trace) return "[Circular]";
6
+ const existingPath = seen.get(value);
7
+ return `[Circular ${existingPath === "" ? "*" : `*${existingPath}`}]`;
8
+ }
9
+ seen.set(value, currentPath);
10
+ const newValue = Array.isArray(value) ? [] : {};
11
+ for (const [propertyKey, propertyValue] of Object.entries(value)) newValue[propertyKey] = serializeValue(propertyValue, seen, trace, currentPath === "" ? propertyKey : `${currentPath}.${propertyKey}`);
12
+ seen.delete(value);
13
+ return newValue;
14
14
  }
15
- function safeStringify(object, { indentation } = {}) {
16
- const seen = /* @__PURE__ */ new WeakSet();
17
- return JSON.stringify(object, safeStringifyReplacer(seen), indentation);
15
+ function safeStringify(value, { indentation, trace } = {}) {
16
+ const serializedValue = serializeValue(value, /* @__PURE__ */ new WeakMap(), trace, "");
17
+ return JSON.stringify(serializedValue, void 0, indentation);
18
18
  }
19
-
20
- //#endregion
21
- export { safeStringify as t };
19
+ export { safeStringify as t };
package/dist/index.d.mts CHANGED
@@ -2,28 +2,61 @@ import * as _logtape_logtape0 from "@logtape/logtape";
2
2
  import { AnsiColorFormatterOptions, Config, ConsoleFormatter, ConsoleSinkOptions, Filter, LogLevel, LogRecord, LogRecord as LogRecord$1, Logger, Sink, Sink as Sink$1, TextFormatter, TextFormatter as TextFormatter$1, TextFormatterOptions, withFilter } from "@logtape/logtape";
3
3
 
4
4
  //#region src/formatters.d.ts
5
+ /**
6
+ * Extract a single Error from a log record (from properties or rawMessage).
7
+ * @param record - Log record that may contain error in properties or rawMessage
8
+ * @returns Merged/wrapped Error or null if none found
9
+ */
5
10
  declare function errorFromLogRecord(record: LogRecord$1): Error | null;
11
+ /**
12
+ * Formatter that outputs only the log message (no timestamp/level/category).
13
+ * @returns TextFormatter that returns just the message string
14
+ */
6
15
  declare function getMessageOnlyFormatter(): TextFormatter$1;
16
+ /**
17
+ * Build a text formatter with optional custom format; appends error from record.
18
+ * @param options - Optional format and logtape options
19
+ * @returns TextFormatter
20
+ */
7
21
  declare function getTextFormatter(options?: TextFormatterOptions): TextFormatter$1;
22
+ /**
23
+ * Build an ANSI-colored text formatter (level/category colors); appends error in red.
24
+ * @param options - Optional format and logtape ANSI options
25
+ * @returns TextFormatter with ANSI colors
26
+ */
8
27
  declare function getAnsiColorFormatter(options?: AnsiColorFormatterOptions): TextFormatter$1;
9
28
  /**
10
29
  * The formatter returns an array where:
11
30
  * - First element is the formatted message string
12
31
  * - Second element is the record properties object
32
+ * @param options - Optional messageFormatter (TextFormatter)
33
+ * @returns ConsoleFormatter for console.log/error
13
34
  */
14
35
  declare function getConsoleFormatter(options?: {
15
36
  messageFormatter?: TextFormatter$1;
16
37
  }): ConsoleFormatter;
17
38
  //#endregion
18
39
  //#region src/sink.d.ts
40
+ /**
41
+ * Create a sink that writes formatted log records to stdout (default formatter).
42
+ * @param options - Optional console sink options (e.g. custom formatter)
43
+ * @returns Sink that writes to stdout
44
+ */
19
45
  declare function getConsoleSink(options?: ConsoleSinkOptions): Sink$1;
20
46
  /**
21
47
  * Creates a console sink that writes to stderr.
22
48
  * (MCP protocol requires stderr to be used for logging)
49
+ * @param options - Optional console sink options (e.g. custom formatter)
50
+ * @returns Sink that writes to stderr
23
51
  */
24
52
  declare function getConsoleStderrSink(options?: ConsoleSinkOptions): Sink$1;
25
53
  //#endregion
26
54
  //#region src/utils.d.ts
55
+ /**
56
+ * Serialize unknown to a string (Error → message + stack; else safe-stringify).
57
+ * @param error - Caught value (Error, string, or arbitrary object)
58
+ * @returns Human-readable string for logging
59
+ */
27
60
  declare function loggable(error: unknown): string;
28
61
  type NormalizeError<ErrorArg> = ErrorArg extends Error ? ErrorArg : Error;
29
62
  /**
@@ -70,6 +103,10 @@ declare const logger: _logtape_logtape0.Logger;
70
103
  * @returns The child logger.
71
104
  */
72
105
  declare function createLogger(subcategory: string | readonly [string] | readonly [string, ...string[]]): _logtape_logtape0.Logger;
106
+ /**
107
+ * Configure the global logger: sinks, loggers, and lowest level per category.
108
+ * @param config - Optional partial config (sinks, loggers). Merged with defaults.
109
+ */
73
110
  declare function configureLogger<TSinkId extends string, TFilterId extends string>(config?: Partial<Config<TSinkId, TFilterId>>): void;
74
111
  //#endregion
75
112
  export { type Filter, type LogLevel, type LogRecord, type Logger, type Sink, type TextFormatter, configureLogger, logger as consola, logger, logger as rootLogger, createLogger, errorFromLogRecord, getAnsiColorFormatter, getConsoleFormatter, getConsoleSink, getConsoleStderrSink, getMessageOnlyFormatter, getTextFormatter, loggable, withFilter, wrapError };
package/dist/index.mjs CHANGED
@@ -1,22 +1,38 @@
1
- import { n as main_default$1, t as main_default } from "./_chunks/libs/merge-error-cause.mjs";
1
+ import { n as wrapErrorMessage, t as mergeErrorCause } from "./_chunks/libs/merge-error-cause.mjs";
2
+ import "./_chunks/libs/is-error-instance.mjs";
3
+ import "./_chunks/libs/is-plain-obj.mjs";
2
4
  import { t as safeStringify } from "./_chunks/libs/safe-stringify.mjs";
3
5
  import { configureSync, getAnsiColorFormatter as getAnsiColorFormatter$1, getConsoleSink as getConsoleSink$1, getLogger, getTextFormatter as getTextFormatter$1, withFilter } from "@logtape/logtape";
4
-
5
- //#region src/utils.ts
6
+ /**
7
+ * Split stack string into lines and normalize (e.g. strip file://).
8
+ * @param stack - Error stack string
9
+ * @returns Array of normalized lines
10
+ */
6
11
  const parseStack = (stack) => {
7
12
  return stack.split("\n").map((l) => {
8
13
  return l.trim().replace("file://", "");
9
14
  });
10
15
  };
16
+ /**
17
+ * Indent each line of value by the given number of spaces.
18
+ * @param value - String or array of lines to indent
19
+ * @param indentation - Number of spaces (default 2)
20
+ * @returns Indented string
21
+ */
11
22
  function indent(value, indentation = 2) {
12
23
  value = Array.isArray(value) ? value : value.split("\n");
13
24
  const prefix = " ".repeat(indentation);
14
25
  return value.map((l) => `${prefix}${l}`).join("\n");
15
26
  }
27
+ /**
28
+ * Serialize unknown to a string (Error → message + stack; else safe-stringify).
29
+ * @param error - Caught value (Error, string, or arbitrary object)
30
+ * @returns Human-readable string for logging
31
+ */
16
32
  function loggable(error) {
17
33
  if (typeof error === "string") return error;
18
34
  if (error instanceof Error) {
19
- const mergedErr = main_default(error);
35
+ const mergedErr = mergeErrorCause(error);
20
36
  if (mergedErr.stack) {
21
37
  const stack = parseStack(mergedErr.stack);
22
38
  return mergedErr.message + "\n" + indent(stack.slice(1));
@@ -59,38 +75,46 @@ function loggable(error) {
59
75
  * ```
60
76
  */
61
77
  function wrapError(error, newMessage) {
62
- return main_default$1(error, newMessage);
78
+ return wrapErrorMessage(error, newMessage);
63
79
  }
64
-
65
- //#endregion
66
- //#region src/formatters.ts
67
- function gerErrorFromLogRecord(record) {
80
+ function getErrorFromLogRecord(record) {
68
81
  const errors = Object.entries(record.properties).flatMap(([k, err]) => {
69
82
  if (err instanceof Error) {
70
- const mergedErr = main_default(err);
83
+ const mergedErr = mergeErrorCause(err);
71
84
  if (mergedErr.stack) mergedErr.stack = parseStack(mergedErr.stack).join("\n");
72
85
  return [mergedErr];
73
86
  }
74
- if (k === "error" || k === "err") return [/* @__PURE__ */ new Error(`${err}`)];
87
+ if (k === "error" || k === "err") return [new Error(loggable(err))];
75
88
  return [];
76
89
  });
77
90
  if (errors.length === 0) return null;
78
91
  return errors.length === 1 ? errors[0] : new AggregateError(errors);
79
92
  }
93
+ /**
94
+ * Extract a single Error from a log record (from properties or rawMessage).
95
+ * @param record - Log record that may contain error in properties or rawMessage
96
+ * @returns Merged/wrapped Error or null if none found
97
+ */
80
98
  function errorFromLogRecord(record) {
81
- const error = gerErrorFromLogRecord(record);
82
- if (error && typeof record.rawMessage === "string") return main_default$1(error, record.rawMessage + "\n");
99
+ const error = getErrorFromLogRecord(record);
100
+ if (error && typeof record.rawMessage === "string") return wrapErrorMessage(error, record.rawMessage + "\n");
83
101
  return error;
84
102
  }
103
+ /**
104
+ * Append error from record properties to the formatted message (optionally colored).
105
+ * @param values - Formatted values (record + message)
106
+ * @param color - When true, wrap error text in ANSI red
107
+ * @returns Updated FormattedValues with error appended to message
108
+ */
85
109
  function appendErrorToMessage(values, color = false) {
86
- const error = gerErrorFromLogRecord(values.record);
110
+ const error = getErrorFromLogRecord(values.record);
87
111
  if (error) {
88
- let errorMessge = error.message;
89
- if (error.stack) errorMessge = errorMessge + "\n" + indent(error.stack.split("\n").slice(1));
90
- if (color) errorMessge = `${ansiColors.red}${errorMessge}${RESET}`;
112
+ let errorMessage = error.message;
113
+ if (error.stack) errorMessage = errorMessage + "\n" + indent(error.stack.split("\n").slice(1));
114
+ if (color) errorMessage = `${ansiColors.red}${errorMessage}${RESET}`;
91
115
  return {
92
116
  ...values,
93
- message: values.message + "\n" + indent(errorMessge)
117
+ message: values.message + "\n" + indent(errorMessage)
94
118
  };
95
119
  }
96
120
  return values;
@@ -103,12 +127,21 @@ const levelAbbreviations = {
103
127
  "error": "ERROR",
104
128
  "fatal": "FATAL"
105
129
  };
130
+ /**
131
+ * Formatter that outputs only the log message (no timestamp/level/category).
132
+ * @returns TextFormatter that returns just the message string
133
+ */
106
134
  function getMessageOnlyFormatter() {
107
135
  return getTextFormatter({ format: ({ message }) => {
108
136
  return message;
109
137
  } });
110
138
  }
111
139
  const level = (l) => levelAbbreviations[l];
140
+ /**
141
+ * Build a text formatter with optional custom format; appends error from record.
142
+ * @param options - Optional format and logtape options
143
+ * @returns TextFormatter
144
+ */
112
145
  function getTextFormatter(options) {
113
146
  const _format = options?.format ?? (({ timestamp, level, category, message }) => {
114
147
  return `${timestamp} ${level} ${category} ${message}`;
@@ -125,6 +158,11 @@ function getTextFormatter(options) {
125
158
  }
126
159
  const RESET = "\x1B[0m";
127
160
  const ansiColors = { red: "\x1B[31m" };
161
+ /**
162
+ * Build an ANSI-colored text formatter (level/category colors); appends error in red.
163
+ * @param options - Optional format and logtape ANSI options
164
+ * @returns TextFormatter with ANSI colors
165
+ */
128
166
  function getAnsiColorFormatter(options) {
129
167
  const _format = options?.format ?? (({ timestamp, level, category, message }) => {
130
168
  return `${timestamp} ${level} ${category} ${message}`;
@@ -145,6 +183,8 @@ function getAnsiColorFormatter(options) {
145
183
  * The formatter returns an array where:
146
184
  * - First element is the formatted message string
147
185
  * - Second element is the record properties object
186
+ * @param options - Optional messageFormatter (TextFormatter)
187
+ * @returns ConsoleFormatter for console.log/error
148
188
  */
149
189
  function getConsoleFormatter(options) {
150
190
  const formatter = options?.messageFormatter;
@@ -159,9 +199,11 @@ function getConsoleFormatter(options) {
159
199
  return message;
160
200
  };
161
201
  }
162
-
163
- //#endregion
164
- //#region src/sink.ts
202
+ /**
203
+ * Create a sink that writes formatted log records to stdout (default formatter).
204
+ * @param options - Optional console sink options (e.g. custom formatter)
205
+ * @returns Sink that writes to stdout
206
+ */
165
207
  function getConsoleSink(options) {
166
208
  return getConsoleSink$1({
167
209
  formatter: getConsoleFormatter(),
@@ -171,6 +213,8 @@ function getConsoleSink(options) {
171
213
  /**
172
214
  * Creates a console sink that writes to stderr.
173
215
  * (MCP protocol requires stderr to be used for logging)
216
+ * @param options - Optional console sink options (e.g. custom formatter)
217
+ * @returns Sink that writes to stderr
174
218
  */
175
219
  function getConsoleStderrSink(options) {
176
220
  const formatter = options?.formatter ?? getConsoleFormatter();
@@ -182,9 +226,6 @@ function getConsoleStderrSink(options) {
182
226
  } else console.error(...args);
183
227
  };
184
228
  }
185
-
186
- //#endregion
187
- //#region src/index.ts
188
229
  const logger = getLogger("likec4");
189
230
  /**
190
231
  * Get a child logger with the given subcategory.
@@ -195,16 +236,21 @@ const logger = getLogger("likec4");
195
236
  function createLogger(subcategory) {
196
237
  return logger.getChild(subcategory);
197
238
  }
239
+ /**
240
+ * Configure the global logger: sinks, loggers, and lowest level per category.
241
+ * @param config - Optional partial config (sinks, loggers). Merged with defaults.
242
+ */
198
243
  function configureLogger(config) {
199
244
  try {
200
- const sinks = config?.sinks ?? {};
245
+ const { sinks = {}, loggers: _loggers, ...restConfig } = config ?? {};
246
+ const sinksWithConsole = {
247
+ console: getConsoleSink(),
248
+ ...sinks
249
+ };
201
250
  configureSync({
202
251
  reset: true,
203
- ...config,
204
- sinks: {
205
- console: getConsoleSink(),
206
- ...sinks
207
- },
252
+ ...restConfig,
253
+ sinks: sinksWithConsole,
208
254
  loggers: [{
209
255
  category: ["logtape", "meta"],
210
256
  sinks: ["console"],
@@ -219,6 +265,4 @@ function configureLogger(config) {
219
265
  console.error(e);
220
266
  }
221
267
  }
222
-
223
- //#endregion
224
- export { configureLogger, logger as consola, logger, logger as rootLogger, createLogger, errorFromLogRecord, getAnsiColorFormatter, getConsoleFormatter, getConsoleSink, getConsoleStderrSink, getMessageOnlyFormatter, getTextFormatter, loggable, withFilter, wrapError };
268
+ export { configureLogger, logger as consola, logger, logger as rootLogger, createLogger, errorFromLogRecord, getAnsiColorFormatter, getConsoleFormatter, getConsoleSink, getConsoleStderrSink, getMessageOnlyFormatter, getTextFormatter, loggable, withFilter, wrapError };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@likec4/log",
3
3
  "description": "Shared interface for logging",
4
4
  "license": "MIT",
5
- "version": "1.48.0",
5
+ "version": "1.50.0",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
8
8
  "author": "Denis Davydkov <denis@davydkov.com>",
@@ -32,17 +32,16 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@logtape/logtape": "^1.3.5",
36
- "std-env": "^3.10.0"
35
+ "@logtape/logtape": "^1.3.7"
37
36
  },
38
37
  "devDependencies": {
39
- "@types/node": "~22.19.7",
38
+ "@types/node": "~22.19.11",
40
39
  "merge-error-cause": "^5.0.2",
41
- "safe-stringify": "^1.2.0",
40
+ "safe-stringify": "^1.3.0",
42
41
  "typescript": "5.9.3",
43
- "obuild": "^0.4.20",
42
+ "obuild": "^0.4.31",
44
43
  "wrap-error-message": "^3.0.1",
45
- "@likec4/tsconfig": "1.48.0",
44
+ "@likec4/tsconfig": "1.50.0",
46
45
  "@likec4/devops": "1.42.0"
47
46
  },
48
47
  "scripts": {
package/src/formatters.ts CHANGED
@@ -11,9 +11,9 @@ import {
11
11
  } from '@logtape/logtape'
12
12
  import mergeErrorCause from 'merge-error-cause'
13
13
  import wrapErrorMessage from 'wrap-error-message'
14
- import { indent, parseStack } from './utils'
14
+ import { indent, loggable, parseStack } from './utils'
15
15
 
16
- function gerErrorFromLogRecord(record: LogRecord): Error | null {
16
+ function getErrorFromLogRecord(record: LogRecord): Error | null {
17
17
  const errors = Object
18
18
  .entries(record.properties)
19
19
  .flatMap(([k, err]) => {
@@ -25,7 +25,7 @@ function gerErrorFromLogRecord(record: LogRecord): Error | null {
25
25
  return [mergedErr]
26
26
  }
27
27
  if (k === 'error' || k === 'err') {
28
- return [new Error(`${err}`)]
28
+ return [new Error(loggable(err))]
29
29
  }
30
30
  return []
31
31
  })
@@ -35,27 +35,38 @@ function gerErrorFromLogRecord(record: LogRecord): Error | null {
35
35
  return errors.length === 1 ? errors[0]! : new AggregateError(errors)
36
36
  }
37
37
 
38
+ /**
39
+ * Extract a single Error from a log record (from properties or rawMessage).
40
+ * @param record - Log record that may contain error in properties or rawMessage
41
+ * @returns Merged/wrapped Error or null if none found
42
+ */
38
43
  export function errorFromLogRecord(record: LogRecord): Error | null {
39
- const error = gerErrorFromLogRecord(record)
44
+ const error = getErrorFromLogRecord(record)
40
45
  if (error && typeof record.rawMessage === 'string') {
41
46
  return wrapErrorMessage(error, record.rawMessage + '\n')
42
47
  }
43
48
  return error
44
49
  }
45
50
 
51
+ /**
52
+ * Append error from record properties to the formatted message (optionally colored).
53
+ * @param values - Formatted values (record + message)
54
+ * @param color - When true, wrap error text in ANSI red
55
+ * @returns Updated FormattedValues with error appended to message
56
+ */
46
57
  export function appendErrorToMessage(values: FormattedValues, color = false): FormattedValues {
47
- const error = gerErrorFromLogRecord(values.record)
58
+ const error = getErrorFromLogRecord(values.record)
48
59
  if (error) {
49
- let errorMessge = error.message
60
+ let errorMessage = error.message
50
61
  if (error.stack) {
51
- errorMessge = errorMessge + '\n' + indent(error.stack.split('\n').slice(1))
62
+ errorMessage = errorMessage + '\n' + indent(error.stack.split('\n').slice(1))
52
63
  }
53
64
  if (color) {
54
- errorMessge = `${ansiColors.red}${errorMessge}${RESET}`
65
+ errorMessage = `${ansiColors.red}${errorMessage}${RESET}`
55
66
  }
56
67
  return {
57
68
  ...values,
58
- message: values.message + '\n' + indent(errorMessge),
69
+ message: values.message + '\n' + indent(errorMessage),
59
70
  }
60
71
  }
61
72
  return values
@@ -70,6 +81,10 @@ const levelAbbreviations: Record<LogLevel, string> = {
70
81
  'fatal': 'FATAL',
71
82
  }
72
83
 
84
+ /**
85
+ * Formatter that outputs only the log message (no timestamp/level/category).
86
+ * @returns TextFormatter that returns just the message string
87
+ */
73
88
  export function getMessageOnlyFormatter(): TextFormatter {
74
89
  return getTextFormatter({
75
90
  format: ({ message }): string => {
@@ -80,11 +95,15 @@ export function getMessageOnlyFormatter(): TextFormatter {
80
95
 
81
96
  const level = (l: LogLevel): string => levelAbbreviations[l]
82
97
 
98
+ /**
99
+ * Build a text formatter with optional custom format; appends error from record.
100
+ * @param options - Optional format and logtape options
101
+ * @returns TextFormatter
102
+ */
83
103
  export function getTextFormatter(options?: TextFormatterOptions): TextFormatter {
84
104
  const _format = options?.format ?? (({ timestamp, level, category, message }: FormattedValues): string => {
85
105
  return `${timestamp} ${level} ${category} ${message}`
86
106
  })
87
- // const format = options?.format
88
107
  return getLogtapeTextFormatter({
89
108
  timestamp: 'time',
90
109
  level,
@@ -109,6 +128,11 @@ const ansiColors = {
109
128
  // white: "\x1b[37m",
110
129
  } as const
111
130
 
131
+ /**
132
+ * Build an ANSI-colored text formatter (level/category colors); appends error in red.
133
+ * @param options - Optional format and logtape ANSI options
134
+ * @returns TextFormatter with ANSI colors
135
+ */
112
136
  export function getAnsiColorFormatter(options?: AnsiColorFormatterOptions): TextFormatter {
113
137
  const _format = options?.format ?? (({ timestamp, level, category, message }: FormattedValues): string => {
114
138
  return `${timestamp} ${level} ${category} ${message}`
@@ -130,6 +154,8 @@ export function getAnsiColorFormatter(options?: AnsiColorFormatterOptions): Text
130
154
  * The formatter returns an array where:
131
155
  * - First element is the formatted message string
132
156
  * - Second element is the record properties object
157
+ * @param options - Optional messageFormatter (TextFormatter)
158
+ * @returns ConsoleFormatter for console.log/error
133
159
  */
134
160
  export function getConsoleFormatter(options?: {
135
161
  messageFormatter?: TextFormatter
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  type Config,
3
+ type Sink,
3
4
  configureSync as configureLogtape,
4
5
  getLogger,
5
6
  } from '@logtape/logtape'
@@ -53,18 +54,23 @@ export function createLogger(subcategory: string | readonly [string] | readonly
53
54
  return logger.getChild(subcategory)
54
55
  }
55
56
 
57
+ /**
58
+ * Configure the global logger: sinks, loggers, and lowest level per category.
59
+ * @param config - Optional partial config (sinks, loggers). Merged with defaults.
60
+ */
56
61
  export function configureLogger<TSinkId extends string, TFilterId extends string>(
57
62
  config?: Partial<Config<TSinkId, TFilterId>>,
58
63
  ) {
59
64
  try {
60
- const sinks = config?.sinks ?? {}
61
- configureLogtape<any, any>({
65
+ const { sinks = {}, loggers: _loggers, ...restConfig } = config ?? {}
66
+ const sinksWithConsole: Record<TSinkId | 'console', Sink> = {
67
+ console: getConsoleSink(),
68
+ ...sinks,
69
+ } as Record<TSinkId | 'console', Sink>
70
+ configureLogtape<TSinkId | 'console', TFilterId>({
62
71
  reset: true,
63
- ...config,
64
- sinks: {
65
- console: getConsoleSink(),
66
- ...sinks,
67
- },
72
+ ...restConfig,
73
+ sinks: sinksWithConsole,
68
74
  loggers: [
69
75
  { category: ['logtape', 'meta'], sinks: ['console'], lowestLevel: 'warning' },
70
76
  ...(config?.loggers ?? [
package/src/sink.ts CHANGED
@@ -6,6 +6,11 @@ import {
6
6
  } from '@logtape/logtape'
7
7
  import { getConsoleFormatter } from './formatters'
8
8
 
9
+ /**
10
+ * Create a sink that writes formatted log records to stdout (default formatter).
11
+ * @param options - Optional console sink options (e.g. custom formatter)
12
+ * @returns Sink that writes to stdout
13
+ */
9
14
  export function getConsoleSink(options?: ConsoleSinkOptions): Sink {
10
15
  return getLogtapeConsoleSink({
11
16
  formatter: getConsoleFormatter(),
@@ -16,6 +21,8 @@ export function getConsoleSink(options?: ConsoleSinkOptions): Sink {
16
21
  /**
17
22
  * Creates a console sink that writes to stderr.
18
23
  * (MCP protocol requires stderr to be used for logging)
24
+ * @param options - Optional console sink options (e.g. custom formatter)
25
+ * @returns Sink that writes to stderr
19
26
  */
20
27
  export function getConsoleStderrSink(options?: ConsoleSinkOptions): Sink {
21
28
  const formatter = options?.formatter ?? getConsoleFormatter()
package/src/utils.ts CHANGED
@@ -2,6 +2,11 @@ import mergeErrorCause from 'merge-error-cause'
2
2
  import safeStringify from 'safe-stringify'
3
3
  import wrapErrorMessage from 'wrap-error-message'
4
4
 
5
+ /**
6
+ * Split stack string into lines and normalize (e.g. strip file://).
7
+ * @param stack - Error stack string
8
+ * @returns Array of normalized lines
9
+ */
5
10
  export const parseStack = (stack: string): string[] => {
6
11
  const lines = stack
7
12
  .split('\n')
@@ -17,12 +22,23 @@ export const parseStack = (stack: string): string[] => {
17
22
  return lines
18
23
  }
19
24
 
25
+ /**
26
+ * Indent each line of value by the given number of spaces.
27
+ * @param value - String or array of lines to indent
28
+ * @param indentation - Number of spaces (default 2)
29
+ * @returns Indented string
30
+ */
20
31
  export function indent(value: string | string[], indentation = 2): string {
21
32
  value = Array.isArray(value) ? value : value.split('\n')
22
33
  const prefix = ' '.repeat(indentation)
23
34
  return value.map((l) => `${prefix}${l}`).join('\n')
24
35
  }
25
36
 
37
+ /**
38
+ * Serialize unknown to a string (Error → message + stack; else safe-stringify).
39
+ * @param error - Caught value (Error, string, or arbitrary object)
40
+ * @returns Human-readable string for logging
41
+ */
26
42
  export function loggable(error: unknown): string {
27
43
  if (typeof error === 'string') {
28
44
  return error