@link-foundation/sensitive-data-sanitizer 0.18.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +8 -0
- package/docs/API.md +216 -39
- package/docs/COVERAGE.md +122 -15
- package/docs/RULES.md +405 -0
- package/examples/custom-log-policy.mjs +23 -0
- package/package.json +17 -2
- package/src/compiled-known.js +55 -0
- package/src/detection.js +9 -0
- package/src/document-catalog.js +246 -0
- package/src/document-entities.js +10 -2
- package/src/document-experience.js +9 -4
- package/src/document-extras.js +2 -2
- package/src/document-fields.js +12 -2
- package/src/document-patterns.js +22 -2
- package/src/document-person-cues.js +35 -0
- package/src/document-vocabulary.js +80 -68
- package/src/engines.js +81 -34
- package/src/index.d.ts +52 -4
- package/src/index.js +5 -0
- package/src/jsonl-stream.js +2 -5
- package/src/ner.d.ts +5 -0
- package/src/ner.js +96 -0
- package/src/personal-variants.js +29 -8
- package/src/policy.js +107 -0
- package/src/propagation.js +2 -1
- package/src/proper-names.js +26 -3
- package/src/record-worker.js +6 -0
- package/src/rule-catalog.js +672 -0
- package/src/rules.js +5 -0
- package/src/sanitizer.js +99 -19
- package/src/stream-worker.js +5 -0
- package/src/stream.js +11 -6
- package/src/strict.js +113 -0
- package/src/structured.js +133 -48
- package/src/sync-detectors.js +38 -0
- package/src/sync-sanitizer.js +16 -0
- package/src/transforms.js +85 -7
- package/src/vocabulary.js +226 -0
- package/src/worker-options.js +12 -0
package/src/proper-names.js
CHANGED
|
@@ -7,6 +7,19 @@ const commaMobile = /,[ \t]*[78]9\d{9}(?![\p{L}\p{N}_])/u;
|
|
|
7
7
|
const mobile = /^[78]9\d{9}$/u;
|
|
8
8
|
const tokenPattern = /[\p{L}\p{M}\p{N}_./:\\?&#%=@+'’~+-]+/gu;
|
|
9
9
|
const upper = /[\p{Lu}\p{Lt}]/u;
|
|
10
|
+
// Only known labels are exempt before colons in activated Cyrillic prose.
|
|
11
|
+
const proseLabels = new Set(
|
|
12
|
+
'опыт стаж навыки образование компания работодатель должность обязанности достижения проекты контакты телефон почта адрес возраст пол гражданство дети национальность вероисповедание инвалидность судимость резюме имя фамилия отчество город статус дата время уровень языки интересы о себе место работы семейное положение'.split(
|
|
13
|
+
' '
|
|
14
|
+
)
|
|
15
|
+
);
|
|
16
|
+
const completeTypes = new Set([
|
|
17
|
+
'EMAIL',
|
|
18
|
+
'PHONE',
|
|
19
|
+
'ID',
|
|
20
|
+
'VIN',
|
|
21
|
+
'PASSPORT_NUMBER',
|
|
22
|
+
]);
|
|
10
23
|
const quotePairs = new Map([
|
|
11
24
|
['«', '»'],
|
|
12
25
|
['“', '”'],
|
|
@@ -109,6 +122,8 @@ export function detectProseAndDocuments(text, emit, options, detectDocuments) {
|
|
|
109
122
|
return;
|
|
110
123
|
}
|
|
111
124
|
const runs = [[]];
|
|
125
|
+
let complete = 0,
|
|
126
|
+
suppressed = 0;
|
|
112
127
|
detectProperNames(
|
|
113
128
|
text,
|
|
114
129
|
(finding) => {
|
|
@@ -123,12 +138,20 @@ export function detectProseAndDocuments(text, emit, options, detectDocuments) {
|
|
|
123
138
|
detectDocuments(
|
|
124
139
|
text,
|
|
125
140
|
(finding) => {
|
|
126
|
-
if (
|
|
141
|
+
if (completeTypes.has(finding.type)) {
|
|
142
|
+
// Contacts and identifiers are indivisible: a domain or series alone
|
|
143
|
+
// cannot safely replace the complete value detected by document rules.
|
|
144
|
+
emit(finding);
|
|
145
|
+
complete++;
|
|
146
|
+
} else if (!runs.some((run) => overlapsRun(run, finding))) {
|
|
127
147
|
emit(finding);
|
|
148
|
+
} else {
|
|
149
|
+
suppressed++;
|
|
128
150
|
}
|
|
129
151
|
},
|
|
130
152
|
options
|
|
131
153
|
);
|
|
154
|
+
options.debug?.({ event: 'document-prose-overlap', complete, suppressed });
|
|
132
155
|
}
|
|
133
156
|
function overlapsRun(run, finding) {
|
|
134
157
|
let low = 0,
|
|
@@ -197,8 +220,8 @@ function preserveToken(text, raw, value, start, end, range) {
|
|
|
197
220
|
!value ||
|
|
198
221
|
(range && start >= range.index && end <= range.index + range[0].length) ||
|
|
199
222
|
(value === 'REDACTED' && text[start - 1] === '[' && text[end] === ']') ||
|
|
200
|
-
raw.endsWith(':') ||
|
|
201
|
-
|
|
223
|
+
((raw.endsWith(':') || text[next] === ':') &&
|
|
224
|
+
(!/^[А-ЯЁа-яё-]+$/u.test(value) || proseLabels.has(value.toLowerCase())))
|
|
202
225
|
);
|
|
203
226
|
}
|
|
204
227
|
function tokenType(value) {
|
package/src/record-worker.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { parentPort, workerData } from 'node:worker_threads';
|
|
2
2
|
import { createSanitizer, prepareStreamEngine } from './engines.js';
|
|
3
|
+
import { compileKnown } from './compiled-known.js';
|
|
4
|
+
|
|
5
|
+
// Structured cloning discards the caller's weak compilation metadata.
|
|
6
|
+
if (workerData.knownPersonal) {
|
|
7
|
+
workerData.knownPersonal = compileKnown(workerData.knownPersonal);
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
parentPort.on(
|
|
5
11
|
'message',
|