@cubenest/rrweb-core 0.1.0-alpha.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 (135) hide show
  1. package/NOTICE +15 -0
  2. package/README.md +26 -0
  3. package/dist/compat/index.d.ts +37 -0
  4. package/dist/compat/index.d.ts.map +1 -0
  5. package/dist/compat/index.js +97 -0
  6. package/dist/compat/index.js.map +1 -0
  7. package/dist/compression/index.d.ts +24 -0
  8. package/dist/compression/index.d.ts.map +1 -0
  9. package/dist/compression/index.js +61 -0
  10. package/dist/compression/index.js.map +1 -0
  11. package/dist/console/buffer.d.ts +99 -0
  12. package/dist/console/buffer.d.ts.map +1 -0
  13. package/dist/console/buffer.js +169 -0
  14. package/dist/console/buffer.js.map +1 -0
  15. package/dist/console/index.d.ts +3 -0
  16. package/dist/console/index.d.ts.map +1 -0
  17. package/dist/console/index.js +16 -0
  18. package/dist/console/index.js.map +1 -0
  19. package/dist/console/types.d.ts +61 -0
  20. package/dist/console/types.d.ts.map +1 -0
  21. package/dist/console/types.js +11 -0
  22. package/dist/console/types.js.map +1 -0
  23. package/dist/index.d.ts +17 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +18 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/masking/body.d.ts +30 -0
  28. package/dist/masking/body.d.ts.map +1 -0
  29. package/dist/masking/body.js +33 -0
  30. package/dist/masking/body.js.map +1 -0
  31. package/dist/masking/headers.d.ts +16 -0
  32. package/dist/masking/headers.d.ts.map +1 -0
  33. package/dist/masking/headers.js +46 -0
  34. package/dist/masking/headers.js.map +1 -0
  35. package/dist/masking/index.d.ts +8 -0
  36. package/dist/masking/index.d.ts.map +1 -0
  37. package/dist/masking/index.js +11 -0
  38. package/dist/masking/index.js.map +1 -0
  39. package/dist/masking/inputs.d.ts +15 -0
  40. package/dist/masking/inputs.d.ts.map +1 -0
  41. package/dist/masking/inputs.js +36 -0
  42. package/dist/masking/inputs.js.map +1 -0
  43. package/dist/masking/regex.d.ts +96 -0
  44. package/dist/masking/regex.d.ts.map +1 -0
  45. package/dist/masking/regex.js +182 -0
  46. package/dist/masking/regex.js.map +1 -0
  47. package/dist/masking/selectors.d.ts +67 -0
  48. package/dist/masking/selectors.d.ts.map +1 -0
  49. package/dist/masking/selectors.js +137 -0
  50. package/dist/masking/selectors.js.map +1 -0
  51. package/dist/masking/text.d.ts +9 -0
  52. package/dist/masking/text.d.ts.map +1 -0
  53. package/dist/masking/text.js +15 -0
  54. package/dist/masking/text.js.map +1 -0
  55. package/dist/network/cdp.d.ts +54 -0
  56. package/dist/network/cdp.d.ts.map +1 -0
  57. package/dist/network/cdp.js +282 -0
  58. package/dist/network/cdp.js.map +1 -0
  59. package/dist/network/index.d.ts +4 -0
  60. package/dist/network/index.d.ts.map +1 -0
  61. package/dist/network/index.js +14 -0
  62. package/dist/network/index.js.map +1 -0
  63. package/dist/network/types.d.ts +133 -0
  64. package/dist/network/types.d.ts.map +1 -0
  65. package/dist/network/types.js +35 -0
  66. package/dist/network/types.js.map +1 -0
  67. package/dist/network/web-request.d.ts +76 -0
  68. package/dist/network/web-request.d.ts.map +1 -0
  69. package/dist/network/web-request.js +294 -0
  70. package/dist/network/web-request.js.map +1 -0
  71. package/dist/persistence/index.d.ts +3 -0
  72. package/dist/persistence/index.d.ts.map +1 -0
  73. package/dist/persistence/index.js +11 -0
  74. package/dist/persistence/index.js.map +1 -0
  75. package/dist/persistence/store.d.ts +18 -0
  76. package/dist/persistence/store.d.ts.map +1 -0
  77. package/dist/persistence/store.js +327 -0
  78. package/dist/persistence/store.js.map +1 -0
  79. package/dist/persistence/types.d.ts +76 -0
  80. package/dist/persistence/types.d.ts.map +1 -0
  81. package/dist/persistence/types.js +21 -0
  82. package/dist/persistence/types.js.map +1 -0
  83. package/dist/rrweb.d.ts +5 -0
  84. package/dist/rrweb.d.ts.map +1 -0
  85. package/dist/rrweb.js +13 -0
  86. package/dist/rrweb.js.map +1 -0
  87. package/dist/screenshot/base64.d.ts +8 -0
  88. package/dist/screenshot/base64.d.ts.map +1 -0
  89. package/dist/screenshot/base64.js +21 -0
  90. package/dist/screenshot/base64.js.map +1 -0
  91. package/dist/screenshot/cdp.d.ts +50 -0
  92. package/dist/screenshot/cdp.d.ts.map +1 -0
  93. package/dist/screenshot/cdp.js +65 -0
  94. package/dist/screenshot/cdp.js.map +1 -0
  95. package/dist/screenshot/index.d.ts +4 -0
  96. package/dist/screenshot/index.d.ts.map +1 -0
  97. package/dist/screenshot/index.js +10 -0
  98. package/dist/screenshot/index.js.map +1 -0
  99. package/dist/screenshot/tabs.d.ts +44 -0
  100. package/dist/screenshot/tabs.d.ts.map +1 -0
  101. package/dist/screenshot/tabs.js +63 -0
  102. package/dist/screenshot/tabs.js.map +1 -0
  103. package/dist/screenshot/types.d.ts +27 -0
  104. package/dist/screenshot/types.d.ts.map +1 -0
  105. package/dist/screenshot/types.js +18 -0
  106. package/dist/screenshot/types.js.map +1 -0
  107. package/dist/shadow-dom/index.d.ts +3 -0
  108. package/dist/shadow-dom/index.d.ts.map +1 -0
  109. package/dist/shadow-dom/index.js +8 -0
  110. package/dist/shadow-dom/index.js.map +1 -0
  111. package/dist/shadow-dom/traverse.d.ts +54 -0
  112. package/dist/shadow-dom/traverse.d.ts.map +1 -0
  113. package/dist/shadow-dom/traverse.js +209 -0
  114. package/dist/shadow-dom/traverse.js.map +1 -0
  115. package/dist/shadow-dom/types.d.ts +43 -0
  116. package/dist/shadow-dom/types.d.ts.map +1 -0
  117. package/dist/shadow-dom/types.js +25 -0
  118. package/dist/shadow-dom/types.js.map +1 -0
  119. package/dist/throttling/apply.d.ts +59 -0
  120. package/dist/throttling/apply.d.ts.map +1 -0
  121. package/dist/throttling/apply.js +101 -0
  122. package/dist/throttling/apply.js.map +1 -0
  123. package/dist/throttling/defaults.d.ts +60 -0
  124. package/dist/throttling/defaults.d.ts.map +1 -0
  125. package/dist/throttling/defaults.js +81 -0
  126. package/dist/throttling/defaults.js.map +1 -0
  127. package/dist/throttling/guards.d.ts +69 -0
  128. package/dist/throttling/guards.d.ts.map +1 -0
  129. package/dist/throttling/guards.js +212 -0
  130. package/dist/throttling/guards.js.map +1 -0
  131. package/dist/throttling/index.d.ts +5 -0
  132. package/dist/throttling/index.d.ts.map +1 -0
  133. package/dist/throttling/index.js +11 -0
  134. package/dist/throttling/index.js.map +1 -0
  135. package/package.json +35 -0
@@ -0,0 +1,61 @@
1
+ import type { LogLevel as PluginLogLevel } from '@rrweb/rrweb-plugin-console-record';
2
+ /**
3
+ * The full set of console levels the upstream plugin can emit. The plugin's
4
+ * default level list is much broader than the typical `log/info/warn/error`
5
+ * quartet — it patches every `console.*` shape it knows about, including
6
+ * `assert`, `count`, `dir`, `group`, `table`, `time*`, and `trace`. We
7
+ * re-export the union here so consumers can declare-and-pass without
8
+ * importing from the vendor package directly.
9
+ *
10
+ * Default level list (from the plugin source) is:
11
+ * `assert, clear, count, countReset, debug, dir, dirxml, error, group,
12
+ * groupCollapsed, groupEnd, info, log, table, time, timeEnd, timeLog,
13
+ * trace, warn`.
14
+ */
15
+ export type ConsoleLevel = PluginLogLevel;
16
+ /**
17
+ * The narrower set of "log-shaped" console levels that carry meaningful
18
+ * `args` payloads in practice — these are the ones most P1/P2 surfaces
19
+ * render. Other levels (`group`, `time*`, `count*`, etc.) still flow
20
+ * through the buffer untouched, but consumers that only want
21
+ * triage-relevant entries typically filter to this subset.
22
+ */
23
+ export type BasicConsoleLevel = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'trace';
24
+ /**
25
+ * A captured console event with the shape downstream consumers see after the
26
+ * rrweb plugin emits and our buffer normalizes it. Mirrors the plugin's
27
+ * `LogData` shape (`{ level, trace, payload: string[] }`) but renames the
28
+ * args array (`payload` → `args`) so consumers don't have to disambiguate
29
+ * the two `payload` fields in the raw rrweb plugin event.
30
+ *
31
+ * Field-by-field mapping vs the plugin's `LogData`:
32
+ * - `level` ← `LogData.level` (verbatim)
33
+ * - `args` ← `LogData.payload` (renamed for clarity)
34
+ * - `trace` ← `LogData.trace` (verbatim; only populated when
35
+ * non-empty — see buffer.ts)
36
+ * - `ts` ← the surrounding rrweb event's `timestamp`
37
+ */
38
+ export interface ConsoleEvent {
39
+ /** Wall-clock time (ms since epoch) the rrweb engine stamped the event. */
40
+ ts: number;
41
+ /**
42
+ * Console level the plugin observed. See `ConsoleLevel` for the full
43
+ * vocabulary; most consumers will filter to `BasicConsoleLevel`.
44
+ */
45
+ level: ConsoleLevel;
46
+ /**
47
+ * Stringified arguments. Already truncated by the plugin per
48
+ * `stringifyOptions.stringLengthLimit` / `numOfKeysLimit` /
49
+ * `depthOfLimit` — we don't re-serialize.
50
+ */
51
+ args: string[];
52
+ /**
53
+ * Stack trace lines if the plugin captured them. The plugin populates
54
+ * this for every patched call (it calls `ErrorStackParser.parse(new
55
+ * Error())` and drops the first frame), but the buffer only retains
56
+ * it when non-empty so consumers can use `trace !== undefined` as a
57
+ * meaningful signal.
58
+ */
59
+ trace?: string[];
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/console/types.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEtF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,KAAK,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB"}
@@ -0,0 +1,11 @@
1
+ // Console capture types — Task 1.8.
2
+ //
3
+ // Public-facing shapes for the console capture buffer. The buffer normalizes
4
+ // the upstream `@rrweb/rrweb-plugin-console-record` `LogData` payload
5
+ // (`{ level, trace: string[], payload: string[] }`) into a stable
6
+ // `ConsoleEvent` with our own field names so downstream consumers (P1 report
7
+ // renderer, P2 MCP tool surface) don't bind to vendor field names that
8
+ // happen to collide (the plugin uses `payload` for the args array, which
9
+ // makes call sites like `event.data.payload.payload` impossible to read).
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/console/types.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,6EAA6E;AAC7E,sEAAsE;AACtE,kEAAkE;AAClE,6EAA6E;AAC7E,uEAAuE;AACvE,yEAAyE;AACzE,0EAA0E"}
@@ -0,0 +1,17 @@
1
+ export { record, Replayer, getRecordConsolePlugin, EventType, IncrementalSource, MouseInteractions, } from './rrweb';
2
+ export type { eventWithTime, customEvent, recordOptions, } from './rrweb';
3
+ export { maskInputValue, maskTextContent, redactNetworkHeaders, redactBody, COMPAT_SELECTORS, } from './masking';
4
+ export { LARGE_DOM_DEFAULTS, applyLargeDomGuards } from './throttling';
5
+ export type { ApplyLargeDomGuardsOptions } from './throttling';
6
+ export { traverseShadowRoots } from './shadow-dom';
7
+ export type { ShadowRootInfo } from './shadow-dom';
8
+ export type { ScreenshotAdapter } from './screenshot';
9
+ export { createCDPScreenshotAdapter, createTabsScreenshotAdapter, type CDPTransport, type CDPScreenshotOptions, type CaptureVisibleTabFn, type TabsScreenshotOptions, } from './screenshot';
10
+ export type { CapturedRequest, CapturedResponse, NetworkCaptureAdapter } from './network';
11
+ export { createCDPNetworkAdapter, createWebRequestNetworkAdapter, type CDPNetworkEventSource, type CDPNetworkOptions, type WebRequestEvent, type WebRequestEventSource, type WebRequestNetworkOptions, } from './network';
12
+ export { createConsoleCaptureBuffer, type BasicConsoleLevel, type ConsoleCaptureBuffer, type ConsoleCaptureOptions, type ConsoleEvent, type ConsoleLevel, } from './console';
13
+ export { compress, decompress } from './compression';
14
+ export { createSessionStore } from './persistence';
15
+ export type { SessionChunk, SessionStore, SessionStoreOptions } from './persistence';
16
+ export { COMPATIBILITY_MATRIX, type CompatEntry } from './compat';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,sBAAsB,EACtB,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,aAAa,EACb,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EACL,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,0BAA0B,EAC1B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGrF,OAAO,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ export { record, Replayer, getRecordConsolePlugin, EventType, IncrementalSource, MouseInteractions, } from './rrweb';
2
+ // Masking
3
+ export { maskInputValue, maskTextContent, redactNetworkHeaders, redactBody, COMPAT_SELECTORS, } from './masking';
4
+ // Throttling defaults + guards
5
+ export { LARGE_DOM_DEFAULTS, applyLargeDomGuards } from './throttling';
6
+ // Shadow DOM
7
+ export { traverseShadowRoots } from './shadow-dom';
8
+ export { createCDPScreenshotAdapter, createTabsScreenshotAdapter, } from './screenshot';
9
+ export { createCDPNetworkAdapter, createWebRequestNetworkAdapter, } from './network';
10
+ // Console capture buffer
11
+ export { createConsoleCaptureBuffer, } from './console';
12
+ // Compression helpers (gzip per-batch via fflate)
13
+ export { compress, decompress } from './compression';
14
+ // IndexedDB persistence helper
15
+ export { createSessionStore } from './persistence';
16
+ // Compatibility matrix
17
+ export { COMPATIBILITY_MATRIX } from './compat';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,sBAAsB,EACtB,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAQjB,UAAU;AACV,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,+BAA+B;AAC/B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGvE,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKnD,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,GAK5B,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,uBAAuB,EACvB,8BAA8B,GAM/B,MAAM,WAAW,CAAC;AAEnB,yBAAyB;AACzB,OAAO,EACL,0BAA0B,GAM3B,MAAM,WAAW,CAAC;AAEnB,kDAAkD;AAClD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAErD,+BAA+B;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,uBAAuB;AACvB,OAAO,EAAE,oBAAoB,EAAoB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface RedactBodyOptions {
2
+ /**
3
+ * Hard cap on returned body length (post-redaction, pre-truncation
4
+ * suffix). Defaults to 1 MB. Sizes here are JavaScript string lengths
5
+ * (UTF-16 code units), which is a close-enough proxy for transport
6
+ * bytes in this layer; consumers needing exact byte semantics can
7
+ * pre-encode and pass the resulting string.
8
+ */
9
+ maxLengthBytes?: number;
10
+ }
11
+ /**
12
+ * Redact a network or DOM body string by:
13
+ * 1. Truncating to `maxLengthBytes` if longer (we trim FIRST so the regex
14
+ * bank never has to scan more than `max` characters — bounds the cost
15
+ * and prevents worst-case backtracking on huge inputs).
16
+ * 2. Running the (possibly-truncated) prefix through the PII regex bank
17
+ * (Luhn-validated credit cards, SSNs, JWTs, API keys, email, phone,
18
+ * PEM blocks).
19
+ * 3. Appending the truncation suffix with the dropped byte count.
20
+ *
21
+ * Caveat: a multi-megabyte PEM block split across the truncation boundary
22
+ * won't be redacted as a PEM. Acceptable — that's already a degenerate
23
+ * input shape and the head/tail markers stay visible enough for human
24
+ * review.
25
+ *
26
+ * Operates purely on strings — no DOM required, no environment coupling.
27
+ * Safe to use in service workers, Node, and tests.
28
+ */
29
+ export declare function redactBody(body: string, opts?: RedactBodyOptions): string;
30
+ //# sourceMappingURL=body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../src/masking/body.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,MAAM,CAS7E"}
@@ -0,0 +1,33 @@
1
+ // Network/payload body redaction.
2
+ import { applyRegexBank } from './regex';
3
+ const DEFAULT_MAX_LENGTH_BYTES = 1024 * 1024; // 1 MB
4
+ const TRUNCATION_SUFFIX = (more) => `... [TRUNCATED ${more} more bytes]`;
5
+ /**
6
+ * Redact a network or DOM body string by:
7
+ * 1. Truncating to `maxLengthBytes` if longer (we trim FIRST so the regex
8
+ * bank never has to scan more than `max` characters — bounds the cost
9
+ * and prevents worst-case backtracking on huge inputs).
10
+ * 2. Running the (possibly-truncated) prefix through the PII regex bank
11
+ * (Luhn-validated credit cards, SSNs, JWTs, API keys, email, phone,
12
+ * PEM blocks).
13
+ * 3. Appending the truncation suffix with the dropped byte count.
14
+ *
15
+ * Caveat: a multi-megabyte PEM block split across the truncation boundary
16
+ * won't be redacted as a PEM. Acceptable — that's already a degenerate
17
+ * input shape and the head/tail markers stay visible enough for human
18
+ * review.
19
+ *
20
+ * Operates purely on strings — no DOM required, no environment coupling.
21
+ * Safe to use in service workers, Node, and tests.
22
+ */
23
+ export function redactBody(body, opts = {}) {
24
+ const max = opts.maxLengthBytes ?? DEFAULT_MAX_LENGTH_BYTES;
25
+ if (body.length === 0)
26
+ return body;
27
+ if (body.length <= max)
28
+ return applyRegexBank(body);
29
+ const head = body.slice(0, max);
30
+ const dropped = body.length - max;
31
+ return `${applyRegexBank(head)}${TRUNCATION_SUFFIX(dropped)}`;
32
+ }
33
+ //# sourceMappingURL=body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/masking/body.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,wBAAwB,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO;AACrD,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,kBAAkB,IAAI,cAAc,CAAC;AAazF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,OAA0B,EAAE;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,IAAI,wBAAwB,CAAC;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAEpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;IAClC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;AAChE,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Redact sensitive headers in place-of in a record. Input is a plain
3
+ * `Record<string, string>` (the lowest common denominator between fetch
4
+ * `Headers`, Node's `IncomingMessage.headers`, and webRequest's
5
+ * `chrome.webRequest.HttpHeader[]` after normalization).
6
+ *
7
+ * Non-deny-list headers are returned unchanged. Header *names* are
8
+ * preserved with their original casing; only *values* on the deny-list
9
+ * are replaced with `<<REDACTED>>`.
10
+ *
11
+ * @example
12
+ * redactNetworkHeaders({ Authorization: 'Bearer abc', Accept: 'json' })
13
+ * // -> { Authorization: '<<REDACTED>>', Accept: 'json' }
14
+ */
15
+ export declare function redactNetworkHeaders(headers: Record<string, string>): Record<string, string>;
16
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/masking/headers.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU5F"}
@@ -0,0 +1,46 @@
1
+ // Network header redaction. Case-insensitive deny-list per
2
+ // IMPLEMENTATION_PLAN.md Task 1.3 and P2 PRD §D.2.
3
+ /**
4
+ * Headers always redacted, regardless of casing. Lowercased here so
5
+ * comparisons can be a single `.toLowerCase()` on the caller side.
6
+ *
7
+ * Per plan: `authorization`, `cookie`, `set-cookie`, `x-api-key`,
8
+ * `x-csrf-token`, `x-real-ip`, `proxy-authorization`.
9
+ */
10
+ const DENY_LIST = new Set([
11
+ 'authorization',
12
+ 'cookie',
13
+ 'set-cookie',
14
+ 'x-api-key',
15
+ 'x-csrf-token',
16
+ 'x-real-ip',
17
+ 'proxy-authorization',
18
+ ]);
19
+ const REDACTED_VALUE = '<<REDACTED>>';
20
+ /**
21
+ * Redact sensitive headers in place-of in a record. Input is a plain
22
+ * `Record<string, string>` (the lowest common denominator between fetch
23
+ * `Headers`, Node's `IncomingMessage.headers`, and webRequest's
24
+ * `chrome.webRequest.HttpHeader[]` after normalization).
25
+ *
26
+ * Non-deny-list headers are returned unchanged. Header *names* are
27
+ * preserved with their original casing; only *values* on the deny-list
28
+ * are replaced with `<<REDACTED>>`.
29
+ *
30
+ * @example
31
+ * redactNetworkHeaders({ Authorization: 'Bearer abc', Accept: 'json' })
32
+ * // -> { Authorization: '<<REDACTED>>', Accept: 'json' }
33
+ */
34
+ export function redactNetworkHeaders(headers) {
35
+ const out = {};
36
+ for (const [name, value] of Object.entries(headers)) {
37
+ if (DENY_LIST.has(name.toLowerCase())) {
38
+ out[name] = REDACTED_VALUE;
39
+ }
40
+ else {
41
+ out[name] = value;
42
+ }
43
+ }
44
+ return out;
45
+ }
46
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/masking/headers.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,mDAAmD;AAEnD;;;;;;GAMG;AACH,MAAM,SAAS,GAAwB,IAAI,GAAG,CAAC;IAC7C,eAAe;IACf,QAAQ;IACR,YAAY;IACZ,WAAW;IACX,cAAc;IACd,WAAW;IACX,qBAAqB;CACtB,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA+B;IAClE,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { maskInputValue } from './inputs';
2
+ export { maskTextContent } from './text';
3
+ export { redactNetworkHeaders } from './headers';
4
+ export { redactBody } from './body';
5
+ export type { RedactBodyOptions } from './body';
6
+ export { COMPAT_SELECTORS } from './selectors';
7
+ export type { CompatSelectorFamily } from './selectors';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/masking/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,11 @@
1
+ // Public barrel for the masking module.
2
+ //
3
+ // Locked surface per IMPLEMENTATION_PLAN.md Public API contract
4
+ // (lines 691-693): the four functions below plus `COMPAT_SELECTORS`. The
5
+ // internals (regex bank, individual matchers, helpers) stay internal.
6
+ export { maskInputValue } from './inputs';
7
+ export { maskTextContent } from './text';
8
+ export { redactNetworkHeaders } from './headers';
9
+ export { redactBody } from './body';
10
+ export { COMPAT_SELECTORS } from './selectors';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/masking/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,gEAAgE;AAChE,yEAAyE;AACzE,sEAAsE;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Return the maskable representation of an input's value.
3
+ *
4
+ * 1. If `type` is password/email/tel: return all `*` of the same length
5
+ * (hard mask; no opt-out).
6
+ * 2. Else if the element or any ancestor carries a mask/block class or
7
+ * Datadog privacy attribute: return all `*` of the same length.
8
+ * 3. Else: return the actual value.
9
+ *
10
+ * The asterisk-of-same-length convention matches PostHog/Sentry; the
11
+ * length leak is intentional so replay still shows "something was typed
12
+ * here" without revealing what.
13
+ */
14
+ export declare function maskInputValue(el: HTMLInputElement | HTMLTextAreaElement): string;
15
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/masking/inputs.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,MAAM,CAgBjF"}
@@ -0,0 +1,36 @@
1
+ // Input-element value masking.
2
+ import { elementMatchesAnyMaskClass } from './selectors';
3
+ /**
4
+ * Hard-masked input types — always returned as asterisks regardless of
5
+ * surrounding selectors, parent attributes, or config. This is the privacy
6
+ * floor: even if every other guard misconfigures, a password field's
7
+ * value never leaves the device.
8
+ */
9
+ const HARD_MASKED_TYPES = new Set(['password', 'email', 'tel']);
10
+ /**
11
+ * Return the maskable representation of an input's value.
12
+ *
13
+ * 1. If `type` is password/email/tel: return all `*` of the same length
14
+ * (hard mask; no opt-out).
15
+ * 2. Else if the element or any ancestor carries a mask/block class or
16
+ * Datadog privacy attribute: return all `*` of the same length.
17
+ * 3. Else: return the actual value.
18
+ *
19
+ * The asterisk-of-same-length convention matches PostHog/Sentry; the
20
+ * length leak is intentional so replay still shows "something was typed
21
+ * here" without revealing what.
22
+ */
23
+ export function maskInputValue(el) {
24
+ const value = el.value ?? '';
25
+ // `type` only exists on HTMLInputElement; textareas always fall through
26
+ // to the class/attribute check.
27
+ const type = 'type' in el && typeof el.type === 'string' ? el.type.toLowerCase() : '';
28
+ if (HARD_MASKED_TYPES.has(type)) {
29
+ return '*'.repeat(value.length);
30
+ }
31
+ if (elementMatchesAnyMaskClass(el)) {
32
+ return '*'.repeat(value.length);
33
+ }
34
+ return value;
35
+ }
36
+ //# sourceMappingURL=inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.js","sourceRoot":"","sources":["../../src/masking/inputs.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAA0C;IACvE,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;IAE7B,wEAAwE;IACxE,gCAAgC;IAChC,MAAM,IAAI,GAAG,MAAM,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtF,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,0BAA0B,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Email — RFC 5322 "lite". Matches the overwhelming majority of real-world
3
+ * addresses without trying to model the full grammar (which permits quoted
4
+ * locals and comments most senders never use).
5
+ *
6
+ * Quantifier caps (`{1,64}`/`{1,255}`/`{2,24}`) are intentional: the spec
7
+ * lets local-parts run to 64 chars and the full address to 254, so the
8
+ * caps are not under-matching real addresses. They DO bound backtracking
9
+ * cost — unbounded `+` here is catastrophic on large no-`@` inputs (a
10
+ * megabyte of `a`s would quadratically backtrack at every start position).
11
+ *
12
+ * False-positive surface: strings like `a@b.co` where the TLD is short
13
+ * will match. Acceptable — we'd rather over-redact emails.
14
+ */
15
+ export declare const EMAIL_REGEX: RegExp;
16
+ /**
17
+ * US Social Security Number — `NNN-NN-NNNN`. We intentionally require the
18
+ * dashes; the dash-less 9-digit form collides with too many legitimate
19
+ * identifiers (order numbers, zip+4, etc).
20
+ */
21
+ export declare const SSN_REGEX: RegExp;
22
+ /**
23
+ * Credit-card candidate — 13-19 contiguous digits with optional separators
24
+ * (spaces or dashes). Match alone is NOT enough; callers MUST pass each
25
+ * match through {@link luhn} before treating it as a real card number.
26
+ *
27
+ * Prefixes we expect to catch (validated by Luhn after the fact):
28
+ * Visa 4xxx
29
+ * Mastercard 5xxx, 2221-2720
30
+ * Amex 34xx, 37xx (15 digits)
31
+ * Discover 6011, 65, 644-649 (16 digits)
32
+ *
33
+ * The `(?:[ -]?\d){12,18}` shape is anchored on a leading digit and only
34
+ * matches 13-19 total digits — bounded width means linear-time matching.
35
+ *
36
+ * False-positive surface without Luhn: phone numbers, account numbers,
37
+ * arbitrary 16-digit strings. Luhn cuts that to near-zero.
38
+ */
39
+ export declare const CREDIT_CARD_REGEX: RegExp;
40
+ /**
41
+ * Phone — international-ish (E.164-friendly). Permissive on separators.
42
+ *
43
+ * False-positive surface: large numeric runs with separators (e.g. some
44
+ * timestamps, account numbers with dashes). We accept this; callers route
45
+ * to `<<REDACTED:PHONE>>` so the AI consumer knows the redaction type and
46
+ * can choose to ignore it if context suggests not-a-phone.
47
+ */
48
+ export declare const PHONE_REGEX: RegExp;
49
+ /**
50
+ * JWT — three base64url segments separated by `.`. The 10-char minimum on
51
+ * each segment screens out very short look-alikes (e.g. `eyJ.a.b`).
52
+ * Upper bound of 4096 per segment is generous (RFC 7519 doesn't set one;
53
+ * real-world JWTs rarely exceed ~2 KB total) and keeps the regex linear.
54
+ */
55
+ export declare const JWT_REGEX: RegExp;
56
+ /**
57
+ * Stripe secret/publishable keys — `sk_live_*`, `sk_test_*`, `pk_live_*`,
58
+ * `pk_test_*` with 24-128 chars of payload (real keys are ~99 chars but
59
+ * the cap protects against pathological inputs).
60
+ */
61
+ export declare const STRIPE_KEY_REGEX: RegExp;
62
+ /**
63
+ * GitHub personal-access tokens — `ghp_` prefix + 36 chars.
64
+ */
65
+ export declare const GITHUB_TOKEN_REGEX: RegExp;
66
+ /**
67
+ * AWS access key IDs — `AKIA` prefix + 16 uppercase-alnum chars.
68
+ */
69
+ export declare const AWS_ACCESS_KEY_REGEX: RegExp;
70
+ /**
71
+ * PEM blocks — anything between `-----BEGIN ...-----` and `-----END ...-----`.
72
+ * Non-greedy so multiple blocks in one string don't merge. The `{1,64}`
73
+ * label cap matches what OpenSSL emits; the `{1,131072}` body cap is the
74
+ * widest realistic PEM (~96 KB for an 8192-bit RSA key with armor).
75
+ */
76
+ export declare const PEM_BLOCK_REGEX: RegExp;
77
+ /**
78
+ * Luhn check (mod-10). Accepts a digit string with optional spaces/dashes;
79
+ * returns true iff the cleaned digit run is 13-19 chars and passes the
80
+ * checksum. Used to confirm a {@link CREDIT_CARD_REGEX} match before
81
+ * tagging as a credit card.
82
+ */
83
+ export declare function luhn(candidate: string): boolean;
84
+ /**
85
+ * Token tags emitted by {@link applyRegexBank}. Exposed for tests; not
86
+ * re-exported from the public barrel.
87
+ */
88
+ export type RedactionTag = 'CC' | 'SSN' | 'EMAIL' | 'PHONE' | 'JWT' | 'STRIPE_KEY' | 'GITHUB_TOKEN' | 'AWS_KEY' | 'PEM';
89
+ /**
90
+ * Apply the regex bank to `input`, returning the redacted string.
91
+ * Credit cards are handled in a separate Luhn-validated pass.
92
+ *
93
+ * Internal — exposed via `redactBody` and `maskTextContent` only.
94
+ */
95
+ export declare function applyRegexBank(input: string): string;
96
+ //# sourceMappingURL=regex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../src/masking/regex.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,QAAiE,CAAC;AAE1F;;;;GAIG;AACH,eAAO,MAAM,SAAS,QAA2B,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,QAA8B,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,QAAgE,CAAC;AAEzF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QACwD,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAqD,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAA6B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAA0B,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QACgD,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAkB/C;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB,IAAI,GACJ,KAAK,GACL,OAAO,GACP,OAAO,GACP,KAAK,GACL,YAAY,GACZ,cAAc,GACd,SAAS,GACT,KAAK,CAAC;AAyBV;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmBpD"}