validator-tax-id 1.1.3 → 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.
package/README.md CHANGED
@@ -1,13 +1,23 @@
1
1
  # Tax ID Validator
2
2
 
3
+ A lightweight, zero-dependency, and universal TypeScript library to validate Tax IDs (Identification Numbers)
4
+
5
+ It uses precise mathematical algorithms to verify the integrity of the document number and follow guides of the country governments
6
+
3
7
  [![NPM Version](https://img.shields.io/npm/v/validator-tax-id?style=flat-square)](https://www.npmjs.com/package/validator-tax-id)
4
8
  [![NPM Downloads](https://img.shields.io/npm/dm/validator-tax-id?style=flat-square)](https://www.npmjs.com/package/validator-tax-id)
5
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://github.com/AngelBlanco97/tax-id-validator/blob/main/LICENSE)
6
10
  [![CI Tests](https://github.com/AngelBlanco97/tax-id-validator/actions/workflows/publish.yml/badge.svg)](https://github.com/AngelBlanco97/tax-id-validator/actions)
11
+ [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square)](https://paypal.me/AngelBlanco747)
7
12
 
8
- A lightweight, zero-dependency, and universal TypeScript library to validate Tax IDs (Identification Numbers)
13
+ ## Supported Countries
9
14
 
10
- It uses precise mathematical algorithms to verify the integrity of the document number and follow guides of the country governments
15
+ | Country | Code | Documents Supported | Algorithm |
16
+ | ----------- | ---- | ------------------------------ | ------------------ |
17
+ | 🇪🇸 Spain | es | DNI, NIE, CIF | Module 23 |
18
+ | 🇵🇹 Portugal | pt | NIF (Personal) | Module 11 |
19
+ | 🇫🇷 France | fr | SIREN, SIRET, NIR | Luhn + Mod.97 |
20
+ | 🇩🇪 Germany | de | SteuerIdNr, VAT Number, W-IdNr | ISO 7064 Mod 10,11 |
11
21
 
12
22
  ## Features
13
23
 
@@ -36,66 +46,97 @@ The main function `validateIdentification` takes two arguments: the **country co
36
46
  import { validateIdentification } from "validator-tax-id";
37
47
 
38
48
  // 🇪🇸 Spain (ES)
39
- // Validates DNI (8 digits + letter)
40
- const isDniValid = validateIdentification("es", "12345678Z"); // true
41
-
42
- // Validates NIE (X/Y/Z + 7 digits + letter)
43
- const isNieValid = validateIdentification("es", "X1234567L"); // true
49
+ validateIdentification("es", "12345678Z"); // true (DNI)
50
+ validateIdentification("es", "X1234567L"); // true (NIE)
51
+ validateIdentification("es", "A58818501"); // true (CIF)
44
52
 
45
53
  // 🇵🇹 Portugal (PT)
46
- // Validates NIF (9 digits with checksum)
47
- const isNifValid = validateIdentification("pt", "232013969"); // true
54
+ validateIdentification("pt", "232013969"); // true (NIF)
48
55
 
49
56
  // 🇫🇷 France (FR)
50
- // Validates SIREN (9 digits) or SIRET (14 digits)
51
- const isSirenValid = validateIdentification("fr", "443061841"); // true
52
- ```
53
-
54
- ## API Reference
55
-
56
- ### `validateIdentification(country, value)`
57
+ validateIdentification("fr", "443061841"); // true (SIREN)
57
58
 
58
- - **country**: `CountryCode` ('es' | 'pt' | 'fr') - The ISO code of the country.
59
- - **value**: `string` | `any` - The document string to validate.
60
- - **Returns**: `boolean` (`true` if valid, `false` otherwise).
61
-
62
- _Note: The validator sanitizes the input automatically (removes spaces, hyphens, and is case-insensitive)._
59
+ // 🇩🇪 Germany (DE)
60
+ validateIdentification("de", "86095742719"); // true (SteuerIdNr)
61
+ validateIdentification("de", "DE136695976"); // true (VAT Number)
62
+ ```
63
63
 
64
- ## SUPPORTED COUNTRIES
64
+ ### Individual Validators (Recommended) ✨
65
65
 
66
- | Country | Code | Documents Supported | Algorithm |
67
- | -------- | ---- | ------------------- | ------------- |
68
- | Spain | es | DNI, NIE , CIF | Module 23 |
69
- | Portugal | pt | NIF (Personal) | Module 11 |
70
- | France | fr | SIREN, SIRET, NIR | Luhn + Mod.97 |
66
+ For better tree-shaking and direct access, use individual validators:
71
67
 
72
- # Changelog
68
+ ```typescript
69
+ import {
70
+ // Spain
71
+ validateDNI,
72
+ validateNIE,
73
+ validateCIF,
74
+ // France
75
+ validateSIREN,
76
+ validateSIRET,
77
+ validateNIR,
78
+ // Portugal
79
+ validateNIF,
80
+ // Germany
81
+ validateSteuerIdNr,
82
+ validateVatNumber,
83
+ validateWidnr,
84
+ } from "validator-tax-id";
85
+
86
+ // 🇪🇸 Spain - Direct validation
87
+ validateDNI("12345678Z"); // true
88
+ validateNIE("X1234567L"); // true
89
+ validateCIF("A58818501"); // true
90
+
91
+ // 🇫🇷 France - Direct validation
92
+ validateSIREN("443061841"); // true
93
+ validateSIRET("44306184100047"); // true
94
+ validateNIR("188057512301180"); // true
95
+
96
+ // 🇵🇹 Portugal - Direct validation
97
+ validateNIF("123456789"); // true
98
+
99
+ // 🇩🇪 Germany - Direct validation
100
+ validateSteuerIdNr("86095742719"); // true
101
+ validateVatNumber("DE136695976"); // true
102
+ validateWidnr("136695976"); // true
103
+ ```
73
104
 
74
- All notable changes to this project will be documented in this file.
105
+ ### Country Auto-detect
75
106
 
76
- ## [1.1.3] - 2026-01-18
107
+ If you don't know the specific document type:
77
108
 
78
- ### Added 🚀
109
+ ```typescript
110
+ import {
111
+ validateES,
112
+ validateFR,
113
+ validatePT,
114
+ validateDE,
115
+ } from "validator-tax-id";
116
+
117
+ validateES("12345678Z"); // true (auto-detects DNI)
118
+ validateES("A58818501"); // true (auto-detects CIF)
119
+ validateFR("443061841"); // true (auto-detects SIREN)
120
+ validatePT("123456789"); // true
121
+ validateDE("86095742719"); // true (auto-detects SteuerIdNr)
122
+ validateDE("DE136695976"); // true (auto-detects VAT Number)
123
+ ```
79
124
 
80
- - **France (FR)** added validation for NIR document and fix SIREN-SIRET algorithm
81
- - **Spain (ES)** added validation for CIF document.
82
- - **Portugal (PT)** added validation on prefix in NIF document
125
+ ## API Reference
83
126
 
84
- ## [1.1.0] - 2026-01-17
127
+ ### `validateIdentification(country, value)`
85
128
 
86
- ### Added 🚀
129
+ - **country**: `CountryCode` ('es' | 'pt' | 'fr' | 'de') - The ISO code of the country.
130
+ - **value**: `string` - The document string to validate.
131
+ - **Returns**: `boolean` (`true` if valid, `false` otherwise).
87
132
 
88
- - **France (FR)** support added.
89
- - Validation for **SIREN** (9 digits) and **SIRET** (14 digits) using Luhn algorithm.
133
+ _Note: The validator sanitizes the input automatically (removes spaces, hyphens, and is case-insensitive)._
90
134
 
91
- ## [1.0.0] - 2026-01-17
135
+ ## Support
92
136
 
93
- ### Added
137
+ If this library helped you, consider buying me a coffee ☕
94
138
 
95
- - Initial release.
96
- - **Spain (ES)** support: DNI and NIE validation (Modulo 23).
97
- - **Portugal (PT)** support: NIF validation (Modulo 11).
98
- - Core logic and TypeScript types.
139
+ [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=for-the-badge)](https://paypal.me/AngelBlanco747)
99
140
 
100
141
  ## License
101
142
 
package/dist/index.cjs CHANGED
@@ -1,33 +1,45 @@
1
- "use strict";var u=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var y=(e,t)=>{for(var o in t)u(e,o,{get:t[o],enumerable:!0})},C=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of m(t))!b.call(e,n)&&n!==o&&u(e,n,{get:()=>t[n],enumerable:!(r=R(t,n))||r.enumerable});return e};var S=e=>C(u({},"__esModule",{value:!0}),e);var h={};y(h,{validateIdentification:()=>$});module.exports=S(h);var T="TRWAGMYFPDXBNJZSQVHLCKE",v="JABCDEFGHI",N=/^([0-9]{8}|[XYZ][0-9]{7})[A-Z]$/,_=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/;var I=e=>{if(typeof e!="string")return!1;let t=e.toUpperCase().replace(/\s|-/g,"");if(N.test(t)){let s=t.slice(0,-1),f=t.slice(-1);s=s.replace("X","0").replace("Y","1").replace("Z","2");let a=parseInt(s,10);return T[a%23]===f}if(!_.test(t))return!1;let o=t[0],r=t.slice(1,8),n=t[8],l=0,c=0;for(let s=0;s<r.length;s++){let f=parseInt(r[s],10);if(s%2===0){let a=f*2;c+=a>9?a-9:a}else l+=f}let i=(10-(l+c)%10)%10,p=v[i];return"PQRSNW".includes(o)?n===p:"ABEH".includes(o)?n===String(i):n===String(i)||n===p};var A=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/;var g=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");return t.length===15?x(t):t.length===9||t.length===14?F(t):!1},D=e=>{let t=0,o=!1;for(let r=e.length-1;r>=0;r--){let n=parseInt(e[r],10);o&&(n*=2,n>9&&(n-=9)),t+=n,o=!o}return t%10===0},F=e=>{let t=e.replace(/\s|-/g,"");return!/^\d{9}$/.test(t)&&!/^\d{14}$/.test(t)||/^(\d)\1+$/.test(t)?!1:D(t)},x=e=>{let t=e.toUpperCase().replace(/\s|-/g,"");if(!A.test(t))return!1;let o=parseInt(t.slice(-2),10),r=t.slice(0,-2),n=r.slice(5,7);n==="2A"&&(r=r.slice(0,5)+"19"+r.slice(7)),n==="2B"&&(r=r.slice(0,5)+"18"+r.slice(7));let l=BigInt(r);return Number(97n-l%97n)===o};var G=["1","2","3","5","6","8","9"];var E=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");if(!/^[0-9]{9}$/.test(t)||!G.includes(t[0]))return!1;let n=11-t.slice(0,8).split("").reduce((l,c,d)=>{let i=9-d;return l+parseInt(c,10)*i},0)%11;return n>=10&&(n=0),n===parseInt(t[8],10)};var L={es:I,pt:E,fr:g};var $=(e,t)=>{let o=L[e];return o?o(t):(console.warn(`[TaxIDValidator] Country '${e}' not supported yet.`),!1)};0&&(module.exports={validateIdentification});
1
+ "use strict";var f=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var X=Object.prototype.hasOwnProperty;var z=(e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})},$=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of O(t))!X.call(e,r)&&r!==n&&f(e,r,{get:()=>t[r],enumerable:!(o=M(t,r))||o.enumerable});return e};var P=e=>$(f({},"__esModule",{value:!0}),e);var rt={};z(rt,{isValidCountryCode:()=>F,isValidString:()=>u,validateCIF:()=>b,validateDE:()=>_,validateDNI:()=>E,validateES:()=>C,validateFR:()=>S,validateIdentification:()=>ot,validateNIE:()=>x,validateNIF:()=>y,validateNIR:()=>R,validatePT:()=>h,validateSIREN:()=>D,validateSIRET:()=>N,validateSteuerIdNr:()=>T,validateVatNumber:()=>k,validateWidnr:()=>v});module.exports=P(rt);var u=e=>typeof e=="string"&&e.length>0,F=e=>e==="es"||e==="pt"||e==="fr"||e==="de";var c=e=>u(e)?e.toUpperCase().replace(/[\s-]/g,""):null,a=(e,t)=>{let n=c(e);return n===null?null:t.test(n)?n:null};var I=e=>{let t=0,n=!1;for(let o=e.length-1;o>=0;o--){let r=parseInt(e[o],10);n&&(r*=2,r>9&&(r-=9)),t+=r,n=!n}return t%10===0},g=(e,t)=>t[e%23],w=e=>{let o=11-e.reduce((r,i,s)=>{let l=9-s;return r+i*l},0)%11;return o>=10?0:o},V=e=>Number(97n-e%97n),A=e=>{let t="JABCDEFGHI",n=0,o=0;for(let s=0;s<e.length;s++){let l=parseInt(e[s],10);if(s%2===0){let p=l*2;o+=p>9?p-9:p}else n+=l}let i=(10-(n+o)%10)%10;return{digit:i,letter:t[i]}},m=e=>/^(\d)\1+$/.test(e),d=e=>{let t=10;for(let o=0;o<e.length;o++){let i=(parseInt(e[o],10)+t)%10;t=(i===0?10:i)*2%11}let n=11-t;return n===10?0:n},G=e=>{let t={};for(let i of e)t[i]=(t[i]||0)+1;let n=Object.values(t),o=n.filter(i=>i===2).length,r=n.filter(i=>i===3).length;return o===1&&r===0||r===1&&o===0};var L="TRWAGMYFPDXBNJZSQVHLCKE",B=/^[0-9]{8}[A-Z]$/,W=/^[XYZ][0-9]{7}[A-Z]$/,Y=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/,H="PQRSNW",J="ABEH",E=e=>{let t=a(e,B);if(!t)return!1;let n=parseInt(t.slice(0,-1),10),o=t.slice(-1);return g(n,L)===o},x=e=>{let t=a(e,W);if(!t)return!1;let n=t.slice(-1),o=t[0],i=parseInt((o==="X"?"0":o==="Y"?"1":"2")+t.slice(1,-1),10);return g(i,L)===n},b=e=>{let t=a(e,Y);if(!t)return!1;let n=t[0],o=t.slice(1,8),r=t[8],{digit:i,letter:s}=A(o);return H.includes(n)?r===s:J.includes(n)?r===String(i):r===String(i)||r===s},C=e=>E(e)||x(e)||b(e);var U=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/,Z=/^\d{9}$/,K=/^\d{14}$/,R=e=>{let t=a(e,U);if(!t)return!1;let n=parseInt(t.slice(-2),10),o=t.slice(0,-2),r=o.slice(5,7);return r==="2A"&&(o=o.slice(0,5)+"19"+o.slice(7)),r==="2B"&&(o=o.slice(0,5)+"18"+o.slice(7)),V(BigInt(o))===n},D=e=>{let t=c(e);return!t||!Z.test(t)||m(t)?!1:I(t)},N=e=>{let t=c(e);return!t||!K.test(t)||m(t)?!1:I(t)};var S=e=>{let t=c(e);return t?t.length===15?R(e):t.length===9?D(e):t.length===14?N(e):!1:!1};var Q=/^[0-9]{9}$/,j=["1","2","3","5","6","8","9"],y=e=>{let t=c(e);if(!t||!Q.test(t)||!j.includes(t[0]))return!1;let n=t.slice(0,8).split("").map(r=>parseInt(r,10));return w(n)===parseInt(t[8],10)},h=y;var q=/^[0-9]{11}$/,tt=/^DE[0-9]{9}$/,et=/^[0-9]{9}$/,T=e=>{let t=a(e,q);if(!t)return!1;let n=t.substring(0,10),o=parseInt(t.substring(10,11),10);return G(n)?d(n)===o:!1},k=e=>{let t=a(e,tt);if(!t)return!1;let n=t.substring(2),o=n.substring(0,8),r=parseInt(n.substring(8,9),10);return d(o)===r},v=e=>{let t=a(e,et);if(!t)return!1;let n=t.substring(0,8),o=parseInt(t.substring(8,9),10);return d(n)===o},_=e=>T(e)||k(e)||v(e);var nt={es:C,pt:h,fr:S,de:_},ot=(e,t)=>{let n=nt[e];return n?n(t):(console.warn(`[TaxIDValidator] Country '${e}' not supported yet.`),!1)};0&&(module.exports={isValidCountryCode,isValidString,validateCIF,validateDE,validateDNI,validateES,validateFR,validateIdentification,validateNIE,validateNIF,validateNIR,validatePT,validateSIREN,validateSIRET,validateSteuerIdNr,validateVatNumber,validateWidnr});
2
2
  /**
3
- * Validate Spanish DNI/NIE/CIF numbers.
4
- * @param value - The DNI or NIE number to validate
5
- * @returns boolean indicating whether the DNI/NIE is valid (true) or not (false)
3
+ * Types for Tax ID Validator
6
4
  * @author AngelBlanco97
7
5
  * @license MIT
8
- * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
9
6
  */
10
7
  /**
11
- * Validates French identification numbers: NIR (Numéro d'Inscription au Répertoire), SIREN, and SIRET.
12
- * @param value - The identification number to validate
13
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
14
10
  * @author AngelBlanco97
15
11
  * @license MIT
16
- * @documentation https://www.service-public.gouv.fr/
17
12
  */
18
13
  /**
19
- * Validates a Portuguese NIF (Número de Identificação Fiscal).
20
- * @param value - The NIF number to validate
21
- * @returns boolean indicating whether the NIF is valid (true) or not (false)
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
22
16
  * @author AngelBlanco97
23
17
  * @license MIT
24
- * @documentation https://en.wikipedia.org/wiki/Tax_identification_number#Portugal
25
18
  */
26
19
  /**
27
- * Function to validate identification numbers based on country/type.
28
- * @param Country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
29
- * @param value - The identification number to validate
30
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
20
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
24
+ /**
25
+ * French Tax ID Validators (NIR, SIREN, SIRET)
26
+ * @author AngelBlanco97
27
+ * @license MIT
28
+ */
29
+ /**
30
+ * Portuguese Tax ID Validators (NIF)
31
+ * @author AngelBlanco97
32
+ * @license MIT
33
+ */
34
+ /**
35
+ * German Validators (SteuerIdNr, VAT Number, W-IdNr)
36
+ * @documentation https://euipo.europa.eu/tunnel-web/secure/webdav/guest/document_library/Documents/COSME/VAT%20numbers%20EU.pdf
37
+ * @documentation https://www.iamexpat.de/expat-info/money-taxation/tax-identification-number-germany
38
+ * @author AngelBlanco97
39
+ * @license MIT
40
+ */
41
+ /**
42
+ * Tax ID Validator - Main Entry Point
31
43
  * @author AngelBlanco97
32
44
  * @license MIT
33
45
  */
package/dist/index.d.cts CHANGED
@@ -1,17 +1,86 @@
1
- declare const validators: {
2
- es: (value: any) => boolean;
3
- pt: (value: any) => boolean;
4
- fr: (value: any) => boolean;
5
- };
6
- type CountryCode = keyof typeof validators;
1
+ export { validateCIF, validateDNI, validateES, validateNIE } from './validators/es.cjs';
2
+ export { validateFR, validateNIR, validateSIREN, validateSIRET } from './validators/fr.cjs';
3
+ export { validateNIF, validatePT } from './validators/pt.cjs';
4
+
5
+ /**
6
+ * German Validators (SteuerIdNr, VAT Number, W-IdNr)
7
+ * @documentation https://euipo.europa.eu/tunnel-web/secure/webdav/guest/document_library/Documents/COSME/VAT%20numbers%20EU.pdf
8
+ * @documentation https://www.iamexpat.de/expat-info/money-taxation/tax-identification-number-germany
9
+ * @author AngelBlanco97
10
+ * @license MIT
11
+ */
12
+ /**
13
+ * Validate German Steueridentifikationsnummer (Tax Identification Number).
14
+ * Unique per person, lifetime validity.
15
+ * Format: 11 digits.
16
+ * Checksum: ISO 7064 Mod 11,10.
17
+ * * @param value - The value to validate
18
+ * @returns boolean indicating whether the SteuerIdNr is valid
19
+ */
20
+ declare const validateSteuerIdNr: (value: unknown) => boolean;
21
+ /**
22
+ * Validate German VAT Number (Umsatzsteuer-Id).
23
+ * Format: DE + 9 digits.
24
+ * Checksum: ISO 7064 Mod 11,10.
25
+ * * @param value - The value to validate
26
+ * @returns boolean indicating whether the VAT number is valid
27
+ */
28
+ declare const validateVatNumber: (value: unknown) => boolean;
29
+ /**
30
+ * Validate Business identification number (W-IdNr)
31
+ * Format: DE + 9 digits + suffix (usually).
32
+ * Based on your regex, we validate the 9 digit core.
33
+ * Checksum: ISO 7064 Mod 11,10 (Same as VAT).
34
+ * * @param value - The value to validate
35
+ * @returns boolean indicating whether the W-IdNr is valid
36
+ */
37
+ declare const validateWidnr: (value: unknown) => boolean;
38
+ /**
39
+ * Validate German Tax Identifiers (SteuerIdNr, Steuernummer, VAT Number, W-IdNr).
40
+ * @param value - The value to validate
41
+ * @returns boolean indicating whether any of the German tax identifiers is valid
42
+ */
43
+ declare const validateDE: (value: unknown) => boolean;
44
+
45
+ /**
46
+ * Types for Tax ID Validator
47
+ * @author AngelBlanco97
48
+ * @license MIT
49
+ */
50
+ /**
51
+ * Supported country codes (ISO 3166-1 alpha-2)
52
+ */
53
+ type CountryCode = "es" | "pt" | "fr" | "de";
54
+ /**
55
+ * Valid input type for tax ID validation.
56
+ * Only strings are valid - this makes the API explicit.
57
+ */
58
+ type TaxIdInput = string;
59
+ /**
60
+ * Validation function signature
61
+ */
62
+ type ValidatorFunction = (value: unknown) => boolean;
63
+ /**
64
+ * Type guard to check if value is a non-empty string
65
+ */
66
+ declare const isValidString: (value: unknown) => value is string;
67
+ /**
68
+ * Type guard to check if country code is valid
69
+ */
70
+ declare const isValidCountryCode: (code: unknown) => code is CountryCode;
71
+
72
+ /**
73
+ * Tax ID Validator - Main Entry Point
74
+ * @author AngelBlanco97
75
+ * @license MIT
76
+ */
77
+
7
78
  /**
8
79
  * Function to validate identification numbers based on country/type.
9
- * @param Country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
80
+ * @param country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
10
81
  * @param value - The identification number to validate
11
82
  * @returns boolean indicating whether the identification number is valid (true) or not (false)
12
- * @author AngelBlanco97
13
- * @license MIT
14
83
  */
15
- declare const validateIdentification: (country: CountryCode, value: any) => boolean;
84
+ declare const validateIdentification: (country: CountryCode, value: unknown) => boolean;
16
85
 
17
- export { type CountryCode, validateIdentification };
86
+ export { type CountryCode, type TaxIdInput, type ValidatorFunction, isValidCountryCode, isValidString, validateDE, validateIdentification, validateSteuerIdNr, validateVatNumber, validateWidnr };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,86 @@
1
- declare const validators: {
2
- es: (value: any) => boolean;
3
- pt: (value: any) => boolean;
4
- fr: (value: any) => boolean;
5
- };
6
- type CountryCode = keyof typeof validators;
1
+ export { validateCIF, validateDNI, validateES, validateNIE } from './validators/es.js';
2
+ export { validateFR, validateNIR, validateSIREN, validateSIRET } from './validators/fr.js';
3
+ export { validateNIF, validatePT } from './validators/pt.js';
4
+
5
+ /**
6
+ * German Validators (SteuerIdNr, VAT Number, W-IdNr)
7
+ * @documentation https://euipo.europa.eu/tunnel-web/secure/webdav/guest/document_library/Documents/COSME/VAT%20numbers%20EU.pdf
8
+ * @documentation https://www.iamexpat.de/expat-info/money-taxation/tax-identification-number-germany
9
+ * @author AngelBlanco97
10
+ * @license MIT
11
+ */
12
+ /**
13
+ * Validate German Steueridentifikationsnummer (Tax Identification Number).
14
+ * Unique per person, lifetime validity.
15
+ * Format: 11 digits.
16
+ * Checksum: ISO 7064 Mod 11,10.
17
+ * * @param value - The value to validate
18
+ * @returns boolean indicating whether the SteuerIdNr is valid
19
+ */
20
+ declare const validateSteuerIdNr: (value: unknown) => boolean;
21
+ /**
22
+ * Validate German VAT Number (Umsatzsteuer-Id).
23
+ * Format: DE + 9 digits.
24
+ * Checksum: ISO 7064 Mod 11,10.
25
+ * * @param value - The value to validate
26
+ * @returns boolean indicating whether the VAT number is valid
27
+ */
28
+ declare const validateVatNumber: (value: unknown) => boolean;
29
+ /**
30
+ * Validate Business identification number (W-IdNr)
31
+ * Format: DE + 9 digits + suffix (usually).
32
+ * Based on your regex, we validate the 9 digit core.
33
+ * Checksum: ISO 7064 Mod 11,10 (Same as VAT).
34
+ * * @param value - The value to validate
35
+ * @returns boolean indicating whether the W-IdNr is valid
36
+ */
37
+ declare const validateWidnr: (value: unknown) => boolean;
38
+ /**
39
+ * Validate German Tax Identifiers (SteuerIdNr, Steuernummer, VAT Number, W-IdNr).
40
+ * @param value - The value to validate
41
+ * @returns boolean indicating whether any of the German tax identifiers is valid
42
+ */
43
+ declare const validateDE: (value: unknown) => boolean;
44
+
45
+ /**
46
+ * Types for Tax ID Validator
47
+ * @author AngelBlanco97
48
+ * @license MIT
49
+ */
50
+ /**
51
+ * Supported country codes (ISO 3166-1 alpha-2)
52
+ */
53
+ type CountryCode = "es" | "pt" | "fr" | "de";
54
+ /**
55
+ * Valid input type for tax ID validation.
56
+ * Only strings are valid - this makes the API explicit.
57
+ */
58
+ type TaxIdInput = string;
59
+ /**
60
+ * Validation function signature
61
+ */
62
+ type ValidatorFunction = (value: unknown) => boolean;
63
+ /**
64
+ * Type guard to check if value is a non-empty string
65
+ */
66
+ declare const isValidString: (value: unknown) => value is string;
67
+ /**
68
+ * Type guard to check if country code is valid
69
+ */
70
+ declare const isValidCountryCode: (code: unknown) => code is CountryCode;
71
+
72
+ /**
73
+ * Tax ID Validator - Main Entry Point
74
+ * @author AngelBlanco97
75
+ * @license MIT
76
+ */
77
+
7
78
  /**
8
79
  * Function to validate identification numbers based on country/type.
9
- * @param Country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
80
+ * @param country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
10
81
  * @param value - The identification number to validate
11
82
  * @returns boolean indicating whether the identification number is valid (true) or not (false)
12
- * @author AngelBlanco97
13
- * @license MIT
14
83
  */
15
- declare const validateIdentification: (country: CountryCode, value: any) => boolean;
84
+ declare const validateIdentification: (country: CountryCode, value: unknown) => boolean;
16
85
 
17
- export { type CountryCode, validateIdentification };
86
+ export { type CountryCode, type TaxIdInput, type ValidatorFunction, isValidCountryCode, isValidString, validateDE, validateIdentification, validateSteuerIdNr, validateVatNumber, validateWidnr };
package/dist/index.js CHANGED
@@ -1,33 +1,45 @@
1
- var E="TRWAGMYFPDXBNJZSQVHLCKE",R="JABCDEFGHI",m=/^([0-9]{8}|[XYZ][0-9]{7})[A-Z]$/,b=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/;var p=e=>{if(typeof e!="string")return!1;let t=e.toUpperCase().replace(/\s|-/g,"");if(m.test(t)){let s=t.slice(0,-1),f=t.slice(-1);s=s.replace("X","0").replace("Y","1").replace("Z","2");let a=parseInt(s,10);return E[a%23]===f}if(!b.test(t))return!1;let o=t[0],n=t.slice(1,8),r=t[8],l=0,c=0;for(let s=0;s<n.length;s++){let f=parseInt(n[s],10);if(s%2===0){let a=f*2;c+=a>9?a-9:a}else l+=f}let i=(10-(l+c)%10)%10,d=R[i];return"PQRSNW".includes(o)?r===d:"ABEH".includes(o)?r===String(i):r===String(i)||r===d};var y=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/;var I=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");return t.length===15?T(t):t.length===9||t.length===14?S(t):!1},C=e=>{let t=0,o=!1;for(let n=e.length-1;n>=0;n--){let r=parseInt(e[n],10);o&&(r*=2,r>9&&(r-=9)),t+=r,o=!o}return t%10===0},S=e=>{let t=e.replace(/\s|-/g,"");return!/^\d{9}$/.test(t)&&!/^\d{14}$/.test(t)||/^(\d)\1+$/.test(t)?!1:C(t)},T=e=>{let t=e.toUpperCase().replace(/\s|-/g,"");if(!y.test(t))return!1;let o=parseInt(t.slice(-2),10),n=t.slice(0,-2),r=n.slice(5,7);r==="2A"&&(n=n.slice(0,5)+"19"+n.slice(7)),r==="2B"&&(n=n.slice(0,5)+"18"+n.slice(7));let l=BigInt(n);return Number(97n-l%97n)===o};var v=["1","2","3","5","6","8","9"];var g=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");if(!/^[0-9]{9}$/.test(t)||!v.includes(t[0]))return!1;let r=11-t.slice(0,8).split("").reduce((l,c,u)=>{let i=9-u;return l+parseInt(c,10)*i},0)%11;return r>=10&&(r=0),r===parseInt(t[8],10)};var N={es:p,pt:g,fr:I};var L=(e,t)=>{let o=N[e];return o?o(t):(console.warn(`[TaxIDValidator] Country '${e}' not supported yet.`),!1)};export{L as validateIdentification};
1
+ var p=e=>typeof e=="string"&&e.length>0,G=e=>e==="es"||e==="pt"||e==="fr"||e==="de";var c=e=>p(e)?e.toUpperCase().replace(/[\s-]/g,""):null,a=(e,t)=>{let n=c(e);return n===null?null:t.test(n)?n:null};var f=e=>{let t=0,n=!1;for(let o=e.length-1;o>=0;o--){let r=parseInt(e[o],10);n&&(r*=2,r>9&&(r-=9)),t+=r,n=!n}return t%10===0},I=(e,t)=>t[e%23],m=e=>{let o=11-e.reduce((r,i,s)=>{let l=9-s;return r+i*l},0)%11;return o>=10?0:o},E=e=>Number(97n-e%97n),x=e=>{let t="JABCDEFGHI",n=0,o=0;for(let s=0;s<e.length;s++){let l=parseInt(e[s],10);if(s%2===0){let d=l*2;o+=d>9?d-9:d}else n+=l}let i=(10-(n+o)%10)%10;return{digit:i,letter:t[i]}},g=e=>/^(\d)\1+$/.test(e),u=e=>{let t=10;for(let o=0;o<e.length;o++){let i=(parseInt(e[o],10)+t)%10;t=(i===0?10:i)*2%11}let n=11-t;return n===10?0:n},b=e=>{let t={};for(let i of e)t[i]=(t[i]||0)+1;let n=Object.values(t),o=n.filter(i=>i===2).length,r=n.filter(i=>i===3).length;return o===1&&r===0||r===1&&o===0};var C="TRWAGMYFPDXBNJZSQVHLCKE",L=/^[0-9]{8}[A-Z]$/,M=/^[XYZ][0-9]{7}[A-Z]$/,O=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/,X="PQRSNW",z="ABEH",R=e=>{let t=a(e,L);if(!t)return!1;let n=parseInt(t.slice(0,-1),10),o=t.slice(-1);return I(n,C)===o},D=e=>{let t=a(e,M);if(!t)return!1;let n=t.slice(-1),o=t[0],i=parseInt((o==="X"?"0":o==="Y"?"1":"2")+t.slice(1,-1),10);return I(i,C)===n},N=e=>{let t=a(e,O);if(!t)return!1;let n=t[0],o=t.slice(1,8),r=t[8],{digit:i,letter:s}=x(o);return X.includes(n)?r===s:z.includes(n)?r===String(i):r===String(i)||r===s},S=e=>R(e)||D(e)||N(e);var $=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/,P=/^\d{9}$/,B=/^\d{14}$/,y=e=>{let t=a(e,$);if(!t)return!1;let n=parseInt(t.slice(-2),10),o=t.slice(0,-2),r=o.slice(5,7);return r==="2A"&&(o=o.slice(0,5)+"19"+o.slice(7)),r==="2B"&&(o=o.slice(0,5)+"18"+o.slice(7)),E(BigInt(o))===n},h=e=>{let t=c(e);return!t||!P.test(t)||g(t)?!1:f(t)},T=e=>{let t=c(e);return!t||!B.test(t)||g(t)?!1:f(t)};var k=e=>{let t=c(e);return t?t.length===15?y(e):t.length===9?h(e):t.length===14?T(e):!1:!1};var W=/^[0-9]{9}$/,Y=["1","2","3","5","6","8","9"],v=e=>{let t=c(e);if(!t||!W.test(t)||!Y.includes(t[0]))return!1;let n=t.slice(0,8).split("").map(r=>parseInt(r,10));return m(n)===parseInt(t[8],10)},_=v;var H=/^[0-9]{11}$/,J=/^DE[0-9]{9}$/,U=/^[0-9]{9}$/,F=e=>{let t=a(e,H);if(!t)return!1;let n=t.substring(0,10),o=parseInt(t.substring(10,11),10);return b(n)?u(n)===o:!1},w=e=>{let t=a(e,J);if(!t)return!1;let n=t.substring(2),o=n.substring(0,8),r=parseInt(n.substring(8,9),10);return u(o)===r},V=e=>{let t=a(e,U);if(!t)return!1;let n=t.substring(0,8),o=parseInt(t.substring(8,9),10);return u(n)===o},A=e=>F(e)||w(e)||V(e);var Z={es:S,pt:_,fr:k,de:A},xt=(e,t)=>{let n=Z[e];return n?n(t):(console.warn(`[TaxIDValidator] Country '${e}' not supported yet.`),!1)};export{G as isValidCountryCode,p as isValidString,N as validateCIF,A as validateDE,R as validateDNI,S as validateES,k as validateFR,xt as validateIdentification,D as validateNIE,v as validateNIF,y as validateNIR,_ as validatePT,h as validateSIREN,T as validateSIRET,F as validateSteuerIdNr,w as validateVatNumber,V as validateWidnr};
2
2
  /**
3
- * Validate Spanish DNI/NIE/CIF numbers.
4
- * @param value - The DNI or NIE number to validate
5
- * @returns boolean indicating whether the DNI/NIE is valid (true) or not (false)
3
+ * Types for Tax ID Validator
6
4
  * @author AngelBlanco97
7
5
  * @license MIT
8
- * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
9
6
  */
10
7
  /**
11
- * Validates French identification numbers: NIR (Numéro d'Inscription au Répertoire), SIREN, and SIRET.
12
- * @param value - The identification number to validate
13
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
14
10
  * @author AngelBlanco97
15
11
  * @license MIT
16
- * @documentation https://www.service-public.gouv.fr/
17
12
  */
18
13
  /**
19
- * Validates a Portuguese NIF (Número de Identificação Fiscal).
20
- * @param value - The NIF number to validate
21
- * @returns boolean indicating whether the NIF is valid (true) or not (false)
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
22
16
  * @author AngelBlanco97
23
17
  * @license MIT
24
- * @documentation https://en.wikipedia.org/wiki/Tax_identification_number#Portugal
25
18
  */
26
19
  /**
27
- * Function to validate identification numbers based on country/type.
28
- * @param Country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
29
- * @param value - The identification number to validate
30
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
20
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
24
+ /**
25
+ * French Tax ID Validators (NIR, SIREN, SIRET)
26
+ * @author AngelBlanco97
27
+ * @license MIT
28
+ */
29
+ /**
30
+ * Portuguese Tax ID Validators (NIF)
31
+ * @author AngelBlanco97
32
+ * @license MIT
33
+ */
34
+ /**
35
+ * German Validators (SteuerIdNr, VAT Number, W-IdNr)
36
+ * @documentation https://euipo.europa.eu/tunnel-web/secure/webdav/guest/document_library/Documents/COSME/VAT%20numbers%20EU.pdf
37
+ * @documentation https://www.iamexpat.de/expat-info/money-taxation/tax-identification-number-germany
38
+ * @author AngelBlanco97
39
+ * @license MIT
40
+ */
41
+ /**
42
+ * Tax ID Validator - Main Entry Point
31
43
  * @author AngelBlanco97
32
44
  * @license MIT
33
45
  */
@@ -0,0 +1,23 @@
1
+ "use strict";var l=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var n in e)l(t,n,{get:e[n],enumerable:!0})},T=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of E(e))!y.call(t,o)&&o!==n&&l(t,o,{get:()=>e[o],enumerable:!(r=C(e,o))||r.enumerable});return t};var b=t=>T(l({},"__esModule",{value:!0}),t);var _={};D(_,{validateCIF:()=>I,validateDNI:()=>f,validateES:()=>O,validateNIE:()=>x});module.exports=b(_);var d=t=>typeof t=="string"&&t.length>0;var N=t=>d(t)?t.toUpperCase().replace(/[\s-]/g,""):null,c=(t,e)=>{let n=N(t);return n===null?null:e.test(n)?n:null};var a=(t,e)=>e[t%23];var g=t=>{let e="JABCDEFGHI",n=0,r=0;for(let u=0;u<t.length;u++){let p=parseInt(t[u],10);if(u%2===0){let i=p*2;r+=i>9?i-9:i}else n+=p}let s=(10-(n+r)%10)%10;return{digit:s,letter:e[s]}};var m="TRWAGMYFPDXBNJZSQVHLCKE",S=/^[0-9]{8}[A-Z]$/,h=/^[XYZ][0-9]{7}[A-Z]$/,R=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/,F="PQRSNW",L="ABEH",f=t=>{let e=c(t,S);if(!e)return!1;let n=parseInt(e.slice(0,-1),10),r=e.slice(-1);return a(n,m)===r},x=t=>{let e=c(t,h);if(!e)return!1;let n=e.slice(-1),r=e[0],s=parseInt((r==="X"?"0":r==="Y"?"1":"2")+e.slice(1,-1),10);return a(s,m)===n},I=t=>{let e=c(t,R);if(!e)return!1;let n=e[0],r=e.slice(1,8),o=e[8],{digit:s,letter:u}=g(r);return F.includes(n)?o===u:L.includes(n)?o===String(s):o===String(s)||o===u},O=t=>f(t)||x(t)||I(t);0&&(module.exports={validateCIF,validateDNI,validateES,validateNIE});
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validate Spanish DNI (Documento Nacional de Identidad).
8
+ * @param value - The DNI number to validate (8 digits + letter)
9
+ * @returns boolean indicating whether the DNI is valid
10
+ * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
11
+ */
12
+ declare const validateDNI: (value: unknown) => boolean;
13
+ /**
14
+ * Validate Spanish NIE (Número de Identidad de Extranjero).
15
+ * @param value - The NIE number to validate (X/Y/Z + 7 digits + letter)
16
+ * @returns boolean indicating whether the NIE is valid
17
+ * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
18
+ */
19
+ declare const validateNIE: (value: unknown) => boolean;
20
+ /**
21
+ * Validate Spanish CIF (Código de Identificación Fiscal).
22
+ * @param value - The CIF number to validate (letter + 7 digits + control)
23
+ * @returns boolean indicating whether the CIF is valid
24
+ */
25
+ declare const validateCIF: (value: unknown) => boolean;
26
+ /**
27
+ * Validate Spanish DNI/NIE/CIF numbers (auto-detect type).
28
+ * @param value - The identification number to validate
29
+ * @returns boolean indicating whether the identification is valid
30
+ */
31
+ declare const validateES: (value: unknown) => boolean;
32
+
33
+ export { validateCIF, validateDNI, validateES, validateNIE };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validate Spanish DNI (Documento Nacional de Identidad).
8
+ * @param value - The DNI number to validate (8 digits + letter)
9
+ * @returns boolean indicating whether the DNI is valid
10
+ * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
11
+ */
12
+ declare const validateDNI: (value: unknown) => boolean;
13
+ /**
14
+ * Validate Spanish NIE (Número de Identidad de Extranjero).
15
+ * @param value - The NIE number to validate (X/Y/Z + 7 digits + letter)
16
+ * @returns boolean indicating whether the NIE is valid
17
+ * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
18
+ */
19
+ declare const validateNIE: (value: unknown) => boolean;
20
+ /**
21
+ * Validate Spanish CIF (Código de Identificación Fiscal).
22
+ * @param value - The CIF number to validate (letter + 7 digits + control)
23
+ * @returns boolean indicating whether the CIF is valid
24
+ */
25
+ declare const validateCIF: (value: unknown) => boolean;
26
+ /**
27
+ * Validate Spanish DNI/NIE/CIF numbers (auto-detect type).
28
+ * @param value - The identification number to validate
29
+ * @returns boolean indicating whether the identification is valid
30
+ */
31
+ declare const validateES: (value: unknown) => boolean;
32
+
33
+ export { validateCIF, validateDNI, validateES, validateNIE };
@@ -0,0 +1,23 @@
1
+ var p=t=>typeof t=="string"&&t.length>0;var m=t=>p(t)?t.toUpperCase().replace(/[\s-]/g,""):null,c=(t,e)=>{let n=m(t);return n===null?null:e.test(n)?n:null};var l=(t,e)=>e[t%23];var d=t=>{let e="JABCDEFGHI",n=0,r=0;for(let s=0;s<t.length;s++){let a=parseInt(t[s],10);if(s%2===0){let i=a*2;r+=i>9?i-9:i}else n+=a}let o=(10-(n+r)%10)%10;return{digit:o,letter:e[o]}};var g="TRWAGMYFPDXBNJZSQVHLCKE",f=/^[0-9]{8}[A-Z]$/,x=/^[XYZ][0-9]{7}[A-Z]$/,I=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/,C="PQRSNW",E="ABEH",y=t=>{let e=c(t,f);if(!e)return!1;let n=parseInt(e.slice(0,-1),10),r=e.slice(-1);return l(n,g)===r},D=t=>{let e=c(t,x);if(!e)return!1;let n=e.slice(-1),r=e[0],o=parseInt((r==="X"?"0":r==="Y"?"1":"2")+e.slice(1,-1),10);return l(o,g)===n},T=t=>{let e=c(t,I);if(!e)return!1;let n=e[0],r=e.slice(1,8),u=e[8],{digit:o,letter:s}=d(r);return C.includes(n)?u===s:E.includes(n)?u===String(o):u===String(o)||u===s},L=t=>y(t)||D(t)||T(t);export{T as validateCIF,y as validateDNI,L as validateES,D as validateNIE};
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * Spanish Tax ID Validators (DNI, NIE, CIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
@@ -0,0 +1,23 @@
1
+ "use strict";var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var h=(e,t)=>{for(var r in t)i(e,r,{get:t[r],enumerable:!0})},R=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of I(t))!y.call(e,o)&&o!==r&&i(e,o,{get:()=>t[o],enumerable:!(n=x(t,o))||n.enumerable});return e};var E=e=>R(i({},"__esModule",{value:!0}),e);var k={};h(k,{validateFR:()=>D,validateFR_NIR:()=>N,validateFR_SIREN_SIRET:()=>C,validateNIR:()=>c,validateSIREN:()=>a,validateSIREN_SIRET:()=>m,validateSIRET:()=>p});module.exports=E(k);var d=e=>typeof e=="string"&&e.length>0;var s=e=>d(e)?e.toUpperCase().replace(/[\s-]/g,""):null,f=(e,t)=>{let r=s(e);return r===null?null:t.test(r)?r:null};var u=e=>{let t=0,r=!1;for(let n=e.length-1;n>=0;n--){let o=parseInt(e[n],10);r&&(o*=2,o>9&&(o-=9)),t+=o,r=!r}return t%10===0};var g=e=>Number(97n-e%97n);var l=e=>/^(\d)\1+$/.test(e);var S=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/,b=/^\d{9}$/,T=/^\d{14}$/,c=e=>{let t=f(e,S);if(!t)return!1;let r=parseInt(t.slice(-2),10),n=t.slice(0,-2),o=n.slice(5,7);return o==="2A"&&(n=n.slice(0,5)+"19"+n.slice(7)),o==="2B"&&(n=n.slice(0,5)+"18"+n.slice(7)),g(BigInt(n))===r},a=e=>{let t=s(e);return!t||!b.test(t)||l(t)?!1:u(t)},p=e=>{let t=s(e);return!t||!T.test(t)||l(t)?!1:u(t)},m=e=>{let t=s(e);return t?t.length===9?a(t):t.length===14?p(t):!1:!1},D=e=>{let t=s(e);return t?t.length===15?c(e):t.length===9?a(e):t.length===14?p(e):!1:!1},C=m,N=c;0&&(module.exports={validateFR,validateFR_NIR,validateFR_SIREN_SIRET,validateNIR,validateSIREN,validateSIREN_SIRET,validateSIRET});
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * French Tax ID Validators (NIR, SIREN, SIRET)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
@@ -0,0 +1,41 @@
1
+ /**
2
+ * French Tax ID Validators (NIR, SIREN, SIRET)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validate French NIR (Numéro d'Inscription au Répertoire) - Social Security Number.
8
+ * @param value - The NIR number to validate (15 digits)
9
+ * @returns boolean indicating whether the NIR is valid
10
+ * @documentation https://www.service-public.gouv.fr/
11
+ */
12
+ declare const validateNIR: (value: unknown) => boolean;
13
+ /**
14
+ * Validate French SIREN (Système d'Identification du Répertoire des Entreprises).
15
+ * @param value - The SIREN number to validate (9 digits)
16
+ * @returns boolean indicating whether the SIREN is valid
17
+ */
18
+ declare const validateSIREN: (value: unknown) => boolean;
19
+ /**
20
+ * Validate French SIRET (Système d'Identification du Répertoire des Établissements).
21
+ * @param value - The SIRET number to validate (14 digits = SIREN + NIC)
22
+ * @returns boolean indicating whether the SIRET is valid
23
+ */
24
+ declare const validateSIRET: (value: unknown) => boolean;
25
+ /**
26
+ * Validate French SIREN or SIRET numbers (auto-detect by length).
27
+ * @param value - The SIREN (9 digits) or SIRET (14 digits) number to validate
28
+ * @returns boolean indicating whether the number is valid
29
+ */
30
+ declare const validateSIREN_SIRET: (value: unknown) => boolean;
31
+ /**
32
+ * Validates French identification numbers: NIR, SIREN, and SIRET (auto-detect).
33
+ * @param value - The identification number to validate
34
+ * @returns boolean indicating whether the identification number is valid
35
+ * @documentation https://www.service-public.gouv.fr/
36
+ */
37
+ declare const validateFR: (value: unknown) => boolean;
38
+ declare const validateFR_SIREN_SIRET: (value: unknown) => boolean;
39
+ declare const validateFR_NIR: (value: unknown) => boolean;
40
+
41
+ export { validateFR, validateFR_NIR, validateFR_SIREN_SIRET, validateNIR, validateSIREN, validateSIREN_SIRET, validateSIRET };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * French Tax ID Validators (NIR, SIREN, SIRET)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validate French NIR (Numéro d'Inscription au Répertoire) - Social Security Number.
8
+ * @param value - The NIR number to validate (15 digits)
9
+ * @returns boolean indicating whether the NIR is valid
10
+ * @documentation https://www.service-public.gouv.fr/
11
+ */
12
+ declare const validateNIR: (value: unknown) => boolean;
13
+ /**
14
+ * Validate French SIREN (Système d'Identification du Répertoire des Entreprises).
15
+ * @param value - The SIREN number to validate (9 digits)
16
+ * @returns boolean indicating whether the SIREN is valid
17
+ */
18
+ declare const validateSIREN: (value: unknown) => boolean;
19
+ /**
20
+ * Validate French SIRET (Système d'Identification du Répertoire des Établissements).
21
+ * @param value - The SIRET number to validate (14 digits = SIREN + NIC)
22
+ * @returns boolean indicating whether the SIRET is valid
23
+ */
24
+ declare const validateSIRET: (value: unknown) => boolean;
25
+ /**
26
+ * Validate French SIREN or SIRET numbers (auto-detect by length).
27
+ * @param value - The SIREN (9 digits) or SIRET (14 digits) number to validate
28
+ * @returns boolean indicating whether the number is valid
29
+ */
30
+ declare const validateSIREN_SIRET: (value: unknown) => boolean;
31
+ /**
32
+ * Validates French identification numbers: NIR, SIREN, and SIRET (auto-detect).
33
+ * @param value - The identification number to validate
34
+ * @returns boolean indicating whether the identification number is valid
35
+ * @documentation https://www.service-public.gouv.fr/
36
+ */
37
+ declare const validateFR: (value: unknown) => boolean;
38
+ declare const validateFR_SIREN_SIRET: (value: unknown) => boolean;
39
+ declare const validateFR_NIR: (value: unknown) => boolean;
40
+
41
+ export { validateFR, validateFR_NIR, validateFR_SIREN_SIRET, validateNIR, validateSIREN, validateSIREN_SIRET, validateSIRET };
@@ -0,0 +1,23 @@
1
+ var l=e=>typeof e=="string"&&e.length>0;var s=e=>l(e)?e.toUpperCase().replace(/[\s-]/g,""):null,c=(e,t)=>{let r=s(e);return r===null?null:t.test(r)?r:null};var i=e=>{let t=0,r=!1;for(let n=e.length-1;n>=0;n--){let o=parseInt(e[n],10);r&&(o*=2,o>9&&(o-=9)),t+=o,r=!r}return t%10===0};var a=e=>Number(97n-e%97n);var u=e=>/^(\d)\1+$/.test(e);var g=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/,m=/^\d{9}$/,x=/^\d{14}$/,p=e=>{let t=c(e,g);if(!t)return!1;let r=parseInt(t.slice(-2),10),n=t.slice(0,-2),o=n.slice(5,7);return o==="2A"&&(n=n.slice(0,5)+"19"+n.slice(7)),o==="2B"&&(n=n.slice(0,5)+"18"+n.slice(7)),a(BigInt(n))===r},d=e=>{let t=s(e);return!t||!m.test(t)||u(t)?!1:i(t)},f=e=>{let t=s(e);return!t||!x.test(t)||u(t)?!1:i(t)},I=e=>{let t=s(e);return t?t.length===9?d(t):t.length===14?f(t):!1:!1},T=e=>{let t=s(e);return t?t.length===15?p(e):t.length===9?d(e):t.length===14?f(e):!1:!1},D=I,C=p;export{T as validateFR,C as validateFR_NIR,D as validateFR_SIREN_SIRET,p as validateNIR,d as validateSIREN,I as validateSIREN_SIRET,f as validateSIRET};
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * French Tax ID Validators (NIR, SIREN, SIRET)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
@@ -0,0 +1,23 @@
1
+ "use strict";var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var x=(t,e)=>{for(var o in e)s(t,o,{get:e[o],enumerable:!0})},I=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of m(e))!f.call(t,n)&&n!==o&&s(t,n,{get:()=>e[n],enumerable:!(r=g(e,n))||r.enumerable});return t};var y=t=>I(s({},"__esModule",{value:!0}),t);var T={};x(T,{validateNIF:()=>l,validatePT:()=>C});module.exports=y(T);var i=t=>typeof t=="string"&&t.length>0;var u=t=>i(t)?t.toUpperCase().replace(/[\s-]/g,""):null;var c=t=>{let r=11-t.reduce((n,p,a)=>{let d=9-a;return n+p*d},0)%11;return r>=10?0:r};var D=/^[0-9]{9}$/,h=["1","2","3","5","6","8","9"],l=t=>{let e=u(t);if(!e||!D.test(e)||!h.includes(e[0]))return!1;let o=e.slice(0,8).split("").map(n=>parseInt(n,10));return c(o)===parseInt(e[8],10)},C=l;0&&(module.exports={validateNIF,validatePT});
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * Portuguese Tax ID Validators (NIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Portuguese Tax ID Validators (NIF)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validates a Portuguese NIF (Número de Identificação Fiscal).
8
+ * @param value - The NIF number to validate (9 digits)
9
+ * @returns boolean indicating whether the NIF is valid
10
+ * @documentation https://en.wikipedia.org/wiki/Tax_identification_number#Portugal
11
+ */
12
+ declare const validateNIF: (value: unknown) => boolean;
13
+ /**
14
+ * Validates a Portuguese NIF (Número de Identificação Fiscal).
15
+ * Alias for validateNIF for consistency with other country validators.
16
+ * @param value - The NIF number to validate
17
+ * @returns boolean indicating whether the NIF is valid
18
+ */
19
+ declare const validatePT: (value: unknown) => boolean;
20
+
21
+ export { validateNIF, validatePT };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Portuguese Tax ID Validators (NIF)
3
+ * @author AngelBlanco97
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * Validates a Portuguese NIF (Número de Identificação Fiscal).
8
+ * @param value - The NIF number to validate (9 digits)
9
+ * @returns boolean indicating whether the NIF is valid
10
+ * @documentation https://en.wikipedia.org/wiki/Tax_identification_number#Portugal
11
+ */
12
+ declare const validateNIF: (value: unknown) => boolean;
13
+ /**
14
+ * Validates a Portuguese NIF (Número de Identificação Fiscal).
15
+ * Alias for validateNIF for consistency with other country validators.
16
+ * @param value - The NIF number to validate
17
+ * @returns boolean indicating whether the NIF is valid
18
+ */
19
+ declare const validatePT: (value: unknown) => boolean;
20
+
21
+ export { validateNIF, validatePT };
@@ -0,0 +1,23 @@
1
+ var s=t=>typeof t=="string"&&t.length>0;var i=t=>s(t)?t.toUpperCase().replace(/[\s-]/g,""):null;var u=t=>{let n=11-t.reduce((o,c,l)=>{let p=9-l;return o+c*p},0)%11;return n>=10?0:n};var a=/^[0-9]{9}$/,d=["1","2","3","5","6","8","9"],g=t=>{let e=i(t);if(!e||!a.test(e)||!d.includes(e[0]))return!1;let r=e.slice(0,8).split("").map(o=>parseInt(o,10));return u(r)===parseInt(e[8],10)},h=g;export{g as validateNIF,h as validatePT};
2
+ /**
3
+ * Types for Tax ID Validator
4
+ * @author AngelBlanco97
5
+ * @license MIT
6
+ */
7
+ /**
8
+ * Sanitization utilities for Tax ID validation
9
+ * Single Responsibility: Only handles string cleaning/normalization
10
+ * @author AngelBlanco97
11
+ * @license MIT
12
+ */
13
+ /**
14
+ * Common validation algorithms
15
+ * Single Responsibility: Only contains mathematical validation algorithms
16
+ * @author AngelBlanco97
17
+ * @license MIT
18
+ */
19
+ /**
20
+ * Portuguese Tax ID Validators (NIF)
21
+ * @author AngelBlanco97
22
+ * @license MIT
23
+ */
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "validator-tax-id",
3
- "version": "1.1.3",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
+ "funding": {
6
+ "type": "paypal",
7
+ "url": "https://paypal.me/AngelBlanco747"
8
+ },
5
9
  "main": "./dist/index.cjs",
6
10
  "module": "./dist/index.js",
7
11
  "types": "./dist/index.d.ts",
@@ -11,6 +15,21 @@
11
15
  "types": "./dist/index.d.ts",
12
16
  "import": "./dist/index.js",
13
17
  "require": "./dist/index.cjs"
18
+ },
19
+ "./es": {
20
+ "types": "./dist/validators/es.d.ts",
21
+ "import": "./dist/validators/es.js",
22
+ "require": "./dist/validators/es.cjs"
23
+ },
24
+ "./fr": {
25
+ "types": "./dist/validators/fr.d.ts",
26
+ "import": "./dist/validators/fr.js",
27
+ "require": "./dist/validators/fr.cjs"
28
+ },
29
+ "./pt": {
30
+ "types": "./dist/validators/pt.d.ts",
31
+ "import": "./dist/validators/pt.js",
32
+ "require": "./dist/validators/pt.cjs"
14
33
  }
15
34
  },
16
35
  "files": [
@@ -1,33 +0,0 @@
1
- "use strict";var TaxIdValidator=(()=>{var u=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var y=(e,t)=>{for(var o in t)u(e,o,{get:t[o],enumerable:!0})},C=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of m(t))!b.call(e,n)&&n!==o&&u(e,n,{get:()=>t[n],enumerable:!(r=R(t,n))||r.enumerable});return e};var S=e=>C(u({},"__esModule",{value:!0}),e);var h={};y(h,{validateIdentification:()=>$});var T="TRWAGMYFPDXBNJZSQVHLCKE",v="JABCDEFGHI",N=/^([0-9]{8}|[XYZ][0-9]{7})[A-Z]$/,_=/^[ABCDEFGHJNPQRSUVW][0-9]{7}[0-9A-J]$/;var I=e=>{if(typeof e!="string")return!1;let t=e.toUpperCase().replace(/\s|-/g,"");if(N.test(t)){let s=t.slice(0,-1),f=t.slice(-1);s=s.replace("X","0").replace("Y","1").replace("Z","2");let a=parseInt(s,10);return T[a%23]===f}if(!_.test(t))return!1;let o=t[0],r=t.slice(1,8),n=t[8],l=0,c=0;for(let s=0;s<r.length;s++){let f=parseInt(r[s],10);if(s%2===0){let a=f*2;c+=a>9?a-9:a}else l+=f}let i=(10-(l+c)%10)%10,p=v[i];return"PQRSNW".includes(o)?n===p:"ABEH".includes(o)?n===String(i):n===String(i)||n===p};var A=/^[1-8]\d{2}(0[1-9]|1[0-2]|[2-9]\d)(\d{2}|2A|2B|97\d)\d{6}\d{2}$/;var g=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");return t.length===15?x(t):t.length===9||t.length===14?F(t):!1},D=e=>{let t=0,o=!1;for(let r=e.length-1;r>=0;r--){let n=parseInt(e[r],10);o&&(n*=2,n>9&&(n-=9)),t+=n,o=!o}return t%10===0},F=e=>{let t=e.replace(/\s|-/g,"");return!/^\d{9}$/.test(t)&&!/^\d{14}$/.test(t)||/^(\d)\1+$/.test(t)?!1:D(t)},x=e=>{let t=e.toUpperCase().replace(/\s|-/g,"");if(!A.test(t))return!1;let o=parseInt(t.slice(-2),10),r=t.slice(0,-2),n=r.slice(5,7);n==="2A"&&(r=r.slice(0,5)+"19"+r.slice(7)),n==="2B"&&(r=r.slice(0,5)+"18"+r.slice(7));let l=BigInt(r);return Number(97n-l%97n)===o};var G=["1","2","3","5","6","8","9"];var E=e=>{if(typeof e!="string")return!1;let t=e.replace(/\s|-/g,"");if(!/^[0-9]{9}$/.test(t)||!G.includes(t[0]))return!1;let n=11-t.slice(0,8).split("").reduce((l,c,d)=>{let i=9-d;return l+parseInt(c,10)*i},0)%11;return n>=10&&(n=0),n===parseInt(t[8],10)};var L={es:I,pt:E,fr:g};var $=(e,t)=>{let o=L[e];return o?o(t):(console.warn(`[TaxIDValidator] Country '${e}' not supported yet.`),!1)};return S(h);})();
2
- /**
3
- * Validate Spanish DNI/NIE/CIF numbers.
4
- * @param value - The DNI or NIE number to validate
5
- * @returns boolean indicating whether the DNI/NIE is valid (true) or not (false)
6
- * @author AngelBlanco97
7
- * @license MIT
8
- * @documentation https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/calculo-del-digito-de-control-del-nif-nie/
9
- */
10
- /**
11
- * Validates French identification numbers: NIR (Numéro d'Inscription au Répertoire), SIREN, and SIRET.
12
- * @param value - The identification number to validate
13
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
14
- * @author AngelBlanco97
15
- * @license MIT
16
- * @documentation https://www.service-public.gouv.fr/
17
- */
18
- /**
19
- * Validates a Portuguese NIF (Número de Identificação Fiscal).
20
- * @param value - The NIF number to validate
21
- * @returns boolean indicating whether the NIF is valid (true) or not (false)
22
- * @author AngelBlanco97
23
- * @license MIT
24
- * @documentation https://en.wikipedia.org/wiki/Tax_identification_number#Portugal
25
- */
26
- /**
27
- * Function to validate identification numbers based on country/type.
28
- * @param Country - The country code representing the type of identification number (e.g., 'es' for Spain, 'pt' for Portugal)
29
- * @param value - The identification number to validate
30
- * @returns boolean indicating whether the identification number is valid (true) or not (false)
31
- * @author AngelBlanco97
32
- * @license MIT
33
- */