@rawnodes/logger 2.9.0 → 2.10.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.
- package/README.md +82 -13
- package/dist/index.d.mts +27 -252
- package/dist/index.d.ts +27 -252
- package/dist/index.js +168 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +168 -94
- package/dist/index.mjs.map +1 -1
- package/dist/transports/relay.d.mts +14 -0
- package/dist/transports/relay.d.ts +14 -0
- package/dist/transports/relay.js +368 -0
- package/dist/transports/relay.js.map +1 -0
- package/dist/transports/relay.mjs +363 -0
- package/dist/transports/relay.mjs.map +1 -0
- package/dist/types-lfJLhC8J.d.mts +280 -0
- package/dist/types-lfJLhC8J.d.ts +280 -0
- package/package.json +21 -5
package/dist/index.js
CHANGED
|
@@ -167,8 +167,10 @@ var DEFAULT_OPTIONS = {
|
|
|
167
167
|
var BaseHttpTransport = class {
|
|
168
168
|
buffer;
|
|
169
169
|
onErrorCallback;
|
|
170
|
+
masker;
|
|
170
171
|
constructor(opts = {}) {
|
|
171
172
|
this.onErrorCallback = opts.onError;
|
|
173
|
+
this.masker = opts.masker;
|
|
172
174
|
this.buffer = new MessageBuffer({
|
|
173
175
|
batchSize: opts.batchSize ?? DEFAULT_OPTIONS.batchSize,
|
|
174
176
|
flushInterval: opts.flushInterval ?? DEFAULT_OPTIONS.flushInterval,
|
|
@@ -203,12 +205,16 @@ var BaseHttpTransport = class {
|
|
|
203
205
|
}
|
|
204
206
|
transformMessage(info) {
|
|
205
207
|
const { level, message, timestamp, context, ...meta } = info;
|
|
208
|
+
let resolvedMeta;
|
|
209
|
+
if (Object.keys(meta).length > 0) {
|
|
210
|
+
resolvedMeta = this.masker ? this.masker(meta) : meta;
|
|
211
|
+
}
|
|
206
212
|
return {
|
|
207
213
|
level,
|
|
208
214
|
message: String(message),
|
|
209
215
|
timestamp: timestamp instanceof Date ? timestamp : timestamp ? new Date(String(timestamp)) : /* @__PURE__ */ new Date(),
|
|
210
216
|
context,
|
|
211
|
-
meta:
|
|
217
|
+
meta: resolvedMeta
|
|
212
218
|
};
|
|
213
219
|
}
|
|
214
220
|
handleError(error, messages) {
|
|
@@ -255,7 +261,7 @@ var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
|
|
|
255
261
|
var DiscordTransport = class extends BaseHttpTransport {
|
|
256
262
|
config;
|
|
257
263
|
requestTimeout;
|
|
258
|
-
constructor(config) {
|
|
264
|
+
constructor(config, masker) {
|
|
259
265
|
super({
|
|
260
266
|
batchSize: config.batchSize ?? 10,
|
|
261
267
|
flushInterval: config.flushInterval ?? 2e3,
|
|
@@ -264,7 +270,8 @@ var DiscordTransport = class extends BaseHttpTransport {
|
|
|
264
270
|
maxQueueSize: config.maxQueueSize,
|
|
265
271
|
dropPolicy: config.dropPolicy,
|
|
266
272
|
onDrop: config.onDrop,
|
|
267
|
-
onError: config.onError
|
|
273
|
+
onError: config.onError,
|
|
274
|
+
masker
|
|
268
275
|
});
|
|
269
276
|
this.config = config;
|
|
270
277
|
this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
@@ -404,7 +411,7 @@ var TelegramTransport = class extends BaseHttpTransport {
|
|
|
404
411
|
config;
|
|
405
412
|
apiUrl;
|
|
406
413
|
requestTimeout;
|
|
407
|
-
constructor(config) {
|
|
414
|
+
constructor(config, masker) {
|
|
408
415
|
super({
|
|
409
416
|
batchSize: config.batchSize ?? 20,
|
|
410
417
|
flushInterval: config.flushInterval ?? 1e3,
|
|
@@ -413,7 +420,8 @@ var TelegramTransport = class extends BaseHttpTransport {
|
|
|
413
420
|
maxQueueSize: config.maxQueueSize,
|
|
414
421
|
dropPolicy: config.dropPolicy,
|
|
415
422
|
onDrop: config.onDrop,
|
|
416
|
-
onError: config.onError
|
|
423
|
+
onError: config.onError,
|
|
424
|
+
masker
|
|
417
425
|
});
|
|
418
426
|
this.config = config;
|
|
419
427
|
this.apiUrl = `https://api.telegram.org/bot${config.botToken}`;
|
|
@@ -518,7 +526,7 @@ var ZohoCliqTransport = class extends BaseHttpTransport {
|
|
|
518
526
|
config;
|
|
519
527
|
endpoint;
|
|
520
528
|
requestTimeout;
|
|
521
|
-
constructor(config) {
|
|
529
|
+
constructor(config, masker) {
|
|
522
530
|
super({
|
|
523
531
|
batchSize: config.batchSize ?? 20,
|
|
524
532
|
flushInterval: config.flushInterval ?? 2e3,
|
|
@@ -527,7 +535,8 @@ var ZohoCliqTransport = class extends BaseHttpTransport {
|
|
|
527
535
|
maxQueueSize: config.maxQueueSize,
|
|
528
536
|
dropPolicy: config.dropPolicy,
|
|
529
537
|
onDrop: config.onDrop,
|
|
530
|
-
onError: config.onError
|
|
538
|
+
onError: config.onError,
|
|
539
|
+
masker
|
|
531
540
|
});
|
|
532
541
|
this.config = config;
|
|
533
542
|
this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS3;
|
|
@@ -649,7 +658,8 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
649
658
|
initialized = false;
|
|
650
659
|
initPromise = null;
|
|
651
660
|
resolvedLogStreamName;
|
|
652
|
-
|
|
661
|
+
maskReplacer;
|
|
662
|
+
constructor(config, configHostname, maskReplacerFn) {
|
|
653
663
|
super({
|
|
654
664
|
batchSize: config.batchSize ?? 100,
|
|
655
665
|
flushInterval: config.flushInterval ?? 1e3,
|
|
@@ -660,6 +670,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
660
670
|
onDrop: config.onDrop,
|
|
661
671
|
onError: config.onError
|
|
662
672
|
});
|
|
673
|
+
this.maskReplacer = maskReplacerFn;
|
|
663
674
|
this.config = config;
|
|
664
675
|
this.resolvedLogStreamName = resolveLogStreamName(config.logStreamName, configHostname);
|
|
665
676
|
this.client = new clientCloudwatchLogs.CloudWatchLogsClient({
|
|
@@ -672,6 +683,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
672
683
|
}
|
|
673
684
|
async sendBatch(messages) {
|
|
674
685
|
await this.ensureInitialized();
|
|
686
|
+
const replacer = this.maskReplacer;
|
|
675
687
|
const logEvents = messages.map((msg) => ({
|
|
676
688
|
timestamp: msg.timestamp.getTime(),
|
|
677
689
|
message: JSON.stringify({
|
|
@@ -679,7 +691,7 @@ var CloudWatchTransport = class extends BaseHttpTransport {
|
|
|
679
691
|
message: msg.message,
|
|
680
692
|
context: msg.context,
|
|
681
693
|
...msg.meta
|
|
682
|
-
})
|
|
694
|
+
}, replacer)
|
|
683
695
|
}));
|
|
684
696
|
logEvents.sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0));
|
|
685
697
|
const command = new clientCloudwatchLogs.PutLogEventsCommand({
|
|
@@ -831,12 +843,12 @@ function shouldPassTransport(log, level, rules, state, respectOverrides) {
|
|
|
831
843
|
return LOG_LEVELS[logLevel] <= LOG_LEVELS[effectiveLevel];
|
|
832
844
|
}
|
|
833
845
|
var RESERVED_LOG_FIELDS = /* @__PURE__ */ new Set(["level", "time", "msg", "context", "__or"]);
|
|
834
|
-
function formatLog(log, format,
|
|
846
|
+
function formatLog(log, format, state) {
|
|
835
847
|
const levelName = getLevelName(log.level);
|
|
836
848
|
const timestamp = new Date(log.time).toISOString();
|
|
837
849
|
const context = log.context || "APP";
|
|
838
850
|
const message = log.msg || "";
|
|
839
|
-
const storeContext = store.getStore();
|
|
851
|
+
const storeContext = state.store.getStore();
|
|
840
852
|
const meta = {};
|
|
841
853
|
for (const [key, value] of Object.entries(log)) {
|
|
842
854
|
if (!RESERVED_LOG_FIELDS.has(key)) {
|
|
@@ -846,6 +858,7 @@ function formatLog(log, format, store) {
|
|
|
846
858
|
if (storeContext) {
|
|
847
859
|
Object.assign(meta, storeContext);
|
|
848
860
|
}
|
|
861
|
+
const replacer = state.maskReplacer;
|
|
849
862
|
if (format === "json") {
|
|
850
863
|
return JSON.stringify({
|
|
851
864
|
level: levelName,
|
|
@@ -853,7 +866,7 @@ function formatLog(log, format, store) {
|
|
|
853
866
|
context,
|
|
854
867
|
message,
|
|
855
868
|
...meta
|
|
856
|
-
}) + "\n";
|
|
869
|
+
}, replacer) + "\n";
|
|
857
870
|
}
|
|
858
871
|
if (format === "plain") {
|
|
859
872
|
const LEVEL_COLORS = {
|
|
@@ -869,10 +882,11 @@ function formatLog(log, format, store) {
|
|
|
869
882
|
const color = LEVEL_COLORS[levelName] || "";
|
|
870
883
|
const coloredLevel = color ? `${color}${levelName}${RESET}` : levelName;
|
|
871
884
|
const formatValue = (key, value) => {
|
|
872
|
-
|
|
873
|
-
|
|
885
|
+
const masked = replacer ? replacer.call(void 0, key, value) : value;
|
|
886
|
+
if (typeof masked === "string" && masked.includes("\n")) {
|
|
887
|
+
return "\n " + masked.split("\n").join("\n ");
|
|
874
888
|
}
|
|
875
|
-
return JSON.stringify(
|
|
889
|
+
return JSON.stringify(masked, replacer);
|
|
876
890
|
};
|
|
877
891
|
const metaStr = Object.keys(meta).length > 0 ? "\n " + Object.entries(meta).map(([k, v]) => `${k}: ${formatValue(k, v)}`).join("\n ") : "";
|
|
878
892
|
return `[${timestamp}] ${coloredLevel} [${context}] ${message}${metaStr}
|
|
@@ -881,7 +895,8 @@ function formatLog(log, format, store) {
|
|
|
881
895
|
if (format === "logfmt") {
|
|
882
896
|
const parts = [`level=${levelName}`, `msg="${message}"`, `context=${context}`, `ts=${timestamp}`];
|
|
883
897
|
for (const [k, v] of Object.entries(meta)) {
|
|
884
|
-
|
|
898
|
+
const masked = replacer ? replacer.call(void 0, k, v) : v;
|
|
899
|
+
parts.push(`${k}=${JSON.stringify(masked, replacer)}`);
|
|
885
900
|
}
|
|
886
901
|
return parts.join(" ") + "\n";
|
|
887
902
|
}
|
|
@@ -905,7 +920,7 @@ function createFormattedFilterStream(format, level, rules, state, destination, r
|
|
|
905
920
|
callback();
|
|
906
921
|
return;
|
|
907
922
|
}
|
|
908
|
-
const formatted = formatLog(log, format, state
|
|
923
|
+
const formatted = formatLog(log, format, state);
|
|
909
924
|
destination.write(formatted);
|
|
910
925
|
callback();
|
|
911
926
|
}
|
|
@@ -962,7 +977,7 @@ function createStreams(config, state) {
|
|
|
962
977
|
});
|
|
963
978
|
}
|
|
964
979
|
for (const discordConfig of toArray(config.discord)) {
|
|
965
|
-
const transport = new DiscordTransport(discordConfig);
|
|
980
|
+
const transport = new DiscordTransport(discordConfig, state.maskerFn);
|
|
966
981
|
transports.push(transport);
|
|
967
982
|
const discordStream = createHttpTransportStream(
|
|
968
983
|
transport,
|
|
@@ -977,7 +992,7 @@ function createStreams(config, state) {
|
|
|
977
992
|
});
|
|
978
993
|
}
|
|
979
994
|
for (const telegramConfig of toArray(config.telegram)) {
|
|
980
|
-
const transport = new TelegramTransport(telegramConfig);
|
|
995
|
+
const transport = new TelegramTransport(telegramConfig, state.maskerFn);
|
|
981
996
|
transports.push(transport);
|
|
982
997
|
const telegramStream = createHttpTransportStream(
|
|
983
998
|
transport,
|
|
@@ -992,7 +1007,7 @@ function createStreams(config, state) {
|
|
|
992
1007
|
});
|
|
993
1008
|
}
|
|
994
1009
|
for (const zohoCliqConfig of toArray(config.zohoCliq)) {
|
|
995
|
-
const transport = new ZohoCliqTransport(zohoCliqConfig);
|
|
1010
|
+
const transport = new ZohoCliqTransport(zohoCliqConfig, state.maskerFn);
|
|
996
1011
|
transports.push(transport);
|
|
997
1012
|
const zohoStream = createHttpTransportStream(
|
|
998
1013
|
transport,
|
|
@@ -1007,7 +1022,7 @@ function createStreams(config, state) {
|
|
|
1007
1022
|
});
|
|
1008
1023
|
}
|
|
1009
1024
|
for (const cloudwatchConfig of toArray(config.cloudwatch)) {
|
|
1010
|
-
const transport = new CloudWatchTransport(cloudwatchConfig, config.hostname);
|
|
1025
|
+
const transport = new CloudWatchTransport(cloudwatchConfig, config.hostname, state.maskReplacer);
|
|
1011
1026
|
transports.push(transport);
|
|
1012
1027
|
const cwStream = createHttpTransportStream(
|
|
1013
1028
|
transport,
|
|
@@ -1079,6 +1094,116 @@ function createHttpTransportStream(transport, level, rules, state, respectOverri
|
|
|
1079
1094
|
});
|
|
1080
1095
|
}
|
|
1081
1096
|
|
|
1097
|
+
// src/utils/mask-secrets.ts
|
|
1098
|
+
var DEFAULT_SECRET_PATTERNS = [
|
|
1099
|
+
"password",
|
|
1100
|
+
"secret",
|
|
1101
|
+
"token",
|
|
1102
|
+
"apikey",
|
|
1103
|
+
"api_key",
|
|
1104
|
+
"api-key",
|
|
1105
|
+
"auth",
|
|
1106
|
+
"credential",
|
|
1107
|
+
"private"
|
|
1108
|
+
];
|
|
1109
|
+
var DEFAULT_MASK = "***";
|
|
1110
|
+
var REGEX_ESCAPE_RE = /[.*+?^${}()|[\]\\]/g;
|
|
1111
|
+
function buildSecretRe(patterns) {
|
|
1112
|
+
const escaped = patterns.map((p) => p.replace(REGEX_ESCAPE_RE, "\\$&"));
|
|
1113
|
+
return new RegExp(escaped.join("|"), "i");
|
|
1114
|
+
}
|
|
1115
|
+
var DEFAULT_SECRET_RE = buildSecretRe(DEFAULT_SECRET_PATTERNS);
|
|
1116
|
+
var DEFAULT_RESOLVED = {
|
|
1117
|
+
secretRe: DEFAULT_SECRET_RE,
|
|
1118
|
+
mask: DEFAULT_MASK,
|
|
1119
|
+
deep: true
|
|
1120
|
+
};
|
|
1121
|
+
function resolveOptions(options) {
|
|
1122
|
+
if (options.patterns === void 0 && options.mask === void 0 && options.deep === void 0) {
|
|
1123
|
+
return DEFAULT_RESOLVED;
|
|
1124
|
+
}
|
|
1125
|
+
const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;
|
|
1126
|
+
return {
|
|
1127
|
+
secretRe: patterns === DEFAULT_SECRET_PATTERNS ? DEFAULT_SECRET_RE : buildSecretRe(patterns),
|
|
1128
|
+
mask,
|
|
1129
|
+
deep
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function isSecretKey(key, secretRe) {
|
|
1133
|
+
return secretRe.test(key);
|
|
1134
|
+
}
|
|
1135
|
+
function maskUrlCredentials(url, mask) {
|
|
1136
|
+
try {
|
|
1137
|
+
const parsed = new URL(url);
|
|
1138
|
+
if (parsed.password) {
|
|
1139
|
+
parsed.password = mask;
|
|
1140
|
+
}
|
|
1141
|
+
if (parsed.username && parsed.password) {
|
|
1142
|
+
parsed.username = mask;
|
|
1143
|
+
}
|
|
1144
|
+
return parsed.toString();
|
|
1145
|
+
} catch {
|
|
1146
|
+
return url;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
function maskString(str, mask) {
|
|
1150
|
+
if (str.length < 10) return str;
|
|
1151
|
+
if (str.charCodeAt(0) !== 104) return str;
|
|
1152
|
+
if (!str.startsWith("http://") && !str.startsWith("https://")) return str;
|
|
1153
|
+
if (str.indexOf("@") === -1) return str;
|
|
1154
|
+
return maskUrlCredentials(str, mask);
|
|
1155
|
+
}
|
|
1156
|
+
function maskInternal(obj, opts) {
|
|
1157
|
+
if (obj === null || obj === void 0) return obj;
|
|
1158
|
+
const t = typeof obj;
|
|
1159
|
+
if (t === "string") return maskString(obj, opts.mask);
|
|
1160
|
+
if (t !== "object") return obj;
|
|
1161
|
+
if (Array.isArray(obj)) {
|
|
1162
|
+
return opts.deep ? obj.map((item) => maskInternal(item, opts)) : obj;
|
|
1163
|
+
}
|
|
1164
|
+
const { secretRe, mask, deep } = opts;
|
|
1165
|
+
const result = {};
|
|
1166
|
+
const syms = Object.getOwnPropertySymbols(obj);
|
|
1167
|
+
for (let i = 0; i < syms.length; i++) {
|
|
1168
|
+
const sym = syms[i];
|
|
1169
|
+
result[sym] = obj[sym];
|
|
1170
|
+
}
|
|
1171
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
1172
|
+
if (isSecretKey(key, secretRe)) {
|
|
1173
|
+
result[key] = mask;
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
const vt = typeof value;
|
|
1177
|
+
if (vt === "string") {
|
|
1178
|
+
result[key] = maskString(value, mask);
|
|
1179
|
+
} else if (deep && vt === "object" && value !== null) {
|
|
1180
|
+
result[key] = maskInternal(value, opts);
|
|
1181
|
+
} else {
|
|
1182
|
+
result[key] = value;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return result;
|
|
1186
|
+
}
|
|
1187
|
+
function maskSecrets(obj, options = {}) {
|
|
1188
|
+
return maskInternal(obj, resolveOptions(options));
|
|
1189
|
+
}
|
|
1190
|
+
function createMasker(options = {}) {
|
|
1191
|
+
const opts = resolveOptions(options);
|
|
1192
|
+
return (obj) => maskInternal(obj, opts);
|
|
1193
|
+
}
|
|
1194
|
+
function maskReplacer(options = {}) {
|
|
1195
|
+
const { secretRe, mask } = resolveOptions(options);
|
|
1196
|
+
return function(key, value) {
|
|
1197
|
+
if (key !== "" && secretRe.test(key)) return mask;
|
|
1198
|
+
if (typeof value !== "string") return value;
|
|
1199
|
+
if (value.length < 10) return value;
|
|
1200
|
+
if (value.charCodeAt(0) !== 104) return value;
|
|
1201
|
+
if (!value.startsWith("http://") && !value.startsWith("https://")) return value;
|
|
1202
|
+
if (value.indexOf("@") === -1) return value;
|
|
1203
|
+
return maskUrlCredentials(value, mask);
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1082
1207
|
// src/state.ts
|
|
1083
1208
|
var CUSTOM_LEVELS = {
|
|
1084
1209
|
http: 25,
|
|
@@ -1127,6 +1252,7 @@ function createState(config, store) {
|
|
|
1127
1252
|
levelOverrides.set(key, rule);
|
|
1128
1253
|
}
|
|
1129
1254
|
const { contextIndex, complexRules } = buildIndexes(levelOverrides);
|
|
1255
|
+
const maskOptions = config.maskSecrets === true ? {} : config.maskSecrets || void 0;
|
|
1130
1256
|
const state = {
|
|
1131
1257
|
pino: null,
|
|
1132
1258
|
store: loggerStore,
|
|
@@ -1135,7 +1261,9 @@ function createState(config, store) {
|
|
|
1135
1261
|
contextIndex,
|
|
1136
1262
|
complexRules,
|
|
1137
1263
|
callerConfig: void 0,
|
|
1138
|
-
transports: []
|
|
1264
|
+
transports: [],
|
|
1265
|
+
maskReplacer: maskOptions ? maskReplacer(maskOptions) : void 0,
|
|
1266
|
+
maskerFn: maskOptions ? createMasker(maskOptions) : void 0
|
|
1139
1267
|
};
|
|
1140
1268
|
const { destination, transports } = createStreams(config, state);
|
|
1141
1269
|
state.transports = transports;
|
|
@@ -1360,7 +1488,16 @@ var RelayConfigSchema = zod.z.object({
|
|
|
1360
1488
|
bufferSize: zod.z.number().int().positive().optional(),
|
|
1361
1489
|
reconnectDelay: zod.z.number().int().positive().optional(),
|
|
1362
1490
|
maxReconnectDelay: zod.z.number().int().positive().optional(),
|
|
1363
|
-
respectRuntimeOverrides: zod.z.boolean().optional()
|
|
1491
|
+
respectRuntimeOverrides: zod.z.boolean().optional(),
|
|
1492
|
+
allowedWsHosts: zod.z.array(zod.z.string()).optional(),
|
|
1493
|
+
maskSecrets: zod.z.union([
|
|
1494
|
+
zod.z.boolean(),
|
|
1495
|
+
zod.z.object({
|
|
1496
|
+
patterns: zod.z.array(zod.z.string()).optional(),
|
|
1497
|
+
mask: zod.z.string().optional(),
|
|
1498
|
+
deep: zod.z.boolean().optional()
|
|
1499
|
+
})
|
|
1500
|
+
]).optional()
|
|
1364
1501
|
});
|
|
1365
1502
|
var LevelConfigObjectSchema = zod.z.object({
|
|
1366
1503
|
default: LogLevelSchema,
|
|
@@ -1378,6 +1515,11 @@ var AutoShutdownConfigSchema = zod.z.object({
|
|
|
1378
1515
|
timeout: zod.z.number().int().positive().optional(),
|
|
1379
1516
|
signals: zod.z.array(zod.z.string()).optional()
|
|
1380
1517
|
});
|
|
1518
|
+
var MaskSecretsOptionsSchema = zod.z.object({
|
|
1519
|
+
patterns: zod.z.array(zod.z.string()).optional(),
|
|
1520
|
+
mask: zod.z.string().optional(),
|
|
1521
|
+
deep: zod.z.boolean().optional()
|
|
1522
|
+
});
|
|
1381
1523
|
var LoggerConfigSchema = zod.z.object({
|
|
1382
1524
|
level: LevelConfigSchema,
|
|
1383
1525
|
console: ConsoleConfigSchema,
|
|
@@ -1389,7 +1531,8 @@ var LoggerConfigSchema = zod.z.object({
|
|
|
1389
1531
|
relay: RelayConfigSchema.optional(),
|
|
1390
1532
|
caller: zod.z.union([zod.z.boolean(), CallerConfigSchema]).optional(),
|
|
1391
1533
|
hostname: zod.z.string().optional(),
|
|
1392
|
-
autoShutdown: zod.z.union([zod.z.boolean(), AutoShutdownConfigSchema]).optional()
|
|
1534
|
+
autoShutdown: zod.z.union([zod.z.boolean(), AutoShutdownConfigSchema]).optional(),
|
|
1535
|
+
maskSecrets: zod.z.union([zod.z.boolean(), MaskSecretsOptionsSchema]).optional()
|
|
1393
1536
|
});
|
|
1394
1537
|
function validateConfig(config) {
|
|
1395
1538
|
return LoggerConfigSchema.parse(config);
|
|
@@ -1927,75 +2070,6 @@ function getOrGenerateRequestId(headers, options = {}) {
|
|
|
1927
2070
|
return extractRequestId(headers) ?? generateRequestId(options);
|
|
1928
2071
|
}
|
|
1929
2072
|
|
|
1930
|
-
// src/utils/mask-secrets.ts
|
|
1931
|
-
var DEFAULT_SECRET_PATTERNS = [
|
|
1932
|
-
"password",
|
|
1933
|
-
"secret",
|
|
1934
|
-
"token",
|
|
1935
|
-
"apikey",
|
|
1936
|
-
"api_key",
|
|
1937
|
-
"api-key",
|
|
1938
|
-
"auth",
|
|
1939
|
-
"credential",
|
|
1940
|
-
"private"
|
|
1941
|
-
];
|
|
1942
|
-
var DEFAULT_MASK = "***";
|
|
1943
|
-
function isSecretKey(key, patterns) {
|
|
1944
|
-
const lowerKey = key.toLowerCase();
|
|
1945
|
-
return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));
|
|
1946
|
-
}
|
|
1947
|
-
function maskUrlCredentials(url, mask) {
|
|
1948
|
-
try {
|
|
1949
|
-
const parsed = new URL(url);
|
|
1950
|
-
if (parsed.password) {
|
|
1951
|
-
parsed.password = mask;
|
|
1952
|
-
}
|
|
1953
|
-
if (parsed.username && parsed.password) {
|
|
1954
|
-
parsed.username = mask;
|
|
1955
|
-
}
|
|
1956
|
-
return parsed.toString();
|
|
1957
|
-
} catch {
|
|
1958
|
-
return url;
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
function maskSecrets(obj, options = {}) {
|
|
1962
|
-
const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;
|
|
1963
|
-
if (obj === null || obj === void 0) {
|
|
1964
|
-
return obj;
|
|
1965
|
-
}
|
|
1966
|
-
if (typeof obj === "string") {
|
|
1967
|
-
if (obj.startsWith("http://") || obj.startsWith("https://")) {
|
|
1968
|
-
return maskUrlCredentials(obj, mask);
|
|
1969
|
-
}
|
|
1970
|
-
return obj;
|
|
1971
|
-
}
|
|
1972
|
-
if (Array.isArray(obj)) {
|
|
1973
|
-
return deep ? obj.map((item) => maskSecrets(item, options)) : obj;
|
|
1974
|
-
}
|
|
1975
|
-
if (typeof obj === "object") {
|
|
1976
|
-
const result = {};
|
|
1977
|
-
for (const sym of Object.getOwnPropertySymbols(obj)) {
|
|
1978
|
-
result[sym] = obj[sym];
|
|
1979
|
-
}
|
|
1980
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
1981
|
-
if (isSecretKey(key, patterns)) {
|
|
1982
|
-
result[key] = mask;
|
|
1983
|
-
} else if (deep && typeof value === "object" && value !== null) {
|
|
1984
|
-
result[key] = maskSecrets(value, options);
|
|
1985
|
-
} else if (typeof value === "string") {
|
|
1986
|
-
result[key] = maskSecrets(value, options);
|
|
1987
|
-
} else {
|
|
1988
|
-
result[key] = value;
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
return result;
|
|
1992
|
-
}
|
|
1993
|
-
return obj;
|
|
1994
|
-
}
|
|
1995
|
-
function createMasker(options = {}) {
|
|
1996
|
-
return (obj) => maskSecrets(obj, options);
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
2073
|
// src/formatters.ts
|
|
2000
2074
|
var MAX_FLATTEN_DEPTH = 10;
|
|
2001
2075
|
var CIRCULAR_REF = "[Circular]";
|
|
@@ -2088,6 +2162,7 @@ exports.generateRequestId = generateRequestId;
|
|
|
2088
2162
|
exports.getCallerInfo = getCallerInfo;
|
|
2089
2163
|
exports.getOrGenerateRequestId = getOrGenerateRequestId;
|
|
2090
2164
|
exports.isValidLogLevel = isValidLogLevel;
|
|
2165
|
+
exports.maskReplacer = maskReplacer;
|
|
2091
2166
|
exports.maskSecrets = maskSecrets;
|
|
2092
2167
|
exports.matchesContext = matchesContext;
|
|
2093
2168
|
exports.measureAsync = measureAsync;
|