@darksheep/logger 1.3.0 → 1.4.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 (53) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +36 -16
  3. package/package.json +7 -5
  4. package/src/create-logger.js +5 -5
  5. package/src/formatters/formatter-console/stack.js +1 -1
  6. package/src/formatters/formatter-console.js +2 -2
  7. package/src/index.js +17 -7
  8. package/src/logger.js +43 -38
  9. package/src/replacer.js +25 -21
  10. package/src/replacers/buffers.js +5 -1
  11. package/src/replacers/error.js +5 -2
  12. package/src/replacers/http-client-request.js +5 -1
  13. package/src/replacers/http-incoming-message.js +7 -2
  14. package/src/replacers/http-server-response.js +5 -1
  15. package/src/replacers/index.js +1 -1
  16. package/src/replacers/long-strings.js +5 -1
  17. package/src/replacers/net-socket.js +5 -1
  18. package/src/replacers/secrets.js +106 -13
  19. package/src/utilities/environment.js +25 -3
  20. package/src/utilities/legacy-secrets.js +36 -0
  21. package/src/utilities/log-types.js +12 -4
  22. package/src/utilities/parse-filters.js +3 -3
  23. package/src/utilities/parse-log-level.js +5 -1
  24. package/src/utilities/resource-usage.js +9 -6
  25. package/types/create-logger.d.ts +3 -2
  26. package/types/formatter.d.ts +2 -2
  27. package/types/formatters/formatter-console/stack.d.ts +15 -11
  28. package/types/formatters/formatter-console.d.ts +2 -2
  29. package/types/formatters/formatter-json.d.ts +1 -1
  30. package/types/index.d.ts +26 -11
  31. package/types/logger.d.ts +150 -61
  32. package/types/replacer.d.ts +16 -16
  33. package/types/replacers/buffers.d.ts +6 -2
  34. package/types/replacers/error.d.ts +13 -12
  35. package/types/replacers/http-client-request.d.ts +6 -2
  36. package/types/replacers/http-incoming-message.d.ts +11 -5
  37. package/types/replacers/http-server-response.d.ts +6 -2
  38. package/types/replacers/index.d.ts +8 -8
  39. package/types/replacers/long-strings.d.ts +6 -2
  40. package/types/replacers/net-socket.d.ts +6 -2
  41. package/types/replacers/secrets.d.ts +8 -4
  42. package/types/stdout-write.d.ts +1 -1
  43. package/types/utilities/colour.d.ts +30 -30
  44. package/types/utilities/environment.d.ts +14 -22
  45. package/types/utilities/json-path.d.ts +1 -1
  46. package/types/utilities/last-callsite.d.ts +1 -1
  47. package/types/utilities/legacy-secrets.d.ts +33 -0
  48. package/types/utilities/log-filters.d.ts +2 -2
  49. package/types/utilities/log-types.d.ts +30 -4
  50. package/types/utilities/parse-filters.d.ts +1 -1
  51. package/types/utilities/parse-log-level.d.ts +6 -2
  52. package/types/utilities/resource-usage.d.ts +2 -2
  53. package/types/utilities/stacktrace.d.ts +15 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.4.0](https://github.com/DarkSheepSoftware/node-packages/compare/logger-v1.3.1...logger-v1.4.0) (2026-09-20)
4
+
5
+
6
+ ### 🌟 Features
7
+
8
+ * split logger secrets into redact and remove ([#845](https://github.com/DarkSheepSoftware/node-packages/issues/845)) ([924c6d5](https://github.com/DarkSheepSoftware/node-packages/commit/924c6d589e105c22048d3f05fd7151f03a2513dd))
9
+ * **traverse:** add @darksheep/traverse deep object traversal package ([#874](https://github.com/DarkSheepSoftware/node-packages/issues/874)) ([981bea0](https://github.com/DarkSheepSoftware/node-packages/commit/981bea0a3fa08c78152713108feb02dc0ccbdc37))
10
+
11
+
12
+ ### 📦 Dependencies
13
+
14
+ * **pkg:** update dependency deepmerge-ts to v7.1.6 ([#938](https://github.com/DarkSheepSoftware/node-packages/issues/938)) ([194912b](https://github.com/DarkSheepSoftware/node-packages/commit/194912bd6af5f4a83c101080c4d5ea76047511c5))
15
+ * **pkg:** update dependency deepmerge-ts to v8 [security] ([ca3b39a](https://github.com/DarkSheepSoftware/node-packages/commit/ca3b39a53603b522d6f89a3230fa2836e02d532c))
16
+ * **pkg:** update dependency deepmerge-ts to v8.0.1 ([#949](https://github.com/DarkSheepSoftware/node-packages/issues/949)) ([0099631](https://github.com/DarkSheepSoftware/node-packages/commit/0099631ca6a8a6f437f75d83d63bb45c8383cead))
17
+ * **pkg:** update dependency deepmerge-ts to v8.0.2 ([#957](https://github.com/DarkSheepSoftware/node-packages/issues/957)) ([4c78b29](https://github.com/DarkSheepSoftware/node-packages/commit/4c78b296fee9d8d73abec141eb2151e6e4903fcf))
18
+
19
+ ## [1.3.1](https://github.com/DarkSheepSoftware/node-packages/compare/logger-v1.3.0...logger-v1.3.1) (2026-04-17)
20
+
21
+
22
+ ### 📚 Documentation
23
+
24
+ * Update the READMEs ([#824](https://github.com/DarkSheepSoftware/node-packages/issues/824)) ([9d282b7](https://github.com/DarkSheepSoftware/node-packages/commit/9d282b724fe056ec275578088bf495985e22c25f))
25
+
3
26
  ## [1.3.0](https://github.com/DarkSheepSoftware/node-packages/compare/logger-v1.2.0...logger-v1.3.0) (2025-10-09)
4
27
 
5
28
 
package/README.md CHANGED
@@ -1,9 +1,7 @@
1
1
  # @darksheep/logger
2
2
  Log configuration for NodeJS repos
3
3
 
4
- This repo contains environment aware logging configurations for our NodeJS modules that use Winston.
5
-
6
- This can be added using `yarn add @darksheep/logger` how ever you require a valid npm token for github packages!
4
+ This can be added using `yarn add @darksheep/logger`
7
5
 
8
6
  ### Quick start
9
7
  #### Get something logging:
@@ -58,7 +56,8 @@ app.get('/', (request, response) => {
58
56
  | `NODE_ENV` | The deployment location |
59
57
  | `LOG_LEVEL` | Overrides the log level set by the detected environment |
60
58
  | `LOG_FILTERS` | This allows you to allow/block specific channels |
61
- | `LOG_SECRETS` | This allows you to hide or remove secrets in an object |
59
+ | `LOG_SECRET_REDACT` | This allows you to obscure secrets in an object |
60
+ | `LOG_SECRET_REMOVE` | This allows you to remove secrets from an object |
62
61
  | `LOG_CALLSITES` | Include the callsite of the log |
63
62
 
64
63
  #### `NODE_ENV`
@@ -110,18 +109,17 @@ The following filter means that ONLY `router` gets logged, except for the `route
110
109
  LOG_FILTERS="router,-router.ok"
111
110
  ```
112
111
 
113
- #### `LOG_SECRETS`
112
+ #### `LOG_SECRET_REDACT`
114
113
 
115
- Secrets also use a filter, if you use a standard filter the secret key is displayed, if you use a negate the key and value are deleted.
114
+ Comma-separated list of key patterns. Matched keys have their values replaced with `[secret ...]`. Prefix a pattern with `-` to exempt it from redacting.
116
115
 
117
- The following means that `password` is deleted, and `token` is obscured.
116
+ Wild cards are permitted.
118
117
 
119
118
  ```js
120
- // LOG_SECRETS="-password,token"
119
+ // LOG_SECRET_REDACT="token"
121
120
 
122
121
  // Given the following context
123
122
  const context = {
124
- password: '1234',
125
123
  token: 'asdf',
126
124
  };
127
125
 
@@ -131,12 +129,8 @@ const output = {
131
129
  };
132
130
  ```
133
131
 
134
- Wild cards are also permitted.
135
-
136
- For example, using a positive (obscure) wildcard
137
-
138
132
  ```js
139
- // LOG_SECRETS="*.token"
133
+ // LOG_SECRET_REDACT="*.token"
140
134
 
141
135
  // Given the following context
142
136
  const context = {
@@ -163,9 +157,35 @@ const output = {
163
157
  };
164
158
  ```
165
159
 
166
- For example, using a negative (delete) wildcard:
160
+ #### `LOG_SECRET_REMOVE`
161
+
162
+ Comma-separated list of key patterns. Matched keys and their values are deleted entirely. Prefix a pattern with `-` to exempt a specific path from removal.
163
+
164
+ Wild cards are permitted.
165
+
166
+ ```js
167
+ // LOG_SECRET_REMOVE="response,-response.statusMessage"
168
+
169
+ // Given the following context
170
+ const context = {
171
+ status: 200,
172
+ response: {
173
+ statusMessage: 'OK',
174
+ body: '...',
175
+ },
176
+ };
177
+
178
+ // Then the following will be logged
179
+ const output = {
180
+ status: 200,
181
+ response: {
182
+ statusMessage: 'OK',
183
+ },
184
+ };
185
+ ```
186
+
167
187
  ```js
168
- // LOG_SECRETS="-*.token"
188
+ // LOG_SECRET_REMOVE="*.token"
169
189
 
170
190
  // Given the following context
171
191
  const context = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darksheep/logger",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Logging your stuff to where ever you want it",
5
5
  "license": "UNLICENCED",
6
6
  "type": "module",
@@ -22,15 +22,17 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@darksheep/environment": "3.2.0",
25
- "deepmerge-ts": "7.1.5",
26
- "stacktrace-parser": "0.1.11",
27
- "traverse": "0.6.11"
25
+ "@darksheep/traverse": "1.0.0",
26
+ "deepmerge-ts": "8.0.2",
27
+ "stacktrace-parser": "0.1.11"
28
28
  },
29
29
  "devDependencies": {
30
- "@types/traverse": "~0.6.33",
31
30
  "nock": "~14.0.0"
32
31
  },
33
32
  "engines": {
34
33
  "node": "^20.13.1 || >=22.2.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
35
37
  }
36
38
  }
@@ -7,21 +7,21 @@ import {
7
7
  HttpServerResponseReplacer,
8
8
  LongStringReplacer,
9
9
  NetSocketReplacer,
10
- SecretDelete,
11
- SecretObscure,
10
+ SecretRedact,
11
+ SecretRemove,
12
12
  } from './replacers/index.js';
13
13
 
14
14
  /**
15
15
  * @param {string} [channel] - The logging channel.
16
- * @returns {import('./logger.js').Logger}
16
+ * @returns {Logger}
17
17
  */
18
18
  export function createLogger(channel) {
19
19
  return new Logger(
20
20
  typeof channel === 'string' ? { channel } : {},
21
21
  { replacers: [
22
22
  // Always run the secret replacer first.
23
- SecretDelete,
24
- SecretObscure,
23
+ SecretRemove,
24
+ SecretRedact,
25
25
 
26
26
  ErrorReplacer,
27
27
  HttpClientRequestReplacer,
@@ -85,7 +85,7 @@ function highlightNumber(number, options, colon = ':') {
85
85
  return '';
86
86
  }
87
87
 
88
- return `${colon}${colourString(`${number}`, options)}`;
88
+ return `${colon}${colourString(String(number), options)}`;
89
89
  }
90
90
 
91
91
  /**
@@ -28,7 +28,7 @@ function flattenChannelLevel(channel, level) {
28
28
  }
29
29
 
30
30
  if (level != null && LogNames[level] != null) {
31
- output += `${LogNames[level].toUpperCase()}`;
31
+ output += LogNames[level].toUpperCase();
32
32
  }
33
33
 
34
34
  output += ': ';
@@ -77,7 +77,7 @@ function formatError(error, indent = 0) {
77
77
  error.message,
78
78
  { foreground: 'red', effects: [ 'bold' ] },
79
79
  )
80
- : `${error.message}`;
80
+ : error.message;
81
81
 
82
82
  const stack = formatStack(error.stack, indent);
83
83
  if (stack.trim().length > 0) {
package/src/index.js CHANGED
@@ -1,10 +1,20 @@
1
1
  import { createLogger } from './create-logger.js';
2
2
 
3
- /** @typedef {import('./utilities/log-types.js').LogContext} LogContext */
4
- /** @typedef {import('./utilities/log-types.js').LogEntry} LogEntry */
5
- /** @typedef {import('./utilities/log-types.js').LogLevel} LogLevel */
6
- /** @typedef {import('./formatter.js').Formatter} Formatter */
7
- /** @typedef {import('./replacer.js').Replacer} Replacer */
3
+ /**
4
+ * @typedef {import('./utilities/log-types.js').LogContext} LogContext
5
+ */
6
+ /**
7
+ * @typedef {import('./utilities/log-types.js').LogEntry} LogEntry
8
+ */
9
+ /**
10
+ * @typedef {import('./utilities/log-types.js').LogLevel} LogLevel
11
+ */
12
+ /**
13
+ * @typedef {import('./formatter.js').Formatter} Formatter
14
+ */
15
+ /**
16
+ * @typedef {import('./replacer.js').Replacer} Replacer
17
+ */
8
18
 
9
19
  export { createLogger } from './create-logger.js';
10
20
  export const logger = createLogger();
@@ -18,8 +28,8 @@ export {
18
28
  HttpServerResponseReplacer,
19
29
  LongStringReplacer,
20
30
  NetSocketReplacer,
21
- SecretDelete,
22
- SecretObscure,
31
+ SecretRedact,
32
+ SecretRemove,
23
33
  } from './replacers/index.js';
24
34
  export { environment } from './utilities/environment.js';
25
35
  export { LogLevels } from './utilities/log-types.js';
package/src/logger.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @import { LogLevel, LogContext, LogEntry} from './utilities/log-types.js'
3
+ * @import { Replacer } from './replacer.js';
4
+ */
5
+
1
6
  import { AsyncLocalStorage } from 'node:async_hooks';
2
7
 
3
8
  import { deepmerge } from 'deepmerge-ts';
@@ -15,16 +20,16 @@ import { LogLevels } from './utilities/log-types.js';
15
20
  /**
16
21
  * @typedef {Object} Options
17
22
  * @property {typeof replace} [replace] - The replacer function to use.
18
- * @property {import('./replacer.js').Replacer<any, any>[]} [replacers] - The replacers to use in the replacer.
23
+ * @property {Replacer[]} [replacers] - The replacers to use in the replacer.
19
24
  * @property {typeof formatter} [format] - The formatter function to use (eg console or json formatter).
20
25
  * @property {typeof stdoutWrite} [write] - The place to write the log to.
21
26
  */
22
27
 
23
28
  export class Logger {
24
- /** @type {AsyncLocalStorage<import('./utilities/log-types.js').LogContext[]>} */
29
+ /** @type {AsyncLocalStorage<LogContext[]>} */
25
30
  static storage = new AsyncLocalStorage();
26
31
 
27
- /** @type {import('./utilities/log-types.js').LogContext} */
32
+ /** @type {LogContext} */
28
33
  #context;
29
34
 
30
35
  /** @type {typeof formatter} */
@@ -36,10 +41,10 @@ export class Logger {
36
41
  /** @type {typeof stdoutWrite} */
37
42
  #write = stdoutWrite;
38
43
 
39
- /** @type {import('./replacer.js').Replacer[]} */
44
+ /** @type {Replacer[]} */
40
45
  replacers = [];
41
46
  /**
42
- * @param {import('./utilities/log-types.js').LogContext} [context] - Context to add to the logger.
47
+ * @param {LogContext} [context] - Context to add to the logger.
43
48
  * @param {Options} [options] - Options for the loggers output.
44
49
  */
45
50
  constructor(context, options) {
@@ -59,7 +64,7 @@ export class Logger {
59
64
  }
60
65
 
61
66
  /**
62
- * @param {import('./utilities/log-types.js').LogContext} context - Context to bind ot the async context.
67
+ * @param {LogContext} context - Context to bind ot the async context.
63
68
  * @returns {void}
64
69
  */
65
70
  static addAsyncContext(context) {
@@ -81,7 +86,7 @@ export class Logger {
81
86
  /**
82
87
  * @template [R=unknown]
83
88
  * @overload
84
- * @param {import('./utilities/log-types.js').LogContext} context - Context to bind ot the async context.
89
+ * @param {LogContext} context - Context to bind ot the async context.
85
90
  * @param {() => R} callback - The function to wrap the context in.
86
91
  * @returns {R}
87
92
  */
@@ -103,14 +108,14 @@ export class Logger {
103
108
  }
104
109
 
105
110
  return Logger.storage.run(
106
- [ ...store, /** @type {import('./utilities/log-types.js').LogContext} */ (context) ],
111
+ [ ...store, /** @type {LogContext} */ (context) ],
107
112
  /** @type {() => R} */ (callback),
108
113
  );
109
114
  }
110
115
 
111
116
  /**
112
- * @param {import('./utilities/log-types.js').LogContext} context - The new context.
113
- * @param {import('./utilities/log-types.js').LogLevel} [level] - The log level at which we allow this context.
117
+ * @param {LogContext} context - The new context.
118
+ * @param {LogLevel} [level] - The log level at which we allow this context.
114
119
  * @returns {Logger}
115
120
  */
116
121
  #overrideContext(context, level) {
@@ -150,27 +155,27 @@ export class Logger {
150
155
  /**
151
156
  * Creating a new logger with {context, ...this.context}.
152
157
  * @overload
153
- * @param {import('./utilities/log-types.js').LogContext} context - The new context.
158
+ * @param {LogContext} context - The new context.
154
159
  * @returns {Logger}
155
160
  */
156
161
  /**
157
162
  * Creating a new logger with {context, ...this.context}.
158
163
  * @overload
159
- * @param {import('./utilities/log-types.js').LogContext} context - The new context.
160
- * @param {import('./utilities/log-types.js').LogLevel} level - The log level at which we allow this context.
164
+ * @param {LogContext} context - The new context.
165
+ * @param {LogLevel} level - The log level at which we allow this context.
161
166
  * @returns {Logger}
162
167
  */
163
168
  /**
164
169
  * Creating a new logger with {context, ...this.context}.
165
170
  * @overload
166
- * @param {import('./utilities/log-types.js').LogLevel} level - The log level at which we allow this context.
167
- * @param {import('./utilities/log-types.js').LogContext} context - The new context.
171
+ * @param {LogLevel} level - The log level at which we allow this context.
172
+ * @param {LogContext} context - The new context.
168
173
  * @returns {Logger}
169
174
  */
170
175
  /**
171
176
  * Creating a new logger with {context, ...this.context}.
172
- * @param {import('./utilities/log-types.js').LogContext | import('./utilities/log-types.js').LogLevel} contextOrLevel - The log level at which we allow this context.
173
- * @param {import('./utilities/log-types.js').LogLevel | import('./utilities/log-types.js').LogContext} [levelOrContext] - The new context.
177
+ * @param {LogContext | LogLevel} contextOrLevel - The log level at which we allow this context.
178
+ * @param {LogLevel | LogContext} [levelOrContext] - The new context.
174
179
  * @returns {Logger}
175
180
  */
176
181
  context(contextOrLevel, levelOrContext) {
@@ -207,31 +212,31 @@ export class Logger {
207
212
  * Write a log with the level 'critical' - A crucial part of the application is not working.
208
213
  *
209
214
  * @param {Error | string} message - The message to log.
210
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
215
+ * @param {LogContext} [context] - Additional context.
211
216
  * @returns {void}
212
217
  */
213
218
  critical(message, context) {
214
- return this.write(LogLevels.critical, message, context);
219
+ this.write(LogLevels.critical, message, context);
215
220
  }
216
221
 
217
222
  /**
218
223
  * Write a log with the level 'debug' - Information that is unlikely to help in production.
219
224
  * @param {Error | string} message - The message to log.
220
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
225
+ * @param {LogContext} [context] - Additional context.
221
226
  * @returns {void}
222
227
  */
223
228
  debug(message, context) {
224
- return this.write(LogLevels.debug, message, context);
229
+ this.write(LogLevels.debug, message, context);
225
230
  }
226
231
 
227
232
  /**
228
233
  * Write a log with the level 'error' - A non critical operation fails.
229
234
  * @param {Error | string} message - The message to log.
230
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
235
+ * @param {LogContext} [context] - Additional context.
231
236
  * @returns {void}
232
237
  */
233
238
  error(message, context) {
234
- return this.write(LogLevels.error, message, context);
239
+ this.write(LogLevels.error, message, context);
235
240
  }
236
241
 
237
242
  /**
@@ -246,21 +251,21 @@ export class Logger {
246
251
  /**
247
252
  * Write a log with the level 'info' - Information about successful operations.
248
253
  * @param {Error | string} message - The message to log.
249
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
254
+ * @param {LogContext} [context] - Additional context.
250
255
  * @returns {void}
251
256
  */
252
257
  info(message, context) {
253
- return this.write(LogLevels.info, message, context);
258
+ this.write(LogLevels.info, message, context);
254
259
  }
255
260
 
256
261
  /**
257
262
  * Write a log with the level 'notice' - Information about events that may be unusual.
258
263
  * @param {Error | string} message - The message to log.
259
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
264
+ * @param {LogContext} [context] - Additional context.
260
265
  * @returns {void}
261
266
  */
262
267
  notice(message, context) {
263
- return this.write(LogLevels.notice, message, context);
268
+ this.write(LogLevels.notice, message, context);
264
269
  }
265
270
 
266
271
  /*
@@ -282,11 +287,11 @@ export class Logger {
282
287
  /**
283
288
  * Write a log with the level 'silly' - Information to help resolve complex logic issues.
284
289
  * @param {Error | string} message - The message to log.
285
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
290
+ * @param {LogContext} [context] - Additional context.
286
291
  * @returns {void}
287
292
  */
288
293
  silly(message, context) {
289
- return this.write(LogLevels.silly, message, context);
294
+ this.write(LogLevels.silly, message, context);
290
295
  }
291
296
 
292
297
  /**
@@ -306,11 +311,11 @@ export class Logger {
306
311
  /**
307
312
  * Write a log with the level 'warning' - An operation might fail in the future.
308
313
  * @param {Error | string} message - The message to log.
309
- * @param {import('./utilities/log-types.js').LogContext} [context] - Additional context.
314
+ * @param {LogContext} [context] - Additional context.
310
315
  * @returns {void}
311
316
  */
312
317
  warning(message, context) {
313
- return this.write(LogLevels.warning, message, context);
318
+ this.write(LogLevels.warning, message, context);
314
319
  }
315
320
 
316
321
  /**
@@ -324,13 +329,13 @@ export class Logger {
324
329
 
325
330
  /**
326
331
  * Write a new log entry.
327
- * @param {import('./utilities/log-types.js').LogLevel} level - The log level of the message to log.
332
+ * @param {LogLevel} level - The log level of the message to log.
328
333
  * @param {Error | string} message - The message to log.
329
- * @param {import('./utilities/log-types.js').LogContext} [context] - Context to add to the log (merged with this.context, and Logger.contexts).
334
+ * @param {LogContext} [context] - Context to add to the log (merged with this.context, and Logger.contexts).
330
335
  * @returns {void}
331
336
  */
332
337
  write(level, message, context) {
333
- /** @type {import('./utilities/log-types.js').LogContext[]} */
338
+ /** @type {LogContext[]} */
334
339
  const contexts = [];
335
340
 
336
341
  const asyncContexts = Logger.storage.getStore();
@@ -344,7 +349,7 @@ export class Logger {
344
349
  }
345
350
 
346
351
  const fullContext =
347
- /** @type {import('./utilities/log-types.js').LogContext} */
352
+ /** @type {LogContext} */
348
353
  (deepmerge(...contexts));
349
354
 
350
355
  if (
@@ -354,7 +359,7 @@ export class Logger {
354
359
  return;
355
360
  }
356
361
 
357
- /** @type {import('./utilities/log-types.js').LogEntry} */
362
+ /** @type {LogEntry} */
358
363
  const entry = (
359
364
  typeof message === 'string'
360
365
  ? { ...fullContext, message, level }
@@ -374,11 +379,11 @@ export class Logger {
374
379
  }
375
380
 
376
381
  const normalised =
377
- /** @type {import('./utilities/log-types.js').LogEntry} */
382
+ /** @type {LogEntry} */
378
383
  (this.#replace(entry, this.replacers));
379
384
 
380
385
  const formatted = this.#format(normalised);
381
386
 
382
- return this.#write(formatted);
387
+ this.#write(formatted);
383
388
  }
384
389
  }
package/src/replacer.js CHANGED
@@ -1,9 +1,9 @@
1
- import Traverse from 'traverse';
1
+ import { createTraverse } from '@darksheep/traverse';
2
2
 
3
3
  import { nodesToPath } from './utilities/json-path.js';
4
4
 
5
5
  /**
6
- * @template [T=unknown]
6
+ * @template [T=any]
7
7
  * @template [O=unknown]
8
8
  * @typedef {Object} Replacer
9
9
  * @property {string} name - The name of the replacer.
@@ -18,31 +18,31 @@ import { nodesToPath } from './utilities/json-path.js';
18
18
  * @returns {unknown}
19
19
  */
20
20
  export function replace(object, replacers = []) {
21
- // eslint-disable-next-line unicorn/no-array-for-each -- This is not an array
22
- return Traverse(object).forEach(
23
- /**
24
- * @param {unknown} value - Current property in the traversed object.
25
- * @returns {void}
26
- * @this {import('traverse').TraverseContext}
27
- */
28
- function (value) {
21
+ const walk = createTraverse(
22
+ (context) => {
23
+ const value = context.node;
24
+
29
25
  if (value == null) {
30
- return this.remove();
26
+ context.remove();
27
+ return;
31
28
  }
32
29
 
33
- if (this.circular != null) {
34
- return this.update({ $ref: nodesToPath(this.circular.path) });
30
+ if (context.circular != null) {
31
+ context.update({ $ref: nodesToPath(context.circular.path) });
32
+ return;
35
33
  }
36
34
 
37
35
  for (const replacer of replacers) {
38
- if (replacer.shouldReplace(value, this.path)) {
39
- const replaced = replacer.replace(value, this.path);
36
+ if (replacer.shouldReplace(value, context.path)) {
37
+ const replaced = replacer.replace(value, context.path);
40
38
 
41
39
  if (replaced == null) {
42
- return this.remove(replacer.stopHere);
40
+ context.remove();
41
+ return;
43
42
  }
44
43
 
45
- return this.update(replaced, replacer.stopHere);
44
+ context.update(replaced, replacer.stopHere);
45
+ return;
46
46
  }
47
47
  }
48
48
 
@@ -52,7 +52,8 @@ export function replace(object, replacers = []) {
52
52
  typeof value.toJSON === 'function'
53
53
  ) {
54
54
  try {
55
- return this.update(value.toJSON());
55
+ context.update(value.toJSON());
56
+ return;
56
57
  } catch { }
57
58
  }
58
59
 
@@ -61,19 +62,22 @@ export function replace(object, replacers = []) {
61
62
  Object.getPrototypeOf(value) !== Object.getPrototypeOf({}) &&
62
63
  Object.getPrototypeOf(value) !== Object.getPrototypeOf([])
63
64
  ) {
64
- return this.update({ $class: value.constructor.name });
65
+ context.update({ $class: value.constructor.name });
66
+ return;
65
67
  }
66
68
 
67
69
  if (Object.getPrototypeOf(value)?.constructor === Object) {
68
- this.update({ ...value });
70
+ context.update({ ...value });
69
71
  }
70
72
 
71
73
  if (
72
74
  Array.isArray(value) &&
73
75
  Object.getPrototypeOf(value).constructor === Array
74
76
  ) {
75
- this.update([ ...value ]);
77
+ context.update([ ...value ]);
76
78
  }
77
79
  },
78
80
  );
81
+
82
+ return walk(object);
79
83
  }
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @import { Replacer } from '../replacer.js';
3
+ */
4
+
1
5
  /**
2
6
  * @param {Buffer} buffer - The buffer to convert to a string.
3
7
  * @returns {string}
@@ -6,7 +10,7 @@ function stringBuffer(buffer) {
6
10
  return buffer.toString('utf8');
7
11
  }
8
12
 
9
- /** @type {import('../replacer.js').Replacer<Buffer>} */
13
+ /** @type {Replacer<Buffer>} */
10
14
  export const BufferReplacer = {
11
15
  name: 'Buffer',
12
16
  stopHere: true,
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { Replacer } from '../replacer.js';
3
+ */
1
4
  import { parseStack } from '../utilities/stacktrace.js';
2
5
 
3
6
  /**
@@ -11,7 +14,7 @@ import { parseStack } from '../utilities/stacktrace.js';
11
14
  * @typedef {BaseError & { [k: string]: unknown }} NormalisedError
12
15
  */
13
16
 
14
- /** @type {import('../replacer.js').Replacer<Error, NormalisedError>} */
17
+ /** @type {Replacer<Error, NormalisedError>} */
15
18
  export const ErrorReplacer = {
16
19
  name: 'Error',
17
20
  shouldReplace: (input) => input instanceof Error,
@@ -21,7 +24,7 @@ export const ErrorReplacer = {
21
24
 
22
25
  for (const key of Object.getOwnPropertyNames(value)) {
23
26
  if (Object.hasOwn(value, key)) {
24
- // @ts-ignore - This is always going to be defined
27
+ // @ts-expect-error - This is always going to be defined
25
28
  error[key] = value[key];
26
29
  }
27
30
  }
@@ -1,6 +1,10 @@
1
+ /**
2
+ * @import { Replacer } from '../replacer.js';
3
+ */
4
+
1
5
  import { ClientRequest } from 'node:http';
2
6
 
3
- /** @type {import('../replacer.js').Replacer<ClientRequest>} */
7
+ /** @type {Replacer<ClientRequest>} */
4
8
  export const HttpClientRequestReplacer = {
5
9
  name: 'HttpClientRequest',
6
10
  shouldReplace: (input) => input instanceof ClientRequest,
@@ -1,11 +1,16 @@
1
+ /**
2
+ * @import { ClientRequest } from 'node:http'
3
+ * @import { Replacer } from '../replacer.js'
4
+ */
5
+
1
6
  import { IncomingMessage } from 'node:http';
2
7
 
3
8
  /**
4
- * @type {import('../replacer.js').Replacer<
9
+ * @type {Replacer<
5
10
  * IncomingMessage & {
6
11
  * hostname?: string,
7
12
  * originalUrl?: string,
8
- * req?: import('node:http').ClientRequest
13
+ * req?: ClientRequest
9
14
  * }
10
15
  * >}
11
16
  */