@doccloak/core 0.11.0 → 0.12.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 +148 -2
- package/README.md +252 -19
- package/dist/doc.d.ts +68 -1
- package/dist/doc.js +447 -62
- package/dist/dom/docx.d.ts +135 -7
- package/dist/dom/docx.js +752 -125
- package/dist/dom/drawingml.d.ts +59 -0
- package/dist/dom/drawingml.js +176 -0
- package/dist/dom/errors.d.ts +35 -0
- package/dist/dom/errors.js +24 -0
- package/dist/dom/index.d.ts +3 -0
- package/dist/dom/index.js +6 -0
- package/dist/dom/office.d.ts +56 -0
- package/dist/dom/office.js +76 -23
- package/dist/dom/opc.d.ts +135 -7
- package/dist/dom/opc.js +407 -14
- package/dist/dom/package-policy.d.ts +137 -0
- package/dist/dom/package-policy.js +355 -0
- package/dist/dom/xlsx.d.ts +64 -6
- package/dist/dom/xlsx.js +130 -20
- package/dist/engine.d.ts +18 -0
- package/dist/engine.js +37 -13
- package/dist/env.d.ts +21 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +10 -5
- package/dist/model-loader.d.ts +61 -6
- package/dist/model-loader.js +122 -17
- package/dist/pipeline.d.ts +87 -8
- package/dist/pipeline.js +249 -50
- package/dist/providers/bardsai.d.ts +8 -1
- package/dist/providers/bardsai.js +22 -2
- package/dist/providers/gliner-base.d.ts +8 -1
- package/dist/providers/gliner-base.js +22 -2
- package/dist/providers/gliner.d.ts +8 -1
- package/dist/providers/gliner.js +22 -2
- package/dist/regex/loader.d.ts +2 -0
- package/dist/regex/loader.js +2 -0
- package/dist/regex/rules.data.js +15 -14
- package/dist/regex/types.d.ts +6 -0
- package/dist/session.d.ts +101 -3
- package/dist/session.js +397 -43
- package/dist/surrogates.js +57 -45
- package/dist/worker-protocol.d.ts +13 -1
- package/dist/worker-protocol.js +164 -12
- package/package.json +1 -1
- package/rules/at.json +1 -1
- package/rules/be.json +1 -1
- package/rules/ch.json +1 -1
- package/rules/de.json +1 -1
- package/rules/dk.json +1 -1
- package/rules/es.json +1 -1
- package/rules/fi.json +1 -1
- package/rules/fr.json +1 -1
- package/rules/it.json +1 -1
- package/rules/no.json +1 -1
- package/rules/pl.json +1 -1
- package/rules/pt.json +1 -1
- package/rules/schema.json +4 -0
- package/rules/se.json +1 -1
- package/rules/universal.json +2 -1
package/dist/regex/rules.data.js
CHANGED
|
@@ -263,7 +263,7 @@ export const RULES_DATA = [
|
|
|
263
263
|
{
|
|
264
264
|
"id": "regex:universal:postal_city",
|
|
265
265
|
"entityType": "ADDRESS",
|
|
266
|
-
"pattern": "\\b\\d{2,5}[-\\s]?\\d{2,4}\\s+[\\p{L}][\\p{L}]
|
|
266
|
+
"pattern": "\\b\\d{2,5}[-\\s]?\\d{2,4}\\s+[\\p{L}][\\p{L}]+(?![\\p{L}\\p{N}])",
|
|
267
267
|
"flags": "gu",
|
|
268
268
|
"confidence": 0.65,
|
|
269
269
|
"domains": [
|
|
@@ -370,6 +370,7 @@ export const RULES_DATA = [
|
|
|
370
370
|
"entityType": "SECRET",
|
|
371
371
|
"pattern": "-----BEGIN (?:[A-Z]+ )*PRIVATE KEY(?: BLOCK)?-----[\\s\\S]*?-----END (?:[A-Z]+ )*PRIVATE KEY(?: BLOCK)?-----",
|
|
372
372
|
"flags": "g",
|
|
373
|
+
"multiline": true,
|
|
373
374
|
"confidence": 0.99,
|
|
374
375
|
"domains": [
|
|
375
376
|
"technical"
|
|
@@ -776,7 +777,7 @@ export const RULES_DATA = [
|
|
|
776
777
|
{
|
|
777
778
|
"id": "regex:pl:postal",
|
|
778
779
|
"entityType": "ADDRESS",
|
|
779
|
-
"pattern": "\\b\\d{2}-\\d{3}\\s+[\\p{L}][\\p{L}\\s-]
|
|
780
|
+
"pattern": "\\b\\d{2}-\\d{3}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
780
781
|
"flags": "gu",
|
|
781
782
|
"confidence": 0.8,
|
|
782
783
|
"domains": [
|
|
@@ -967,7 +968,7 @@ export const RULES_DATA = [
|
|
|
967
968
|
{
|
|
968
969
|
"id": "regex:de:postal",
|
|
969
970
|
"entityType": "ADDRESS",
|
|
970
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]
|
|
971
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
971
972
|
"flags": "gu",
|
|
972
973
|
"confidence": 0.8,
|
|
973
974
|
"domains": [
|
|
@@ -1161,7 +1162,7 @@ export const RULES_DATA = [
|
|
|
1161
1162
|
{
|
|
1162
1163
|
"id": "regex:fr:postal",
|
|
1163
1164
|
"entityType": "ADDRESS",
|
|
1164
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
1165
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1165
1166
|
"flags": "gu",
|
|
1166
1167
|
"confidence": 0.8,
|
|
1167
1168
|
"domains": [
|
|
@@ -1320,7 +1321,7 @@ export const RULES_DATA = [
|
|
|
1320
1321
|
{
|
|
1321
1322
|
"id": "regex:es:postal",
|
|
1322
1323
|
"entityType": "ADDRESS",
|
|
1323
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
1324
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1324
1325
|
"flags": "gu",
|
|
1325
1326
|
"confidence": 0.75,
|
|
1326
1327
|
"domains": [
|
|
@@ -1448,7 +1449,7 @@ export const RULES_DATA = [
|
|
|
1448
1449
|
{
|
|
1449
1450
|
"id": "regex:pt:postal",
|
|
1450
1451
|
"entityType": "ADDRESS",
|
|
1451
|
-
"pattern": "\\b\\d{4}-\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
1452
|
+
"pattern": "\\b\\d{4}-\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1452
1453
|
"flags": "gu",
|
|
1453
1454
|
"confidence": 0.85,
|
|
1454
1455
|
"domains": [
|
|
@@ -1597,7 +1598,7 @@ export const RULES_DATA = [
|
|
|
1597
1598
|
{
|
|
1598
1599
|
"id": "regex:se:postal",
|
|
1599
1600
|
"entityType": "ADDRESS",
|
|
1600
|
-
"pattern": "\\b\\d{3}\\s?\\d{2}\\s+[\\p{L}][\\p{L}\\s-]
|
|
1601
|
+
"pattern": "\\b\\d{3}\\s?\\d{2}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1601
1602
|
"flags": "gu",
|
|
1602
1603
|
"confidence": 0.8,
|
|
1603
1604
|
"domains": [
|
|
@@ -1729,7 +1730,7 @@ export const RULES_DATA = [
|
|
|
1729
1730
|
{
|
|
1730
1731
|
"id": "regex:no:postal",
|
|
1731
1732
|
"entityType": "ADDRESS",
|
|
1732
|
-
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]
|
|
1733
|
+
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1733
1734
|
"flags": "gu",
|
|
1734
1735
|
"confidence": 0.8,
|
|
1735
1736
|
"domains": [
|
|
@@ -1875,7 +1876,7 @@ export const RULES_DATA = [
|
|
|
1875
1876
|
{
|
|
1876
1877
|
"id": "regex:it:postal",
|
|
1877
1878
|
"entityType": "ADDRESS",
|
|
1878
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]
|
|
1879
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
1879
1880
|
"flags": "gu",
|
|
1880
1881
|
"confidence": 0.8,
|
|
1881
1882
|
"domains": [
|
|
@@ -2043,7 +2044,7 @@ export const RULES_DATA = [
|
|
|
2043
2044
|
{
|
|
2044
2045
|
"id": "regex:be:postal",
|
|
2045
2046
|
"entityType": "ADDRESS",
|
|
2046
|
-
"pattern": "\\b[1-9]\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]
|
|
2047
|
+
"pattern": "\\b[1-9]\\d{3}\\s+[\\p{L}][\\p{L}\\s'-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
2047
2048
|
"flags": "gu",
|
|
2048
2049
|
"confidence": 0.75,
|
|
2049
2050
|
"domains": [
|
|
@@ -2113,7 +2114,7 @@ export const RULES_DATA = [
|
|
|
2113
2114
|
{
|
|
2114
2115
|
"id": "regex:at:postal",
|
|
2115
2116
|
"entityType": "ADDRESS",
|
|
2116
|
-
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]
|
|
2117
|
+
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
2117
2118
|
"flags": "gu",
|
|
2118
2119
|
"confidence": 0.8,
|
|
2119
2120
|
"domains": [
|
|
@@ -2179,7 +2180,7 @@ export const RULES_DATA = [
|
|
|
2179
2180
|
{
|
|
2180
2181
|
"id": "regex:ch:postal-city",
|
|
2181
2182
|
"entityType": "ADDRESS",
|
|
2182
|
-
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]
|
|
2183
|
+
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
2183
2184
|
"flags": "gu",
|
|
2184
2185
|
"confidence": 0.8,
|
|
2185
2186
|
"domains": [
|
|
@@ -2292,7 +2293,7 @@ export const RULES_DATA = [
|
|
|
2292
2293
|
{
|
|
2293
2294
|
"id": "regex:dk:postal-city",
|
|
2294
2295
|
"entityType": "ADDRESS",
|
|
2295
|
-
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]
|
|
2296
|
+
"pattern": "\\b\\d{4}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
2296
2297
|
"flags": "gu",
|
|
2297
2298
|
"confidence": 0.8,
|
|
2298
2299
|
"domains": [
|
|
@@ -2335,7 +2336,7 @@ export const RULES_DATA = [
|
|
|
2335
2336
|
{
|
|
2336
2337
|
"id": "regex:fi:postal-city",
|
|
2337
2338
|
"entityType": "ADDRESS",
|
|
2338
|
-
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]
|
|
2339
|
+
"pattern": "\\b\\d{5}\\s+[\\p{L}][\\p{L}\\s-]*[\\p{L}](?![\\p{L}\\p{N}])",
|
|
2339
2340
|
"flags": "gu",
|
|
2340
2341
|
"confidence": 0.8,
|
|
2341
2342
|
"domains": [
|
package/dist/regex/types.d.ts
CHANGED
|
@@ -24,4 +24,10 @@ export interface RegexRule {
|
|
|
24
24
|
falsePositiveNotes?: string;
|
|
25
25
|
/** Optional validation function for post-match filtering (e.g., Luhn check, checksum) */
|
|
26
26
|
validate?: (match: string) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* True when the rule must see the whole document (a match spans line
|
|
29
|
+
* breaks, e.g. PEM key blocks). Default false: detectWithRegex runs the
|
|
30
|
+
* rule on each line separately (T180, bounds ReDoS cost to line length).
|
|
31
|
+
*/
|
|
32
|
+
multiline?: boolean;
|
|
27
33
|
}
|
package/dist/session.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export interface SessionOptions {
|
|
|
11
11
|
*/
|
|
12
12
|
salt?: string;
|
|
13
13
|
}
|
|
14
|
+
/** Input accepted by registerDocumentValues: plain values or anything carrying a `value`. */
|
|
15
|
+
export type DocumentValueInput = string | {
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
14
18
|
export declare class AnonymizationSession {
|
|
15
19
|
private forwardMap;
|
|
16
20
|
private reverseMap;
|
|
@@ -21,6 +25,34 @@ export declare class AnonymizationSession {
|
|
|
21
25
|
* the base re-derives its variants and deserialized maps re-link.
|
|
22
26
|
*/
|
|
23
27
|
private variantOf;
|
|
28
|
+
/**
|
|
29
|
+
* Compiled exact-restore alternation (R4), rebuilt lazily; null after
|
|
30
|
+
* every reverse-map mutation (see invalidateRestore).
|
|
31
|
+
*/
|
|
32
|
+
private restoreRe;
|
|
33
|
+
/**
|
|
34
|
+
* Every value known to occur in the session's documents (R3), lowercased:
|
|
35
|
+
* whole entity values plus their person tokens (and hyphen parts). Fed by
|
|
36
|
+
* anonymizeText, anonymize, importEntries and registerDocumentValues;
|
|
37
|
+
* cumulative until clear(). A surrogate is never one of these. No
|
|
38
|
+
* capitalised-word heuristic: it would starve the pools in German and
|
|
39
|
+
* Polish prose (plan v2 section 9).
|
|
40
|
+
*/
|
|
41
|
+
private documentValues;
|
|
42
|
+
/**
|
|
43
|
+
* Letter-only document tokens of MIN_NAME_TOKEN_LENGTH or more, bucketed
|
|
44
|
+
* by their first MIN_NAME_TOKEN_LENGTH characters, for the containment
|
|
45
|
+
* rule in isDocumentValue: linear in the candidate's length instead of
|
|
46
|
+
* a scan over every document token.
|
|
47
|
+
*/
|
|
48
|
+
private documentNameIndex;
|
|
49
|
+
/**
|
|
50
|
+
* PERSON values that matched two or more mapped people equally well and
|
|
51
|
+
* therefore got a fresh identity instead of a guessed one (R5).
|
|
52
|
+
*/
|
|
53
|
+
private ambiguousValues;
|
|
54
|
+
/** Whether the most recent anonymize() call refused an ambiguous unification. */
|
|
55
|
+
private lastAmbiguousFlag;
|
|
24
56
|
private mode;
|
|
25
57
|
/** Surrogate-mode salt (T043); constant for the session's lifetime. */
|
|
26
58
|
private salt;
|
|
@@ -45,12 +77,67 @@ export declare class AnonymizationSession {
|
|
|
45
77
|
*/
|
|
46
78
|
private nextSurrogate;
|
|
47
79
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
80
|
+
* Whether a PERSON surrogate candidate carries a document name (R3):
|
|
81
|
+
* any of its tokens is a document value, or contains one of at least
|
|
82
|
+
* MIN_NAME_TOKEN_LENGTH letters ("Johnson" with "John" in the document,
|
|
83
|
+
* "Nowakowski" with "Nowak"). Other types are covered by the exact
|
|
84
|
+
* whole-value check alone: their tokens ("+48", "ul.", "GmbH") recur in
|
|
85
|
+
* every surrogate of the same shape and would starve the pools.
|
|
86
|
+
*/
|
|
87
|
+
private containsDocumentName;
|
|
88
|
+
/** Record one document value: whole (lowercased), its tokens and hyphen parts. */
|
|
89
|
+
private addDocumentValue;
|
|
90
|
+
/**
|
|
91
|
+
* Declare values that occur in the session's documents (R3) so no later
|
|
92
|
+
* surrogate equals or, for people, contains one of them. anonymizeText
|
|
93
|
+
* registers its entities itself; hosts that call anonymize() value by
|
|
94
|
+
* value should register the whole entity list first, otherwise a person
|
|
95
|
+
* mapped early can still receive the name of a person mapped later.
|
|
96
|
+
* Accepts plain strings or objects with a `value` (DetectedEntity,
|
|
97
|
+
* ReplacementEntry-like `{ value }` shapes). Cumulative until clear().
|
|
98
|
+
*/
|
|
99
|
+
registerDocumentValues(input: ReadonlyArray<DocumentValueInput>): void;
|
|
100
|
+
/**
|
|
101
|
+
* Whether the most recent anonymize() call met an ambiguous PERSON value
|
|
102
|
+
* (R5): a bare name that fits two or more mapped people equally well.
|
|
103
|
+
* Such a value is NOT unified; it gets its own number or surrogate. For
|
|
104
|
+
* anonymizeText, which maps many values, use getAmbiguousValues().
|
|
105
|
+
*/
|
|
106
|
+
lastAmbiguous(): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Every PERSON value this session refused to unify because it matched
|
|
109
|
+
* two or more people equally well (R5), in mapping order. Cumulative
|
|
110
|
+
* until clear(); hosts can flag them for the user to resolve.
|
|
111
|
+
*/
|
|
112
|
+
getAmbiguousValues(): string[];
|
|
113
|
+
/**
|
|
114
|
+
* One reference name per person group (R5): the fullest mapped original
|
|
115
|
+
* of each group (most tokens; the first mapped on ties). Variants never
|
|
116
|
+
* act as match targets on their own, so "Anna" cannot pull "Anna
|
|
117
|
+
* Kowalska" into Anna Nowak's group, while a group whose fuller form
|
|
118
|
+
* arrived later ("John" then "John Smith") still matches "Smith".
|
|
119
|
+
*/
|
|
120
|
+
private personReferences;
|
|
121
|
+
/**
|
|
122
|
+
* The mapped person that a new PERSON value is a variant of (T057):
|
|
123
|
+
* only group references are considered (see personReferences); most
|
|
124
|
+
* shared tokens wins. A tie between two or more people is AMBIGUOUS
|
|
125
|
+
* (R5): no guess is made, the value gets a fresh identity and the
|
|
126
|
+
* session records it (lastAmbiguous / getAmbiguousValues).
|
|
127
|
+
* Deterministic; match is null when nothing (or too much) matches.
|
|
51
128
|
*/
|
|
52
129
|
private findPersonVariant;
|
|
53
130
|
anonymize(original: string, entityType: EntityType): string;
|
|
131
|
+
/** Drop the cached restore regex; called on every reverse-map change. */
|
|
132
|
+
private invalidateRestore;
|
|
133
|
+
/**
|
|
134
|
+
* The exact-restore regex (R4): ONE alternation of every reverse-map
|
|
135
|
+
* key, longest first so a longer key always wins at a given position
|
|
136
|
+
* ("[PERSON_11]" before "[PERSON_1]", "Adam Nowak" before "Adam"), each
|
|
137
|
+
* key escaped and guarded per restoreKeyPattern. Compiled once per map
|
|
138
|
+
* state and reused across replies. Null when nothing is restorable.
|
|
139
|
+
*/
|
|
140
|
+
private restoreRegex;
|
|
54
141
|
/**
|
|
55
142
|
* The group a mapped value belongs to (T171): its base token and the
|
|
56
143
|
* canonical original that token restores to.
|
|
@@ -86,6 +173,13 @@ export declare class AnonymizationSession {
|
|
|
86
173
|
* forms no key owns.
|
|
87
174
|
*/
|
|
88
175
|
private deanonymizeMangledTokens;
|
|
176
|
+
/**
|
|
177
|
+
* R9: placeholders written LITERALLY in the user's text ("[PERSON_1]" in
|
|
178
|
+
* a template or a previously anonymized document) raise the per-type
|
|
179
|
+
* counter above them, so a freshly issued placeholder never restores to
|
|
180
|
+
* a value the text never carried under that token.
|
|
181
|
+
*/
|
|
182
|
+
private reserveLiteralPlaceholders;
|
|
89
183
|
anonymizeText(text: string, entities: DetectedEntity[]): string;
|
|
90
184
|
getEntries(): ReplacementEntry[];
|
|
91
185
|
getForward(original: string): string | undefined;
|
|
@@ -156,6 +250,10 @@ export declare class AnonymizationSession {
|
|
|
156
250
|
* forward map but excluded from the reverse map, preserving their
|
|
157
251
|
* irreversibility. Entries merge into whatever the session already
|
|
158
252
|
* holds; call clear() first for a fresh seeded session.
|
|
253
|
+
*
|
|
254
|
+
* R11: the input is validated BEFORE anything is applied (an array of
|
|
255
|
+
* at most 10 000 well-formed entries, see validateImportEntry); a
|
|
256
|
+
* violation throws and leaves the session untouched.
|
|
159
257
|
*/
|
|
160
258
|
importEntries(entries: ReplacementEntry[]): void;
|
|
161
259
|
/**
|