@visulima/redact
Version:
Detect whether a terminal or browser supports ansi colors.
116 lines (110 loc) • 4.82 kB
JavaScript
;
const nlp = require('compromise');
const _interopDefaultCompat = e => e && typeof e === 'object' && 'default' in e ? e.default : e;
const nlp__default = /*#__PURE__*/_interopDefaultCompat(nlp);
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
const maskText = /* @__PURE__ */ __name((maskMaps, text, tag) => {
const lowerCaseTag = tag.toLowerCase();
if (!maskMaps[lowerCaseTag]) {
maskMaps[lowerCaseTag] = /* @__PURE__ */ new Map();
}
const { size } = maskMaps[lowerCaseTag];
const maskedValue = `<${tag.toUpperCase()}${size > 0 ? size : ""}>`;
maskMaps[lowerCaseTag].set(text, maskedValue);
return maskMaps[lowerCaseTag].get(text);
}, "maskText");
const replaceWithMasks = /* @__PURE__ */ __name((typesToAnonymize, documentTerms, output) => {
const maskMaps = {};
for (const type of typesToAnonymize) {
maskMaps[type] = /* @__PURE__ */ new Map();
}
let outputResult = output;
for (const term of documentTerms) {
const { tag, text } = term;
const mask = maskText(maskMaps, text, tag);
outputResult = outputResult.replace(text, mask);
}
return outputResult;
}, "replaceWithMasks");
const createDocumentTermsFromTerms = /* @__PURE__ */ __name((typesToAnonymize, processedTerms, documentObject, term, logger) => {
const reversedTags = term.tags.reverse();
logger?.debug(`reversedTags: ${JSON.stringify(reversedTags)}`);
const foundTag = reversedTags.find((tag) => typesToAnonymize.includes(tag.toLowerCase()));
logger?.debug(`foundTag: ${foundTag}`);
if (foundTag) {
processedTerms.push({ start: documentObject.offset.start, tag: foundTag, text: term.text });
}
return processedTerms;
}, "createDocumentTermsFromTerms");
const createUniqueAndSortedTerms = /* @__PURE__ */ __name((processedTerms) => {
const uniqueProcessedTerms = [...processedTerms.reduce((map, term) => map.set(term.text + term.start + term.tag, term), /* @__PURE__ */ new Map()).values()];
return uniqueProcessedTerms.sort((a, b) => {
const startDiff = a.start - b.start;
if (startDiff !== 0) {
return startDiff;
}
return b.text.length - a.text.length;
});
}, "createUniqueAndSortedTerms");
const processWithRegex = /* @__PURE__ */ __name((stringAnonymizeModifiers, input, processedTerms) => {
for (const modifier of stringAnonymizeModifiers) {
const { key, pattern } = modifier;
const rx = new RegExp(pattern, "giu");
let match;
while ((match = rx.exec(input)) !== null) {
processedTerms.push({
start: match.index,
tag: key,
text: match[0]
});
}
}
return processedTerms;
}, "processWithRegex");
const processTerms = /* @__PURE__ */ __name((typesToAnonymize, input, processedTerms, logger) => {
const document_ = nlp__default(input);
const processedDocument = [
...document_.emails().out("offset"),
...document_.money().out("offset"),
...document_.organizations().out("offset"),
...document_.people().out("offset"),
...document_.phoneNumbers().out("offset"),
...document_.urls().out("offset")
];
processedDocument.forEach((documentObject) => {
const { terms } = documentObject;
for (const term of terms) {
processedTerms = createDocumentTermsFromTerms(typesToAnonymize, processedTerms, documentObject, term, logger);
}
});
return processedTerms;
}, "processTerms");
const processDocument = /* @__PURE__ */ __name((input, typesToAnonymize, stringAnonymizeModifiers, logger) => {
let processedTerms = [];
processedTerms = processTerms(typesToAnonymize, input, processedTerms, logger);
processedTerms = processWithRegex(stringAnonymizeModifiers, input, processedTerms);
return createUniqueAndSortedTerms(processedTerms);
}, "processDocument");
const stringAnonymize = /* @__PURE__ */ __name((input, modifiers, options) => {
const patternModifiers = [];
const typesToAnonymize = [];
for (const modifier of modifiers) {
if (options?.exclude && (typeof modifier === "string" && options.exclude.includes(modifier) || typeof modifier === "number" && options.exclude.includes(modifier) || typeof modifier === "object" && options.exclude.includes(modifier.key))) {
continue;
}
if (typeof modifier === "object" && modifier.pattern) {
patternModifiers.push(modifier);
}
if (typeof modifier === "string" || typeof modifier === "number") {
typesToAnonymize.push(modifier + "");
} else {
typesToAnonymize.push(modifier.key);
}
}
let output = input;
const documentTerms = processDocument(input, typesToAnonymize, patternModifiers, options?.logger);
output = replaceWithMasks(typesToAnonymize, documentTerms, output);
return output;
}, "stringAnonymize");
module.exports = stringAnonymize;