@socprime/logtotal-sanitizer 0.0.1-beta.2 → 0.0.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.0.1-beta.3] - 2026-08-26
11
+
12
+ ### Fixed
13
+
14
+ - JSON preview `before` segments now highlight values redacted via `jsonKeys`, not only regex
15
+ matches. Fields such as `UserName` were replaced in the output (and highlighted in `after`) but
16
+ left unmarked on the left-hand preview.
17
+
8
18
  ## [0.0.1-beta.2] - 2026-08-25
9
19
 
10
20
  ### Changed
@@ -562,6 +562,55 @@ function highlightReplacements(text) {
562
562
  }
563
563
  return segments.length > 0 ? segments : [{ text, changed: false }];
564
564
  }
565
+ function jsonStringContent(value) {
566
+ return JSON.stringify(value).slice(1, -1);
567
+ }
568
+ function findOriginal(text, original, from) {
569
+ const encoded = jsonStringContent(original.value);
570
+ if (original.wholeValue) {
571
+ const quoted = `"${encoded}"`;
572
+ const quotedIndex = text.indexOf(quoted, from);
573
+ if (quotedIndex !== -1) {
574
+ return { index: quotedIndex + 1, length: encoded.length };
575
+ }
576
+ }
577
+ const needles = encoded === original.value ? [encoded] : [encoded, original.value];
578
+ for (const needle of needles) {
579
+ const index = text.indexOf(needle, from);
580
+ if (index !== -1) {
581
+ return { index, length: needle.length };
582
+ }
583
+ }
584
+ return null;
585
+ }
586
+ function highlightOriginals(text, originals) {
587
+ if (originals.length === 0) {
588
+ return [{ text, changed: false }];
589
+ }
590
+ const segments = [];
591
+ let cursor = 0;
592
+ for (const original of originals) {
593
+ if (original.value.length === 0) {
594
+ continue;
595
+ }
596
+ const found = findOriginal(text, original, cursor);
597
+ if (found === null) {
598
+ continue;
599
+ }
600
+ if (found.index > cursor) {
601
+ segments.push({ text: text.slice(cursor, found.index), changed: false });
602
+ }
603
+ segments.push({
604
+ text: text.slice(found.index, found.index + found.length),
605
+ changed: true
606
+ });
607
+ cursor = found.index + found.length;
608
+ }
609
+ if (cursor < text.length) {
610
+ segments.push({ text: text.slice(cursor), changed: false });
611
+ }
612
+ return segments.length > 0 ? segments : [{ text, changed: false }];
613
+ }
565
614
  function redactJsonLine(line, ctx, options = {}) {
566
615
  const terminatorMatch = /(\r\n|\r|\n)$/.exec(line);
567
616
  const terminator = terminatorMatch ? terminatorMatch[0] : "";
@@ -577,18 +626,27 @@ function redactJsonLine(line, ctx, options = {}) {
577
626
  }
578
627
  const withSegments = options.withSegments ?? false;
579
628
  const withMatches = options.withMatches ?? false;
629
+ const collectOriginals = withMatches || withSegments;
580
630
  const keyIndex = jsonKeyIndex(ctx.rules);
581
631
  const counts = {};
582
632
  const matches = [];
633
+ const originals = [];
583
634
  const contextFor = (value) => {
584
635
  if (ctx.contextChars <= 0) {
585
636
  return {};
586
637
  }
587
- const index = content.indexOf(value);
588
- if (index < 0) {
589
- return { contextBefore: "", contextAfter: "" };
638
+ const encoded = jsonStringContent(value);
639
+ const encodedIndex = content.indexOf(encoded);
640
+ if (encodedIndex >= 0) {
641
+ return sliceContext(content, encodedIndex, encoded.length, ctx.contextChars);
642
+ }
643
+ if (encoded !== value) {
644
+ const rawIndex = content.indexOf(value);
645
+ if (rawIndex >= 0) {
646
+ return sliceContext(content, rawIndex, value.length, ctx.contextChars);
647
+ }
590
648
  }
591
- return sliceContext(content, index, value.length, ctx.contextChars);
649
+ return { contextBefore: "", contextAfter: "" };
592
650
  };
593
651
  const redactValue = (value, key) => {
594
652
  if (typeof value === "string") {
@@ -599,6 +657,9 @@ function redactJsonLine(line, ctx, options = {}) {
599
657
  }
600
658
  const replacement = buildReplacement(ctx, fieldRule.id, value);
601
659
  counts[fieldRule.id] = (counts[fieldRule.id] ?? 0) + 1;
660
+ if (withSegments) {
661
+ originals.push({ value, wholeValue: true });
662
+ }
602
663
  if (withMatches) {
603
664
  matches.push({
604
665
  ruleId: fieldRule.id,
@@ -609,11 +670,16 @@ function redactJsonLine(line, ctx, options = {}) {
609
670
  }
610
671
  return replacement;
611
672
  }
612
- const result = redactLine(value, ctx, { withMatches });
673
+ const result = redactLine(value, ctx, { withMatches: collectOriginals });
613
674
  mergeCounts(counts, result.counts);
614
- if (withMatches) {
675
+ if (collectOriginals) {
615
676
  for (const match of result.matches) {
616
- matches.push({ ...match, ...contextFor(match.original) });
677
+ if (withSegments) {
678
+ originals.push({ value: match.original, wholeValue: false });
679
+ }
680
+ if (withMatches) {
681
+ matches.push({ ...match, ...contextFor(match.original) });
682
+ }
617
683
  }
618
684
  }
619
685
  return result.output;
@@ -634,13 +700,12 @@ function redactJsonLine(line, ctx, options = {}) {
634
700
  if (!withSegments) {
635
701
  return { output, counts, matches };
636
702
  }
637
- const preview = redactLine(line, ctx, { withSegments: true });
638
703
  return {
639
704
  output,
640
705
  counts,
641
706
  matches,
642
707
  segments: {
643
- before: preview.segments?.before ?? [{ text: line, changed: false }],
708
+ before: highlightOriginals(line, originals),
644
709
  after: highlightReplacements(output)
645
710
  }
646
711
  };
@@ -929,5 +994,5 @@ function toNullSink() {
929
994
  }
930
995
 
931
996
  export { createSanitizer, fromBlob, fromString, fromWebStream, generateKey, sanitizeStream, sanitizeText, toCallbackSink, toNullSink, toStringSink };
932
- //# sourceMappingURL=chunk-CH3ID3BM.js.map
933
- //# sourceMappingURL=chunk-CH3ID3BM.js.map
997
+ //# sourceMappingURL=chunk-32RNSQDF.js.map
998
+ //# sourceMappingURL=chunk-32RNSQDF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/constants.ts","../src/core/hmac.ts","../src/core/key.ts","../src/rules/alwaysRedact.ts","../src/core/allowlist.ts","../src/core/pseudonymize.ts","../src/core/compile.ts","../src/core/lineSplitter.ts","../src/core/redactLine.ts","../src/core/redactJsonLine.ts","../src/core/report.ts","../src/core/resolveRules.ts","../src/core/sanitizer.ts","../src/io/sources.ts","../src/io/sinks.ts"],"names":["normalizeKey","sanitizeText","sanitizeStream"],"mappings":"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","file":"chunk-32RNSQDF.js","sourcesContent":["export const DEFAULT_PREVIEW_BYTES = 256 * 1024;\n\nexport const DEFAULT_MAX_LINE_CHARS = 1024 * 1024;\n\nexport const DEFAULT_LINE_OVERLAP_CHARS = 1024;\n\nexport const DEFAULT_KEY_BYTES = 32;\n\nexport const MASK_TOKEN_PREFIX = 'R';\n\nexport const ALWAYS_REDACT_RULE_ID = 'custom';\n\nexport const ALWAYS_REDACT_TOKEN = 'CUSTOM';\n","const BLOCK_BYTES = 64;\nconst DIGEST_BYTES = 32;\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst INITIAL_STATE = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\nfunction concatBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.length + b.length);\n out.set(a, 0);\n out.set(b, a.length);\n return out;\n}\n\nfunction padMessage(message: Uint8Array): Uint8Array {\n const bitLength = message.length * 8;\n const paddedLength = Math.ceil((message.length + 9) / BLOCK_BYTES) * BLOCK_BYTES;\n const padded = new Uint8Array(paddedLength);\n\n padded.set(message);\n padded[message.length] = 0x80;\n\n const view = new DataView(padded.buffer);\n view.setUint32(paddedLength - 8, Math.floor(bitLength / 2 ** 32), false);\n view.setUint32(paddedLength - 4, bitLength >>> 0, false);\n\n return padded;\n}\n\nexport function sha256(message: Uint8Array): Uint8Array {\n const padded = padMessage(message);\n const view = new DataView(padded.buffer);\n const state = Uint32Array.from(INITIAL_STATE);\n const w = new Uint32Array(64);\n\n for (let offset = 0; offset < padded.length; offset += BLOCK_BYTES) {\n for (let i = 0; i < 16; i += 1) {\n w[i] = view.getUint32(offset + i * 4, false);\n }\n\n for (let i = 16; i < 64; i += 1) {\n const s0 = rotr(w[i - 15]!, 7) ^ rotr(w[i - 15]!, 18) ^ (w[i - 15]! >>> 3);\n const s1 = rotr(w[i - 2]!, 17) ^ rotr(w[i - 2]!, 19) ^ (w[i - 2]! >>> 10);\n w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) >>> 0;\n }\n\n let a = state[0]!;\n let b = state[1]!;\n let c = state[2]!;\n let d = state[3]!;\n let e = state[4]!;\n let f = state[5]!;\n let g = state[6]!;\n let h = state[7]!;\n\n for (let i = 0; i < 64; i += 1) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const temp1 = (h + s1 + ch + K[i]! + w[i]!) >>> 0;\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (s0 + maj) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n state[0] = (state[0]! + a) >>> 0;\n state[1] = (state[1]! + b) >>> 0;\n state[2] = (state[2]! + c) >>> 0;\n state[3] = (state[3]! + d) >>> 0;\n state[4] = (state[4]! + e) >>> 0;\n state[5] = (state[5]! + f) >>> 0;\n state[6] = (state[6]! + g) >>> 0;\n state[7] = (state[7]! + h) >>> 0;\n }\n\n const digest = new Uint8Array(DIGEST_BYTES);\n const digestView = new DataView(digest.buffer);\n\n for (let i = 0; i < 8; i += 1) {\n digestView.setUint32(i * 4, state[i]!, false);\n }\n\n return digest;\n}\n\nfunction normalizeKey(key: Uint8Array): Uint8Array {\n const hashed = key.length > BLOCK_BYTES ? sha256(key) : key;\n\n if (hashed.length === BLOCK_BYTES) {\n return hashed;\n }\n\n const padded = new Uint8Array(BLOCK_BYTES);\n padded.set(hashed);\n return padded;\n}\n\nexport type KeyedHmacSha256 = (message: Uint8Array) => Uint8Array;\n\nexport function createHmacSha256(key: Uint8Array): KeyedHmacSha256 {\n const block = normalizeKey(key);\n const ipad = new Uint8Array(BLOCK_BYTES);\n const opad = new Uint8Array(BLOCK_BYTES);\n\n for (let i = 0; i < BLOCK_BYTES; i += 1) {\n ipad[i] = block[i]! ^ 0x36;\n opad[i] = block[i]! ^ 0x5c;\n }\n\n return (message: Uint8Array): Uint8Array =>\n sha256(concatBytes(opad, sha256(concatBytes(ipad, message))));\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n\n for (let i = 0; i < bytes.length; i += 1) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n\n return bytes;\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n","import type { KeyEncoding } from '../types';\nimport { DEFAULT_KEY_BYTES } from './constants';\nimport { InvalidKeyError } from './errors';\nimport { bytesToHex } from './hmac';\n\nconst HEX_PATTERN = /^(?:[0-9a-fA-F]{2})+$/;\n\n/**\n * Generates a random hex-encoded key for token derivation.\n *\n * Persist the returned value if tokens have to stay comparable across runs or files; discard it if\n * they should not. There is no way to recover the original values from the tokens, with or without\n * the key — the key only determines which token a given value maps to.\n *\n * @param byteLength Key length in bytes, at least 16.\n * @throws {InvalidKeyError} When `byteLength` is too small or no secure random source is available.\n *\n * @example\n * ```ts\n * const key = generateKey();\n * const sanitizer = createSanitizer({ key });\n * ```\n */\nexport function generateKey(byteLength: number = DEFAULT_KEY_BYTES): string {\n if (!Number.isInteger(byteLength) || byteLength < 16) {\n throw new InvalidKeyError(`Key length must be an integer of at least 16 bytes, got ${byteLength}.`);\n }\n\n const source = globalThis.crypto;\n\n if (typeof source?.getRandomValues !== 'function') {\n throw new InvalidKeyError(\n 'No secure random source available. Pass an explicit `key` or provide a Web Crypto implementation on globalThis.crypto.',\n );\n }\n\n const bytes = new Uint8Array(byteLength);\n source.getRandomValues(bytes);\n\n return bytesToHex(bytes);\n}\n\nexport function assertKey(key: string, encoding: KeyEncoding): void {\n if (key.length === 0) {\n throw new InvalidKeyError('Key must not be empty.');\n }\n\n if (encoding === 'hex' && !HEX_PATTERN.test(key)) {\n throw new InvalidKeyError(\n 'A hex key must contain an even number of hexadecimal characters. Pass `keyEncoding: \"utf8\"` for a passphrase.',\n );\n }\n}\n","import { ALWAYS_REDACT_RULE_ID, ALWAYS_REDACT_TOKEN } from '../core/constants';\nimport { InvalidOptionError } from '../core/errors';\nimport type { AlwaysRedactOptions, SanitizeRule } from '../types';\n\nexport function escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction normalizeValues(values: readonly string[]): string[] {\n const unique = new Set(values.map((value) => value.trim()).filter((value) => value.length > 0));\n\n return [...unique].sort((left, right) => right.length - left.length || left.localeCompare(right));\n}\n\nfunction normalizePatterns(patterns: readonly (string | RegExp)[]): string[] {\n return patterns.map((pattern) => {\n const source = typeof pattern === 'string' ? pattern : pattern.source;\n\n try {\n new RegExp(source, 'u');\n } catch (cause) {\n throw new InvalidOptionError(\n `alwaysRedact.patterns contains an invalid regular expression: ${String(cause)}`,\n );\n }\n\n return `(?:${source})`;\n });\n}\n\nexport function createAlwaysRedactRule(\n options: AlwaysRedactOptions | undefined,\n): SanitizeRule | null {\n if (!options) {\n return null;\n }\n\n const patterns = [\n ...normalizeValues(options.values ?? []).map((value) => `(?:${escapeRegExp(value)})`),\n ...normalizePatterns(options.patterns ?? []),\n ];\n\n if (patterns.length === 0) {\n return null;\n }\n\n return {\n id: options.ruleId ?? ALWAYS_REDACT_RULE_ID,\n label: 'Always redacted',\n description: 'Values and patterns the caller marked as always sensitive.',\n mode: options.mode ?? 'pseudo',\n token: options.token ?? ALWAYS_REDACT_TOKEN,\n patterns,\n };\n}\n","import type { NeverRedactOptions } from '../types';\nimport { InvalidOptionError } from './errors';\n\nexport interface AllowList {\n empty: boolean;\n values: ReadonlySet<string>;\n pattern: RegExp | null;\n byRule: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nexport function patternSource(pattern: string | RegExp): string {\n return typeof pattern === 'string' ? pattern : pattern.source;\n}\n\nfunction compileAnchored(patterns: readonly (string | RegExp)[]): RegExp | null {\n const sources = patterns.map(patternSource).filter((source) => source.length > 0);\n\n if (sources.length === 0) {\n return null;\n }\n\n const combined = sources.map((source) => `(?:${source})`).join('|');\n\n try {\n return new RegExp(`^(?:${combined})$`, 'u');\n } catch (cause) {\n throw new InvalidOptionError(\n `neverRedact.patterns contains an invalid regular expression: ${String(cause)}`,\n );\n }\n}\n\nexport function createAllowList(options: NeverRedactOptions | undefined): AllowList {\n const values = new Set((options?.values ?? []).filter((value) => value.length > 0));\n const pattern = compileAnchored(options?.patterns ?? []);\n const byRule = new Map<string, Set<string>>();\n\n for (const entry of options?.byRule ?? []) {\n const existing = byRule.get(entry.ruleId) ?? new Set<string>();\n\n for (const value of entry.values) {\n if (value.length > 0) {\n existing.add(value);\n }\n }\n\n byRule.set(entry.ruleId, existing);\n }\n\n return {\n empty: values.size === 0 && pattern === null && byRule.size === 0,\n values,\n pattern,\n byRule,\n };\n}\n\nexport function isAllowed(allow: AllowList, ruleId: string, value: string): boolean {\n if (allow.empty) {\n return false;\n }\n\n if (allow.values.has(value)) {\n return true;\n }\n\n if (allow.byRule.get(ruleId)?.has(value) === true) {\n return true;\n }\n\n return allow.pattern !== null && allow.pattern.test(value);\n}\n","import type { KeyEncoding, SanitizeRule } from '../types';\nimport { MASK_TOKEN_PREFIX } from './constants';\nimport { bytesToHex, createHmacSha256, hexToBytes } from './hmac';\n\nconst TOKEN_HEX_LENGTH = 16;\nconst TOKEN_BYTES = TOKEN_HEX_LENGTH / 2;\n\nconst textEncoder = new TextEncoder();\n\nexport type Pseudonymizer = (ruleId: string, value: string) => string;\n\nexport function createPseudonymizer(key: string, encoding: KeyEncoding): Pseudonymizer {\n const keyBytes = encoding === 'utf8' ? textEncoder.encode(key) : hexToBytes(key);\n const sign = createHmacSha256(keyBytes);\n const cache = new Map<string, string>();\n\n return (ruleId, value) => {\n const cacheKey = `${ruleId}\\u0000${value}`;\n const cached = cache.get(cacheKey);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const digest = sign(textEncoder.encode(cacheKey));\n const token = bytesToHex(digest.subarray(0, TOKEN_BYTES));\n\n cache.set(cacheKey, token);\n return token;\n };\n}\n\nexport function replacementPrefix(rule: SanitizeRule): string {\n if (rule.mode === 'mask') {\n return MASK_TOKEN_PREFIX;\n }\n\n return rule.token ?? rule.id.toUpperCase();\n}\n","import type { SanitizeRule } from '../types';\nimport type { AllowList } from './allowlist';\nimport { InvalidRuleError } from './errors';\nimport { replacementPrefix, type Pseudonymizer } from './pseudonymize';\n\nexport interface RuleContext {\n compiled: RegExp | null;\n rules: SanitizeRule[];\n ruleIds: string[];\n rulesById: Map<string, SanitizeRule>;\n prefixById: Map<string, string>;\n pseudonymize: Pseudonymizer;\n allow: AllowList;\n contextChars: number;\n json: boolean;\n}\n\nexport function compileRules(rules: SanitizeRule[], aggressive: boolean): RegExp | null {\n const parts = rules\n .map((rule) => ({\n id: rule.id,\n patterns: aggressive ? [...rule.patterns, ...(rule.aggressivePatterns ?? [])] : rule.patterns,\n }))\n .filter(({ patterns }) => patterns.length > 0)\n .map(({ id, patterns }) => `(?<${id}>${patterns.join('|')})`);\n\n if (parts.length === 0) {\n return null;\n }\n\n try {\n return new RegExp(parts.join('|'), 'gu');\n } catch (cause) {\n throw new InvalidRuleError(`Failed to compile the combined rule pattern: ${String(cause)}`);\n }\n}\n\nexport interface RuleContextInput {\n rules: SanitizeRule[];\n aggressive: boolean;\n pseudonymize: Pseudonymizer;\n allow: AllowList;\n contextChars: number;\n json: boolean;\n}\n\nexport function createRuleContext(input: RuleContextInput): RuleContext {\n const { rules } = input;\n\n return {\n compiled: compileRules(rules, input.aggressive),\n rules,\n ruleIds: rules.map((rule) => rule.id),\n rulesById: new Map(rules.map((rule) => [rule.id, rule])),\n prefixById: new Map(rules.map((rule) => [rule.id, replacementPrefix(rule)])),\n pseudonymize: input.pseudonymize,\n allow: input.allow,\n contextChars: input.contextChars,\n json: input.json,\n };\n}\n\nexport function buildReplacement(ctx: RuleContext, ruleId: string, value: string): string {\n return `<${ctx.prefixById.get(ruleId) ?? ruleId.toUpperCase()}:${ctx.pseudonymize(ruleId, value)}>`;\n}\n","import type { LineOptions } from '../types';\nimport { DEFAULT_LINE_OVERLAP_CHARS, DEFAULT_MAX_LINE_CHARS } from './constants';\nimport { InvalidOptionError } from './errors';\n\nexport interface LineSplitter {\n push(chunk: string): string[];\n flush(): string[];\n}\n\nfunction extractLines(buffer: string): { lines: string[]; rest: string } {\n const lines: string[] = [];\n let start = 0;\n\n for (let i = 0; i < buffer.length; i += 1) {\n if (buffer[i] === '\\n') {\n lines.push(buffer.slice(start, i + 1));\n start = i + 1;\n }\n }\n\n return { lines, rest: buffer.slice(start) };\n}\n\nexport function createLineSplitter(options: LineOptions = {}): LineSplitter {\n const maxLineChars = options.maxLineChars ?? DEFAULT_MAX_LINE_CHARS;\n const overlapChars = options.overlapChars ?? DEFAULT_LINE_OVERLAP_CHARS;\n\n if (maxLineChars < 1) {\n throw new InvalidOptionError('lines.maxLineChars must be at least 1.');\n }\n\n if (overlapChars < 0 || overlapChars >= maxLineChars) {\n throw new InvalidOptionError(\n `lines.overlapChars must be between 0 and lines.maxLineChars - 1 (${maxLineChars - 1}), got ${overlapChars}.`,\n );\n }\n\n let carry = '';\n\n function push(chunk: string): string[] {\n carry += chunk;\n\n const { lines, rest } = extractLines(carry);\n carry = rest;\n\n while (carry.length > maxLineChars) {\n const cut = carry.length - overlapChars;\n lines.push(carry.slice(0, cut));\n carry = carry.slice(cut);\n }\n\n return lines;\n }\n\n function flush(): string[] {\n if (carry.length === 0) {\n return [];\n }\n\n const rest = carry;\n carry = '';\n return [rest];\n }\n\n return { push, flush };\n}\n","import type { SanitizeSegment } from '../types';\nimport { isAllowed } from './allowlist';\nimport { buildReplacement, type RuleContext } from './compile';\n\nexport interface RedactMatch {\n ruleId: string;\n original: string;\n replacement: string;\n contextBefore?: string;\n contextAfter?: string;\n}\n\nexport interface RedactResult {\n output: string;\n counts: Record<string, number>;\n matches: RedactMatch[];\n segments?: {\n before: SanitizeSegment[];\n after: SanitizeSegment[];\n };\n}\n\nexport interface RedactOptions {\n withSegments?: boolean;\n withMatches?: boolean;\n}\n\nexport function sliceContext(\n text: string,\n index: number,\n length: number,\n chars: number,\n): { contextBefore: string; contextAfter: string } {\n return {\n contextBefore: text.slice(Math.max(0, index - chars), index),\n contextAfter: text.slice(index + length, index + length + chars),\n };\n}\n\nfunction matchedRuleId(\n ruleIds: string[],\n groups: Record<string, string | undefined>,\n): string | undefined {\n for (const id of ruleIds) {\n if (groups[id] !== undefined) {\n return id;\n }\n }\n\n return undefined;\n}\n\nexport function redactLine(\n line: string,\n ctx: RuleContext,\n options: RedactOptions = {},\n): RedactResult {\n const { compiled, ruleIds, rulesById, allow, contextChars } = ctx;\n const withSegments = options.withSegments ?? false;\n const withMatches = options.withMatches ?? false;\n\n if (!compiled) {\n return {\n output: line,\n counts: {},\n matches: [],\n segments: withSegments\n ? { before: [{ text: line, changed: false }], after: [{ text: line, changed: false }] }\n : undefined,\n };\n }\n\n compiled.lastIndex = 0;\n\n const counts: Record<string, number> = {};\n const matches: RedactMatch[] = [];\n const before: SanitizeSegment[] = [];\n const after: SanitizeSegment[] = [];\n let output = '';\n let cursor = 0;\n let match = compiled.exec(line);\n\n while (match !== null) {\n const ruleId = match.groups ? matchedRuleId(ruleIds, match.groups) : undefined;\n const rule = ruleId === undefined ? undefined : rulesById.get(ruleId);\n const original = match[0];\n\n if (rule === undefined || ruleId === undefined) {\n compiled.lastIndex = match.index + Math.max(original.length, 1);\n match = compiled.exec(line);\n continue;\n }\n\n const rejected =\n (rule.validate !== undefined && !rule.validate(original)) ||\n isAllowed(allow, ruleId, original);\n\n if (rejected) {\n compiled.lastIndex = match.index + Math.max(original.length, 1);\n match = compiled.exec(line);\n continue;\n }\n\n const replacement = buildReplacement(ctx, ruleId, original);\n\n if (withSegments) {\n if (match.index > cursor) {\n const gap = line.slice(cursor, match.index);\n before.push({ text: gap, changed: false });\n after.push({ text: gap, changed: false });\n }\n\n before.push({ text: original, changed: true });\n after.push({ text: replacement, changed: true });\n }\n\n output += line.slice(cursor, match.index) + replacement;\n cursor = match.index + original.length;\n counts[ruleId] = (counts[ruleId] ?? 0) + 1;\n\n if (withMatches) {\n matches.push({\n ruleId,\n original,\n replacement,\n ...(contextChars > 0 ? sliceContext(line, match.index, original.length, contextChars) : {}),\n });\n }\n\n if (original.length === 0) {\n compiled.lastIndex += 1;\n }\n\n match = compiled.exec(line);\n }\n\n output += line.slice(cursor);\n\n if (withSegments && cursor < line.length) {\n const tail = line.slice(cursor);\n before.push({ text: tail, changed: false });\n after.push({ text: tail, changed: false });\n }\n\n return {\n output,\n counts,\n matches,\n segments: withSegments ? { before, after } : undefined,\n };\n}\n","import type { SanitizeRule, SanitizeSegment } from '../types';\nimport { isAllowed } from './allowlist';\nimport { buildReplacement, type RuleContext } from './compile';\nimport {\n redactLine,\n sliceContext,\n type RedactMatch,\n type RedactOptions,\n type RedactResult,\n} from './redactLine';\n\nconst REPLACEMENT_TOKEN_RE = /<[A-Z][A-Z0-9]*:[0-9a-f]+>/g;\n\nexport function looksLikeJson(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.length > 0 && (trimmed.startsWith('{') || trimmed.startsWith('['));\n}\n\nfunction normalizeKey(key: string): string {\n return key.toLowerCase().replace(/[-_]/g, '');\n}\n\nfunction buildJsonKeyIndex(rules: SanitizeRule[]): Map<string, SanitizeRule> {\n const index = new Map<string, SanitizeRule>();\n\n for (const rule of rules) {\n for (const key of rule.jsonKeys ?? []) {\n const normalized = normalizeKey(key);\n\n if (!index.has(normalized)) {\n index.set(normalized, rule);\n }\n }\n }\n\n return index;\n}\n\nconst jsonKeyIndexCache = new WeakMap<SanitizeRule[], Map<string, SanitizeRule>>();\n\nfunction jsonKeyIndex(rules: SanitizeRule[]): Map<string, SanitizeRule> {\n const cached = jsonKeyIndexCache.get(rules);\n\n if (cached) {\n return cached;\n }\n\n const index = buildJsonKeyIndex(rules);\n jsonKeyIndexCache.set(rules, index);\n return index;\n}\n\nfunction mergeCounts(target: Record<string, number>, source: Record<string, number>): void {\n for (const [id, count] of Object.entries(source)) {\n target[id] = (target[id] ?? 0) + count;\n }\n}\n\nfunction highlightReplacements(text: string): SanitizeSegment[] {\n const segments: SanitizeSegment[] = [];\n let cursor = 0;\n\n REPLACEMENT_TOKEN_RE.lastIndex = 0;\n let match = REPLACEMENT_TOKEN_RE.exec(text);\n\n while (match !== null) {\n if (match.index > cursor) {\n segments.push({ text: text.slice(cursor, match.index), changed: false });\n }\n\n segments.push({ text: match[0], changed: true });\n cursor = match.index + match[0].length;\n match = REPLACEMENT_TOKEN_RE.exec(text);\n }\n\n if (cursor < text.length) {\n segments.push({ text: text.slice(cursor), changed: false });\n }\n\n return segments.length > 0 ? segments : [{ text, changed: false }];\n}\n\ninterface PreviewOriginal {\n value: string;\n wholeValue: boolean;\n}\n\nfunction jsonStringContent(value: string): string {\n return JSON.stringify(value).slice(1, -1);\n}\n\nfunction findOriginal(\n text: string,\n original: PreviewOriginal,\n from: number,\n): { index: number; length: number } | null {\n const encoded = jsonStringContent(original.value);\n\n if (original.wholeValue) {\n const quoted = `\"${encoded}\"`;\n const quotedIndex = text.indexOf(quoted, from);\n\n if (quotedIndex !== -1) {\n return { index: quotedIndex + 1, length: encoded.length };\n }\n }\n\n const needles = encoded === original.value ? [encoded] : [encoded, original.value];\n\n for (const needle of needles) {\n const index = text.indexOf(needle, from);\n\n if (index !== -1) {\n return { index, length: needle.length };\n }\n }\n\n return null;\n}\n\nfunction highlightOriginals(text: string, originals: PreviewOriginal[]): SanitizeSegment[] {\n if (originals.length === 0) {\n return [{ text, changed: false }];\n }\n\n const segments: SanitizeSegment[] = [];\n let cursor = 0;\n\n for (const original of originals) {\n if (original.value.length === 0) {\n continue;\n }\n\n const found = findOriginal(text, original, cursor);\n\n if (found === null) {\n continue;\n }\n\n if (found.index > cursor) {\n segments.push({ text: text.slice(cursor, found.index), changed: false });\n }\n\n segments.push({\n text: text.slice(found.index, found.index + found.length),\n changed: true,\n });\n cursor = found.index + found.length;\n }\n\n if (cursor < text.length) {\n segments.push({ text: text.slice(cursor), changed: false });\n }\n\n return segments.length > 0 ? segments : [{ text, changed: false }];\n}\n\nexport function redactJsonLine(\n line: string,\n ctx: RuleContext,\n options: RedactOptions = {},\n): RedactResult | null {\n const terminatorMatch = /(\\r\\n|\\r|\\n)$/.exec(line);\n const terminator = terminatorMatch ? terminatorMatch[0] : '';\n const content = terminator ? line.slice(0, -terminator.length) : line;\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n return null;\n }\n\n const withSegments = options.withSegments ?? false;\n const withMatches = options.withMatches ?? false;\n const collectOriginals = withMatches || withSegments;\n const keyIndex = jsonKeyIndex(ctx.rules);\n const counts: Record<string, number> = {};\n const matches: RedactMatch[] = [];\n const originals: PreviewOriginal[] = [];\n\n const contextFor = (value: string): Partial<RedactMatch> => {\n if (ctx.contextChars <= 0) {\n return {};\n }\n\n const encoded = jsonStringContent(value);\n const encodedIndex = content.indexOf(encoded);\n\n if (encodedIndex >= 0) {\n return sliceContext(content, encodedIndex, encoded.length, ctx.contextChars);\n }\n\n if (encoded !== value) {\n const rawIndex = content.indexOf(value);\n\n if (rawIndex >= 0) {\n return sliceContext(content, rawIndex, value.length, ctx.contextChars);\n }\n }\n\n return { contextBefore: '', contextAfter: '' };\n };\n\n const redactValue = (value: unknown, key?: string): unknown => {\n if (typeof value === 'string') {\n const fieldRule = key === undefined ? undefined : keyIndex.get(normalizeKey(key));\n\n if (fieldRule) {\n if (isAllowed(ctx.allow, fieldRule.id, value)) {\n return value;\n }\n\n const replacement = buildReplacement(ctx, fieldRule.id, value);\n counts[fieldRule.id] = (counts[fieldRule.id] ?? 0) + 1;\n\n if (withSegments) {\n originals.push({ value, wholeValue: true });\n }\n\n if (withMatches) {\n matches.push({\n ruleId: fieldRule.id,\n original: value,\n replacement,\n ...contextFor(value),\n });\n }\n\n return replacement;\n }\n\n const result = redactLine(value, ctx, { withMatches: collectOriginals });\n mergeCounts(counts, result.counts);\n\n if (collectOriginals) {\n for (const match of result.matches) {\n if (withSegments) {\n originals.push({ value: match.original, wholeValue: false });\n }\n\n if (withMatches) {\n matches.push({ ...match, ...contextFor(match.original) });\n }\n }\n }\n\n return result.output;\n }\n\n if (Array.isArray(value)) {\n return value.map((item: unknown) => redactValue(item));\n }\n\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n\n for (const [entryKey, entryValue] of Object.entries(value)) {\n out[entryKey] = redactValue(entryValue, entryKey);\n }\n\n return out;\n }\n\n return value;\n };\n\n const output = JSON.stringify(redactValue(parsed)) + terminator;\n\n if (!withSegments) {\n return { output, counts, matches };\n }\n\n return {\n output,\n counts,\n matches,\n segments: {\n before: highlightOriginals(line, originals),\n after: highlightReplacements(output),\n },\n };\n}\n","import type { RuleCounts, SanitizeReplacement, SanitizeReport, SanitizeSegment } from '../types';\nimport { DEFAULT_PREVIEW_BYTES } from './constants';\nimport { InvalidOptionError } from './errors';\nimport type { RedactResult } from './redactLine';\n\nexport interface ReportCollectorOptions {\n previewBytes?: number;\n replacements?: boolean;\n}\n\nexport interface ReportSnapshotOptions {\n includeReplacements?: boolean;\n}\n\nexport interface ReportCollector {\n needsSegments(): boolean;\n needsMatches(): boolean;\n record(result: RedactResult): void;\n build(options?: ReportSnapshotOptions): SanitizeReport;\n}\n\nexport function createReportCollector(options: ReportCollectorOptions = {}): ReportCollector {\n const previewBytes = options.previewBytes ?? DEFAULT_PREVIEW_BYTES;\n const collectReplacements = options.replacements ?? true;\n\n if (previewBytes < 0) {\n throw new InvalidOptionError('report.previewBytes must not be negative.');\n }\n\n const counts: Record<string, number> = {};\n const replacements = new Map<string, SanitizeReplacement>();\n const before: SanitizeSegment[] = [];\n const after: SanitizeSegment[] = [];\n let lineCount = 0;\n let previewBytesUsed = 0;\n let previewClosed = previewBytes === 0;\n\n function needsSegments(): boolean {\n return !previewClosed;\n }\n\n function needsMatches(): boolean {\n return collectReplacements;\n }\n\n function record(result: RedactResult): void {\n lineCount += 1;\n\n for (const [id, count] of Object.entries(result.counts)) {\n counts[id] = (counts[id] ?? 0) + count;\n }\n\n if (collectReplacements) {\n for (const match of result.matches) {\n const key = `${match.ruleId}\\u0000${match.original}`;\n const existing = replacements.get(key);\n\n if (existing) {\n existing.count += 1;\n } else {\n replacements.set(key, {\n ruleId: match.ruleId,\n original: match.original,\n replacement: match.replacement,\n count: 1,\n ...(match.contextBefore !== undefined\n ? { contextBefore: match.contextBefore, contextAfter: match.contextAfter }\n : {}),\n });\n }\n }\n }\n\n if (previewClosed) {\n return;\n }\n\n if (result.segments) {\n before.push(...result.segments.before);\n after.push(...result.segments.after);\n }\n\n previewBytesUsed += result.output.length;\n\n if (previewBytesUsed >= previewBytes) {\n previewClosed = true;\n }\n }\n\n function build(snapshot?: ReportSnapshotOptions): SanitizeReport {\n const includeReplacements = snapshot?.includeReplacements ?? true;\n let totalMatches = 0;\n\n for (const count of Object.values(counts)) {\n totalMatches += count;\n }\n\n return {\n counts: { ...counts } as RuleCounts,\n totalMatches,\n lineCount,\n replacements: includeReplacements ? [...replacements.values()] : [],\n preview: { before: [...before], after: [...after] },\n };\n }\n\n return { needsSegments, needsMatches, record, build };\n}\n","import { getBuiltinRule } from '../rules/registry';\nimport { validateRule } from '../rules/validateRule';\nimport type { RuleSelector, SanitizeRule } from '../types';\nimport { UnknownRuleError } from './errors';\n\nfunction toRule(selector: RuleSelector): SanitizeRule {\n if (typeof selector === 'string') {\n const builtin = getBuiltinRule(selector);\n\n if (!builtin) {\n throw new UnknownRuleError(\n `Unknown rule \"${selector}\". Pass a rule object for custom rules, or one of the built-in identifiers.`,\n );\n }\n\n return builtin;\n }\n\n return validateRule(selector);\n}\n\nexport function resolveRules(\n selectors: readonly RuleSelector[],\n extraRules: readonly SanitizeRule[] = [],\n): SanitizeRule[] {\n const resolved: SanitizeRule[] = [];\n const positions = new Map<string, number>();\n\n for (const selector of [...selectors, ...extraRules]) {\n const rule = toRule(selector);\n const existing = positions.get(rule.id);\n\n if (existing === undefined) {\n positions.set(rule.id, resolved.length);\n resolved.push(rule);\n } else {\n resolved[existing] = rule;\n }\n }\n\n return resolved;\n}\n","import { createAlwaysRedactRule } from '../rules/alwaysRedact';\nimport { builtinRuleIds } from '../rules/registry';\nimport type {\n RuleInfo,\n Sanitizer,\n SanitizerOptions,\n SanitizeReport,\n SanitizeRule,\n SanitizeStreamOptions,\n SanitizeTextResult,\n TextSink,\n TextSource,\n} from '../types';\nimport { createAllowList } from './allowlist';\nimport { createRuleContext, type RuleContext } from './compile';\nimport { InvalidOptionError, SanitizationAbortedError } from './errors';\nimport { assertKey, generateKey } from './key';\nimport { createLineSplitter } from './lineSplitter';\nimport { createPseudonymizer } from './pseudonymize';\nimport { looksLikeJson, redactJsonLine } from './redactJsonLine';\nimport { redactLine } from './redactLine';\nimport { createReportCollector, type ReportCollector } from './report';\nimport { resolveRules } from './resolveRules';\n\nasync function* toAsyncIterable(source: TextSource): AsyncIterable<string> {\n yield* source as AsyncIterable<string>;\n}\n\nfunction processLine(line: string, ctx: RuleContext, collector: ReportCollector): string {\n const options = {\n withSegments: collector.needsSegments(),\n withMatches: collector.needsMatches(),\n };\n\n const parsed = ctx.json && looksLikeJson(line) ? redactJsonLine(line, ctx, options) : null;\n const result = parsed ?? redactLine(line, ctx, options);\n\n collector.record(result);\n return result.output;\n}\n\n/**\n * Creates a reusable sanitizer.\n *\n * Rules are resolved, validated and compiled into a single pattern once, here — so sanitizing many\n * inputs with one sanitizer is much cheaper than calling the one-shot helpers repeatedly.\n *\n * @throws {UnknownRuleError} When `rules` names a rule that is not built in.\n * @throws {InvalidRuleError} When a custom rule is malformed.\n * @throws {InvalidKeyError} When `key` is malformed, or none could be generated.\n * @throws {InvalidOptionError} When an option value is out of range.\n *\n * @example\n * ```ts\n * const sanitizer = createSanitizer({\n * rules: ['secrets', 'ips', 'users'],\n * alwaysRedact: { values: ['acme-internal'] },\n * neverRedact: { values: ['127.0.0.1'] },\n * });\n *\n * const { output, report } = sanitizer.sanitizeText('login from 10.0.0.7 failed');\n * ```\n */\nexport function createSanitizer(options: SanitizerOptions = {}): Sanitizer {\n const keyEncoding = options.keyEncoding ?? 'hex';\n const key = options.key ?? generateKey();\n assertKey(key, keyEncoding);\n\n const contextChars = options.report?.contextChars ?? 0;\n\n if (contextChars < 0) {\n throw new InvalidOptionError('report.contextChars must not be negative.');\n }\n\n const selected = resolveWithAlwaysRedact(options);\n\n const ctx = createRuleContext({\n rules: selected,\n aggressive: options.aggressive ?? false,\n pseudonymize: createPseudonymizer(key, keyEncoding),\n allow: createAllowList(options.neverRedact),\n contextChars,\n json: options.json !== false,\n });\n\n const collectorOptions = {\n previewBytes: options.report?.previewBytes,\n replacements: options.report?.replacements,\n };\n\n const rules: readonly RuleInfo[] = selected.map((rule) => ({\n id: rule.id,\n label: rule.label,\n description: rule.description,\n mode: rule.mode,\n }));\n\n function sanitizeText(text: string): SanitizeTextResult {\n const collector = createReportCollector(collectorOptions);\n const splitter = createLineSplitter(options.lines);\n let output = '';\n\n for (const line of splitter.push(text)) {\n output += processLine(line, ctx, collector);\n }\n\n for (const line of splitter.flush()) {\n output += processLine(line, ctx, collector);\n }\n\n return { output, report: collector.build() };\n }\n\n async function sanitizeStream(\n source: TextSource,\n sink: TextSink,\n streamOptions: SanitizeStreamOptions = {},\n ): Promise<SanitizeReport> {\n const collector = createReportCollector(collectorOptions);\n const splitter = createLineSplitter(options.lines);\n const { signal, onProgress } = streamOptions;\n let charsRead = 0;\n\n const writeLine = async (line: string): Promise<void> => {\n if (signal?.aborted === true) {\n throw new SanitizationAbortedError();\n }\n\n await sink.write(processLine(line, ctx, collector));\n };\n\n for await (const chunk of toAsyncIterable(source)) {\n charsRead += chunk.length;\n\n for (const line of splitter.push(chunk)) {\n await writeLine(line);\n }\n\n onProgress?.({ charsRead, report: collector.build({ includeReplacements: false }) });\n }\n\n for (const line of splitter.flush()) {\n await writeLine(line);\n }\n\n await sink.close?.();\n\n return collector.build();\n }\n\n return { key, rules, sanitizeText, sanitizeStream };\n}\n\nfunction resolveWithAlwaysRedact(options: SanitizerOptions): SanitizeRule[] {\n const selected = resolveRules(options.rules ?? builtinRuleIds, options.extraRules);\n const alwaysRule = createAlwaysRedactRule(options.alwaysRedact);\n\n if (!alwaysRule) {\n return selected;\n }\n\n if (selected.some((rule) => rule.id === alwaysRule.id)) {\n throw new InvalidOptionError(\n `alwaysRedact.ruleId \"${alwaysRule.id}\" collides with an active rule. Choose an identifier that is not in use.`,\n );\n }\n\n return [alwaysRule, ...selected];\n}\n\n/**\n * Sanitizes a string with a one-off configuration.\n *\n * Convenient for scripts and tests. Each call builds a new sanitizer, so unless `options.key` is\n * supplied the tokens are not comparable between calls. For repeated use, create a sanitizer with\n * {@link createSanitizer} instead.\n */\nexport function sanitizeText(text: string, options?: SanitizerOptions): SanitizeTextResult {\n return createSanitizer(options).sanitizeText(text);\n}\n\n/**\n * Streams text through a one-off sanitizer.\n *\n * See {@link sanitizeText} for the trade-off of creating a sanitizer per call.\n */\nexport function sanitizeStream(\n source: TextSource,\n sink: TextSink,\n options?: SanitizerOptions & SanitizeStreamOptions,\n): Promise<SanitizeReport> {\n const { onProgress, signal, ...sanitizerOptions } = options ?? {};\n\n return createSanitizer(sanitizerOptions).sanitizeStream(source, sink, { onProgress, signal });\n}\n","import type { BlobLike, ReadableStreamLike, TextSource } from '../types';\n\nconst DEFAULT_CHUNK_BYTES = 4 * 1024 * 1024;\n\n/**\n * Wraps a string as a source, split into fixed-size chunks.\n *\n * Useful for exercising the streaming path in tests and for feeding text that is already in memory\n * without copying it in one piece.\n */\nexport function fromString(text: string, chunkChars = DEFAULT_CHUNK_BYTES): TextSource {\n return {\n *[Symbol.iterator](): Iterator<string> {\n for (let offset = 0; offset < text.length; offset += chunkChars) {\n yield text.slice(offset, offset + chunkChars);\n }\n },\n };\n}\n\n/**\n * Reads a `Blob` or `File` as UTF-8 text, one chunk at a time.\n *\n * Multi-byte characters split across a chunk boundary are decoded correctly. Accepts any object\n * with `size`, `slice` and `arrayBuffer`, so browser `File`, browser `Blob` and Node's `Blob` all\n * work.\n *\n * @example\n * ```ts\n * const report = await sanitizer.sanitizeStream(fromBlob(file), toStringSink());\n * ```\n */\nexport function fromBlob(blob: BlobLike, chunkBytes = DEFAULT_CHUNK_BYTES): TextSource {\n return {\n async *[Symbol.asyncIterator](): AsyncIterator<string> {\n const decoder = new TextDecoder('utf-8');\n\n for (let offset = 0; offset < blob.size; offset += chunkBytes) {\n const slice = blob.slice(offset, Math.min(offset + chunkBytes, blob.size));\n const buffer = await slice.arrayBuffer();\n const text = decoder.decode(new Uint8Array(buffer), { stream: true });\n\n if (text.length > 0) {\n yield text;\n }\n }\n\n const tail = decoder.decode();\n\n if (tail.length > 0) {\n yield tail;\n }\n },\n };\n}\n\n/**\n * Reads a `ReadableStream` of text or bytes.\n *\n * Byte chunks are decoded as UTF-8 across chunk boundaries. Accepts web streams from `fetch`,\n * `Blob.stream()` and `node:stream/web`.\n */\nexport function fromWebStream(stream: ReadableStreamLike<string | Uint8Array>): TextSource {\n return {\n async *[Symbol.asyncIterator](): AsyncIterator<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder('utf-8');\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n if (value === undefined) {\n continue;\n }\n\n const text = typeof value === 'string' ? value : decoder.decode(value, { stream: true });\n\n if (text.length > 0) {\n yield text;\n }\n }\n\n const tail = decoder.decode();\n\n if (tail.length > 0) {\n yield tail;\n }\n } finally {\n reader.releaseLock();\n }\n },\n };\n}\n","import type { TextSink } from '../types';\n\n/** A sink that accumulates everything in memory. */\nexport interface StringSink extends TextSink {\n /** Everything written so far, joined. */\n readonly text: string;\n}\n\n/**\n * Collects sanitized output into a string.\n *\n * Only appropriate when the output is known to fit in memory — the point of the streaming API is\n * usually to avoid that.\n *\n * @example\n * ```ts\n * const sink = toStringSink();\n * const report = await sanitizer.sanitizeStream(fromString(input), sink);\n * console.log(sink.text, report.totalMatches);\n * ```\n */\nexport function toStringSink(): StringSink {\n const chunks: string[] = [];\n\n return {\n write(chunk: string): void {\n chunks.push(chunk);\n },\n get text(): string {\n return chunks.join('');\n },\n };\n}\n\n/**\n * Sends sanitized output to a callback, one line at a time.\n *\n * The callback may return a promise; it is awaited before the next line is written, so\n * backpressure propagates to the source.\n */\nexport function toCallbackSink(\n onChunk: (chunk: string) => void | Promise<void>,\n onClose?: () => void | Promise<void>,\n): TextSink {\n return {\n write: onChunk,\n ...(onClose ? { close: onClose } : {}),\n };\n}\n\n/** A sink that discards everything, for report-only runs. */\nexport function toNullSink(): TextSink {\n return { write: () => undefined };\n}\n"]}
@@ -564,6 +564,55 @@ function highlightReplacements(text) {
564
564
  }
565
565
  return segments.length > 0 ? segments : [{ text, changed: false }];
566
566
  }
567
+ function jsonStringContent(value) {
568
+ return JSON.stringify(value).slice(1, -1);
569
+ }
570
+ function findOriginal(text, original, from) {
571
+ const encoded = jsonStringContent(original.value);
572
+ if (original.wholeValue) {
573
+ const quoted = `"${encoded}"`;
574
+ const quotedIndex = text.indexOf(quoted, from);
575
+ if (quotedIndex !== -1) {
576
+ return { index: quotedIndex + 1, length: encoded.length };
577
+ }
578
+ }
579
+ const needles = encoded === original.value ? [encoded] : [encoded, original.value];
580
+ for (const needle of needles) {
581
+ const index = text.indexOf(needle, from);
582
+ if (index !== -1) {
583
+ return { index, length: needle.length };
584
+ }
585
+ }
586
+ return null;
587
+ }
588
+ function highlightOriginals(text, originals) {
589
+ if (originals.length === 0) {
590
+ return [{ text, changed: false }];
591
+ }
592
+ const segments = [];
593
+ let cursor = 0;
594
+ for (const original of originals) {
595
+ if (original.value.length === 0) {
596
+ continue;
597
+ }
598
+ const found = findOriginal(text, original, cursor);
599
+ if (found === null) {
600
+ continue;
601
+ }
602
+ if (found.index > cursor) {
603
+ segments.push({ text: text.slice(cursor, found.index), changed: false });
604
+ }
605
+ segments.push({
606
+ text: text.slice(found.index, found.index + found.length),
607
+ changed: true
608
+ });
609
+ cursor = found.index + found.length;
610
+ }
611
+ if (cursor < text.length) {
612
+ segments.push({ text: text.slice(cursor), changed: false });
613
+ }
614
+ return segments.length > 0 ? segments : [{ text, changed: false }];
615
+ }
567
616
  function redactJsonLine(line, ctx, options = {}) {
568
617
  const terminatorMatch = /(\r\n|\r|\n)$/.exec(line);
569
618
  const terminator = terminatorMatch ? terminatorMatch[0] : "";
@@ -579,18 +628,27 @@ function redactJsonLine(line, ctx, options = {}) {
579
628
  }
580
629
  const withSegments = options.withSegments ?? false;
581
630
  const withMatches = options.withMatches ?? false;
631
+ const collectOriginals = withMatches || withSegments;
582
632
  const keyIndex = jsonKeyIndex(ctx.rules);
583
633
  const counts = {};
584
634
  const matches = [];
635
+ const originals = [];
585
636
  const contextFor = (value) => {
586
637
  if (ctx.contextChars <= 0) {
587
638
  return {};
588
639
  }
589
- const index = content.indexOf(value);
590
- if (index < 0) {
591
- return { contextBefore: "", contextAfter: "" };
640
+ const encoded = jsonStringContent(value);
641
+ const encodedIndex = content.indexOf(encoded);
642
+ if (encodedIndex >= 0) {
643
+ return sliceContext(content, encodedIndex, encoded.length, ctx.contextChars);
644
+ }
645
+ if (encoded !== value) {
646
+ const rawIndex = content.indexOf(value);
647
+ if (rawIndex >= 0) {
648
+ return sliceContext(content, rawIndex, value.length, ctx.contextChars);
649
+ }
592
650
  }
593
- return sliceContext(content, index, value.length, ctx.contextChars);
651
+ return { contextBefore: "", contextAfter: "" };
594
652
  };
595
653
  const redactValue = (value, key) => {
596
654
  if (typeof value === "string") {
@@ -601,6 +659,9 @@ function redactJsonLine(line, ctx, options = {}) {
601
659
  }
602
660
  const replacement = buildReplacement(ctx, fieldRule.id, value);
603
661
  counts[fieldRule.id] = (counts[fieldRule.id] ?? 0) + 1;
662
+ if (withSegments) {
663
+ originals.push({ value, wholeValue: true });
664
+ }
604
665
  if (withMatches) {
605
666
  matches.push({
606
667
  ruleId: fieldRule.id,
@@ -611,11 +672,16 @@ function redactJsonLine(line, ctx, options = {}) {
611
672
  }
612
673
  return replacement;
613
674
  }
614
- const result = redactLine(value, ctx, { withMatches });
675
+ const result = redactLine(value, ctx, { withMatches: collectOriginals });
615
676
  mergeCounts(counts, result.counts);
616
- if (withMatches) {
677
+ if (collectOriginals) {
617
678
  for (const match of result.matches) {
618
- matches.push({ ...match, ...contextFor(match.original) });
679
+ if (withSegments) {
680
+ originals.push({ value: match.original, wholeValue: false });
681
+ }
682
+ if (withMatches) {
683
+ matches.push({ ...match, ...contextFor(match.original) });
684
+ }
619
685
  }
620
686
  }
621
687
  return result.output;
@@ -636,13 +702,12 @@ function redactJsonLine(line, ctx, options = {}) {
636
702
  if (!withSegments) {
637
703
  return { output, counts, matches };
638
704
  }
639
- const preview = redactLine(line, ctx, { withSegments: true });
640
705
  return {
641
706
  output,
642
707
  counts,
643
708
  matches,
644
709
  segments: {
645
- before: preview.segments?.before ?? [{ text: line, changed: false }],
710
+ before: highlightOriginals(line, originals),
646
711
  after: highlightReplacements(output)
647
712
  }
648
713
  };
@@ -940,5 +1005,5 @@ exports.sanitizeText = sanitizeText;
940
1005
  exports.toCallbackSink = toCallbackSink;
941
1006
  exports.toNullSink = toNullSink;
942
1007
  exports.toStringSink = toStringSink;
943
- //# sourceMappingURL=chunk-DSS2N6HK.cjs.map
944
- //# sourceMappingURL=chunk-DSS2N6HK.cjs.map
1008
+ //# sourceMappingURL=chunk-6CWTMBTN.cjs.map
1009
+ //# sourceMappingURL=chunk-6CWTMBTN.cjs.map