@loggerjs/processors 0.5.1 → 0.5.3
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/error-fields.d.ts +7 -0
- package/dist/error-fields.d.ts.map +1 -0
- package/dist/index.cjs +179 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +179 -16
- package/dist/index.js.map +1 -1
- package/dist/privacy-guard.d.ts +1 -1
- package/dist/privacy-guard.d.ts.map +1 -1
- package/dist/redact.d.ts +1 -1
- package/dist/redact.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,24 +1,58 @@
|
|
|
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
|
|
25
|
+
function keyName$1(key) {
|
|
26
|
+
if (typeof key === "symbol") return key.description ?? key.toString();
|
|
27
|
+
return String(key);
|
|
28
|
+
}
|
|
29
|
+
function ownEnumerableEntries$1(value) {
|
|
30
|
+
return Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key)).map((key) => [key, value[key]]);
|
|
31
|
+
}
|
|
3
32
|
function matchesKey(key, path, value, matchers) {
|
|
33
|
+
const name = keyName$1(key);
|
|
4
34
|
return matchers.some((matcher) => {
|
|
5
|
-
if (typeof matcher === "
|
|
35
|
+
if (typeof matcher === "symbol") return matcher === key;
|
|
36
|
+
if (typeof matcher === "string") return matcher.toLowerCase() === name.toLowerCase();
|
|
6
37
|
if (matcher instanceof RegExp) {
|
|
7
38
|
matcher.lastIndex = 0;
|
|
8
|
-
const keyMatches = matcher.test(
|
|
39
|
+
const keyMatches = matcher.test(name);
|
|
9
40
|
matcher.lastIndex = 0;
|
|
10
41
|
return keyMatches || matcher.test(path);
|
|
11
42
|
}
|
|
12
|
-
return matcher(
|
|
43
|
+
return matcher(name, path, value);
|
|
13
44
|
});
|
|
14
45
|
}
|
|
15
46
|
function pathMatches(path, paths) {
|
|
16
47
|
return paths.includes(path);
|
|
17
48
|
}
|
|
49
|
+
function shouldRedact(key, path, value, options) {
|
|
50
|
+
return matchesKey(key, path, value, options.keys ?? []) || pathMatches(path, options.paths ?? []);
|
|
51
|
+
}
|
|
18
52
|
function redactValue(value, options, path = "", depth = 0, seen = /* @__PURE__ */ new WeakMap()) {
|
|
19
53
|
if (value === null || value === void 0) return value;
|
|
20
54
|
if (typeof value !== "object") return value;
|
|
21
|
-
if (depth >= options.maxDepth) return
|
|
55
|
+
if (depth >= options.maxDepth) return options.replacement;
|
|
22
56
|
if (seen.has(value)) return seen.get(value);
|
|
23
57
|
if (Array.isArray(value)) {
|
|
24
58
|
const out = [];
|
|
@@ -26,14 +60,67 @@ function redactValue(value, options, path = "", depth = 0, seen = /* @__PURE__ *
|
|
|
26
60
|
for (let index = 0; index < value.length; index += 1) out[index] = redactValue(value[index], options, `${path}[${index}]`, depth + 1, seen);
|
|
27
61
|
return out;
|
|
28
62
|
}
|
|
29
|
-
if (value instanceof Error) return value;
|
|
30
63
|
if (value instanceof Date) return value;
|
|
31
|
-
|
|
64
|
+
if (value instanceof Error) {
|
|
65
|
+
const entries = ownEnumerableEntries$1(value);
|
|
66
|
+
const hiddenFields = hiddenErrorFields(value);
|
|
67
|
+
if (entries.length === 0 && hiddenFields.length === 0) return value;
|
|
68
|
+
const errorOut = Object.create(Object.getPrototypeOf(value));
|
|
69
|
+
seen.set(value, errorOut);
|
|
70
|
+
defineHidden(errorOut, "message", value.message);
|
|
71
|
+
defineHidden(errorOut, "stack", value.stack);
|
|
72
|
+
for (const field of hiddenFields) {
|
|
73
|
+
const child = value[field];
|
|
74
|
+
const childPath = dotPath(path, field);
|
|
75
|
+
if (shouldRedact(field, childPath, child, options)) {
|
|
76
|
+
if (options.remove) continue;
|
|
77
|
+
defineHidden(errorOut, field, options.replacement);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
defineHidden(errorOut, field, redactValue(child, options, childPath, depth + 1, seen));
|
|
81
|
+
}
|
|
82
|
+
for (const [key, child] of entries) {
|
|
83
|
+
const childPath = dotPath(path, keyName$1(key));
|
|
84
|
+
if (shouldRedact(key, childPath, child, options)) {
|
|
85
|
+
if (options.remove) continue;
|
|
86
|
+
errorOut[key] = options.replacement;
|
|
87
|
+
} else errorOut[key] = redactValue(child, options, childPath, depth + 1, seen);
|
|
88
|
+
}
|
|
89
|
+
return errorOut;
|
|
90
|
+
}
|
|
91
|
+
if (value instanceof Map) {
|
|
92
|
+
const mapOut = /* @__PURE__ */ new Map();
|
|
93
|
+
seen.set(value, mapOut);
|
|
94
|
+
for (const [key, child] of value) {
|
|
95
|
+
if (typeof key === "string" || typeof key === "symbol") {
|
|
96
|
+
const childPath = dotPath(path, keyName$1(key));
|
|
97
|
+
if (shouldRedact(key, childPath, child, options)) {
|
|
98
|
+
if (options.remove) continue;
|
|
99
|
+
mapOut.set(key, options.replacement);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
mapOut.set(key, redactValue(child, options, childPath, depth + 1, seen));
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
mapOut.set(key, redactValue(child, options, path, depth + 1, seen));
|
|
106
|
+
}
|
|
107
|
+
return mapOut;
|
|
108
|
+
}
|
|
109
|
+
if (value instanceof Set) {
|
|
110
|
+
const setOut = /* @__PURE__ */ new Set();
|
|
111
|
+
seen.set(value, setOut);
|
|
112
|
+
let index = 0;
|
|
113
|
+
for (const child of value) {
|
|
114
|
+
setOut.add(redactValue(child, options, `${path}[${index}]`, depth + 1, seen));
|
|
115
|
+
index += 1;
|
|
116
|
+
}
|
|
117
|
+
return setOut;
|
|
118
|
+
}
|
|
32
119
|
const out = {};
|
|
33
120
|
seen.set(value, out);
|
|
34
|
-
for (const [key, child] of
|
|
35
|
-
const childPath = path
|
|
36
|
-
if (
|
|
121
|
+
for (const [key, child] of ownEnumerableEntries$1(value)) {
|
|
122
|
+
const childPath = dotPath(path, keyName$1(key));
|
|
123
|
+
if (shouldRedact(key, childPath, child, options)) {
|
|
37
124
|
if (options.remove) continue;
|
|
38
125
|
out[key] = options.replacement;
|
|
39
126
|
} else out[key] = redactValue(child, options, childPath, depth + 1, seen);
|
|
@@ -1023,6 +1110,13 @@ function isAsciiAlphaNumeric(code) {
|
|
|
1023
1110
|
function hasChar(code, chars) {
|
|
1024
1111
|
return chars.includes(String.fromCharCode(code));
|
|
1025
1112
|
}
|
|
1113
|
+
function keyName(key) {
|
|
1114
|
+
if (typeof key === "symbol") return key.description ?? key.toString();
|
|
1115
|
+
return String(key);
|
|
1116
|
+
}
|
|
1117
|
+
function ownEnumerableEntries(value) {
|
|
1118
|
+
return Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key)).map((key) => [key, value[key]]);
|
|
1119
|
+
}
|
|
1026
1120
|
function isEmailLocalChar(code) {
|
|
1027
1121
|
return isAsciiAlphaNumeric(code) || hasChar(code, "._%+-");
|
|
1028
1122
|
}
|
|
@@ -1088,12 +1182,14 @@ function redactEmailAddresses(input, path, options) {
|
|
|
1088
1182
|
};
|
|
1089
1183
|
}
|
|
1090
1184
|
function matcherMatches(matcher, key, path, value) {
|
|
1091
|
-
|
|
1185
|
+
const name = keyName(key);
|
|
1186
|
+
if (typeof matcher === "symbol") return matcher === key;
|
|
1187
|
+
if (typeof matcher === "string") return matcher.toLowerCase() === name.toLowerCase();
|
|
1092
1188
|
if (matcher instanceof RegExp) {
|
|
1093
1189
|
matcher.lastIndex = 0;
|
|
1094
|
-
return matcher.test(
|
|
1190
|
+
return matcher.test(name) || matcher.test(path);
|
|
1095
1191
|
}
|
|
1096
|
-
return matcher(
|
|
1192
|
+
return matcher(name, path, value);
|
|
1097
1193
|
}
|
|
1098
1194
|
function matchesAny(matchers, key, path, value) {
|
|
1099
1195
|
return matchers.some((matcher) => matcherMatches(matcher, key, path, value));
|
|
@@ -1134,6 +1230,12 @@ function guardString(input, path, options) {
|
|
|
1134
1230
|
changed: changed || value !== input
|
|
1135
1231
|
};
|
|
1136
1232
|
}
|
|
1233
|
+
function guardErrorString(input, path, options) {
|
|
1234
|
+
return typeof input === "string" ? guardString(input, path, options) : {
|
|
1235
|
+
value: input,
|
|
1236
|
+
changed: false
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1137
1239
|
function guardValue(value, path, key, depth, options, seen) {
|
|
1138
1240
|
if (matchesAny(options.denyKeys, key, path, value) && !matchesAny(options.allowKeys, key, path, value)) return {
|
|
1139
1241
|
value: redact(path, "deny-key", options),
|
|
@@ -1152,10 +1254,72 @@ function guardValue(value, path, key, depth, options, seen) {
|
|
|
1152
1254
|
value: seen.get(value),
|
|
1153
1255
|
changed: true
|
|
1154
1256
|
};
|
|
1155
|
-
if (value instanceof Date
|
|
1257
|
+
if (value instanceof Date) return {
|
|
1156
1258
|
value,
|
|
1157
1259
|
changed: false
|
|
1158
1260
|
};
|
|
1261
|
+
if (value instanceof Error) {
|
|
1262
|
+
const message = guardErrorString(value.message, dotPath(path, "message"), options);
|
|
1263
|
+
const stack = guardErrorString(value.stack, dotPath(path, "stack"), options);
|
|
1264
|
+
const fieldChanged = message.changed || stack.changed;
|
|
1265
|
+
const entries = ownEnumerableEntries(value);
|
|
1266
|
+
const hiddenFields = hiddenErrorFields(value);
|
|
1267
|
+
if (entries.length === 0 && hiddenFields.length === 0 && !fieldChanged) return {
|
|
1268
|
+
value,
|
|
1269
|
+
changed: false
|
|
1270
|
+
};
|
|
1271
|
+
const errorOut = Object.create(Object.getPrototypeOf(value));
|
|
1272
|
+
seen.set(value, errorOut);
|
|
1273
|
+
defineHidden(errorOut, "message", message.value);
|
|
1274
|
+
defineHidden(errorOut, "stack", stack.value);
|
|
1275
|
+
let changed = fieldChanged;
|
|
1276
|
+
for (const field of hiddenFields) {
|
|
1277
|
+
const childPath = dotPath(path, field);
|
|
1278
|
+
const child = guardValue(value[field], childPath, field, depth + 1, options, seen);
|
|
1279
|
+
defineHidden(errorOut, field, child.value);
|
|
1280
|
+
changed ||= child.changed;
|
|
1281
|
+
}
|
|
1282
|
+
for (const [childKey, childValue] of entries) {
|
|
1283
|
+
const child = guardValue(childValue, dotPath(path, keyName(childKey)), childKey, depth + 1, options, seen);
|
|
1284
|
+
errorOut[childKey] = child.value;
|
|
1285
|
+
changed ||= child.changed;
|
|
1286
|
+
}
|
|
1287
|
+
return {
|
|
1288
|
+
value: changed ? errorOut : value,
|
|
1289
|
+
changed
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
if (value instanceof Map) {
|
|
1293
|
+
const mapOut = /* @__PURE__ */ new Map();
|
|
1294
|
+
seen.set(value, mapOut);
|
|
1295
|
+
let changed = false;
|
|
1296
|
+
for (const [mapKey, mapValue] of value) {
|
|
1297
|
+
const isNamedKey = typeof mapKey === "string" || typeof mapKey === "symbol";
|
|
1298
|
+
const child = guardValue(mapValue, isNamedKey ? dotPath(path, keyName(mapKey)) : path, isNamedKey ? mapKey : key, depth + 1, options, seen);
|
|
1299
|
+
mapOut.set(mapKey, child.value);
|
|
1300
|
+
changed ||= child.changed;
|
|
1301
|
+
}
|
|
1302
|
+
return {
|
|
1303
|
+
value: changed ? mapOut : value,
|
|
1304
|
+
changed
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
if (value instanceof Set) {
|
|
1308
|
+
const setOut = /* @__PURE__ */ new Set();
|
|
1309
|
+
seen.set(value, setOut);
|
|
1310
|
+
let changed = false;
|
|
1311
|
+
let index = 0;
|
|
1312
|
+
for (const item of value) {
|
|
1313
|
+
const child = guardValue(item, `${path}[${index}]`, String(index), depth + 1, options, seen);
|
|
1314
|
+
setOut.add(child.value);
|
|
1315
|
+
changed ||= child.changed;
|
|
1316
|
+
index += 1;
|
|
1317
|
+
}
|
|
1318
|
+
return {
|
|
1319
|
+
value: changed ? setOut : value,
|
|
1320
|
+
changed
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1159
1323
|
if (Array.isArray(value)) {
|
|
1160
1324
|
const out = [];
|
|
1161
1325
|
seen.set(value, out);
|
|
@@ -1170,12 +1334,11 @@ function guardValue(value, path, key, depth, options, seen) {
|
|
|
1170
1334
|
changed
|
|
1171
1335
|
};
|
|
1172
1336
|
}
|
|
1173
|
-
const input = value;
|
|
1174
1337
|
const out = {};
|
|
1175
1338
|
seen.set(value, out);
|
|
1176
1339
|
let changed = false;
|
|
1177
|
-
for (const [childKey, childValue] of
|
|
1178
|
-
const child = guardValue(childValue, path
|
|
1340
|
+
for (const [childKey, childValue] of ownEnumerableEntries(value)) {
|
|
1341
|
+
const child = guardValue(childValue, dotPath(path, keyName(childKey)), childKey, depth + 1, options, seen);
|
|
1179
1342
|
out[childKey] = child.value;
|
|
1180
1343
|
changed ||= child.changed;
|
|
1181
1344
|
}
|