@loggerjs/processors 0.5.0 → 0.5.2

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.
package/dist/index.js CHANGED
@@ -1,4 +1,26 @@
1
1
  import { createBoundContext, createMiddleware, eventToRecord, incrementLoggerMetaCounter, recordToEvent, toLevelName, toLevelValue, withLogEventRoute } from "@loggerjs/core";
2
+ //#region src/error-fields.ts
3
+ const NATIVE_ERROR_FIELDS = ["cause", "errors"];
4
+ function hiddenErrorFields(value) {
5
+ const fields = [];
6
+ for (const field of NATIVE_ERROR_FIELDS) {
7
+ const descriptor = Object.getOwnPropertyDescriptor(value, field);
8
+ if (descriptor && !descriptor.enumerable) fields.push(field);
9
+ }
10
+ return fields;
11
+ }
12
+ function defineHidden(target, field, value) {
13
+ Object.defineProperty(target, field, {
14
+ value,
15
+ writable: true,
16
+ enumerable: false,
17
+ configurable: true
18
+ });
19
+ }
20
+ function dotPath(path, field) {
21
+ return path ? `${path}.${field}` : field;
22
+ }
23
+ //#endregion
2
24
  //#region src/redact.ts
3
25
  function matchesKey(key, path, value, matchers) {
4
26
  return matchers.some((matcher) => {
@@ -15,10 +37,13 @@ function matchesKey(key, path, value, matchers) {
15
37
  function pathMatches(path, paths) {
16
38
  return paths.includes(path);
17
39
  }
40
+ function shouldRedact(key, path, value, options) {
41
+ return matchesKey(key, path, value, options.keys ?? []) || pathMatches(path, options.paths ?? []);
42
+ }
18
43
  function redactValue(value, options, path = "", depth = 0, seen = /* @__PURE__ */ new WeakMap()) {
19
44
  if (value === null || value === void 0) return value;
20
45
  if (typeof value !== "object") return value;
21
- if (depth >= options.maxDepth) return value;
46
+ if (depth >= options.maxDepth) return options.replacement;
22
47
  if (seen.has(value)) return seen.get(value);
23
48
  if (Array.isArray(value)) {
24
49
  const out = [];
@@ -26,14 +51,68 @@ function redactValue(value, options, path = "", depth = 0, seen = /* @__PURE__ *
26
51
  for (let index = 0; index < value.length; index += 1) out[index] = redactValue(value[index], options, `${path}[${index}]`, depth + 1, seen);
27
52
  return out;
28
53
  }
29
- if (value instanceof Error) return value;
30
54
  if (value instanceof Date) return value;
55
+ if (value instanceof Error) {
56
+ const entries = Object.entries(value);
57
+ const hiddenFields = hiddenErrorFields(value);
58
+ if (entries.length === 0 && hiddenFields.length === 0) return value;
59
+ const errorOut = Object.create(Object.getPrototypeOf(value));
60
+ seen.set(value, errorOut);
61
+ defineHidden(errorOut, "message", value.message);
62
+ defineHidden(errorOut, "stack", value.stack);
63
+ for (const field of hiddenFields) {
64
+ const child = value[field];
65
+ const childPath = dotPath(path, field);
66
+ if (shouldRedact(field, childPath, child, options)) {
67
+ if (options.remove) continue;
68
+ defineHidden(errorOut, field, options.replacement);
69
+ continue;
70
+ }
71
+ defineHidden(errorOut, field, redactValue(child, options, childPath, depth + 1, seen));
72
+ }
73
+ for (const [key, child] of entries) {
74
+ const childPath = dotPath(path, key);
75
+ if (shouldRedact(key, childPath, child, options)) {
76
+ if (options.remove) continue;
77
+ errorOut[key] = options.replacement;
78
+ } else errorOut[key] = redactValue(child, options, childPath, depth + 1, seen);
79
+ }
80
+ return errorOut;
81
+ }
82
+ if (value instanceof Map) {
83
+ const mapOut = /* @__PURE__ */ new Map();
84
+ seen.set(value, mapOut);
85
+ for (const [key, child] of value) {
86
+ if (typeof key === "string") {
87
+ const childPath = dotPath(path, key);
88
+ if (shouldRedact(key, childPath, child, options)) {
89
+ if (options.remove) continue;
90
+ mapOut.set(key, options.replacement);
91
+ continue;
92
+ }
93
+ mapOut.set(key, redactValue(child, options, childPath, depth + 1, seen));
94
+ continue;
95
+ }
96
+ mapOut.set(key, redactValue(child, options, path, depth + 1, seen));
97
+ }
98
+ return mapOut;
99
+ }
100
+ if (value instanceof Set) {
101
+ const setOut = /* @__PURE__ */ new Set();
102
+ seen.set(value, setOut);
103
+ let index = 0;
104
+ for (const child of value) {
105
+ setOut.add(redactValue(child, options, `${path}[${index}]`, depth + 1, seen));
106
+ index += 1;
107
+ }
108
+ return setOut;
109
+ }
31
110
  const input = value;
32
111
  const out = {};
33
112
  seen.set(value, out);
34
113
  for (const [key, child] of Object.entries(input)) {
35
- const childPath = path ? `${path}.${key}` : key;
36
- if (matchesKey(key, childPath, child, options.keys ?? []) || pathMatches(childPath, options.paths ?? [])) {
114
+ const childPath = dotPath(path, key);
115
+ if (shouldRedact(key, childPath, child, options)) {
37
116
  if (options.remove) continue;
38
117
  out[key] = options.replacement;
39
118
  } else out[key] = redactValue(child, options, childPath, depth + 1, seen);
@@ -1134,6 +1213,12 @@ function guardString(input, path, options) {
1134
1213
  changed: changed || value !== input
1135
1214
  };
1136
1215
  }
1216
+ function guardErrorString(input, path, options) {
1217
+ return typeof input === "string" ? guardString(input, path, options) : {
1218
+ value: input,
1219
+ changed: false
1220
+ };
1221
+ }
1137
1222
  function guardValue(value, path, key, depth, options, seen) {
1138
1223
  if (matchesAny(options.denyKeys, key, path, value) && !matchesAny(options.allowKeys, key, path, value)) return {
1139
1224
  value: redact(path, "deny-key", options),
@@ -1152,10 +1237,72 @@ function guardValue(value, path, key, depth, options, seen) {
1152
1237
  value: seen.get(value),
1153
1238
  changed: true
1154
1239
  };
1155
- if (value instanceof Date || value instanceof Error) return {
1240
+ if (value instanceof Date) return {
1156
1241
  value,
1157
1242
  changed: false
1158
1243
  };
1244
+ if (value instanceof Error) {
1245
+ const message = guardErrorString(value.message, dotPath(path, "message"), options);
1246
+ const stack = guardErrorString(value.stack, dotPath(path, "stack"), options);
1247
+ const fieldChanged = message.changed || stack.changed;
1248
+ const entries = Object.entries(value);
1249
+ const hiddenFields = hiddenErrorFields(value);
1250
+ if (entries.length === 0 && hiddenFields.length === 0 && !fieldChanged) return {
1251
+ value,
1252
+ changed: false
1253
+ };
1254
+ const errorOut = Object.create(Object.getPrototypeOf(value));
1255
+ seen.set(value, errorOut);
1256
+ defineHidden(errorOut, "message", message.value);
1257
+ defineHidden(errorOut, "stack", stack.value);
1258
+ let changed = fieldChanged;
1259
+ for (const field of hiddenFields) {
1260
+ const childPath = dotPath(path, field);
1261
+ const child = guardValue(value[field], childPath, field, depth + 1, options, seen);
1262
+ defineHidden(errorOut, field, child.value);
1263
+ changed ||= child.changed;
1264
+ }
1265
+ for (const [childKey, childValue] of entries) {
1266
+ const child = guardValue(childValue, dotPath(path, childKey), childKey, depth + 1, options, seen);
1267
+ errorOut[childKey] = child.value;
1268
+ changed ||= child.changed;
1269
+ }
1270
+ return {
1271
+ value: changed ? errorOut : value,
1272
+ changed
1273
+ };
1274
+ }
1275
+ if (value instanceof Map) {
1276
+ const mapOut = /* @__PURE__ */ new Map();
1277
+ seen.set(value, mapOut);
1278
+ let changed = false;
1279
+ for (const [mapKey, mapValue] of value) {
1280
+ const isStringKey = typeof mapKey === "string";
1281
+ const child = guardValue(mapValue, isStringKey ? dotPath(path, mapKey) : path, isStringKey ? mapKey : key, depth + 1, options, seen);
1282
+ mapOut.set(mapKey, child.value);
1283
+ changed ||= child.changed;
1284
+ }
1285
+ return {
1286
+ value: changed ? mapOut : value,
1287
+ changed
1288
+ };
1289
+ }
1290
+ if (value instanceof Set) {
1291
+ const setOut = /* @__PURE__ */ new Set();
1292
+ seen.set(value, setOut);
1293
+ let changed = false;
1294
+ let index = 0;
1295
+ for (const item of value) {
1296
+ const child = guardValue(item, `${path}[${index}]`, String(index), depth + 1, options, seen);
1297
+ setOut.add(child.value);
1298
+ changed ||= child.changed;
1299
+ index += 1;
1300
+ }
1301
+ return {
1302
+ value: changed ? setOut : value,
1303
+ changed
1304
+ };
1305
+ }
1159
1306
  if (Array.isArray(value)) {
1160
1307
  const out = [];
1161
1308
  seen.set(value, out);
@@ -1175,7 +1322,7 @@ function guardValue(value, path, key, depth, options, seen) {
1175
1322
  seen.set(value, out);
1176
1323
  let changed = false;
1177
1324
  for (const [childKey, childValue] of Object.entries(input)) {
1178
- const child = guardValue(childValue, path ? `${path}.${childKey}` : childKey, childKey, depth + 1, options, seen);
1325
+ const child = guardValue(childValue, dotPath(path, childKey), childKey, depth + 1, options, seen);
1179
1326
  out[childKey] = child.value;
1180
1327
  changed ||= child.changed;
1181
1328
  }