@wdio/logger 9.1.3 → 9.15.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 CHANGED
@@ -70,3 +70,51 @@ const uploadInterval = setInterval(() => {
70
70
  }
71
71
  }, 100);
72
72
  ```
73
+
74
+ ## Masking Patterns
75
+
76
+ For more secure logging, `setMaskingPatterns`, `WDIO_LOG_MASKING_PATTERNS` or `maskingPatterns` can obfuscate sensitive information from the log.
77
+ For example, we can replace `--key=MySecretKey` with `--key=**MASKED**` to hide your cloud service access key or secret key
78
+ - The regular expression pattern must be provided as a string similar as a RegEx but as string type, for example, `--key=[^ ]*`
79
+ - It support flags and capturing groups like `/--key=([^ ]*)/i`
80
+ - Multiple patterns are separated by a comma, like `--key=([^ ]*),secrets=([^ ]*)`
81
+ - If no capturing group is provided, the entire matching string of the pattern is masked
82
+ - If one or more capturing groups are provided, we replace all the matching groups with `**MASKED**`
83
+ - If there are multiple matches for a single group, we replace them all, too
84
+ - Support both masking in a file and the console
85
+ - Note: In the console, when masking, some colors get stripped, which is a known limitation
86
+
87
+ `setMaskingPatterns` example
88
+ ```javascript
89
+ import logger from '@wdio/logger';
90
+
91
+ // Default for all loggers
92
+ logger.setMaskingPatterns('/--key=([^ ]*)/i,/--secrets=([^ ]*)/i')
93
+
94
+ // For a specific logger
95
+ logger.setMaskingPatterns({'internal' : '/--key=([^ ]*)/i,/--secrets=([^ ]*)/i'})
96
+ const log = logger('internal');
97
+ ```
98
+
99
+ Using wdio config from a `conf.ts` file, we can also configure masking patterns
100
+ ```javascript
101
+ export const config: WebdriverIO.Config = {
102
+ /**
103
+ * test configurations
104
+ */
105
+ logLevel: 'debug',
106
+ maskingPatterns: '/--key=([^ ]*)/i,/--secrets=([^ ]*)/i',
107
+ }
108
+ ```
109
+
110
+ Below are examples with the environment variable `WDIO_LOG_MASKING_PATTERNS` in the code directly:
111
+
112
+ ```javascript
113
+ // Using environment variable in code
114
+ process.env.WDIO_LOG_MASKING_PATTERNS = '/--key=([^ ]*)/i,/--secrets=([^ ]*)/i'
115
+ ```
116
+
117
+ Or before your command line
118
+ ```shell
119
+ WDIO_LOG_MASKING_PATTERNS='RESULT ([^ ]*)' npx wdio run ./wdio/wdio.conf.ts
120
+ ```
@@ -1,4 +1,5 @@
1
1
  export type { Logger } from './index.js';
2
+ export declare const SENSITIVE_DATA_REPLACER = "**MASKED**";
2
3
  /**
3
4
  * This implementation of the Logger package is a simple adptation to run it within
4
5
  * a browser environment.
@@ -7,6 +8,7 @@ declare function getLogger(component: string): Console;
7
8
  declare namespace getLogger {
8
9
  var setLevel: () => void;
9
10
  var setLogLevelsConfig: () => void;
11
+ var setMaskingPatterns: () => void;
10
12
  var waitForBuffer: () => void;
11
13
  var clearLogger: () => void;
12
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC;;;GAGG;AACH,iBAAwB,SAAS,CAAE,SAAS,EAAE,MAAM,WAcnD;kBAduB,SAAS;;;;;;eAAT,SAAS"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,eAAO,MAAM,uBAAuB,eAAe,CAAA;AAEnD;;;GAGG;AACH,iBAAwB,SAAS,CAAE,SAAS,EAAE,MAAM,WAYnD;kBAZuB,SAAS;;;;;;;eAAT,SAAS"}
package/build/browser.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/browser.ts
2
2
  var LOG_METHODS = ["error", "warn", "info", "debug", "trace", "silent"];
3
+ var SENSITIVE_DATA_REPLACER = "**MASKED**";
3
4
  function getLogger(component) {
4
5
  return LOG_METHODS.reduce((acc, cur) => {
5
6
  const prop = cur;
@@ -13,10 +14,13 @@ getLogger.setLevel = () => {
13
14
  };
14
15
  getLogger.setLogLevelsConfig = () => {
15
16
  };
17
+ getLogger.setMaskingPatterns = () => {
18
+ };
16
19
  getLogger.waitForBuffer = () => {
17
20
  };
18
21
  getLogger.clearLogger = () => {
19
22
  };
20
23
  export {
24
+ SENSITIVE_DATA_REPLACER,
21
25
  getLogger as default
22
26
  };
package/build/index.cjs CHANGED
@@ -29,11 +29,63 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
30
 
31
31
  // src/index.ts
32
- var src_exports = {};
33
- __export(src_exports, {
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ SENSITIVE_DATA_REPLACER: () => SENSITIVE_DATA_REPLACER,
34
35
  default: () => getLogger
35
36
  });
36
- module.exports = __toCommonJS(src_exports);
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/utils.ts
40
+ var SENSITIVE_DATA_REPLACER = "**MASKED**";
41
+ var skipError = (aFunction) => {
42
+ try {
43
+ return aFunction();
44
+ } catch {
45
+ return void 0;
46
+ }
47
+ };
48
+ var parseMaskingPatterns = (maskingRegexString) => {
49
+ if (typeof maskingRegexString !== "string") {
50
+ return void 0;
51
+ }
52
+ const regexStrings = maskingRegexString?.split(/,\s*/).filter((regexStr) => regexStr.trim() !== "");
53
+ return regexStrings?.map((regexStr) => {
54
+ const regexParts = regexStr.match(/^\/(.*?)\/([gimsuy]*)$/);
55
+ if (!regexParts) {
56
+ return skipError(() => new RegExp(regexStr));
57
+ } else if (regexParts?.[1]) {
58
+ return skipError(() => regexParts[2] ? new RegExp(regexParts[1], regexParts[2]) : new RegExp(regexParts[1]));
59
+ }
60
+ return void 0;
61
+ }).filter((regex) => regex !== void 0);
62
+ };
63
+ var mask = (text, maskingPatterns) => {
64
+ if (!maskingPatterns || typeof text !== "string") {
65
+ return text;
66
+ }
67
+ const endsWithNewline = text.endsWith("\n");
68
+ let maskedText = text;
69
+ maskingPatterns.forEach((maskingRegex) => {
70
+ maskedText = maskedText.replace(maskingRegex, (fullMatch, ...capturedGroupsAndMore) => {
71
+ const capturedGroups = capturedGroupsAndMore.slice(0, capturedGroupsAndMore.length - 2);
72
+ if (capturedGroups.length === 0) {
73
+ return SENSITIVE_DATA_REPLACER;
74
+ }
75
+ let matchedMaskedText = fullMatch;
76
+ capturedGroups.forEach((group) => {
77
+ matchedMaskedText = matchedMaskedText.replace(group, SENSITIVE_DATA_REPLACER);
78
+ });
79
+ return matchedMaskedText;
80
+ });
81
+ });
82
+ if (endsWithNewline && !maskedText.endsWith("\n")) {
83
+ maskedText += "\n";
84
+ }
85
+ return maskedText;
86
+ };
87
+
88
+ // src/index.ts
37
89
  var import_node_fs = __toESM(require("node:fs"), 1);
38
90
  var import_node_util = __toESM(require("node:util"), 1);
39
91
  var import_loglevel = __toESM(require("loglevel"), 1);
@@ -84,10 +136,11 @@ var SERIALIZERS = [{
84
136
  }];
85
137
  var loggers = import_loglevel.default.getLoggers();
86
138
  var logLevelsConfig = {};
139
+ var maskingPatternsConfig = {};
87
140
  var logCache = /* @__PURE__ */ new Set();
88
141
  var logFile;
89
142
  var originalFactory = import_loglevel.default.methodFactory;
90
- var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
143
+ var wdioLoggerMethodFactory = (wdioLogger) => function(methodName, logLevel, loggerName) {
91
144
  const rawMethod = originalFactory(methodName, logLevel, loggerName);
92
145
  return (...args) => {
93
146
  if (!logFile && process.env.WDIO_LOG_PATH) {
@@ -106,8 +159,9 @@ var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
106
159
  }
107
160
  return arg;
108
161
  });
109
- const logText = (0, import_strip_ansi.default)(`${import_node_util.default.format.apply(this, args)}
162
+ const unmaskedLogText = (0, import_strip_ansi.default)(`${import_node_util.default.format.apply(this, args)}
110
163
  `);
164
+ const maskedLogText = mask(unmaskedLogText, wdioLogger.maskingPatterns);
111
165
  if (logFile && logFile.writable) {
112
166
  if (logCache.size) {
113
167
  logCache.forEach((log2) => {
@@ -117,13 +171,17 @@ var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
117
171
  });
118
172
  logCache.clear();
119
173
  }
120
- if (!logsContainInitPackageError(logText)) {
121
- return logFile.write(logText);
174
+ if (!logsContainInitPackageError(unmaskedLogText)) {
175
+ return logFile.write(maskedLogText);
122
176
  }
123
- logFile.write(logText);
177
+ logFile.write(maskedLogText);
178
+ }
179
+ logCache.add(maskedLogText);
180
+ if (maskedLogText === unmaskedLogText) {
181
+ rawMethod(...args);
182
+ } else {
183
+ rawMethod(maskedLogText.replace(/\n$/, ""));
124
184
  }
125
- logCache.add(logText);
126
- rawMethod(...args);
127
185
  };
128
186
  };
129
187
  var progress = function(data) {
@@ -147,16 +205,18 @@ function getLogger(name) {
147
205
  logLevel = logLevelsConfig[logLevelName];
148
206
  }
149
207
  loggers[name] = import_loglevel.default.getLogger(name);
150
- loggers[name].setLevel(logLevel);
151
- loggers[name].methodFactory = wdioLoggerMethodFactory;
152
- loggers[name].progress = progress;
153
- import_loglevel_plugin_prefix.default.apply(loggers[name], {
208
+ const logger = loggers[name];
209
+ logger.setLevel(logLevel);
210
+ logger.maskingPatterns = maskingPatternsConfig[name] ?? parseMaskingPatterns(process.env.WDIO_LOG_MASKING_PATTERNS);
211
+ logger.progress = progress;
212
+ logger.methodFactory = wdioLoggerMethodFactory(logger);
213
+ import_loglevel_plugin_prefix.default.apply(logger, {
154
214
  template: "%t %l %n:",
155
215
  timestampFormatter: (date) => import_chalk.default.gray(date.toISOString()),
156
216
  levelFormatter: (level) => import_chalk.default[COLORS[level]](level.toUpperCase()),
157
217
  nameFormatter: (name2) => import_chalk.default.whiteBright(name2)
158
218
  });
159
- return loggers[name];
219
+ return logger;
160
220
  }
161
221
  getLogger.waitForBuffer = async () => new Promise((resolve) => {
162
222
  if (logFile && Array.isArray(logFile.writableBuffer) && logFile.writableBuffer.length !== 0) {
@@ -189,6 +249,24 @@ getLogger.setLogLevelsConfig = (logLevels = {}, wdioLogLevel = DEFAULT_LEVEL) =>
189
249
  loggers[logName].setLevel(logLevel);
190
250
  });
191
251
  };
252
+ getLogger.setMaskingPatterns = (pattern) => {
253
+ if (typeof pattern === "string") {
254
+ if (process.env.WDIO_LOG_MASKING_PATTERNS === void 0) {
255
+ process.env.WDIO_LOG_MASKING_PATTERNS = pattern;
256
+ }
257
+ } else if (typeof pattern === "object") {
258
+ maskingPatternsConfig = Object.entries(pattern).reduce((acc, [logName, maskingPatternsString]) => {
259
+ acc[logName] = parseMaskingPatterns(maskingPatternsString);
260
+ return acc;
261
+ }, maskingPatternsConfig);
262
+ } else {
263
+ throw new Error(`Invalid pattern property, expected \`string\` or \`Record<string, string>\` but received \`${typeof pattern}\``);
264
+ }
265
+ Object.keys(loggers).forEach((logName) => {
266
+ const maskingPatterns = maskingPatternsConfig[logName] ?? parseMaskingPatterns(process.env.WDIO_LOG_MASKING_PATTERNS);
267
+ loggers[logName].maskingPatterns = maskingPatterns;
268
+ });
269
+ };
192
270
  var getLogLevelName = (logName) => logName.split(":").shift();
193
271
  function logsContainInitPackageError(logText) {
194
272
  return ERROR_LOG_VALIDATOR.every((pattern) => logText.includes(pattern));
@@ -199,3 +277,7 @@ var ERROR_LOG_VALIDATOR = [
199
277
  "nor as community package",
200
278
  "Please make sure you have it installed"
201
279
  ];
280
+ // Annotate the CommonJS export names for ESM import in node:
281
+ 0 && (module.exports = {
282
+ SENSITIVE_DATA_REPLACER
283
+ });
package/build/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
+ export { SENSITIVE_DATA_REPLACER } from './utils.js';
1
2
  import log from 'loglevel';
2
3
  interface LoggerInterface extends log.Logger {
3
- progress(...msg: any[]): void;
4
+ maskingPatterns: RegExp[] | undefined;
5
+ progress(...msg: string[]): void;
4
6
  }
5
7
  declare function getLogger(name: string): LoggerInterface;
6
8
  declare namespace getLogger {
@@ -8,7 +10,10 @@ declare namespace getLogger {
8
10
  var setLevel: (name: string, level: log.LogLevelDesc) => void;
9
11
  var clearLogger: () => void;
10
12
  var setLogLevelsConfig: (logLevels?: Record<string, log.LogLevelDesc>, wdioLogLevel?: log.LogLevelDesc) => void;
13
+ var setMaskingPatterns: (pattern: MaskPattern | MaskPatternForSpecificLogger) => void;
11
14
  }
12
15
  export default getLogger;
16
+ type MaskPattern = string;
17
+ type MaskPatternForSpecificLogger = Record<string, MaskPattern>;
13
18
  export type Logger = LoggerInterface;
14
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,UAAU,CAAA;AAsD1B,UAAU,eAAgB,SAAQ,GAAG,CAAC,MAAM;IACxC,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CACjC;AA+ED,iBAAwB,SAAS,CAAE,IAAI,EAAE,MAAM,mBAyB9C;kBAzBuB,SAAS;;yBAwCL,MAAM,SAAS,GAAG,CAAC,YAAY;;yCAOhB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,iBAAqB,GAAG,CAAC,YAAY;;eA/CxF,SAAS;AAiFjC,MAAM,MAAM,MAAM,GAAG,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAKpD,OAAO,GAAG,MAAM,UAAU,CAAA;AAuD1B,UAAU,eAAgB,SAAQ,GAAG,CAAC,MAAM;IACxC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACpC;AAwFD,iBAAwB,SAAS,CAAE,IAAI,EAAE,MAAM,mBA8B9C;kBA9BuB,SAAS;;yBA6CL,MAAM,SAAS,GAAG,CAAC,YAAY;;yCAOhB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,iBAAqB,GAAG,CAAC,YAAY;sCAmCvE,WAAW,GAAG,4BAA4B;;eAvF3D,SAAS;AAqFjC,KAAK,WAAW,GAAG,MAAM,CAAA;AACzB,KAAK,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAoC/D,MAAM,MAAM,MAAM,GAAG,eAAe,CAAA"}
package/build/index.js CHANGED
@@ -1,3 +1,52 @@
1
+ // src/utils.ts
2
+ var SENSITIVE_DATA_REPLACER = "**MASKED**";
3
+ var skipError = (aFunction) => {
4
+ try {
5
+ return aFunction();
6
+ } catch {
7
+ return void 0;
8
+ }
9
+ };
10
+ var parseMaskingPatterns = (maskingRegexString) => {
11
+ if (typeof maskingRegexString !== "string") {
12
+ return void 0;
13
+ }
14
+ const regexStrings = maskingRegexString?.split(/,\s*/).filter((regexStr) => regexStr.trim() !== "");
15
+ return regexStrings?.map((regexStr) => {
16
+ const regexParts = regexStr.match(/^\/(.*?)\/([gimsuy]*)$/);
17
+ if (!regexParts) {
18
+ return skipError(() => new RegExp(regexStr));
19
+ } else if (regexParts?.[1]) {
20
+ return skipError(() => regexParts[2] ? new RegExp(regexParts[1], regexParts[2]) : new RegExp(regexParts[1]));
21
+ }
22
+ return void 0;
23
+ }).filter((regex) => regex !== void 0);
24
+ };
25
+ var mask = (text, maskingPatterns) => {
26
+ if (!maskingPatterns || typeof text !== "string") {
27
+ return text;
28
+ }
29
+ const endsWithNewline = text.endsWith("\n");
30
+ let maskedText = text;
31
+ maskingPatterns.forEach((maskingRegex) => {
32
+ maskedText = maskedText.replace(maskingRegex, (fullMatch, ...capturedGroupsAndMore) => {
33
+ const capturedGroups = capturedGroupsAndMore.slice(0, capturedGroupsAndMore.length - 2);
34
+ if (capturedGroups.length === 0) {
35
+ return SENSITIVE_DATA_REPLACER;
36
+ }
37
+ let matchedMaskedText = fullMatch;
38
+ capturedGroups.forEach((group) => {
39
+ matchedMaskedText = matchedMaskedText.replace(group, SENSITIVE_DATA_REPLACER);
40
+ });
41
+ return matchedMaskedText;
42
+ });
43
+ });
44
+ if (endsWithNewline && !maskedText.endsWith("\n")) {
45
+ maskedText += "\n";
46
+ }
47
+ return maskedText;
48
+ };
49
+
1
50
  // src/index.ts
2
51
  import fs from "node:fs";
3
52
  import util from "node:util";
@@ -49,10 +98,11 @@ var SERIALIZERS = [{
49
98
  }];
50
99
  var loggers = log.getLoggers();
51
100
  var logLevelsConfig = {};
101
+ var maskingPatternsConfig = {};
52
102
  var logCache = /* @__PURE__ */ new Set();
53
103
  var logFile;
54
104
  var originalFactory = log.methodFactory;
55
- var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
105
+ var wdioLoggerMethodFactory = (wdioLogger) => function(methodName, logLevel, loggerName) {
56
106
  const rawMethod = originalFactory(methodName, logLevel, loggerName);
57
107
  return (...args) => {
58
108
  if (!logFile && process.env.WDIO_LOG_PATH) {
@@ -71,8 +121,9 @@ var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
71
121
  }
72
122
  return arg;
73
123
  });
74
- const logText = ansiStrip(`${util.format.apply(this, args)}
124
+ const unmaskedLogText = ansiStrip(`${util.format.apply(this, args)}
75
125
  `);
126
+ const maskedLogText = mask(unmaskedLogText, wdioLogger.maskingPatterns);
76
127
  if (logFile && logFile.writable) {
77
128
  if (logCache.size) {
78
129
  logCache.forEach((log2) => {
@@ -82,13 +133,17 @@ var wdioLoggerMethodFactory = function(methodName, logLevel, loggerName) {
82
133
  });
83
134
  logCache.clear();
84
135
  }
85
- if (!logsContainInitPackageError(logText)) {
86
- return logFile.write(logText);
136
+ if (!logsContainInitPackageError(unmaskedLogText)) {
137
+ return logFile.write(maskedLogText);
87
138
  }
88
- logFile.write(logText);
139
+ logFile.write(maskedLogText);
140
+ }
141
+ logCache.add(maskedLogText);
142
+ if (maskedLogText === unmaskedLogText) {
143
+ rawMethod(...args);
144
+ } else {
145
+ rawMethod(maskedLogText.replace(/\n$/, ""));
89
146
  }
90
- logCache.add(logText);
91
- rawMethod(...args);
92
147
  };
93
148
  };
94
149
  var progress = function(data) {
@@ -112,16 +167,18 @@ function getLogger(name) {
112
167
  logLevel = logLevelsConfig[logLevelName];
113
168
  }
114
169
  loggers[name] = log.getLogger(name);
115
- loggers[name].setLevel(logLevel);
116
- loggers[name].methodFactory = wdioLoggerMethodFactory;
117
- loggers[name].progress = progress;
118
- prefix.apply(loggers[name], {
170
+ const logger = loggers[name];
171
+ logger.setLevel(logLevel);
172
+ logger.maskingPatterns = maskingPatternsConfig[name] ?? parseMaskingPatterns(process.env.WDIO_LOG_MASKING_PATTERNS);
173
+ logger.progress = progress;
174
+ logger.methodFactory = wdioLoggerMethodFactory(logger);
175
+ prefix.apply(logger, {
119
176
  template: "%t %l %n:",
120
177
  timestampFormatter: (date) => chalk.gray(date.toISOString()),
121
178
  levelFormatter: (level) => chalk[COLORS[level]](level.toUpperCase()),
122
179
  nameFormatter: (name2) => chalk.whiteBright(name2)
123
180
  });
124
- return loggers[name];
181
+ return logger;
125
182
  }
126
183
  getLogger.waitForBuffer = async () => new Promise((resolve) => {
127
184
  if (logFile && Array.isArray(logFile.writableBuffer) && logFile.writableBuffer.length !== 0) {
@@ -154,6 +211,24 @@ getLogger.setLogLevelsConfig = (logLevels = {}, wdioLogLevel = DEFAULT_LEVEL) =>
154
211
  loggers[logName].setLevel(logLevel);
155
212
  });
156
213
  };
214
+ getLogger.setMaskingPatterns = (pattern) => {
215
+ if (typeof pattern === "string") {
216
+ if (process.env.WDIO_LOG_MASKING_PATTERNS === void 0) {
217
+ process.env.WDIO_LOG_MASKING_PATTERNS = pattern;
218
+ }
219
+ } else if (typeof pattern === "object") {
220
+ maskingPatternsConfig = Object.entries(pattern).reduce((acc, [logName, maskingPatternsString]) => {
221
+ acc[logName] = parseMaskingPatterns(maskingPatternsString);
222
+ return acc;
223
+ }, maskingPatternsConfig);
224
+ } else {
225
+ throw new Error(`Invalid pattern property, expected \`string\` or \`Record<string, string>\` but received \`${typeof pattern}\``);
226
+ }
227
+ Object.keys(loggers).forEach((logName) => {
228
+ const maskingPatterns = maskingPatternsConfig[logName] ?? parseMaskingPatterns(process.env.WDIO_LOG_MASKING_PATTERNS);
229
+ loggers[logName].maskingPatterns = maskingPatterns;
230
+ });
231
+ };
157
232
  var getLogLevelName = (logName) => logName.split(":").shift();
158
233
  function logsContainInitPackageError(logText) {
159
234
  return ERROR_LOG_VALIDATOR.every((pattern) => logText.includes(pattern));
@@ -165,5 +240,6 @@ var ERROR_LOG_VALIDATOR = [
165
240
  "Please make sure you have it installed"
166
241
  ];
167
242
  export {
243
+ SENSITIVE_DATA_REPLACER,
168
244
  getLogger as default
169
245
  };
@@ -0,0 +1,21 @@
1
+ export declare const SENSITIVE_DATA_REPLACER = "**MASKED**";
2
+ /**
3
+ * Parses a comma-separated string of regular expressions into an array of RegExp objects.
4
+ * Supports both `/pattern/flags` and plain pattern formats.
5
+ *
6
+ * @param {string | undefined} maskingRegexString - The string containing regex patterns.
7
+ * @returns {(RegExp[] | undefined)} Array of RegExp objects or undefined if input is invalid.
8
+ */
9
+ export declare const parseMaskingPatterns: (maskingRegexString: string | undefined) => any[] | undefined;
10
+ /**
11
+ * Masks sensitive data in a string using the provided masking patterns.
12
+ *
13
+ * - If a pattern has no capturing groups, the whole match is replaced with the mask.
14
+ * - If a pattern has capturing groups, each group is replaced with the mask, preserving the rest of the match.
15
+ *
16
+ * @param {string} text - The text to mask.
17
+ * @param {RegExp[] | undefined} maskingPatterns - Array of RegExp patterns to use for masking.
18
+ * @returns {string} The masked text, or the original value if not a string or if no patterns are provided.
19
+ */
20
+ export declare const mask: (text: string, maskingPatterns: RegExp[] | undefined) => string;
21
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,eAAe,CAAA;AAUnD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uBAAwB,MAAM,GAAG,SAAS,sBAgB1E,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,SAAU,MAAM,mBAAmB,MAAM,EAAE,GAAG,SAAS,WA6BvE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/logger",
3
- "version": "9.1.3",
3
+ "version": "9.15.0",
4
4
  "description": "A helper utility for logging of WebdriverIO packages",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-logger",
@@ -45,5 +45,5 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "db677c6008e388301aba23f655679f4c5b6ea023"
48
+ "gitHead": "0161f7203a99a181ee945286b676b37e032763fe"
49
49
  }