euredact 0.0.1 → 0.1.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.
@@ -0,0 +1,624 @@
1
+ function clean(candidate, chars = /[\s.\-]/g) {
2
+ return candidate.replace(chars, "");
3
+ }
4
+ export function validateIban(candidate) {
5
+ const c = candidate.replace(/[\s\-]/g, "").toUpperCase();
6
+ if (c.length < 5 || !/^[A-Z]{2}/.test(c) || !/^\d{2}$/.test(c.slice(2, 4)))
7
+ return false;
8
+ const ibanLengths = {
9
+ AL: 28, AD: 24, AT: 20, AZ: 28, BH: 22, BY: 28, BE: 16, BA: 20, BR: 29, BG: 22, CR: 22, HR: 21,
10
+ CY: 28, CZ: 24, DK: 18, DO: 28, TL: 23, EE: 20, FO: 18, FI: 18, FR: 27, GE: 22, DE: 22, GI: 23,
11
+ GR: 27, GL: 18, GT: 28, HU: 28, IS: 26, IQ: 23, IE: 22, IL: 23, IT: 27, JO: 30, KZ: 20, XK: 20,
12
+ KW: 30, LV: 21, LB: 28, LI: 21, LT: 20, LU: 20, MT: 31, MR: 27, MU: 30, MC: 27, MD: 24, ME: 22,
13
+ NL: 18, MK: 19, NO: 15, PK: 24, PS: 29, PL: 28, PT: 25, QA: 29, RO: 24, LC: 32, SM: 27, SA: 24,
14
+ RS: 22, SC: 31, SK: 24, SI: 19, ES: 24, SE: 24, CH: 21, TN: 24, TR: 26, UA: 29, AE: 23, GB: 22,
15
+ VA: 22, VG: 24,
16
+ };
17
+ const country = c.slice(0, 2);
18
+ const expected = ibanLengths[country];
19
+ if (expected !== undefined && c.length !== expected)
20
+ return false;
21
+ const rearranged = c.slice(4) + c.slice(0, 4);
22
+ let numeric = "";
23
+ for (const ch of rearranged) {
24
+ if (/\d/.test(ch))
25
+ numeric += ch;
26
+ else if (/[A-Z]/.test(ch))
27
+ numeric += (ch.charCodeAt(0) - 55).toString();
28
+ else
29
+ return false;
30
+ }
31
+ // BigInt mod 97
32
+ let remainder = 0n;
33
+ for (let i = 0; i < numeric.length; i += 7) {
34
+ const chunk = remainder.toString() + numeric.slice(i, i + 7);
35
+ remainder = BigInt(chunk) % 97n;
36
+ }
37
+ return remainder === 1n;
38
+ }
39
+ export function validateBsn(candidate) {
40
+ const c = clean(candidate);
41
+ if (c.length !== 9 || !/^\d{9}$/.test(c) || c === "000000000")
42
+ return false;
43
+ const weights = [9, 8, 7, 6, 5, 4, 3, 2, -1];
44
+ let total = 0;
45
+ for (let i = 0; i < 9; i++)
46
+ total += parseInt(c[i]) * weights[i];
47
+ return total % 11 === 0 && total !== 0;
48
+ }
49
+ export function validateBelgianNn(candidate) {
50
+ const c = clean(candidate);
51
+ if (c.length !== 11 || !/^\d{11}$/.test(c))
52
+ return false;
53
+ const firstNine = parseInt(c.slice(0, 9));
54
+ const check = parseInt(c.slice(9, 11));
55
+ if (97 - (firstNine % 97) === check)
56
+ return true;
57
+ const firstNine2000 = parseInt("2" + c.slice(0, 9));
58
+ return 97 - (firstNine2000 % 97) === check;
59
+ }
60
+ export function validateLuhn(candidate) {
61
+ const c = candidate.replace(/[\s\-]/g, "");
62
+ if (!/^\d+$/.test(c) || c.length < 12)
63
+ return false;
64
+ let total = 0;
65
+ for (let i = c.length - 1; i >= 0; i--) {
66
+ let n = parseInt(c[i]);
67
+ if ((c.length - 1 - i) % 2 === 1) {
68
+ n *= 2;
69
+ if (n > 9)
70
+ n -= 9;
71
+ }
72
+ total += n;
73
+ }
74
+ return total % 10 === 0;
75
+ }
76
+ export function validateBelgianVat(candidate) {
77
+ let c = clean(candidate).toUpperCase();
78
+ if (c.startsWith("BE"))
79
+ c = c.slice(2);
80
+ if (c.length !== 10 || !/^\d{10}$/.test(c) || c[0] !== "0")
81
+ return false;
82
+ const firstPart = parseInt(c.slice(0, 8));
83
+ const check = parseInt(c.slice(8, 10));
84
+ return (firstPart % 97) === (97 - check) || (97 - (firstPart % 97)) === check;
85
+ }
86
+ export function validateVatNl(candidate) {
87
+ let c = clean(candidate).toUpperCase();
88
+ if (c.startsWith("NL"))
89
+ c = c.slice(2);
90
+ if (c.length !== 12)
91
+ return false;
92
+ return /^\d{9}B\d{2}$/.test(c);
93
+ }
94
+ export function validateVatDe(candidate) {
95
+ let c = clean(candidate).toUpperCase();
96
+ if (c.startsWith("DE"))
97
+ c = c.slice(2);
98
+ return c.length === 9 && /^\d{9}$/.test(c);
99
+ }
100
+ export function validateVatFr(candidate) {
101
+ let c = clean(candidate).toUpperCase();
102
+ if (c.startsWith("FR"))
103
+ c = c.slice(2);
104
+ if (c.length !== 11)
105
+ return false;
106
+ for (const ch of c.slice(0, 2)) {
107
+ if (!(/\d/.test(ch) || (/[A-Z]/.test(ch) && ch !== "O" && ch !== "I")))
108
+ return false;
109
+ }
110
+ return /^\d{9}$/.test(c.slice(2));
111
+ }
112
+ export function validateVatLu(candidate) {
113
+ let c = clean(candidate).toUpperCase();
114
+ if (c.startsWith("LU"))
115
+ c = c.slice(2);
116
+ return c.length === 8 && /^\d{8}$/.test(c);
117
+ }
118
+ export function validateGermanTaxId(candidate) {
119
+ const c = candidate.replace(/[\s.\-/]/g, "");
120
+ if (c.length !== 11 || !/^\d{11}$/.test(c) || c[0] === "0")
121
+ return false;
122
+ let product = 10;
123
+ for (let i = 0; i < 10; i++) {
124
+ let total = (parseInt(c[i]) + product) % 10;
125
+ if (total === 0)
126
+ total = 10;
127
+ product = (total * 2) % 11;
128
+ }
129
+ const check = (11 - product) % 10;
130
+ return check === parseInt(c[10]);
131
+ }
132
+ export function validateFrenchNir(candidate) {
133
+ const c = clean(candidate);
134
+ if (c.length !== 15)
135
+ return false;
136
+ let numeric = c;
137
+ const upper = c.toUpperCase();
138
+ if (!/^\d+$/.test(c)) {
139
+ if (upper.includes("A"))
140
+ numeric = upper.replace(/A/g, "0");
141
+ else if (upper.includes("B"))
142
+ numeric = upper.replace(/B/g, "0");
143
+ else
144
+ return false;
145
+ }
146
+ if (!/^\d+$/.test(numeric))
147
+ return false;
148
+ let first13 = parseInt(numeric.slice(0, 13));
149
+ if (upper.includes("A")) {
150
+ first13 = parseInt(upper.slice(0, 7).replace(/A/g, "0") + c.slice(7, 13)) - 1000000;
151
+ }
152
+ else if (upper.includes("B")) {
153
+ first13 = parseInt(upper.slice(0, 7).replace(/B/g, "0") + c.slice(7, 13)) - 2000000;
154
+ }
155
+ const check = parseInt(numeric.slice(13, 15));
156
+ return (97 - (first13 % 97)) === check;
157
+ }
158
+ export function validateVin(candidate) {
159
+ const c = candidate.replace(/[\s\-]/g, "").toUpperCase();
160
+ if (c.length !== 17)
161
+ return false;
162
+ return !/[IOQ]/.test(c);
163
+ }
164
+ export function validateBic(candidate) {
165
+ const c = candidate.replace(/ /g, "").toUpperCase();
166
+ if (c.length !== 8 && c.length !== 11)
167
+ return false;
168
+ if (!/^[A-Z]{4}/.test(c))
169
+ return false;
170
+ if (!/^[A-Z]{2}$/.test(c.slice(4, 6)))
171
+ return false;
172
+ if (!/^[A-Z0-9]{2}$/.test(c.slice(6, 8)))
173
+ return false;
174
+ if (c.length === 11 && !/^[A-Z0-9]{3}$/.test(c.slice(8, 11)))
175
+ return false;
176
+ return true;
177
+ }
178
+ export function validateKvk(candidate) {
179
+ const c = clean(candidate);
180
+ return c.length === 8 && /^\d{8}$/.test(c);
181
+ }
182
+ export function validateSwedishPnr(candidate) {
183
+ let c = candidate.replace(/[\s\-+]/g, "");
184
+ if (c.length === 12)
185
+ c = c.slice(2);
186
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
187
+ return false;
188
+ const month = parseInt(c.slice(2, 4));
189
+ const day = parseInt(c.slice(4, 6));
190
+ if (month < 1 || month > 12 || day < 1 || day > 31)
191
+ return false;
192
+ let total = 0;
193
+ for (let i = 0; i < 10; i++) {
194
+ let n = parseInt(c[i]) * (i % 2 === 0 ? 2 : 1);
195
+ total += Math.floor(n / 10) + (n % 10);
196
+ }
197
+ return total % 10 === 0;
198
+ }
199
+ export function validateNorwegianFnr(candidate) {
200
+ const c = candidate.replace(/[\s\-]/g, "");
201
+ if (c.length !== 11 || !/^\d{11}$/.test(c))
202
+ return false;
203
+ const d = c.split("").map(Number);
204
+ const w1 = [3, 7, 6, 1, 8, 9, 4, 5, 2];
205
+ let s1 = 0;
206
+ for (let i = 0; i < 9; i++)
207
+ s1 += d[i] * w1[i];
208
+ let c1 = 11 - (s1 % 11);
209
+ if (c1 === 11)
210
+ c1 = 0;
211
+ if (c1 === 10)
212
+ return false;
213
+ if (d[9] !== c1)
214
+ return false;
215
+ const w2 = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
216
+ let s2 = 0;
217
+ for (let i = 0; i < 10; i++)
218
+ s2 += d[i] * w2[i];
219
+ let c2 = 11 - (s2 % 11);
220
+ if (c2 === 11)
221
+ c2 = 0;
222
+ if (c2 === 10)
223
+ return false;
224
+ return d[10] === c2;
225
+ }
226
+ export function validateFinnishHetu(candidate) {
227
+ const c = candidate.trim();
228
+ if (c.length !== 11)
229
+ return false;
230
+ const digits = c.slice(0, 6);
231
+ const sep = c[6];
232
+ const individual = c.slice(7, 10);
233
+ const checkChar = c[10];
234
+ if (!/^\d{6}$/.test(digits) || !/^\d{3}$/.test(individual))
235
+ return false;
236
+ if (!"-+ABCDEFYXWVU".includes(sep))
237
+ return false;
238
+ const lookup = "0123456789ABCDEFHJKLMNPRSTUVWXY";
239
+ const num = parseInt(digits + individual);
240
+ return checkChar === lookup[num % 31];
241
+ }
242
+ export function validateIcelandicKt(candidate) {
243
+ const c = candidate.replace(/[\s\-]/g, "");
244
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
245
+ return false;
246
+ const d = c.split("").map(Number);
247
+ const w = [3, 2, 7, 6, 5, 4, 3, 2];
248
+ let s = 0;
249
+ for (let i = 0; i < 8; i++)
250
+ s += d[i] * w[i];
251
+ const check = (11 - (s % 11)) % 11;
252
+ if (check === 10)
253
+ return false;
254
+ return d[8] === check;
255
+ }
256
+ export function validateDanishVat(candidate) {
257
+ let c = candidate.replace(/[\s\-]/g, "").toUpperCase();
258
+ if (c.startsWith("DK"))
259
+ c = c.slice(2);
260
+ if (c.length !== 8 || !/^\d{8}$/.test(c))
261
+ return false;
262
+ const d = c.split("").map(Number);
263
+ const w = [2, 7, 6, 5, 4, 3, 2, 1];
264
+ let total = 0;
265
+ for (let i = 0; i < 8; i++)
266
+ total += d[i] * w[i];
267
+ return total % 11 === 0;
268
+ }
269
+ export function validateFinnishBusinessId(candidate) {
270
+ let c = candidate.replace(/\s/g, "");
271
+ if (c.includes("-")) {
272
+ const parts = c.split("-");
273
+ if (parts.length !== 2)
274
+ return false;
275
+ c = parts[0] + parts[1];
276
+ }
277
+ if (c.length !== 8 || !/^\d{8}$/.test(c))
278
+ return false;
279
+ const d = c.split("").map(Number);
280
+ const w = [7, 9, 10, 5, 8, 4, 2];
281
+ let s = 0;
282
+ for (let i = 0; i < 7; i++)
283
+ s += d[i] * w[i];
284
+ const remainder = s % 11;
285
+ let check;
286
+ if (remainder === 0)
287
+ check = 0;
288
+ else if (remainder === 1)
289
+ return false;
290
+ else
291
+ check = 11 - remainder;
292
+ return d[7] === check;
293
+ }
294
+ export function validateImei(candidate) {
295
+ const c = candidate.replace(/[\s\-/]/g, "");
296
+ if (c.length !== 15 || !/^\d{15}$/.test(c))
297
+ return false;
298
+ if (c.slice(0, 8) === "00000000")
299
+ return false;
300
+ let total = 0;
301
+ for (let i = 0; i < 15; i++) {
302
+ let n = parseInt(c[i]);
303
+ if (i % 2 === 1) {
304
+ n *= 2;
305
+ if (n > 9)
306
+ n -= 9;
307
+ }
308
+ total += n;
309
+ }
310
+ return total % 10 === 0;
311
+ }
312
+ export function validateDanishCpr(candidate) {
313
+ const c = candidate.replace(/[\s\-]/g, "");
314
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
315
+ return false;
316
+ const day = parseInt(c.slice(0, 2));
317
+ const month = parseInt(c.slice(2, 4));
318
+ return day >= 1 && day <= 31 && month >= 1 && month <= 12;
319
+ }
320
+ export function validateNorwegianOrg(candidate) {
321
+ const c = candidate.replace(/[\s\-]/g, "");
322
+ if (c.length !== 9 || !/^\d{9}$/.test(c) || !("89".includes(c[0])))
323
+ return false;
324
+ const d = c.split("").map(Number);
325
+ const w = [3, 2, 7, 6, 5, 4, 3, 2];
326
+ let s = 0;
327
+ for (let i = 0; i < 8; i++)
328
+ s += d[i] * w[i];
329
+ const remainder = s % 11;
330
+ let check;
331
+ if (remainder === 0)
332
+ check = 0;
333
+ else if (remainder === 1)
334
+ return false;
335
+ else
336
+ check = 11 - remainder;
337
+ return d[8] === check;
338
+ }
339
+ export function validateAustrianSvnr(candidate) {
340
+ const c = candidate.replace(/\s/g, "");
341
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
342
+ return false;
343
+ const d = c.split("").map(Number);
344
+ const weights = [3, 7, 9, 0, 5, 8, 4, 2, 1, 6];
345
+ let total = 0;
346
+ for (let i = 0; i < 10; i++)
347
+ total += d[i] * weights[i];
348
+ return total % 11 === d[3];
349
+ }
350
+ export function validateSwissAhv(candidate) {
351
+ const c = clean(candidate);
352
+ if (c.length !== 13 || !/^\d{13}$/.test(c) || !c.startsWith("756"))
353
+ return false;
354
+ let total = 0;
355
+ for (let i = 0; i < 12; i++)
356
+ total += parseInt(c[i]) * (i % 2 === 0 ? 1 : 3);
357
+ const check = (10 - (total % 10)) % 10;
358
+ return check === parseInt(c[12]);
359
+ }
360
+ export function validateItalianCf(candidate) {
361
+ const c = candidate.toUpperCase().trim();
362
+ if (c.length !== 16)
363
+ return false;
364
+ if (!/^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/.test(c))
365
+ return false;
366
+ const oddMap = {
367
+ "0": 1, "1": 0, "2": 5, "3": 7, "4": 9, "5": 13, "6": 15, "7": 17, "8": 19, "9": 21,
368
+ A: 1, B: 0, C: 5, D: 7, E: 9, F: 13, G: 15, H: 17, I: 19, J: 21, K: 2, L: 4, M: 18, N: 20, O: 11,
369
+ P: 3, Q: 6, R: 8, S: 12, T: 14, U: 16, V: 10, W: 22, X: 25, Y: 24, Z: 23,
370
+ };
371
+ const evenMap = {
372
+ "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
373
+ A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11, M: 12, N: 13, O: 14,
374
+ P: 15, Q: 16, R: 17, S: 18, T: 19, U: 20, V: 21, W: 22, X: 23, Y: 24, Z: 25,
375
+ };
376
+ let total = 0;
377
+ for (let i = 0; i < 15; i++) {
378
+ total += i % 2 === 0 ? (oddMap[c[i]] ?? 0) : (evenMap[c[i]] ?? 0);
379
+ }
380
+ return c[15] === String.fromCharCode(65 + (total % 26));
381
+ }
382
+ export function validateSpanishDni(candidate) {
383
+ const c = candidate.toUpperCase().trim();
384
+ if (!/^\d{8}[A-Z]$/.test(c))
385
+ return false;
386
+ const lookup = "TRWAGMYFPDXBNJZSQVHLCKE";
387
+ return c[8] === lookup[parseInt(c.slice(0, 8)) % 23];
388
+ }
389
+ export function validateSpanishNie(candidate) {
390
+ const c = candidate.toUpperCase().trim();
391
+ if (!/^[XYZ]\d{7}[A-Z]$/.test(c))
392
+ return false;
393
+ const prefixMap = { X: "0", Y: "1", Z: "2" };
394
+ const num = parseInt(prefixMap[c[0]] + c.slice(1, 8));
395
+ const lookup = "TRWAGMYFPDXBNJZSQVHLCKE";
396
+ return c[8] === lookup[num % 23];
397
+ }
398
+ export function validatePortugueseNif(candidate) {
399
+ const c = clean(candidate);
400
+ if (c.length !== 9 || !/^\d{9}$/.test(c) || "04".includes(c[0]))
401
+ return false;
402
+ const weights = [9, 8, 7, 6, 5, 4, 3, 2];
403
+ let total = 0;
404
+ for (let i = 0; i < 8; i++)
405
+ total += parseInt(c[i]) * weights[i];
406
+ const remainder = total % 11;
407
+ const check = remainder < 2 ? 0 : 11 - remainder;
408
+ return parseInt(c[8]) === check;
409
+ }
410
+ export function validatePolishPesel(candidate) {
411
+ const c = candidate.replace(/[\s\-]/g, "");
412
+ if (c.length !== 11 || !/^\d{11}$/.test(c))
413
+ return false;
414
+ const d = c.split("").map(Number);
415
+ const weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
416
+ let total = 0;
417
+ for (let i = 0; i < 10; i++)
418
+ total += d[i] * weights[i];
419
+ return d[10] === (10 - (total % 10)) % 10;
420
+ }
421
+ export function validatePolishNip(candidate) {
422
+ const c = candidate.replace(/[\s\-]/g, "");
423
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
424
+ return false;
425
+ const d = c.split("").map(Number);
426
+ const weights = [6, 5, 7, 2, 3, 4, 5, 6, 7];
427
+ let total = 0;
428
+ for (let i = 0; i < 9; i++)
429
+ total += d[i] * weights[i];
430
+ return total % 11 === d[9];
431
+ }
432
+ export function validateCzechBirthNumber(candidate) {
433
+ const c = candidate.replace(/[/\s]/g, "");
434
+ if (!/^\d+$/.test(c) || (c.length !== 9 && c.length !== 10))
435
+ return false;
436
+ if (c.length === 10)
437
+ return parseInt(c) % 11 === 0;
438
+ return true;
439
+ }
440
+ export function validateRomanianCnp(candidate) {
441
+ const c = candidate.replace(/[\s\-]/g, "");
442
+ if (c.length !== 13 || !/^\d{13}$/.test(c) || !"12345678".includes(c[0]))
443
+ return false;
444
+ const key = "279146358279";
445
+ let total = 0;
446
+ for (let i = 0; i < 12; i++)
447
+ total += parseInt(c[i]) * parseInt(key[i]);
448
+ const remainder = total % 11;
449
+ const check = remainder === 10 ? 1 : remainder;
450
+ return parseInt(c[12]) === check;
451
+ }
452
+ export function validateHungarianTaj(candidate) {
453
+ const c = candidate.replace(/[\s\-]/g, "");
454
+ if (c.length !== 9 || !/^\d{9}$/.test(c))
455
+ return false;
456
+ const d = c.split("").map(Number);
457
+ let total = 0;
458
+ for (let i = 0; i < 8; i++)
459
+ total += d[i] * (i % 2 === 0 ? 3 : 7);
460
+ return total % 10 === d[8];
461
+ }
462
+ export function validateBulgarianEgn(candidate) {
463
+ const c = candidate.replace(/[\s\-]/g, "");
464
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
465
+ return false;
466
+ const d = c.split("").map(Number);
467
+ const weights = [2, 4, 8, 5, 10, 9, 7, 3, 6];
468
+ let total = 0;
469
+ for (let i = 0; i < 9; i++)
470
+ total += d[i] * weights[i];
471
+ let check = total % 11;
472
+ if (check === 10)
473
+ check = 0;
474
+ return d[9] === check;
475
+ }
476
+ export function validateCroatianOib(candidate) {
477
+ const c = candidate.replace(/[\s\-]/g, "");
478
+ if (c.length !== 11 || !/^\d{11}$/.test(c))
479
+ return false;
480
+ let product = 10;
481
+ for (let i = 0; i < 10; i++) {
482
+ let total = (parseInt(c[i]) + product) % 10;
483
+ if (total === 0)
484
+ total = 10;
485
+ product = (total * 2) % 11;
486
+ }
487
+ const check = (11 - product) % 10;
488
+ return check === parseInt(c[10]);
489
+ }
490
+ export function validateSlovenianEmso(candidate) {
491
+ const c = candidate.replace(/[\s\-]/g, "");
492
+ if (c.length !== 13 || !/^\d{13}$/.test(c))
493
+ return false;
494
+ const d = c.split("").map(Number);
495
+ const weights = [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
496
+ let total = 0;
497
+ for (let i = 0; i < 12; i++)
498
+ total += d[i] * weights[i];
499
+ const remainder = total % 11;
500
+ let check = remainder === 0 ? 0 : 11 - remainder;
501
+ if (check === 10)
502
+ return false;
503
+ return d[12] === check;
504
+ }
505
+ export function validateIrishPps(candidate) {
506
+ const c = candidate.toUpperCase().trim();
507
+ if (!/^\d{7}[A-W][ABWTXZ]?$/.test(c))
508
+ return false;
509
+ const weights = [8, 7, 6, 5, 4, 3, 2];
510
+ let total = 0;
511
+ for (let i = 0; i < 7; i++)
512
+ total += parseInt(c[i]) * weights[i];
513
+ if (c.length === 9 && /[A-Z]/.test(c[8]))
514
+ total += (c.charCodeAt(8) - 64) * 9;
515
+ const expected = total % 23;
516
+ const check = expected > 0 ? String.fromCharCode(64 + expected) : "W";
517
+ return c[7] === check;
518
+ }
519
+ export function validateEstonianId(candidate) {
520
+ const c = candidate.replace(/[\s\-]/g, "");
521
+ if (c.length !== 11 || !/^\d{11}$/.test(c) || !"123456".includes(c[0]))
522
+ return false;
523
+ const d = c.split("").map(Number);
524
+ const w1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1];
525
+ let s1 = 0;
526
+ for (let i = 0; i < 10; i++)
527
+ s1 += d[i] * w1[i];
528
+ s1 = s1 % 11;
529
+ if (s1 !== 10)
530
+ return d[10] === s1;
531
+ const w2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
532
+ let s2 = 0;
533
+ for (let i = 0; i < 10; i++)
534
+ s2 += d[i] * w2[i];
535
+ s2 = s2 % 11;
536
+ if (s2 === 10)
537
+ s2 = 0;
538
+ return d[10] === s2;
539
+ }
540
+ export function validateUkNhs(candidate) {
541
+ const c = candidate.replace(/[\s\-]/g, "");
542
+ if (c.length !== 10 || !/^\d{10}$/.test(c))
543
+ return false;
544
+ const weights = [10, 9, 8, 7, 6, 5, 4, 3, 2];
545
+ let total = 0;
546
+ for (let i = 0; i < 9; i++)
547
+ total += parseInt(c[i]) * weights[i];
548
+ let check = 11 - (total % 11);
549
+ if (check === 11)
550
+ check = 0;
551
+ if (check === 10)
552
+ return false;
553
+ return parseInt(c[9]) === check;
554
+ }
555
+ export function validateGreekAfm(candidate) {
556
+ const c = candidate.replace(/[\s\-]/g, "");
557
+ if (c.length !== 9 || !/^\d{9}$/.test(c))
558
+ return false;
559
+ const d = c.split("").map(Number);
560
+ let total = 0;
561
+ for (let i = 0; i < 8; i++)
562
+ total += d[i] * Math.pow(2, 8 - i);
563
+ return d[8] === (total % 11) % 10;
564
+ }
565
+ export function validateGreekAmka(candidate) {
566
+ const c = candidate.replace(/[\s\-]/g, "");
567
+ if (c.length !== 11 || !/^\d{11}$/.test(c))
568
+ return false;
569
+ let total = 0;
570
+ for (let i = c.length - 1; i >= 0; i--) {
571
+ let n = parseInt(c[i]);
572
+ if ((c.length - 1 - i) % 2 === 1) {
573
+ n *= 2;
574
+ if (n > 9)
575
+ n -= 9;
576
+ }
577
+ total += n;
578
+ }
579
+ return total % 10 === 0;
580
+ }
581
+ export const VALIDATORS = {
582
+ iban: validateIban,
583
+ bsn: validateBsn,
584
+ belgian_nn: validateBelgianNn,
585
+ luhn: validateLuhn,
586
+ belgian_vat: validateBelgianVat,
587
+ vat_nl: validateVatNl,
588
+ vat_de: validateVatDe,
589
+ vat_fr: validateVatFr,
590
+ vat_lu: validateVatLu,
591
+ german_tax_id: validateGermanTaxId,
592
+ french_nir: validateFrenchNir,
593
+ vin: validateVin,
594
+ bic: validateBic,
595
+ kvk: validateKvk,
596
+ swedish_pnr: validateSwedishPnr,
597
+ norwegian_fnr: validateNorwegianFnr,
598
+ finnish_hetu: validateFinnishHetu,
599
+ icelandic_kt: validateIcelandicKt,
600
+ danish_vat: validateDanishVat,
601
+ finnish_business_id: validateFinnishBusinessId,
602
+ norwegian_org: validateNorwegianOrg,
603
+ danish_cpr: validateDanishCpr,
604
+ imei: validateImei,
605
+ austrian_svnr: validateAustrianSvnr,
606
+ swiss_ahv: validateSwissAhv,
607
+ italian_cf: validateItalianCf,
608
+ spanish_dni: validateSpanishDni,
609
+ spanish_nie: validateSpanishNie,
610
+ portuguese_nif: validatePortugueseNif,
611
+ polish_pesel: validatePolishPesel,
612
+ polish_nip: validatePolishNip,
613
+ czech_birth_number: validateCzechBirthNumber,
614
+ romanian_cnp: validateRomanianCnp,
615
+ hungarian_taj: validateHungarianTaj,
616
+ bulgarian_egn: validateBulgarianEgn,
617
+ croatian_oib: validateCroatianOib,
618
+ slovenian_emso: validateSlovenianEmso,
619
+ irish_pps: validateIrishPps,
620
+ estonian_id: validateEstonianId,
621
+ uk_nhs: validateUkNhs,
622
+ greek_afm: validateGreekAfm,
623
+ greek_amka: validateGreekAmka,
624
+ };
@@ -0,0 +1,15 @@
1
+ import { type RedactResult } from "./types.js";
2
+ export interface RedactOptions {
3
+ countries?: string[] | null;
4
+ mode?: string;
5
+ pseudonymize?: boolean;
6
+ detectDates?: boolean;
7
+ cache?: boolean;
8
+ }
9
+ export declare class EuRedact {
10
+ private engine;
11
+ private cache;
12
+ private pseudonymMapper;
13
+ redact(text: string, options?: RedactOptions): RedactResult;
14
+ redactBatch(texts: string[], options?: RedactOptions): RedactResult[];
15
+ }