@stll/anonymize 2.8.2 → 2.9.0
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/README.md +35 -20
- package/dist/build-native-package.d.mts +14 -0
- package/dist/build-native-package.mjs +2 -0
- package/dist/build-native-package2.mjs +211 -0
- package/dist/build-native-package2.mjs.map +1 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +3 -3
- package/dist/native-node.d.mts +14 -2
- package/dist/native-node.mjs +3 -3
- package/dist/native-node2.d.mts +3 -3
- package/dist/native-node2.mjs +114 -141
- package/dist/native-node2.mjs.map +1 -1
- package/dist/native-runtime.d.mts +2 -2
- package/dist/native-runtime.mjs +1 -1
- package/dist/native.d.mts +8 -428
- package/dist/native.mjs +187 -18
- package/dist/native.mjs.map +1 -1
- package/dist/native2.d.mts +2 -2
- package/dist/types.d.mts +429 -0
- package/native-pipeline.cs.stlanonpkg +0 -0
- package/native-pipeline.de.stlanonpkg +0 -0
- package/native-pipeline.en.stlanonpkg +0 -0
- package/native-pipeline.stlanonpkg +0 -0
- package/package.json +7 -13
- package/scripts/build-native-pipeline-package.mjs +22 -10
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { a as DetectionSource, n as DETECTION_SOURCES, p as OperatorType } from "./constants2.mjs";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Fields shared by every entity span in the source text.
|
|
5
|
+
*/
|
|
6
|
+
type EntityBase = {
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
label: string;
|
|
10
|
+
text: string;
|
|
11
|
+
score: number;
|
|
12
|
+
sourceDetail?: "custom-deny-list" | "custom-regex" | "gazetteer-extension";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A PII entity span found by a primary detection layer
|
|
16
|
+
* (regex, NER, legal forms, deny list, ...).
|
|
17
|
+
*/
|
|
18
|
+
type DetectedEntity = EntityBase & {
|
|
19
|
+
source: Exclude<DetectionSource, typeof DETECTION_SOURCES.COREFERENCE>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* An alias mention of a previously detected entity: a
|
|
23
|
+
* defined term ("the Seller") or a propagated bare
|
|
24
|
+
* mention ("Acme" after "Acme Corp.").
|
|
25
|
+
*
|
|
26
|
+
* `corefSourceText` is required by construction, so an
|
|
27
|
+
* alias cannot exist without the link back to its source
|
|
28
|
+
* entity. Placeholder numbering reads it to give the
|
|
29
|
+
* alias the same placeholder as the source. The link
|
|
30
|
+
* travels with the entity instead of living in a
|
|
31
|
+
* side-channel map that a producer could forget to
|
|
32
|
+
* write — or that a later pass could clear.
|
|
33
|
+
*/
|
|
34
|
+
type CorefAliasEntity = EntityBase & {
|
|
35
|
+
source: typeof DETECTION_SOURCES.COREFERENCE;
|
|
36
|
+
/** Full text of the source entity this alias refers to. */
|
|
37
|
+
corefSourceText: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A detected PII entity span in the source text.
|
|
41
|
+
* Every detection layer produces these.
|
|
42
|
+
*/
|
|
43
|
+
type Entity = DetectedEntity | CorefAliasEntity;
|
|
44
|
+
/**
|
|
45
|
+
* Entity after human review. Extends the base Entity
|
|
46
|
+
* with a review decision.
|
|
47
|
+
*/
|
|
48
|
+
type ReviewDecision = "confirmed" | "rejected" | "relabeled";
|
|
49
|
+
type ReviewedEntity = Entity & {
|
|
50
|
+
decision?: ReviewDecision;
|
|
51
|
+
originalLabel?: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* A single entry in the workspace-scoped gazetteer
|
|
55
|
+
* (deny list). Persisted in IndexedDB.
|
|
56
|
+
*/
|
|
57
|
+
type GazetteerEntry = {
|
|
58
|
+
id: string;
|
|
59
|
+
canonical: string;
|
|
60
|
+
label: string;
|
|
61
|
+
variants: string[];
|
|
62
|
+
workspaceId: string;
|
|
63
|
+
createdAt: number;
|
|
64
|
+
source: "manual" | "confirmed-from-model";
|
|
65
|
+
};
|
|
66
|
+
/** Extraction strategy — closed discriminated union. */
|
|
67
|
+
type TriggerStrategy = {
|
|
68
|
+
type: "to-next-comma";
|
|
69
|
+
/**
|
|
70
|
+
* Optional list of lowercase keywords that terminate
|
|
71
|
+
* the value scan, in addition to commas/newlines. Useful
|
|
72
|
+
* for triggers like court names that may continue past
|
|
73
|
+
* a missing comma into adjacent clause text ("Městským
|
|
74
|
+
* soudem v Praze dne 1. 1. 2020"); listing `"dne"` here
|
|
75
|
+
* stops the scan at the date boundary. Matched on a
|
|
76
|
+
* word-boundary, case-insensitive.
|
|
77
|
+
*/
|
|
78
|
+
stopWords?: string[];
|
|
79
|
+
/**
|
|
80
|
+
* Hard cap on the captured span length, in characters,
|
|
81
|
+
* regardless of where the next comma / stop char sits.
|
|
82
|
+
* Use for triggers that label short formulaic phrases
|
|
83
|
+
* ("State of Delaware") and must not absorb the rest
|
|
84
|
+
* of a long forum-selection clause when the comma is
|
|
85
|
+
* sentences away. Falls back to the default 100-char
|
|
86
|
+
* fallback when omitted.
|
|
87
|
+
*/
|
|
88
|
+
maxLength?: number;
|
|
89
|
+
} | {
|
|
90
|
+
type: "to-end-of-line";
|
|
91
|
+
} | {
|
|
92
|
+
type: "n-words";
|
|
93
|
+
count: number;
|
|
94
|
+
} | {
|
|
95
|
+
type: "company-id-value";
|
|
96
|
+
} | {
|
|
97
|
+
type: "address";
|
|
98
|
+
maxChars?: number;
|
|
99
|
+
} | {
|
|
100
|
+
/**
|
|
101
|
+
* Extract the first regex match in the value text.
|
|
102
|
+
* Useful for shape-bounded values that follow a
|
|
103
|
+
* label on the same line as other fields, where
|
|
104
|
+
* `to-end-of-line` would over-capture. The pattern
|
|
105
|
+
* is anchored to the start of the (already
|
|
106
|
+
* leading-whitespace-stripped) value, so use
|
|
107
|
+
* `(?:.*?)` prefix only when intentional.
|
|
108
|
+
*/
|
|
109
|
+
type: "match-pattern";
|
|
110
|
+
pattern: string;
|
|
111
|
+
flags?: string;
|
|
112
|
+
};
|
|
113
|
+
/** Validation rules — closed discriminated union. */
|
|
114
|
+
type TriggerValidation = {
|
|
115
|
+
type: "starts-uppercase";
|
|
116
|
+
} | {
|
|
117
|
+
type: "min-length";
|
|
118
|
+
min: number;
|
|
119
|
+
} | {
|
|
120
|
+
type: "max-length";
|
|
121
|
+
max: number;
|
|
122
|
+
} | {
|
|
123
|
+
type: "no-digits";
|
|
124
|
+
} | {
|
|
125
|
+
type: "has-digits";
|
|
126
|
+
} | {
|
|
127
|
+
type: "matches-pattern";
|
|
128
|
+
pattern: string;
|
|
129
|
+
flags?: string;
|
|
130
|
+
} |
|
|
131
|
+
/**
|
|
132
|
+
* Run a named stdnum validator (checksum + length)
|
|
133
|
+
* against the captured value. Keeps the trigger
|
|
134
|
+
* path symmetrical with the formatted-regex
|
|
135
|
+
* detectors so e.g. `CPF nº 00000000000` does not
|
|
136
|
+
* survive as a tax-ID entity.
|
|
137
|
+
*/
|
|
138
|
+
{
|
|
139
|
+
type: "valid-id";
|
|
140
|
+
validator: ValidIdValidator;
|
|
141
|
+
};
|
|
142
|
+
/** Built-in stdnum validators that can be referenced
|
|
143
|
+
* by `valid-id` validations. */
|
|
144
|
+
type ValidIdValidator = "br.cpf" | "br.cnpj" | "us.rtn";
|
|
145
|
+
/** Auto-generated trigger variants — closed set. */
|
|
146
|
+
type TriggerExtension = "add-colon" | "add-trailing-space" | "add-colon-space" | "normalize-spaces";
|
|
147
|
+
/** V2 trigger config entry (JSON shape). */
|
|
148
|
+
type TriggerGroupConfig = {
|
|
149
|
+
id?: string;
|
|
150
|
+
triggers: string[];
|
|
151
|
+
label: string;
|
|
152
|
+
strategy: TriggerStrategy;
|
|
153
|
+
extensions?: TriggerExtension[];
|
|
154
|
+
validations?: TriggerValidation[];
|
|
155
|
+
/** When true, include the trigger text in the
|
|
156
|
+
* entity span (e.g., court names). */
|
|
157
|
+
includeTrigger?: boolean;
|
|
158
|
+
};
|
|
159
|
+
/** Compiled validation with pre-built regex. */
|
|
160
|
+
type CompiledValidation = {
|
|
161
|
+
type: "starts-uppercase";
|
|
162
|
+
re: RegExp;
|
|
163
|
+
} | {
|
|
164
|
+
type: "min-length";
|
|
165
|
+
min: number;
|
|
166
|
+
} | {
|
|
167
|
+
type: "max-length";
|
|
168
|
+
max: number;
|
|
169
|
+
} | {
|
|
170
|
+
type: "no-digits";
|
|
171
|
+
re: RegExp;
|
|
172
|
+
} | {
|
|
173
|
+
type: "has-digits";
|
|
174
|
+
re: RegExp;
|
|
175
|
+
} | {
|
|
176
|
+
type: "matches-pattern";
|
|
177
|
+
re: RegExp;
|
|
178
|
+
} | {
|
|
179
|
+
type: "valid-id";
|
|
180
|
+
validator: ValidIdValidator;
|
|
181
|
+
check: (value: string) => boolean;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Runtime rule — one per trigger string after
|
|
185
|
+
* expansion. Fed to the Aho-Corasick automaton.
|
|
186
|
+
*/
|
|
187
|
+
type TriggerRule = {
|
|
188
|
+
trigger: string;
|
|
189
|
+
label: string;
|
|
190
|
+
strategy: TriggerStrategy;
|
|
191
|
+
validations: CompiledValidation[];
|
|
192
|
+
includeTrigger: boolean;
|
|
193
|
+
};
|
|
194
|
+
/** Per-label operator selection. Key is the entity label. */
|
|
195
|
+
type MaskDirection = "start" | "end";
|
|
196
|
+
type MaskOperatorConfig = {
|
|
197
|
+
type: "mask";
|
|
198
|
+
maskingCharacter: string;
|
|
199
|
+
charactersToMask: number;
|
|
200
|
+
direction: MaskDirection;
|
|
201
|
+
};
|
|
202
|
+
type OperatorSelection = Exclude<OperatorType, "mask"> | MaskOperatorConfig;
|
|
203
|
+
type OperatorConfig = {
|
|
204
|
+
/** Operator per label. Missing labels default to "replace". */
|
|
205
|
+
operators: Record<string, OperatorSelection>;
|
|
206
|
+
/** Custom replacement string for the redact operator. */
|
|
207
|
+
redactString: string;
|
|
208
|
+
};
|
|
209
|
+
/** Whether an operator produces a reversible redaction entry. */
|
|
210
|
+
type OperatorReversibility = "reversible" | "irreversible" | "preserving";
|
|
211
|
+
type AnonymisationOperator = {
|
|
212
|
+
type: OperatorType;
|
|
213
|
+
reversibility: OperatorReversibility;
|
|
214
|
+
/**
|
|
215
|
+
* Apply the operator to a single entity occurrence.
|
|
216
|
+
* Returns the replacement string to embed in the document.
|
|
217
|
+
*/
|
|
218
|
+
apply: (text: string, label: string, placeholder: string, redactString: string, selection: OperatorSelection) => string;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Redacted document output with stable entity mapping.
|
|
222
|
+
*/
|
|
223
|
+
type RedactionResult = {
|
|
224
|
+
redactedText: string;
|
|
225
|
+
/**
|
|
226
|
+
* Maps placeholder to original text. Only populated for
|
|
227
|
+
* reversible operators (replace). Empty for redact, keep, and mask.
|
|
228
|
+
*/
|
|
229
|
+
redactionMap: Map<string, string>;
|
|
230
|
+
/** Maps placeholder to the operator that produced it. */
|
|
231
|
+
operatorMap: Map<string, OperatorType>;
|
|
232
|
+
entityCount: number;
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Configuration for the detection pipeline.
|
|
236
|
+
*/
|
|
237
|
+
type DenyListCategory = "Names" | "Places" | "Addresses" | "Courts" | "Financial" | "Government" | "Healthcare" | "Education" | "Political" | "Organizations" | "International";
|
|
238
|
+
/**
|
|
239
|
+
* Metadata for a single dictionary entry in the
|
|
240
|
+
* deny-list system. Mirrors the shape from
|
|
241
|
+
* the anonymize-data package so consumers can pass
|
|
242
|
+
* pre-loaded data without a runtime dependency.
|
|
243
|
+
*/
|
|
244
|
+
type DictionaryMeta = {
|
|
245
|
+
label: string;
|
|
246
|
+
category: DenyListCategory;
|
|
247
|
+
country: string | null;
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Caller-supplied exact terms for deny-list matching.
|
|
251
|
+
* These entries are merged with the published deny-list
|
|
252
|
+
* dictionaries when `enableDenyList` is enabled.
|
|
253
|
+
*/
|
|
254
|
+
type CustomDenyListEntry = {
|
|
255
|
+
value: string;
|
|
256
|
+
label: string;
|
|
257
|
+
variants?: readonly string[];
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Caller-supplied regex detector. The pattern is passed
|
|
261
|
+
* to the native Rust regex engine, so use its supported
|
|
262
|
+
* regex syntax. Inline flags such as `(?i)` are accepted
|
|
263
|
+
* when supported by that engine.
|
|
264
|
+
*/
|
|
265
|
+
type CustomRegexPattern = {
|
|
266
|
+
pattern: string;
|
|
267
|
+
label: string;
|
|
268
|
+
score?: number;
|
|
269
|
+
preparedArtifactPolicy?: "include" | "omit";
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Pre-loaded dictionary data for dependency injection.
|
|
273
|
+
* Consumers that want name/city/deny-list detection
|
|
274
|
+
* load dictionaries themselves (e.g. from the
|
|
275
|
+
* anonymize-data package) and pass them here; the
|
|
276
|
+
* anonymize package has zero cross-package imports.
|
|
277
|
+
*
|
|
278
|
+
* All fields are optional. When a field is absent,
|
|
279
|
+
* the corresponding detection path is skipped (same
|
|
280
|
+
* behavior as when no dictionaries are available).
|
|
281
|
+
*/
|
|
282
|
+
type Dictionaries = {
|
|
283
|
+
/**
|
|
284
|
+
* First names per language code (e.g., "cs", "de").
|
|
285
|
+
*/
|
|
286
|
+
firstNames?: Readonly<Record<string, readonly string[]>>;
|
|
287
|
+
/**
|
|
288
|
+
* Surnames per language code.
|
|
289
|
+
*/
|
|
290
|
+
surnames?: Readonly<Record<string, readonly string[]>>;
|
|
291
|
+
/**
|
|
292
|
+
* Non-Western name tokens per locale code
|
|
293
|
+
* (e.g., "in", "ar", "ja-latn", "ko", "zh-latn",
|
|
294
|
+
* "th", "vi", "fil", "id"). Merged with bundled
|
|
295
|
+
* names-nw-*.json data at init time.
|
|
296
|
+
*/
|
|
297
|
+
nonWesternNames?: Readonly<Record<string, readonly string[]>>;
|
|
298
|
+
/**
|
|
299
|
+
* Pre-loaded deny-list dictionaries keyed by
|
|
300
|
+
* dictionary ID (e.g., "courts/CZ", "banks/DE").
|
|
301
|
+
* Each value is the array of terms for that
|
|
302
|
+
* dictionary.
|
|
303
|
+
*/
|
|
304
|
+
denyList?: Readonly<Record<string, readonly string[]>>;
|
|
305
|
+
/**
|
|
306
|
+
* Metadata per dictionary ID. Required when
|
|
307
|
+
* `denyList` is provided so the pipeline knows
|
|
308
|
+
* labels, categories, and country filters.
|
|
309
|
+
*/
|
|
310
|
+
denyListMeta?: Readonly<Record<string, DictionaryMeta>>;
|
|
311
|
+
/**
|
|
312
|
+
* Pre-loaded city names, already merged across
|
|
313
|
+
* all desired countries.
|
|
314
|
+
*
|
|
315
|
+
* Prefer `citiesByCountry` when callers also pass
|
|
316
|
+
* `denyListCountries` / `denyListRegions`; merged
|
|
317
|
+
* city arrays cannot be scoped after injection.
|
|
318
|
+
*/
|
|
319
|
+
cities?: readonly string[];
|
|
320
|
+
/**
|
|
321
|
+
* Pre-loaded city names keyed by ISO 3166-1 alpha-2
|
|
322
|
+
* country code. When provided, the deny-list builder
|
|
323
|
+
* applies `denyListCountries` / `denyListRegions`
|
|
324
|
+
* before adding city patterns to the search automaton.
|
|
325
|
+
*/
|
|
326
|
+
citiesByCountry?: Readonly<Record<string, readonly string[]>>;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Street-address detection without a known-city anchor.
|
|
330
|
+
*/
|
|
331
|
+
type StandaloneStreetDetection = "off" | "houseNumberAnchored";
|
|
332
|
+
type PipelineConfig = {
|
|
333
|
+
threshold: number;
|
|
334
|
+
enableTriggerPhrases: boolean;
|
|
335
|
+
enableRegex: boolean;
|
|
336
|
+
/**
|
|
337
|
+
* Expected content language codes. When present, these
|
|
338
|
+
* derive default dictionary scopes for name corpus and
|
|
339
|
+
* deny-list matching unless the lower-level scope fields
|
|
340
|
+
* below are set explicitly.
|
|
341
|
+
*/
|
|
342
|
+
languages?: string[];
|
|
343
|
+
/**
|
|
344
|
+
* Convenience form for single-language documents. Ignored
|
|
345
|
+
* when `languages` is also provided.
|
|
346
|
+
*/
|
|
347
|
+
language?: string;
|
|
348
|
+
/**
|
|
349
|
+
* Enables legal-form organization detection.
|
|
350
|
+
* Required for typed callers; legacy untyped
|
|
351
|
+
* callers that omit this field are treated as
|
|
352
|
+
* enabled at runtime for backward compatibility.
|
|
353
|
+
*/
|
|
354
|
+
enableLegalForms: boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Enables first-name/surname/title corpus matching.
|
|
357
|
+
* When deny-list mode is enabled, this also controls
|
|
358
|
+
* whether name-corpus entries are injected into the
|
|
359
|
+
* deny-list search automaton.
|
|
360
|
+
*/
|
|
361
|
+
enableNameCorpus: boolean;
|
|
362
|
+
/**
|
|
363
|
+
* Optional language scope for first-name/surname
|
|
364
|
+
* dictionaries, using the keys present in
|
|
365
|
+
* `dictionaries.firstNames` / `dictionaries.surnames`
|
|
366
|
+
* (for example `["en", "de"]`). When omitted, all
|
|
367
|
+
* injected name languages are used for backward
|
|
368
|
+
* compatibility.
|
|
369
|
+
*/
|
|
370
|
+
nameCorpusLanguages?: string[];
|
|
371
|
+
enableDenyList: boolean;
|
|
372
|
+
denyListCountries?: string[];
|
|
373
|
+
denyListRegions?: string[];
|
|
374
|
+
denyListExcludeCategories?: string[];
|
|
375
|
+
/**
|
|
376
|
+
* Caller-owned exact terms to match through the
|
|
377
|
+
* deny-list layer. Requires `enableDenyList: true`.
|
|
378
|
+
*/
|
|
379
|
+
customDenyList?: readonly CustomDenyListEntry[];
|
|
380
|
+
/**
|
|
381
|
+
* Caller-owned regex detectors. Requires
|
|
382
|
+
* `enableRegex: true`.
|
|
383
|
+
*/
|
|
384
|
+
customRegexes?: readonly CustomRegexPattern[];
|
|
385
|
+
enableGazetteer: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* Detect country names (ISO 3166-1 names, curated
|
|
388
|
+
* aliases, alpha-3 codes). Defaults to true. Names
|
|
389
|
+
* span all manifest languages plus widely-used
|
|
390
|
+
* additions (Dutch, Russian, Chinese, Arabic, etc.).
|
|
391
|
+
*/
|
|
392
|
+
enableCountries?: boolean;
|
|
393
|
+
enableConfidenceBoost: boolean;
|
|
394
|
+
enableCoreference: boolean;
|
|
395
|
+
enableZoneClassification?: boolean;
|
|
396
|
+
enableHotwordRules?: boolean;
|
|
397
|
+
/**
|
|
398
|
+
* Detect a street address that carries no known-city
|
|
399
|
+
* anchor. Defaults to `"off"`.
|
|
400
|
+
*
|
|
401
|
+
* `"houseNumberAnchored"` accepts a street-type word
|
|
402
|
+
* with a house number directly beside it, in either
|
|
403
|
+
* order ("14 Rue de la Paix", "Hauptstraße 5",
|
|
404
|
+
* "123 Main Street"). A bare street name with no
|
|
405
|
+
* number never fires.
|
|
406
|
+
*
|
|
407
|
+
* A street-type word plus a nearby number is a much
|
|
408
|
+
* weaker signal than a city-anchored address and does
|
|
409
|
+
* fire on contract prose ("District Court 2019"), so
|
|
410
|
+
* this stays opt-in per workspace.
|
|
411
|
+
*/
|
|
412
|
+
standaloneStreetDetection?: StandaloneStreetDetection;
|
|
413
|
+
/**
|
|
414
|
+
* Requested output labels. An empty array means
|
|
415
|
+
* "do not filter by label" for deterministic detectors.
|
|
416
|
+
*/
|
|
417
|
+
labels: string[];
|
|
418
|
+
workspaceId: string;
|
|
419
|
+
/**
|
|
420
|
+
* Pre-loaded dictionary data for name, deny-list,
|
|
421
|
+
* and city detection. When omitted, dictionary-based
|
|
422
|
+
* detection paths are skipped. Consumers load from
|
|
423
|
+
* the anonymize-data package and pass the data here.
|
|
424
|
+
*/
|
|
425
|
+
dictionaries?: Dictionaries;
|
|
426
|
+
};
|
|
427
|
+
//#endregion
|
|
428
|
+
export { TriggerRule as _, Dictionaries as a, GazetteerEntry as c, PipelineConfig as d, RedactionResult as f, TriggerGroupConfig as g, TriggerExtension as h, DenyListCategory as i, OperatorConfig as l, ReviewedEntity as m, CustomDenyListEntry as n, DictionaryMeta as o, ReviewDecision as p, CustomRegexPattern as r, Entity as s, AnonymisationOperator as t, OperatorSelection as u, TriggerStrategy as v, TriggerValidation as y };
|
|
429
|
+
//# sourceMappingURL=types.d.mts.map
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/anonymize",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Deterministic PII detection and anonymization with regex, deny lists, and coreference resolution",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anonymization",
|
|
@@ -104,24 +104,18 @@
|
|
|
104
104
|
"smoke:wasm-browser": "node scripts/smoke-wasm-browser.mjs",
|
|
105
105
|
"format": "oxfmt ."
|
|
106
106
|
},
|
|
107
|
-
"
|
|
107
|
+
"dependencies": {
|
|
108
108
|
"@stll/anonymize-data": "^0.0.10"
|
|
109
109
|
},
|
|
110
|
-
"peerDependenciesMeta": {
|
|
111
|
-
"@stll/anonymize-data": {
|
|
112
|
-
"optional": true
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
110
|
"optionalDependencies": {
|
|
116
|
-
"@stll/anonymize-darwin-arm64": "2.
|
|
117
|
-
"@stll/anonymize-darwin-x64": "2.
|
|
118
|
-
"@stll/anonymize-linux-arm64-gnu": "2.
|
|
119
|
-
"@stll/anonymize-linux-x64-gnu": "2.
|
|
120
|
-
"@stll/anonymize-win32-x64-msvc": "2.
|
|
111
|
+
"@stll/anonymize-darwin-arm64": "2.9.0",
|
|
112
|
+
"@stll/anonymize-darwin-x64": "2.9.0",
|
|
113
|
+
"@stll/anonymize-linux-arm64-gnu": "2.9.0",
|
|
114
|
+
"@stll/anonymize-linux-x64-gnu": "2.9.0",
|
|
115
|
+
"@stll/anonymize-win32-x64-msvc": "2.9.0"
|
|
121
116
|
},
|
|
122
117
|
"devDependencies": {
|
|
123
118
|
"@napi-rs/cli": "^3.8.6",
|
|
124
|
-
"@stll/anonymize-data": "workspace:*",
|
|
125
119
|
"bun-types": "1.4.0",
|
|
126
120
|
"fast-check": "^4.9.0",
|
|
127
121
|
"fflate": "^0.8.3",
|
|
@@ -6,7 +6,12 @@ import { pathToFileURL } from "node:url";
|
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_NATIVE_PIPELINE_CONFIG,
|
|
8
8
|
prepareNativePipelinePackage,
|
|
9
|
+
SUPPORTED_LANGUAGES,
|
|
9
10
|
} from "../dist/index.mjs";
|
|
11
|
+
import {
|
|
12
|
+
applyPipelineLanguageScope,
|
|
13
|
+
defaultDictionaryBundleOptions,
|
|
14
|
+
} from "../dist/build-native-package.mjs";
|
|
10
15
|
import { loadNativeAnonymizeBinding } from "../dist/native-node.mjs";
|
|
11
16
|
|
|
12
17
|
const args = parseArgs(process.argv.slice(2));
|
|
@@ -100,20 +105,20 @@ function requiredValue(values, index, option) {
|
|
|
100
105
|
|
|
101
106
|
async function loadPackageInput(options) {
|
|
102
107
|
const input = await loadBasePackageInput(options);
|
|
108
|
+
const scopedConfig = applyPipelineLanguageScope(
|
|
109
|
+
applyCliLanguageScope(input.config, options),
|
|
110
|
+
);
|
|
103
111
|
const withDictionaries =
|
|
104
|
-
!options.defaultDictionaries ||
|
|
105
|
-
? input
|
|
112
|
+
!options.defaultDictionaries || scopedConfig.dictionaries !== undefined
|
|
113
|
+
? { ...input, config: scopedConfig }
|
|
106
114
|
: {
|
|
107
115
|
...input,
|
|
108
116
|
config: {
|
|
109
|
-
...
|
|
110
|
-
dictionaries: await loadDefaultDictionaries(),
|
|
117
|
+
...scopedConfig,
|
|
118
|
+
dictionaries: await loadDefaultDictionaries(scopedConfig),
|
|
111
119
|
},
|
|
112
120
|
};
|
|
113
|
-
return
|
|
114
|
-
...withDictionaries,
|
|
115
|
-
config: applyCliLanguageScope(withDictionaries.config, options),
|
|
116
|
-
};
|
|
121
|
+
return withDictionaries;
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
async function loadBasePackageInput(options) {
|
|
@@ -171,6 +176,11 @@ function normalizeLanguageOption(value, option) {
|
|
|
171
176
|
if (language.length === 0) {
|
|
172
177
|
throw new Error(`${option} requires a non-empty language code`);
|
|
173
178
|
}
|
|
179
|
+
if (!SUPPORTED_LANGUAGES.includes(language)) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Unsupported pipeline language ${JSON.stringify(value)}; expected one of: ${SUPPORTED_LANGUAGES.join(", ")}`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
174
184
|
return language;
|
|
175
185
|
}
|
|
176
186
|
|
|
@@ -185,7 +195,7 @@ function normalizeLanguageList(value) {
|
|
|
185
195
|
return languages;
|
|
186
196
|
}
|
|
187
197
|
|
|
188
|
-
async function loadDefaultDictionaries() {
|
|
198
|
+
async function loadDefaultDictionaries(pipelineConfig) {
|
|
189
199
|
let loaded;
|
|
190
200
|
try {
|
|
191
201
|
// The bundle loads city dictionaries, so it ships in the data package's
|
|
@@ -203,7 +213,9 @@ async function loadDefaultDictionaries() {
|
|
|
203
213
|
"@stll/anonymize-data/cities does not export loadDictionaryBundle",
|
|
204
214
|
);
|
|
205
215
|
}
|
|
206
|
-
return loaded.loadDictionaryBundle(
|
|
216
|
+
return loaded.loadDictionaryBundle(
|
|
217
|
+
defaultDictionaryBundleOptions(pipelineConfig),
|
|
218
|
+
);
|
|
207
219
|
}
|
|
208
220
|
|
|
209
221
|
function formatError(error) {
|