@stll/anonymize-wasm 1.1.1 → 1.3.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.
Files changed (59) hide show
  1. package/dist/address-boundaries.mjs +113 -5
  2. package/dist/address-stop-keywords.mjs +137 -0
  3. package/dist/address-stop-keywords.mjs.map +1 -0
  4. package/dist/address-stopwords.mjs +81 -0
  5. package/dist/address-stopwords.mjs.map +1 -0
  6. package/dist/address-street-types.mjs +67 -4
  7. package/dist/clause-noun-heads.mjs +75 -0
  8. package/dist/clause-noun-heads.mjs.map +1 -0
  9. package/dist/coreference.es.mjs +22 -0
  10. package/dist/coreference.es.mjs.map +1 -0
  11. package/dist/coreference.fr.mjs +32 -0
  12. package/dist/coreference.fr.mjs.map +1 -0
  13. package/dist/coreference.it.mjs +27 -0
  14. package/dist/coreference.it.mjs.map +1 -0
  15. package/dist/coreference.pl.mjs +27 -0
  16. package/dist/coreference.pl.mjs.map +1 -0
  17. package/dist/coreference.pt-br.mjs +14 -0
  18. package/dist/coreference.pt-br.mjs.map +1 -0
  19. package/dist/coreference.sk.mjs +22 -5
  20. package/dist/generic-roles.mjs +179 -1
  21. package/dist/hotword-rules.mjs +7 -3
  22. package/dist/legal-forms.mjs +3 -0
  23. package/dist/legal-role-heads.cs.mjs +42 -0
  24. package/dist/legal-role-heads.cs.mjs.map +1 -0
  25. package/dist/legal-role-heads.de.mjs +33 -0
  26. package/dist/legal-role-heads.de.mjs.map +1 -0
  27. package/dist/legal-role-heads.en.mjs +37 -0
  28. package/dist/legal-role-heads.en.mjs.map +1 -0
  29. package/dist/legal-role-heads.es.mjs +54 -0
  30. package/dist/legal-role-heads.es.mjs.map +1 -0
  31. package/dist/legal-role-heads.fr.mjs +72 -0
  32. package/dist/legal-role-heads.fr.mjs.map +1 -0
  33. package/dist/legal-role-heads.it.mjs +68 -0
  34. package/dist/legal-role-heads.it.mjs.map +1 -0
  35. package/dist/legal-role-heads.pl.mjs +84 -0
  36. package/dist/legal-role-heads.pl.mjs.map +1 -0
  37. package/dist/legal-role-heads.pt-br.mjs +63 -0
  38. package/dist/legal-role-heads.pt-br.mjs.map +1 -0
  39. package/dist/legal-role-heads.sk.mjs +80 -0
  40. package/dist/legal-role-heads.sk.mjs.map +1 -0
  41. package/dist/manifest.mjs +21 -8
  42. package/dist/names-exclusions.mjs +21 -1
  43. package/dist/person-stopwords.mjs +121 -1
  44. package/dist/section-headings.mjs +15 -3
  45. package/dist/sentence-verb-indicators.mjs +223 -0
  46. package/dist/sentence-verb-indicators.mjs.map +1 -0
  47. package/dist/triggers.cs.mjs +107 -3
  48. package/dist/triggers.es.mjs +43 -4
  49. package/dist/triggers.fr.mjs +206 -7
  50. package/dist/triggers.it.mjs +26 -4
  51. package/dist/triggers.pl.mjs +191 -4
  52. package/dist/triggers.pt-br.mjs +193 -0
  53. package/dist/triggers.pt-br.mjs.map +1 -0
  54. package/dist/triggers.sk.mjs +493 -0
  55. package/dist/vite.mjs.map +1 -1
  56. package/dist/wasm.d.mts +100 -8
  57. package/dist/wasm.mjs +2520 -1360
  58. package/dist/wasm.mjs.map +1 -1
  59. package/package.json +2 -2
package/dist/wasm.d.mts CHANGED
@@ -35,6 +35,7 @@ type Entity = {
35
35
  text: string;
36
36
  score: number;
37
37
  source: DetectionSource;
38
+ sourceDetail?: "custom-deny-list" | "custom-regex";
38
39
  };
39
40
  /**
40
41
  * Entity after human review. Extends the base Entity
@@ -61,6 +62,16 @@ type GazetteerEntry = {
61
62
  /** Extraction strategy — closed discriminated union. */
62
63
  type TriggerStrategy = {
63
64
  type: "to-next-comma";
65
+ /**
66
+ * Optional list of lowercase keywords that terminate
67
+ * the value scan, in addition to commas/newlines. Useful
68
+ * for triggers like court names that may continue past
69
+ * a missing comma into adjacent clause text ("Městským
70
+ * soudem v Praze dne 1. 1. 2020"); listing `"dne"` here
71
+ * stops the scan at the date boundary. Matched on a
72
+ * word-boundary, case-insensitive.
73
+ */
74
+ stopWords?: string[];
64
75
  } | {
65
76
  type: "to-end-of-line";
66
77
  } | {
@@ -71,6 +82,19 @@ type TriggerStrategy = {
71
82
  } | {
72
83
  type: "address";
73
84
  maxChars?: number;
85
+ } | {
86
+ /**
87
+ * Extract the first regex match in the value text.
88
+ * Useful for shape-bounded values that follow a
89
+ * label on the same line as other fields, where
90
+ * `to-end-of-line` would over-capture. The pattern
91
+ * is anchored to the start of the (already
92
+ * leading-whitespace-stripped) value, so use
93
+ * `(?:.*?)` prefix only when intentional.
94
+ */
95
+ type: "match-pattern";
96
+ pattern: string;
97
+ flags?: string;
74
98
  };
75
99
  /** Validation rules — closed discriminated union. */
76
100
  type TriggerValidation = {
@@ -89,7 +113,21 @@ type TriggerValidation = {
89
113
  type: "matches-pattern";
90
114
  pattern: string;
91
115
  flags?: string;
116
+ }
117
+ /**
118
+ * Run a named stdnum validator (checksum + length)
119
+ * against the captured value. Keeps the trigger
120
+ * path symmetrical with the formatted-regex
121
+ * detectors so e.g. `CPF nº 00000000000` does not
122
+ * survive as a tax-ID entity.
123
+ */
124
+ | {
125
+ type: "valid-id";
126
+ validator: ValidIdValidator;
92
127
  };
128
+ /** Built-in stdnum validators that can be referenced
129
+ * by `valid-id` validations. */
130
+ type ValidIdValidator = "br.cpf" | "br.cnpj";
93
131
  /** Auto-generated trigger variants — closed set. */
94
132
  type TriggerExtension = "add-colon" | "add-trailing-space" | "add-colon-space" | "normalize-spaces";
95
133
  /** V2 trigger config entry (JSON shape). */
@@ -123,6 +161,9 @@ type CompiledValidation = {
123
161
  } | {
124
162
  type: "matches-pattern";
125
163
  re: RegExp;
164
+ } | {
165
+ type: "valid-id";
166
+ check: (value: string) => boolean;
126
167
  };
127
168
  /**
128
169
  * Runtime rule — one per trigger string after
@@ -185,6 +226,27 @@ type DictionaryMeta = {
185
226
  category: DenyListCategory;
186
227
  country: string | null;
187
228
  };
229
+ /**
230
+ * Caller-supplied exact terms for deny-list matching.
231
+ * These entries are merged with the published deny-list
232
+ * dictionaries when `enableDenyList` is enabled.
233
+ */
234
+ type CustomDenyListEntry = {
235
+ value: string;
236
+ label: string;
237
+ variants?: readonly string[];
238
+ };
239
+ /**
240
+ * Caller-supplied regex detector. The pattern is passed
241
+ * to the underlying text-search regex engine, so use its
242
+ * supported regex syntax. Inline flags such as `(?i)` are
243
+ * accepted when supported by that engine.
244
+ */
245
+ type CustomRegexPattern = {
246
+ pattern: string;
247
+ label: string;
248
+ score?: number;
249
+ };
188
250
  /**
189
251
  * Pre-loaded dictionary data for dependency injection.
190
252
  * Consumers that want name/city/deny-list detection
@@ -248,6 +310,16 @@ type PipelineConfig = {
248
310
  denyListCountries?: string[];
249
311
  denyListRegions?: string[];
250
312
  denyListExcludeCategories?: string[];
313
+ /**
314
+ * Caller-owned exact terms to match through the
315
+ * deny-list layer. Requires `enableDenyList: true`.
316
+ */
317
+ customDenyList?: readonly CustomDenyListEntry[];
318
+ /**
319
+ * Caller-owned regex detectors. Requires
320
+ * `enableRegex: true`.
321
+ */
322
+ customRegexes?: readonly CustomRegexPattern[];
251
323
  enableGazetteer: boolean;
252
324
  enableNer: boolean;
253
325
  enableConfidenceBoost: boolean;
@@ -278,12 +350,13 @@ type PipelineConfig = {
278
350
  * every pipeline run and never persisted to the database.
279
351
  * Renaming a label here requires no migration.
280
352
  */
281
- declare const DEFAULT_ENTITY_LABELS: readonly ["person", "organization", "phone number", "address", "email address", "date", "date of birth", "bank account number", "iban", "tax identification number", "identity card number", "registration number", "credit card number", "passport number", "monetary amount", "land parcel"];
353
+ declare const DEFAULT_ENTITY_LABELS: readonly ["person", "organization", "phone number", "address", "email address", "date", "date of birth", "bank account number", "iban", "tax identification number", "identity card number", "birth number", "national identification number", "social security number", "registration number", "credit card number", "passport number", "monetary amount", "land parcel", "misc"];
282
354
  //#endregion
283
355
  //#region src/detectors/regex.d.ts
284
356
  type RegexMeta = {
285
357
  label: string;
286
- score: number; /** Post-match stdnum validator for confirmation. */
358
+ score: number;
359
+ sourceDetail?: Entity["sourceDetail"]; /** Post-match stdnum validator for confirmation. */
287
360
  validator?: Validator;
288
361
  };
289
362
  /** Flat pattern array for text-search. */
@@ -320,15 +393,16 @@ declare const CURRENCY_PATTERN_META: Readonly<RegexMeta>;
320
393
  declare const processRegexMatches: (allMatches: Match[], sliceStart: number, sliceEnd: number, meta_: readonly RegexMeta[]) => Entity[];
321
394
  //#endregion
322
395
  //#region src/detectors/deny-list.d.ts
323
- type DenyListConfig = Pick<PipelineConfig, "enableDenyList" | "enableNameCorpus" | "denyListCountries" | "denyListRegions" | "denyListExcludeCategories" | "dictionaries">;
396
+ type DenyListConfig = Pick<PipelineConfig, "enableDenyList" | "enableNameCorpus" | "denyListCountries" | "denyListRegions" | "denyListExcludeCategories" | "customDenyList" | "dictionaries">;
324
397
  /**
325
398
  * Source tag for each pattern in the automaton.
326
399
  * "deny-list" = standard deny list entry
400
+ * "custom-deny-list" = caller-owned exact term
327
401
  * "first-name" = name corpus first name
328
402
  * "surname" = name corpus surname
329
403
  * "title" = academic/professional title
330
404
  */
331
- type PatternSource = "deny-list" | "first-name" | "surname" | "title";
405
+ type PatternSource = "deny-list" | "custom-deny-list" | "first-name" | "surname" | "title";
332
406
  /**
333
407
  * Pre-built deny list data. Constructed once by
334
408
  * `buildDenyList`, reused across `processDenyListMatches`
@@ -342,7 +416,8 @@ type DenyListData = {
342
416
  * appears in multiple dictionaries (e.g., "Denver"
343
417
  * is both a person name and a city name).
344
418
  */
345
- labels: string[][]; /** Maps pattern index → original pattern text. */
419
+ labels: string[][]; /** Maps pattern index → labels contributed by custom entries. */
420
+ customLabels: string[][]; /** Maps pattern index → original pattern text. */
346
421
  originals: string[]; /** Maps pattern index → source types (plural). */
347
422
  sources: PatternSource[][];
348
423
  };
@@ -396,10 +471,12 @@ type GazetteerData = {
396
471
  isFuzzy: boolean[];
397
472
  };
398
473
  type UnifiedSearchInstance = {
399
- /** Regex + triggers + legal-forms. */tsRegex: TextSearch; /** Deny-list + street-types + gazetteer. */
474
+ /** Regex + triggers + legal-forms. */tsRegex: TextSearch; /** Caller-owned custom regexes, isolated for overlap preservation. */
475
+ tsCustomRegex: TextSearch; /** Deny-list + street-types + gazetteer. */
400
476
  tsLiterals: TextSearch;
401
477
  slices: {
402
478
  regex: PatternSlice;
479
+ customRegex: PatternSlice;
403
480
  legalForms: PatternSlice;
404
481
  triggers: PatternSlice;
405
482
  denyList: PatternSlice;
@@ -407,6 +484,7 @@ type UnifiedSearchInstance = {
407
484
  gazetteer: PatternSlice;
408
485
  };
409
486
  regexMeta: readonly RegexMeta[];
487
+ customRegexMeta: readonly RegexMeta[];
410
488
  triggerRules: readonly TriggerRule[];
411
489
  denyListData: DenyListData | null;
412
490
  gazetteerData: GazetteerData | null;
@@ -464,7 +542,9 @@ type PipelineContext = {
464
542
  allowList: ReadonlySet<string> | null;
465
543
  allowListPromise: Promise<ReadonlySet<string>> | null;
466
544
  personStopwords: ReadonlySet<string> | null;
467
- personStopwordsPromise: Promise<ReadonlySet<string>> | null; /** First-name exclusions for stopword filtering. */
545
+ personStopwordsPromise: Promise<ReadonlySet<string>> | null;
546
+ addressStopwords: ReadonlySet<string> | null;
547
+ addressStopwordsPromise: Promise<ReadonlySet<string>> | null; /** First-name exclusions for stopword filtering. */
468
548
  firstNameExclusions: ReadonlySet<string> | null;
469
549
  firstNameExclusionCorpusLen: number;
470
550
  genericRoles: ReadonlySet<string> | null;
@@ -589,6 +669,7 @@ declare const DEFAULT_OPERATOR_CONFIG: OperatorConfig;
589
669
  declare const resolveOperator: (config: OperatorConfig, label: string) => OperatorType;
590
670
  //#endregion
591
671
  //#region src/detectors/legal-forms.d.ts
672
+ declare const warmLegalRoleHeads: () => Promise<void>;
592
673
  /**
593
674
  * Build legal form regex pattern strings.
594
675
  * Returns an array of regex strings for the unified
@@ -600,6 +681,14 @@ declare const buildLegalFormPatterns: () => Promise<string[]>;
600
681
  * Process legal form matches from the unified search.
601
682
  * Receives all matches; filters to the legal forms
602
683
  * slice via sliceStart/sliceEnd.
684
+ *
685
+ * The role-head trimming step reads per-language data from
686
+ * a cache that `runPipeline` warms via `warmLegalRoleHeads()`
687
+ * before calling this. Callers that invoke
688
+ * `processLegalFormMatches` directly (without going through
689
+ * `runPipeline`) must `await warmLegalRoleHeads()` first;
690
+ * otherwise the trim falls back to a no-op and sentence-
691
+ * fragment fixes do not apply.
603
692
  */
604
693
  declare const processLegalFormMatches: (allMatches: Match[], sliceStart: number, sliceEnd: number, fullText?: string) => Entity[];
605
694
  //#endregion
@@ -739,6 +828,7 @@ declare const detectNameCorpus: (fullText: string, ctx?: PipelineContext) => Ent
739
828
  //#region src/unified-search.d.ts
740
829
  type UnifiedResult = {
741
830
  /** All matches from both instances combined. */regexMatches: Match[];
831
+ customRegexMatches: Match[];
742
832
  literalMatches: Match[];
743
833
  };
744
834
  declare const runUnifiedSearch: (instance: UnifiedSearchInstance, fullText: string) => UnifiedResult;
@@ -780,6 +870,8 @@ type CountryCode = NonNullRegion[keyof NonNullRegion][number];
780
870
  declare const resolveCountries: (regions?: string[], countries?: string[]) => Set<string> | null;
781
871
  //#endregion
782
872
  //#region src/filters/false-positives.d.ts
873
+ /** Ensure street-type vocabulary is loaded. */
874
+ declare const initAddressComponents: () => Promise<void>;
783
875
  /**
784
876
  * Filter out entities that are likely false positives:
785
877
  * template placeholders, clause/section numbers,
@@ -996,5 +1088,5 @@ declare const levenshtein: (rawA: string, rawB: string) => number;
996
1088
  */
997
1089
  declare const normalizeForSearch: (text: string) => string;
998
1090
  //#endregion
999
- export { type AnonymisationOperator, CURRENCY_PATTERN_META, type CountryCode, DATE_PATTERN_META, DEFAULT_ENTITY_LABELS, DEFAULT_OPERATOR_CONFIG, DETECTION_SOURCES, DETECTOR_PRIORITY, type DefinitionPattern, type DenyListCategory, type DenyListData, type DetectionSource, type Dictionaries, type DictionaryMeta, type DocumentZone, type Entity, type EntityResult, type GazetteerData, type GazetteerEntry, type HotwordRule, type NameCorpusData, type NerInferenceFn, OPERATOR_REGISTRY, OPERATOR_TYPES, type OperatorConfig, type OperatorType, type PipelineConfig, type PipelineContext, type PipelineOptions, REGEX_META, REGEX_PATTERNS, REGIONS, type RawInferenceResult, type RedactionResult, type RegexMeta, type RegionId, type ReviewDecision, type ReviewedEntity, type TriggerExtension, type TriggerGroupConfig, type TriggerRule, type TriggerStrategy, type TriggerValidation, type UnifiedResult, type UnifiedSearchInstance, ZONE_SCORE_ADJUSTMENTS, type ZoneSpan, applyHotwordRules, applyZoneAdjustments, boostNearMissEntities, buildDenyList, buildGazetteerPatterns, buildLegalFormPatterns, buildPlaceholderMap, buildStreetTypePatterns, buildTriggerPatterns, buildUnifiedSearch, chunkText, classifyZones, computeChunkOffsets, corefKey, createPipelineContext, deanonymise, decodeSpans, decodeTokenSpans, detectNameCorpus, ensureDenyListData, exportRedactionKey, extractDefinedTerms, filterFalsePositives, findCoreferenceSpans, getCurrencyPatterns, getDatePatterns, initHotwordRules, initNameCorpus, initZoneClassifier, levenshtein, mergeAndDedup, mergeChunkEntities, normalizeForSearch, prepareBatch, processAddressSeeds, processDenyListMatches, processGazetteerMatches, processLegalFormMatches, processRegexMatches, processTriggerMatches, propagateOrgNames, redactText, resolveCountries, resolveOperator, runPipeline, runUnifiedSearch, sanitizeEntities, tokenizeText };
1091
+ export { type AnonymisationOperator, CURRENCY_PATTERN_META, type CountryCode, type CustomDenyListEntry, type CustomRegexPattern, DATE_PATTERN_META, DEFAULT_ENTITY_LABELS, DEFAULT_OPERATOR_CONFIG, DETECTION_SOURCES, DETECTOR_PRIORITY, type DefinitionPattern, type DenyListCategory, type DenyListData, type DetectionSource, type Dictionaries, type DictionaryMeta, type DocumentZone, type Entity, type EntityResult, type GazetteerData, type GazetteerEntry, type HotwordRule, type NameCorpusData, type NerInferenceFn, OPERATOR_REGISTRY, OPERATOR_TYPES, type OperatorConfig, type OperatorType, type PipelineConfig, type PipelineContext, type PipelineOptions, REGEX_META, REGEX_PATTERNS, REGIONS, type RawInferenceResult, type RedactionResult, type RegexMeta, type RegionId, type ReviewDecision, type ReviewedEntity, type TriggerExtension, type TriggerGroupConfig, type TriggerRule, type TriggerStrategy, type TriggerValidation, type UnifiedResult, type UnifiedSearchInstance, ZONE_SCORE_ADJUSTMENTS, type ZoneSpan, applyHotwordRules, applyZoneAdjustments, boostNearMissEntities, buildDenyList, buildGazetteerPatterns, buildLegalFormPatterns, buildPlaceholderMap, buildStreetTypePatterns, buildTriggerPatterns, buildUnifiedSearch, chunkText, classifyZones, computeChunkOffsets, corefKey, createPipelineContext, deanonymise, decodeSpans, decodeTokenSpans, detectNameCorpus, ensureDenyListData, exportRedactionKey, extractDefinedTerms, filterFalsePositives, findCoreferenceSpans, getCurrencyPatterns, getDatePatterns, initAddressComponents, initHotwordRules, initNameCorpus, initZoneClassifier, levenshtein, mergeAndDedup, mergeChunkEntities, normalizeForSearch, prepareBatch, processAddressSeeds, processDenyListMatches, processGazetteerMatches, processLegalFormMatches, processRegexMatches, processTriggerMatches, propagateOrgNames, redactText, resolveCountries, resolveOperator, runPipeline, runUnifiedSearch, sanitizeEntities, tokenizeText, warmLegalRoleHeads };
1000
1092
  //# sourceMappingURL=wasm.d.mts.map