purgo
Version:
Zero-config PHI-scrubber for browser and Node.js
87 lines (85 loc) • 2.83 kB
JavaScript
;
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();