@cognipeer/pii
v0.1.1
Published
Offline PII detection for Turkish and English -- regex + checksum + a built-in gazetteer, plus an optional bundled 0.7 MB char-CNN NER model. CPU-only, no network calls.
Keywords
Readme
@cognipeer/pii (Node)
Offline PII detection for Turkish and English. CPU-only, no network calls. See the repository README for the full picture (why this exists, cross-language parity, benchmarks); this file covers the Node API.
Install
npm install @cognipeer/piiZero dependencies for the pattern and pattern+dictionary tiers.
The pattern+dictionary+ner tier runs a bundled 1.45 MB (int8,
Gather-only quantised) char-CNN -- the model file ships inside this package,
nothing is downloaded at install or at runtime. It needs the ONNX runtime to
execute it, declared as an optionalDependency:
npm install onnxruntime-nodeUsage
const pii = require('@cognipeer/pii');
// Synchronous: pattern tier only (email, phone, IBAN, TC Kimlik, ...)
pii.detect('e-postam [email protected], IBAN: TR330006100519786457841326');
pii.redact('...'); // findings removed from outputText
pii.mask('...'); // findings replaced with [CATEGORY] placeholders
// Reversible tokenization
const { outputText, vault } = pii.tokenizeText('Kart no: 4111111111111111');
pii.detokenizeText(outputText, vault); // restores the original text
// Async: opt into the dictionary tier (person/organization/location)
const result = await pii.detectAsync(
'Ahmet Yılmaz, Cognipeer Teknoloji A.Ş.\'de çalışıyor.',
{ detection: { mode: 'pattern+dictionary' } },
);
// Async: add the bundled char-CNN tagger, which finds names the gazetteer
// has never heard of. Still CPU-only and offline.
const withNer = await pii.detectAsync(text, {
detection: {
mode: 'pattern+dictionary+ner',
ner: { minScore: 0.5, maxConcurrent: 2, timeoutMs: 1500 },
},
});
// Async: the CNN as a JUDGE instead of another vote -- re-scores every
// pattern/dictionary candidate by how much the CNN agrees with that exact
// span (up OR down), rather than only ever reinforcing it. See the
// repository README's "pattern+ner-verified" section for the full math.
const verified = await pii.detectAsync(text, {
detection: { mode: 'pattern+ner-verified' },
});Options
detect/redact/mask/tokenizeText and their Async counterparts share
one options object:
| Option | Default | What it does |
|---|---|---|
| categories | all defaultEnabled categories on | { email: true, tc_kimlik: false, ... } -- explicitly enable/disable per category |
| customPatterns | none | your own regex rules, run through a bounded vm.Script timeout so a catastrophic pattern can't hang the process |
| languages | undefined (all) | restrict to categories tagged for these languages, e.g. ['tr'] |
| locale | 'en' | passed through to category label lookups |
| detection.mode | 'pattern' | 'pattern' | 'pattern+dictionary' | 'pattern+dictionary+ner' | 'pattern+ner-verified' |
| detection.ner | -- | { minScore?, maxChars?, timeoutMs?, maxConcurrent?, failMode?, decode? }. decode is 'argmax' (default, used by pattern+dictionary+ner) or 'viterbi' (BIO-constrained, used by pattern+ner-verified). Missing onnxruntime-node degrades to the dictionary tier with a note in degraded, it never throws. |
| detection.verify | see README | pattern+ner-verified-only: { agreeWeight: 0.5, floor: 0.25, checksumFloor: 0.7, contextFloor: 0.8, dictionaryFloor: 0.5, nerOnlyWeight: 0.6, nerOnlyNumberWeight: 0.35 } |
Categories
31 built-in categories (11 on by default) -- import categories/
categoriesById from the package to inspect them, or see the table and the
"front tier" section in the repository README for which ones and why.
Testing
npm install
npm test # unit tests + parity fixtures
node test/ner.js # char-CNN contract tests + Viterbi/BIO decoding
node test/verify.js # pattern+ner-verified fusion math (injected agreements, no model needed)
node --test # everything at onceBenchmarking
See the top-level README's Benchmarks section, and
benchmarks/BENCHMARK.md for the reference
numbers on the shipped model.
