UNPKG

purgo

Version:

Zero-config PHI-scrubber for browser and Node.js

66 lines (65 loc) 1.86 kB
// src/core.ts var BUILT_IN_PATTERNS = { // Email addresses email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, // Phone numbers (various formats) phone: /(\+\d{1,2}\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}/g, // Social Security Numbers ssn: /\b\d{3}[-]?\d{2}[-]?\d{4}\b/g, // Medical Record Numbers (generic pattern, can be customized) mrn: /\b\d{6,10}\b/g, // ICD-10 codes icd10: /\b[A-Z]\d{2}(\.[A-Z0-9]{1,4})?\b/g }; var DEFAULT_CENSOR = () => "***"; var globalConfig = { patterns: [], censor: DEFAULT_CENSOR }; function initRedactionEngine(options = {}) { const patterns = options.patterns || ["email", "phone", "ssn", "mrn", "icd10"]; const regexPatterns = patterns.map((pattern) => { if (typeof pattern === "string") { return BUILT_IN_PATTERNS[pattern] || new RegExp(pattern, "g"); } return pattern; }); globalConfig = { patterns: regexPatterns, censor: options.censor || DEFAULT_CENSOR }; } function redactString(value) { if (typeof value !== "string") return value; let result = value; for (const patternTemplate of globalConfig.patterns) { const pattern = new RegExp(patternTemplate.source, patternTemplate.flags); result = result.replace(pattern, (match) => globalConfig.censor(match)); } return result; } function redact(value) { if (value === null || value === void 0) return value; if (typeof value !== "object") { return typeof value === "string" ? redactString(value) : value; } if (Array.isArray(value)) { return value.map((item) => redact(item)); } const result = {}; for (const key in value) { if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = redact(value[key]); } } return result; } initRedactionEngine(); export { BUILT_IN_PATTERNS, initRedactionEngine, redact, redactString };