UNPKG

@visulima/redact

Version:

Detect whether a terminal or browser supports ansi colors.

116 lines (110 loc) 4.82 kB
'use strict'; 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;