@blindfold/sdk 1.0.2
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/LICENSE +21 -0
- package/README.md +427 -0
- package/dist/index-CsE6Vhax.d.mts +177 -0
- package/dist/index-CsE6Vhax.d.mts.map +1 -0
- package/dist/index-Dfv8zV_d.d.ts +177 -0
- package/dist/index-Dfv8zV_d.d.ts.map +1 -0
- package/dist/index.d.mts +450 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +450 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +575 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +568 -0
- package/dist/index.mjs.map +1 -0
- package/dist/regex/index.d.mts +2 -0
- package/dist/regex/index.d.ts +2 -0
- package/dist/regex/index.js +5 -0
- package/dist/regex/index.mjs +4 -0
- package/dist/regex-BEaK0E7Y.js +4881 -0
- package/dist/regex-BEaK0E7Y.js.map +1 -0
- package/dist/regex-ByjZg3Zy.mjs +4839 -0
- package/dist/regex-ByjZg3Zy.mjs.map +1 -0
- package/package.json +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Blindfold
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Blindfold JS SDK
|
|
2
|
+
|
|
3
|
+
Detect, redact, tokenize, and mask PII in JavaScript/TypeScript. 80+ entity types, 30+ countries, works offline with zero dependencies.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@blindfold/sdk)
|
|
6
|
+
[](https://github.com/blindfold-dev/blindfold/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## Why Blindfold?
|
|
9
|
+
|
|
10
|
+
- **Works offline, zero dependencies** — No API key needed for local detection. No network calls. No external packages.
|
|
11
|
+
- **80+ PII entity types** across 30+ countries with checksum validation (Luhn, IBAN mod-97, Verhoeff, etc.)
|
|
12
|
+
- **85x faster than Presidio** — 0.4s vs 34s on 3,000 samples ([benchmark](https://blindfold.dev/blog/pii-detection-benchmark))
|
|
13
|
+
- **Higher accuracy** — F1 58.6% vs Presidio 38.8% on AI4Privacy multilingual benchmark
|
|
14
|
+
- **8 operations**: detect, redact, tokenize, detokenize, mask, hash, encrypt, synthesize
|
|
15
|
+
- **Compliance-ready** — Built-in GDPR, HIPAA, PCI-DSS policies
|
|
16
|
+
- **Optional NLP upgrade** — Add API key to detect names, addresses, organizations (60+ additional entities)
|
|
17
|
+
- **Batch processing**, typed errors, full TypeScript support
|
|
18
|
+
|
|
19
|
+
## Quick Comparison
|
|
20
|
+
|
|
21
|
+
| Feature | Blindfold | Presidio | regex-only |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| Entity types (local) | 80+ | ~20 | Custom |
|
|
24
|
+
| Countries | 30+ | ~5 | Custom |
|
|
25
|
+
| Checksum validation | Luhn, mod-97, Verhoeff, ... | Partial | No |
|
|
26
|
+
| Speed (3K samples) | 0.4s | 34s | Varies |
|
|
27
|
+
| Zero dependencies | Yes | No (spaCy) | Yes |
|
|
28
|
+
| NLP upgrade path | Yes (API) | Yes (built-in) | No |
|
|
29
|
+
| Tokenize/detokenize | Yes | No | No |
|
|
30
|
+
|
|
31
|
+
## Common Use Cases
|
|
32
|
+
|
|
33
|
+
- **Sanitize LLM prompts** — Strip PII before sending to OpenAI, Anthropic, etc.
|
|
34
|
+
- **PII-safe RAG pipelines** — Redact before embedding, restore after retrieval
|
|
35
|
+
- **Log scrubbing** — Anonymize data in logs and data pipelines
|
|
36
|
+
- **GDPR/HIPAA compliance** — Built-in policies for AI applications
|
|
37
|
+
- **Synthetic test data** — Format-preserving fake data generation
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install @blindfold/sdk
|
|
43
|
+
# or
|
|
44
|
+
yarn add @blindfold/sdk
|
|
45
|
+
# or
|
|
46
|
+
pnpm add @blindfold/sdk
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start (no API key needed)
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { Blindfold } from '@blindfold/sdk'
|
|
53
|
+
|
|
54
|
+
const client = new Blindfold()
|
|
55
|
+
|
|
56
|
+
// Detect PII locally — no API key, no network call
|
|
57
|
+
const result = await client.detect("Email john@acme.com, SSN 123-45-6789")
|
|
58
|
+
for (const entity of result.detected_entities) {
|
|
59
|
+
console.log(`${entity.type}: ${entity.text} (score: ${entity.score})`)
|
|
60
|
+
}
|
|
61
|
+
// Email Address: john@acme.com (score: 0.95)
|
|
62
|
+
// Social Security Number: 123-45-6789 (score: 1.0)
|
|
63
|
+
|
|
64
|
+
// Redact PII locally
|
|
65
|
+
const redacted = await client.redact("Email john@acme.com, SSN 123-45-6789")
|
|
66
|
+
console.log(redacted.text)
|
|
67
|
+
// "Email, SSN"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Protect AI Prompts
|
|
71
|
+
|
|
72
|
+
Tokenize PII before sending to any LLM. The AI never sees real data.
|
|
73
|
+
|
|
74
|
+
### OpenAI
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { Blindfold } from '@blindfold/sdk'
|
|
78
|
+
import OpenAI from 'openai'
|
|
79
|
+
|
|
80
|
+
const bf = new Blindfold() // Free local mode
|
|
81
|
+
const openai = new OpenAI()
|
|
82
|
+
|
|
83
|
+
// 1. Tokenize PII
|
|
84
|
+
const safe = await bf.tokenize("My name is John Smith, email john@acme.com")
|
|
85
|
+
// safe.text → "My name is <Person_1>, email <Email Address_1>"
|
|
86
|
+
|
|
87
|
+
// 2. Send to GPT — PII never reaches OpenAI
|
|
88
|
+
const response = await openai.chat.completions.create({
|
|
89
|
+
model: 'gpt-4o',
|
|
90
|
+
messages: [{ role: 'user', content: safe.text }]
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// 3. Restore original data
|
|
94
|
+
const result = bf.detokenize(response.choices[0].message.content, safe.mapping)
|
|
95
|
+
console.log(result.text)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Anthropic Claude
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { Blindfold } from '@blindfold/sdk'
|
|
102
|
+
import Anthropic from '@anthropic-ai/sdk'
|
|
103
|
+
|
|
104
|
+
const bf = new Blindfold()
|
|
105
|
+
const anthropic = new Anthropic()
|
|
106
|
+
|
|
107
|
+
const safe = await bf.tokenize("My name is John Smith, email john@acme.com")
|
|
108
|
+
|
|
109
|
+
const response = await anthropic.messages.create({
|
|
110
|
+
model: 'claude-sonnet-4-20250514',
|
|
111
|
+
max_tokens: 1024,
|
|
112
|
+
messages: [{ role: 'user', content: safe.text }]
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const result = bf.detokenize(response.content[0].text, safe.mapping)
|
|
116
|
+
console.log(result.text)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Works with any AI provider:** OpenAI, Anthropic Claude, Google Gemini, AWS Bedrock, Azure OpenAI, LangChain, LlamaIndex, Vercel AI SDK, CrewAI — [see all integrations](https://docs.blindfold.dev/integrations).
|
|
120
|
+
|
|
121
|
+
## Upgrade to Blindfold API (optional)
|
|
122
|
+
|
|
123
|
+
For names, addresses, organizations, and 60+ entity types, add your API key:
|
|
124
|
+
|
|
125
|
+
1. Sign up at [blindfold.dev](https://www.blindfold.dev/)
|
|
126
|
+
2. Get your API key at [app.blindfold.dev/api-keys](https://app.blindfold.dev/api-keys)
|
|
127
|
+
3. Set environment variable: `BLINDFOLD_API_KEY=sk-***`
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// With API key — auto-switches to NLP-powered API
|
|
131
|
+
const client = new Blindfold({ apiKey: 'sk-...' })
|
|
132
|
+
const result = await client.detect("John Smith lives at 123 Oak Street")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Initialization
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { Blindfold } from '@blindfold/sdk'
|
|
139
|
+
|
|
140
|
+
// Local mode (no API key) — regex-based detection
|
|
141
|
+
const client = new Blindfold()
|
|
142
|
+
|
|
143
|
+
// API mode (with API key) — NLP-powered detection
|
|
144
|
+
const client = new Blindfold({ apiKey: 'sk-...' })
|
|
145
|
+
|
|
146
|
+
// Force local mode even with an API key (useful for latency-critical paths)
|
|
147
|
+
const client = new Blindfold({ apiKey: 'sk-...', mode: 'local' })
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Operations
|
|
151
|
+
|
|
152
|
+
### Tokenize (Reversible)
|
|
153
|
+
|
|
154
|
+
Replace sensitive data with reversible tokens (e.g., `<Person_1>`).
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const response = await client.tokenize(
|
|
158
|
+
"Contact John Doe at john@example.com",
|
|
159
|
+
{
|
|
160
|
+
policy: 'gdpr_eu', // Optional: 'hipaa_us', 'basic', 'pci_dss', 'strict'
|
|
161
|
+
entities: ['person', 'email address'], // Optional: filter entities
|
|
162
|
+
score_threshold: 0.4 // Optional: confidence threshold
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
console.log(response.text)
|
|
167
|
+
// "Contact <Person_1> at <Email Address_1>"
|
|
168
|
+
|
|
169
|
+
console.log(response.mapping)
|
|
170
|
+
// { "<Person_1>": "John Doe", "<Email Address_1>": "john@example.com" }
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Detokenize
|
|
174
|
+
|
|
175
|
+
Restore original values from tokens. Runs **client-side** — no API call.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// No await needed — runs locally!
|
|
179
|
+
const original = client.detokenize(
|
|
180
|
+
"AI response for <Person_1>",
|
|
181
|
+
response.mapping
|
|
182
|
+
)
|
|
183
|
+
console.log(original.text)
|
|
184
|
+
// "AI response for John Doe"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Redact
|
|
188
|
+
|
|
189
|
+
Permanently remove sensitive data.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const response = await client.redact(
|
|
193
|
+
"My password is secret123",
|
|
194
|
+
{ entities: ['person', 'email address'] }
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Mask
|
|
199
|
+
|
|
200
|
+
Partially hide sensitive data (e.g., `****-****-****-1234`).
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const response = await client.mask(
|
|
204
|
+
"Credit card: 4532-7562-9102-3456",
|
|
205
|
+
{ masking_char: '*', chars_to_show: 4, from_end: true }
|
|
206
|
+
)
|
|
207
|
+
console.log(response.text)
|
|
208
|
+
// "Credit card: ***************3456"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Hash
|
|
212
|
+
|
|
213
|
+
Replace data with deterministic hashes (useful for analytics/matching).
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const response = await client.hash(
|
|
217
|
+
"User ID: 12345",
|
|
218
|
+
{ hash_type: 'sha256', hash_prefix: 'ID_' }
|
|
219
|
+
)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Encrypt
|
|
223
|
+
|
|
224
|
+
Encrypt sensitive data using AES (reversible with key).
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const response = await client.encrypt(
|
|
228
|
+
"Secret message",
|
|
229
|
+
{ encryption_key: 'your-secure-key-min-16-chars' }
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Synthesize
|
|
234
|
+
|
|
235
|
+
Replace real data with realistic fake data. Works offline with format-preserving generation.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// Works offline — no API key required
|
|
239
|
+
const client = new Blindfold()
|
|
240
|
+
const response = await client.synthesize("Email john@acme.com, SSN 123-45-6789")
|
|
241
|
+
console.log(response.text)
|
|
242
|
+
// "Email user3a9f1b2c@example.com, SSN 847-29-3156"
|
|
243
|
+
|
|
244
|
+
// With API key — NLP-powered synthesis (names, addresses, etc.)
|
|
245
|
+
const response = await client.synthesize(
|
|
246
|
+
"John lives in New York",
|
|
247
|
+
{ language: 'en' }
|
|
248
|
+
)
|
|
249
|
+
console.log(response.text)
|
|
250
|
+
// "Michael lives in Boston"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Batch Processing
|
|
254
|
+
|
|
255
|
+
Process multiple texts in a single request (max 100 texts):
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const result = await client.tokenizeBatch(
|
|
259
|
+
["Contact John Doe", "jane@example.com", "No PII here"],
|
|
260
|
+
{ policy: "gdpr_eu" }
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
console.log(result.total) // 3
|
|
264
|
+
console.log(result.succeeded) // 3
|
|
265
|
+
console.log(result.failed) // 0
|
|
266
|
+
|
|
267
|
+
result.results.forEach(item => console.log(item.text))
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
All methods have batch variants: `tokenizeBatch`, `detectBatch`, `redactBatch`, `maskBatch`, `synthesizeBatch`, `hashBatch`, `encryptBatch`.
|
|
271
|
+
|
|
272
|
+
## Local PII Scanner
|
|
273
|
+
|
|
274
|
+
The built-in regex scanner works offline with zero dependencies. Use it directly for fine-grained control:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { PIIScanner, EntityType } from '@blindfold/sdk/regex'
|
|
278
|
+
|
|
279
|
+
// Default: US locale
|
|
280
|
+
const scanner = new PIIScanner()
|
|
281
|
+
const matches = scanner.detect("Call me at john@acme.com or 555-867-5309")
|
|
282
|
+
|
|
283
|
+
for (const match of matches) {
|
|
284
|
+
console.log(`${match.entityType}: ${match.text} (score: ${match.score})`)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Redact PII
|
|
288
|
+
const { text, matches: redacted } = scanner.redact("SSN 123-45-6789, CC 4532015112830366")
|
|
289
|
+
console.log(text)
|
|
290
|
+
// "SSN, CC"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Multi-locale support
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// US + EU entities
|
|
297
|
+
const scanner = new PIIScanner({ locales: ['us', 'eu'] })
|
|
298
|
+
const matches = scanner.detect("SSN 123-45-6789, IBAN DE89370400440532013000")
|
|
299
|
+
|
|
300
|
+
// UK entities
|
|
301
|
+
const scanner = new PIIScanner({ locales: ['uk'] })
|
|
302
|
+
const matches = scanner.detect("NI number: AB 12 34 56 A")
|
|
303
|
+
|
|
304
|
+
// All locales
|
|
305
|
+
const scanner = new PIIScanner({ locales: ['us', 'eu', 'uk'] })
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Filter by entity type
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
// Only detect emails and credit cards
|
|
312
|
+
const scanner = new PIIScanner({ entities: [EntityType.EMAIL, EntityType.CREDIT_CARD] })
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Error Handling
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { AuthenticationError, APIError, NetworkError } from '@blindfold/sdk'
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
await client.tokenize("...")
|
|
322
|
+
} catch (error) {
|
|
323
|
+
if (error instanceof AuthenticationError) {
|
|
324
|
+
// Handle invalid API key
|
|
325
|
+
} else if (error instanceof APIError) {
|
|
326
|
+
// Handle API error (e.g. validation)
|
|
327
|
+
} else if (error instanceof NetworkError) {
|
|
328
|
+
// Handle network issues
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
<details>
|
|
334
|
+
<summary><strong>Supported local entity types (80+)</strong></summary>
|
|
335
|
+
|
|
336
|
+
| Entity Type | Locale | Validation |
|
|
337
|
+
|---|---|---|
|
|
338
|
+
| Email Address | Universal | RFC 5322 pattern |
|
|
339
|
+
| Credit Card Number | Universal | Luhn checksum |
|
|
340
|
+
| Phone Number | Universal | Format + digit count |
|
|
341
|
+
| IP Address (v4/v6) | Universal | Octet range |
|
|
342
|
+
| URL | Universal | TLD validation |
|
|
343
|
+
| MAC Address | Universal | Pattern |
|
|
344
|
+
| Date of Birth | Universal | Context-required |
|
|
345
|
+
| CVV/CVC | Universal | Context-required |
|
|
346
|
+
| Social Security Number | US | Format rules + context |
|
|
347
|
+
| Driver's License | US | Multi-state formats + context |
|
|
348
|
+
| US Passport | US | Context-required |
|
|
349
|
+
| Tax ID / EIN | US | Prefix validation + context |
|
|
350
|
+
| ZIP Code | US | Context-required + validator |
|
|
351
|
+
| US ITIN | US | Format validation |
|
|
352
|
+
| IBAN | EU | ISO 7064 mod-97 checksum |
|
|
353
|
+
| Postal Code | EU | DE/FR/NL patterns |
|
|
354
|
+
| VAT ID | EU | Country prefix + format |
|
|
355
|
+
| UK NI Number | UK | Format validation |
|
|
356
|
+
| UK NHS Number | UK | Modulus-11 checksum |
|
|
357
|
+
| UK Postcode | UK | Pattern |
|
|
358
|
+
| UK Passport | UK | Context-required |
|
|
359
|
+
| UK UTR | UK | Mod-11 checksum |
|
|
360
|
+
| German Personal ID | DE | Context-required |
|
|
361
|
+
| German Tax ID | DE | Check digit |
|
|
362
|
+
| French National ID (NIR) | FR | Check digit |
|
|
363
|
+
| French SIREN | FR | Luhn checksum |
|
|
364
|
+
| Spanish DNI | ES | Letter validation |
|
|
365
|
+
| Spanish NIE | ES | Letter validation |
|
|
366
|
+
| Spanish NSS | ES | Mod-97 checksum |
|
|
367
|
+
| Spanish CIF | ES | Custom checksum |
|
|
368
|
+
| Italian Codice Fiscale | IT | Check digit |
|
|
369
|
+
| Italian Partita IVA | IT | Luhn-like checksum |
|
|
370
|
+
| Portuguese NIF | PT | Check digit |
|
|
371
|
+
| Dutch BSN | NL | Modulus-11 check |
|
|
372
|
+
| Belgian National Number | BE | Mod-97 checksum |
|
|
373
|
+
| Belgian Enterprise Number | BE | Mod-97 checksum |
|
|
374
|
+
| Austrian SVNR | AT | Mod-11 checksum |
|
|
375
|
+
| Swiss AHV | CH | EAN-13 checksum |
|
|
376
|
+
| Irish PPS Number | IE | Mod-23 checksum |
|
|
377
|
+
| Polish PESEL | PL | Check digit |
|
|
378
|
+
| Polish NIP | PL | Check digit |
|
|
379
|
+
| Polish REGON | PL | Mod-11 checksum |
|
|
380
|
+
| Czech Birth Number | CZ | Modulus validation |
|
|
381
|
+
| Czech ICO (Company ID) | CZ | Mod-11 weighted checksum |
|
|
382
|
+
| Czech DIC (Tax/VAT ID) | CZ | ICO checksum / mod-11 |
|
|
383
|
+
| Czech Bank Account | CZ | Mod-11 weighted checksum |
|
|
384
|
+
| Slovak Birth Number | SK | Modulus validation |
|
|
385
|
+
| Slovak ICO | SK | Mod-11 weighted checksum |
|
|
386
|
+
| Slovak DIC | SK | Mod-11 divisibility |
|
|
387
|
+
| Romanian CNP | RO | Check digit |
|
|
388
|
+
| Romanian CUI | RO | Mod-11 checksum |
|
|
389
|
+
| Danish CPR | DK | Date validation |
|
|
390
|
+
| Danish CVR | DK | Mod-11 checksum |
|
|
391
|
+
| Swedish Personnummer | SE | Luhn algorithm |
|
|
392
|
+
| Swedish Organisationsnummer | SE | Luhn algorithm |
|
|
393
|
+
| Norwegian Birth Number | NO | Check digit |
|
|
394
|
+
| Norwegian Organisasjonsnummer | NO | Mod-11 checksum |
|
|
395
|
+
| Finnish HETU | FI | Mod-31 checksum |
|
|
396
|
+
| Finnish Y-tunnus | FI | Mod-11 checksum |
|
|
397
|
+
| Hungarian Tax ID | HU | Mod-11 checksum |
|
|
398
|
+
| Hungarian TAJ | HU | Mod-10 checksum |
|
|
399
|
+
| Bulgarian EGN | BG | Mod-11 checksum |
|
|
400
|
+
| Croatian OIB | HR | ISO 7064 MOD 11,2 |
|
|
401
|
+
| Slovenian EMSO | SI | Mod-11 checksum |
|
|
402
|
+
| Slovenian Tax Number | SI | Mod-11 checksum |
|
|
403
|
+
| Lithuanian Personal Code | LT | Dual-pass mod-11 |
|
|
404
|
+
| Latvian Personal Code | LV | Weighted checksum |
|
|
405
|
+
| Estonian Personal Code | EE | Dual-pass mod-11 |
|
|
406
|
+
| Russian INN | RU | Check digit |
|
|
407
|
+
| Russian SNILS | RU | Check digit |
|
|
408
|
+
| Canadian SIN | CA | Luhn checksum |
|
|
409
|
+
| Australian TFN | AU | Mod-11 checksum |
|
|
410
|
+
| Australian Medicare | AU | Mod-10 checksum |
|
|
411
|
+
| New Zealand IRD | NZ | Dual-pass mod-11 |
|
|
412
|
+
| Indian Aadhaar | IN | Verhoeff algorithm |
|
|
413
|
+
| Indian PAN | IN | Format validation |
|
|
414
|
+
| Japanese My Number | JP | Mod-11 checksum |
|
|
415
|
+
| Korean RRN | KR | Weighted checksum |
|
|
416
|
+
| South African ID | ZA | Luhn checksum |
|
|
417
|
+
| Turkish Kimlik | TR | Custom dual check |
|
|
418
|
+
| Israeli ID | IL | Luhn checksum |
|
|
419
|
+
| Brazilian CPF | BR | Check digit |
|
|
420
|
+
| Brazilian CNPJ | BR | Check digit |
|
|
421
|
+
| Argentine CUIT | AR | Mod-11 checksum |
|
|
422
|
+
| Chilean RUT | CL | Mod-11 with K |
|
|
423
|
+
| Colombian NIT | CO | Mod-11 prime weights |
|
|
424
|
+
|
|
425
|
+
> Add your [API key](#upgrade-to-blindfold-api-optional) to unlock names, addresses, organizations, and 60+ additional entity types with NLP-powered detection.
|
|
426
|
+
|
|
427
|
+
</details>
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
//#region src/regex/entities.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* PII entity types detected by the regex scanner.
|
|
4
|
+
* Names match the Blindfold API entity types for transparent switching.
|
|
5
|
+
*/
|
|
6
|
+
declare enum EntityType {
|
|
7
|
+
EMAIL_ADDRESS = "Email Address",
|
|
8
|
+
CREDIT_CARD = "Credit Card Number",
|
|
9
|
+
PHONE_NUMBER = "Phone Number",
|
|
10
|
+
IP_ADDRESS = "IP Address",
|
|
11
|
+
URL = "URL",
|
|
12
|
+
MAC_ADDRESS = "MAC Address",
|
|
13
|
+
DATE_OF_BIRTH = "Date of Birth",
|
|
14
|
+
CVV = "CVV",
|
|
15
|
+
SSN = "Social Security Number",
|
|
16
|
+
DRIVERS_LICENSE = "Driver's License",
|
|
17
|
+
US_PASSPORT = "US Passport",
|
|
18
|
+
TAX_ID = "Tax ID",
|
|
19
|
+
ZIP_CODE = "ZIP Code",
|
|
20
|
+
IBAN = "IBAN",
|
|
21
|
+
EU_POSTAL_CODE = "Postal Code",
|
|
22
|
+
VAT_ID = "VAT ID",
|
|
23
|
+
NI_NUMBER = "NI Number",
|
|
24
|
+
NHS_NUMBER = "NHS Number",
|
|
25
|
+
UK_POSTCODE = "UK Postcode",
|
|
26
|
+
UK_PASSPORT = "UK Passport",
|
|
27
|
+
DE_PERSONAL_ID = "German Personal ID",
|
|
28
|
+
DE_TAX_ID = "German Tax ID",
|
|
29
|
+
FR_NATIONAL_ID = "French National ID",
|
|
30
|
+
ES_DNI = "Spanish DNI",
|
|
31
|
+
ES_NIE = "Spanish NIE",
|
|
32
|
+
IT_CODICE_FISCALE = "Italian Codice Fiscale",
|
|
33
|
+
PT_NIF = "Portuguese NIF",
|
|
34
|
+
PL_PESEL = "Polish PESEL",
|
|
35
|
+
PL_NIP = "Polish NIP",
|
|
36
|
+
CZ_BIRTH_NUMBER = "Czech Birth Number",
|
|
37
|
+
CZ_ICO = "Czech ICO",
|
|
38
|
+
CZ_DIC = "Czech DIC",
|
|
39
|
+
CZ_BANK_ACCOUNT = "Czech Bank Account",
|
|
40
|
+
RU_INN = "Russian INN",
|
|
41
|
+
RU_SNILS = "Russian SNILS",
|
|
42
|
+
NL_BSN = "Dutch BSN",
|
|
43
|
+
RO_CNP = "Romanian CNP",
|
|
44
|
+
SK_BIRTH_NUMBER = "Slovak Birth Number",
|
|
45
|
+
DK_CPR = "Danish CPR",
|
|
46
|
+
SE_PERSONNUMMER = "Swedish Personnummer",
|
|
47
|
+
NO_BIRTH_NUMBER = "Norwegian Birth Number",
|
|
48
|
+
BR_CPF = "Brazilian CPF",
|
|
49
|
+
BR_CNPJ = "Brazilian CNPJ",
|
|
50
|
+
US_ITIN = "US ITIN",
|
|
51
|
+
UK_UTR = "UK UTR",
|
|
52
|
+
FR_SIREN = "French SIREN",
|
|
53
|
+
ES_NSS = "Spanish NSS",
|
|
54
|
+
ES_CIF = "Spanish CIF",
|
|
55
|
+
IT_PARTITA_IVA = "Italian Partita IVA",
|
|
56
|
+
PL_REGON = "Polish REGON",
|
|
57
|
+
SK_ICO = "Slovak ICO",
|
|
58
|
+
SK_DIC = "Slovak DIC",
|
|
59
|
+
RO_CUI = "Romanian CUI",
|
|
60
|
+
DK_CVR = "Danish CVR",
|
|
61
|
+
SE_ORGNR = "Swedish Organisationsnummer",
|
|
62
|
+
NO_ORGNR = "Norwegian Organisasjonsnummer",
|
|
63
|
+
BE_NATIONAL_NUMBER = "Belgian National Number",
|
|
64
|
+
BE_ENTERPRISE_NUMBER = "Belgian Enterprise Number",
|
|
65
|
+
AT_SVNR = "Austrian SVNR",
|
|
66
|
+
IE_PPS = "Irish PPS Number",
|
|
67
|
+
FI_HETU = "Finnish HETU",
|
|
68
|
+
FI_YTUNNUS = "Finnish Y-tunnus",
|
|
69
|
+
HU_TAX_ID = "Hungarian Tax ID",
|
|
70
|
+
HU_TAJ = "Hungarian TAJ",
|
|
71
|
+
BG_EGN = "Bulgarian EGN",
|
|
72
|
+
HR_OIB = "Croatian OIB",
|
|
73
|
+
SI_EMSO = "Slovenian EMSO",
|
|
74
|
+
SI_TAX_NUMBER = "Slovenian Tax Number",
|
|
75
|
+
LT_PERSONAL_CODE = "Lithuanian Personal Code",
|
|
76
|
+
LV_PERSONAL_CODE = "Latvian Personal Code",
|
|
77
|
+
EE_PERSONAL_CODE = "Estonian Personal Code",
|
|
78
|
+
CA_SIN = "Canadian SIN",
|
|
79
|
+
CH_AHV = "Swiss AHV",
|
|
80
|
+
AU_TFN = "Australian TFN",
|
|
81
|
+
AU_MEDICARE = "Australian Medicare",
|
|
82
|
+
NZ_IRD = "New Zealand IRD",
|
|
83
|
+
IN_AADHAAR = "Indian Aadhaar",
|
|
84
|
+
IN_PAN = "Indian PAN",
|
|
85
|
+
JP_MY_NUMBER = "Japanese My Number",
|
|
86
|
+
KR_RRN = "Korean RRN",
|
|
87
|
+
ZA_ID = "South African ID",
|
|
88
|
+
TR_KIMLIK = "Turkish Kimlik",
|
|
89
|
+
IL_ID = "Israeli ID",
|
|
90
|
+
AR_CUIT = "Argentine CUIT",
|
|
91
|
+
CL_RUT = "Chilean RUT",
|
|
92
|
+
CO_NIT = "Colombian NIT",
|
|
93
|
+
}
|
|
94
|
+
/** A single PII match found by a detector. */
|
|
95
|
+
interface PIIMatch {
|
|
96
|
+
entityType: string;
|
|
97
|
+
text: string;
|
|
98
|
+
start: number;
|
|
99
|
+
end: number;
|
|
100
|
+
score: number;
|
|
101
|
+
} //#endregion
|
|
102
|
+
//#region src/regex/scanner.d.ts
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=entities.d.ts.map
|
|
105
|
+
interface PIIScannerOptions {
|
|
106
|
+
/** List of locale codes to enable (default: ["us"]). */
|
|
107
|
+
locales?: string[];
|
|
108
|
+
}
|
|
109
|
+
interface TokenizeResult {
|
|
110
|
+
text: string;
|
|
111
|
+
mapping: Record<string, string>;
|
|
112
|
+
matches: PIIMatch[];
|
|
113
|
+
}
|
|
114
|
+
interface MaskResult {
|
|
115
|
+
text: string;
|
|
116
|
+
matches: PIIMatch[];
|
|
117
|
+
}
|
|
118
|
+
interface HashResult {
|
|
119
|
+
text: string;
|
|
120
|
+
matches: PIIMatch[];
|
|
121
|
+
}
|
|
122
|
+
interface EncryptResult {
|
|
123
|
+
text: string;
|
|
124
|
+
matches: PIIMatch[];
|
|
125
|
+
}
|
|
126
|
+
interface SynthesizeResult {
|
|
127
|
+
text: string;
|
|
128
|
+
matches: PIIMatch[];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Local regex-based PII scanner.
|
|
132
|
+
*
|
|
133
|
+
* Usage:
|
|
134
|
+
* const scanner = new PIIScanner({ locales: ['us', 'eu'] })
|
|
135
|
+
* const matches = scanner.detect('Email john@acme.com, SSN 123-45-6789')
|
|
136
|
+
* const [redacted, matches] = scanner.redact('Email john@acme.com')
|
|
137
|
+
*/
|
|
138
|
+
declare class PIIScanner {
|
|
139
|
+
private registry;
|
|
140
|
+
constructor(options?: PIIScannerOptions);
|
|
141
|
+
/** Detect PII entities in text and return deduplicated matches. */
|
|
142
|
+
detect(text: string, entities?: string[]): PIIMatch[];
|
|
143
|
+
/**
|
|
144
|
+
* Detect and remove PII from text.
|
|
145
|
+
* Returns a tuple of [redactedText, detectedMatches].
|
|
146
|
+
*/
|
|
147
|
+
redact(text: string, entities?: string[]): [string, PIIMatch[]];
|
|
148
|
+
/**
|
|
149
|
+
* Detect PII and replace with numbered tokens like `<Email Address_1>`.
|
|
150
|
+
* Returns tokenized text, a mapping from tokens to original values, and matches.
|
|
151
|
+
*/
|
|
152
|
+
tokenize(text: string, entities?: string[]): TokenizeResult;
|
|
153
|
+
/**
|
|
154
|
+
* Detect PII and partially mask each match.
|
|
155
|
+
*/
|
|
156
|
+
mask(text: string, charsToShow?: number, fromEnd?: boolean, maskingChar?: string, entities?: string[]): MaskResult;
|
|
157
|
+
/**
|
|
158
|
+
* Detect PII and replace each match with a deterministic hash.
|
|
159
|
+
*/
|
|
160
|
+
hash(text: string, hashType?: string, hashPrefix?: string, hashLength?: number, entities?: string[]): HashResult;
|
|
161
|
+
/**
|
|
162
|
+
* Detect PII and encrypt each match with AES-256-CBC.
|
|
163
|
+
* @param encryptionKey - Required, minimum 16 characters.
|
|
164
|
+
*/
|
|
165
|
+
encrypt(text: string, encryptionKey: string, entities?: string[]): EncryptResult;
|
|
166
|
+
/**
|
|
167
|
+
* Detect PII and replace each match with format-preserving synthetic data.
|
|
168
|
+
* @param _language - Accepted for API compatibility but ignored locally.
|
|
169
|
+
*/
|
|
170
|
+
synthesize(text: string, _language?: string, entities?: string[]): SynthesizeResult;
|
|
171
|
+
/** Remove overlapping matches, preferring higher score then longer span. */
|
|
172
|
+
private deduplicate;
|
|
173
|
+
} //#endregion
|
|
174
|
+
|
|
175
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
176
|
+
export { EntityType as EntityType$1, PIIMatch, PIIScanner as PIIScanner$1, PIIScannerOptions };
|
|
177
|
+
//# sourceMappingURL=index-CsE6Vhax.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CsE6Vhax.d.mts","names":[],"sources":["../src/regex/entities.ts","../src/regex/scanner.ts"],"sourcesContent":null,"mappings":";;;;;aAMY,UAAA;EAAA,aAAU,GAAA,eAAA;;EAqML,YAAQ,GAAA,cAAA;;;;ECjMR,aAAA,GAAA,eAAiB;EAKjB,GAAA,GAAA,KAAA;EAAc,GAAA,GAAA,wBAAA;EAAA,eAEpB,GAAA,kBAAA;EAAM,WACN,GAAA,aAAA;EAAQ,MAAA,GAAA,QAAA;EAGF,QAAA,GAAA,UAAU;EAKV,IAAA,GAAA,MAAU;EAKV,cAAA,GAAa,aAEnB;EAGM,MAAA,GAAA,QAAA;;;;;;;;;EAaJ,MAAA,GAAA,aAAU;EAAA,iBAAA,GAAA,wBAAA;EAAA,MAGC,GAAA,gBAAA;EAAiB,QAKI,GAAA,cAAA;EAAQ,MAwBC,GAAA,YAAA;EAAQ,eAsBf,GAAA,oBAAA;EAAc,MAwCxD,GAAA,WAAA;EAAU,MAiCV,GAAA,WAAA;EAAU,eAsBsD,GAAA,oBAAA;EAAa,MA+Bb,GAAA,aAAA;EAAgB,QAAA,GAAA,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UD1BpE,QAAA;;;;;;;;;;UCjMA,iBAAA;;;ADJjB;UCSiB,cAAA;ED4LA,IAAA,EAAA,MAAQ;WC1Ld;WACA;;AARM,UAWA,UAAA,CAXiB;EAKjB,IAAA,EAAA,MAAA;EAAc,OAAA,EAQpB,QARoB,EAAA;;AAGpB,UAQM,UAAA,CARN;EAAQ,IAAA,EAAA,MAAA;EAGF,OAAA,EAON,QAPgB,EAAA;AAK3B;AAKiB,UAAA,aAAA,CAEN;EAGM,IAAA,EAAA,MAAA;WAHN;;UAGM,gBAAA;;WAEN;;;;AAWX;;;;;;AA8FK,cA9FQ,UAAA,CA8FR;EAAU,QAiCV,QAAA;EAAU,WAsBsD,CAAA,OAAA,CAAA,EAlJ7C,iBAkJ6C;EAAa;EA+BG,MAAA,CAAA,IAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,MAAA,EAAA,CAAA,EA5KxC,QA4KwC,EAAA;;;;;sDApJ/B;;;;;+CAsBP;;;;0GAwC1C;;;;wGAiCA;;;;;qEAsBgE;;;;;qEA+BA"}
|