pw-sanitizer 0.1.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 (86) hide show
  1. package/README.md +415 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +113 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config/loader.d.ts +30 -0
  7. package/dist/config/loader.d.ts.map +1 -0
  8. package/dist/config/loader.js +173 -0
  9. package/dist/config/loader.js.map +1 -0
  10. package/dist/config/types.d.ts +432 -0
  11. package/dist/config/types.d.ts.map +1 -0
  12. package/dist/config/types.js +6 -0
  13. package/dist/config/types.js.map +1 -0
  14. package/dist/config/validator.d.ts +34 -0
  15. package/dist/config/validator.d.ts.map +1 -0
  16. package/dist/config/validator.js +95 -0
  17. package/dist/config/validator.js.map +1 -0
  18. package/dist/index.d.ts +74 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +190 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/logger.d.ts +82 -0
  23. package/dist/logger.d.ts.map +1 -0
  24. package/dist/logger.js +122 -0
  25. package/dist/logger.js.map +1 -0
  26. package/dist/processors/html-report.d.ts +27 -0
  27. package/dist/processors/html-report.d.ts.map +1 -0
  28. package/dist/processors/html-report.js +220 -0
  29. package/dist/processors/html-report.js.map +1 -0
  30. package/dist/processors/screenshot.d.ts +37 -0
  31. package/dist/processors/screenshot.d.ts.map +1 -0
  32. package/dist/processors/screenshot.js +52 -0
  33. package/dist/processors/screenshot.js.map +1 -0
  34. package/dist/processors/trace-file.d.ts +29 -0
  35. package/dist/processors/trace-file.d.ts.map +1 -0
  36. package/dist/processors/trace-file.js +250 -0
  37. package/dist/processors/trace-file.js.map +1 -0
  38. package/dist/redact/json-walker.d.ts +28 -0
  39. package/dist/redact/json-walker.d.ts.map +1 -0
  40. package/dist/redact/json-walker.js +164 -0
  41. package/dist/redact/json-walker.js.map +1 -0
  42. package/dist/redact/matcher.d.ts +25 -0
  43. package/dist/redact/matcher.d.ts.map +1 -0
  44. package/dist/redact/matcher.js +130 -0
  45. package/dist/redact/matcher.js.map +1 -0
  46. package/dist/redact/pattern-loader.d.ts +25 -0
  47. package/dist/redact/pattern-loader.d.ts.map +1 -0
  48. package/dist/redact/pattern-loader.js +111 -0
  49. package/dist/redact/pattern-loader.js.map +1 -0
  50. package/dist/redact/pattern-registry.d.ts +17 -0
  51. package/dist/redact/pattern-registry.d.ts.map +1 -0
  52. package/dist/redact/pattern-registry.js +58 -0
  53. package/dist/redact/pattern-registry.js.map +1 -0
  54. package/dist/remove/detector.d.ts +22 -0
  55. package/dist/remove/detector.d.ts.map +1 -0
  56. package/dist/remove/detector.js +152 -0
  57. package/dist/remove/detector.js.map +1 -0
  58. package/dist/remove/remover.d.ts +18 -0
  59. package/dist/remove/remover.d.ts.map +1 -0
  60. package/dist/remove/remover.js +72 -0
  61. package/dist/remove/remover.js.map +1 -0
  62. package/dist/remove/rule-loader.d.ts +25 -0
  63. package/dist/remove/rule-loader.d.ts.map +1 -0
  64. package/dist/remove/rule-loader.js +110 -0
  65. package/dist/remove/rule-loader.js.map +1 -0
  66. package/dist/remove/rule-registry.d.ts +17 -0
  67. package/dist/remove/rule-registry.d.ts.map +1 -0
  68. package/dist/remove/rule-registry.js +58 -0
  69. package/dist/remove/rule-registry.js.map +1 -0
  70. package/dist/remove/timestamp-repair.d.ts +28 -0
  71. package/dist/remove/timestamp-repair.d.ts.map +1 -0
  72. package/dist/remove/timestamp-repair.js +157 -0
  73. package/dist/remove/timestamp-repair.js.map +1 -0
  74. package/dist/reporter.d.ts +44 -0
  75. package/dist/reporter.d.ts.map +1 -0
  76. package/dist/reporter.js +180 -0
  77. package/dist/reporter.js.map +1 -0
  78. package/dist/teardown.d.ts +27 -0
  79. package/dist/teardown.d.ts.map +1 -0
  80. package/dist/teardown.js +42 -0
  81. package/dist/teardown.js.map +1 -0
  82. package/dist/utils.d.ts +36 -0
  83. package/dist/utils.d.ts.map +1 -0
  84. package/dist/utils.js +112 -0
  85. package/dist/utils.js.map +1 -0
  86. package/package.json +71 -0
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const logger_js_1 = require("../logger.js");
40
+ /**
41
+ * Ordered list of config file names that are auto-discovered in the current
42
+ * working directory when no explicit `--config` path is provided.
43
+ */
44
+ const CONFIG_FILE_NAMES = [
45
+ 'playwright-sanitizer.config.ts',
46
+ 'playwright-sanitizer.config.js',
47
+ 'playwright-sanitizer.config.json',
48
+ ];
49
+ /**
50
+ * Loads a {@link SanitizerConfig} from an explicit file path.
51
+ *
52
+ * - `.json` files are parsed with `JSON.parse`.
53
+ * - `.ts` / `.js` files are loaded via dynamic `import()`.
54
+ * If loading a `.ts` file fails, a compiled `.js` sibling is tried automatically.
55
+ *
56
+ * @param filePath - Absolute or relative path to the config file.
57
+ * @returns The resolved {@link SanitizerConfig}.
58
+ * @throws Calls `logger.fatal` (which throws) if the file is not found or cannot be parsed.
59
+ */
60
+ async function loadConfigFromFile(filePath) {
61
+ const absolutePath = path.resolve(filePath);
62
+ if (!fs.existsSync(absolutePath)) {
63
+ return logger_js_1.logger.fatal(`Config file not found: ${absolutePath}`);
64
+ }
65
+ const ext = path.extname(absolutePath).toLowerCase();
66
+ if (ext === '.json') {
67
+ const content = fs.readFileSync(absolutePath, 'utf-8');
68
+ return JSON.parse(content);
69
+ }
70
+ // .ts or .js — use dynamic import
71
+ try {
72
+ const module = await import(absolutePath);
73
+ return (module.default ?? module);
74
+ }
75
+ catch (err) {
76
+ // If .ts failed, try .js sibling
77
+ if (ext === '.ts') {
78
+ const jsSibling = absolutePath.replace(/\.ts$/, '.js');
79
+ if (fs.existsSync(jsSibling)) {
80
+ try {
81
+ const module = await import(jsSibling);
82
+ return (module.default ?? module);
83
+ }
84
+ catch {
85
+ return logger_js_1.logger.fatal(`Failed to load config from both ${absolutePath} and ${jsSibling}. ` +
86
+ `Ensure tsx or ts-node is available, or provide a .js config file.`);
87
+ }
88
+ }
89
+ }
90
+ return logger_js_1.logger.fatal(`Failed to load config from ${absolutePath}: ${err instanceof Error ? err.message : String(err)}`);
91
+ }
92
+ }
93
+ /**
94
+ * Attempts to load a sanitizer config from the `sanitizer` key inside
95
+ * `playwright.config.ts` or `playwright.config.js` in the given directory.
96
+ *
97
+ * Returns `null` if no Playwright config is found, the file cannot be
98
+ * loaded, or it does not contain a `sanitizer` key.
99
+ *
100
+ * @param cwd - The directory to search for a Playwright config file.
101
+ * @returns The embedded {@link SanitizerConfig}, or `null` if not found.
102
+ */
103
+ async function loadFromPlaywrightConfig(cwd) {
104
+ const candidates = ['playwright.config.ts', 'playwright.config.js'];
105
+ for (const name of candidates) {
106
+ const fullPath = path.resolve(cwd, name);
107
+ if (fs.existsSync(fullPath)) {
108
+ try {
109
+ const module = await import(fullPath);
110
+ const config = module.default ?? module;
111
+ if (config && typeof config === 'object' && 'sanitizer' in config) {
112
+ return config.sanitizer;
113
+ }
114
+ }
115
+ catch {
116
+ // Not loadable or no sanitizer key — continue
117
+ }
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ /**
123
+ * Resolves and loads the sanitizer configuration.
124
+ *
125
+ * Config discovery priority (first match wins):
126
+ * 1. Explicit `configPath` (from `--config` CLI flag or programmatic call)
127
+ * 2. `playwright-sanitizer.config.ts` in `cwd`
128
+ * 3. `playwright-sanitizer.config.js` in `cwd`
129
+ * 4. `playwright-sanitizer.config.json` in `cwd`
130
+ * 5. `sanitizer` key inside `playwright.config.ts` / `playwright.config.js`
131
+ *
132
+ * If none of the above are found, the function calls `logger.fatal` which
133
+ * throws an `Error` with an actionable message.
134
+ *
135
+ * @param configPath - Optional explicit path to a config file.
136
+ * When provided, auto-discovery is skipped entirely.
137
+ * @returns The resolved {@link SanitizerConfig}.
138
+ * @throws Calls `logger.fatal` (which throws) when no config can be found or loaded.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * // Auto-discover config in cwd
143
+ * const config = await loadConfig();
144
+ *
145
+ * // Load from an explicit path
146
+ * const config = await loadConfig('./configs/sanitizer.config.ts');
147
+ * ```
148
+ */
149
+ async function loadConfig(configPath) {
150
+ const cwd = process.cwd();
151
+ // 1. Explicit path
152
+ if (configPath) {
153
+ logger_js_1.logger.verbose(`Loading config from explicit path: ${configPath}`);
154
+ return loadConfigFromFile(configPath);
155
+ }
156
+ // 2-4. Auto-discover config files
157
+ for (const name of CONFIG_FILE_NAMES) {
158
+ const fullPath = path.resolve(cwd, name);
159
+ if (fs.existsSync(fullPath)) {
160
+ logger_js_1.logger.verbose(`Found config file: ${fullPath}`);
161
+ return loadConfigFromFile(fullPath);
162
+ }
163
+ }
164
+ // 5. Playwright config sanitizer key
165
+ const fromPlaywright = await loadFromPlaywrightConfig(cwd);
166
+ if (fromPlaywright) {
167
+ logger_js_1.logger.verbose('Loaded config from playwright.config sanitizer key');
168
+ return fromPlaywright;
169
+ }
170
+ return logger_js_1.logger.fatal('No playwright-sanitizer config found. ' +
171
+ 'Create playwright-sanitizer.config.ts or pass --config <path>.');
172
+ }
173
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,432 @@
1
+ /**
2
+ * Root configuration object for `playwright-sanitizer`.
3
+ *
4
+ * All sections are optional — omitting a section disables that feature entirely.
5
+ * Nothing is redacted or removed unless explicitly declared here.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // playwright-sanitizer.config.ts
10
+ * import type { SanitizerConfig } from 'playwright-sanitizer';
11
+ *
12
+ * const config: SanitizerConfig = {
13
+ * redact: {
14
+ * patterns: [{ id: 'auth-header', key: 'authorization' }],
15
+ * },
16
+ * remove: {
17
+ * rules: [{ label: 'noisy-poll', stepName: /waitFor/ }],
18
+ * },
19
+ * };
20
+ *
21
+ * export default config;
22
+ * ```
23
+ */
24
+ export interface SanitizerConfig {
25
+ /**
26
+ * Declares what values to mask.
27
+ * Nothing is redacted unless explicitly listed here.
28
+ */
29
+ redact?: RedactConfig;
30
+ /**
31
+ * Declares which steps to delete entirely.
32
+ * Nothing is removed unless explicitly listed here.
33
+ */
34
+ remove?: RemoveConfig;
35
+ /** Output behaviour */
36
+ output?: OutputConfig;
37
+ /** Summary and logging */
38
+ reporting?: ReportingConfig;
39
+ }
40
+ /**
41
+ * Configuration for the redaction pipeline.
42
+ *
43
+ * Patterns are loaded from `patternFiles` first, then merged with inline
44
+ * `patterns`. Duplicate IDs result in a warning; the last definition wins.
45
+ */
46
+ export interface RedactConfig {
47
+ /**
48
+ * Path(s) to external pattern files (.ts, .js, .json).
49
+ * Merged with inline `patterns`. No built-in patterns apply.
50
+ */
51
+ patternFiles?: string | string[];
52
+ /**
53
+ * Inline pattern definitions. Merged with patternFiles.
54
+ * These are the only patterns that will ever be applied.
55
+ */
56
+ patterns?: RedactPattern[];
57
+ /**
58
+ * Replacement string for redacted values.
59
+ * Default: `'[REDACTED]'`
60
+ */
61
+ placeholder?: string;
62
+ /**
63
+ * Partial redaction: keep first `prefix` and last `suffix` characters,
64
+ * replace the middle with `'***'`.
65
+ *
66
+ * @example
67
+ * With `{ prefix: 4, suffix: 4 }`:
68
+ * `'Bearer eyJhbGci...'` → `'Bear***..ci'`
69
+ *
70
+ * When set, takes priority over `placeholder` for string values.
71
+ * If the value is too short to apply partial redaction, it is fully redacted.
72
+ */
73
+ partialRedaction?: {
74
+ prefix: number;
75
+ suffix: number;
76
+ };
77
+ }
78
+ /**
79
+ * A single secret-matching rule used by the redaction pipeline.
80
+ *
81
+ * At least one of {@link key} or {@link valuePattern} must be provided.
82
+ * When both are provided, **both** must match for redaction to apply (AND logic).
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * // Redact any field named "authorization" regardless of value
87
+ * { id: 'auth-header', key: 'authorization' }
88
+ *
89
+ * // Redact any field whose value looks like a Bearer token
90
+ * { id: 'bearer-token', valuePattern: /^Bearer\s+\S+$/ }
91
+ *
92
+ * // Redact only when both match
93
+ * { id: 'api-key', key: /^x-api-key$/i, valuePattern: /^[A-Za-z0-9]{32,}$/ }
94
+ * ```
95
+ */
96
+ export interface RedactPattern {
97
+ /**
98
+ * REQUIRED. Unique identifier for this pattern.
99
+ * Used in summary output, warnings, and the dry-run log.
100
+ */
101
+ id: string;
102
+ /** Optional human-readable description of why this is being redacted. */
103
+ description?: string;
104
+ /**
105
+ * Match against the field/key name (header name, body property, query param name).
106
+ *
107
+ * - `string`: exact case-insensitive match
108
+ * - `RegExp`: tested against the key string
109
+ *
110
+ * At least one of `key` or {@link valuePattern} must be provided.
111
+ */
112
+ key?: string | RegExp;
113
+ /**
114
+ * Match against the field value. When provided alongside {@link key},
115
+ * **both** must match for redaction to apply (AND logic).
116
+ */
117
+ valuePattern?: RegExp;
118
+ /**
119
+ * Severity level — informational only, used for filtering in summary output.
120
+ * Does not affect whether redaction runs.
121
+ */
122
+ severity?: 'low' | 'medium' | 'high' | 'critical';
123
+ }
124
+ /**
125
+ * Configuration for the step-removal pipeline.
126
+ *
127
+ * Rules are loaded from `ruleFiles` first, then merged with inline `rules`.
128
+ * Duplicate labels result in a warning; the last definition wins.
129
+ */
130
+ export interface RemoveConfig {
131
+ /**
132
+ * Path(s) to external step rule files (.ts, .js, .json).
133
+ * Merged with inline `rules`. No built-in rules apply.
134
+ */
135
+ ruleFiles?: string | string[];
136
+ /**
137
+ * Inline step removal rules. Merged with ruleFiles.
138
+ * These are the only rules that will ever be applied.
139
+ */
140
+ rules?: RemoveRule[];
141
+ /**
142
+ * How to redistribute time after a step is deleted.
143
+ *
144
+ * - `'absorb-into-prev'` *(default)*: the preceding step's `endTime` absorbs the deleted duration.
145
+ * - `'absorb-into-next'`: the following step's `startTime` is shifted back.
146
+ * - `'gap'`: timestamps are not adjusted; a visible gap appears in the timeline.
147
+ */
148
+ timestampStrategy?: TimestampStrategy;
149
+ /**
150
+ * When `true`: log what would be removed per rule, but do not write any files.
151
+ * Default: `false`
152
+ */
153
+ dryRun?: boolean;
154
+ /**
155
+ * What to do with child steps when a parent step is removed.
156
+ *
157
+ * - `'remove-children'` *(default)*: also remove all descendant steps.
158
+ * - `'keep-shell'`: keep the parent as a no-op container without its children.
159
+ */
160
+ orphanStrategy?: 'remove-children' | 'keep-shell';
161
+ }
162
+ /**
163
+ * Controls how the timestamp timeline is repaired after step removal.
164
+ *
165
+ * @see {@link RemoveConfig.timestampStrategy}
166
+ */
167
+ export type TimestampStrategy = 'absorb-into-prev' | 'absorb-into-next' | 'gap';
168
+ /**
169
+ * A single step-matching rule used by the removal pipeline.
170
+ *
171
+ * At least one of {@link stepName}, {@link selector}, {@link url}, or
172
+ * {@link actionType} must be provided. When multiple matchers are set,
173
+ * **all** must match (AND logic) for a step to be removed.
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * // Remove all "waitForTimeout" steps
178
+ * { label: 'timeouts', stepName: /waitForTimeout/ }
179
+ *
180
+ * // Remove network requests to a specific polling endpoint
181
+ * { label: 'health-poll', url: /\/api\/health$/, actionType: 'route' }
182
+ *
183
+ * // Safety guard: only remove if seen 5+ times consecutively
184
+ * { label: 'scroll-noise', actionType: 'scroll', minConsecutiveOccurrences: 5 }
185
+ * ```
186
+ */
187
+ export interface RemoveRule {
188
+ /**
189
+ * REQUIRED. Human-readable label for this rule.
190
+ * Used in summary output, dry-run logs, and safety-guard warnings.
191
+ */
192
+ label: string;
193
+ /**
194
+ * Match against the step/action name as shown in the HTML report.
195
+ *
196
+ * - `string`: case-sensitive substring match
197
+ * - `RegExp`: tested against the step title, action, or method name
198
+ */
199
+ stepName?: string | RegExp;
200
+ /**
201
+ * Match against the CSS selector or XPath locator of a UI step.
202
+ *
203
+ * - `string`: case-sensitive substring match
204
+ * - `RegExp`: tested against the selector string
205
+ */
206
+ selector?: string | RegExp;
207
+ /**
208
+ * Match against the URL of a network request step.
209
+ *
210
+ * - `string`: case-sensitive substring match
211
+ * - `RegExp`: tested against the URL string
212
+ */
213
+ url?: string | RegExp;
214
+ /**
215
+ * Match against the Playwright internal action type from `trace.json`
216
+ * (e.g. `'click'`, `'fill'`, `'route'`, `'waitForSelector'`).
217
+ *
218
+ * - `string`: case-sensitive substring match
219
+ * - `RegExp`: tested against the action type string
220
+ */
221
+ actionType?: string | RegExp;
222
+ /**
223
+ * **SAFETY GUARD** — not an automatic detection threshold.
224
+ *
225
+ * Only remove a matching step if it appears **at least this many times
226
+ * consecutively** within a single test run. If the actual consecutive count
227
+ * is below this threshold, the tool **skips removal** and emits a warning.
228
+ *
229
+ * Use this to protect against accidentally removing legitimate one-off
230
+ * occurrences of a step that also appears in noisy repeating sequences.
231
+ */
232
+ minConsecutiveOccurrences?: number;
233
+ }
234
+ /**
235
+ * Controls where sanitized files are written and which file types are processed.
236
+ */
237
+ export interface OutputConfig {
238
+ /** Directory containing Playwright HTML report files. Default: `'./playwright-report'` */
239
+ reportDir?: string;
240
+ /** Directory containing Playwright test result trace files. Default: `'./test-results'` */
241
+ traceDir?: string;
242
+ /**
243
+ * Output mode.
244
+ *
245
+ * - `'copy'` *(default)*: write sanitized files to {@link dir}, originals untouched.
246
+ * - `'in-place'`: overwrite original files (**destructive** — ensure version control).
247
+ * - `'side-by-side'`: write `<name>.sanitized.<ext>` next to each original.
248
+ */
249
+ mode?: 'copy' | 'in-place' | 'side-by-side';
250
+ /** Destination directory when {@link mode} is `'copy'`. Default: `'./sanitized-report'` */
251
+ dir?: string;
252
+ /** Whether to process HTML reports. Default: `true` */
253
+ processReports?: boolean;
254
+ /** Whether to process trace `.zip` files. Default: `true` */
255
+ processTraces?: boolean;
256
+ /**
257
+ * Whether to attempt screenshot redaction in trace files.
258
+ * Requires the optional `sharp` peer dependency.
259
+ * Default: `false`
260
+ */
261
+ redactScreenshots?: boolean;
262
+ }
263
+ /**
264
+ * Controls summary output and log verbosity.
265
+ */
266
+ export interface ReportingConfig {
267
+ /** Print a summary table to stdout after processing. Default: `true` */
268
+ summary?: boolean;
269
+ /** Write the summary as JSON to this file path. Optional. */
270
+ summaryFile?: string;
271
+ /**
272
+ * Log verbosity level.
273
+ *
274
+ * - `'silent'` — no output at all
275
+ * - `'normal'` — info, warnings, and errors (default)
276
+ * - `'verbose'` — everything including per-step traces
277
+ */
278
+ logLevel?: 'silent' | 'normal' | 'verbose';
279
+ }
280
+ /**
281
+ * A single event entry from a Playwright `trace.json` or HTML report step list.
282
+ *
283
+ * Fields are a superset of what Playwright may emit — not all fields are present
284
+ * on every event type. Extra fields are preserved via the index signature.
285
+ */
286
+ export interface TraceEvent {
287
+ /** Playwright internal event type (e.g. `'action'`, `'event'`). */
288
+ type?: string;
289
+ /** Human-readable action name (e.g. `'click'`, `'fill'`). */
290
+ action?: string;
291
+ /** API method name for protocol-level events. */
292
+ method?: string;
293
+ /** Arbitrary parameters attached to the event. */
294
+ params?: Record<string, unknown>;
295
+ /** Unix timestamp (ms) when the event started. */
296
+ startTime: number;
297
+ /** Unix timestamp (ms) when the event ended. */
298
+ endTime: number;
299
+ /** Display title shown in the Playwright report UI. */
300
+ title?: string;
301
+ /** CSS selector or XPath locator targeted by the action. */
302
+ selector?: string;
303
+ /** URL associated with a network request step. */
304
+ url?: string;
305
+ /** Playwright action type string used for internal classification. */
306
+ actionType?: string;
307
+ /** `callId` of the parent step, used to reconstruct the tree hierarchy. */
308
+ parentId?: string;
309
+ /** Unique identifier for this step within the trace. */
310
+ callId?: string;
311
+ /** Nested child steps (tree representation). */
312
+ children?: TraceEvent[];
313
+ /** Network request ID, used to correlate trace steps with `network.json` entries. */
314
+ requestId?: string;
315
+ /** Catch-all for any additional fields Playwright may add. */
316
+ [key: string]: unknown;
317
+ }
318
+ /**
319
+ * Result of attempting to redact a single string value.
320
+ */
321
+ export interface RedactionResult {
322
+ /** `true` if a pattern matched and the value was replaced. */
323
+ redacted: boolean;
324
+ /** The (potentially replaced) value. Equal to the input when `redacted` is `false`. */
325
+ value: string;
326
+ /** ID of the pattern that triggered redaction. `undefined` when `redacted` is `false`. */
327
+ matchedPatternId?: string;
328
+ }
329
+ /**
330
+ * Records where a redaction occurred within the JSON tree.
331
+ */
332
+ export interface RedactionMatch {
333
+ /** Dot-notation path to the redacted field (e.g. `'request.headers.authorization'`). */
334
+ keyPath: string;
335
+ /** ID of the {@link RedactPattern} that matched. */
336
+ patternId: string;
337
+ }
338
+ /**
339
+ * Aggregated result from a full `walkAndRedact` traversal.
340
+ */
341
+ export interface WalkResult {
342
+ /** The transformed JSON tree (new object, input is never mutated). */
343
+ result: unknown;
344
+ /** Total number of individual values that were redacted. */
345
+ count: number;
346
+ /** Detailed list of every redaction that occurred. */
347
+ matches: RedactionMatch[];
348
+ }
349
+ /**
350
+ * A single step that was matched by a removal rule.
351
+ */
352
+ export interface StepMatch {
353
+ /** Zero-based index of the step in the flat events array. */
354
+ index: number;
355
+ /** Label of the {@link RemoveRule} that matched this step. */
356
+ ruleLabel: string;
357
+ /** The matched {@link TraceEvent} object. */
358
+ event: TraceEvent;
359
+ }
360
+ /**
361
+ * The set of steps identified for removal across all rules.
362
+ */
363
+ export interface RemovalSet {
364
+ /** Deduplicated set of event indices to remove. */
365
+ indices: Set<number>;
366
+ /** Detailed list of every match (one entry per step per rule). */
367
+ matches: StepMatch[];
368
+ }
369
+ /**
370
+ * Processing result for a single file (HTML report or trace `.zip`).
371
+ */
372
+ export interface ProcessResult {
373
+ /** Absolute path of the input file. */
374
+ file: string;
375
+ /** Number of individual value redactions applied. */
376
+ redactionsApplied: number;
377
+ /** Number of top-level steps removed (children excluded from count). */
378
+ stepsRemoved: number;
379
+ /** Number of timestamp adjustments made after step removal. */
380
+ timestampRepairs: number;
381
+ /** Detailed list of every redaction match. */
382
+ redactionMatches: RedactionMatch[];
383
+ /** Detailed list of every step-removal match. */
384
+ removalMatches: StepMatch[];
385
+ }
386
+ /**
387
+ * Aggregated statistics produced after processing all files.
388
+ * Returned by {@link generateSummary} and optionally written to disk as JSON.
389
+ */
390
+ export interface SanitizationSummary {
391
+ /** ISO-8601 timestamp of when processing completed. */
392
+ processedAt: string;
393
+ /** Count of HTML reports and trace files processed. */
394
+ filesProcessed: {
395
+ reports: number;
396
+ traces: number;
397
+ };
398
+ /** Redaction statistics. */
399
+ redact: {
400
+ /** Number of distinct patterns that were loaded. */
401
+ patternsLoaded: number;
402
+ /** Total number of value occurrences replaced across all files. */
403
+ totalOccurrencesReplaced: number;
404
+ /** Per-pattern occurrence counts, keyed by pattern `id`. */
405
+ byPatternId: Record<string, number>;
406
+ };
407
+ /** Step-removal statistics. */
408
+ remove: {
409
+ /** Number of distinct rules that were loaded. */
410
+ rulesLoaded: number;
411
+ /** Total number of steps deleted across all files. */
412
+ totalStepsDeleted: number;
413
+ /** Number of timestamp adjustments applied. */
414
+ timestampRepairs: number;
415
+ /** The {@link TimestampStrategy} that was used. */
416
+ timestampStrategy: string;
417
+ /** Per-rule removal counts. */
418
+ byRuleLabel: Array<{
419
+ label: string;
420
+ count: number;
421
+ files: number;
422
+ }>;
423
+ /** Safety-guard warning messages emitted during processing. */
424
+ safetyGuardWarnings: string[];
425
+ };
426
+ /** Output mode and destination directory. */
427
+ output: {
428
+ mode: string;
429
+ dir: string;
430
+ };
431
+ }
432
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // ─────────────────────────────────────────────
3
+ // Top-level config
4
+ // ─────────────────────────────────────────────
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,mBAAmB;AACnB,gDAAgD"}
@@ -0,0 +1,34 @@
1
+ import type { SanitizerConfig, RedactPattern, RemoveRule } from './types.js';
2
+ /**
3
+ * Validates that the config is structurally correct and has meaningful content.
4
+ *
5
+ * Checks that at least one of `redact` or `remove` contains actionable
6
+ * patterns / rules, then validates each pattern and rule individually.
7
+ * Any violation calls `logger.fatal` which throws immediately.
8
+ *
9
+ * @param config - The {@link SanitizerConfig} to validate.
10
+ * @throws Calls `logger.fatal` (which throws) for any validation failure.
11
+ */
12
+ export declare function validateConfig(config: SanitizerConfig): void;
13
+ /**
14
+ * Validates a single {@link RedactPattern}.
15
+ *
16
+ * Ensures that at least one of `key` or `valuePattern` is defined — a pattern
17
+ * with neither matcher would match nothing and is almost certainly a mistake.
18
+ *
19
+ * @param pattern - The pattern to validate.
20
+ * @throws Calls `logger.fatal` (which throws) if the pattern has no matchers.
21
+ */
22
+ export declare function validatePattern(pattern: RedactPattern): void;
23
+ /**
24
+ * Validates a single {@link RemoveRule}.
25
+ *
26
+ * Ensures that at least one matcher field (`stepName`, `selector`, `url`, or
27
+ * `actionType`) is defined — a rule with no matchers would match every step,
28
+ * which is almost certainly unintentional.
29
+ *
30
+ * @param rule - The rule to validate.
31
+ * @throws Calls `logger.fatal` (which throws) if the rule has no matchers.
32
+ */
33
+ export declare function validateRule(rule: RemoveRule): void;
34
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/config/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7E;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAqB5D;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAM5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAMnD"}