@exodus/stdnum 1.0.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 +225 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +190 -0
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +58 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# @exodus/stdnum
|
|
2
|
+
|
|
3
|
+
Library for validating and identifying tax IDs, national identification numbers, and passports across 70+ countries.
|
|
4
|
+
|
|
5
|
+
Built on top of [stdnum](https://www.npmjs.com/package/stdnum), with additional validators and customizations tailored for KYC and payment platform integrations.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add @exodus/stdnum
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### getDocumentType
|
|
16
|
+
|
|
17
|
+
Returns the document type abbreviation for a valid identification number. Useful for determining which type of ID was provided when multiple formats are accepted.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { getDocumentType } from '@exodus/stdnum'
|
|
21
|
+
|
|
22
|
+
getDocumentType('US', '123-45-6789') // 'ssn'
|
|
23
|
+
getDocumentType('AR', '20-05536168-2') // 'cuil'
|
|
24
|
+
getDocumentType('AR', '12345678') // 'dni'
|
|
25
|
+
getDocumentType('AU', 'M1234567') // 'passport'
|
|
26
|
+
getDocumentType('US', 'invalid') // undefined
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### isValid
|
|
30
|
+
|
|
31
|
+
Simple boolean check for whether an identification number is valid for a given country.
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
import { isValid } from '@exodus/stdnum'
|
|
35
|
+
|
|
36
|
+
isValid('US', '123-45-6789') // true
|
|
37
|
+
isValid('US', 'invalid') // false
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Supported Countries
|
|
41
|
+
|
|
42
|
+
| Country | Code | Document Types |
|
|
43
|
+
| ---------------------- | ---- | ------------------------------------------ |
|
|
44
|
+
| Albania | AL | NIPT |
|
|
45
|
+
| Andorra | AD | NRT |
|
|
46
|
+
| Argentina | AR | CBU, DNI, CUIL, Passport |
|
|
47
|
+
| Armenia | AM | TIN, Passport |
|
|
48
|
+
| Australia | AU | TFN, ABN, ACN, Passport |
|
|
49
|
+
| Belarus | BY | UNP |
|
|
50
|
+
| Belgium | BE | NRRN, VAT, Passport |
|
|
51
|
+
| Belize | BZ | TIN |
|
|
52
|
+
| Bosnia and Herzegovina | BA | JMBG |
|
|
53
|
+
| Brazil | BR | CPF, CNPJ, Passport |
|
|
54
|
+
| Bulgaria | BG | UCN, PNF, VAT, Passport |
|
|
55
|
+
| Canada | CA | SIN, BC BHN, GST, PST, QST, Passport |
|
|
56
|
+
| Chile | CL | RUN |
|
|
57
|
+
| China | CN | RICN, USCC, Passport |
|
|
58
|
+
| Colombia | CO | NIT |
|
|
59
|
+
| Costa Rica | CR | CPF, CPJ, CR |
|
|
60
|
+
| Croatia | HR | OIB |
|
|
61
|
+
| Cyprus | CY | VAT |
|
|
62
|
+
| Czech Republic | CZ | RC, DIC, Passport |
|
|
63
|
+
| Denmark | DK | CPR, CVR |
|
|
64
|
+
| Ecuador | EC | CI, RUC |
|
|
65
|
+
| Egypt | EG | TN |
|
|
66
|
+
| El Salvador | SV | NIT |
|
|
67
|
+
| Estonia | EE | IK, KMKR, Passport |
|
|
68
|
+
| Faroe Islands | FO | VN |
|
|
69
|
+
| Finland | FI | HETU, ALV, Passport |
|
|
70
|
+
| France | FR | SPI, NIR, SIREN, SIRET, VAT, Passport |
|
|
71
|
+
| Germany | DE | Steuer ID, Passport, PWNR, STNR, SVNR, VAT |
|
|
72
|
+
| Ghana | GH | TIN |
|
|
73
|
+
| Greece | GR | AMKA, VAT |
|
|
74
|
+
| Guatemala | GT | CUI, NIT |
|
|
75
|
+
| Guinea | GN | NIFP |
|
|
76
|
+
| Hungary | HU | ANUM |
|
|
77
|
+
| Iceland | IS | Kennitala, VSK |
|
|
78
|
+
| India | IN | PAN, Aadhaar, EPIC, GSTIN, VID, Passport |
|
|
79
|
+
| Ireland | IE | PPSN, VAT, Passport |
|
|
80
|
+
| Israel | IL | HP, IDNR |
|
|
81
|
+
| Italy | IT | Codice Fiscale, AIC, VAT, Passport |
|
|
82
|
+
| Japan | JP | My Number, CN, Passport |
|
|
83
|
+
| Kenya | KE | PIN |
|
|
84
|
+
| Latvia | LV | VAT |
|
|
85
|
+
| Liechtenstein | LI | PEID |
|
|
86
|
+
| Lithuania | LT | Asmens, PVM |
|
|
87
|
+
| Luxembourg | LU | VAT |
|
|
88
|
+
| Malta | MT | VAT |
|
|
89
|
+
| Mauritius | MU | NID |
|
|
90
|
+
| Mexico | MX | CURP, RFC, CLABE |
|
|
91
|
+
| Moldova | MD | IDNO |
|
|
92
|
+
| Monaco | MC | VAT |
|
|
93
|
+
| Netherlands | NL | BSN, VAT, Passport |
|
|
94
|
+
| New Zealand | NZ | IRD, Passport |
|
|
95
|
+
| Norway | NO | Fødselsnummer, VAT, Orgnr |
|
|
96
|
+
| Paraguay | PY | National ID, RUC |
|
|
97
|
+
| Peru | PE | CUI, CE, RUC |
|
|
98
|
+
| Philippines | PH | TIN, Passport |
|
|
99
|
+
| Poland | PL | PESEL, VAT, Passport |
|
|
100
|
+
| Portugal | PT | NIF, CC, Passport |
|
|
101
|
+
| Romania | RO | CNP, VAT, Passport |
|
|
102
|
+
| Russia | RU | INN, Passport |
|
|
103
|
+
| Saudi Arabia | SA | TIN |
|
|
104
|
+
| Serbia | RS | JMBG |
|
|
105
|
+
| Slovakia | SK | VAT, RC |
|
|
106
|
+
| Slovenia | SI | VAT, EMSO, TIN |
|
|
107
|
+
| South Korea | KR | RRN, BRN, Passport |
|
|
108
|
+
| Spain | ES | NIE, NIF, NSS, Passport |
|
|
109
|
+
| Sweden | SE | TIN, VAT, Passport |
|
|
110
|
+
| Switzerland | CH | AHV, UID, VAT, Passport |
|
|
111
|
+
| Thailand | TH | TIN, Passport |
|
|
112
|
+
| Tunisia | TN | MF |
|
|
113
|
+
| United Arab Emirates | AE | Emirates ID |
|
|
114
|
+
| United Kingdom | GB | NINO, UTR, VAT, Passport |
|
|
115
|
+
| United States | US | SSN |
|
|
116
|
+
| Uruguay | UY | CI, VAT, NIE |
|
|
117
|
+
|
|
118
|
+
## Document Type Abbreviations
|
|
119
|
+
|
|
120
|
+
| Abbreviation | Full Name |
|
|
121
|
+
| --------------- | ----------------------------------------------- |
|
|
122
|
+
| `aadhaar` | Indian Unique Identification Number |
|
|
123
|
+
| `abn` | Australian Business Number |
|
|
124
|
+
| `acn` | Australian Company Number |
|
|
125
|
+
| `ahv` | Swiss Social Security Number |
|
|
126
|
+
| `aic` | Italian Pharmaceutical Product Code |
|
|
127
|
+
| `alv` | Finnish VAT Number |
|
|
128
|
+
| `amka` | Greek Social Security Number |
|
|
129
|
+
| `anum` | Hungarian VAT Number |
|
|
130
|
+
| `asmens` | Lithuanian Personal Code |
|
|
131
|
+
| `bc_bhn` | British Columbia Birth Health Number |
|
|
132
|
+
| `brn` | Korean Business Registration Number |
|
|
133
|
+
| `bsn` | Dutch Citizen Service Number |
|
|
134
|
+
| `cbu` | Argentine Bank Account Number |
|
|
135
|
+
| `cc` | Portuguese Citizen Card |
|
|
136
|
+
| `ce` | Peruvian Foreigner Card |
|
|
137
|
+
| `ci` | Identity Card (Ecuador/Uruguay) |
|
|
138
|
+
| `clabe` | Mexican Bank Account Number |
|
|
139
|
+
| `cn` | Japanese Corporate Number |
|
|
140
|
+
| `cnp` | Romanian Personal Numeric Code |
|
|
141
|
+
| `cnpj` | Brazilian Company Taxpayer Registry |
|
|
142
|
+
| `cf` | Italian Fiscal Code |
|
|
143
|
+
| `cpf` | Brazilian/Costa Rican Individual Taxpayer ID |
|
|
144
|
+
| `cpj` | Costa Rican Legal Entity ID |
|
|
145
|
+
| `cpr` | Danish Personal Identification Number |
|
|
146
|
+
| `cr` | Costa Rican ID |
|
|
147
|
+
| `cui` | Personal ID (Guatemala/Peru) |
|
|
148
|
+
| `cuil` | Argentine Labor Identification Code |
|
|
149
|
+
| `curp` | Mexican Population Registry Code |
|
|
150
|
+
| `cvr` | Danish Business Registration Number |
|
|
151
|
+
| `dic` | Czech VAT Number |
|
|
152
|
+
| `dni` | Argentine National Identity Document |
|
|
153
|
+
| `emirates_id` | UAE Emirates ID |
|
|
154
|
+
| `emso` | Slovenian Unique Master Citizen Number |
|
|
155
|
+
| `epic` | Indian Voter ID Card |
|
|
156
|
+
| `fodselsnummer` | Norwegian Birth Number |
|
|
157
|
+
| `gst` | Canadian Goods and Services Tax Number |
|
|
158
|
+
| `gstin` | Indian GST Identification Number |
|
|
159
|
+
| `hetu` | Finnish Personal Identity Code |
|
|
160
|
+
| `hp` | Israeli Company Number |
|
|
161
|
+
| `idno` | Moldovan Company ID |
|
|
162
|
+
| `idnr` | Israeli ID Number |
|
|
163
|
+
| `ik` | Estonian Personal Identification Code |
|
|
164
|
+
| `inn` | Russian Taxpayer Identification Number |
|
|
165
|
+
| `ird` | New Zealand Inland Revenue Number |
|
|
166
|
+
| `jmbg` | Unique Master Citizen Number (Bosnia/Serbia) |
|
|
167
|
+
| `kennitala` | Icelandic Personal/Company ID |
|
|
168
|
+
| `kmkr` | Estonian VAT Number |
|
|
169
|
+
| `mf` | Tunisian Tax ID |
|
|
170
|
+
| `mn` | Japanese My Number |
|
|
171
|
+
| `national_id` | Paraguayan National ID |
|
|
172
|
+
| `nid` | Mauritius National ID |
|
|
173
|
+
| `nie` | Foreigner Identification Number (Spain/Uruguay) |
|
|
174
|
+
| `nif` | Tax Identification Number (Spain/Portugal) |
|
|
175
|
+
| `nifp` | Guinea Tax ID |
|
|
176
|
+
| `nino` | UK National Insurance Number |
|
|
177
|
+
| `nipt` | Albanian Business Tax Number |
|
|
178
|
+
| `nir` | French Social Security Number |
|
|
179
|
+
| `nit` | Tax ID Number (Colombia/Guatemala/El Salvador) |
|
|
180
|
+
| `nrrn` | Belgian National Register Number |
|
|
181
|
+
| `nrt` | Andorran Tax Number |
|
|
182
|
+
| `nss` | Spanish Social Security Number |
|
|
183
|
+
| `oib` | Croatian Personal Identification Number |
|
|
184
|
+
| `orgnr` | Norwegian Organization Number |
|
|
185
|
+
| `pan` | Indian Permanent Account Number |
|
|
186
|
+
| `passport` | Passport Number |
|
|
187
|
+
| `peid` | Liechtenstein Company ID |
|
|
188
|
+
| `pesel` | Polish National Identification Number |
|
|
189
|
+
| `pin` | Kenyan Personal Identification Number |
|
|
190
|
+
| `pnf` | Bulgarian Foreigner Personal Number |
|
|
191
|
+
| `ppsn` | Irish Personal Public Service Number |
|
|
192
|
+
| `pst` | Canadian Provincial Sales Tax Number |
|
|
193
|
+
| `pvm` | Lithuanian VAT Number |
|
|
194
|
+
| `pwnr` | German Passport Card Number |
|
|
195
|
+
| `qst` | Quebec Sales Tax Number |
|
|
196
|
+
| `rc` | Birth Number (Czech/Slovakia) |
|
|
197
|
+
| `rfc` | Mexican Federal Taxpayer Registry |
|
|
198
|
+
| `ricn` | Chinese Resident Identity Card Number |
|
|
199
|
+
| `rrn` | Korean Resident Registration Number |
|
|
200
|
+
| `ruc` | Taxpayer Registry (Ecuador/Paraguay/Peru) |
|
|
201
|
+
| `run` | Chilean National Identification Number |
|
|
202
|
+
| `sin` | Canadian Social Insurance Number |
|
|
203
|
+
| `siren` | French Company Registration Number |
|
|
204
|
+
| `siret` | French Establishment Identification Number |
|
|
205
|
+
| `spi` | French Tax Identification Number |
|
|
206
|
+
| `ssn` | US Social Security Number |
|
|
207
|
+
| `steuer_id` | German Tax Identification Number |
|
|
208
|
+
| `stnr` | German Tax Number |
|
|
209
|
+
| `svnr` | German Social Insurance Number |
|
|
210
|
+
| `tfn` | Australian Tax File Number |
|
|
211
|
+
| `tin` | Tax Identification Number (generic) |
|
|
212
|
+
| `tn` | Egyptian Tax Number |
|
|
213
|
+
| `ucn` | Bulgarian Unified Civil Number |
|
|
214
|
+
| `uid` | Swiss Business ID |
|
|
215
|
+
| `unp` | Belarusian Taxpayer Number |
|
|
216
|
+
| `uscc` | Chinese Unified Social Credit Code |
|
|
217
|
+
| `utr` | UK Unique Taxpayer Reference |
|
|
218
|
+
| `vat` | Value Added Tax Number |
|
|
219
|
+
| `vid` | Indian Virtual ID |
|
|
220
|
+
| `vn` | Faroese V-Number |
|
|
221
|
+
| `vsk` | Icelandic VAT Number |
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
MIT
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { stdnum } from 'stdnum';
|
|
2
|
+
import { changeAbbreviation, createPassportValidator, createValidator } from './utils.js';
|
|
3
|
+
const cuil = createValidator('Código Único de Identificación Laboral', 'CUIL');
|
|
4
|
+
const tin = createValidator('Tax Identification Number', 'TIN');
|
|
5
|
+
const ricn = changeAbbreviation(stdnum.CN.ric, 'ricn');
|
|
6
|
+
const rc = changeAbbreviation(stdnum.CZ.rc, 'rc');
|
|
7
|
+
const ppsn = changeAbbreviation(stdnum.IE.pps, 'ppsn');
|
|
8
|
+
const pynationalid = changeAbbreviation(stdnum.PY.cedula, 'national_id');
|
|
9
|
+
const nn = changeAbbreviation(stdnum.BE.nn, 'nrrn');
|
|
10
|
+
const ucn = changeAbbreviation(stdnum.BG.egn, 'ucn');
|
|
11
|
+
const spi = changeAbbreviation(stdnum.FR.nif, 'spi');
|
|
12
|
+
const steuerid = changeAbbreviation(stdnum.DE.idnr, 'steuer_id');
|
|
13
|
+
const belgianvat = changeAbbreviation(stdnum.BE.vat, 'vat');
|
|
14
|
+
const bulgarianvat = changeAbbreviation(stdnum.BG.vat, 'vat');
|
|
15
|
+
const swissvat = changeAbbreviation(stdnum.CH.vat, 'vat');
|
|
16
|
+
const cypriotvat = changeAbbreviation(stdnum.CY.vat, 'vat');
|
|
17
|
+
const germanvat = changeAbbreviation(stdnum.DE.vat, 'vat');
|
|
18
|
+
const britishvat = changeAbbreviation(stdnum.GB.vat, 'vat');
|
|
19
|
+
const greekvat = changeAbbreviation(stdnum.GR.vat, 'vat');
|
|
20
|
+
const irishvat = changeAbbreviation(stdnum.IE.vat, 'vat');
|
|
21
|
+
const italianvat = changeAbbreviation(stdnum.IT.iva, 'vat');
|
|
22
|
+
const mn = createValidator('Japanese My Number', 'mn', 12);
|
|
23
|
+
const ahv = changeAbbreviation(stdnum.CH.ssn, 'ahv');
|
|
24
|
+
const swedentin = changeAbbreviation(stdnum.SE.personnummer, 'tin');
|
|
25
|
+
const swedenvat = changeAbbreviation(stdnum.SE.vat, 'vat');
|
|
26
|
+
const armeniatin = createValidator('Armenian Taxpayer Identification Number', 'tin', 8);
|
|
27
|
+
const emiratesid = createValidator('Emirates ID', 'emirates_id', 15);
|
|
28
|
+
const pnf = changeAbbreviation(stdnum.BG.pnf, 'pnf');
|
|
29
|
+
const unp = changeAbbreviation(stdnum.BY.unp, 'unp');
|
|
30
|
+
const dic = changeAbbreviation(stdnum.CZ.dic, 'dic');
|
|
31
|
+
const stnr = changeAbbreviation(stdnum.DE.stnr, 'stnr');
|
|
32
|
+
const alv = changeAbbreviation(stdnum.FI.alv, 'alv');
|
|
33
|
+
const frenchvat = changeAbbreviation(stdnum.FR.tva, 'vat');
|
|
34
|
+
const hp = changeAbbreviation(stdnum.IL.hp, 'hp');
|
|
35
|
+
const idnr = changeAbbreviation(stdnum.IL.idnr, 'idnr');
|
|
36
|
+
const aadhaar = changeAbbreviation(stdnum.IN.aadhaar, 'aadhaar');
|
|
37
|
+
const kennitala = changeAbbreviation(stdnum.IS.kennitala, 'kennitala');
|
|
38
|
+
const asmens = changeAbbreviation(stdnum.LT.asmens, 'asmens');
|
|
39
|
+
const pvm = changeAbbreviation(stdnum.LT.pvm, 'pvm');
|
|
40
|
+
const luxembourgvat = changeAbbreviation(stdnum.LU.tva, 'vat');
|
|
41
|
+
const latvianvat = changeAbbreviation(stdnum.LV.pvn, 'vat');
|
|
42
|
+
const monacovat = changeAbbreviation(stdnum.MC.tva, 'vat');
|
|
43
|
+
const maltesevat = changeAbbreviation(stdnum.MT.vat, 'vat');
|
|
44
|
+
const dutchvat = changeAbbreviation(stdnum.NL.btw, 'vat');
|
|
45
|
+
const norwegianvat = changeAbbreviation(stdnum.NO.mva, 'vat');
|
|
46
|
+
const fodselsnummer = changeAbbreviation(stdnum.NO.fodselsnummer, 'fodselsnummer');
|
|
47
|
+
const polishvat = changeAbbreviation(stdnum.PL.nip, 'vat');
|
|
48
|
+
const romanianvat = changeAbbreviation(stdnum.RO.cif, 'vat');
|
|
49
|
+
const inn = changeAbbreviation(stdnum.RU.inn, 'inn');
|
|
50
|
+
const slovenianvat = changeAbbreviation(stdnum.SI.ddv, 'vat');
|
|
51
|
+
const emso = changeAbbreviation(stdnum.SI.emso, 'emso');
|
|
52
|
+
const slovakvat = changeAbbreviation(stdnum.SK.dph, 'vat');
|
|
53
|
+
const uruguayanvat = changeAbbreviation(stdnum.UY.rut, 'vat');
|
|
54
|
+
const armenianpassport = createPassportValidator('Armenian Passport', /^[A-Z]{2}\d{7}$/);
|
|
55
|
+
const argentinianpassport = createPassportValidator('Argentinian Passport', /^[A-Z]{3}\d{6}$/);
|
|
56
|
+
const australianpassport = createPassportValidator('Australian Passport', /^[A-Z]\d{7}$/);
|
|
57
|
+
const belgianpassport = createPassportValidator('Belgian Passport', /^[A-Z]{2}\d{6}$/);
|
|
58
|
+
const bulgarianpassport = createPassportValidator('Bulgarian Passport', /^\d{9}$/);
|
|
59
|
+
const brazilianpassport = createPassportValidator('Brazilian Passport', /^[A-Z]{2}\d{6}$/);
|
|
60
|
+
const canadianpassport = createPassportValidator('Canadian Passport', /^[A-Z]{2}\d{6}$|^[A-Z]\d{6}[A-Z]{2}$/u);
|
|
61
|
+
const swisspassport = createPassportValidator('Swiss Passport', /^[A-Z]\d{7}$/);
|
|
62
|
+
const chinesepassport = createPassportValidator('Chinese Passport', /^G\d{8}$|^E(?![IO])[\dA-Z]\d{7}$/);
|
|
63
|
+
const czechpassport = createPassportValidator('Czech Passport', /^\d{8}$/);
|
|
64
|
+
const estonianpassport = createPassportValidator('Estonian Passport', /^([A-Z]\d{7}|[A-Z]{2}\d{7})$/);
|
|
65
|
+
const spanishpassport = createPassportValidator('Spanish Passport', /^[A-Z0-9]{2}([A-Z0-9]?)\d{6}$/);
|
|
66
|
+
const finnishpassport = createPassportValidator('Finnish Passport', /^[A-Z]{2}\d{7}$/);
|
|
67
|
+
const frenchpassport = createPassportValidator('French Passport', /^\d{2}[A-Z]{2}\d{5}$/);
|
|
68
|
+
const britishpassport = createPassportValidator('British Passport', /^\d{9}$/);
|
|
69
|
+
const irishpassport = createPassportValidator('Irish Passport', /^[A-Z0-9]{2}\d{7}$/);
|
|
70
|
+
const indianpassport = createPassportValidator('Indian Passport', /^[A-Z]{1}-?\d{7}$/);
|
|
71
|
+
const italianpassport = createPassportValidator('Italian Passport', /^[A-Z0-9]{2}\d{7}$/);
|
|
72
|
+
const japanesepassport = createPassportValidator('Japanese Passport', /^[A-Z]{2}\d{7}$/);
|
|
73
|
+
const koreanpassport = createPassportValidator('Korean Passport', /^[MS]\d{8}$/);
|
|
74
|
+
const netherlandspassport = createPassportValidator('Netherlands Passport', /^[A-Z]{2}[A-Z0-9]{6}\d$/);
|
|
75
|
+
const newzealandpassport = createPassportValidator('New Zealand Passport', /^([Ll]([Aa]|[Dd]|[Ff]|[Hh])|[Ee]([Aa]|[Pp])|[Nn])\d{6}$/);
|
|
76
|
+
const philippinepassport = createPassportValidator('Philippine Passport', /^([A-Z](\d{6}|\d{7}[A-Z]))|([A-Z]{2}(\d{6}|\d{7}))$/);
|
|
77
|
+
const polishpassport = createPassportValidator('Polish Passport', /^[A-Z]{2}\d{7}$/);
|
|
78
|
+
const portuguesepassport = createPassportValidator('Portuguese Passport', /^[A-Z]\d{6}$/);
|
|
79
|
+
const romanianpassport = createPassportValidator('Romanian Passport', /^\d{8,9}$/);
|
|
80
|
+
const russianpassport = createPassportValidator('Russian Passport', /^\d{9,10}$/);
|
|
81
|
+
const swedishpassport = createPassportValidator('Swedish Passport', /^\d{8}$/);
|
|
82
|
+
const thailandpassport = createPassportValidator('Thailand Passport', /^[A-Z]{1,2}\d{6,7}$/);
|
|
83
|
+
const validators = {
|
|
84
|
+
AD: [stdnum.AD.nrt],
|
|
85
|
+
AE: [emiratesid],
|
|
86
|
+
AL: [stdnum.AL.nipt],
|
|
87
|
+
AM: [armeniatin, armenianpassport],
|
|
88
|
+
AR: [stdnum.AR.cbu, stdnum.AR.dni, cuil, argentinianpassport],
|
|
89
|
+
AU: [stdnum.AU.tfn, stdnum.AU.abn, stdnum.AU.acn, australianpassport],
|
|
90
|
+
BA: [stdnum.BA.jmbg],
|
|
91
|
+
BE: [nn, belgianvat, belgianpassport],
|
|
92
|
+
BG: [ucn, pnf, bulgarianvat, bulgarianpassport],
|
|
93
|
+
BR: [stdnum.BR.cpf, stdnum.BR.cnpj, brazilianpassport],
|
|
94
|
+
BY: [unp],
|
|
95
|
+
BZ: [stdnum.BZ.tin],
|
|
96
|
+
CA: [
|
|
97
|
+
stdnum.CA.sin,
|
|
98
|
+
stdnum.CA.bc_bhn,
|
|
99
|
+
stdnum.CA.gst,
|
|
100
|
+
stdnum.CA.pst,
|
|
101
|
+
stdnum.CA.qst,
|
|
102
|
+
canadianpassport,
|
|
103
|
+
],
|
|
104
|
+
CH: [ahv, stdnum.CH.uid, swissvat, swisspassport],
|
|
105
|
+
CL: [stdnum.CL.run],
|
|
106
|
+
CN: [ricn, stdnum.CN.uscc, chinesepassport],
|
|
107
|
+
CO: [stdnum.CO.nit],
|
|
108
|
+
CR: [stdnum.CR.cpf, stdnum.CR.cpj, stdnum.CR.cr],
|
|
109
|
+
CY: [cypriotvat],
|
|
110
|
+
CZ: [rc, dic, czechpassport],
|
|
111
|
+
DE: [steuerid, stdnum.DE.passport, stdnum.DE.pwnr, stnr, stdnum.DE.svnr, germanvat],
|
|
112
|
+
DK: [stdnum.DK.cpr, stdnum.DK.cvr],
|
|
113
|
+
EC: [stdnum.EC.ci, stdnum.EC.ruc],
|
|
114
|
+
EE: [stdnum.EE.ik, stdnum.EE.kmkr, estonianpassport],
|
|
115
|
+
EG: [stdnum.EG.tn],
|
|
116
|
+
ES: [stdnum.ES.nie, stdnum.ES.nif, stdnum.ES.nss, spanishpassport],
|
|
117
|
+
FI: [stdnum.FI.hetu, alv, finnishpassport],
|
|
118
|
+
FO: [stdnum.FO.vn],
|
|
119
|
+
FR: [spi, stdnum.FR.nir, stdnum.FR.siren, stdnum.FR.siret, frenchvat, frenchpassport],
|
|
120
|
+
GB: [stdnum.GB.nino, stdnum.GB.utr, britishvat, britishpassport],
|
|
121
|
+
GH: [stdnum.GH.tin],
|
|
122
|
+
GN: [stdnum.GN.nifp],
|
|
123
|
+
GR: [stdnum.GR.amka, greekvat],
|
|
124
|
+
GT: [stdnum.GT.cui, stdnum.GT.nit],
|
|
125
|
+
HR: [stdnum.HR.oib],
|
|
126
|
+
HU: [stdnum.HU.anum],
|
|
127
|
+
IE: [ppsn, irishvat, irishpassport],
|
|
128
|
+
IL: [hp, idnr],
|
|
129
|
+
IN: [
|
|
130
|
+
stdnum.IN.pan,
|
|
131
|
+
aadhaar,
|
|
132
|
+
stdnum.IN.epic,
|
|
133
|
+
stdnum.IN.gstin,
|
|
134
|
+
stdnum.IN.vid,
|
|
135
|
+
indianpassport,
|
|
136
|
+
],
|
|
137
|
+
IS: [kennitala, stdnum.IS.vsk],
|
|
138
|
+
IT: [stdnum.IT.codicefiscale, stdnum.IT.aic, italianvat, italianpassport],
|
|
139
|
+
JP: [mn, stdnum.JP.cn, japanesepassport],
|
|
140
|
+
KE: [stdnum.KE.pin],
|
|
141
|
+
KR: [stdnum.KR.rrn, stdnum.KR.brn, koreanpassport],
|
|
142
|
+
LI: [stdnum.LI.peid],
|
|
143
|
+
LT: [asmens, pvm],
|
|
144
|
+
LU: [luxembourgvat],
|
|
145
|
+
LV: [latvianvat],
|
|
146
|
+
MC: [monacovat],
|
|
147
|
+
MD: [stdnum.MD.idno],
|
|
148
|
+
MT: [maltesevat],
|
|
149
|
+
MU: [stdnum.MU.nid],
|
|
150
|
+
MX: [stdnum.MX.curp, stdnum.MX.rfc, stdnum.MX.clabe],
|
|
151
|
+
NL: [stdnum.NL.bsn, dutchvat, netherlandspassport],
|
|
152
|
+
NO: [fodselsnummer, norwegianvat, stdnum.NO.orgnr],
|
|
153
|
+
NZ: [stdnum.NZ.ird, newzealandpassport],
|
|
154
|
+
PE: [stdnum.PE.cui, stdnum.PE.ce, stdnum.PE.ruc],
|
|
155
|
+
PH: [philippinepassport, tin],
|
|
156
|
+
PL: [stdnum.PL.pesel, polishvat, polishpassport],
|
|
157
|
+
PT: [stdnum.PT.nif, stdnum.PT.cc, portuguesepassport],
|
|
158
|
+
PY: [pynationalid, stdnum.PY.ruc],
|
|
159
|
+
RO: [stdnum.RO.cnp, romanianvat, romanianpassport],
|
|
160
|
+
RU: [inn, russianpassport],
|
|
161
|
+
RS: [stdnum.RS.jmbg],
|
|
162
|
+
SA: [tin],
|
|
163
|
+
SE: [swedentin, swedenvat, swedishpassport],
|
|
164
|
+
SI: [slovenianvat, emso, tin],
|
|
165
|
+
SK: [slovakvat, stdnum.SK.rc],
|
|
166
|
+
SV: [stdnum.SV.nit],
|
|
167
|
+
TH: [stdnum.TH.tin, thailandpassport],
|
|
168
|
+
TN: [stdnum.TN.mf],
|
|
169
|
+
US: [stdnum.US.ssn],
|
|
170
|
+
UY: [stdnum.UY.cedula, uruguayanvat, stdnum.UY.nie],
|
|
171
|
+
};
|
|
172
|
+
function validate(country, value) {
|
|
173
|
+
const vset = validators[country.toLocaleUpperCase()];
|
|
174
|
+
if (!vset || vset.length === 0) {
|
|
175
|
+
return { checked: false };
|
|
176
|
+
}
|
|
177
|
+
const match = vset.filter((grp) => grp.validate(value).isValid);
|
|
178
|
+
return { checked: true, isValid: match.length > 0, matchedValidators: match };
|
|
179
|
+
}
|
|
180
|
+
export function getDocumentType(countryCode, taxId) {
|
|
181
|
+
const { isValid, matchedValidators = [] } = validate(countryCode, taxId);
|
|
182
|
+
if (isValid) {
|
|
183
|
+
const [validator] = matchedValidators;
|
|
184
|
+
return validator?.abbreviation?.toLowerCase();
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
export function isValid(countryCode, taxId) {
|
|
189
|
+
return getDocumentType(countryCode, taxId) !== undefined;
|
|
190
|
+
}
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Validator } from 'stdnum';
|
|
2
|
+
export declare function createValidator(name: string, abbreviation: string, length?: number): Validator;
|
|
3
|
+
export declare function createPassportValidator(name: string, regex: RegExp): Validator;
|
|
4
|
+
export declare function changeAbbreviation(validator: Validator, abbreviation: string): Validator;
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { InvalidFormat, InvalidLength } from 'stdnum/lib/cjs/exceptions.js';
|
|
2
|
+
function identity(value) {
|
|
3
|
+
return value;
|
|
4
|
+
}
|
|
5
|
+
export function createValidator(name, abbreviation, length) {
|
|
6
|
+
return {
|
|
7
|
+
name,
|
|
8
|
+
localName: name,
|
|
9
|
+
abbreviation,
|
|
10
|
+
compact: identity,
|
|
11
|
+
format: identity,
|
|
12
|
+
validate: (value) => {
|
|
13
|
+
const formatted = value.trim().replace(/-/gu, '');
|
|
14
|
+
if (length && formatted.length !== length) {
|
|
15
|
+
return {
|
|
16
|
+
isValid: false,
|
|
17
|
+
error: new InvalidLength(`Expected length ${length}, got ${value.length}`),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
isValid: true,
|
|
22
|
+
compact: value,
|
|
23
|
+
isIndividual: true,
|
|
24
|
+
isCompany: false,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function createPassportValidator(name, regex) {
|
|
30
|
+
return {
|
|
31
|
+
name,
|
|
32
|
+
localName: name,
|
|
33
|
+
abbreviation: 'passport',
|
|
34
|
+
compact: identity,
|
|
35
|
+
format: identity,
|
|
36
|
+
validate: (value) => {
|
|
37
|
+
const normalizedStr = value.replace(/\s/g, '').toUpperCase();
|
|
38
|
+
if (!regex.test(normalizedStr)) {
|
|
39
|
+
return {
|
|
40
|
+
isValid: false,
|
|
41
|
+
error: new InvalidFormat(`Expected format ${regex.toString()}, got ${value}`),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
isValid: true,
|
|
46
|
+
compact: value,
|
|
47
|
+
isIndividual: true,
|
|
48
|
+
isCompany: false,
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function changeAbbreviation(validator, abbreviation) {
|
|
54
|
+
return {
|
|
55
|
+
...validator,
|
|
56
|
+
abbreviation,
|
|
57
|
+
};
|
|
58
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exodus/stdnum",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "Exodus Movement, Inc.",
|
|
5
|
+
"description": "Library for validating and formatting standard numbers.",
|
|
6
|
+
"main": "src/index.mjs",
|
|
7
|
+
"module": "src/index.mjs",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"files": [
|
|
10
|
+
"lib",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "run -T exodus-test --jest --esbuild",
|
|
15
|
+
"lint": "run -T eslint",
|
|
16
|
+
"lint:fix": "yarn lint --fix",
|
|
17
|
+
"build": "run -T tsc -p tsconfig.build.json",
|
|
18
|
+
"prepublishOnly": "yarn run -T build --scope @exodus/sentry-client"
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/libraries/stdnum",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Astdnum"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/ExodusMovement/exodus-hydra.git"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"stdnum": "^1.11.7"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"provenance": false
|
|
36
|
+
}
|
|
37
|
+
}
|