UNPKG

purgo

Version:

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

87 lines (85 loc) 2.83 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/core.ts var core_exports = {}; __export(core_exports, { BUILT_IN_PATTERNS: () => BUILT_IN_PATTERNS, initRedactionEngine: () => initRedactionEngine, redact: () => redact, redactString: () => redactString }); module.exports = __toCommonJS(core_exports); 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();